在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

+0

我有同样的问题,并发现解决方案,并发布它[这里](https://*.com/questions/45702372)。 – cppguy 2017-08-22 18:23:25

我猜你在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这可能是我值得研究的问题。

+0

对不起,这不起作用。打开我的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); 
    } 

它不会让你的图标消失,但至少当你的应用程序获得焦点时,图标会反弹。

您也可以尝试存储图标,以便您不需要继续构建它。

+0

这可能会作为一种解决方法,除了我的错误的情况下,如果用户执行“最小化到系统托盘”然后关闭系统托盘。无法将主窗口恢复为恢复图标工作。 – Jippers 2010-06-17 17:20:39

+0

你是对的。但是,通过在“最小化到Sys托盘”事件中添加恢复图标逻辑,您可以进一步降低这一点。 此外,您可以在应用程序最小化时添加一个计时器,并且每隔30秒左右继续并重置该图标。这会消耗更多的资源,但它会完成工作。 – 2010-06-17 21:24:01

+0

除此之外,你可以做的唯一事情就是把你的文档放进去,如果有人确实碰到这个边缘情况,他们必须启动任务管理器并点击“切换到”。 – 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都会到达通知对象。正如你的代码中你有一个第一个MessageBoxALT-F4被这个立即关闭的MessageBox捕获。显示第二个MessageBox,因此通知对象不关闭。

我已经测试了单个return(并且里面没有e.Cancel),但每次notify对象关闭而应用程序的其余部分仍在运行的进程中。

另一个好处是,您仍然可以使用标准ALT-F4正常工作来关闭应用程序(一旦它不在托盘中!)。