c - OpenGL 窗口错误

标签 c windows window opengl-4

我正在尝试用 C 创建一个简单的 OpenGL 窗口,但窗口本身存在问题。创建一个窗口,然后它突然消失。我通过将“msg”归零来修复此问题,但窗口仍然尝试退出并且所有其他消息都不会传递。所以我无法通过按escape退出(未通过WM_KEYDOWN)。渲染图形就像它应该的那样。有谁知道造成这种情况的原因以及如何解决它?

入口点.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

最佳答案

  1. 您的 ZeroMemory 操作过多,并且正在损坏您的堆栈。
  2. 当您销毁临时窗口时,它将调用 PostQuitMessage,因为这是您在其 WM_DESTROY 处理程序中告诉它执行的操作。然后,消息循环会获取该退出消息,使其立即退出。

关于c - OpenGL 窗口错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14674853/

相关文章:

c# - 如何使 .NET 窗体始终位于另一个应用程序之上?

c - 由于 MPI_comm_size 导致的段错误

c - 错误 "expression must have pointer type"何时发生?

c - 有没有更好的方法来查找任何字符串或数字的长度?

windows - ffmpeg 在播放全屏的电视上保持宽高比

Windows批处理文件,等待命令完成?

c - 逻辑运算符和增量运算符

Windows 服务无法打开 COM 端口

python - Maya PySide 窗口 - 记住位置和大小

javascript - js 如何从 $(document) 和 $(window) 获取选择器?