我曾经参与了一个大型项目,其中有许多框架和许多动态创建的控件。当软件运行时,很难弄清楚哪个控件是哪个,以及它在哪里创建。
因此,我编写了这个小代码片段,告诉您鼠标下面是哪个控件。只有在调试模式下编译程序时,我才会显示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);
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;
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);
end;
end;
一旦我们深入到形式中,我们就会离开递归调用。
提示:您可以将FindVCLWindow替换为FindDragTarget以使代码执行您想要的操作。
FindVCLWindow()
不适用于你以及应该使用哪个函数。你也知道这个函数返回什么,把ctrl
变量改为该类型。如果不能猜出来,请查看帮助中关于额外的AllowDisabled
参数意义的说明。 - Tom Brunberg