我有一个窗口,里面有两个文本字段。
如何使用WinAPI调用获取两个文本字段的句柄?
注意:两个文本框都属于不同的应用程序(我在应用程序A中进行WinAPI调用,文本框位于应用程序B中)。
更新1:
我在调用Invalid window handle
时收到GetClassName
消息。
我认为我的回调函数声明出了问题。
EnumChildWindows
是从TMyClass
的一种方法中调用的,如下所示:
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;
答案 0 :(得分:5)
使用像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;
documentation清楚地表明了这一点。不幸的是,EnumChildWindows
中Windows.pas
的声明完全放弃了回调函数的类型安全性。所以你必须在没有编译器帮助的情况下做到正确。
另请注意,HWND
和THandle
不是一回事。不要混淆它们。