Платформа.NET « [Csharp] Global KeyPressEvent или как отловить нажатие кнопки

Есть голая форма. Задача: обработать нажатие клавиши на клавиатуре. Покопался в интернете нарыл, информацию про WindowsHook и немного примеров, переделал их на свой лад получилось сие.
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .csharp.geshi_code {font-family:monospace;} .csharp.geshi_code .imp {font-weight: bold; color: red;} .csharp.geshi_code .kw1 {color: #0600FF;} .csharp.geshi_code .kw2 {color: #FF8000; font-weight: bold;} .csharp.geshi_code .kw3 {color: #008000;} .csharp.geshi_code .kw4 {color: #FF0000;} .csharp.geshi_code .kw5 {color: #000000;} .csharp.geshi_code .co1 {color: #008080; font-style: italic;} .csharp.geshi_code .co2 {color: #008080;} .csharp.geshi_code .co3 {color: #008080;} .csharp.geshi_code .coMULTI {color: #008080; font-style: italic;} .csharp.geshi_code .es0 {color: #008080; font-weight: bold;} .csharp.geshi_code .es_h {color: #008080; font-weight: bold;} .csharp.geshi_code .br0 {color: #000000;} .csharp.geshi_code .sy0 {color: #008000;} .csharp.geshi_code .st0 {color: #666666;} .csharp.geshi_code .st_h {color: #666666;} .csharp.geshi_code .nu0 {color: #FF0000;} .csharp.geshi_code .me1 {color: #0000FF;} .csharp.geshi_code .me2 {color: #0000FF;} .csharp.geshi_code span.xtra { display:block; }
using System;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            SetHook(_proc);
        }

        ~Form1()
        {
            UnhookWindowsHookEx(_hookID);
        }

        private delegate IntPtr KeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

        private const int WH_KEYBOARD = 2;
        private static KeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;

        private static IntPtr SetHook(KeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(
                    WH_KEYBOARD,
                    proc,
                    GetModuleHandle(curModule.ModuleName),//подскажите зачем нужен этот параметр
                    (uint)AppDomain.GetCurrentThreadId());
            }
        }
        //при нажатии на кнопку этот метод вызывается несколько раз, а нужен то всего один
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                int vkCode = wParam.ToInt32();
                MessageBox.Show(((Keys)vkCode).ToString());
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,KeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);  
    }
}


Вообщем проблема в том что когда я жму на кнопку один раз, то метод
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .csharp.geshi_code {font-family:monospace;} .csharp.geshi_code .imp {font-weight: bold; color: red;} .csharp.geshi_code .kw1 {color: #0600FF;} .csharp.geshi_code .kw2 {color: #FF8000; font-weight: bold;} .csharp.geshi_code .kw3 {color: #008000;} .csharp.geshi_code .kw4 {color: #FF0000;} .csharp.geshi_code .kw5 {color: #000000;} .csharp.geshi_code .co1 {color: #008080; font-style: italic;} .csharp.geshi_code .co2 {color: #008080;} .csharp.geshi_code .co3 {color: #008080;} .csharp.geshi_code .coMULTI {color: #008080; font-style: italic;} .csharp.geshi_code .es0 {color: #008080; font-weight: bold;} .csharp.geshi_code .es_h {color: #008080; font-weight: bold;} .csharp.geshi_code .br0 {color: #000000;} .csharp.geshi_code .sy0 {color: #008000;} .csharp.geshi_code .st0 {color: #666666;} .csharp.geshi_code .st_h {color: #666666;} .csharp.geshi_code .nu0 {color: #FF0000;} .csharp.geshi_code .me1 {color: #0000FF;} .csharp.geshi_code .me2 {color: #0000FF;} .csharp.geshi_code span.xtra { display:block; }
HookCallback

вызывается несколько раз. Но мне нужно всего лишь один.

Подскажите пожалуйста, где я допустил ошибку, либо предложите альтернативу.

1 ответов


Вообщем, я не разобрался почему событие происходит по 3 раза при нажатии кнопки. Но нашел более стандартный вариант.

У формы есть свойство KeyPreview, и если оно установлено в true, то в начале все события клавиатуры будут проходить через обработчики формы, а уж потом через обработчики компонентов на форме.