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));
            }
        }
    }
  • 相关阅读:
    git push错误,如何回滚
    mybatis类型转换器
    SpringBoot2 + Druid + Mybatis 多数据源动态配置
    从SqlSessionFactoryBean的引用浅谈spring两种bean模式
    maven常用命令
    ubuntu 16.04安装mysql server入门
    HTML5多文件异步上传 个人笔记代码
    sqlserver中取出刚插入的主键(主键是guid类型)
    快速排序示例代码
    oracle用户创建及权限设置(转)
  • 原文地址:https://www.cnblogs.com/nanfei/p/2976650.html
Copyright © 2011-2022 走看看