2013-02-03 40 views
0

我想在C中创建一个简单的OpenGL窗口,但我遇到了窗口本身的问题。一个窗口被创建,然后它突然消失。我通过置零“msg”来解决这个问题,但是窗口仍然会尝试退出,并且所有其他消息都不会被传递。所以我不能按退出键退出(WM_KEYDOWN没有通过)。渲染图形就像它应该那样。有谁知道这是什么原因,以及如何解决它?OpenGL窗口错误

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 
+0

模糊标题不可能对未来的访问者有用。 –

回答

2
  1. 您ZeroMemory'ing太多而被破坏你的筹码。
  2. 当你销毁临时窗口时,它会调用PostQuitMessage,因为这就是你告诉它在其WM_DESTROY处理程序中执行的操作。这条退出的消息随后被你的消息循环拾取,这会导致它立即退出。
+0

谢谢,我没有意识到代码也是第一次。 – para