Question

I'm trying to create a simple OpenGL window in C, but I'm having problems with the window itself. A window is created, and then it suddenly disappears. I fixed this by zeroing "msg" but then the window still tries to exit and all other messages aren't passed. So I can't exit by pressing escape (WM_KEYDOWN isn't passed). Rendering the graphics works like it should. Does anyone know what causes this, and how to fix it?

entrypoint.c

#include "main.h"
#include "graphics.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    int breedte, hoogte;
    DEVMODE dmScreenSettings;
    HWND hWnd;
    WNDCLASSEX wcex;
    MSG msg;

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wcex.lpfnWndProc = Actie;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
    wcex.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"WinClass";
    wcex.hIconSm = NULL;
    breedte = GetSystemMetrics(SM_CXSCREEN);
    hoogte = GetSystemMetrics(SM_CYSCREEN);
    RegisterClassEx(&wcex);

    // Tijdelijk "nep" venster maken
    hWnd = CreateWindowEx(WS_EX_APPWINDOW, L"WinClass", L"My Window", WS_POPUP,
        0, 0, 640, 480, NULL, NULL, hInstance, NULL);
    if(hWnd == NULL) {
        MessageBox(NULL, L"Error: er kon geen venster worden gemaakt.", L"ERROR", MB_OK);
        return -1;
    }

    if (InitializeExtensions(hWnd) != 0) {
        MessageBox(NULL, L"Error: OpenGL extensies konden niet worden geladen.", L"ERROR", MB_OK);
        return -1;
    }

    // Tijdelijk venster verwijderen
    DestroyWindow(hWnd);

    if (FULLSCREEN == 1) {
        memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
        dmScreenSettings.dmSize       = sizeof(dmScreenSettings);
        dmScreenSettings.dmPelsWidth  = (unsigned long)breedte;
        dmScreenSettings.dmPelsHeight = (unsigned long)hoogte;
        dmScreenSettings.dmBitsPerPel = 32;         
        dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
        ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
        hWnd = CreateWindowEx(WS_EX_APPWINDOW, L"WinClass", L"My Window", WS_POPUP, 
            0, 0, breedte, hoogte, NULL, NULL, hInstance, NULL);
    }
    else {
        hWnd = CreateWindowEx(WS_EX_APPWINDOW, L"WinClass", L"My Window", WS_POPUP,  
            (breedte / 4), (hoogte / 4), (breedte / 2), (hoogte / 2), NULL, NULL, hInstance, NULL);
        breedte /= 2;
        hoogte /= 2;
    }

    if(hWnd == NULL) {
        MessageBox(NULL, L"Error: er kon geen venster worden gemaakt.", L"ERROR", MB_OK);
        return -1;
    }

    if (InitializeOpenGL(hWnd, breedte, hoogte, SCREEN_DEPTH, SCREEN_NEAR, VSYNC) != 0) {
        MessageBox(NULL, L"Error: OpenGL kon niet worden geïnitialiseerd", L"ERROR", MB_OK);
        return -1;
    }

    // Scherm laten zien
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
    SetForegroundWindow(hWnd);
    SetFocus(hWnd);

    main_loop(&msg, hWnd);
    return msg.wParam;
}

main.c

#include "main.h"
#include "graphics.h"

void keyevent();

BYTE key_down[256];

LRESULT CALLBACK CALLBACK Actie(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        ShutdownOpenGL(hWnd);
        PostQuitMessage(0);
        return 0;
    case WM_KEYDOWN:
        key_down[(unsigned int)wParam] = 1;
        keyevent();
        return 0;
    case WM_KEYUP:
        key_down[(unsigned int)wParam] = 0;
        return 0;
    default:
        return DefWindowProc(hWnd, msg, wParam, lParam);
        break;
    }
}

void main_loop(MSG* msg, HWND hWnd)
{
    memset(key_down, 0, 256);
    memset(&msg, 0, sizeof(MSG));

    while (1) {
        if(PeekMessage(msg, NULL, 0, 0, PM_REMOVE)) {
            if(msg->message == WM_QUIT) 
                break;

            TranslateMessage(msg);  
            DispatchMessage(msg);
        }

        if (Render() != 0) {
            break;
        }
    }
}

void keyevent()
{
    if (key_down[VK_ESCAPE] == 1) {
        PostQuitMessage(0);
    }
}

main.h

#ifndef MAIN_HEADER

#define MAIN_HEADER
#define FULLSCREEN      1
#define VSCYNC          1
#define SCREEN_DEPTH    1000.0f
#define SCREEN_NEAR     0.1f

#include <Windows.h>

LRESULT CALLBACK CALLBACK Actie(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void main_loop(MSG* msg, HWND hWnd);

#endif
Was it helpful?

Solution

  1. You are ZeroMemory'ing too much and are corrupting your stack.
  2. When you destroy the temporary window, it will call PostQuitMessage since that's what you told it to do in its WM_DESTROY handler. That quit message is then picked up by your message loop, which causes it to exit immediately.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top