2012-02-13 5 views
2

だから、私は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); 

問題は、アプリケーションは、私は窓の一つを閉じるたびに終了し、あります。私が必要とするのは2つの別々のウィンドウです。メインアプリケーションウィンドウと、アプリケーションのさまざまな設定にアクセスできるもの - したがって、設定ウィンドウを閉じてもメインウィンドウには影響しません。これを達成する方法はありますか?ありがとうございました。


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などに対して何をしますか?メッセージループはどのように見えますか? –

+0

@Tom Whittockそれは終了メッセージを投稿します: 'PostQuitMessage(0);' –

答えて

3

あなたは同じlpfnWndProcとの両方のウィンドウクラスを登録します。したがって、すべてのメッセージ(マウスのクリックやキーボードの押下を含む)は同じ機能StaticWndProcに送られます。

したがって、この関数がWM_CLOSE messageを受信すると、ウィンドウを破棄して応答し、メッセージポンプを停止してプログラムを終了します。両方のウィンドウは同じメッセージハンドラ機能を持っているため、同じ方法で応答します。

ソリューションは、アプリケーション全体を閉鎖できるようにしたいウィンドウのDefWindowProcを呼び出して、二つの異なるWndProc方法、あなたの窓のそれぞれに1つ、または専用ケースWM_CLOSEメッセージの処理を定義することです。

+0

あなたの思い出しは正確に正しいです。あなたの答えを少し広げる自由を取って、ちょっとした疑問を払拭しました。あなたが気にしないことを願っています! :-) –

+0

上記の文脈で2番目の 'StaticWndProc'関数を実装する方法を教えてください。 –

+0

@CodyGrayありがとうございます。 –

2

StaticWndProcハンドルをWM_CLOSEまたはWM_DESTROYのいずれかに設定します。この場合、openedWindows-counterを減らす必要があります。そのカウンタがゼロになると、PostQuitMessageが呼び出されます。

+0

私はこの事件についてちょっと読んだだけですが、私には依然として不明です。各ウインドウに独自のメッセージセットを受け取る方法はありますか? –

+0

@Abdulali:はい、 'RegisterClass'でウィンドウを作成すると、ウィンドウごとに異なる' WndProc'関数を登録します。 –

関連する問題