There are two articles on MSN's core discussion group today. The discussion is whether the application is unresponsive. The original text is as follows:
> How was it possible to determine a process was "not responding" like NT Task
> Manager do?
The heuristic works only for GUI processes, and consists of calling
SendMessageTimeout () with Smto_abortifhung.
>there is an any API for the job, or this status is simply a deduction
>based on process counters, like this returned from call to Getprocesstimes
>api function?
Use SendMessageTimeout with a value of wm_null. That's all Task
Manager does to determine this AFAIK.
--
Rational and rational. Of course, I have a undocumented function here, but other solutions, NT and 9X have a USER32.DLL function, Ishungappwindow (NT) and Ishungthread (9X). It's incredibly easy to use. The prototype is given below.
BOOL Ishungappwindow (
HWND hwnd,//Handle to main app ' s window
);
BOOL Ishungthread (
DWORD dwThreadID,//The thread ' s identifier of the main app ' s window
);
With prototypes, there's no need for explanations.:) However, the call requires GetProcAddress. The function is not in the library.
****************************************
Check whether an application (window) isn't responding?
{1. The documented-i}
{
An application can check if a window was responding to messages by
Sending the Wm_null message with the SendMessageTimeout function.
}
function appisresponding (classname:string): Boolean;
Const
{Specifies the duration, in milliseconds, of the time-out period}
TIMEOUT = 50;
Var
Res:dword;
H:hwnd;
Begin
H: = FindWindow (PChar (ClassName), nil);
If h <> 0 Then
Result: = SendMessageTimeout (H,
Wm_null,
0,
0,
Smto_normal or Smto_abortifhung,
TIMEOUT,
Res) <> 0
Else
ShowMessage (Format ('%s not found! ', [ClassName]));
End
Procedure Tform1.button1click (Sender:tobject);
Begin
If appisresponding (' Opusapp ') then
{Opusapp is the Class Name of Winword. EXE}
ShowMessage (' App. Responding ');
End
{2. The undocumented-i}
{
Translated form C to Delphi by Thomas Stutz
Original Code:
(c) 1999 Ashot Oganesyan K, Smartline, INC
Mailto:[email protected], http://www.protect-me.com, http://www.codepile.com
The code doesn ' t use the Win32 API sendmessagetimout function to
Determine if the target application is responding but calls
Undocumented functions from the User32.dll.
--Windows 95/98/me We call the Ishungthread () API
The function Ishungappwindow retrieves the status (running or not responding)
of the specified application
Ishungappwindow (Wnd:hwnd)://Handle to main app ' s window
BOOL;
-For NT/2000/XP the Ishungappwindow () API:
The function ishungthread retrieves the status (running or not responding) of
The specified thread
Ishungthread (DWORD dwThreadID)://The thread ' s identifier of the main app ' s window
BOOL;
Unfortunately, Microsoft doesn ' t provide us with the exports symbols in the
User32.lib for these functions, so we should load them dynamically using the
GetModuleHandle and GetProcAddress functions:
}
For win9x/me
function isapprespondig9x (Dwthreadid:dword): Boolean;
Type
Tishungthread = function (Dwthreadid:dword): BOOL; stdcall;
Var
Huser32:thandle;
Ishungthread:tishungthread;
Begin
Result: = True;
HUser32: = GetModuleHandle (' user32.dll ');
if (HUser32 > 0) Then
Begin
@IsHungThread: = GetProcAddress (HUser32, ' ishungthread ');
If Assigned (Ishungthread) Then
Begin
Result: = Not ishungthread (dwThreadID);
End
End
End
For Win NT/2000/XP
function Isapprespondignt (wnd:hwnd): Boolean;
Type
Tishungappwindow = function (Wnd:hwnd): BOOL; stdcall;
Var
Huser32:thandle;
Ishungappwindow:tishungappwindow;
Begin
Result: = True;
HUser32: = GetModuleHandle (' user32.dll ');
if (HUser32 > 0) Then
Begin
@IsHungAppWindow: = GetProcAddress (HUser32, ' Ishungappwindow ');
If Assigned (Ishungappwindow) Then
Begin
Result: = Not Ishungappwindow (WND);
End
End
End
function Isapprespondig (wnd:hwnd): Boolean;
Begin
If not IsWindow (Wnd) Then
Begin
ShowMessage (' incorrect window handle! ');
Exit;
End
If Win32platform = Ver_platform_win32_nt Then
Result: = Isapprespondignt (WND)
Else
Result: = isapprespondig9x (GetWindowThreadProcessId (Wnd,nil));
End
Example:check if Word is hung/responding
Procedure Tform1.button3click (Sender:tobject);
Var
Res:dword;
H:hwnd;
Begin
Find Word by classname
H: = FindWindow (PChar (' Opusapp '), nil);
If h <> 0 Then
Begin
If Isapprespondig (h) Then
ShowMessage (' Word is responding! ')
Else
ShowMessage (' Word is not responding! ');
End
Else
ShowMessage (' Word is not open! ');
End
How Delphi determines that the application is not responding