c ++ / приложение с несколькими отдельными окнами - PullRequest
2 голосов
/ 13 февраля 2012

Итак, у меня есть этот код, который создает два окна:

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);

Проблема в том, что приложение закрывается каждый раз, когда я закрываю одно из окон.Что мне нужно, это два отдельных окна;главное окно приложения и то, которое дает доступ к различным настройкам приложения - поэтому закрытие окна настроек не должно влиять на главное окно.Есть ли способ добиться этого?Спасибо.


PS Моя функция 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;
}

Ответы [ 2 ]

3 голосов
/ 13 февраля 2012

Вы регистрируете оба класса окон с одинаковыми lpfnWndProc.Таким образом, все сообщения (включая щелчки мыши и нажатия клавиш) будут направлены на одну и ту же функцию, StaticWndProc.

Таким образом, когда эта функция получает сообщение WM_CLOSE , онаответит, уничтожив окно, которое останавливает прокачку сообщения и завершает программу.Поскольку оба окна имеют одинаковую функцию-обработчик сообщений, они оба будут реагировать одинаково.

Решение состоит в том, чтобы определить два разных метода WndProc, по одному для каждого из ваших окон, или в особом случае обработкусообщения WM_CLOSE, вызывая DefWindowProc только для окна, которое вы хотите разрешить закрывать все приложение.

2 голосов
/ 13 февраля 2012

Сделайте ваш StaticWndProc дескриптор либо WM_CLOSE, либо WM_DESTROY: в этом случае он должен уменьшить значение счетчика открытых окон. Если этот счетчик достигает нуля, звоните PostQuitMessage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...