【问题标题】:Any method to cast a Handle?有什么方法可以铸造一个句柄?
【发布时间】:2012-06-02 17:48:08
【问题描述】:

早安,

我有来自不同非 VLC 对象(例如(SysListView32、ToolbarWin32)的不同句柄,我想知道是否有任何方法可以转换这些句柄(HWND)。

例如,我得到了开始按钮(位于桌面左下角)的句柄。然后我找到了类名“Button”。

我想投射他并从他那里检索标题属性“开始”。例如:

type 
  TButtonStartMenuFictiveClass = class(TButton)
  public
    Text: string;
  end;

if classname = 'button' then
begin
  ShowMessage((objecthandle as TButtonStartMenuFictiveClass).Text);
end;

我希望挂钩所有对象并显示它们的文本。就像 Windows 中的叙述者。

【问题讨论】:

  • 我不太明白微软的讲述者是谁写的
  • 您不能将 HWND 转换为 Delphi 类,因为您不能将自行车转换为法拉利,因为它们都有轮胎。类型转换不能将某些东西转换成绝对不是的东西;类型转换不能执行魔术。您也不能将 Delphi TEdit(这是一个 HWND)的句柄类型转换为 TTreeView(也有一个 HWND 句柄)并访问节点,因为 TEdit 不是TTreeView.
  • 搜索 Microsoft Active Accessibility (MSAA) 和/或 UIAutomation。准备好发现这些框架在其他语言中更易于使用
  • @Ken,不过最好把自行车打成法拉利 :-)
  • @TLama,特别是如果您可以不止一次这样做。你可以变得相当富有——我想这将是一个能够低买高卖的真实案例。 ;-)

标签: windows delphi casting handle


【解决方案1】:

在某些情况下,您可以实例化一个 VCL 对象并将外部HWND 分配给它的WindowHandle 属性,例如:

var
  S: String;

with TButton.Create(nil) do
try
  WindowHandle := TheButtonWnd;
  try
    S := Caption;
  finally
    WindowHandle := 0; // important
  end;
finally
  Free;
end;

【讨论】:

  • 不过,这并不是将 HWND 类型转换为 Delphi 对象,这就是问题所在。
  • 类型转换的目的是转换/访问一种类型的值,就好像它是另一种类型一样。显然,HWND 不能被类型转换为 VCL 对象,但可以作为一个对象访问。这个问题确实询问了如何访问 HWND 的属性,就好像它来自 VCL 对象一样,所以我提供了一种方法来做到这一点。不同的技术,相同的结果。
【解决方案2】:

正如我在您的previous question 中解释的那样,您需要使用 Windows API 来访问外部窗口控件的属性。您不能简单地将窗口句柄转换为对象。它们不是指向 Delphi 对象的指针。

我链接的示例不仅显示了您悬停的控件的类名,还显示了控件的标题(文本)。这个函数也可以解决问题:

function GetWndText(const Handle: Hwnd): string;
var
  Len: Integer;
begin
  Len := GetWindowTextLength(Handle) + 1;
  SetLength(Result, Len);
  GetWindowText(Handle, PChar(Result), Len);
end;

【讨论】:

  • 如果HWND 属于调用者以外的另一个进程,则不能使用GetWindowTextLength()GetWindowText()。文档说了这么多。您必须直接将WM_GETTEXTLENWM_GETTEXT 消息发送到HWND
  • 我知道文档是这么说的,但我自己从未真正经历过这种限制。如果您尝试该功能,您会发现它在其他进程中运行良好。
猜你喜欢
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
  • 2015-05-21
  • 2013-05-27
  • 1970-01-01
相关资源
最近更新 更多