Identify Component under mouse cursor does not work with TImage Control

问题描述 投票:0回答:2

我正在使用以下过程来识别我在 Delphi XE3 中鼠标下的控件。一切都适用于

vcl.contols
。但是,当鼠标悬停在
TImage
上时,不会返回任何控件名称。

procedure TMainForm.ApplicationEvents1Idle(Sender: TObject; var Done: oolean);    
var
  ctrl : TWinControl;
begin    
  ctrl := FindVCLWindow(Mouse.CursorPos);     
  if ctrl <> nil then begin    
    Label2.caption := ctrl.Name;    
    //do something if mouse is over TLabeledEdit    
    if ctrl is TLabeledEdit the begin    
      Caption := TLabeledEdit(ctrl).Text;    
    end;
  end;
end;

有没有一种简单的方法来访问

TImage
的名字-我错过了一些非常简单的东西吗?

delphi vcl delphi-xe3
2个回答
7
投票

FindVCLWindow
查找
TWinControl
的后代。由于
TImage
不是窗口控件,也没有继承自
TWinControl
,所以
FindVCLWindow
将无法找到它。就像它将无法在其祖先中找到任何其他没有
TWinControl
类的控件一样。

但是,有一个类似的函数

FindDragTarget
将返回任何 VCL 控件,包括非窗口控件。

这个函数也在

Vcl.Controls
中声明,就像
FindVCLWindow

function FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean): TControl;

它有额外的参数 -

AllowDisabled
控制是否返回禁用的控件。

您应该按如下方式重写您的方法 - 请注意,

ctrl
必须重新声明为
TControl

procedure TMainForm.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
var
  ctrl : TControl;
begin
  ctrl := FindDragTarget(Mouse.CursorPos, true);
  if ctrl <> nil then
    begin
      Label2.caption := ctrl.Name;
      ...
    end;
end;

0
投票

我参与了一个大型项目,该项目有很多框架和很多动态创建的控件。当软件运行时,很难弄清楚哪个控件是哪个以及它是被创建的。 所以,我写了这个一小段代码告诉你哪个控件在鼠标下。只有当程序在调试模式下编译时,我才显示 Digger 表单,所以它对客户不可用,而只对开发人员可用。

代码非常简单。这一切都恢复到一个名为 ShowParentTree 的递归函数。 我们开始从 Digg 调用 ShowParentTree,它在应用程序空闲时调用:

procedure TfrmDigger.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
begin
   Digg;
end;

Digg 功能如下所示。魔术是由 FindVCLWindow 完成的:

procedure TfrmDigger.Digg;
VAR Ctrl : TWinControl;
begin
 Ctrl := FindVCLWindow(Mouse.CursorPos); { It will not “see” disabled controls }

 if Ctrl <> NIL then
 begin
  VAR s:= ctrl.Name+ ‘ (‘+ ctrl.ClassName + ‘)’;
  Memo.Text:= s+ #13#10+ ShowParentTree(ctrl, 1);

 Caption := s;
 if ctrl is TLabeledEdit then
 Caption := Caption + ‘ Text: ‘+TLabeledEdit(ctrl).Text;
end;
end;

一旦我们获得了鼠标下的控件,ShowParentTree 就会通过递归调用自身来挖掘该控件的父级,以及父级的父级等等:

function ShowParentTree(Control: TControl; Depth: Integer): string; { Recursive }
VAR Ctrl: TControl;
begin
  Ctrl:= Control.Parent;
  if Ctrl = NIL
  then Result:= ”
  else
  begin
     Result:= System.StringOfChar(‘ ‘, Depth);
     Inc(Depth);
     Result:= Result+ ‘ ‘+ Ctrl.Name + ‘ (‘+ Ctrl.ClassName+ ‘)’+ #13#10+ ShowParentTree(Ctrl, Depth); { Recursive }
  end;
end;

一旦深入到表单,我们就离开递归调用。

提示:您可以将 FindVCLWindow 替换为 FindDragTarget t 使代码执行您想要的操作。

© www.soinside.com 2019 - 2024. All rights reserved.