PeekMessage 收不到消息?
我创建了一个自定义消息类型,用于调整 Window
的大小,称为 WM_NEED_RESIZE
。我已在 .h 文件中定义它,并在 .cpp 文件中初始化。我还注册了我的 WindowProc 函数来接受消息。以下是这些项目的代码:
const uint32 WindowsGLWindow::WM_NEED_RESIZE = WM_USER + 100;
LONG WINAPI WindowsGLWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;// do I need this?
static sint32 newWidth = 0;
static sint32 newHeight = 0;
bool res = false;
switch (uMsg) {
case WM_PAINT:
//display();
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_SIZE:
//glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
res = PostMessage(hWnd, WindowsGLWindow::WM_NEED_RESIZE, wParam, lParam);
std::cout << "WM_SIZE: " << res << std::endl;
return 0;
case WindowsGLWindow::WM_NEED_RESIZE:
std::cout << "WindowsGLWindow::WM_NEED_RESIZE" << std::endl;
break;
case WM_CHAR:
switch (wParam) {
case 27: /* ESC key */
PostQuitMessage(0);
break;
}
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
在另一个函数中,我运行 PeekMessage(..)
来收集所有消息。以下是消息泵的片段:
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) == TRUE) // maybe use GetInputState(?) as well?
{
if (msg.message == WM_QUIT)
retVal = -1;
if (msg.message == WindowsGLWindow::WM_NEED_RESIZE) {
uint32 newWidth = LOWORD(msg.lParam);
uint32 newHeight = HIWORD(msg.lParam);
std::cout << "PeekMessage: WindowsGLWindow::WM_NEED_RESIZE" << std::endl;
// call resize only if our window-size changed
if ((newWidth != width_) || (newHeight != height_)) {
resize(newWidth, newHeight);
}
PostMessage(msg.hwnd, WM_PAINT, 0, 0);
}
switch (msg.message) {
case WM_MOUSEMOVE:
// Retrieve mouse screen position
//int x = (short) LOWORD(lParam);
//int y = (short) HIWORD(lParam);
// Check to see if the left button is held down:
//bool leftButtonDown = wParam & MK_LBUTTON;
// Check if right button down:
//bool rightButtonDown = wParam & MK_RBUTTON;
break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_KEYUP:
case WM_KEYDOWN:
/*
switch (msg.wParam) {
case 'W':
// w key pressed
break;
case VK_RIGHT:
// Right arrow pressed
break;
default:
break;
}
*/
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
我的问题是,当窗口首次打开时,WM_NEED_RESIZE
消息仅在消息队列中找到一次,之后就再也找不到了通过我的 PeekMessage(..)
在消息队列中。我真的不知道为什么会发生这种情况。然而,它被 WindowProc(..)
方法接收(这对我没有真正的帮助)。我将不胜感激你们能提供的任何帮助。
谢谢贾勒特
I've created a custom message type for use in resizing my Window
, called WM_NEED_RESIZE
. I've defined it in my .h file, and initialized in my .cpp file. I have also registered my WindowProc
function to accept messages. Here is the code for these items:
const uint32 WindowsGLWindow::WM_NEED_RESIZE = WM_USER + 100;
LONG WINAPI WindowsGLWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;// do I need this?
static sint32 newWidth = 0;
static sint32 newHeight = 0;
bool res = false;
switch (uMsg) {
case WM_PAINT:
//display();
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_SIZE:
//glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
res = PostMessage(hWnd, WindowsGLWindow::WM_NEED_RESIZE, wParam, lParam);
std::cout << "WM_SIZE: " << res << std::endl;
return 0;
case WindowsGLWindow::WM_NEED_RESIZE:
std::cout << "WindowsGLWindow::WM_NEED_RESIZE" << std::endl;
break;
case WM_CHAR:
switch (wParam) {
case 27: /* ESC key */
PostQuitMessage(0);
break;
}
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
In another function I am running through PeekMessage(..)
to collect all messages. Here is the snippet of the message pump:
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) == TRUE) // maybe use GetInputState(?) as well?
{
if (msg.message == WM_QUIT)
retVal = -1;
if (msg.message == WindowsGLWindow::WM_NEED_RESIZE) {
uint32 newWidth = LOWORD(msg.lParam);
uint32 newHeight = HIWORD(msg.lParam);
std::cout << "PeekMessage: WindowsGLWindow::WM_NEED_RESIZE" << std::endl;
// call resize only if our window-size changed
if ((newWidth != width_) || (newHeight != height_)) {
resize(newWidth, newHeight);
}
PostMessage(msg.hwnd, WM_PAINT, 0, 0);
}
switch (msg.message) {
case WM_MOUSEMOVE:
// Retrieve mouse screen position
//int x = (short) LOWORD(lParam);
//int y = (short) HIWORD(lParam);
// Check to see if the left button is held down:
//bool leftButtonDown = wParam & MK_LBUTTON;
// Check if right button down:
//bool rightButtonDown = wParam & MK_RBUTTON;
break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_KEYUP:
case WM_KEYDOWN:
/*
switch (msg.wParam) {
case 'W':
// w key pressed
break;
case VK_RIGHT:
// Right arrow pressed
break;
default:
break;
}
*/
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
My problem is that the WM_NEED_RESIZE
message is only found once in the message queue when the window first opens, after which it is never found in the message queue by my PeekMessage(..)
. I'm really not sure why this is happening. It is, however, being received by the WindowProc(..)
method (which doesn't really help me). I would appreciate any help you guys could provide.
Thanks
Jarrett
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不要使用 std::cout 期望在调试器中看到该输出,而是使用 OutputDebugString(); 。
您需要将类指针传递给 CreateWindowEx 调用的最后一个参数,然后从 WM_CREATE 的 LPARAM 中传递给您的 LPCREATESTRUCT 中检索该指针,您的类指针将位于该结构的 lpCreateParmas 字段中。将您的 class 指针设置为窗口的 GWLP_USERDATA ,并在任何其他消息调用中,调用 GetWindowsLong ,检索您的类指针,然后将消息、wparam 和 lparam 全部传递给您的内部类消息处理程序。
http://msdn.microsoft.com/en -us/library/ff381400%28v=VS.85%29.aspx
Dont use std::cout expecting to see that output in your debugger, insted use OutputDebugString(); .
You need to pass your class pointer to the last parameter of your call to CreateWindowEx, then retrieve that pointer from the LPCREATESTRUCT passed to you in the LPARAM of WM_CREATE, your class pointer will be in the lpCreateParmas feild of the struct. Set your clas pointer to the GWLP_USERDATA of your window, and on any other message calls , call GetWindowsLong , retrieve your class pointer, then pass the message, wparam, and lparam all off to your internal class message handler.
http://msdn.microsoft.com/en-us/library/ff381400%28v=VS.85%29.aspx
一旦队列为空,您显示的消息泵循环就会退出。我无法从您发布的内容判断它是否再次被输入。
如果这是您的主要消息泵,您应该使用 相反,GetMessage(),因为它会等到有可用的内容后再返回。请查看这篇 MSDN 文章 了解更多信息。
The message pump loop that you are showing will exit as soon as the queue is empty. I can't tell from what you've posted if it ever gets entered again.
If this is your main message pump, you should use GetMessage() instead, as it will wait until something is available before returning. Take a look at this MSDN article for more info.