博客园  :: 首页  :: 联系 :: 管理

C#中捕捉对话框的文本内容

Posted on 2006-11-03 12:39  sunrack  阅读(735)  评论(0编辑  收藏  举报

      如何找到桌面上报错的窗口,不管是父窗口还是子窗口,而且获得它的出错信息呢?

      主要是利用API函数:
   [DllImport("user32.dll")]
  public static extern int FindWindowEx(int hwndParent, int hwndChildAfter, 
                                                                     string lpszClass, string lpszWindow);
  
  [DllImport("user32.dll")]
  public static extern int FindWindow(string strclassName, string strWindowName);

  
  [DllImport("user32.dll")]
  public static extern int GetLastActivePopup(int hWnd);
  
  [DllImport("user32.dll")]
  public static extern int AnyPopup();
  
  [DllImport("user32.dll")]
  public static extern int GetWindowText(int hWnd,StringBuilder lpString,int nMaxCount);
   
  [DllImport("user32.dll")]
  public static extern int EnumThreadWindows(int dwThreadId,CallBack lpfn,int lParam);
  
  [DllImport("user32.dll")]
  public static extern int EnumWindows(CallBack lpfn,int lParam);
  
  [DllImport("user32.dll")]
  public static extern int EnumChildWindows(int hWndParent,CallBack lpfn,int lParam);

         最关键的是对windows操作系统中窗口本质的认识,使用Spy++工具,查找窗口就可以发现,其实对于给定的对话框窗口,其中的任何控件,如图标、文本、确定、取消按钮等都是它的子窗口,本质上还是窗口,所不同的只是,顶级父窗口查找时,用FindWindow函数,而查找子窗口时用FindWindowEx。

         另外比较有用的是EnumWindows,可以遍历所有的顶级父窗口,而EnumChildWindows则是遍历其子窗口。经过测试,EnumThreadWindows的回调函数无法调用,不知道是什么原因,望高手指教。

         所以问题的解决思路就是使用EnumWindows遍历所有的顶级父窗口,对每个顶级父窗口使用EnumChildWindows遍历它的所有控件,每个控件其实也是窗口,拿到该控件的句柄后,就可以调用GetWindowText来获取文本信息了。

         具体实现时,首先需要定义以上API函数的回调函数代理:

   /// <summary>
  /// 回调函数代理
  /// </summary>
  public delegate bool CallBack(int hwnd, int lParam); 


         然后必须针对每个API函数定义代理的实例函数:

/// <summary>
  /// 进程回调处理函数
  /// </summary>
  /// <param name="hwnd"></param>
  /// <param name="lParam"></param>
  /// <returns></returns>
  public static bool ThreadWindowProcess(int hwnd, int lParam)
  {
   EnumChildWindows(hwnd,callBackEnumChildWindows, 0);
   return true;
  }
  
  /// <summary>
  /// 窗口回调处理函数
  /// </summary>
  /// <param name="hwnd"></param>
  /// <param name="lParam"></param>
  /// <returns></returns>
  public static bool WindowProcess(int hwnd, int lParam)
  {
   EnumChildWindows(hwnd,callBackEnumChildWindows, 0);
   return true;
  }
  
  /// <summary>
  /// 子窗口回调处理函数
  /// </summary>
  /// <param name="hwnd"></param>
  /// <param name="lParam"></param>
  /// <returns></returns>
  public static bool ChildWindowProcess(int hwnd, int lParam)
  {
   StringBuilder title = new StringBuilder(200);
   
   int len;
   len = GetWindowText(hwnd, title, 200);
        
   if(len > 0)
   {
    if(title.ToString().IndexOf(GlobalManager.ErrorMessage) != -1 )
    {
     FindError = true;
    }
   }
   
   return true;
  }

         最后要定义回调代理的实例

/// <summary>
  /// 进程窗口回调函数代理
  /// </summary>
  public static CallBack callBackEnumThreadWindows = new CallBack(ThreadWindowProcess);
  
  /// <summary>
  /// 窗口回调函数代理
  /// </summary>
  public static CallBack callBackEnumWindows = new CallBack(WindowProcess);
  
  
  /// <summary>
  /// 子窗口回调函数代理
  /// </summary>
  public static CallBack callBackEnumChildWindows = new CallBack(ChildWindowProcess);



使用的例子:

/// <summary>
  /// 客户端是否弹出对话框
  /// </summary>
  /// <returns></returns>
  public bool IsClientPopupWindows()
  {
   bool FindError = false;
   
   EnumWindows(callBackEnumWindows,0);
   
   return FindError;
  }