4

別のアプリケーションのウィンドウでリストボックスアイテムを読み取るにはどうすればよいですか?ウィンドウのハンドルを取得できましたが、内部のコンポーネントにアクセスする明確な方法がわかりません。

4

2 に答える 2

8

次のプロジェクトから何かを取得することができます。ここでは、子ウィンドウを列挙する方法、特定のクラス名でそれらをフィルター処理する方法、およびリストボックスの項目を取得する方法を示しています。コメントしますが、これは長い話になりますので、一時的な投稿としてお受けください...

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.
于 2012-08-22T10:53:42.703 に答える
5

EnumChildWindowsを使用して子コントロールのリストを取得します(メインウィンドウのハンドルがすでにわかっている場合)。

次に、MSDN(またはDelphi WinSDKヘルプ)のLB_GETTEXTメッセージを確認します。文字列の長さ(LB_GETTEXTLEN)を確認し、メモリバッファを割り当てることを忘れないでください

于 2012-08-22T10:43:28.643 に答える