大家好,请看以下程序和问题:#include <windows.h>
#include <stdio.h>#define WM_MYMESSAGE (WM_USER + 100)LRESULT CALLBACK WinSunProc(
HWND hwnd,      // handle to window
UINT uMsg,      // message identifier
WPARAM wParam,  // first message parameter
LPARAM lParam   // second message parameter
);int WINAPI WinMain(
   HINSTANCE hInstance,      // handle to current instance
   HINSTANCE hPrevInstance,  // handle to previous instance
   LPSTR lpCmdLine,          // command line
   int nCmdShow              // show state
   )
{
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinSunProc;
wndcls.lpszClassName="Weixin2003";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);

HWND hwnd;
hwnd=CreateWindow("Weixin2003","北京维新科学技术培训中心",WS_OVERLAPPEDWINDOW,
0,0,600,400,NULL,NULL,hInstance,NULL);
HANDLE handle=hwnd;
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);

SendMessage(hwnd, WM_MYMESSAGE, 1, 1);

MSG msg;
//问题1.以下语句过滤出WM_MYMESSAGE,但为什么WinSunProc还是截获到其它消息呢?
while(GetMessage(&msg,hwnd,WM_MYMESSAGE,WM_MYMESSAGE)) 
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}LRESULT CALLBACK WinSunProc(
HWND hwnd,      // handle to window
UINT uMsg,      // message identifier
WPARAM wParam,  // first message parameter
LPARAM lParam   // second message parameter
)
{ switch(uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
//问题2,DefWindowProc是对消息的默认处理,但是为什么把以下语句屏蔽掉以后,会导致截取不到消息WM_MYMESSAGE呢?
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
请大家回答以上问题。谢谢!

解决方案 »

  1.   

    1。GetMessage是提取消息队列里面的消息的,当用SendMessage给窗口发消息的时候并不进消息队列,而是直接调用窗口过程WinSunProc;
    2。你可以自己处理WM_MYMESSAGE,否则就要调用DefWindowProc交由OS处理,如果这两个都没有的话,就不会处理你的消息了。
      

  2.   

    问题1:你是用 SendMessage(hwnd, WM_MYMESSAGE, 1, 1);
    用SendMessage前你必须知道它是不进入消息队列的,也就是说不进入GetMessage。
    为什么WinSunProc还是截获到其它消息呢?看一下GetMessage的原型。
    BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax)
    而你这样写GetMessage(&msg,hwnd,WM_MYMESSAGE,WM_MYMESSAGE)其实就是截获这条消息WM_MYMESSAGE,而你会觉得是其它消息。
    另外, SendMessage(hwnd, WM_MYMESSAGE, 1, 1);其实就跑进了WinSunProc。但是WinSunProc又没有定义这条消息过程,因此,它只能交给操作系统默认处理函数了。
    这也是为什么你把default:return DefWindowProc(hwnd,uMsg,wParam,lParam);屏蔽掉会导致截取不到消息WM_MYMESSAGE,其实是截获得到的,只是没有得到相应的函数处理,OK!回答了你第二个问题。
      

  3.   

    请问WinSunProc中,判断截获的是什么消息,不是用参数uMsg判断吗?WM_MYMESSAGE的值是1124,但是为什么我发现其他值了?谢谢大家!
      

  4.   

    //问题1.以下语句过滤出WM_MYMESSAGE,但为什么WinSunProc还是截获到其它消息呢?
    =======================
    有些消息确实是不进入消息队列的,所以WinSunProc能处理别的消息也是有可能的。比如用SendMessage发送一个消息,它就是直接调用WinSunProc,而不是由GetMessage去得到消息而触发WinSunProc的。
      

  5.   

    //问题2,DefWindowProc是对消息的默认处理,但是为什么把以下语句屏蔽掉以后,会导致截取不到消息WM_MYMESSAGE呢?
    =========================
    屏蔽了它之后你的消息因为没有处理而直接被忽略了。
      

  6.   

    endMessage发送一个消息,它就是直接调用WinSunProc,而不是由GetMessage去得到消息而触发WinSunProc的。
    ------------------------
    学习了
      

  7.   


    你查看msdn里,对每个消息的解释,它会解释消息会被Send到窗口还是Post到窗口。如下:
    WM_LBUTTONDOWN message
    Posted when the user presses the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
    (注意解释里说的是Posted)WM_ACTIVATE message
    Sent to both the window being activated and the window being deactivated. If the windows use the same input queue, the message is sent synchronously, first to the window procedure of the top-level window being deactivated, then to the window procedure of the top-level window being activated. If the windows use different input queues, the message is sent asynchronously, so the window is activated immediately. 
    (注意解释里说的是Sent to)
    这个其实很重要的,但很多人都忽略这个问题。
    PostMessage会进入消息队列。
    Send的消息会直接调用窗口过程函数。