我正在使用以下过程来识别我在 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
的名字-我错过了一些非常简单的东西吗?
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;
我参与了一个大型项目,该项目有很多框架和很多动态创建的控件。当软件运行时,很难弄清楚哪个控件是哪个以及它是被创建的。 所以,我写了这个一小段代码告诉你哪个控件在鼠标下。只有当程序在调试模式下编译时,我才显示 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 使代码执行您想要的操作。