How can I find an error window on the desktop, whether it is a parent window or a child window, and obtain its error information?
It mainly uses API functions:
Copy and save
[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);
The most important thing is to understand the nature of windows in windows. You can find the window by using the spy ++ tool. In fact, for a given dialog box window, any of its controls, the cursor, text, OK, and cancel buttons are all subwindows. They are essentially windows. The difference is that when the top parent window is searched, the findwindow function is used, when searching for sub-Windows, use find1_wex.
In addition, enumwindows can traverse all top-level parent windows, while enumchildwindows can traverse its subwindows. After testing, the callback function of enumthreadwindows cannot be called. I don't know why.
Therefore, the solution is to use enumwindows to traverse all top-level parent windows, and use enumchildwindows to traverse all its controls for each top-level parent window. Each control is actually a window, after obtaining the control handle, you can call getwindowtext to obtain text information.
For specific implementation, you must first define the callback function proxy of the above API functions:
Copy and save
/// <Summary>/// Callback function proxy/// </Summary>Public Delegate BoolCallback (IntHwnd,IntLparam );
Then you must define the proxy instance function for each API function:
Copy and save
/// <Summary>/// Process callback Handler/// </Summary>/// <Param name = "hwnd"> </param>/// <Param name = "lparam"> </param>/// <Returns> </returns>Public Static BoolThreadwindowprocess (IntHwnd,IntLparam) {enumchildwindows (hwnd, callbackenumchildwindows, 0 );Return True;}/// <Summary>/// Window callback Handler/// </Summary>/// <Param name = "hwnd"> </param>/// <Param name = "lparam"> </param>/// <Returns> </returns>Public Static BoolWindowprocess (IntHwnd,IntLparam) {enumchildwindows (hwnd, callbackenumchildwindows, 0 );Return True;}/// <Summary>/// Subwindow callback Handler/// </Summary>/// <Param name = "hwnd"> </param>/// <Param name = "lparam"> </param>/// <Returns> </returns>Public Static BoolChildwindowprocess (IntHwnd,IntLparam) {stringbuilder Title =NewStringbuilder (200 );IntLen; Len = getwindowtext (hwnd, title, 200 );If(LEN> 0 ){If(Title. tostring (). indexof (globalmanager. errormessage )! =-1) {finderror =True;}}Return True;}
Finally, you need to define the instance of the callback proxy.
Copy and save
/// <Summary>/// Process window callback function proxy/// </Summary>Public StaticCallback callbackenumthreadwindows =NewCallback (threadwindowprocess );/// <Summary>/// Window callback function proxy/// </Summary>Public StaticCallback callbackenumwindows =NewCallback (windowprocess );/// <Summary>/// Subwindow callback function proxy/// </Summary>Public StaticCallback callbackenumchildwindows =NewCallback (childwindowprocess );
Example:
Copy and save
/// <Summary>/// Whether the dialog box is displayed on the client/// </Summary>/// <Returns> </returns>Public BoolIsclientpopupwindows (){BoolFinderror =False; Enumwindows (callbackenumwindows, 0 );ReturnFinderror ;}