Обнаружить закрытие окна вне wndproc? - PullRequest
1 голос
/ 12 июня 2009

В настоящее время я работаю над приложением win32 GUI, которое выполняет большую часть своей работы в потоке окна.
Этот поток иногда может быть заблокирован, так как он запускает механизм сценариев, который может быть приостановлен внешним отладчиком сценариев (другой процесс). В большинстве случаев это не проблема, так как ожидается поведение.
Однако если пользователь пытается закрыть окно, приложение, очевидно, перестает отвечать на запросы, и появляется диалоговое окно «Это приложение не отвечает ...».
Мой план состоял в том, чтобы периодически перезванивать из «кода приостановки» в приложение и заставить его делать PeekMessage для WM_CLOSE, и если это так, завершать отладчик. К сожалению, насколько я понимаю, WM_CLOSE отправляется непосредственно в wndproc.

Есть ли какой-то другой способ, которым я мог бы обнаружить, что пользователь хочет закрыть окно, кроме редизайна приложения, которое не является вариантом?
Например, есть ли какое-либо другое сообщение, которое можно проверить с помощью PeekMessage?

Ответы [ 4 ]

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

Не могли бы вы добавить еще одну ветку для редизайна приложения? Это, безусловно, сделает вашу жизнь намного проще! Просто позвольте Gui выполнять всю работу с Gui, запускать цикл обработки сообщений и выполнять всю тяжелую работу в другом потоке. Если пользователь хочет выйти из приложения, подайте ему приятное сообщение OK / Cancel и соответственно приостановите / отмените «рабочий поток». Обработка двух отдельных задач в этом одном потоке - со всеми обходными путями - сделает вещи намного более беспорядочными, чем это должно быть. Удачи!

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

Я полагаю, что вы можете продолжать обрабатывать ваше сообщение WM_ CLOSE в wndproc, и когда вы его получите, вы вызываете PostQuitMessage () , который, в свою очередь, сгенерирует сообщение WM_ QUIT, которое, в свою очередь, будет прочитано GetMessage () / PeekMessage () . * +1007 *

Если ваша оконная нить полностью заблокирована, вам не повезло. У вас есть несколько вариантов. Поток должен иметь возможность периодически выполнять PeekMessage (), находясь в «режиме обработчика сценариев».

while (IsScripting()) {
    ScriptEngineTimeSlice();
    while (PeekMessage( .. )) {
        TranslateMessage( .. );
        DispatchMessage( .. ); // <-- wnd procedure will be called
        // ..
    }
}

Это, вероятно, старые новости для вас, так как вы уже знаете об этом. Но если вы как-то не можете прервать поток пользовательского интерфейса, то нет способа решить эту проблему. Если поток заблокирован, он заблокирован.

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

Как насчет этого: периодически вращать цикл сообщений для отправки любых сообщений в очереди сообщений (это приведет к обработке сообщений мыши / ввода, что приведет к созданию WM_CLOSE). В главном окне вашего приложения установите флаг при получении WM_CLOSE и проверьте этот флаг после вращения цикла.

Простейший случай вращения цикла сообщений для сброса любых ожидающих сообщений:

while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

хотя фреймворк вашего приложения уже может иметь функции для этого. Надеюсь, это поможет.

0 голосов
/ 12 июня 2009

Если вы отлаживаете, не означает ли это, что пользователь отлаживает? Почему они были бы удивлены тем, что приложение тогда «не отвечало»? В любом случае, у вас есть контроль над оконной процедурой для окна, так почему бы просто не увидеть там сообщение WM_CLOSE? Это твое окно?

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