在Win表单上禁用Alt-F4 NotifyIcon
我使用Win Forms中的NotifyIcon为我的WPF C#应用程序创建了一个系统托盘图标。在Win表单上禁用Alt-F4 NotifyIcon
我有一个错误,如果用户右键单击上下文菜单的图标,他们可以按Alt-F4,图标将从托盘中消失,但主WPF应用程序仍在运行。当他们“最小化到系统托盘”时,这是一个特别的问题,应用程序的唯一控制权已经消失。
任何人都知道如何处理这个特殊的系统上?我查看了NotifyIcon文档,并没有任何与按键事件相关的内容。
更新:这里有一个示例应用程序来展示我如何使用系统托盘和实际的错误。 http://cid-e75a75f1a1fbfbb5.office.live.com/self.aspx/.Public/WpfApplication1.zip?sa=221089565
所以这是一个错误,我已经报告给Microsoft Connect。查看最新内容,我想: https://connect.microsoft.com/VisualStudio/feedback/details/568590/unable-to-disable-alt-f4-on-winforms-notifyicon-when-context-menu-is-open?wa=wsignin1.0
我猜你在WinFormHost中使用NotifyIcon?作为NotifyIcon的是简单的窗体上的控件,你可能要消耗的主要形式的情况下,如果主窗口被隐藏,忽略按键,像(伪):
public mainForm_keypressed(object sender, //eventargs
{
if(_hidden && //Keystroke detection)
{
e.Handled = true;
return;
}
}
编辑
http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx这可能是我值得研究的问题。
对不起,这不起作用。打开我的systrayicon的上下文菜单后,按下键时,主窗口不会收到任何事件。 – Jippers 2010-06-17 17:19:04
嗯,我得说这是一个棘手的问题,但经过一些快速测试后,我认为这样做。
private void Form1_Load(object sender, EventArgs e)
{
this.Activated += new EventHandler(Form1_Activated);
}
void Form1_Activated(object sender, EventArgs e)
{
string iconPath = "some file system path";
notifyIcon1.Icon = new Icon(iconPath);
}
它不会让你的图标消失,但至少当你的应用程序获得焦点时,图标会反弹。
您也可以尝试存储图标,以便您不需要继续构建它。
这可能会作为一种解决方法,除了我的错误的情况下,如果用户执行“最小化到系统托盘”然后关闭系统托盘。无法将主窗口恢复为恢复图标工作。 – Jippers 2010-06-17 17:20:39
你是对的。但是,通过在“最小化到Sys托盘”事件中添加恢复图标逻辑,您可以进一步降低这一点。 此外,您可以在应用程序最小化时添加一个计时器,并且每隔30秒左右继续并重置该图标。这会消耗更多的资源,但它会完成工作。 – 2010-06-17 21:24:01
除此之外,你可以做的唯一事情就是把你的文档放进去,如果有人确实碰到这个边缘情况,他们必须启动任务管理器并点击“切换到”。 – 2010-06-17 22:31:23
首先,你可以设置在项目中的隐藏窗口并激活它在contextMenuStrip2_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
事件如果e.alt
是真实的。
其次你关闭隐藏窗口,可以修复这个bug。
如:
//public partial class HotKeyWin : Window // WindowStyle="ToolWindow"
public partial class NotifyIconWrapper : Component
{
private HotKeyWin hkeyWin = new HotKeyWin();
public NotifyIconWrapper()
{
hkeyWin.Show();
hkeyWin.Closing += new CancelEventHandler(hkeyWin_Closing);
hkeyWin.Hide();
}
void hkeyWin_Closing(object sender, CancelEventArgs e)
{
Console.WriteLine("hkeyWin_Closing enter");
e.Cancel = true;
}
private void contextMenuStrip2_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.Alt) hkeyWin.Activate();
}
}
我知道这是很老,但我得到了同样的问题,因为我发现了一些合理的工作,以防万一,我很高兴在这里分享。
该解决方案来自WinForm ContextMenuStrip对象中的事件PreviewKeyDown
。您添加了此事件,只需使用以下代码从AFT-F4
停止仅关闭托盘中的图标(及其菜单)。
private void myMenuTray_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Menu && e.KeyValue == 18 && e.Alt)
{
MessageBox.Show("");
MessageBox.Show("YOU CAN'T CLOSE HERE WITH ALT-F4");
return;
}
}
我知道这看起来很丑。但它工作正常。你可以使用一些确认问题来看起来更好。
说明:在任何情况下,ALT-F4
都会到达通知对象。正如你的代码中你有一个第一个MessageBox
,ALT-F4
被这个立即关闭的MessageBox
捕获。显示第二个MessageBox
,因此通知对象不关闭。
我已经测试了单个return
(并且里面没有e.Cancel
),但每次notify对象关闭而应用程序的其余部分仍在运行的进程中。
另一个好处是,您仍然可以使用标准ALT-F4
正常工作来关闭应用程序(一旦它不在托盘中!)。
我有同样的问题,并发现解决方案,并发布它[这里](https://*.com/questions/45702372)。 – cppguy 2017-08-22 18:23:25