zoukankan      html  css  js  c++  java
  • c# console 在非主线程Hot Key

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace ConsoleApplication1
    {
        public class Win32APIs
        {
            [DllImport("user32", EntryPoint = "GetMessage")]
            public static extern int GetMessage(
                    out tagMSG lpMsg,
                    int hwnd,
                    int wMsgFilterMin,
                    int wMsgFilterMax
            );
    
            [DllImport("user32", EntryPoint = "DispatchMessage")]
            public static extern int DispatchMessage(
                   ref tagMSG lpMsg
            );
    
            [DllImport("user32", EntryPoint = "TranslateMessage")]
            public static extern int TranslateMessage(
                   ref tagMSG lpMsg
            );
    
            [DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
            public static extern Int32 GetCurrentThreadId();
    
        }
    
        public struct tagMSG
        {
            public int hwnd;
            public uint message;
            public int wParam;
            public long lParam;
            public uint time;
            public int pt;
        }
    
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace ConsoleApplication1
    {
        /// <summary>
        /// A class that manages a global low level keyboard hook
        /// </summary>
        class globalKeyboardHook
        {
            #region Constant, Structure and Delegate Definitions
            /// <summary>
            /// defines the callback type for the hook
            /// </summary>
            public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);
    
            public struct keyboardHookStruct
            {
                public int vkCode;
                public int scanCode;
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
    
            const int WH_KEYBOARD_LL = 13;
            const int WM_KEYDOWN = 0x100;
            const int WM_KEYUP = 0x101;
            const int WM_SYSKEYDOWN = 0x104;
            const int WM_SYSKEYUP = 0x105;
            #endregion
    
            keyboardHookProc khp;
    
            #region Instance Variables
            /// <summary>
            /// The collections of keys to watch for
            /// </summary>
            public List<int> HookedKeys = new List<int>();
            /// <summary>
            /// Handle to the hook, need this to unhook and call the next hook
            /// </summary>
            IntPtr hhook = IntPtr.Zero;
            #endregion
    
            #region Events
            /// <summary>
            /// Occurs when one of the hooked keys is pressed
            /// </summary>
            public event EventHandler<KeyDownUpEventArgs> KeyDown;
            /// <summary>
            /// Occurs when one of the hooked keys is released
            /// </summary>
            public event EventHandler<KeyDownUpEventArgs> KeyUp;
            #endregion
    
            #region Constructors and Destructors
            /// <summary>
            /// Initializes a new instance of the <see cref="globalKeyboardHook"/> class and installs the keyboard hook.
            /// </summary>
            public globalKeyboardHook(uint threadID = 0)
            {
                khp = new keyboardHookProc(hookProc);
                hook(threadID);
            }
    
            /// <summary>
            /// Releases unmanaged resources and performs other cleanup operations before the
            /// <see cref="globalKeyboardHook"/> is reclaimed by garbage collection and uninstalls the keyboard hook.
            /// </summary>
            ~globalKeyboardHook()
            {
                unhook();
            }
            #endregion
    
            #region Public Methods
            /// <summary>
            /// Installs the global hook
            /// </summary>
            public void hook(uint threadID = 0)
            {
                IntPtr hInstance = LoadLibrary("User32");
                hhook = SetWindowsHookEx(WH_KEYBOARD_LL, khp, hInstance, 0);
            }
    
            /// <summary>
            /// Uninstalls the global hook
            /// </summary>
            public void unhook()
            {
                UnhookWindowsHookEx(hhook);
            }
    
            /// <summary>
            /// The callback for the keyboard hook
            /// </summary>
            /// <param name="code">The hook code, if it isn't >= 0, the function shouldn't do anyting</param>
            /// <param name="wParam">The event type</param>
            /// <param name="lParam">The keyhook event information</param>
            /// <returns></returns>
            public int hookProc(int code, int wParam, ref keyboardHookStruct lParam)
            {
                if (code >= 0)
                {
                    var key = new KeyDownUpEventArgs(lParam.vkCode);
                    if (HookedKeys.Contains(key.KeyCode))
                    {
                        if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
                        {
                            KeyDown(this, key);
                        }
                        else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
                        {
                            KeyUp(this, key);
                        }
                        if (key.Handled)
                            return 1;
                    }
                }
                return CallNextHookEx(hhook, code, wParam, ref lParam);
            }
            #endregion
    
            #region DLL imports
            /// <summary>
            /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null
            /// </summary>
            /// <param name="idHook">The id of the event you want to hook</param>
            /// <param name="callback">The callback.</param>
            /// <param name="hInstance">The handle you want to attach the event to, can be null</param>
            /// <param name="threadId">The thread you want to attach the event to, can be null</param>
            /// <returns>a handle to the desired hook</returns>
            [DllImport("user32.dll")]
            static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);
    
            /// <summary>
            /// Unhooks the windows hook.
            /// </summary>
            /// <param name="hInstance">The hook handle that was returned from SetWindowsHookEx</param>
            /// <returns>True if successful, false otherwise</returns>
            [DllImport("user32.dll")]
            static extern bool UnhookWindowsHookEx(IntPtr hInstance);
    
            /// <summary>
            /// Calls the next hook.
            /// </summary>
            /// <param name="idHook">The hook id</param>
            /// <param name="nCode">The hook code</param>
            /// <param name="wParam">The wparam.</param>
            /// <param name="lParam">The lparam.</param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);
    
            /// <summary>
            /// Loads the library.
            /// </summary>
            /// <param name="lpFileName">Name of the library</param>
            /// <returns>A handle to the library</returns>
            [DllImport("kernel32.dll")]
            static extern IntPtr LoadLibrary(string lpFileName);
            #endregion
        }
    
        public class KeyDownUpEventArgs : EventArgs
        {
            public KeyDownUpEventArgs(int keyCode)
            {
                this.KeyCode = keyCode;
            }
    
            public int KeyCode { get; private set; }
            public bool Handled { get; set; }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.ServiceProcess;
    using System.Text;
    using System.Security.Principal;
    using System.Runtime.InteropServices;
    using System.IO;
    using System.Threading;
    namespace ConsoleApplication1
    {
        static class Program
        {
            static void Main(string[] args)
            {
                var thread = new Thread(delegate()
                {
                    globalKeyboardHook gkh = new globalKeyboardHook((uint)Win32APIs.GetCurrentThreadId());
                    gkh.HookedKeys.Add((int)'A');
                    gkh.HookedKeys.Add((int)'B');
                    gkh.KeyDown += new EventHandler<KeyDownUpEventArgs>(gkh_KeyDown);
                    gkh.KeyUp += new EventHandler<KeyDownUpEventArgs>(gkh_KeyUp);
    
                    int bRet;
                    tagMSG msg;
                    int hWnd = 0;
    
                    while ((bRet = Win32APIs.GetMessage(out msg, hWnd, 0, 0)) != 0)
                    {
                        if (bRet == -1)
                        {
                            // handle the error and possibly exit
                        }
                        else
                        {
                            Win32APIs.TranslateMessage(ref msg);
                            Win32APIs.DispatchMessage(ref msg);
                        }
                    }
                });
    
                thread.Start();
    
                Console.In.ReadLine();
            }
    
            static void gkh_KeyUp(object sender, KeyDownUpEventArgs e)
            {
                Console.WriteLine(string.Format("{0} up", (char)e.KeyCode));
            }
    
            static void gkh_KeyDown(object sender, KeyDownUpEventArgs e)
            {
                Console.WriteLine(string.Format("{0} down", (char)e.KeyCode));
            }
        }
    }
  • 相关阅读:
    2021NUAA暑假集训 Day3 题解
    2021NUAA暑假集训 Day2 题解
    2021NUAA暑期模拟赛部分题解
    CodeForces 1038D Slime
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 10689 Yet another Number Sequence
    HDU 4549 M斐波那契数列
    HDU 4990 Reading comprehension
    CodeForces 450B Jzzhu and Sequences
  • 原文地址:https://www.cnblogs.com/nanfei/p/2976650.html
Copyright © 2011-2022 走看看