2017-07-22 2 views
0

J'ai une fonction de rappel:un message WINAPI- WM_QUIT pas envoyé

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); 
} 

Cependant, « Fermer ou se Détruit » est pas imprimé lorsque je clique sur le bouton X ou appuyez sur Alt + F4. Enfait, je suis incapable de déplacer la fenêtre par la souris!

Quelques autres fonctions:

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 est mon objet pour la mise en œuvre de la fenêtre. initWindow() et run() sont appelés une seule fois respectivement. La classe complète si vous voulez:

#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); 
} 

Voici comment il est mis en œuvre:

#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; 
} 

Répondre

2

!PeekMessage est faux, si elle renvoie une valeur non-zéro, vous avez un message que vous devez gérer.

+0

Oui, ça a marché! Je vous remercie! –