DELPHI 隐藏程序窗口,以及TListView控件,点击标题进行排序
设置视图:
运行效果:
unit HideWindown; interface uses Windows, Messages, SysUtils, Classes, Forms, StdCtrls, ActiveX, ComObj, ShellAPI, Tlhelp32, Vcl.Controls, Vcl.ComCtrls, psapi, Vcl.ExtCtrls; type TForm1 = class(TForm) GetWList: TButton; ListView1: TListView; HideBtn: TButton; ShowBtn: TButton; RadioGroup1: TRadioGroup; Edit1: TEdit; QueryBtn: TButton; procedure GetWListClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure HideBtnClick(Sender: TObject); procedure ShowBtnClick(Sender: TObject); procedure RadioGroup1Click(Sender: TObject); procedure QueryBtnClick(Sender: TObject); procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn); private procedure SetWindowState(isVisible: Boolean); procedure AddListItem(hwnd: HWND; State, Title: string); function FoundTitle(beginIndex, endIndex: Integer): Boolean; var public { Public declarations } end; var Form1: TForm1; FSortColumn: Integer; //当前哪一列正在被排序 FSortAscending: Boolean; //排序的状态 implementation {$R *.dfm} function GetWindowTitle(hwnd: hwnd): string; var Buffer: array[0..255] of Char; begin Result := ''; if GetWindowText(hwnd, Buffer, SizeOf(Buffer)) > 0 then begin Result := Buffer; end; end; procedure EnumWindowsProc(hwnd: hwnd; lParam: lParam); stdcall; const MAX_PATH = 260; // 确保常量定义明确 var ProcessID: DWORD; ProcessHandle: THandle; Title: array[0..MAX_PATH] of Char; ListItem: TListItem; State: string; ShouldAdd: Boolean; begin // 获取进程 ID 和窗口标题 GetWindowThreadProcessId(hwnd, @ProcessID); GetWindowText(hwnd, Title, MAX_PATH); // 如果窗口标题不为空 if Title <> '' then begin // 打开进程以获取更多信息 ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID); if ProcessHandle <> 0 then try // 检查窗口是否可见 ShouldAdd := IsWindowVisible(hwnd); if ShouldAdd then State := '显示' else State := '隐藏'; // 根据 RadioGroup 的选择决定是否添加项 case Form1.RadioGroup1.ItemIndex of 0: // 显示所有窗口 ShouldAdd := True; 1: // 只显示可见窗口 ShouldAdd := ShouldAdd; 2: // 只显示隐藏窗口 ShouldAdd := not ShouldAdd; else ShouldAdd := False; end; // 如果符合条件,添加到 ListView if ShouldAdd then begin Form1.AddListItem(hwnd, State, Title); end; finally CloseHandle(ProcessHandle); end; end; end; procedure TForm1.AddListItem(hwnd: hwnd; State, Title: string); var ListItem: TListItem; begin ListItem := Form1.ListView1.Items.Add; ListItem.Caption := IntToStr(hwnd); ListItem.SubItems.Add(State); ListItem.SubItems.Add(Title); end; procedure TForm1.GetWListClick(Sender: TObject); begin ListView1.Clear; ListView1.Items.BeginUpdate; try EnumWindows(@EnumWindowsProc, 0); finally ListView1.Items.EndUpdate; end; end; procedure TForm1.SetWindowState(isVisible: Boolean); begin var n := ListView1.Items.Count; if (n = 0) or (ListView1.ItemIndex = -1) then begin Application.MessageBox('请先选中一个目标', '错误!', MB_OK + MB_ICONSTOP); exit; end; // 遍历Listview1中的所有选中项 for var i := 0 to ListView1.Items.Count - 1 do begin var selectedItem := ListView1.items[i]; if selectedItem.Selected then begin if isVisible then begin selectedItem.SubItems[0] := '显示'; ShowWindow(StrToInt64(selectedItem.Caption), SW_SHOW); end else begin selectedItem.SubItems[0] := '隐藏'; ShowWindow(StrToInt64(selectedItem.Caption), SW_HIDE); end; Break; end; end; end; procedure TForm1.ShowBtnClick(Sender: TObject); begin SetWindowState(TRUE); //显示应用 end; procedure TForm1.HideBtnClick(Sender: TObject); //隐藏应用 begin SetWindowState(False); end; function CustomSortProc(Item1, Item2: TListItem; ColumnIndex: integer): integer; stdcall; begin if FSortAscending then begin if ColumnIndex = 0 then Result := CompareText(Item1.Caption, Item2.Caption) else Result := CompareText(Item1.SubItems[ColumnIndex - 1], Item2.SubItems[ColumnIndex - 1]); end else begin if ColumnIndex = 0 then Result := CompareText(Item2.Caption, Item1.Caption) else Result := CompareText(Item2.SubItems[ColumnIndex - 1], Item1.SubItems[ColumnIndex - 1]); end; end; procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn); begin if Column.Index = FSortColumn then FSortAscending := not FSortAscending else begin FSortColumn := Column.Index; FSortAscending := True; end; ListView1.CustomSort(@CustomSortProc, FSortColumn); end; function TForm1.FoundTitle(beginIndex, endIndex: Integer): Boolean; begin for var I := beginIndex to endIndex do begin // 检查当前项的标题或子项是否包含Edit1.Text if ansiPos(LowerCase(Edit1.Text), LowerCase(ListView1.Items[I].SubItems[1])) > 0 then begin Result := True; ListView1.Items[I].Selected := True; ListView1.Items[I].MakeVisible(False); Break; end else begin ListView1.Items[I].Selected := False; end; end; end; procedure TForm1.QueryBtnClick(Sender: TObject); var I, indx: Integer; Found: Boolean; label tip; begin indx := ListView1.ItemIndex; if indx = -1 then indx := 0 else if indx <> ListView1.Items.Count - 1 then indx := indx + 1; // 遍历ListView中的所有项 Found := FoundTitle(indx, ListView1.Items.Count - 1); if not Found then begin if indx <> 0 then begin Found := FoundTitle(0, indx - 1); if not Found then goto tip else exit; end; tip: Application.MessageBox('我翻到底了,但是没找到匹配的项.', '错误!', MB_OK + MB_ICONSTOP); end; end; procedure TForm1.RadioGroup1Click(Sender: TObject); begin GetWListClick(Sender); end; procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_RETURN then QueryBtnClick(Sender); //按下回车,执行查询 end; procedure TForm1.FormCreate(Sender: TObject); begin ListView1.ViewStyle := vsReport; //设置视图模式 ListView1.Columns.Add.Caption := '窗口句柄'; ListView1.Columns.Add.Caption := '显示状态'; ListView1.Columns.Add.Caption := '应用程序名称'; //设置列宽.-1表示匹配最长内容,-2表示匹配标题长度 ListView1.Columns[0].Width := -2; ListView1.Columns[1].Width := -2; ListView1.Columns[2].Width := -2; GetWListClick(Sender); FSortColumn := 0; FSortAscending := true; end; end.