This is a more concrete question that is connected with my previous one.
I have an application that uses a timer. The code is written the way the my WM_TIMER
handler call a DialogBoxParam(...)
with some custom message handler (let's call it DlgProc
).
This is done somewhat the following way:
case WM_TIMER: { // Routine, that displays a special message box 开发者_JAVA百科 DisplayMessageBox(...); return 0; }
Now, if I make DlgProc
handle the messages like this (see the code), this would result in tons of dialog boxes (one per WM_TIMER
call).
switch (msg)
{
case WM_INITDIALOG:
// (...)
return TRUE;
case WM_COMMAND:
// (...)
return TRUE;
return FALSE;
}
But if I add a dummy WM_PAINT
handler (return TRUE;
) to my DlgProc
, this results in exactly one shown DialogBox and 100% CPU load (that's because I receive tons of WM_PAINT
messages).
Q:
What can be done here if I want my application to show exactly ONE dialog box and have no CPU load for WM_PAINT processing? (I mean like, have behaviour similiar to draw unique dialog box and fully pause the parent window).
Also it would be great if someone explains what actually happens in this situation and why do I receive gazillions of WM_PAINT
messages to my dialog box and why their processing (with return TRUE
) results in preventing the other dialog boxes creation.
Thank you.
1) You should disable the timer after the first WM_TIMER signal is caught if you want to show only one single dialog box. You can do this using KillTimer().
2) Windows wants to keep the GUI up-to-date. Whenever a region on the screen should be updated, it is invalidated using InvalidateRect or InvalidateRgn. Now, for every "invalid" screen part, WM_PAINT is called in order to make in "valid" again.
If you don't do it (or just parts of it), Windows will call WM_PAINT again ... and again. One way is to call ValidateRect. In many cases BeginPaint() and EndPaint() are used to do the job.
3) Maybe most important: you should not just return FALSE! Try DefWindowProc() for windows and DefDlgProc() for dialogs. They will also take care of WM_PAINT appropriately.
It's not that you registered for WM_PAINT, something must cause it (even if you don't add WM_PAINT: handler), look for re/draw functions (like InvalidateRect())
精彩评论