这种说法是正确的,SendMessage和PostMessage就是这样工作的,另外默认的循环队列大小为10000条整,可以通过修改注册表来修改默认队列大小。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\
找到USERPostMessageLimit 项。可以通过修改该值来改变消息队列的容量,重启后生效。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\
找到USERPostMessageLimit 项。可以通过修改该值来改变消息队列的容量,重启后生效。
SendMessage 是阻塞的,有些场景是不适合的
我说的是SendNotifyMessage,不是SendMessageSendNotifyMessage将消息发送到一个可自扩充的队列中,而PostMessage将消息发送到系统的消息队列中,你上面说的修改注册表的方法,只对PostMessage起作用.我想确认的是,在异步模式下,SendnotifyMessage是否不会丢失消息?
#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);
}
}
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: }