如下面的代码所示,对于自定义消息 WM_TESTMSG 处理程序,它调用 SendMessage 来发送相同的消息。我认为将会有一个 Stack Overflow异常并且 MessageBeep 将不会被调用,因为SendMessage将直接调用WindowProc。但是当我测试代码时,它运行良好! 为什么没有例外?谢谢!
#include <Windows.h>
#define WM_TESTMSG (WM_USER + 0x100)
LRESULT CALLBACK MainWndProc(IN HWND hWnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
{
LRESULT ret = 0;
switch (uMsg)
{
case WM_CREATE:
{
PostMessage(hWnd, WM_TESTMSG, 0, 0);
break;
}
case WM_TESTMSG:
{
SendMessage(hWnd, WM_TESTMSG, 0, 0);
MessageBeep(MB_ICONERROR); // I think the program can't run to here
break;
}
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
{
ret = ::DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
}
return ret;
}
BOOL RegisterWndClass(IN HINSTANCE hInstance)
{
WNDCLASSEX wndClassEx;
ZeroMemory(&wndClassEx, sizeof(wndClassEx));
wndClassEx.cbSize = sizeof (wndClassEx);
wndClassEx.style = CS_HREDRAW | CS_VREDRAW;
wndClassEx.lpfnWndProc = MainWndProc;
wndClassEx.cbClsExtra = 0;
wndClassEx.cbWndExtra = 0;
wndClassEx.hInstance = hInstance;
wndClassEx.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_HAND));
wndClassEx.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
wndClassEx.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
wndClassEx.lpszMenuName = NULL;
wndClassEx.lpszClassName = TEXT("MyMainWnd");
wndClassEx.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ERROR));
return ::RegisterClassEx(&wndClassEx);
}
int WINAPI WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
RegisterWndClass(hInstance);
HWND hMainWnd = CreateWindowEx(0, L"MyMainWnd", L"MainWnd", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, 0, hInstance, 0);
ShowWindow(hMainWnd, SW_SHOWNORMAL);
UpdateWindow(hMainWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}