2010-06-17 2 views
2

Я использую NotifyIcon из Win Forms, чтобы создать значок systray для моего приложения WPF C#.Отключение Alt-F4 в Win Forms NotifyIcon

У меня есть ошибка, где, если пользователь щелкнет правой кнопкой мыши значок контекстного меню, они могут нажать Alt-F4, и значок исчезнет из лотка, но основное приложение WPF все еще работает. Это особенно проблема, когда они «сведены к минимуму до systray», и единственный контроль над приложением теперь исчез.

Кто-нибудь знает, как обращаться с этим конкретно на системном компьютере? Я просмотрел документацию NotifyIcon, и нет ничего, связанного с событиями нажатия клавиш.

UPDATE: вот пример приложения, чтобы показать, как я использую systray и фактическую ошибку. http://cid-e75a75f1a1fbfbb5.office.live.com/self.aspx/.Public/WpfApplication1.zip?sa=221089565

+0

У меня была та же проблема, и я нашел решение и разместил его [здесь] (https://stackoverflow.com/questions/45702372). – cppguy

ответ

0

Я думаю, вы используете NotifyIcon в WinFormHost? Как NotifyIcon просто элемент управления на форме, вы, вероятно, должны потреблять событие в основной форме, а если MainWindow скрыт, игнорировать нажатие клавиши, как (псевдо):

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

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

Он не будет делать это так Тэй вы не можете сделать значок исчезнут, но, по крайней мере, когда ваше приложение получить фокус, значок Retrun.

Возможно, вы также захотите сохранить значок, чтобы вам не нужно было его конструировать.

+0

это может работать как работа, за исключением экземпляра моей ошибки, если пользователь выполняет «Свести к минимуму», а затем закрывает systrayicon. Невозможно вернуть главный указатель на значок восстановления. – Jippers

+0

Вы правы. Тем не менее, вы можете свести к минимуму это немного, добавив логику значка восстановления в событие «Свернуть до Sys Tray». Кроме того, вы можете добавить таймер, когда приложение будет сведено к минимуму, и каждые 30 секунд просто перейдите и сбросьте значок. Это потребует больше ресурсов, но оно выполнит свою работу. –

+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

Я знаю, что это довольно старая, но, как я получил тот же вопрос, и я нашел разумную работу Arround я рад поделиться здесь.

Решение происходит от события PreviewKeyDown в объекте WinForm ContextMenuStrip. Вы добавили это событие, просто используйте следующий код для остановки от 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; 
    } 
} 

Я знаю, что это выглядит uggly. Но он отлично работает. До вас можно использовать какой-то подтверждающий вопрос, чтобы выглядеть лучше.

Пояснения: в любом случае ALT-F4 прибывает на объект уведомления.Как и в вашем коде, у вас есть 1-й MessageBox, ALT-F4 попадает в движение по этому MessageBox, который закрывается немедленно. Отображается 2-й номер MessageBox, поэтому объект уведомления не закрывается.

Я протестировал единственный return (и там нет e.Cancel), но каждый раз, когда объект уведомления закрыт, пока остальная часть приложения все еще находится в запущенных процессах.

Другим хорошим моментом является то, что вы все еще можете нормально работать со стандартом ALT-F4, чтобы закрыть приложение (если оно не находится в лотке!).

Смежные вопросы