确定程序是否是.NET中的活动窗口
我有一个 C#/.NET 应用程序,我想实现以下行为:
我有一个弹出菜单。 每当用户单击应用程序内的任何内容(不是弹出菜单)时,我都希望关闭弹出菜单。
但是,每当用户不在应用程序中时,我都不希望发生任何事情。
我正在尝试通过 LostFocus 事件来管理此问题,但我无法确定我的应用程序是否是活动窗口。 代码看起来像这样。
private void Button_LostFocus(object sender, System.EventArgs e)
{
if (InActiveWindow()) {
CloseMenu()
}
else {
// not in active window, do nothing
}
}
我需要知道的是如何实现 InActiveWindow() 方法。
I have a C#/.NET app and I want to implement the following behavior:
I have a popup menu. Whenever the user clicks on anything within the application that is not the popup menu, I want the popup menu to close.
However, whenever a user is not in the application I don't want anything to happen.
I'm trying to manage this through the LostFocus event, but I'm having trouble determining whether my application is the active window. The code looks something like this.
private void Button_LostFocus(object sender, System.EventArgs e)
{
if (InActiveWindow()) {
CloseMenu()
}
else {
// not in active window, do nothing
}
}
What I need to know is how to implement the InActiveWindow() method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以 P/Invoke 到 GetForegroundWindow() ,并比较返回到应用程序的 form.Handle 属性的 HWND。
获得句柄后,您还可以 P/Invoke GetAncestor () 获取根所有者窗口。 如果它在您的应用程序中,这应该是您的应用程序的主启动窗口的句柄。
You could P/Invoke into GetForegroundWindow(), and compare the HWND returned to the application's form.Handle property.
Once you have the handle, you can also P/Invoke GetAncestor() to get the root owner window. This should be the handle of your application's main, startup window, if this is in your application.
我在开发一个项目时偶然发现了你的问题,并且基于 Reed Copsey 的回答,我编写了这段快速代码,看起来效果很好。
这是代码:
我没有太多时间将其转换为 C#,因为我正在开发一个项目,截止日期为 2 天,但我相信您可以快速完成转换。这是 C# 版本VB.NET 代码:
I stumbled upon your question while working on a project and based on Reed Copsey's answer, I wrote this quick code which seems to do the job well.
Here's the code:
I didn't have too much time to convert it to C# as I'm working on a project with a deadline in 2 days but I believe you can quickly do the conversion.Here is the C# version of the VB.NET code:
这看起来很棘手的最大原因是因为弹出窗口在主窗体停用之前失去焦点,因此在此事件发生时活动窗口将始终位于应用程序中。 实际上,您想知道事件结束后它是否仍然是活动窗口。
您可以设置某种方案,让您记住弹出窗口正在失去焦点,忽略您需要关闭它的事实,然后在
LostFocus
或Deactivate
中应用程序主窗体的事件取消告诉您需要关闭它的注释; 但问题是你什么时候处理这张纸条?我认为这可能会更容易,至少如果弹出窗口是主窗体的直接子窗体(我怀疑在您的情况下可能是这样)来挂钩
Focus
甚至可能主窗体的 Click
事件并使用它关闭弹出窗口(如果弹出窗口打开)(也许通过扫描其子窗体列表以查找任何实现 ICloseOnLostFocus 接口的窗体,以便弹出窗口有机会参与决策并做任何其他需要做的事情)。我希望我知道一份更好的文档来解释所有这些事件的实际含义以及它们如何相互排序,MSDN 在描述它们方面还有很多不足之处。
It seems like the biggest reason this is tricky is because the popup loses focus before the main form is deactivated, so the active window will always be in the application at the time of this event. Really, you want to know whether it will still be the active window after the event is over.
You could set up some kind of scheme where you remember that a popup is losing focus, set aside the fact that you will need to close it, and in the
LostFocus
orDeactivate
event of the application's main form cancel the note that tells you you need to close it; but the problem is when will you process the note?I'm thinking it might be easier, at least if the popup is a direct child of the main form (which I suspect in your case it may be) to hook the
Focus
or maybe evenClick
event of the main form and use it close the popup if it is open (perhaps by scanning its list of child forms for any that implement an ICloseOnLostFocus interface, so that the popup will have a chance to participate in the decision and do anything else it needs to do).I wish I knew of a better document explaining what all these events actually mean and how they are sequenced with respect to one another, MSDN leaves a lot to be desired in describing them.