2012-02-13 142 views
2

應用所以我有這樣的代碼,創建兩個窗口:C++ /具有多個獨立的窗口

WNDCLASS wc; 
    wc.style = CS_BYTEALIGNCLIENT | CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = StaticWndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr); 
    wc.hCursor = LoadCursor(nullptr, IDC_ARROW); 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 
    wc.lpszMenuName = nullptr; 
    wc.lpszClassName = _T("Move Engine"); 
    RegisterClass(&wc); 
    m_hWnd = CreateWindow("Move Engine", "Move Engine", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, usWidth, usHeight, nullptr, nullptr, wc.hInstance, this); 

    // Create the settings window 
    wc.lpszClassName = _T("Settings"); 
    RegisterClass(&wc); 
    s_hWnd = CreateWindow("Settings", "Settings", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 20, nullptr, nullptr, wc.hInstance, this); 

ShowWindow(m_hWnd, SW_SHOW); 
ShowWindow(s_hWnd, SW_SHOW); 

的問題是,應用每個i關閉窗口之一時終止。我需要的是兩個獨立的窗口;主應用程序窗口和允許訪問應用程序的各種設置的窗口 - 因此關閉設置窗口不應影響主窗口。有什麼辦法可以做到這一點?謝謝。


P.S.我的WinMain函數修改如下:

int WINAPI WinMain(HINSTANCE a_hInstance, HINSTANCE a_hPrevInstance, LPTSTR a_lpCmdLine, int a_iCmdShow) 
{ 
    int iReturnCode; 

    // Initialise the engine. 
    if (!MyEngine.InitInstance(a_hInstance, a_lpCmdLine, a_iCmdShow)) return 0; 

    // Begin the gameplay process and return when the application due to exit 
    iReturnCode = MyEngine.StartEngine(); 

    // Return the correct exit code. 
    return iReturnCode; 
} 

和StaticWndProc看起來是這樣的:

LRESULT CALLBACK CMoveEngine::StaticWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) 
{ 
    // If this is a create message, trap the 'this' pointer passed in and store it within the window. 
    if (Message == WM_CREATE) SetWindowLong(hWnd, GWL_USERDATA, (LONG)((CREATESTRUCT FAR *)lParam)->lpCreateParams); 

    // Obtain the correct destination for this message 
    CMoveEngine *Destination = (CMoveEngine*)GetWindowLong(hWnd, GWL_USERDATA); 

    // If the hWnd has a related class, pass it through 
    if (Destination) return Destination->DisplayWndProc(hWnd, Message, wParam, lParam); 

    // No destination found, defer to system... 
    return DefWindowProc(hWnd, Message, wParam, lParam); 
} 

消息循環:

int CMoveEngine::StartEngine() 
{ 
    MSG msg; 
// Start main loop 
while (true) 
{ 
    // Did we recieve a message, or are we idling? 
    if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) 
    { 
     if (msg.message == WM_QUIT) break; 
     TranslateMessage(&msg); 
     DispatchMessage (&msg); 
    } 
    else 
    { 

    } 
} 

return 0; 
} 
+0

你的StaticWndProc對WM_CLOSE等有什麼作用?你的消息循環是什麼樣的? – 2012-02-13 08:53:48

+0

@Tom Whittock它發佈了一條退出消息:'PostQuitMessage(0);' – 2012-02-13 09:06:00

回答

3

你用相同的lpfnWndProc都註冊窗口類。因此,所有消息(包括鼠標點擊和鍵盤按下)將被定向到相同的功能,StaticWndProc

因此,當這個函數收到WM_CLOSE message時,它會通過銷燬窗口來響應,這會停止消息泵並終止程序。由於兩個窗口具有相同的消息處理函數,它們都將以相同的方式響應。

解決方法是定義兩個不同的WndProc方法,每一個你的窗戶,或者特殊情況下,WM_CLOSE消息的處理,只呼籲DefWindowProc爲您要允許關閉整個應用程序的窗口。

+0

您的回憶是完全正確的。我冒昧地只是擴大你的答案,並刪除了自我懷疑的表示。希望你不介意! :-) – 2012-02-13 09:12:15

+0

你能告訴我應該如何在上面的上下文中實現第二個'StaticWndProc'函數嗎? – 2012-02-13 09:13:20

+0

@CodyGray謝謝。 – 2012-02-13 11:42:05

2

使你的StaticWndProc句柄WM_CLOSEWM_DESTROY:在這種情況下,它應該減少一個打開的Windows計數器。如果該計數器達到零呼叫PostQuitMessage

+0

我剛剛讀了一些關於這種情況的文章,但對我而言還不清楚 - 是否有任何方法可以讓每個窗口都收到自己的一組消息? – 2012-02-13 09:10:01

+0

@Abdulali:是的,當你用'RegisterClass'創建它們時,爲每個窗口註冊一個不同的'WndProc'函數。 – 2012-02-13 09:13:42

相關問題