Перерисовка окна. Сто раз читал - не могу понять!
От: Nickolaich  
Дата: 12.12.10 04:02
Оценка:
Всем доброго времени суток. Читал перечитал кучу форумов, но все равно не могу сделать.
Программа "Построение графиков". Проблемы с перерисовкой.
Вызываю меню построения графика, ввожу необходимые параметры, жму кнопку построить — строится, все хорошо.
Вызываю опять окно построения графика, хочу нарисовать новый график, а старый либо остается полностью, либо частично, пока не сверну и опять не разверну окно.
Пробовал все функции:
//ValidateRect(Rect);
//Invalidate(FALSE);
//InvalidateRect(Rect,0);
//CDialog::OnPaint();
//UpdateWindow();
//SendMessage(WM_PAINT,0,0);
//OnPaint();
в разных комбинациях — ничего не получается.
Кто может помочь? Код тоже могу прислать.
Re: Перерисовка окна. Сто раз читал - не могу понять!
От: Pavel Dvorkin Россия  
Дата: 12.12.10 06:06
Оценка:
Здравствуйте, Nickolaich, Вы писали:

N>Всем доброго времени суток. Читал перечитал кучу форумов, но все равно не могу сделать.

N>Программа "Построение графиков". Проблемы с перерисовкой.
N>Вызываю меню построения графика, ввожу необходимые параметры, жму кнопку построить — строится, все хорошо.
N>Вызываю опять окно построения графика, хочу нарисовать новый график, а старый либо остается полностью, либо частично, пока не сверну и опять не разверну окно.
N>Пробовал все функции:
N> //ValidateRect(Rect);
N> //Invalidate(FALSE);

Invalidate(); // то есть с TRUE — по умолчанию.
With best regards
Pavel Dvorkin
Re[2]: Перерисовка окна. Сто раз читал - не могу понять!
От: Nickolaich  
Дата: 12.12.10 07:31
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Invalidate(); // то есть с TRUE — по умолчанию.


И это пробовал — он просто очищает окно, а новый график не рисует. Только после свертывания-развертывания окна)


void CПостроениеграфиковDlg::OnPaint()
{
if (IsIconic())
{.......}
else
{
CDC *pDC = GetDC();
// рисую оси координат
// и сам график
CPen PGraph;
PGraph.CreatePen(PS_SOLID, 1, col_graf);
CPen *pOldPen = pDC->SelectObject (&PGraph);

for (int i=0; i<fx.size()-1; i++)
Line(pDC,215+15*fx[i],200-15*fy[i],215+15*fx[i+1],200-15*fy[i+1]);
CDialog::OnPaint();
}
}

void CПостроениеграфиковDlg::On_From_File()
{
...............
// Это заполнение векторов координат (х,y), по которым в OnPaint() рисуются линии
for (int i=0; i<coordx.size(); i++)
{
fx.push_back(atof(coordx[i].c_str()));
fy.push_back(atof(coordy[i].c_str()));
}
// затем хочу вызвать OnPaint для отрисовки

UpdateWindow(); // тогда при нажатии на кнопку построить, он просто очищает окно и все,
// рисует график только, когда сверну и разверну окно
// Если на использовать UpdateWindow();, то делаю так
Invalidate(FALSE); // тогда он рисует нормально график. Потом я хочу нарисовать новый.
// он рисует старый и новый, а при свертывании, развертывании — убирает старый // и оставляет новый
}
Re[3]: Перерисовка окна. Сто раз читал - не могу понять!
От: Pavel Dvorkin Россия  
Дата: 12.12.10 07:35
Оценка:
Здравствуйте, Nickolaich, Вы писали:

N>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Invalidate(); // то есть с TRUE — по умолчанию.


N>И это пробовал — он просто очищает окно, а новый график не рисует. Только после свертывания-развертывания окна)



N>void CПостроениеграфиковDlg::OnPaint()


Убрать полностью. У тебя есть OnDraw, в нее контекст передается. Если ее нет — добавь. Его и используй, рисование перенеси туда.

N>{

N> if (IsIconic())
N> {.......}
N> else
N> {
N> CDC *pDC = GetDC();

Дело в том, что GetDC нельзя использовать в OnPaint. В ней нужно использовать CPaintDC. Но еще раз — не перекрывай OnPaint, а используй OnDraw. OnPaint базового класса вызовет эту OnDraw.
With best regards
Pavel Dvorkin
Re[4]: Перерисовка окна. Сто раз читал - не могу понять!
От: Nickolaich  
Дата: 12.12.10 07:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

Если я правильно понял, то
1) void CПостроениеграфиковDlg::OnPaint() заменяю на void CПостроениеграфиковDlg::OnDraw()
2) Остальной код, который был в OnPaint() и использовал CDC *pDC = GetDC() оставляю прежним, т.к. теперь работаю с OnDraw().
3) В функциях, где нужно вызвать перерисовку графика вставляю UpdateWindow();
Все так?
Re[4]: Перерисовка окна. Сто раз читал - не могу понять!
От: Nickolaich  
Дата: 12.12.10 09:47
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Nickolaich, Вы писали:


N>>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>>Invalidate(); // то есть с TRUE — по умолчанию.


N>>И это пробовал — он просто очищает окно, а новый график не рисует. Только после свертывания-развертывания окна)



N>>void CПостроениеграфиковDlg::OnPaint()


PD>Убрать полностью. У тебя есть OnDraw, в нее контекст передается. Если ее нет — добавь. Его и используй, рисование перенеси туда.


N>>{

N>> if (IsIconic())
N>> {.......}
N>> else
N>> {
N>> CDC *pDC = GetDC();

PD>Дело в том, что GetDC нельзя использовать в OnPaint. В ней нужно использовать CPaintDC. Но еще раз — не перекрывай OnPaint, а используй OnDraw. OnPaint базового класса вызовет эту OnDraw.



Оставил OnPaint() как он был при создании проекта.
Добавил OnDraw() и перенес туда весь код.
Поставил UpdateWindow() — и оно все равно неправильно перерисовывает. Стирает все полностью после того как сворачиваю и разворачиваю окно
Re[5]: Перерисовка окна. Сто раз читал - не могу понять!
От: Pavel Dvorkin Россия  
Дата: 12.12.10 10:34
Оценка:
Здравствуйте, Nickolaich, Вы писали:

N>Здравствуйте, Pavel Dvorkin, Вы писали:


N>Если я правильно понял, то

N>1) void CПостроениеграфиковDlg::OnPaint() заменяю на void CПостроениеграфиковDlg::OnDraw()

Да

N>2) Остальной код, который был в OnPaint() и использовал CDC *pDC = GetDC() оставляю прежним, т.к. теперь работаю с OnDraw().


Да

N>3) В функциях, где нужно вызвать перерисовку графика вставляю UpdateWindow();


Invalidate();
// можно еще после нее UpdateWindow();
With best regards
Pavel Dvorkin
Re[6]: Перерисовка окна. Сто раз читал - не могу понять!
От: Nickolaich  
Дата: 12.12.10 12:09
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Nickolaich, Вы писали:


N>>Здравствуйте, Pavel Dvorkin, Вы писали:


N>>Если я правильно понял, то

N>>1) void CПостроениеграфиковDlg::OnPaint() заменяю на void CПостроениеграфиковDlg::OnDraw()

PD>Да


N>>2) Остальной код, который был в OnPaint() и использовал CDC *pDC = GetDC() оставляю прежним, т.к. теперь работаю с OnDraw().


PD>Да


N>>3) В функциях, где нужно вызвать перерисовку графика вставляю UpdateWindow();


PD>Invalidate();

PD>// можно еще после нее UpdateWindow();

Не получается все равно — начисто все убирает, не прорисовывает.

void CПостроениеграфиковDlg::OnDraw(CDC* pDC)
{
...
CPen PGraph;
PGraph.CreatePen(PS_SOLID, 1, col_graf);
CPen *pOldPen = pDC->SelectObject (&PGraph);

for (int i=0; i<fx.size()-1; i++)
Line(pDC,215+15*fx[i],200-15*fy[i],215+15*fx[i+1],200-15*fy[i+1]);
}

void CПостроениеграфиковDlg::On_From_File()
{
........................
for (int i=0; i<coordx.size(); i++)
{
fx.push_back(atof(coordx[i].c_str()));
fy.push_back(atof(coordy[i].c_str()));
}

this->OnDraw(pDC);

Invalidate();
UpdateWindow();
}
Re[6]: Перерисовка окна. Сто раз читал - не могу понять!
От: AlexGin Беларусь  
Дата: 13.12.10 08:02
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Nickolaich, Вы писали:


N>>Здравствуйте, Pavel Dvorkin, Вы писали:


N>>Если я правильно понял, то

N>>1) void CПостроениеграфиковDlg::OnPaint() заменяю на void CПостроениеграфиковDlg::OnDraw()

PD>Да


А разве в классе, наследуемом от CDialog будет OnDraw ???
OnDraw — будет ТОЛЬКО в классах, наследуемыз от CView (где она чисто виртуальная).

N>>2) Остальной код, который был в OnPaint() и использовал CDC *pDC = GetDC() оставляю прежним, т.к. теперь работаю с OnDraw().


PD>Да

Скорее всего придется оставить OnPaint, а в ней:
CClientDC dcClient(this);

N>>3) В функциях, где нужно вызвать перерисовку графика вставляю UpdateWindow();


PD>Invalidate();

PD>// можно еще после нее UpdateWindow();
Это вполне логично
Re[3]: Перерисовка окна. Сто раз читал - не могу понять!
От: AlexGin Беларусь  
Дата: 13.12.10 08:15
Оценка:
Здравствуйте, Nickolaich, Вы писали:

N>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Invalidate(); // то есть с TRUE — по умолчанию.


N>И это пробовал — он просто очищает окно, а новый график не рисует. Только после свертывания-развертывания окна)



N>void CПостроениеграфиковDlg::OnPaint()

N>{
N> if (IsIconic())
N> {.......}
N> else
N> {
N> CDC *pDC = GetDC();
N> // рисую оси координат
N> // и сам график
N> CPen PGraph;
N> PGraph.CreatePen(PS_SOLID, 1, col_graf);
N> CPen *pOldPen = pDC->SelectObject (&PGraph);

N> for (int i=0; i<fx.size()-1; i++)

N> Line(pDC,215+15*fx[i],200-15*fy[i],215+15*fx[i+1],200-15*fy[i+1]);
N> CDialog::OnPaint();
N> }
N>}

Не уверен — что надо в конце вызывать CDialog::OnPaint();
Вы же сами рисуете график, а не метод базового класса...
Попробуйте закоментировать этот вызов...
Re[7]: Перерисовка окна. Сто раз читал - не могу понять!
От: Pavel Dvorkin Россия  
Дата: 13.12.10 08:55
Оценка:
Здравствуйте, AlexGin, Вы писали:

AG>А разве в классе, наследуемом от CDialog будет OnDraw ???

AG>OnDraw — будет ТОЛЬКО в классах, наследуемыз от CView (где она чисто виртуальная).

Хм. Верно. не обратил я внимание на то, что там диалог.


N>>>2) Остальной код, который был в OnPaint() и использовал CDC *pDC = GetDC() оставляю прежним, т.к. теперь работаю с OnDraw().


PD>>Да

AG>Скорее всего придется оставить OnPaint, а в ней:
AG>CClientDC dcClient(this);

Да, тогда так. Впрочем, все же можно сделать OnDraw и вызвать ее из OnPaint
With best regards
Pavel Dvorkin
Re[3]: Перерисовка окна. Сто раз читал - не могу понять!
От: Hawk Россия  
Дата: 20.12.10 09:52
Оценка:
Здравствуйте, Nickolaich,

Попробуйте так:
void CПостроениеграфиковDlg::OnPaint()
{
     CPaintDC dc(this);

     // рисую оси координат
     // и сам график
     CPen PGraph;
     PGraph.CreatePen(PS_SOLID, 1, col_graf);
     CPen *pOldPen = dc.SelectObject (&PGraph);

     for (int i=0; i<fx.size()-1; i++)
        Line(&dc,215+15*fx[i],200-15*fy[i],215+15*fx[i+1],200-15*fy[i+1]);

    dc.SelectObject(pOldPen);
}

Чтобы перерисвать окно, вызывайте Invalidate() или Invalidate(TRUE).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.