zoukankan      html  css  js  c++  java
  • delphi 如何判断应用程序未响应

    http://www.cnblogs.com/smallmuda/archive/2009/07/24/1529845.html

    delphi 如何判断应用程序未响应

     
     今天在MSN的核心讨论组上看到两篇文章.讨论的乃是应用程序是否没有响应.原文如下:     
        
      >   How   is   it   possible   to   determine   a   process   is   "not   responding"   like   NT   Task     
      >   Manager   do?     
      The   heuristic   works   only   for   GUI   processes,   and   consists   of   calling     
      SendMessageTimeOut()   with   SMTO_ABORTIFHUNG.     
        
      >There   is   any   API   call   to   do   the   job,   or   this   status   is   simply   a   deduction     
      >based   on   process   counters,   like   that   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.     
        
      --     
      有理有理.当然,我这里还有一个UNDOCUMENTED函数,乃是其他的解决方案,NT和9X有个USER32.DLL的函数,IsHungAppWindow(NT)和IsHungThread(9X).使用起来简便无比.下面给出原型.     
      BOOL   IsHungAppWindow   (     
      HWND   hWnd,   //   handle   to   main   app's   window     
      );     
        
      BOOL   IsHungThread   (     
      DWORD   dwThreadId,   //   The   thread's   identifier   of   the   main   app's   window     
      );     
      有了原型,连解释都不需要,好得不的了.:)不过调用时需要GetProcAddress.库里没有该函数.     
      ****************************************   
      check   whether   an   application   (window)   is   not   responding?   
        
      {1.   The   Documented   way}     
        
      {     
          An   application   can   check   if   a   window   is   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   way}     
        
      {     
          //   Translated   form   C   to   Delphi   by   Thomas   Stutz     
          //   Original   Code:     
          //   (c)1999   Ashot   Oganesyan   K,   SmartLine,   Inc     
          //   mailto:ashot@aha.ru,   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.     
        
        -->   For   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;     
  • 相关阅读:
    cad.net 仿lisp函数专篇
    操作篇 cad一个小技巧,通过块中块插入含有字段块,保证更新
    cad.net 外部参照功能和相对路径转换
    cad.net 动态块名 .IsDynamicBlock出错 eInvalidObjectId错误.
    cad.net 委托的学习
    cad.net 关于保存文件Database.SaveAs()出现"eFileAccessErr"错误的解决方法
    测试篇 c# winFrom Close报错 System.ObjectDisposedException:“无法访问已释放的对象。
    测试篇 c#枚举类型怎么用?
    cad.net 2008使用WPF(摘录山人)
    日志篇 随着win10更新...
  • 原文地址:https://www.cnblogs.com/zhangzhifeng/p/6396700.html
Copyright © 2011-2022 走看看