2014-02-10 21 views
0

我試圖用WinAPI創建一個OpenGL上下文,它工作的很好,但我認爲我搞砸了一些東西,因爲當我點擊上面的欄(關閉按鈕時,最小化按鈕是),它調用ResizeWindow功能莫名其妙...... Image showing thisWindows創建錯誤 - 也許事件處理

這裏是我的主要功能:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) 
{ 
    GLWindow *window = new GLWindow(); 
    Event *evt = new Event(); 

    window->Create("OpenGL Window", 800, 600, 32); 

    while (window->IsRunning()) 
    { 
     evt->Clear(); 
     while (window->DispatchEvent(evt)) 
     { 
     } 
     Render(); 
     window->Present(); 
    } 

    delete evt; 
    delete window; 
} 

事件僅僅是一類具有一個地圖包含事件PARAMS。我刪除每一個事件中的WndProc處理所以它不可能是一個問題

窗口創建代碼:

bool GLWindow::Create(char* title, int width, int height, int bits) 
{ 
    GLuint PixelFormat; 
    WNDCLASS wClass; 
    DWORD dwExStyle; 
    DWORD dwStyle; 
    RECT WindowRect; 
    WindowRect.left = (long)0; 
    WindowRect.top = (long)0; 
    WindowRect.right = (long)width; 
    WindowRect.bottom = (long)height; 

    hInstance = GetModuleHandle(NULL); 
    wClass.cbClsExtra = 0; 
    wClass.cbWndExtra = 0; 
    wClass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); 
    wClass.hCursor = LoadCursor(hInstance, IDC_ARROW); 
    wClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION); 
    wClass.hInstance = hInstance; 
    wClass.lpfnWndProc = &GLWindow::WndProc; 
    wClass.lpszClassName = "GL"; 
    wClass.lpszMenuName = NULL; 
    wClass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC; 

    dwStyle = WS_OVERLAPPEDWINDOW; 
    dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; 

    if (!RegisterClass(&wClass)) 
    { 
     MessageBox(NULL, "Error! Cannot register window class!", "ERROR", MB_OK); 
     return 0; 
    } 

    AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle); 

    if (!(hWnd = CreateWindowEx(
     dwExStyle, 
     "GL", 
     "Title", 
     WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, 
     0, 
     0, 
     WINDOW_WIDTH, 
     WINDOW_HEIGHT, 
     NULL, 
     NULL, 
     hInstance, 
     NULL))) 
    { 
     KillWindow(); 
     MessageBox(NULL, "Window creation error.", "Error", MB_OK); 
     return false; 
    } 

    static PIXELFORMATDESCRIPTOR pfd = 
    { 
     sizeof(PIXELFORMATDESCRIPTOR), 
     1,                    //Version number 
     PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_TYPE_RGBA,  //Formats 
     bits,                   //color depth 
     0, 0, 0, 0, 0, 0,                //color bits ignored 
     0,                    //no alpha buffer 
     0,                    //shift bit ignored 
     0,                    //no accumulation buffer 
     0, 0, 0, 0,                  //accumulation bits ignored 
     16,                    //16bit Zbuffer (depth buffer) 
     0,                    //no stencilbuffer 
     0,                    //no auxiliary buffer 
     PFD_MAIN_PLANE,                 //main drawing layer 
     0,                    //reserved 
     0, 0, 0                   //layer masks ignored 
    }; 

    if (!(hDC = GetDC(hWnd))) 
    { 
     KillWindow(); 
     MessageBox(NULL, "Can't create OpenGL Window", "Error", MB_OK); 
     return false; 
    } 

    if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) 
    { 
     KillWindow(); 
     MessageBox(NULL, "Can't find suitable PixelFormat", "Error", MB_OK); 
     return false; 
    } 

    if (!SetPixelFormat(hDC, PixelFormat, &pfd)) 
    { 
     KillWindow(); 
     MessageBox(NULL, "Can't set pixelformat", "Error", MB_OK); 
     return false; 
    } 

    if (!(hRC = wglCreateContext(hDC))) 
    { 
     KillWindow(); 
     MessageBox(NULL, "Can't create OpenGL context", "Error", MB_OK); 
     return false; 
    } 

    if (!wglMakeCurrent(hDC, hRC)) 
    { 
     KillWindow(); 
     MessageBox(NULL, "Can't activate OGL context", "Error", MB_OK); 
     return false; 
    } 

    ShowWindow(hWnd, SW_SHOW); 
    SetForegroundWindow(hWnd); 
    SetFocus(hWnd); 
    ResizeWindow(800, 600); 

    if (!InitGL()) 
    { 
     KillWindow(); 
     MessageBox(NULL, "Failed initialization", "Error", MB_OK); 
     return false; 
    } 

    return true; 
} 

調度事件:

bool GLWindow::DispatchEvent(Event* evt) 
{ 
    MSG msg; 

    bool wasThereAnyEvent = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); 

    if (wasThereAnyEvent) 
    { 

     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    return wasThereAnyEvent; 
} 

我刪除事件緩衝區填充,所以它只是過程每一條消息。

的WndProc:

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
    { 
     switch (msg) 
     { 
      case WM_CREATE: 
       break; 
      case WM_DESTROY: 
      case WM_QUIT: 
      case WM_CLOSE: 
       isRunning = false; 
       PostQuitMessage(0); 
       return 0; 
      case WM_ACTIVATE: 
      { 
       isActiveWindow = !HIWORD(wParam); 
       return 0; 
      } 
      case WM_SYSCOMMAND: 
       switch (wParam) 
       { 
        case SC_SCREENSAVE: 
        case SC_MONITORPOWER: 
         return 0; 
       } 
      case WM_SIZE: 
       ResizeWindow(LOWORD(lParam), HIWORD(lParam)); 
       return 0; 
      } 

     return DefWindowProc(hWnd, msg, wParam, lParam); 
    } 
+0

您不需要調整窗口的大小以響應'WM_SIZE' - 您的窗口已調整大小後,您會收到此消息**。它可以讓你更新你的客戶區域等。如果你調整窗口的大小來響應它,你會冒着創建反饋循環的風險。 –

回答

1

我認爲問題是,你不使用任何休息裏面你(當然他們不會在任何情況下需要)switch聲明。當您收到WM_SYSCOMMAND(不包含SC_SCREENSAVESC_MONITORPOWER)時,下一個案例陳述(此例中爲WM_SIZE)會被執行。

switch (msg) 
    { 
     case WM_CREATE: 
      break; 
     case WM_DESTROY: 
     case WM_QUIT: 
     case WM_CLOSE: 
      isRunning = false; 
      PostQuitMessage(0); 
      return 0; 
      break; 
     case WM_ACTIVATE: 
     { 
      isActiveWindow = !HIWORD(wParam); 
      return 0; 
     } break; 
     case WM_SYSCOMMAND: 
     { 
      switch (wParam) 
      { 
       case SC_SCREENSAVE: 
       case SC_MONITORPOWER: 
        return 0; 
      } 
     } break; 
     case WM_SIZE: 
      ResizeWindow(LOWORD(lParam), HIWORD(lParam)); 
      return 0; 
     } 
+0

ooooh ...是啊,我忘了那個休息!謝謝 :)) – RobeeZ