У меня проблема, очень похожая на описанную здесь:
http://www.eggheadcafe.com/software/aspnet/30579866/prevent-vista-from-markin.aspx
Этот поток предполагает, что диспетчер задач отправляет WM_NULL процессу и ожидает, что процесс будет использовать это сообщение в течение срока ожидания (5 секунд?).
Когда я гуглю «WM_NULL повесил», есть много ссылок на ту же технику.
Однако я не вижу сообщений WM_NULL в очереди моего приложения, пока оно работает над длительной операцией - у меня есть вторичный поток, который переключается на основной поток каждые 0,5 секунды и вызывает PeekMessage (), ищущий WM_NULL, и ничего не находит!
Итак, какой метод использует Windows (Vista) для определения зависания приложения?
Какие сообщения должно принимать мое приложение, чтобы Windows считала приложение отзывчивым?
БОЛЬШЕ ДЕТАЛЕЙ:
Наряду с тем, что PeekMessage () ищет WM_NULL, мы также вызываем PeekMessage () для событий мыши, так как мы также хотим понять, выбрал ли пользователь определенную область окна, где нарисован знак остановки. Если область выбрана, мы устанавливаем флаг, который периодически проверяет длительная операция в основном потоке, и остановится, если будет выбран знак остановки.
Проблема с Vista заключается в том, что когда она объявляет приложение не отвечающим, оно заменяет свое окно на призрачное окно - см. описание PeekMessage () :
Если окно верхнего уровня перестает отвечать на сообщения более чем на несколько секунд, система считает, что окно не отвечает, и заменяет его окном-призраком, имеющим тот же z-порядок, местоположение, размер и визуальные атрибуты , Это позволяет пользователю перемещать его, изменять его размер или даже закрывать приложение. Однако это единственные доступные действия, потому что приложение на самом деле не отвечает. Когда приложение отлаживается, система не создает окно-призрак.
Это призрачное окно не позволяет мышке проходить к нашему окну, потому что окно больше не отображается на экране!
Поэтому моя цель - не допустить появления этого призрачного окна ...
ПОСЛЕ НЕКОТОРЫХ ИССЛЕДОВАНИЙ:
После того, как я добавил код Майкл предложил в своем ответе на этот вопрос
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
приложение больше не считается зависшим в Windows; однако я не могу использовать это решение, потому что приложение начинает реагировать на нажатия на различные кнопки и т. д. (что не должно происходить).
Поэтому я попытался увидеть, какие сообщения приходят. Я использовал Spy ++, а также отладочную печать, и оба показали только два вида сообщений: WM_TIMER и 0x0118 (WM_SYSTIMER). Поэтому я изменил код следующим образом
while (PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE) ||
PeekMessage(&msg, NULL, 0x0118, 0x0118, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Удивительно, но приложение снова зависает !!
Теперь я действительно застрял. Если я перехватываю только входящие сообщения и позволяю приложению обрабатывать их, почему Windows все еще думает, что приложение не обрабатывает события ??
Любое содержательное предложение будет с благодарностью оценено.