Forms Delphi如何在包含其他组件的窗体上的任何位置检测单击事件
我在TFrame实例中包含的Delphi VCL表单应用程序中有一个TEdit,如果它重要的话。当用户通过单击表单上的其他位置指示他们已完成编辑后,插入符号和焦点将保留在此控件上,直到我单击另一个控件,该控件将获得焦点。但是,我希望TEdit能够释放焦点,而不管用户点击哪里。我希望我可以使用ActiveControl:=nil来结束对所选控件的关注,但我不确定在哪里调用它 我想要的是焦点离开所选控件,而不必将其转移到另一个控件。我可以在表单的OnClick事件中结束焦点,但如果用户选择表单上的帧中也包含的任何其他控件,则这将不起作用,因为表单的OnClick事件不会被触发。为表单上的每个附加项提供单独的OnClick事件似乎既不雅观又乏味 实现此行为的全局解决方案是什么?尝试使用事件查找消息 您可以在VCL.Controls单元中同时使用VCL或功能,查看单击坐标处是否有TWinControl。或者更简单,您也可以使用VCL.Controls单元中的VCL函数直接从消息的目标HWND获取TWinControlForms Delphi如何在包含其他组件的窗体上的任何位置检测单击事件,forms,delphi,onclick,components,frames,Forms,Delphi,Onclick,Components,Frames,我在TFrame实例中包含的Delphi VCL表单应用程序中有一个TEdit,如果它重要的话。当用户通过单击表单上的其他位置指示他们已完成编辑后,插入符号和焦点将保留在此控件上,直到我单击另一个控件,该控件将获得焦点。但是,我希望TEdit能够释放焦点,而不管用户点击哪里。我希望我可以使用ActiveControl:=nil来结束对所选控件的关注,但我不确定在哪里调用它 我想要的是焦点离开所选控件,而不必将其转移到另一个控件。我可以在表单的OnClick事件中结束焦点,但如果用户选择表单上的帧
如果鼠标下不存在控件,或者控件不可聚焦,则其CanFocus方法返回False,然后设置ActiveControl=nil。否则,什么也不做,在处理消息时让单击的控件自己聚焦。为什么要这样做?“这只会让用户体验更糟,因为它是非标准的。@DavidHeffernan该程序提供了一个游戏板,并且在初始设置期间,编辑器主要由用户使用。一旦游戏开始,用户提供输入,包括键盘和由独立于这些编辑器的程序管理和显示的输入。在用户视图中,焦点已简单地更改为由包含图像和tlabel文本显示的帧组成的其他组件。@Ashlar TApplicationEvents.OnMessage查看来自主线程消息队列并由VCL消息循环TApplication.Run、TForm.ShowModal检索的每条消息,等。鼠标消息被发布到队列中,因此OnMessage在正常情况下应该可以看到它们。如果您没有看到消息,那么代码中可能有一个二级消息循环正在运行,它没有将消息传递给OnMessage。使用OnMessage的替代方法是使用SetWindowsHookEx在UI线程中安装特定于线程的鼠标挂钩。谢谢。我发现了问题,onMessage对WM_LButtonDown做出了反应。但是,当我单击tedit时,FindVCLWindow mouse.curpos返回nil。它似乎与mouse.curpos有关,所以需要单独的问题coming@Ashlar为什么要使用Mouse.CursorPos,而不是使用WM_LBUTTONDOWN本身提供的坐标?LPRAM包含相对于消息目标HWND的客户机坐标。鼠标可能在WM_LBUTTONDOWN消息排队之后以及在检索之前移动过。因此,为什么不直接使用消息的目标HWND本身呢?您可以使用VCL的函数从HWND获取TWinControl。您在此处的评论和其他类似的评论会让我按照您的建议更正代码。我正在学习正确使用消息,所以您在LParam上的信息对我来说是新信息,非常有用。我还有更多的研究要做!