Mega Code Archive

 
Categories / Delphi / OOP
 

Cleaning up EnumWindows

Title: Cleaning up EnumWindows. Question: I`ve seen how to use EnumWindows to get a list of all the current windows - but I get back a bunch of blanks and things I`ve never heard of. What`s going on? Answer: The follwoing appiles to Win95, 98 and NT - I have no idea if it works on 2000. EnumWindows and it's callback EnumWndProc don't pull pack the handles of all the forms running, it pulls back all the handles of the Windowed Controlls ( i.e., forms, Editboxes, Memos, ect.) So, if your tring to use EnumWindows to find all the open forms on a system, you have to seperate the wheat from the chaff, so to speak. To do this, I've found that two API functions, IsChild and GetClassName work well. IsChild Compares two Handles and returns weather or not the second is the child of the first. This should rid your list of most of the EditBoxes, Memos ect. GetClassName returns the class name of a Windowed Object - i.e., TForm TEditBox, ect. (Please note: this is often returned as the Windows class name or the C Class name, depending apon what language the App was developed under.) Here's the prototypes for these functions: Function GetClassName( hWnd : THandle; // handle of window lpClassName : PChar; // buffer for class name nMaxCount : Integer; // size of buffer, in characters ) : integer; // Returns number of Characters copied, 0 = an Error Function IsChild( parWhnd : THandle; // Handle of Parent Object ChdWhnd : THandle; // Handle of Child Object ) : Boolean; // Returns True if ParWhnd is the Parent of ChdWhnd Don't worry - There both in the Windows Unit. The following code impiments this methodology - Please pay close attention to the scope that the variables are in. It's supper touchy because of the callback. Uses Windows; Interface type THandleArray = Array of THandle; Procedure GetWindows( out WindowList : THandleArray; out Count : Integer; BadClassName : String); Implimentation var Wind : THandleList; //Temporary Storage of the Handles var WinCount : Integer; //Temporary Counter Function EnumWndProc(hwnd : THandle; Param : Cardinal) : Boolean; export; StdCall; begin // Remember - this function loops through for every window Result := True; //Get The next Handle winCount := WinCount + 1; //Increase the count SetLength(Wind, winCount); //Expand the Dynamic Array Wind[(WinCOunt - 1)] := hwnd; // Set the handle into the Temp Storage end; Procedure GetWindows( out WindowList : THandleArray; out Count : Integer; BadClassName : String); var I, II, Count : Integer; var AddWin : Boolean; var Classname : String; begin winCount := 0; /Set The Count to 0 EnumWindows(@EnumWndProc, 0); // Start the loop through WnumWndProc Count := 0; for I := 0 to (WinCount - 1) do Begin AddWin := True; // Set The Add Flag to true GetClassName(Wind[I], PChar(ClassName), 255) // get the class name ClassName := PChar(ClassName); //Reformat the classname If Lowercase(ClassName) = Lowercase(BadClassName) then AddWin := False; // set flag acordingly for II := 0 to (WinCOunt - 1) do begin if I II then // Don't check yourself! begin if ((Wind[I] = Wind[II]) or (isChild(Wind[II], Wind[I])) then AddWin := False; // check for children and dups end; end; if AddWin = True then begin Count := Count + 1; SetLength(tempList, Count); tempList[(Count - 1)] := Wind[I]; end; end; end;