这种说法是正确的,SendMessage和PostMessage就是这样工作的,另外默认的循环队列大小为10000条整,可以通过修改注册表来修改默认队列大小。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\
找到USERPostMessageLimit 项。可以通过修改该值来改变消息队列的容量,重启后生效。

解决方案 »

  1.   


    SendMessage 是阻塞的,有些场景是不适合的
      

  2.   


    我说的是SendNotifyMessage,不是SendMessageSendNotifyMessage将消息发送到一个可自扩充的队列中,而PostMessage将消息发送到系统的消息队列中,你上面说的修改注册表的方法,只对PostMessage起作用.我想确认的是,在异步模式下,SendnotifyMessage是否不会丢失消息?
      

  3.   

    SendNotifyMessage怎么都不会丢消息,如有疑虑,可以写代码测试,比如:#include <Windows.h>
    #include <process.h>
    #include <iostream>
    using namespace std;#define WM_MY_MESSAGE (WM_USER + 1)
    #define WM_RUBBISH_MESSAGE (WM_USER + 2)LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM IParam) 
    {
    //尽管是在消息队列被填满后,新开线程SendNotifyMessage发送的WM_MY_MESSAGE最终仍然能收到
    //并在此弹出MessageBox
    if (message == WM_MY_MESSAGE)
    MessageBox(NULL, L"收到啦!", L"提示", MB_OK);
    else if (message == WM_DESTROY)
    PostQuitMessage(0);
    return DefWindowProc(hwnd,message,wParam,IParam);
    }void Thread(void *p)
    {
    HWND hwnd = reinterpret_cast<HWND>(p);
    BOOL b = SendNotifyMessage(hwnd, WM_MY_MESSAGE, NULL, NULL);
    }int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
    {
    static TCHAR szAppName[]=TEXT("Test!");
    HWND hwnd;
    WNDCLASS wndclass = {NULL};
    wndclass.lpfnWndProc = WndProc;
    wndclass.style = CS_HREDRAW|CS_VREDRAW;
    wndclass.lpszClassName = szAppName;
    wndclass.hInstance = hInstance;
    wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    RegisterClass(&wndclass);
    hwnd = CreateWindow(szAppName, L"The Test Program", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 
    0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    ShowWindow(hwnd,SW_SHOW);
    UpdateWindow(hwnd);
    //放入5万个垃圾消息,把消息队列填满
    for (int i = 0; i < 50000; i++)
    PostMessage(hwnd, WM_RUBBISH_MESSAGE, NULL, NULL);
    //启动线程,用SendNotifyMessage放一个WM_MY_MESSAGE消息
    _beginthread(Thread, NULL, hwnd);
    //等一下,确保线程运行完毕
    Sleep(3000);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    }
      

  4.   

    GetMessage永远都取不到SendNotifyMessage发送的消息,就是说SendNotifyMessage发送的消息怎么都不会进循环队列,自然也不会受循环队列满不满的影响。另一方面SendNotifyMessage既然返回TRUE,那么就意味着消息肯定能送达目标窗口过程,不然这个API就出歧义了,明明TRUE还发失败了,岂不是就出BUG了。如果还不放心,可以用windbg或od调试一下看看SendNotifyMessage内部究竟做了什么。
      

  5.   

    Multiple Threads in the User Interface http://msdn.microsoft.com/zh-cn/library/ms810439.aspx
      

  6.   

    File: C:\windows_2000_source_code\win2k\private\ntos\w32\ntuser\kernel\ntstubs.c
       5599: BOOL NtUserSendNotifyMessage(  // API SendNotifyMessageA/W
       5600:     IN HWND hwnd,
       5601:     IN UINT Msg,
       5602:     IN WPARAM wParam,
       5603:     IN LPARAM lParam OPTIONAL)
       5604: {
       5605:     PWND pwnd;
       5606:     TL tlpwnd;
       5607:     LARGE_STRING strLParam;
       5608: 
       5609:     BEGINRECV(BOOL, FALSE);
       5610: 
       5611:     /*
       5612:      * Prevent apps from setting hi 16 bits so we can use them internally.
       5613:      */
       5614:     if (Msg & MSGFLAG_MASK) {
       5615:         RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid message");
       5616:         MSGERROR(0);
       5617:     }
       5618: 
       5619:     if ((Msg == WM_WININICHANGE || Msg == WM_DEVMODECHANGE) &&
       5620:             ARGUMENT_PRESENT(lParam)) {
       5621:         try {
       5622:             strLParam = ProbeAndReadLargeString((PLARGE_STRING)lParam);
       5623:             ProbeForReadUnicodeStringBuffer(strLParam);
       5624:             lParam = (LPARAM)&strLParam;
       5625:         } except (StubExceptionHandler(TRUE)) {
       5626:             MSGERROR(0);
       5627:         }
       5628:     }
       5629: 
       5630:     ValidateHWNDFF(pwnd, hwnd);
       5631: 
       5632:     if (pwnd != PWND_BROADCAST)
       5633:         ThreadLockAlways(pwnd, &tlpwnd);
       5634: 
       5635:     retval = xxxSendNotifyMessage(
       5636:             pwnd,
       5637:             Msg,
       5638:             wParam,
       5639:             lParam );
       5640: 
       5641:     if (pwnd != PWND_BROADCAST)
       5642:         ThreadUnlock(&tlpwnd);
       5643: 
       5644:     TRACE("NtUserSendNotifyMessage");
       5645:     ENDRECV();
       5646: }