鼠标指针下组件识别在TImage控件中无法工作

4

我正在使用以下过程来识别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的名称 - 我是不是忽略了什么非常简单的东西?


我已经寻找了一个使用FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean): TControl的示例。 - WobblyBob
我已经寻找了一个使用FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean): TControl的例子,但是一直没有找到:(有人能指点我正确的方向或提供示例,包括必须添加到“uses”部分的任何对象/项吗? - WobblyBob
4
我友情建议你停止成为一个“复制粘贴程序员”,通过阅读文档和自己思考来学习。你已经知道了为什么FindVCLWindow()不适用于你以及应该使用哪个函数。你也知道这个函数返回什么,把ctrl变量改为该类型。如果不能猜出来,请查看帮助中关于额外的AllowDisabled参数意义的说明。 - Tom Brunberg
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;

非常感谢Dalija - 我的问题已经解决了 - 你真是个明星 ;) - WobblyBob
这是一个宝石。谢谢。 - Frank Pedro

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以使代码执行您想要的操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接