別のプロセスのウィンドウにあるVCLコントロールのHwndがあります。Windows APIを介してそのコントロールのVCL名(TControl.Name
プロパティ)を取得する方法はありますか?WM_SETTEXT
そのウィンドウにはいくつかのTEditがあり、メッセージを送信するために必要なTEditを識別する必要があるため、名前が必要です。
どちらのアプリケーションもDelphi2010で構築されています。
Delphiには、指定されたhWndFindControl()
を返す関数が組み込まれています。TWinControl
ただし、VCLの同じインスタンスで機能します。調べてみるべきだと思います。TWinControlオブジェクトへのポインタを取得した後、その名前(文字列)は+8
オフセットに配置されます。あなたはそれを読むためにReadProcessMemoryを試すことができます。ここでの主な問題は、ニーズに合ったバージョンのFindControl()を作成することです。
編集:(ついにそれを手に入れました:D)GetWinControlName関数を呼び出します
// Get Pointer to TWinControl in another process
function GetWinControl(Wnd: HWND; out ProcessId: THandle): Pointer;
var
WindowAtomString: String;
WindowAtom: ATOM;
begin
if GetWindowThreadProcessId(Wnd, ProcessId) = 0 then RaiseLastOSError;
// This is atom for remote process (See controls.pas for details on this)
WindowAtomString := Format('Delphi%.8X',[ProcessID]);
WindowAtom := GlobalFindAtom(PChar(WindowAtomString));
if WindowAtom = 0 then RaiseLastOSError;
Result := Pointer(GetProp(Wnd, MakeIntAtom(WindowAtom)));
end;
function GetWinControlName(Wnd: HWND): string;
var
ProcessId: THandle;
ObjSelf: Pointer;
Buf: Pointer;
bytes: Cardinal;
destProcess: THandle;
begin
ObjSelf := GetWinControl(Wnd, ProcessId);
destProcess := OpenProcess(PROCESS_VM_READ, TRUE, ProcessId);
if destProcess = 0 then RaiseLastOSError;
try
GetMem(Buf, 256);
try
if not ReadProcessMemory(destProcess, Pointer(Cardinal(ObjSelf) + 8), Buf, 4, bytes) then RaiseLastOSError;
if not ReadProcessMemory(destProcess, Pointer(Cardinal(Buf^)), Buf, 256, bytes) then RaiseLastOSError;
Result := PChar(Buf);
finally
FreeMem(Buf);
end;
finally
CloseHandle(destProcess);
end;
end;
いいえ、コントロールの名前を生成するWindowsAPI関数はありません。これは、Delphiのプライベート実装の詳細です。
ターゲットプロセスのコードを制御する場合は、明らかに、問題を解決するために何らかの形式のIPCを実装できます。それ以外の場合、コントロール名を生成するソリューションには、かなり下品なハッキングが含まれます。1つのアプローチは、同じバージョンのランタイムでビルドされたDLLをプロセスに挿入することです。そのDLLを取得して、HWNDからVCLコントロール参照を見つけ、名前を読み取ります。これには多くのバリエーションがあり、ReadProcessMemory
@ Samalianiの答えによって提供されるうまく行われたトリックは、あなたが飛び越えなければならないフープの典型です。
しかし、私はあなたの問題に対するはるかに簡単な解決策を考えることができます。すべての編集コントロールのハンドルを見つけ、それらのハンドルを使用してコントロールの座標を受け取ります。編集コントロールの相対的な位置は、どれが目的のターゲットであるかを識別するのに十分です。そして、いくつかのより有用な考えについては、以下の@dthorpeのコメントを読んでください。