我有一个回调函数:
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if(msg == WM_DESTROY || msg == WM_CLOSE) {
std::cout << "Close or get DESTROYED!\n";
}
if(g_mApp)
return g_mApp->MsgProc(hwnd, msg, wParam, lParam);
else
return DefWindowProc(hwnd, msg, wParam, lParam);
}
然而,&#34;关闭或被摧毁&#34;单击X按钮或按Alt + F4时不打印。事实上,我无法通过鼠标移动窗口!
其他一些功能:
int GLApp::run() {
__int64 prevTime = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&prevTime);
__int64 countsPerSec = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&countsPerSec);
float secondsPerCount = 1.0f / countsPerSec;
MSG msg = {0};
while(msg.message != WM_QUIT) {
if(!PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
__int64 curTime = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&curTime);
float deltaTime = (curTime - prevTime) * secondsPerCount;
update(deltaTime);
render();
calculateFPS(deltaTime);
prevTime = curTime;
}
}
shutdown();
return static_cast<int>(msg.wParam);
}
bool GLApp::initWindow() {
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hInstance = m_hAppInstance;
wcex.lpfnWndProc = MainWndProc;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wcex.lpszClassName = "GLAPPWNDCLASS";
wcex.lpszMenuName = NULL;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex)) {
return outErrorMessage("Failed to register GLAPPWNDCLASS");
}
// ADJUST WINDOW RECT FOR REQUESTED CLIENT SIZE
RECT r;
r.left = r.top = 0;
r.right = m_ClientWidth;
r.bottom = m_ClientHeight;
AdjustWindowRect(&r, m_WindowStyle, FALSE);
int width = r.right - r.left;
int height = r.bottom - r.top;
int x = GetSystemMetrics(SM_CXSCREEN)/2 - width / 2;
int y = GetSystemMetrics(SM_CYSCREEN)/2 - height / 2;
m_hAppWnd = CreateWindow("GLAPPWNDCLASS", m_AppTitle, m_WindowStyle, x, y, width, height, NULL, NULL, m_hAppInstance, NULL);
if(!m_hAppWnd) return outErrorMessage("Failed to create window from GLAPPWNDCLASS");
ShowWindow(m_hAppWnd, SW_SHOW);
return true;
}
g_mApp是我自己的实现窗口的对象。 initWindow()
和run()
仅分别调用一次。全班,如果你愿意:
#include "GLApp.h"
#include <iostream>
namespace {
GLApp* g_mApp = NULL;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if(msg == WM_DESTROY || msg == WM_CLOSE) {
std::cout << "Close or get DESTROYED!\n";
}
if(g_mApp)
return g_mApp->MsgProc(hwnd, msg, wParam, lParam);
else
return DefWindowProc(hwnd, msg, wParam, lParam);
}
GLApp::GLApp(void)
{
}
GLApp::GLApp(HINSTANCE hInstance) {
m_hAppInstance = hInstance;
m_hAppWnd = NULL;
m_hDevContext = NULL;
m_hGLRenderContext = NULL;
m_ClientWidth = 800;
m_ClientHeight = 600;
m_AppTitle = "OpenGL Application";
m_WindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX;
m_FPS = 0.0f;
g_mApp = this;
}
GLApp::~GLApp()
{
}
int GLApp::run() {
__int64 prevTime = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&prevTime);
__int64 countsPerSec = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&countsPerSec);
float secondsPerCount = 1.0f / countsPerSec;
MSG msg = {0};
while(msg.message != WM_QUIT) {
if(!PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
__int64 curTime = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&curTime);
float deltaTime = (curTime - prevTime) * secondsPerCount;
update(deltaTime);
render();
calculateFPS(deltaTime);
prevTime = curTime;
}
}
shutdown();
return static_cast<int>(msg.wParam);
}
bool GLApp::init() {
return initWindow() && initGL();
}
bool GLApp::initWindow() {
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.hInstance = m_hAppInstance;
wcex.lpfnWndProc = MainWndProc;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wcex.lpszClassName = "GLAPPWNDCLASS";
wcex.lpszMenuName = NULL;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex)) {
return outErrorMessage("Failed to register GLAPPWNDCLASS");
}
// ADJUST WINDOW RECT FOR REQUESTED CLIENT SIZE
RECT r;
r.left = r.top = 0;
r.right = m_ClientWidth;
r.bottom = m_ClientHeight;
AdjustWindowRect(&r, m_WindowStyle, FALSE);
int width = r.right - r.left;
int height = r.bottom - r.top;
int x = GetSystemMetrics(SM_CXSCREEN)/2 - width / 2;
int y = GetSystemMetrics(SM_CYSCREEN)/2 - height / 2;
m_hAppWnd = CreateWindow("GLAPPWNDCLASS", m_AppTitle, m_WindowStyle, x, y, width, height, NULL, NULL, m_hAppInstance, NULL);
if(!m_hAppWnd) return outErrorMessage("Failed to create window from GLAPPWNDCLASS");
ShowWindow(m_hAppWnd, SW_SHOW);
return true;
}
bool GLApp::initGL() {
// CREATE OUR DEVICE CONTEXT
m_hDevContext = GetDC(m_hAppWnd);
// CREATE PIXEL FORMAT DESCRIPTOR
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
int format = ChoosePixelFormat(m_hDevContext, &pfd);
if(!SetPixelFormat(m_hDevContext, format, &pfd)) {
return outErrorMessage("Failed to set pixel format");
}
// CREATE RENDER CONTEXT
m_hGLRenderContext = wglCreateContext(m_hDevContext);
if(!wglMakeCurrent(m_hDevContext, m_hGLRenderContext)) {
return outErrorMessage("Failed to create and activate render context");
}
// INITIALIZE GLEW
if(glewInit() != GLEW_OK) {
return outErrorMessage("Failed to initialize GLEW");
}
return true;
}
LRESULT GLApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CLOSE: {
DestroyWindow(hwnd);
return 0;
}
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
void GLApp::calculateFPS(float dt) {
}
void GLApp::shutdown() {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hGLRenderContext);
ReleaseDC(m_hAppWnd, m_hDevContext);
}
这是如何实施的:
#include "GLApp.h"
#include <iostream>
class TestApp : public GLApp {
public:
TestApp(HINSTANCE hInstance);
~TestApp();
// OVERRIDES
bool init() override;
void update(float dt) override;
void render() override;
LRESULT MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) override;
};
TestApp::TestApp(HINSTANCE hInstance) : GLApp(hInstance) {
}
TestApp::~TestApp() {}
bool TestApp::init() {
return GLApp::init();
}
void TestApp::update(float dt) {
}
void TestApp::render() {
}
LRESULT TestApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
default:
return GLApp::MsgProc(hwnd, msg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nCmdShow) {
TestApp app(hInstance);
if(!app.init()) {
return 1;
}
return app.run();
}
bool outErrorMessage(const char* message) {
MessageBox(NULL, message, NULL, MB_OK);
return false;
}
答案 0 :(得分:2)
!PeekMessage
错误,如果它返回非零,则会收到您需要处理的消息。