2013-02-03 172 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