delphi 识别鼠标光标下的组件不适用于TIimage控件

omvjsjqw  于 2023-03-12  发布在  其他
关注(0)|答案(2)|浏览(135)

我使用下面的过程来识别 Delphi XE 3中鼠标下的控件。对于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的名称-我是否遗漏了一些非常简单的东西?

7kjnsjlb

7kjnsjlb1#

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;
gzszwxb4

gzszwxb42#

我曾在一个大型项目中工作过,这个项目有很多框架和很多动态创建的控件。当软件运行时,很难弄清楚哪个控件是哪个控件,以及它是在哪里创建的。所以,我编写了这个tiny piece of code,它告诉你哪个控件在鼠标下。只有当程序在调试模式下编译时,我才显示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;

一旦深入到表单,我们就离开递归调用。
提示:您可以用FindDragTarget替换FindVCLWindow,以使代码执行您想要的操作。

相关问题