如何让透明Form获取鼠标输入事件?
我想创建一个 Delphi 应用程序,当用户将鼠标移到屏幕左上角时,它会执行一些有趣的操作。我考虑了一下并计划采用以下策略:
创建一个非常小的 3x3 表单并使其透明并始终位于顶部。也使其没有标题栏或边框。
为表单定义鼠标进入事件。
我在步骤1中使用以下代码:
procedure TopLeftForm.FormCreate(Sender: TObject);
begin
FormStyle := fsStayOnTop;
self.TransparentColor := true;
self.TransparentColorValue := self.Color;
self.BorderStyle := bsNone;
end;
问题是我发现当表单透明时,它无法捕获鼠标输入事件。我可以使表单不透明,以便获得鼠标输入事件,但这样用户可以在屏幕左上角看到表单,这不是我想要的。
您对我的问题有什么建议?
I want to create a Delphi application that does something interesting when the user moves his mouse over the top-left corner of the screen. I thought about it and plan to do it with the following strategy:
Create a very small 3x3 Form and make it transparent and always on top. Also make it with no title bar or border.
Define mouse enter event for the Form.
I use the following code for step 1:
procedure TopLeftForm.FormCreate(Sender: TObject);
begin
FormStyle := fsStayOnTop;
self.TransparentColor := true;
self.TransparentColorValue := self.Color;
self.BorderStyle := bsNone;
end;
The problem is that I found that when the Form is transparent, it can't capture mouse enter events. I could make the Form not transparent in order to get mouse enter events, but that way users can see the Form at the top-left screen corner, which is not what I want.
What's your suggestions to my problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您想要的是一个“钩子”,它可以为您提供有关鼠标事件的信息,而这些事件并不适用于您的程序。这是一个太大的主题,无法一次性为您提供操作方法,但这两个链接应该会有所帮助:
了解如何使用 Windows Hooks
使用 Delphi 代码的鼠标钩子教程
为什么使用 Windows Hook?
Windows 环境是围绕传递消息而设计的。通常,程序只对直接发送到其自己的窗口的消息感兴趣。尝试确保您的应用程序有一个可以获取消息的窗口,当其他应用程序位于您的应用程序下方的同一位置时,会阻止其他应用程序接收这些消息,并且如果另一个窗口位于您的窗口上方,那么您将无法收到消息。如果您想了解正在发生但通常不会发送给您的活动 - 例如,在应用程序窗口外单击鼠标。为了使应用程序能够看到并非针对其自身的事件,可以使用 Windows 挂钩。
有不同类型的挂钩,具体取决于您要访问的内容。鼠标钩适合您在此处指定的内容。系统为所有已安装的钩子维护一个“钩子链”——您有责任将消息沿着链传递,并从链中卸载自己。
要访问消息,您的钩子函数将如下所示(代码取自上面的第二个链接并进行改编):
在您的钩子函数中:
ACode
取决于钩子的类型并指示活动wParam
和lParam
具有特定于事件的含义要传递消息,您应该调用
CallNextHookEx
- 但是对于某些钩子,该消息将无论如何都要传承下去。挂钩可以安装为全局挂钩 - 这意味着它们拦截与调用线程在同一桌面/WinStation 中运行的所有线程上的消息。因此,例如,如果您有多个通过 RD 连接的用户,则该挂钩仅特定于其中一个桌面。
What you want is a 'Hook' that can give you information about mouse events without the events being intended for your program. It's too big a topic to be able to give you a how-to in one go, but these two links should be helpful:
Understanding how to use Windows Hooks
Mouse Hook Tutorial with Delphi codes
Why use a Windows Hook?
The Windows environment is designed around messages being passed around. Typically, a program is only interested in messages that are sent directly to its own windows. Trying to make sure that your application has a window that will get the messages blocks other applications from receiving those messages when they are in the same location under yours, and if another window is over yours then you won't get the messages. If you want to know about activity that's happening that wouldn't normally be sent to you - for example, a mouse click outside of your application's window. To enable applications to have visibility of events that are not destined for itself, a windows hook can be used.
There are different types of hooks, depending on what you want to access. A mouse hook is appropriate for what you have specified here. The system maintains a 'Hook Chain' for all of the hooks that have been installed - it will be your responsibility to pass the messages on down the chain, and to uninstall yourself from the chain.
To access the messages, your hook function will look something like this (code taken from the 2nd link above and adapted):
In your hook function:
ACode
is dependent on the type of hook and indicates the eventwParam
andlParam
have a meaning specific to the eventTo pass the message on, you should call
CallNextHookEx
- however for some hooks, the message will always be passed on regardless.Hooks can be installed as Global hooks - meaning they intercept messages on all threads running in the same Desktop / WinStation as the calling thread. So, if you have multiple users connected via RD, for example, the hook is specific to one of those desktops only.