Avatar
matesax
Redaktor
Avatar
matesax:

Dobrý den,
chtěl bych hlídat KeyDown mimo program. Ovšem funguje mi to jen v programu a navíc jen při rychle stisklých klávesách. Jinak dojde k selhání - viz nadpis. Chápu v čem je problém, ale co s tím? Děkuji.

https://gist.github.com/3723328

Kód použití:

public MainWindow()
{
    InitializeComponent();

    myKDP.KeyDown += new KeyEventHandler(Preview_KeyDown);
}

private void Preview_KeyDown(object sender, KeyEventArgs e)
{
    System.Windows.Forms.MessageBox.Show(e.KeyData.ToString());
    e.Handled = true;
}
 
Odpovědět 14.9.2012 19:20
Avatar
matesax
Redaktor
Avatar
Odpovídá na matesax
matesax:

Vyřešeno nulováním delegáta...

using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.ComponentModel;

class KeyDownPreview
{
    #region Initialization

    private IntPtr Hook = IntPtr.Zero;

    public event KeyEventHandler KeyDown, KeyUp;

    [DllImport("user32.dll")]
    static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookProccess callback, IntPtr hInstance, uint threadId);

    [DllImport("user32.dll")]
    static extern bool UnhookWindowsHookEx(IntPtr hInstance);

    [DllImport("user32.dll")]
    static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref KeyboardHookStruct lParam);

    [DllImport("kernel32.dll")]
    static extern IntPtr LoadLibrary(string lpFileName);

    public struct KeyboardHookStruct
    {
        public int KeyCode, ScanCode, Flags, Time, DwExtraInfo;
    }

    private delegate int KeyboardHookProccess(int code, int wParam, ref KeyboardHookStruct lParam);

    private const int WH_KEYBOARD_LL = 13, WM_KEYDOWN = 0x100, WM_KEYUP = 0x101, WM_SYSKEYDOWN = 0x104, WM_SYSKEYUP = 0x105;

    #endregion

    #region Main

    private static KeyboardHookProccess callbackDelegate;

    public KeyDownPreview()
    {
        var hInstance = LoadLibrary("User32");
        callbackDelegate = new KeyboardHookProccess(HookProccess);
        Hook = SetWindowsHookEx(WH_KEYBOARD_LL, callbackDelegate, hInstance, 0);

        if (Hook == IntPtr.Zero)
            throw new Win32Exception();
    }

    ~KeyDownPreview()
    {
        bool noOK = !UnhookWindowsHookEx(Hook);

        if (noOK)
            throw new Win32Exception();

        callbackDelegate = null;

    }

    public int HookProccess(int code, int wParam, ref KeyboardHookStruct lParam)
    {
        if (code >= 0)
        {
            var kea = new KeyEventArgs((Keys)lParam.KeyCode);

            if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && KeyDown != null)
            {
                KeyDown(this, kea);
            }
            else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && KeyUp != null)
            {
                KeyUp(this, kea);
            }

            if (kea.Handled)
                return 1;
        }

        return CallNextHookEx(Hook, code, wParam, ref lParam);
    }

    #endregion
}

Jen to má nějakou divnou odezvu (dlouhou) - ale to snad půjde odchytit v programu...

 
Nahoru Odpovědět  +1 15.9.2012 9:45
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.