i am learning win32 thesedays and playing with PostMessage function.
tricky thing i found was when posting WM_TIMER message into window message queue, window didn't receive any message. if only receive when i set lparam to 0, otherwise not working at all the code here. and also i tested with sendmessage which is totally fine either ways.
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_CREATE:
{
//PostMessage(hWnd, WM_TIMER, 0, 0); // receive msg
PostMessage(hWnd, WM_TIMER, 0, 1); // not receiving
}
return 0;
case WM_TIMER:
{
switch (wparam)
{
case 0:
{
HDC dc = GetDC(hWnd);
Ellipse(dc, 70, 70, 120, 120);
ReleaseDC(hWnd, dc);
}
break;
}
return 0;
}
}
return DefWindowProc(hWnd, msg, wparam, lparam);
}
would be amazing if somebody explain why this is happening. just hope i am missing some basic concept of windows processing system.
According to the WM_TIMER
documentation:
lParam [in]
A pointer to an application-defined callback function that was passed to the
SetTimer
function when the timer was installed.
So, when you use PostMessage(hWnd, WM_TIMER, 0, 0)
, you pass 0 (as a null pointer) to lParam
.
According to the SetTimer
documentation:
A pointer to the function to be notified when the time-out value elapses. For more information about the function, see TimerProc. If
lpTimerFunc
isNULL
, the system posts a WM_TIMER message to the application queue. Thehwnd
member of the message'sMSG
structure contains the value of thehWnd
parameter.
This means when DispatchMessage()
sees the WM_TIMER
message with its lParam
set to 0, it will simply deliver the message as-is to the window message procedure of the window specified by hWnd
.
But, when you use PostMessage(hWnd, WM_TIMER, 0, 1);
instead, you are passing 1 as the lParam
, so it is treated as a pointer to a timer callback function. This means when DispatchMessage()
sees the WM_TIMER
message with its lParam
set to non-zero, it will not deliver the message to the window message procedure of hWnd
, it will instead try to actually call the function pointed to by lParam
, which is obviously illegal in this case. The system cannot call a function through this invalid pointer.
According to the DispatchMessage()
documentation:
The
MSG
structure must contain valid message values. If thelpmsg
parameter points to aWM_TIMER
message and thelParam
parameter of theWM_TIMER
message is notNULL
,lParam
points to a function that is called instead of the window procedure.