2012-10-17 55 views
1

我有一个窗口,里面有两个文本字段。如何查找窗口中的所有文本字段?

如何获得使用WinAPI调用的两个文本字段的句柄?

注意:这两个文本框属于不同的应用程序(我在应用程序A中进行WinAPI调用,文本框位于应用程序B中)。

更新1:

调用GetClassName当我得到Invalid window handle消息。

我想我的回调函数声明有问题。

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

你可以使用构造函数返回的句柄吗? – ammar26

+0

我有以下情况:我在Delphi中有应用程序A,此应用程序通过WinAPI与应用程序B交互。我有应用程序A的源代码,但不是应用程序B的源代码。 因此 - 不,我不能从构造函数中获取这些值,因为它们在应用程序B中。 –

+0

应用程序B也是用Delphi编写的。 –

回答

5
  1. 使用FindWindow函数或EnumWindows的找到目标应用程序的顶层窗口。
  2. 调用EnumChildWindows枚举顶层窗口的所有子项。
  3. 在枚举回调中,使用GetClassName检查所需的窗口类。例如,它将编辑一个原始的Win32编辑窗口。

使用像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明确。不幸的是Windows.pasEnumChildWindows的声明完全放弃了回调函数的类型安全性。所以你必须在没有编译器帮助的情况下做对。

还要注意的是,HWNDTHandle不是一回事。不要混淆。

+0

第3步:这是将当前控件的类名读入ClassName变量的正确方法吗? 'GetClassName(Win,PAnsiChar(ClassName),1024)'其中'ClassName:array [1..1024] of Char;'。 –

+1

使用'PChar(@ClassName)'或'@ClassName [1]'作为第二个参数。 –

+0

如何在调试输出中打印'ClassName'? 'OutputDebugString(PChar('ClassName:'+ ClassName));'不起作用(产生类似于'ClassName:'的输出)。 –

相关问题