Как принудительно перерисовать окно своей программы? Я вызываю UpdateWindow или посылаю WM_PAINT, но внешний вид окошка не меняется (а должен). Окно у меня WS_EX_LAYERED с LMA_ALPHA or LMA_COLORKEY, на окошке я рисую через DrawText и т.п., а когда данные изменяются, надо их напечатать по новой. Что-то делаю не так??
Текст выведеный через DrawText при перерисовке не перерииисовуется системой, его надо выводить снова , отлавливая сообщения WM_PAINT
Все, что ты выводишь, нужно перерисовывать в WM_PAINT заново. Оно для этого и посылается программе, чтобы та перерисовала клиентскую часть окна. Когда окно затирается другим, А потом снова появляется, то неклиентскую часть винда перерисовывает самостоятельно (хотя это поведение можно изменить). А вот как рисовать клиентскую часть она не знает, поэтому и посылает WM_PAINT, чтобы программа сама занялась обновлением клиентской части окна. То есть, если у тебя графический редактор, например, придется гдето запоминать нарисованное дополнительно, чтобы это все заново воспроизводить в окошке при WM_PAINT
Perre, Great я всё это прекрасно понимаю, поэтому тем более мне непонятно, почему PaintProc, которая выполняется у меня при обработке сообщения WM_PAINT выполняется лишь однажды - при первом построении окна, но затем при вызове UpdateWindow сообщение WM_PAINT больше не приходит окну.. Сдается мне, что-то я делаю не так! Но что именно? У меня календарик на рабочий стол. Есть глобальная переменная типа SYSTEMTIME и ещё пара глобальных переменных, которые я заполняю до создания окна, а потом на основе этих переменных строится вся картинка в PaintProc. Процедура выполняется после сообщения WM_PAINT, следовательно достаточно изменить мои переменные и заставить перерисовать окно. Переменные меняю, но вот как перерисовать, если UpdateWindow у меня почему-то не сработала? не перерисовывается мое окно
Сдается мне, что действительно что-то не так. Покажи код. точнее, у тебя почему-то не вызывается WndProc с WM_PAINT Опять же, код в студию. Полный сорс обработчика сообщений и создания окна
Ни разу не видел, чтобы задержка была бы заметна на глаз К тому же в описании UpdateWindow не указано, что UpdateWindow форсирует WM_PAINT. Посылает - да, но сообщение будет послано, когда винда посчитает нужным. Иначе говоря, не форсирует.
cresta Примитивная спрайтовая анимация на слабой машине - задержку видно на глаз. Но проблема у человека не в задержке сообщения а в том, что оно не приходит. Если не использовать UpdateWindow, то сообщения WM_PAINT могут совмещаться, т.е. вместо нескольких таких сообщений подряд приходит одно. А что она тогда делает?
cresta описании UpdateWindow не указано Imho заблуждаешься. Цитата msdn. UpdateWindow: "The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty. The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. If the update region is empty, no message is sent."
Код (Text): ... case WM_PAINT: WmPaint (); // <-- BRK1 break; ... UpdateWindow (...); // <-- BRK2 NextCall (); // <-- BRK3 В отладчике легко видно, что если достигается BRK2, то BRK1 будет перед BRK3, иными словами WM_PAINT вызовется до возврата из UpdateWindow().
Забудьте об этой никчемной UpdateWindow При изменении данных - либо InvalidateRect(hWnd,0,1), либо RedrawWindow(hWnd,0,0,RDW_INVALIDATE OR RDW_ERASE), а далее - либо на WM_PAINT: BeginPaint(hWnd,addr ps) Func(eax) EndPaint(hWnd,addr ps) либо на WM_ERASEBKGND: DefWindowProc(hWnd,uMsg,wParam,lParam) Func(wParam) где Func, например, - SetBkMode(TRANSPARENT) DrawText
Всем спасибо, решил эту проблемму вчера вечером, додумался точно до того же: GetClientRect - InvalidateRect - UpdateWindow У меня не работало потому, что UpdateWindow не будет посылать никакого сообщения WN_PAINT, если нет областей указанны для перерисовки. Спасибо большое за участие всем ещё раз!
mc black >GetClientRect - InvalidateRect - UpdateWindow Решили - это хорошо, но уверены, что код у вас не избыточен ? В ваших же интересах было бы его все-таки показать.
Только не надо вызывать самому ни WM_PAINT, ни WM_ERASEBKGND. Это делает Windows. Не так давно, я сопровождал большой C++ проект, где такая "техника" постоянно использовалась. После такого невозможно отловить те места, где не происходит правильная перерисовка - всегда оставались не перерисованные места. Правильный подход к рисованию это пара InvalidateRect()/UpdateWindow() или единственный RedrawWindow(). Причём "InvalidateRect (hWnd, 0, 1);" может вызвать мелькание. Лучше всего в InvalidateRect () указывать инвалидный прямоугольник, тогда Windows отсечёт всё не нужное и прорисовка произойдёт быстрее.
Не вопрос с исходниками, код открытый целиком и стопудово не на 100% оптимальный, возможно где-то и избыточный. Скачать можно на http://mc-black.narod.ru/src/dzp.src.zip По всему проекту интересны ваши отклики. AsmGuru62, UpdateWindow блокирует все сообщения до тех пор, пока окошко не перерисуется, поэтому и могут возникать корявости, когда пытаются отправлять WM_PAINT.
mc black >UpdateWindow блокирует все сообщения до тех пор, пока окошко не перерисуется, поэтому и могут возникать корявости, когда пытаются отправлять WM_PAINT. ???
kero Всё верно - блокирует. Потому что напрямую вызывается процедура окна: Что-то в таком вот виде (реализация UpdateWindow()): Код (Text): BOOL UpdateWindow (HWND hWnd) { ... WNDPROC pfnWndProc = GetWindowLong (hWnd, GWL_WNDPROC); CallWindowProc (pfnWndProc, hWnd, WM_PAINT, ... , ... ); ... } Ну и естественно, пока процедура окна не вернётся - других сообщений не получим. Хотя процедура окна реентерабельна... в принципе.