// 试试下面代码, 使用 EnumWindows与EnumChildWindows ,<br>// 想找指定内容可以在里面设置过滤条件,返回值为 = False 时停止枚举窗口<br><br>var<br> RootNode: TTreeNode; // 第一层节点对象 - 每个顶层窗口都有(除了排除列表)<br> ChildNodes: array [0..30] of TTreeNode; // 预设最深层=31<br> TreeView: TTreeView; // 窗口树对象<br> CengChi: integer; // 当前层次<br><br> // Class Name , Text Buffer<br> NoList: array [0..11,0..1] of string =<br> (('IME','Default IME'),('MSCTFIME UI','M'),('TfrmKBSetValue','KBSetValue'),<br> ('SystemTray_Main','电表'),('SysFader','SysFader'), ('BCWDBKSYNCHWND','DBK'),<br> ('MS_WebcheckMonitor','MS_WebcheckMonitor'),('OleDdeWndClass','DDE Server Window'),<br> ('#43','MCI command handling window'),('ATI video bios poller','ATI video bios poller'),<br> ('Progman','Program Manager'),('NDDEAgnt','NetDDE Agent')<br>  
;<br><br>function IsInNoList(const psClassName,psBufferText: string): boolean;<br>var<br> i: integer;<br>begin<br> // 字串是否在列表中<br> Result := False;<br> for i := Low(NoList) to High(NoList) do<br> if SameText(NoList[i,0],psClassName) and<br> SameText(NoList[i,1],psBufferText) then<br> begin<br> Result := True;<br> Break;<br> end;<br>end;<br><br>function GetClassText(HWND: HWND): string;<br>var<br> Text: PChar;<br>begin<br> GetMem(Text, 144);<br> GetClassName(HWnd, Text, 144);<br> Result := Text;<br> freemem(Text);<br>end;<br><br>function GetText(HWND: HWND): string;<br>var<br> TextLength: integer;<br> Text: PChar;<br>begin<br> TextLength := SendMessage(HWND, WM_GETTEXTLENGTH, 0, 0);<br> if TextLength = 0 then<br> Result := ''<br> else<br> begin<br> getmem(Text, TextLength + 1);<br> SendMessage(HWND, WM_GetTEXT, TextLength + 1, integer(Text));<br> Result := Text;<br> freemem(Text);<br> end;<br>end;<br><br>function EnumChildWindowProc(HWND: HWND; lParam: LPARAM): BOOL; stdcall;<br>var<br> S, S1: string;<br> Node: TTreeNode;<br>begin<br> // 枚举子窗口回调函数<br> Result := True;<br> S := GetText(HWND);<br> S1 := GetClassText(HWND);<br> Node := TreeView.Items.AddChild(ChildNodes[CengChi], 'H
' + <br> IntToHex(HWND, 8) +<br> ')' + S + '(' + S1 + ')');<br> Node.ImageIndex := -1;<br> Node.StateIndex := HWND;<br> Inc(CengChi);<br> ChildNodes[CengChi] := Node;<br> EnumChildWindows(HWND, @EnumChildWindowProc, lParam); // 递归枚举子窗口<br> Dec(CengChi);<br>end;<br><br>function EnumAllWindow(HWND: HWND; lParam: LPARAM): BOOL; stdcall;<br>var<br> S, S1: string;<br>begin<br> // 枚举所有顶层窗口<br> Result := True;<br> S := GetText(HWND);<br> S1 := GetClassText(HWND);<br> if (S <> '') and<br> ( ((lParam=-1) and (Not IsInNoList(S1,S))) or<br> ((lParam=0) and (Not SameText(S1,'TfrmKBSetValue')) ))<br> then // 排除定义列表<br> begin<br> RootNode := TreeView.Items.AddChild(nil, 'H
' + IntToHex(HWND, 8) + ')' + S + '(' + S1 + ')');<br> RootNode.ImageIndex := -1;<br> RootNode.StateIndex := HWND;<br> CengChi := 0;<br> ChildNodes[CengChi] := RootNode;<br> EnumChildWindows(HWND, @EnumChildWindowProc, lParam); // 枚举所有子窗口<br> end;<br>end;<br><br>// 应用<br>procedure TfrmKBSetValue.mmRefreshAllClick(Sender: TObject);<br>begin<br> // 枚举所有窗口以及窗口的控件<br> <br> Tree.Items.BeginUpdate;<br> Screen.Cursor := crHourGlass;<br> try<br> Tree.Items.Clear;<br> EnumWindows(@EnumAllWindow, StrToInt(BoolToStr(chkFilterSys.Checked)));<br> chkFilterSys.Caption := '过滤系统窗口 ' + IntToStr(Tree.Items.Count);<br> finally<br> Screen.Cursor := crDefault ;<br> Tree.Items.EndUpdate;<br> end;<br>end;<br><br>procedure TfrmKBSetValue.TreeChange(Sender: TObject; Node: TTreeNode);<br>var<br> H: HWND;<br>begin<br> if Tree.Selected = nil then<br> Exit;<br> H := Node.StateIndex;<br> ClassEdit.Text := GetClassText(H); // 类名<br> TextEdit.Text := GetText(H); // 文本<br>end;<br><br><br>// ---- 按类名与出现次数查找窗口句柄<br>var<br> EnumWindowComClass: string;<br> EndmWIndowComHwnd: HWND;<br> ChildIndex, ChildINC :integer;<br><br>function EnumChildProc_Class(HWND: HWND; lParam: LPARAM): BOOL; stdcall;<br>var<br> S: string;<br>begin<br> Result := True;<br> S := GetClassText(HWND);<br> if Uppercase(S) = EnumWindowComClass then<br> begin<br> if ChildInc = ChildIndex then<br> begin<br> EndmWIndowComHwnd := HWND;<br> Result := False;<br> end;<br> Inc(ChildInc);<br> end<br> else<br> begin<br> // 递归查找子窗口,要在同层查找则不要递归调用。<br> EnumChildWindows(HWND, @EnumChildProc_Class, 0); <br> end;<br>end; // Local<br><br>function FindWindowClass(FormHWND: HWND; ComClass: string; Index: integer): HWND;<br>begin<br> ChildIndex := Index; // 取第Index次出现的次数<br> ChildINC := 0; // 找到的次数<br> EndmWIndowComHwnd := 0; // 找到的句柄<br> EnumWindowComClass := Uppercase(ComClass); // 查找类名<br> EnumChildWindows(FormHWND, @EnumChildProc_Class, 0);<br> Result := EndmWIndowComHwnd;<br>end;