Tuborg
Команда клуба
Offline
|
|
« : 18-07-2007 09:34 » |
|
Проект тот же, диалог, на нём сверрху рисуется диаграмма. Проблемв с отрисовкой диаграммы была решена в https://forum.shelek.ru/index.php/topic,12000.0.html Но теперь проявилась другая проблема (на тот момент не обратил на неё внимания). Диаграмма то отрисовывается... а вот на диалоге кроме Rectangle с диаграмой есть ещё и другие контролы.... они не перерисовываются.... вернее перерисовываются если я минимизирую окно... но не перерисовываются вместе с диаграммой. Почему так? void CWin_CCDlg::OnPaint() { CDC CMemDC1, CMemDC2, CMemDC3; CBitmap pBitmap1, pBitmap2, pBitmap3, *pOldBitmap; if (IsIconic()) {... } else { CRect FrameRect; CWnd *pWnd1=this->GetDlgItem(IDC_GRAPH_FRAME1); // Прямоугольник1 типа Rectangle (Код для прямоугольника 2 и 3 удаляю так как всё также) if(graphComplete){ // Флаг который выставляется процедурой чтения данных из файла // после того как порция данных была преобразована в график во // внутренних структурах класса отвечающих за график CPaintDC dc(this);
pWnd1->GetWindowRect(FrameRect);// Привожу координаты прямоугольника this->ScreenToClient(FrameRect); // к координатам окна
CMemDC1.CreateCompatibleDC(&dc); // Создаю MemDC для способа быстрой перерисовки // Буду рисовать на MemDC а потом поточечно копировать на DC прямоугольника 1
if (CMemDC1) { //Делаю на DC битмап для рисования, а точнее чтоб потом проще было на реальный //DC копировать pBitmap1.CreateCompatibleBitmap(&dc, FrameRect.Width()-1, FrameRect.Height()-1); pOldBitmap = (CBitmap*)CMemDC1.SelectObject(pBitmap1); ch_Graph->DrawGraph(&CMemDC1, FrameRect.Width(), FrameRect.Height(),1,ch_Graph->GetSeriesQuantity()+1); // Вызов процедуры вывода графика на указанный DC // копируем биты из памяти на DC прямоугольника dc.BitBlt(0, 0,FrameRect.Width()-2, FrameRect.Height()-2, &CMemDC1, 0, 0, SRCCOPY); // возвращаем старый bitmap CMemDC1.SelectObject(&pOldBitmap); // освобождаем контекст DeleteDC(CMemDC1); } }
} } Умом понимаю... что в OnPaint'е я в принципе и не прошу перерисовать контролы.... А как об этом "попросить"?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 18-07-2007 09:50 » |
|
помести CPaintDC dc(this);
сразу после
else {
|
|
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 18-07-2007 10:03 » |
|
Tuborg, поставь там, где я показал ) Там и ТОЛЬКО ТАМ , больше нигде!
это создаётся контекст окна. Альтернатива вызову OnPaint() родительского класса
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 18-07-2007 10:04 » |
|
для теста ещё заремарь всё остальное в else после CPaintDC dc(this);
|
|
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 18-07-2007 10:31 » |
|
значит дело в другом... ну попробуй ещё так для интереса void CWin_CCDlg::OnPaint() { CPaintDC dc(this); }
и, в конце концов, вот так void CWin_CCDlg::OnPaint() { CDialog::OnPaint(); }
|
|
« Последнее редактирование: 18-07-2007 10:32 от Алексей1153++ »
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 18-07-2007 11:29 » |
|
Tuborg, Invalidate лишь помечает (обрати внимание!) окно как инвалидное, то есть оно будет перерисовано при очередном попадании сообщения WM_PAINT из очереди сообщений в оконную процедуру. Не факт, что сообщение будет в очереди! Его надо туда положить. И не факт, что если мы его туда и положим, сообщение скоро дойдёт до оконной процедуры, если к окну идёт интенсивный поток сообщений. Поютому, раз в , скажем, 100мс вызываем для окна UpdateWindow() , что приводит к немедленной отправке WM_PAINT непосредственно в оконную процедуру. Сильно часто UpdateWindow() вызывать не нужно - будут тормоза. По идее - чтобы было приятно глазу, не чаще. Но и не реже и ещё опять повторю,что тебе ранее писал Invalidate(0) - помечает окно как инвалидное Invalidate(1) - помечает окно как инвалидное + стирает
|
|
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 18-07-2007 13:06 » |
|
Tuborg, если вычисления в цикле, то можно воспользоваться ::GetTickCount DWORD dwdLast=0; DWORD dwdCurr=0; DWORD dwdDiff=100;
for(;;) {
//смотрим разницу dwdCurr=::GetTickCount(); if(dwdCurr-dwdLast>dwdDiff) { dwdLast=dwdCurr;
//выполняем UpdateWindow нужного окна }
//тут код твоих вычислений //... }
|
|
« Последнее редактирование: 18-07-2007 13:38 от Алексей1153++ »
|
Записан
|
|
|
|
|
Tuborg
Команда клуба
Offline
|
|
« Ответ #12 : 18-07-2007 13:50 » |
|
Результат не очень впечатлил. Прилагаю снимок экрана. UpdateWindow по прежнему не лучшее решение =) На снимке экрана видно как прямоугольники за диаграмами прорисовались на половину.... что самое интересное эффект происходит не так уж часто.... это если я возьму окно и начинаю его быстро-быстро перемещать по экрану... Переключившись на другую вкладку и вернувшись обратно - прямоугольники прорисуются.... если водить медленно, такого не происходит =(
|
GUI.JPG (58.28 Кб - загружено 1126 раз.)
|
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #14 : 18-07-2007 15:30 » |
|
Tuborg, если пишешь в VC6 , скинь проект. Похоже ты фон не дорисовываешь, что ли...
|
|
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #16 : 19-07-2007 09:25 » |
|
тогда скинь файлы своего контрола
|
|
|
Записан
|
|
|
|
Tuborg
Команда клуба
Offline
|
|
« Ответ #17 : 19-07-2007 09:55 » |
|
Обращение к контролу в OnPaint происходит так: Graph *ch_graph; ...
// рисуем все что требуется pBitmap1.CreateCompatibleBitmap(&dc, FrameRect.Width(), FrameRect.Height()); pOldBitmap = (CBitmap*)CMemDC1.SelectObject(pBitmap1);
ch_Graph->DrawGraph(&CMemDC1, FrameRect.Width(), FrameRect.Height(),1,ch_Graph->GetSeriesQuantity()+1); // копируем биты dc.BitBlt(FrameRect.left+2, FrameRect.top+2,FrameRect.Width()-4, FrameRect.Height()-4, &CMemDC1, 0, 0, SRCCOPY); // возвращаем старый bitmap CMemDC1.SelectObject(&pOldBitmap); // освобождаем контекст DeleteDC(CMemDC1);
Я тут начал уже эксперементировать с границами... потому что думал что что то затираю при рисовании... оказалось не так... =(
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #18 : 19-07-2007 10:56 » |
|
>>pBitmap1.CreateCompatibleBitmap(&dc, FrameRect.Width(), FrameRect.Height());
>>dc.BitBlt(FrameRect.left+2, FrameRect.top+2,FrameRect.Width()-4, FrameRect.Height()-4, &CMemDC1, 0, 0, SRCCOPY);
(sorry za translit - gluk , russkaja raskladka ne vrubaetsa....)
eta ramka v 2 pixela - ona zhe u tebja ne inicializirovana, vot i polu4aetsja tak. Nuzhno tozhe zakrasit` eto
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #19 : 19-07-2007 11:37 » |
|
Tuborg, выложи проект или кинь на мыло - у меня все версии студии есть.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #21 : 19-07-2007 12:12 » |
|
Tuborg, закрась рамку цветом таким :
RGB color = ::GetSysColor(COLOR_3DFACE);
(это настроенный в системе цвет для фона диалога, обычно серый)
|
|
« Последнее редактирование: 19-07-2007 12:14 от Алексей1153++ »
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #23 : 20-07-2007 03:31 » |
|
Tuborg, попробуй поймать сообщение WM_NCPAINT (добавь визардом обработчик и там нарисуй рамку)
или вообще убери рамку, а нарисуй её сам
|
|
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #25 : 20-07-2007 11:41 » |
|
The WM_NCPAINT message is sent to a window when its frame must be painted. LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // WM_NCPAINT WPARAM wParam, // handle to update region (HRGN) LPARAM lParam // not used );
wParam - Handle to the update region of the window. The update region is clipped to the window frame. When wParam is 1, the entire window frame needs to be updated.
lParam -This parameter is not used.
но как-то я склоняюсь всё же к нарисованию своей рамки в OnPaint() для рамки можно воспользоваться CDC::Draw3dRect( ) или просто отрисовать при помощи 4 вызовов CDC::FillSolidRect() зы. Если честно - надо ждать Джона, он посоветует, что истинно правильно
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #26 : 20-07-2007 13:53 » |
|
Так... пытаюсь разобраться с проектом. Я конечно не ожидал, что получу ВСЁ. На будущее, Tuborg, если можно - только пример с неработающей частью (например только график и только одну кнопку). И если можно, то либо русский в юникоде, либо аглицкий (пусть хоть с ошибками). Русский в ANSI у меня отображается закорючками.
Пока наблюдаю след эффект (загрузил данные из файла imit_pila.scd):
сначала всё нормально - вижу и график и кнопки, нажимаю "проигрывать" всё тоже в порядке. Сразу после нажатия на "стоп" пропадают всё контролы на этой страничке. Последующее "воспроизведение" и изменение размеров окна не помогают. Они появляются только если переключиться на другую страничку, а потом обратно.
Те это и является проблемой? Или я что-то просмотрел?
зы так замечания по коду:
как ты ф-ции обработки событий вставляешь?
ON_BN_CLICKED(ID_PAUSEREPLAY, &CPageControl::OnBnClickedPause)
можешь просто писать без &CPageControl::
ON_BN_CLICKED(ID_PAUSEREPLAY, OnBnClickedPause)
в С++ имя функции автоматически является указателем, а принадлежность указывается в BEGIN_MESSAGE_MAP(CPageControl, CDialog)
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #27 : 20-07-2007 15:10 » |
|
Ну в принципе я так сразу и подумал. После остановки ни одно из условий в OnPaint у тебя не выполняется:
if(graphComplete)
if (dis_graphComplete)
if (measure_graphComplete)
Те НИЧЕГО НЕ ПРОИСХОДИТ в OnPaint.
Ну ессно почему так происходит я тебе не могу сказать. Ты должен проверить эти переменные. Потом будем дальше посмотреть. А ну и ещё ты намутил в обработке нажатия на стоп с Update/Invalidate. Не надо их там столько.
Вобще-то так не делается. Я конечно не знаю почему ты сделал именно так. Теория простая:
1. Если ты делаешь своё контрол, наследуя его от CWnd, то и вся отрисовка происходит в OnPaint этого контролла. В диалоге нет ничего, кроме передачи размеров при OnSize и внешнего управления (Вкл/Выкл). Ну типа стандартных контроллов. Ведь нет у тебя в OnPaint диалога ни кнопок, ни каких других элементов, а ведь они отрисовываются. Самостоятельно.
2. Если твой контрол не наследован от CWnd, а использует DC родителя, то тогда он отрисовывается в OnPaint родителя. Обычно у него есть своя ф-я в которую родитель передаёт указатель на свой DC, чтобы не загромождать код родителя.
Всё. А у тебя? И CPageControl хранит указатель на диалог, являясь в свою очередь его ребёнком (если это необходимо - есть ф-я GetParent), и вызывает ф-ции работы с графиком в нём, хотя логичней предположить, что он сам должен быть родителем графика. Ну и тд. Плюс ко всему оформление кода... Читать и разбираться очень трудно. Посмотри для примера оформление кода С++ MFC в MSDN, codeguru.com codeproject.com.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #28 : 20-07-2007 15:13 » |
|
Да самое главное - начни с бумаги. Нарисуй сначала модель программы. Что где находится и от чего зависит. Структуру классов. Если точно ещё не значешь какие именно это должны быть объекты - ничего страшного. Называй как хочешь, главное что они стоят на нужном месте. Потом по такой шпаргалке самому легче будет разбираться.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Tuborg
Команда клуба
Offline
|
|
« Ответ #29 : 20-07-2007 19:16 » |
|
Спасибо за проведённые исследования. Извиняюсь за бардак в структуре классов... но это я перелажу на прогу с несколькими табами.... раньше была прога с одним диалогом и ничего мудрённого в ней не было... а щас.... =) Да Юникод я не очень люблю, так как стандартом он и не стал, увы.... на будущее для себя учту - буду писать в английском ANSI. сначала всё нормально - вижу и график и кнопки, нажимаю "проигрывать" всё тоже в порядке. Сразу после нажатия на "стоп" пропадают всё контролы на этой страничке. Последующее "воспроизведение" и изменение размеров окна не помогают. Они появляются только если переключиться на другую страничку, а потом обратно.
Те это и является проблемой? Или я что-то просмотрел?
Да именно это проблемой и является.... есть и ещё одна.... если диалог потаскать мышкой... то исчезает PictureControl на которых рисуется график.... но эта одна и та же проблема... просто вылазит поразному =) Ну в принципе я так сразу и подумал. После остановки ни одно из условий в OnPaint у тебя не выполняется:
if(graphComplete)
if (dis_graphComplete)
if (measure_graphComplete)
Те НИЧЕГО НЕ ПРОИСХОДИТ в OnPaint.
Не рисуется график... я бы с этим смирился... но почему беда с Picture Control происходит? Ведь я как понимаю не должен отвечать за прорисовку Picture Control?
|
|
|
Записан
|
|
|
|
|