Некоторое время тому назад, я писал очередное расширение для моего
С одной стороны что может быть проще - использовать обычную функцию SendMessageTimeout для отправки окну приложения какого-то контрольного сообщения и если ф-ция выходит по таймауту, то считать, что приложение "висит". Однако хитрый и коварный системный программист, писавший Windows думал иначе (и конечно он был прав!) то, что окно (оконная ф-ция) не реагирует на внешние сообщения не может однозначно определять состояние "зависа", поэтому я решил запустить свой любимый дизассемблер и узнать очередную порцию правды о Windows.
Как всегда, все оказалось очень просто - библиотека User32.dll содержит специальную ф-цию для определения состояния приложения. Единственная трудность только в том, что эта ф-ция имеет разные названия и разный синтаксис в
HWND hWnd, // описатель главного окна приложения
);
BOOL IsHungThread (
DWORD dwThreadId, // идентификатор потока, которому принадлежит главное окно приложения
);
Так как эти ф-ции являются недокументированными, то Микрософт не включило их экспортные символы в User32.lib, но это не должно стать нам преградой - используем динамическую загрузку:
typedef BOOL (WINAPI *PROCISHUNGAPPWINDOW) (HWND);typedef BOOL (WINAPI *PROCISHUNGTHREAD) (DWORD);
PROCISHUNGAPPWINDOW IsHungAppWindow;
PROCISHUNGTHREAD IsHungThread;
HMODULE hUser32 = GetModuleHandle("user32");
IsHungAppWindow = | (PROCISHUNGAPPWINDOW) GetProcAddress(hUser32,"IsHungAppWindow"); |
IsHungThread = | (PROCISHUNGTHREAD) GetProcAddress(hUser32,"IsHungThread"); |
Ну что же, теперь мы все можем и все умеем, осталось только написать маленький работающий пример: ishung.zip (15Kb)
Оригинал этой статьи на английском языке лежит здесь: Trick 1
Не документированные ф-ции Windows NT и Windows 95/98 и описания на английском языке: www.codepile.com