输入语言挂钩

| 我正在编写一种应用程序,该应用程序需要获取系统输入语言,而应用程序窗口未聚焦。 搜索Google之后,我发现执行此操作的方法是挂起
WM_INPUTLANGCHANGE
消息。 但是我找不到钩子的语法示例。 我找到了以下代码,并尝试使其适应我的需要,但失败了: 编辑: 我已将WM_KEYUP替换为WM_INPUTLANGCHANGE,但是它不起作用。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace KeyHook
{
    class LenHook
    {

        private const int WM_INPUTLANGCHANGE = 0x0051;
        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;


        [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)]
        public static extern bool UnhookWindowsHookEx(IntPtr hhk);

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

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


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


        public LenHook()
        {


            _hookID = SetHook(_proc);
            UnhookWindowsHookEx(_hookID);
            System.Windows.Forms.Application.Run();


        }
        //Install hook
        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (var curProcess = Process.GetCurrentProcess())
            {
                using (var curModule = curProcess.MainModule)
                {
                    return SetWindowsHookEx(WM_INPUTLANGCHANGE, proc, GetModuleHandle(curModule.ModuleName), 0);
                }
            }
        }

        //Do it when key press
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {

            MessageBox.Show(wParam.ToString());
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }
     }
}
    
已邀请:
        我的一个项目中的这段代码对我有用,似乎我们可能使用了相同的示例:
private static IntPtr _hookId = IntPtr.Zero;
private readonly External.LowLevelKeyboardProc _proc;

public FrmMain()
{
    _proc = HookCallback;
    _hookId = SetHook(_proc);
    InitializeComponent();
}

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

private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    // You can change this to WM_KEYDOWN
    if (nCode >= 0 && wParam == (IntPtr)External.WM_KEYUP)
    {
         // Code you want to run when a button is pressed.
    }
    return External.CallNextHookEx(_hookId, nCode, wParam, lParam);
}
另外,这是我的
External
课。
public static class External
{
    public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

    public const int WH_KEYBOARD_LL = 13;
    public const int WM_KEYDOWN = 0x0100;
    public const int WM_KEYUP = 0x0101;
    public const uint WM_GETTEXT = 0x0D;
    public const uint WM_GETTEXTLENGTH = 0x0E;
    public const uint EM_GETSEL = 0xB0;

    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr GetForegroundWindow();

    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    [DllImport(\"kernel32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern uint GetCurrentThreadId();

    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr GetFocus();

    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int SendMessage(IntPtr hWnd, uint Msg, out int wParam, out int lParam);

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

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

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

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

    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool GetCaretPos(out Point lPoint);

    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
}
我已经读到,如果您尝试从控制台应用程序执行这些挂钩,尽管您对
Application.Run()
的调用应该可以解决此问题,但是您会遇到问题。     

要回复问题请先登录注册