delphi - 另一個應用程序中的列錶框內容




winapi listbox (2)

我怎樣才能讀取另一個應用程序的窗口中的列錶框項目? 我可以得到窗口的句柄,但我不知道一個清晰的方式來訪問組件內。


使用EnumChildWindows獲取子控件列表(當主窗口句柄已知時)。

然後查看MSDN上的LB_GETTEXT消息(或Delphi WinSDK幫助)。 不要忘記檢查字符串長度(LB_GETTEXTLEN)並分配內存緩衝區


您可以嘗試從下面的項目中獲取某些內容,如何顯示子窗口,如何篩選給定的類名以及如何獲取列錶框的項目。 我會發表評論,但這將是一個漫長的故事,所以請把它作為一個臨時的帖子 ...

Unit1.pas

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TEnumData = class
    ClassName: string;
    HandleItems: TStrings;
  end;

type
  TForm1 = class(TForm)
    CloneListBox: TListBox;
    HandleEdit: TEdit;
    HandleListBox: TListBox;
    HandleEnumButton: TButton;
    procedure HandleEnumButtonClick(Sender: TObject);
    procedure HandleListBoxClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function EnumCallback(Handle: HWND; EnumData: TEnumData): BOOL; stdcall;
var
  Buffer: array[0..255] of Char;
begin
  Result := True;
  if GetClassName(Handle, Buffer, 256) <> 0 then
    if Buffer = EnumData.ClassName then
      EnumData.HandleItems.Add(IntToStr(Handle));
end;

procedure GetListBoxItems(Handle: HWND; Target: TListBox);
var
  I: Integer;
  ItemCount: Integer;
  TextBuffer: string;
  TextLength: Integer;
begin
  ItemCount := SendMessage(Handle, LB_GETCOUNT, 0, 0);
  if ItemCount <> LB_ERR then
  begin
    Target.Items.BeginUpdate;
    try
      Target.Clear;
      for I := 0 to ItemCount - 1 do
      begin
        TextLength := SendMessage(Handle, LB_GETTEXTLEN, I, 0);
        SetLength(TextBuffer, TextLength);
        SendMessage(Handle, LB_GETTEXT, I, LPARAM(PChar(TextBuffer)));
        Target.Items.Add(TextBuffer);
      end;
    finally
      Target.Items.EndUpdate;
    end;
  end;
end;

procedure TForm1.HandleEnumButtonClick(Sender: TObject);
var
  EnumData: TEnumData;
begin
  EnumData := TEnumData.Create;
  try
    EnumData.ClassName := 'TListBox';
    EnumData.HandleItems := HandleListBox.Items;
    EnumChildWindows(StrToInt(HandleEdit.Text), @EnumCallback, LPARAM(EnumData));
  finally
    EnumData.Free;
  end;
end;

procedure TForm1.HandleListBoxClick(Sender: TObject);
var
  SourceHandle: Integer;
begin
  if TryStrToInt(HandleListBox.Items[HandleListBox.ItemIndex], SourceHandle) then
    GetListBoxItems(SourceHandle, CloneListBox);
end;

end.

Unit1.dfm

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 259
  ClientWidth = 460
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object CloneListBox: TListBox
    Left = 224
    Top = 8
    Width = 228
    Height = 243
    ItemHeight = 13
    TabOrder = 0
  end
  object HandleEnumButton: TButton
    Left = 127
    Top = 8
    Width = 88
    Height = 25
    Caption = 'Enumerate'
    TabOrder = 1
    OnClick = HandleEnumButtonClick
  end
  object HandleListBox: TListBox
    Left = 8
    Top = 40
    Width = 207
    Height = 211
    ItemHeight = 13
    TabOrder = 2
    OnClick = HandleListBoxClick
  end
  object HandleEdit: TEdit
    Left = 8
    Top = 8
    Width = 113
    Height = 21
    TabOrder = 3
    Text = '0'
  end
end

Project1.dpr

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.




listboxitems