本文介绍了如何截获所有键盘事件,并防止在一个WinForms应用程序失去焦点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个朋友是盲目的,我已经得到了开发一个程序,将让他用一台PC用盲打字方法和可听反馈的帮助的想法。经验会更丰富(充分利用特定功能的多个键)和完美(如防止偶尔的焦点丢失),如果我的应用程序可以强行只要它开始采取总量控制在整个键盘输入(我把它在启动时的他)。我是一个WinForms C#.NET开发人员,所以我想在使用这种特定的框架和语言(不介意包裹WinAPI的要求虽然)的应用程序来实现这一点。

A friend of mine is blind and I've got an idea of developing a program that would let him use a PC with the help of a blind typing method and audial feedback. The experience would be much richer (making use of more keys for particular functions) and flawless (like preventing occasional focus loss) if my application could forcibly take total control over the whole keyboard input as soon as it is started (I'd put it in start-up for him). I am a WinForms C# .Net developer so I'd like to implement this in an application using this particular framework and language (don't mind wrapped WinAPI calls though).

PS:我不介意系统保持控制权,按Ctrl +醛固酮+ Del组合键,但我想借此控制所有其他键组合,包括Windows徽标和标准的应用程序启动按钮。

PS: I don't mind the system keeping control over the Ctrl+Ald+Del combination, but I'd like to take control over all the other keys and combinations, including the Windows logo and standard application launcher buttons.

推荐答案

您可以使用低级别的键盘钩子实现的 /archive/2006/05/03/589423.aspx\">posted。它不应窃取任何项目集中离开,但按键时你的程序可以得到通知。这是从的情况下的链接后停止工作的代码

You can use the low-level keyboard hook implementation posted here. It shouldn't steal focus away from any programs but your program can be notified when keys are pressed. This is the code from the post in case the link stops working.

using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class InterceptKeys
{
    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;
    private static LowLevelKeyboardProc _proc = HookCallback;
    private static IntPtr _hookID = IntPtr.Zero;

    public static void Main()
    {
        _hookID = SetHook(_proc);
        Application.Run();
        UnhookWindowsHookEx(_hookID);
    }

    private static IntPtr SetHook(LowLevelKeyboardProc proc)
    {
        using (Process curProcess = Process.GetCurrentProcess())
        using (ProcessModule curModule = curProcess.MainModule)
        {
            return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                GetModuleHandle(curModule.ModuleName), 0);
        }
    }

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

    private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            Console.WriteLine((Keys)vkCode);
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook,
        LowLevelKeyboardProc 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);
}

您可以处理在 HookCallback 事件(或进一步抽象的主体部分为一个单独的类,并引发一个事件)。

You can handle the key presses in the HookCallback event (or further abstract the main parts into a separate class and raise an event).

这篇关于如何截获所有键盘事件,并防止在一个WinForms应用程序失去焦点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!