我有一个小问题。 我先给你看一个例子,然后我会告诉你问题出在哪里。
示例:
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
该示例工作正常,但如果“GetMessage”函数中的参数 2 更改为窗口句柄名称,如下所示:
示例2:更改后
while(GetMessage(&msg, Hwnd, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
退出程序时会出现一点问题。 该程序仍然在进程列表中运行。 并且需要选择它然后单击结束进程按钮来终止程序
现在,add(NULL 或窗口句柄)之间有区别吗?
您在第二个示例中遇到的问题是,在您的窗口被销毁后,您提供给
GetMessage()
的窗口句柄不再有效。 随后的每个调用都会返回一个错误来通知您(使用 GetLastError()
给出 ERROR_INVALID_WINDOW_HANDLE
),但代码不处理这种情况,因此最终会永远处于繁忙循环中。
这就是为什么 MSDN 库页面的
GetMessage()
建议不要使用 while (GetMessage(...))
。
您提供的两个示例之间的根本区别在于应用程序处理消息的方式。第一个示例将从消息队列中为您可能在应用程序中创建的任何窗口提取消息。后面的示例将仅从与传递给函数的句柄关联的窗口中提取消息。您可能会在应用程序中创建许多窗口。如果您只对捕获特定窗口的消息感兴趣,则该参数将用于限制转换并分派到窗口过程函数的消息。但是,如果您计划仅创建一个窗口,则差异可以忽略不计。
有两种方法可以解决这个问题:
1- 将
NULL
值传递给 GetMessage
函数而不是窗口。手柄。
GetMessage(&msg, NULL, 0, 0)
2- 因为返回值可以是非零、零或-1,所以如果 hWnd 是无效参数(例如引用已被销毁的窗口),则返回 -1 的可能性意味着此类代码可能导致致命的应用程序错误。相反,请使用这样的代码。
BOOL gmRet;
while ((gmRet = GetMessage(&msg, hWnd, 0, 0)) != 0) {
if (gmRet == -1) {
return 0;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}