2017-05-03 88 views
0

我想創建一個演示窗口框架在它自己的類中處理並在WinMain文件中調用,我有main.cpp和window.h和window.cpp,代碼編譯成功,但窗口不會盡管在系統托盤窗口標題我在main.cpp中通過彈出顯示,這裏是整個代碼:WinApi的c + +窗口不會出現oop

main.cpp中:

#include <Windows.h> 
#include "window.h" 


window* WinapiInit = new window; 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE PrevhInstance, LPSTR 
lpCmdLine, int nCmdShow) 
{ 
WinapiInit->initWindow(hInstance, 800, 600, L"DirectX 12 Demo", nCmdShow); 

delete WinapiInit; 

return 0; 
} 

window.h

#pragma once 
#include <Windows.h> 

class window 
{ 

private: 
LPCWSTR m_WindowTitle; 
const LPCTSTR m_WindowClassName = L"WindowClass1"; 

int m_WindowWidth; 
int m_WindowHeight; 
const int m_ScreenPosX = GetSystemMetrics(SM_CXSCREEN); 
const int m_ScreenPosY = GetSystemMetrics(SM_CYSCREEN); 


HWND hWnd; 
WNDCLASSEX wcex; 
MSG msg; 

public: 
void initWindow(HINSTANCE hInstance, int WindowWidth, int WindowHeight, 
LPCWSTR WindowTitle, int nCmdShow); 
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam); 
void mainLoop(); 

}; 

window.cpp

#include "window.h" 


LRESULT window::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
switch (uMsg) 
{ 
case WM_DESTROY: 
    PostQuitMessage(0); 
    ExitProcess(0); 
    break; 
default: 
    return DefWindowProc(hWnd, uMsg, wParam, lParam); 
    break; 
} 
return 0; 
} 

void window::mainLoop() 
{ 
msg = { 0 }; 
while (WM_QUIT != msg.message) 
{ 
    if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    //GAME CODE HERE 
    //... 

} 
} 

void window::initWindow(const HINSTANCE hInstance, int WindowWidth, int 
WindowHeight, LPCWSTR WindowTitle, const int nCmdShow) 
{ 

m_WindowWidth = WindowWidth; 
m_WindowHeight = WindowHeight; 
m_WindowTitle = WindowTitle; 

wcex = { 0 }; 
wcex.cbSize = sizeof(WNDCLASSEX); 
wcex.cbClsExtra = 0; 
wcex.cbWndExtra = 0; 
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 3); 
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION); 
wcex.hIconSm = LoadIcon(hInstance, IDI_APPLICATION); 
wcex.hInstance = hInstance; 
wcex.lpfnWndProc = window::WndProc; 
wcex.lpszMenuName = nullptr; 
wcex.lpszClassName = m_WindowClassName; 
wcex.style = CS_HREDRAW | CS_VREDRAW; 

if (!RegisterClassEx(&wcex)) 
{ 
    MessageBox(NULL, L"RegisterClassEx Call Error!", L"ERROR" , MB_OK | 
    MB_ICONERROR); 
} 

hWnd = CreateWindowEx(NULL, m_WindowClassName, WindowTitle, 
         WS_OVERLAPPEDWINDOW, m_ScreenPosX, m_ScreenPosY, 
WindowWidth, 
         WindowHeight, NULL, NULL, hInstance, NULL); 

if (!hWnd) 
{ 
    MessageBox(NULL, L"CreateWindowEx Call Error!", L"ERROR", MB_OK | 
    MB_ICONERROR); 
} 

ShowWindow(hWnd, nCmdShow); 
UpdateWindow(hWnd); 

mainLoop(); 

} 

是什麼導致了窗口不顯示?我是面向對象編程的初學者,所以我認爲這是一個問題,但我無法弄清楚,任何幫助將不勝感激。

+0

如果你正在做C++的Win32開發,你可以看看MFC。 –

+0

@Dan ok然後,謝謝你的領導 –

+0

@Cody Gray很好,WinapiInit是一個指向窗口類的指針(希望),我發佈了頭文件和cpp文件,對於任何幫助將不勝感激 –

回答

1

還有一堆的東西,在這裏錯了,因爲你已經設法使一個簡單的應用程序非常複雜,因此難以調試,

最關鍵的是有關於你的問題,你初始化m_ScreenPosX和m_ScreenPosY與系統度量標準SM_CXSCREEN和SM_CYSCREEN--根據定義,這意味着窗口已經放置在桌面的可見區域之外。

由於這看起來應該成長爲DirectX應用程序,因此您可能希望使用0,0作爲位置,並且主顯示器的尺寸(在多顯示器系統上不會是SM_CXSCREEN,SM_CYSCREEN)將窗口定位在主顯示屏上。

但是在短期內,CW_USEDEFAULT將是一個明智的位置值,可用於初始開發。

錯誤的下一個最重要的來源是您的消息循環作爲您的窗口類的一部分。即使只有一個應用程序窗口,大多數(如果不是全部的話)用於Windows開發的OOP框架將「窗口」與「應用程序」分開。這意味着應用程序對象擁有消息循環,它永遠不會通過hWnd進行過濾:發佈到應用程序的消息(如WM_QUIT)不會發送到HWND,(可能)是您的WM_DESTROY處理程序也會調用ExitProcess的原因。刪除對ExitProcess的調用,並刪除hWnd過濾,PostQuitMessage()將導致您的應用程序乾淨地終止。最後,除非你只是想存儲你的窗口類的單例(因爲遊戲窗口不太可能會導致問題),你很快就會急於要將整個窗口類實現爲靜態方法。 通常的方法是使用SetWindowLongPtr/GetWindowLongPtrGWLP_USERDATA來存儲和檢索您的靜態WndProc中的this指針,以便它可以調用非靜態類方法。

+0

這是相當豐富!謝謝。 –