Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] Установка глобального HotKey (http://forum.oszone.net/showthread.php?t=198437)

giv5dot26 03-02-2011 06:35 1603276

Установка глобального HotKey
 
Привет всем. Нужно: установить сочетания клавиш глобальное. Делаю так:

Код:

      [DllImport("user32.dll")] 
        public static extern bool RegisterHotKey(IntPtr hWND, int id, uint fsModifiers, uint vk);
        [DllImport("user32.dll")]
        public static extern bool UnregisterHotKey(IntPtr hWND, int iD);
 
        private const int MOD_ALT = 0x1;
        private const int MOD_CONTROL = 0x2;
        private const int MOD_SHIFT = 0x4;
        private const int MOD_WIN = 0x8;
        private const int WM_HOTKEY = 0x312;
       
      public Form()
      {
            RegisterHotKey(this.Handle, 42, MOD_WIN, (int)Keys.Escape);
      }
 
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == WM_HOTKEY)
            {
                switch (m.WParam.ToInt32())
                {
                    case 42:
                        if (this.Visible == false)
                        {
                            this.Show();
                            this.Tray.Visible = false;
                            this.ShowInTaskbar = true;
                        }
                        break;
                }
            }           
        }


Но ничего не происходит когда я нажимаю комбинацию клавишь. Ставлю точку останова на строке if (m.Msg == WM_HOTKEY) но программа туда даже не заходит. Что я сделал не так?

Delirium 03-02-2011 08:24 1603296

Глобальная клавиша для чего нужна, для того, чтобы на форме в любом месте нажать, например, F3 и открылось какое то меню или действие? Если да, то все гораздо проще:
1. Выставляем у формы свойство KeyPreview=true;
2. Вставляем обработчик на KeyDown:

Код:

private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
          if (e.KeyCode == Keys.F1)
            {
            //тут код после нажатия нужной клавиши
            }
}


giv5dot26 03-02-2011 08:39 1603301

Нет без привязки к форме. Все нужно чтобы вызывать свернутое окно.

Delirium 03-02-2011 08:48 1603305

ну хотя бы на base.WndProc(ref m); он доходит? Или просто не заходит в функцию?

giv5dot26 03-02-2011 08:57 1603306

Да доходит не срабатывает именно условие как будто клавишу и не нажимали вовсе.
Код:

if (m.Msg == WM_HOTKEY)
вот это место "пролетает".

Admiral 04-02-2011 02:22 1603999

giv5dot26 приведённый код неполон. Но должен работать.
Первоначально хотел предложить вызов RegisterHotKey перенести из конструктора формы (подозрение на не валидный this.Handle) куда-нибудь в OnLoad (событие наступает сразу после первого отображения формы). Но нет, работать будет и там (this.Handle валидный в обоих случаях).
читать дальше »
Код:

using System;
using System.Drawing;
using System.Windows.Forms;

using System.Runtime.InteropServices;  //for DllImport

class Form1 : Form
{
    [DllImport("user32.dll")]
    public static extern bool RegisterHotKey(IntPtr hWND, int id, uint fsModifiers, uint vk);
    [DllImport("user32.dll")]
    public static extern bool UnregisterHotKey(IntPtr hWND, int iD);
    private const int MOD_WIN = 0x8;
    private const int WM_HOTKEY = 0x312;

    public static void Main()
    {
        Application.Run(new Form1());
    }
    public Form1()
    {
      RegisterHotKey(this.Handle, 42, MOD_WIN, (int)Keys.Escape);
    }
    protected override void OnLoad(EventArgs ea)
    {
      base.OnLoad(ea);
      //RegisterHotKey(this.Handle, 42, MOD_WIN, (int)Keys.Escape);
    }
    protected override void WndProc(ref Message msg)
    {
        base.WndProc(ref msg);
        if (msg.Msg == WM_HOTKEY)
        {
            switch (msg.WParam.ToInt32())
            {
                case 42:
                    MessageBox.Show("Hello there");
                break;
                default:
                    MessageBox.Show("Hello stranger");
                break;
            }
        }     
    }
    protected override void OnClosing(System.ComponentModel.CancelEventArgs cea)
    {
        base.OnClosing(cea);
        UnregisterHotKey(this.Handle, 42);
    }
}

Есть реакция на сочетание Win+Esc.
В примере название экземпляра класса Form1, а не Form (что бы не было путаницы с именем класса).

giv5dot26 04-02-2011 05:28 1604026

В общем приведенный Вами код работает, но вот стоит форму свернуть в трей как реакция на нажатие прекращается и вот это уже не проходит
Код:

if (msg.Msg == WM_HOTKEY)
        {
            switch (msg.WParam.ToInt32())
            {
                case 42:
                    MessageBox.Show("Hello there");
                break;
                default:
                    MessageBox.Show("Hello stranger");
                break;
            }
        }

Почему как считаете?

Admiral 05-02-2011 15:48 1605199

giv5dot26, в предыдущем посте пропустил слово - приведённый выше код неполон. Иными словами, в первом посте приводится вполне рабочий код (на его основе полный вариант под споллером в 6 посте), однако не уточнен способ сворачивания в трей.
Что касается трея, то как-то не доводилось его программировать, но есть предположение создать две формы, первая (невидимая) пускай принимает сообщения, вторая получает их от первой, будучи свёрнута в трей.

Здесь WndProc doesn't receive hotkey message when minimized человек пришёл к выводу, что виной всему this.ShowInTaskbar = false; после которого описатель приложения становится не валидным.

giv5dot26 11-02-2011 07:33 1609921

Да так и есть. Если не использовать
Код:

this.ShowInTaskbar = false
то все работает как надо. Все нормально.


Время: 18:07.

Время: 18:07.
© OSzone.net 2001-