【问题标题】:How to make transparent Form get mouse enter events?如何让透明Form获取鼠标进入事件?
【发布时间】:2022-03-19 00:47:52
【问题描述】:

我想创建一个 Delphi 应用程序,当用户将鼠标移到屏幕的左上角时,它会做一些有趣的事情。我想了想,打算用下面的策略来做:

  1. 创建一个非常小的 3x3 表单并使其透明并始终位于顶部。也让它没有标题栏或边框。

  2. 为窗体定义鼠标输入事件。

    我在第 1 步中使用以下代码:

    procedure TopLeftForm.FormCreate(Sender: TObject);
    begin
      FormStyle := fsStayOnTop;
    
      self.TransparentColor := true;
      self.TransparentColorValue := self.Color;
      self.BorderStyle := bsNone;
    end;
    

    问题是我发现当Form是透明的时候,是捕捉不到鼠标进入事件的。为了获得鼠标输入事件,我可以使表单不透明,但这样用户就可以在屏幕左上角看到表单,这不是我想要的。

    你对我的问题有什么建议?

【问题讨论】:

  • 恢复 transparent... 设置并设置 AlphaBlend := TrueAlphaBlendValue := 1。这将使表单几乎不可见,但它仍会捕获鼠标事件。
  • 在某些情况下,您的表格仍然可以被其他表格覆盖。我建议您考虑使用 Windows Hooks 来确定鼠标何时位于您想要的位置。

标签: forms delphi events mouse transparent


【解决方案1】:

您想要的是一个“挂钩”,它可以为您提供有关鼠标事件的信息,而不是为您的程序准备的事件。这个话题太大了,无法一次性给你一个操作方法,但这两个链接应该会有帮助:

Understanding how to use Windows Hooks

Mouse Hook Tutorial with Delphi codes

为什么要使用 Windows Hook?

Windows 环境是围绕传递的消息设计的。通常,程序只对直接发送到它自己的窗口的消息感兴趣。尝试确保您的应用程序有一个可以获取消息的窗口,当其他应用程序位于您的同一位置时,它们会阻止其他应用程序接收这些消息,如果另一个窗口位于您的窗口上方,则您将不会收到消息。如果您想了解通常不会发送给您的正在发生的活动 - 例如,在应用程序窗口外单击鼠标。为了使应用程序能够看到不是发往自身的事件,可以使用 Windows 挂钩。

有不同类型的挂钩,具体取决于您要访问的内容。鼠标挂钩适用于您在此处指定的内容。系统为所有已安装的挂钩维护一个“挂钩链”——您有责任将消息传递到链下,并将您自己从链中卸载。

要访问消息,您的挂钩函数将如下所示(代码取自上面的第二个链接并进行了改编):

function MouseHookHandler(ACode: Integer; WParam: WParam; LParam: LParam): LResult; stdcall;
var
  vMouseInfo: PMouseHookStruct;
begin
  if ACode < 0 then
    Result := CallNextHookEx(Data^.MouseHook, ACode, WParam, LParam)
  else
  begin
    vMouseInfo := PMouseHookStruct(Pointer(LParam));
    PostMessage(Data^.AppHandle, WM_CUSTOM_MOUSE, vMouseInfo^.pt.X, vMouseInfo^.pt.Y);
    // we dont want to block the mouse messages
    Result := CallNextHookEx(nil, ACode, WParam, LParam);
  end;
end;

在你的钩子函数中:

  • ACode 取决于钩子的类型,表示事件

  • wParamlParam 具有特定于事件的含义

要传递消息,您应该调用CallNextHookEx - 但是对于某些挂钩,无论如何都会传递消息。

挂钩可以安装为全球的挂钩 - 意味着它们拦截在与调用线程相同的桌面/WinStation 中运行的所有线程上的消息。因此,例如,如果您有多个用户通过 RD 连接,则挂钩仅特定于其中一个桌面。

【讨论】:

  • @DavidHeffernan 感谢您不厌其烦地对答案发表评论。但是,您提供的链接表明链接不应该是答案中的唯一信息。我不认为这里是这种情况。 OP 解释了他们的目标,我已经指出,做他想做的事情的适当方法是采取不同的方向——即使用 Windows Hooks。我确实意识到 SO 上有很多人经常会发布 cmets 说 OP 是荒谬的或不合理的或不合理的设计,但我发现这样的 cmets 无益,粗鲁,在某些情况下只是简单的冒犯。
  • 无益的是没有详细信息而只有链接的答案。扩展答案以至少对您的建议背后的概念给出一个很好的总结。
猜你喜欢
  • 2015-11-30
  • 2021-01-21
  • 2013-01-04
  • 1970-01-01
  • 2011-08-28
  • 2013-03-26
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多