我有一个窗口,里面有两个文本字段.
如何使用WinAPI调用获取两个文本字段的句柄?
注意:两个文本框都属于不同的应用程序(我在应用程序A中进行WinAPI调用,文本框位于应用程序B中).
更新1:
我Invalid window handle在调用时收到消息GetClassName.
我想我的回调函数声明有问题.
EnumChildWindows从这样的方法之一调用TMyClass:
EnumChildWindows(handle, @TMyClass.CBList, 0);
Run Code Online (Sandbox Code Playgroud)
这是回调函数的代码.
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;
Run Code Online (Sandbox Code Playgroud)
使用像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;
Run Code Online (Sandbox Code Playgroud)
然后您可以编写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;
Run Code Online (Sandbox Code Playgroud)
请注意,我使用的缓冲区长度为256,因为窗口类名称长度不得超过该长度.
关于更新中的代码,不得使用实例方法进行回调.必须像这样声明回调:
function EnumChildWindowsCallback(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
begin
OutputDebugString(PChar(GetWindowClassName(hwnd)));
Result := True;
end;
Run Code Online (Sandbox Code Playgroud)
这在文档中已明确说明.不幸的声明EnumChildWindows中Windows.pas完全放弃键入回调函数的安全性.所以你必须在没有编译器帮助的情况下做到正确.
还要注意HWND并且THandle不是一回事.不要混淆它们.