Заетото приложение води до фалшиво състояние Не отговаря в Windows 7 - WM_UPDATE

По време на дългосрочни операции нашето приложение C++ Win32 показва модален диалогов прозорец за състояние с лента на процеса, който се актуализира нередовно на всеки няколко секунди или така. Започвайки с Windows 7, разбрахме, че Windows много скоро показва съобщение „изглежда увисва...“ и/или добавя „Не отговаря“ към заглавната лента на нашия прозорец.

Разбрахме, че диалоговият прозорец на процеса трябва да обработва съобщения, за да се избегне това. По-конкретно изглежда, че Windows 7 непрекъснато изпраща WM_UPDATE съобщения, за да провери дали нашата програма е жива. По-рано бяхме деактивирали всички ненужни обработки на съобщения в този диалогов прозорец, тъй като изпълнението на профили показва, че те забавят значително.

Но въпреки че смятахме, че сме поправили този проблем, потребителите отново съобщават за такива проблеми: Windows показва „изглежда увисва...“ и/или добавя „Не отговаря“ към заглавната лента на нашия прозорец, въпреки че обработваме всички събития на всеки няколко секунди.

Въпроси:

  • Има ли някаква документация за тази промяна в поведението в Windows 7 (или Windows Vista)? Не намерихме такива. Открихме и редица други промени в поведението на съобщенията.

  • Има ли евентуален начин да деактивирате всички такива проверки "живо ли е" от Windows? Нашето приложение е доста живо и процесите могат да отнемат доста дълго време.

РЕДАКТИРАНЕ: За да бъдем по-конкретни - това, което правим само на всеки няколко секунди, е да извикваме помпата за съобщения PeekMessage/TranslateMessage/DispatchMessage.

Тъй като това е доста стара наследена програма, използването на отделна работна нишка не е възможно в близко бъдеще. Ние, разбира се, правим това за нов код. Моля, имайте предвид също, че основната ми гледна точка е, че това поведение определено се промени с Windows vista / Windows 7. Не намерих никаква документация за това.


person RED SOFT ADAIR    schedule 09.08.2011    source източник
comment
Това извиква нишка за фонов работник.   -  person Deanna    schedule 09.08.2011
comment
деактивира всички ненужни обработки на съобщения - MSDN е доста ясен по този въпрос: Ако [прозоречна процедура] не обработи съобщение, тя трябва да изпрати съобщението обратно на системата за обработка по подразбиране. Прозоречната процедура прави това чрез извикване на функцията DefWindowProc.   -  person MSalters    schedule 09.08.2011


Отговори (2)


Е, директният отговор на въпроса ви е, че можете да се обадите на DisableProcessWindowsGhosting().

Въпреки това би било много по-добре да се обърне внимание на корена на проблема, вместо да се потискат симптомите. Вашият прозорец е призрачен, защото не изпомпвате опашката за съобщения. Не правите това поради възхитителната причина, че приложението ви е заето да върши работа. Приетият начин да вършите работа и да поддържате опашката си натоварена е да вършите работата в отделна нишка.

person David Heffernan    schedule 09.08.2011
comment
Благодаря за вашият отговор. В документацията се казва, че призрачните прозорци са функция на Windows Manager, която позволява на потребителя да минимизира, премести или затвори главния прозорец на приложение, което не отговаря. Не се казва нищо за деактивирането на бележката, която изглежда виси. Знаете ли нещо повече за това? - person RED SOFT ADAIR; 09.08.2011
comment
Когато деактивирате ghosting, няма да видите никакъв (без отговор) текст, прикачен към надписа и т.н. - person David Heffernan; 09.08.2011
comment

Има две функции, налични в main.js, exports.main и exports.onUnload, които се извикват съответно преди изпълнението на добавката и преди да бъде разтоварена. Можете да ги замените по следния начин:

exports.main = function(options, callbacks)
{
    if (options.loadReason == 'install') {
        // init stuff
    }
}

exports.onUnload = function(reason)
{
    if (reason == 'uninstall') {
        // uninit stuff
    }
}

Има повече полета в options и множество възможни причини. Източникът.

- person Ben; 09.11.2012

Открих, че приложението не трябва да извършва действителната обработка на съобщенията, за да предотврати състоянието (без отговор), докато изпълнява задача за блокиране в основната нишка.

Просто трябва периодично да се обажда:

PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
person Jusid    schedule 26.02.2021