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.

 

posted @ 2024-10-20 11:36  一曲轻扬  阅读(26)  评论(0编辑  收藏  举报