2012-02-13 84 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

相关问题