Лучший способ закрыть и дождаться окна дочернего фрейма, используя Win32 / MFC - PullRequest
1 голос
/ 11 июня 2009

Возможно, здесь есть несколько вариантов, но что бы вы посоветовали, чтобы быть самым безопасным способом сделать следующее:

У меня есть дочерний CFrameWnd с parent = NULL (так что он может жить отдельно от основного приложения, пока приложение работает, по крайней мере). У меня все эти окна хранятся в списке. Когда основное приложение закрывается (MainFrame получает OnClose), я прохожу массив и выдаю PostMessage (WM_CLOSE) для всех. Однако проблема в том, что каждый из них должен что-то сделать, прежде чем закрыться. Итак, мне нужно ждать их. Но мы все в одном потоке ... Итак, как мне ждать, пока дети закроются, не блокируя их собственную обработку в однопоточном приложении?

Или я должен запустить рабочий поток, чтобы позаботиться об этом? Будет ли проще?

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 11 июня 2009

Используйте SendMessage () вместо PostMessage ().

Редактировать: Другой вариант может состоять в том, чтобы просто обрабатывать WM_DESTROY в ваших дочерних окнах (в зависимости от вашего кода, конечно).

1 голос
/ 11 июня 2009

Ну, вы, конечно, не можете просто ждать, пока они закроются, вам нужно как минимум прокачать сообщения , чтобы они получили и обработали WM_CLOSE. Как вы это делаете, зависит от вас. Но я вижу, что вы делаете PostMessage. Почему бы не сделать SendMessage вместо этого - это запустит закрытие синхронно в оконной процедуре для окна. Или вы пытаетесь выйти из приложения? Тогда вы действительно должны использовать PostQuitMessage, а затем перекачивать сообщения обычным способом, пока GetMessage не вернет 0. Много опций.

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

BOOL bRet;

// note that GetMessage returns 0 when WM_QUIT is received - this is how PostQuitMessage
// would work to get us to shut down
// We are passing NULL for the hWnd parameter - this means receive all window and
// thread messages for this thread
while( (bRet = GetMessage( &msg, NULL /* hWnd */, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

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

Если вы отправили сообщение вместо публикации, то оконная процедура для окна вызывается напрямую, а не в очередь. Вам не нужно будет прокачивать сообщения, потому что когда SendMessage вернет сообщение, оно будет полностью обработано.

Способ PostQuitMessage работает путем установки флага в очереди сообщений, указывающего, что приложение должно выйти. Сообщение WM_QUIT на самом деле не является оконным сообщением, которое вы бы отправили - в результате GetMessage проверит этот флаг после обработки всех остальных опубликованных оконных сообщений и вернет 0, если оно установлено. Это приведет к правильному закрытию всех окон, и вам не нужно отправлять его самим окнам.

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