在Win Forms NotifyIcon上禁用Alt-F4

时间:2010-06-17 16:13:03

标签: .net notifyicon keyevent

我正在使用Win Forms中的NotifyIcon为我的WPF C#应用程序创建一个系统托盘图标。

我有一个错误,如果用户右键单击上下文菜单的图标,他们可以按Alt-F4,图标将从托盘中消失,但主WPF应用程序仍在运行。当它们“最小化到系统托管”并且应用程序的唯一控制现在消失时,这尤其是一个问题。

任何人都知道如何在系统托盘上特别处理这个问题?我查看了NotifyIcon文档,并没有任何与keypress事件有关的内容。

更新:这是一个示例应用程序,用于显示我如何使用系统托盘和实际的错误。 http://cid-e75a75f1a1fbfbb5.office.live.com/self.aspx/.Public/WpfApplication1.zip?sa=221089565

5 个答案:

答案 0 :(得分:1)

首先,如果contextMenuStrip2_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)为真,您可以在项目中设置隐藏窗口并在e.alt事件中激活它。
其次你禁用隐藏窗口关闭,可以解决这个错误。

例如:

//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();
    }
}

答案 1 :(得分:1)

我知道它已经很老了,但是当我遇到同样的问题时,我发现了一些合理的工作,我很乐意在这里分享。

解决方案来自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-F4MessageBox会被MessageBox捕获,该return立即关闭。显示第二个e.Cancel,因此通知对象没有关闭。

我已经测试过单ALT-F4(并且那里没有import numpy as np import cv2 img = cv2.imread('Corner_0.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) gray = np.float32(gray) corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 10) corners = np.int0(corners) for corner in corners: x,y = corner.ravel() cv2.circle(img,(x,y),3,255,-1) cv2.imwrite('Detected_Corner_0.jpg',img) ),但每次关闭通知对象而应用程序的其余部分仍处于正在运行的进程中

另一个好处是,您仍然可以使用标准def print_numbers_modulo(List,Operator,ModuloNumber): CheckIfPrintedNumber=False for i in range(0,len(List)): if (abs(List[i]),Operator,ModuloNumber): print(List[i]) if (CheckIfPrintedNumber == False): print("There are no numbers having modulo",Operator,ModuloNumber) 正常工作以关闭应用程序(一旦它不在托盘中!)。

答案 2 :(得分:0)

我猜你在WinFormHost中使用NotifyIcon?由于NotifyIcon只是Form上的一个控件,你可能必须使用主窗体中的事件,如果主窗口被隐藏,忽略键击,如(伪):

public mainForm_keypressed(object sender, //eventargs
{
  if(_hidden && //Keystroke detection)
  {
    e.Handled = true;
    return;
  }
}

<击>

修改

http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx这可能是我值得研究的事情。

答案 3 :(得分:0)

好吧,我得说这是一个棘手的问题,但经过一些快速测试后,我认为这样做了。

    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);
    }

它不会让你不能让图标消失,但至少当你的应用程序获得焦点时,图标将会重新显示。

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

答案 4 :(得分:0)

所以这是一个错误,我已将其报告给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