在任何VCL组件上单击鼠标,然后确定其.Tag值

时间:2011-11-10 17:06:58

标签: delphi

我正在使用本土翻译工具。 (下次我将使用其中一个库,如下所述:delphi translation tool。)

我的译员抱怨翻译一长串字符串很困难,因为他们没有在上下文中看到它们(在它们出现的屏幕上)。

一位译者提出了一个很好的建议,即他应该能够点击某个组件来更改其文本。我可以实现这个如果我可以找到一种方法来挂钩程序范围,这是一个事件,这样当用户在按住CTRL键的同时点击一个组件时,就会调用一个事件处理程序。事件处理程序将确定组件是否具有.Caption属性,如果是,则获取Tag组件的值(然后允许一些用户输入。)

(每个可翻译组件在其Tag中都有唯一的整数,我用它来查找组件的.Caption。)

有关如何解决这个问题的任何建议?这是我的头脑。我需要像表单的KeyPreview这样的东西,但是对于鼠标点击可以找出点击的VCL组件,并确定它的.Tag值。

汤姆

编辑:

使用David H.的建议,我得到的唯一事件是当应用程序获得焦点或失去它时。我做错了什么?

    function TForm1.AppHookFunc(var Message : TMessage) : Boolean;
    begin
      Result := FALSE;
      inc(i); outputdebugstring(Pchar(inttostr(i) + ': ' + IntTostr(Message.msg)));
      if Message.Msg = WM_MBUTTONDOWN then
        begin      Beep;
        //...DoSomething...
        //Result := True;
        end;
    end;

    procedure TForm1.FormCreate(  Sender: TObject);
    begin
      Application.HookMainWindow(AppHookFunc);
    end;

    procedure TForm1.FormDestroy(
      Sender: TObject);
    begin
      Application.UnHookMainWindow(AppHookFunc);
    end;

编辑2

我快到了!但FindDragTarget很少返回任何东西,只有零。如果我用一个巨大的按钮覆盖大部分控件,我有时可以让它工作。收到的tagMSG中的X,Y坐标是相对于对照的。虽然他们相对于表格我会的。我还在使用不同的事件钩子吗?任何建议:

  procedure TForm1.ApplicationEvents1Message( var Msg: tagMSG;
                                              var Handled: Boolean);
  var
    Target: TControl;
    Point: TPoint;
  begin
    Handled := FALSE;
    if (Msg.Message = WM_LBUTTONDOWN) And isAltDown then
      begin
        Point.X := LongRec(Msg.lParam).Lo;
        Point.Y := LongRec(Msg.lParam).Hi;
        Target := FindDragTarget( Point, {AllowDisabled=}TRUE);
        if Assigned(Target) then
          begin
            if Target Is TButton then
              outputdebugString(Pchar(TButton(Target).Caption));
          end
        else
          outputdebugstring(Pchar(IntToStr(Point.X) + ', ' + IntToStr(Point.Y)));
      end;
  end;

最终编辑:

我将上面的代码更改为使用GetCursorPos而不是Msg.lParam。它现在正在运作。很酷! SO Rocks!

感谢您的帮助!

1 个答案:

答案 0 :(得分:10)

我假设这是一个VCL应用程序。对于FireMonkey,这不起作用。

  1. 添加Application.OnMessage事件处理程序。
  2. 在事件处理程序中查找WM_LBUTTONDOWNWM_LBUTTONUP,并检查修改键状态是否符合您的要求,例如: CTRL已关闭。
  3. 调用FindDragTarget传递与鼠标事件关联的位置。这将为您提供鼠标控制,如果确实有一个(即检查nil)。
  4. 做任何你想要的控制。