Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Как узнать, что приложение не отвечает


Автор: MadCoder 15.7.2009, 20:39
Добрый вечер!

Подскажите, как можно определить, что чужое приложение не отвечает (как это делает Windows), т.е. интерфейс программы завис и не обновляется smile .

Автор: kami 15.7.2009, 21:28
http://msdn.microsoft.com/en-us/library/ms644952(VS.85).aspx

Добавлено через 40 секунд
но опять-таки, нужно знать какому окну отправлять сообщение.

Автор: MadCoder 15.7.2009, 22:37
Например, так:
Код

var
H: HWND;
Res: Cardinal;
begin
H := FindWindow('TTest', 'Test');
SendMessageTimeout(H, WM_NULL, 0, 0,SMTO_BLOCK, 5000,Res);
ShowMessage(IntToStr(Res));
end;


Test - зависшее приложение. Только несмотря на зависание Res равен 1, если программа не висит - тогда 0 (я так понимаю, там должны быть миллисекунды). Хотя выполнение SendMessageTimeout занимает ощутимо больше секунды...

Автор: kami 15.7.2009, 22:50
Цитата(MadCoder @  15.7.2009,  22:37 Найти цитируемый пост)
 выполнение SendMessageTimeout занимает ощутимо больше секунды

не то анализируешь. Нужен результат, возвращаемый самой SendMessageTimeout.
Цитата

If the function fails or times out, the return value is zero. To get extended error information, call GetLastError. If GetLastError returns ERROR_TIMEOUT, then the function timed out.

А res - это результат обработки оконной функцией твоего сообщения.
Ощутимо более секунды... ну так ты сам указал таймаут в 5 секунд...
P.S. попробуй комбинации с SMTO_ABORTIFHUNG.

Автор: MadCoder 15.7.2009, 23:03
Хм, пишет 0 мс и "Параметр задан неверно", хотя чужое приложение Test закрывается успешно:
Код

var
H: HWND;
Res: Cardinal;
begin
H := FindWindow('TTest', 'Test');
ShowMessage(IntToStr(SendMessageTimeout(H, WM_CLOSE, 0, 0,SMTO_ABORTIFHUNG, 50000,Res)));
if Res=0 then
 ShowMessage(SysErrorMessage(GetLastError));

Автор: kami 15.7.2009, 23:10
Код

var
  H: HWND;
  Res: Cardinal;
  IsHung:boolean
begin
  H := FindWindow('TTest', 'Test');
  SetLastError(0);
  IsHung:=SendMessageTimeout(H, WM_NULL, 0, 0,SMTO_BLOCK, 5000,Res)=0; // 5000мс=5 сек. Не много ли?
  if IsHung then
    ShowMessage('Не доставлено или прервано по таймауту. Ошибка №'+IntToStr(GetLastError));
end;


Добавлено через 1 минуту и 10 секунд
И в этом коде нет обработки - найдено окно или нет.
Потому что если не найдено - смысл отправлять сообщение?

Автор: MadCoder 15.7.2009, 23:19
Круто! Спасибо, все работает замечательно smile. Проверку добавлю smile.

Автор: MadCoder 15.7.2009, 23:49
Вот http://gunsmoker.blogspot.com/2009/01/anti-freeze-eurekalog.html тоже интересный материяльчик smile.

Автор: CodeMonkey 16.7.2009, 09:41
Есть ещё http://msdn.microsoft.com/en-us/library/ms633526(VS.85).aspx.
Примерно это то же самое, что ручная отправка SendMessageTimeout, только без настроек.

Автор: MadCoder 16.7.2009, 09:46
Спасибо smile

Автор: Rrader 16.7.2009, 11:06
В DRKB целая статья по этому вопросу - http://antonn.ru/index.php?drkb=200&id=1576&str_path=0|126|147|200

Цитата(CodeMonkey @  16.7.2009,  15:41 Найти цитируемый пост)
Есть ещё IsHungAppWindow.
Примерно это то же самое, что ручная отправка SendMessageTimeout, только без настроек. 


К сожалению, примечание не радует :(

Автор: CodeMonkey 16.7.2009, 12:10
Цитата(Rrader @  16.7.2009,  11:06 Найти цитируемый пост)
К сожалению, примечание не радует

Это про:
Цитата
It is recommended that you do not use it in new programs because it might be altered or unavailable in subsequent versions of Windows.
 ?

Автор: Rrader 16.7.2009, 14:46
Ну да.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)