zoukankan      html  css  js  c++  java
  • 详解 EnumWindows 与 EnumWindowsProc 回复 "SplendourChiang" 的问题


    问题来源: http://www.cnblogs.com/del/archive/2009/10/16/1584488.html#1727205

    // EnumWindows 的功能是遍历所有顶层窗口
    function EnumWindows(
      lpEnumFunc: TFNWndEnumProc; {回调函数指针}
      lParam: LPARAM              {给回调函数的参数, 它对应回调函数的第二个参数}
    ): BOOL; stdcall; //成功与否, 其实是返回了回调函数的返回值
    
    // EnumWindows 专用的回调函数的格式:
    function EnumWindowsProc(
      hwnd: HWND;        {找到的窗口句柄}
      lParam: LPARAM     {EnumWindows 传给的参数; 因为它是指针, 可传入, 但一般用作传出数据}
    ): Boolean; stdcall; {函数返回 False 时, 调用它的 EnumWindows 将停止遍历并返回 False}
    

    例一: 获取所有顶层窗口的句柄

    //需要个 TListBox 显示数据
    function EnumWindowsProc_1(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
    begin
      Form1.ListBox1.Items.Add(IntToStr(hwnd));
      Result := True;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      EnumWindows(@EnumWindowsProc_1, 0);
    end;
    

    例二: 获取所有顶层窗口的标题(排除无标题窗口)

    function EnumWindowsProc_2(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
    var
      buf: array[Byte] of Char;
    begin
      GetWindowText(hwnd, buf, SizeOf(buf));
      if buf <> '' then Form1.ListBox1.Items.Add(buf);
      Result := True;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      EnumWindows(@EnumWindowsProc_2, 0);
    end;
    

    例三: 查找第一个记事本的句柄

    function EnumWindowsProc_3(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
    var
      buf: array[Byte] of Char;
    begin
      GetClassName(hwnd, buf, SizeOf(buf));
      if buf = 'Notepad' then
      begin
        Form1.ListBox1.Items.Add(Format('记事本句柄: %d', [hwnd]));
        Result := False; //如果不需要继续找, 找到第一个就结束
      end
      else
      begin
        Result := True;
      end;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      EnumWindows(@EnumWindowsProc_3, 0);
    end;
    

    例四: 获取所有顶层窗口的句柄与类名数组:

    type
      TMyStruct = record
        hwnd: HWND;
        ClassName: string;
      end;
      TMyStructArray = array of TMyStruct;
      PMyStructArray = ^TMyStructArray;
    
    function EnumWindowsProc_4(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
    var
      buf: array[Byte] of Char;
      p: PMyStructArray;
    begin
      GetClassName(hwnd, buf, SizeOf(buf));
      p := PMyStructArray(lParam);
      SetLength(p^, Length(p^) + 1);
      p^[High(p^)].hwnd := hwnd;
      p^[High(p^)].ClassName := buf;
      Result := True;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Arr: TMyStructArray;
    begin
      EnumWindows(@EnumWindowsProc_4, Integer(@Arr));
      ShowMessage(IntToStr(Length(Arr)));                         //总数
      ShowMessageFmt('%d - %s', [Arr[0].hwnd, Arr[0].ClassName]); //第一个元素
    end;
    

    例五: 重复上一个例子, 如果数组是全局遍历并不靠参数传递, 代码会简单些

    type
      TMyStruct = record
        hwnd: HWND;
        ClassName: string;
      end;
    var
      Arr: array of TMyStruct;
    
    function EnumWindowsProc_5(hwnd: HWND; lParam: LPARAM): Boolean; stdcall;
    var
      buf: array[Byte] of Char;
    begin
      GetClassName(hwnd, buf, SizeOf(buf));
      SetLength(Arr, Length(Arr) + 1);
      Arr[High(Arr)].hwnd := hwnd;
      Arr[High(Arr)].ClassName := buf;
      Result := True;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      SetLength(Arr, 0);
      EnumWindows(@EnumWindowsProc_5, Integer(Arr));
      ShowMessage(IntToStr(Length(Arr)));                         //总数
      ShowMessageFmt('%d - %s', [Arr[0].hwnd, Arr[0].ClassName]); //第一个元素
    end;
    

    SplendourChiang 的目的是获取进程 ID 和窗口句柄的数组, 按 "例四" 的方法给修改如下:

    type
      MyProcessInfo = record
        PID, WinHWND : DWORD;
      end;
      TMyProcessInfoArray = array of MyProcessInfo;
      PMyProcessInfoArray = ^TMyProcessInfoArray;
    
    function MyEnumWindowsProc(Wnd: DWORD; lParam: LPARAM): Bool; stdcall;
    var
      PID : DWORD;
      p: PMyProcessInfoArray;
    begin
      GetWindowThreadProcessID(Wnd, @PID);
      p := PMyProcessInfoArray(lParam);
      SetLength(p^, Length(p^) + 1);
      p^[High(p^)].PID := PID;
      p^[High(p^)].WinHWND := Wnd;
      Result := True;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      CC: TMyProcessInfoArray;
    begin
      SetLength(CC, 0);
      EnumWindows(@MyEnumWindowsProc, Integer(@CC));
      ShowMessage(IntToStr(Length(CC)));                     //总数
      ShowMessageFmt('%d - %d', [CC[0].PID, CC[0].WinHWND]); //第一个元素
    end;
    
  • 相关阅读:
    hdu 1715
    hdu 1370
    hdu 2370
    hdu 1393
    hdu 1564
    hdu 1720
    hdu 1342
    SQL技巧(sp_procedure_params_rowset,SQL中设置数据值为null)
    Control ‘dg’ of type 'GridView' must be placed inside a form tag with runat=server
    GridView事件中获取rowIndex值
  • 原文地址:https://www.cnblogs.com/del/p/1627110.html
Copyright © 2011-2022 走看看