发布WM_QUIT消息的内容
What posts the WM_QUIT message?
我刚刚开始学习NeHe的OpenGl教程,我已经编写了第一个教程中的所有代码。该程序没有按照我希望的方式运行,所以我开始调试它,发现某处发布了一条WM_QUIT消息。
我没有将其发布在"案例关闭"以外的任何地方(这永远不会发生,我没有走那么远)。
所以我只是想知道,什么可以发布WM_QUIT消息。我对 c++ 不是很熟悉,但我以前做过很多 java。
提前感谢,对不起我的英语不好。
法典:
#include <Windows.h>
#include <glGL.h>
#include <glGLU.h>
#include <glaux.h>
#include <iostream>
// Window/Rendering vars
HGLRC hRC = NULL; // Handle to the rendering context
HDC hDC = NULL; // Handle to Device context
HWND hWnd = NULL; // Handle to the Window
HINSTANCE hInstance = NULL; // Handle to a instance of the application
bool active = true; // Is window active
bool fullscreen = true; // Is window fullscreen
bool keys[256]; // Array for keypresses
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration of the window procedure
GLvoid ResizeGLScene(GLsizei width, GLsizei height) //resize and initialize GL window
{
if(height == 0)
{
height = 1;
}
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); // Code after this will affect the projection matrix
glLoadIdentity(); // Reset the current matrix(projection)
gluPerspective(45.0f, width/height, 0.1f, 100.0f); // setting the perspective and calculating aspect ratio
glMatrixMode(GL_MODELVIEW); // Code after this will affect the modelview matrix
glLoadIdentity(); // Reset the current matrix(modelview)
}
int InitGL(GLvoid) //Setup and initialize openGL
{
glShadeModel(GL_SMOOTH); //Set shademodel to smooth shading
glClearColor(1.0f, 0.5f, 0.5f, 0.0f); //set the screen default color rgb
glClearDepth(1.0f); // set default depth to 1 and setup
glEnable(GL_DEPTH_TEST); // Enables depth test
glDepthFunc(GL_LEQUAL); // indicates the type of depth test
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // nicest perspective calculations
return true;
}
int DrawGLScene(GLvoid) //DRAWING
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // set the screen to the clear color and clears the depth buffer
glLoadIdentity();
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(100, 200);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(200, 200);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(200, 100);
glColor3f(0.0f, 0.0f, 0.0f);
glVertex2f(100, 100);
glEnd();
return true;
}
GLvoid KillGLWindow(GLvoid)
{
if(fullscreen) // is fuulscreen active
{
ChangeDisplaySettings(NULL, 0); // use default displaysetting(no fullscreen)
ShowCursor(true);
}
if(hRC) // is a rendering context present?
{
if(!wglMakeCurrent(NULL, NULL)) // can device context and rendering context be released?
{
MessageBox(NULL, "Couldn't Release DC And RC", "Shutdown Error", MB_OK | MB_ICONINFORMATION);
}
if(!wglDeleteContext(hRC)) // can rendering context be deleted
{
MessageBox(NULL, "Couldn't Release DC And RC", "Shutdown Error", MB_OK | MB_ICONINFORMATION);MessageBox(NULL, "Couldn't Delete Rendering Context", "Shutdown Error", MB_OK | MB_ICONINFORMATION);
}
hRC = NULL;
}
if(hDC && !ReleaseDC(hWnd, hDC)) // Can device context be released
{
MessageBox(NULL, "Couldn't Release Device Context", "Shutdown Error", MB_OK | MB_ICONINFORMATION);
}
if(hWnd && !DestroyWindow(hWnd)) // can window be destroyed
{
MessageBox(NULL, "Couldn't destroy window handle", "Shutdown Error", MB_OK | MB_ICONINFORMATION);
hWnd = NULL;
}
if(!UnregisterClass("OpenGL", hInstance))
{
MessageBox(NULL, "Couldn't Unregister Class", "Shutdown Error", MB_OK | MB_ICONINFORMATION);
hInstance = NULL;
}
}
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat;
WNDCLASS wc;
DWORD dwExStyle; //Window Extended Style
DWORD dwStyle; //Window Style
RECT WindowRect;
WindowRect.left = 0;
WindowRect.right = width;
WindowRect.top = 0;
WindowRect.bottom = height;
fullscreen = fullscreenflag;
hInstance = GetModuleHandle(NULL);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
if(!RegisterClass(&wc))
{
MessageBox(NULL, "Couldn't Register The Window Class", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(fullscreen)
{
DEVMODE dmScreenSettings; //Device Mode
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsHeight = width;
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
if(MessageBox(NULL, "Fullscreen mode not supported by Graphics Card. Do you want to use windowed mode?", "OpenGL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
{
fullscreen = false;
}
else
{
MessageBox(NULL, "Program is closing.", "CLOSING", MB_OK | MB_ICONSTOP);
return false;
}
}
}
if(fullscreen)
{
dwExStyle = WS_EX_APPWINDOW;
dwStyle = WS_POPUP;
ShowCursor(false);
}
else
{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle = WS_OVERLAPPEDWINDOW;
}
AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle);
if(!(hWnd = CreateWindowEx(dwExStyle,
"OpenGL",
title,
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN |
dwStyle,
0, 0,
WindowRect.right - WindowRect.left,
WindowRect.bottom - WindowRect.top,
NULL,
NULL,
hInstance,
NULL)))
{
KillGLWindow();
MessageBox(NULL, "Window creation error", "Error", MB_OK | MB_ICONEXCLAMATION);
return false;
}
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
bits,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
if(!(hDC = GetDC(hWnd)))
{
KillGLWindow();
MessageBox(NULL, "Can't create a Gl Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))
{
KillGLWindow();
MessageBox(NULL, "Couldn't find the rigth pixelformat", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(!SetPixelFormat(hDC, PixelFormat, &pfd))
{
KillGLWindow();
MessageBox(NULL, "Couldn't set pixelformat", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(!(hRC = wglCreateContext(hDC)))
{
KillGLWindow();
MessageBox(NULL, "Can't create a Gl rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(!wglMakeCurrent(hDC, hRC))
{
KillGLWindow();
MessageBox(NULL, "Can't activate a Gl rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
ResizeGLScene(width, height);
if(!InitGL())
{
KillGLWindow();
MessageBox(NULL, "GL Initialization Failed", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return false;
}
return true;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_ACTIVATE:
{
if(!HIWORD(wParam))
{
active = true;
}
else
{
active = false;
}
return 0;
}
case WM_SYSCOMMAND:
{
switch(wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
break;
}
case WM_CLOSE:
{
std::cout << "Close" << std::endl;
PostQuitMessage(0);
return 0;
}
case WM_KEYDOWN:
{
keys[wParam] = true;
return 0;
}
case WM_KEYUP:
{
keys[wParam] = false;
return 0;
}
case WM_SIZE:
{
ResizeGLScene(LOWORD(lParam), HIWORD(lParam));
return 0;
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
bool done = false;
if(MessageBox(NULL, "Run application in fullscreen mode?", "Initate Fullscreen", MB_YESNO | MB_ICONQUESTION) == IDNO)
{
fullscreen = false;
}
if(!CreateGLWindow("NeHe's OpenGl Framework", 800, 600, 16, fullscreen))
{
MessageBox(NULL, "framwork failed", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return 0;
}
while(!done)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message = WM_QUIT)
{
std::cout << "EXIT" << std::endl;
done = false;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
std::cout << "Translate and Dispatch Msg" << std::endl;
}
}
else
{
if(active)
{
if(keys[VK_ESCAPE])
{
done = true;
}
else
{
DrawGLScene();
SwapBuffers(hDC);
}
}
if(keys[VK_F1])
{
keys[VK_F1] = false;
KillGLWindow();
fullscreen =! fullscreen;
if(!CreateGLWindow("NeHe's OpenGL Framework", 800, 600, 16, fullscreen))
{
return 0;
}
}
}
}
KillGLWindow();
return (msg.wParam);
}
在这个程序的情况下,将消息设置为WM_QUIT
的事情是这样的:
if(msg.message = WM_QUIT)
您不小心将消息设置为 WM_QUIT
,而不是使用 ==
来测试该值,并且由于操作的结果是非零值,因此它始终计算 true 部分。换句话说,一旦它收到一条消息,它就会终止,而不是抽取消息循环。
如果将该行更改为:
if(msg.message == WM_QUIT)
然后它进行测试,而不是分配值,并且应该正常工作。
通常,使用完整警告进行编译会指出这一点。
来自 MSDN 文档:
WM_QUIT消息
指示终止应用程序的请求,并在应用程序调用 PostQuitMessage 函数时生成。此消息会导致 GetMessage 函数返回零。
相关文章:
- boost::进程间消息队列引发错误
- 在线编译器中的分段C++没有打印消息
- C++错误消息*成员参考.**初学者*
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- C++quit()函数中可能存在作用域问题
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何通过参数抛出错误消息
- 从服务器传输到客户端的消息不会出现
- ROS2 动态消息模板
- C++秘密消息学校作业
- glad 导致 glfwSwapBuffers 返回错误消息
- C++入门 5 版:类消息和文件夹
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- Boost.TEST with CLion: "Test framework quit unexpectedly"
- 由于无效的 ValidateRgn() 子窗口不会收到WM_PAINT消息
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- 重新定义预定义的 errno 错误消息 (E2BIG)