1

内部に 2 つのテキスト フィールドがあるウィンドウがあります。

WinAPI 呼び出しを使用して両方のテキスト フィールドのハンドルを取得するにはどうすればよいですか?

注: 両方のテキスト ボックスは別のアプリケーションに属しています (アプリケーション A で WinAPI 呼び出しを行い、テキスト ボックスはアプリケーション B にあります)。

更新 1:

Invalid window handle呼び出すとメッセージが表示されますGetClassName

コールバック関数の宣言に何か問題があると思います。

EnumChildWindowsTMyClass次のようなメソッドの 1 つから呼び出されます。

EnumChildWindows(handle, @TMyClass.CBList, 0);

コールバック関数のコードは次のとおりです。

function TMyClass.CBList(Win: THandle; lp: LPARAM): Boolean; stdcall;
var
  ClassName:array [1..1024] of Char;
begin
  GetClassName(Win, PChar(@ClassName), 1024);
  OutputDebugString(PChar('SysErrorMessage(GetLastError): '));

  result := true;
end;
4

1 に答える 1

5
  1. FindWindow または EnumWindows を使用して、ターゲット アプリケーションのトップ レベル ウィンドウを見つけます。
  2. EnumChildWindows を呼び出して、最上位ウィンドウのすべての子を列挙します。
  3. 列挙型コールバックで GetClassName を使用して、目的のウィンドウ クラスを確認します。たとえば、生の Win32 編集ウィンドウの場合は EDIT になります。

Spy++ のようなツールを使用して、ターゲット アプリの構造を理解し、それが使用する正確なウィンドウ クラス名を見つけます。


電話のかけ方に関するコメントでのあなたの質問は、GetClassName私に考えさせました。XE3 を使用している場合は、シンプルなタイプのレコード ヘルパーを記述してHWND、クラス名を取得するための構文をわかりやすくすることができます。

type
  THWNDHelper = record helper for HWND
  private
    function GetClassName: string;
  public
    property ClassName: string read GetClassName;
  end;

function THWNDHelper.GetClassName: string;
var
  Buffer: array [0..255] of Char;
begin
  if Winapi.Windows.GetClassName(Self, @Buffer, Length(Buffer))=0 then
    RaiseLastOSError;
  Result := Buffer;
end;

そしてhwnd.ClassName、ウィンドウ クラス名を取得するように記述できます。もちろん、XE3 を使用していない場合は、次のように実行できます。

function GetWindowClassName(hwnd: HWND): string;
var
  Buffer: array [0..255] of Char;
begin
  if GetClassName(hwnd, @Buffer, Length(Buffer))=0 then
    RaiseLastOSError;
  Result := Buffer;
end;

ウィンドウクラス名の長さがそれより長くならないように制限されているため、256 のバッファー長を使用していることに注意してください。


更新のコードに関しては、コールバックにインスタンス メソッドを使用しないでください。コールバックは次のように宣言する必要があります。

function EnumChildWindowsCallback(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
begin
  OutputDebugString(PChar(GetWindowClassName(hwnd)));
  Result := True;
end;

これはドキュメントで明確にされています。EnumChildWindows残念ながら、 inの宣言はWindows.pas、コールバック関数の型安全性を完全に放棄します。したがって、コンパイラの助けを借りずに正しく処理する必要があります。

HWNDTHandleは同じものではないことにも注意してください。それらを混同しないでください。

于 2012-10-17T07:26:19.963 に答える