почему бы не отправить WM_PAINT вручную

Я прочитал, что я никогда не должен отправлять WM_PAINT вручную и должен позвонить InvalidateRect но не нашел ничего, почему бы и нет. Так почему не?

Обновить работает с InvalidateRect но не с SendMessage(WM_PAINT)

LRESULT CALLBACK window_proc(HWND wnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
switch (msg)
{
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(wnd, &ps);

Polyline(..);

EndPaint(wnd, &ps);
return 0;

case WM_USER:
// SendMessage(wnd, WM_PAINT, NULL, NULL);
// InvalidateRect(wnd, NULL, FALSE);

return 0;
}
}

2

Решение

Официальные документы для WM_PAINT заявите, что вы не должны в самом первом предложении раздела замечаний. Серьезно, этого должно быть достаточно, чтобы не делать этого.

Что касается технических причин, почему, я думаю, это один из них, взятый из BeginPaint раздел замечаний:

Регион обновления задается InvalidateRect или же InvalidateRgn функции и системой после изменения размера, перемещения, создания, прокрутки или любой другой операции, которая влияет на клиентскую область.

таким образом BeginPaint может не работать правильно, если вы отправите WM_PAINT вручную.

Там может быть больше причин / сюрпризов.

5

Другие решения

Если вы хотите запустить немедленную перерисовку, правильный подход заключается в следующем:

  1. использование InvalidateRect() с последующим UpdateWindow(),

  2. использование RedrawWindow(),

Те вызовут новый WM_PAINT сообщение будет сгенерировано.

3

У вас нет никакой информации о окнах других программ, раскрывающих ваши окна. Только операционная система имеет эту информацию. Таким образом, вы не знаете все время, когда или где нужно перекрасить окно. WM_PAINT и BeginPaint предоставляют эту недостающую информацию.

2

Так как WM_PAINT это не настоящее сообщение.

Думайте об этом, как будто каждое окно имеет структуру, хранящую «недопустимую область», то есть «эта часть окна на экране больше не актуальна и требует перекраски».

Эта недопустимая область изменяется самим оконным менеджером (размер окна изменяется, открывается и т. Д.) Или путем вызова InvalidateRect, ValidateRect, EndPaint и тому подобное.

Теперь вот грубый макет того, как GetMessage обрабатывает это:

... GetMessage(MSG* msg, ...)
{
while(true) {
if(ThereIsAnyMessageInTheMessageQueue()) {
*msg = GetFirstMessageOfTheMessageQueue();
return ...;
} else if(TheInvalidRegionIsNotEmpty()) {
*msg = CreateWMPaintMessage();
return ...;
} else {
WaitUntilSomethingHappend();
}
}
}

ТЛ; др: WM_PAINT предназначен для получения, а не отправки.

1
По вопросам рекламы [email protected]