C#语言实例源码系列-虚拟键盘

news2024/11/25 22:52:08
专栏分享
  • 点击跳转=>Unity3D特效百例
  • 点击跳转=>案例项目实战源码
  • 点击跳转=>游戏脚本-辅助自动化
  • 点击跳转=>Android控件全解手册

👉关于作者

众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣 !!!
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎私我,交流群让学习不再孤单

在这里插入图片描述

👉实践过程

😜效果

在这里插入图片描述

😜代码

public partial class Form1 : Form
{
    private HookEx.UserActivityHook hook;//实例化HookEx.UserActivityHook
    private static IDictionary<short, IList<FecitButton>> spacialVKButtonsMap;//表示键/值对应的泛型集合
    private static IDictionary<short, IList<FecitButton>> combinationVKButtonsMap;//表示键/值对应的泛型集合

    public Form1()
    {
        InitializeComponent();

        #region 将指定的按钮值添加到键类型中
        spacialVKButtonsMap = new Dictionary<short, IList<FecitButton>>();
        combinationVKButtonsMap = new Dictionary<short, IList<FecitButton>>();
        IList<FecitButton> buttonList = new List<FecitButton>();//实例化IList<FecitButton>(按照索引单独访问的一组对象)
        buttonList.Add(this.btnLCTRL);//添加左面的CTRL键
        combinationVKButtonsMap.Add(KeyboardConstaint.VK_CONTROL, buttonList);//添加左面的CTRL键值
        buttonList = new List<FecitButton>();
        buttonList.Add(this.btnLSHFT);//添加左面的LSHFT键
        buttonList.Add(this.btnRSHFT);//添加右面的LSHFT键
        combinationVKButtonsMap.Add(KeyboardConstaint.VK_SHIFT, buttonList);//添加LSHFT键值
        buttonList = new List<FecitButton>();//实例化IList<FecitButton>
        buttonList.Add(this.btnLALT);//添加左面的ALT键
        combinationVKButtonsMap.Add(KeyboardConstaint.VK_MENU, buttonList);//添加左面的ALT键值
        buttonList = new List<FecitButton>();//实例化IList<FecitButton>
        buttonList.Add(this.btnLW);//添加左面的WIN键
        combinationVKButtonsMap.Add(KeyboardConstaint.VK_LWIN, buttonList);//添加左面的WIN键值
        buttonList = new List<FecitButton>();//实例化IList<FecitButton>
        buttonList.Add(this.btnLOCK);//添加LOCK键
        spacialVKButtonsMap.Add(KeyboardConstaint.VK_CAPITAL, buttonList);//添加LOCK键值
        #endregion

        foreach (Control ctrl in this.Controls)
        {
            FecitButton button = ctrl as FecitButton;
            if (button == null)
            {
                continue;
            }

            #region 设置按键的消息值
            short key = 0;//记录键值
            bool isSpacialKey = true;
            //记录快捷键的键值
            switch (button.Name)//获取键名称
            {
                case "btnLCTRL"://CTRL键的左键名称
                case "btnRCTRL"://CTRL键的右键名称
                    key = KeyboardConstaint.VK_CONTROL;//获取CTRL键的键值
                    break;
                case "btnLSHFT"://SHFT键的左键名称
                case "btnRSHFT"://SHFT键的左键名称
                    key = KeyboardConstaint.VK_SHIFT;//获取SHFT键的键值
                    break;
                case "btnLALT"://ALT键的左键名称
                case "btnRALT"://ALT键的左键名称
                    key = KeyboardConstaint.VK_MENU;//获取ALT键的键值
                    break;
                case "btnLW"://WIN键的左键名称
                case "btnRW"://WIN键的左键名称
                    key = KeyboardConstaint.VK_LWIN;//获取WIN键的键值
                    break;
                case "btnESC"://ESC键的名称
                    key = KeyboardConstaint.VK_ESCAPE;//获取ESC键的键值
                    break;
                case "btnTAB"://TAB键的名称
                    key = KeyboardConstaint.VK_TAB;//获取TAB键的键值
                    break;
                case "btnF1"://F1键的名称
                    key = KeyboardConstaint.VK_F1;//获取F1键的键值
                    break;
                case "btnF2":
                    key = KeyboardConstaint.VK_F2;
                    break;
                case "btnF3":
                    key = KeyboardConstaint.VK_F3;
                    break;
                case "btnF4":
                    key = KeyboardConstaint.VK_F4;
                    break;
                case "btnF5":
                    key = KeyboardConstaint.VK_F5;
                    break;
                case "btnF6":
                    key = KeyboardConstaint.VK_F6;
                    break;
                case "btnF7":
                    key = KeyboardConstaint.VK_F7;
                    break;

                case "btnF8":
                    key = KeyboardConstaint.VK_F8;
                    break;
                case "btnF9":
                    key = KeyboardConstaint.VK_F9;
                    break;
                case "btnF10":
                    key = KeyboardConstaint.VK_F10;
                    break;
                case "btnF11":
                    key = KeyboardConstaint.VK_F11;
                    break;
                case "btnF12":
                    key = KeyboardConstaint.VK_F12;
                    break;
                case "btnENT":
                case "btnNUMENT":
                    key = KeyboardConstaint.VK_RETURN;
                    break;
                case "btnWave":
                    key = KeyboardConstaint.VK_OEM_3;
                    break;
                case "btnSem":
                    key = KeyboardConstaint.VK_OEM_1;
                    break;
                case "btnQute":
                    key = KeyboardConstaint.VK_OEM_7;
                    break;
                case "btnSpace":
                    key = KeyboardConstaint.VK_SPACE;
                    break;
                case "btnBKSP":
                    key = KeyboardConstaint.VK_BACK;
                    break;
                case "btnComma":
                    key = KeyboardConstaint.VK_OEM_COMMA;
                    break;
                case "btnFullStop":
                    key = KeyboardConstaint.VK_OEM_PERIOD;
                    break;
                case "btnLOCK":
                    key = KeyboardConstaint.VK_CAPITAL;
                    break;
                case "btnMinus":
                    key = KeyboardConstaint.VK_OEM_MINUS;
                    break;
                case "btnEqual":
                    key = KeyboardConstaint.VK_OEM_PLUS;
                    break;
                case "btnLBracket":
                    key = KeyboardConstaint.VK_OEM_4;
                    break;
                case "btnRBracket":
                    key = KeyboardConstaint.VK_OEM_6;
                    break;
                case "btnPath":
                    key = KeyboardConstaint.VK_OEM_5;
                    break;
                case "btnDivide":
                    key = KeyboardConstaint.VK_OEM_2;
                    break;
                case "btnPSC":
                    key = KeyboardConstaint.VK_SNAPSHOT;
                    break;
                case "btnINS"://Insert键的名称
                    key = KeyboardConstaint.VK_INSERT;//获取Insert键的键值
                    break;
                case "btnDEL"://Delete键的名称
                    key = KeyboardConstaint.VK_DELETE;//获取Delete键的键值
                    break;
                default:
                    isSpacialKey = false;
                    break;
            }
            if (!isSpacialKey)
            {
                key = (short)button.Name[3];//获取按钮的键值
            }
            button.Tag = key;//在按钮的Tag属性中记录相应的键值
            #endregion
            button.Click += ButtonOnClick;//重载按钮的单击事件
        }
        this.hook = new HookEx.UserActivityHook(true, true);
        HookEvents();
    }

    private void HookEvents()
    {
        this.hook.KeyDown += HookOnGlobalKeyDown;//重载hook类中的自定义事件KeyDown
        this.hook.KeyUp += HookOnGlobalKeyUp;//重载hook类中的自定义事件KeyUp
        this.hook.MouseActivity += HookOnMouseActivity;//重载hook类中的自定义事件MouseActivity
    }

    private void ButtonOnClick(object sender, EventArgs e)//按键的单击事件
    {
        FecitButton btnKey = sender as FecitButton;//获取当前按键的信息
        if (btnKey == null)//如果按键为空值
            return;
        SendKeyCommand(btnKey);//发送按键的信息
    }

    /// <summary>
    /// 接收并发送按键信息
    /// </summary>
    /// <param keyButton="FecitButton">按键信息</param>
    private void SendKeyCommand(FecitButton keyButton)
    {
        short key = Convert.ToInt16(keyButton.Tag.ToString());//获取当前键的键值
        if (combinationVKButtonsMap.ContainsKey(key))//如果键值在键值列表中
        {
            if (keyButton.Checked)//如果按钮处于按下状态
            {
                SendKeyUp(key);//对按钮进行抬起操作
            }
            else
            {
                SendKeyDown(key);//对按钮进行按下操作
            }
        }
        else
        {
            //执行按钮按下和抬起的操作
            SendKeyDown(key);
            SendKeyUp(key);
        }
    }

    /// <summary>
    /// 记录键盘的按下操作的值
    /// </summary>
    /// <param key="short">键值</param>
    private void SendKeyDown(short key)
    {
        Input[] input = new Input[1];//实例化Input[]
        input[0].type = INPUT.KEYBOARD;//记录当有键值的类型
        input[0].ki.wVk = key;//记录当前键值
        input[0].ki.time = NativeMethods.GetTickCount();//获取自windows启动以来经历的时间长度(毫秒)
        //消息的输入
        if (NativeMethods.SendInput((uint)input.Length, input, Marshal.SizeOf(input[0])) < input.Length)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());//指定错误的初始化
        }
    }

    /// <summary>
    /// 记录键盘抬起操作的值
    /// </summary>
    /// <param key="short">键值</param>
    private void SendKeyUp(short key)
    {
        Input[] input = new Input[1];//实例化Input[]
        input[0].type = INPUT.KEYBOARD;//记录当有键值的类型
        input[0].ki.wVk = key;//记录当前键值
        input[0].ki.dwFlags = KeyboardConstaint.KEYEVENTF_KEYUP;
        input[0].ki.time = NativeMethods.GetTickCount();//获取自windows启动以来经历的时间长度(毫秒)
        //消息的输入
        if (NativeMethods.SendInput((uint)input.Length, input, Marshal.SizeOf(input[0])) < input.Length)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());//指定错误的初始化
        }
    }

    //键盘的按下事件
    private void HookOnGlobalKeyDown(object sender, HookEx.KeyExEventArgs e)
    {
        SetButtonStatus(e, true);
    }

    //键盘的抬起事件
    private void HookOnGlobalKeyUp(object sender, HookEx.KeyExEventArgs e)
    {
        SetButtonStatus(e, false);
    }

    /// <summary>
    /// 设置当前按钮的状态
    /// </summary>
    /// <param args="KeyExEventArgs">键信息</param>
    /// <param isDown="bool">标识,当前键是否按下</param>
    private void SetButtonStatus(HookEx.KeyExEventArgs args, bool isDown)
    {
        IList<FecitButton> buttonList = FindButtonList(args);//查找当有键
        if (buttonList.Count <= 0)//如果没有找到
            return;//退出本次操作
        short key = (short)args.KeyValue;//获取当前键的键值
        if (spacialVKButtonsMap.ContainsKey(key))//如果键/值列表中有该键
        {
            if (!isDown)//如果按钮没有被按下
            {
                FecitButton button = spacialVKButtonsMap[key][0];//设置按钮的信息
                button.Checked = !button.Checked;//设置当前按钮为按下状态
            }
        }
        else
        {
            foreach (FecitButton button in buttonList)//遍历IList中的所有按钮
            {
                if (button == null)//如果按钮为空
                    break;//退出循环
                button.Checked = isDown;//设置按钮的状态
            }
        }
    }

    /// <summary>
    /// 鼠标事件
    /// </summary>
    /// <param sener="object">鼠标对象</param>
    /// <param e="MouseExEventArgs">为MouseUp、MouseDown和MouseMove事件提供数据</param>
    private void HookOnMouseActivity(object sener, HookEx.MouseExEventArgs e)
    {
        Point location = e.Location;//获取鼠标的位置
        if (e.Button == MouseButtons.Left)//如果是鼠标左键
        {
            Rectangle captionRect = new Rectangle(this.Location, new Size(this.Width, SystemInformation.CaptionHeight));//获取窗体的所在区域
            if (captionRect.Contains(location))//如果鼠标在该窗体范围内
            {   //设置窗体的扩展样式
                NativeMethods.SetWindowLong(this.Handle, KeyboardConstaint.GWL_EXSTYLE, (int)NativeMethods.GetWindowLong(this.Handle, KeyboardConstaint.GWL_EXSTYLE) & (~KeyboardConstaint.WS_DISABLED));
                //将消息发送给指定窗体 
                NativeMethods.SendMessage(this.Handle, KeyboardConstaint.WM_SETFOCUS, IntPtr.Zero, IntPtr.Zero);
            }
            else
            {
                //设置窗体的扩展样式
                NativeMethods.SetWindowLong(this.Handle, KeyboardConstaint.GWL_EXSTYLE, (int)NativeMethods.GetWindowLong(this.Handle, KeyboardConstaint.GWL_EXSTYLE) | KeyboardConstaint.WS_DISABLED);
            }
        }
    }

    /// <summary>
    /// 在键列表中查找键值
    /// </summary>
    /// <param args="KeyExEventArgs">键信息</param>
    private IList<FecitButton> FindButtonList(HookEx.KeyExEventArgs args)
    {
        short key = (short)args.KeyValue;//获取键值
        if (key == KeyboardConstaint.VK_LCONTROL || key == KeyboardConstaint.VK_RCONTROL)//如果是CTRL键
        {
            key = KeyboardConstaint.VK_CONTROL;//记录CTRL键值
        }
        else if (key == KeyboardConstaint.VK_LSHIFT || key == KeyboardConstaint.VK_RSHIFT)//如果是SHIFT键
        {
            key = KeyboardConstaint.VK_SHIFT;//记录SHIFT键值
        }
        else if (key == KeyboardConstaint.VK_LMENU || key == KeyboardConstaint.VK_RMENU)//如果是ALT键
        {
            key = KeyboardConstaint.VK_MENU;//记录ALT键值
        }
        else if (key == KeyboardConstaint.VK_RWIN)//如果是WIN键
        {
            key = KeyboardConstaint.VK_LWIN;//记录WIN键值
        }

        if (combinationVKButtonsMap.ContainsKey(key))//如果在IDictionary的集合中
        {
            return combinationVKButtonsMap[key];//返回当前键的键值
        }
        IList<FecitButton> buttonList = new List<FecitButton>();//实例化IList<FecitButton>
        foreach (Control ctrl in this.Controls)//遍历当前窗体中的所有控件
        {
            FecitButton button = ctrl as FecitButton;//如果当前控件是FecitButton按钮
            if (button == null)//如果当前按钮为空
                continue;//重新循环
            short theKey = Convert.ToInt16(button.Tag.ToString());//获取当前按钮的键值
            if (theKey == key)//如果与当前操作的按钮相同
            {
                buttonList.Add(button);//添加当前操作的按键信息
                break;
            }
        }
        return buttonList;
    }
}
public partial class FecitButton : Button
{
    public FecitButton()
    {
        InitializeComponent();
        base.Font = new Font("宋体", 9.75F, FontStyle.Bold);
        base.Width = 26;
        base.Height = 25;
    }

    private Color Color_Brush = Color.MediumPurple;
    private Color Color_Pen = Color.Indigo;
    public static bool MouseE = false;

    private bool TChecked = false;
    [Browsable(true), Category("按钮操作"), Description("设置按钮是否被按下,如按下,则为true")]
    public bool Checked
    {
        get { return TChecked; }
        set
        {
            TChecked = value;
            Invalidate();
        }
    }

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        Color tem_colorb = Color_Brush;
        Color tem_colorp = Color_Pen;
        if (Checked)
        {
            Color_Brush = Color.Pink;
            Color_Pen = Color.PaleVioletRed;
        }
        else
        {
            Color_Brush = tem_colorb;
            Color_Pen = tem_colorp;
        }
        SolidBrush tem_Brush = new SolidBrush(Color_Brush);
        Pen tem_Pen = new Pen(new SolidBrush(Color_Pen), 2);
        e.Graphics.FillRectangle(tem_Brush, 0, 0, this.Width, this.Height);
        e.Graphics.DrawRectangle(tem_Pen, 1, 1, this.Width - 2, this.Height - 2);
        ProtractText(e.Graphics);
    }

    /// <summary>
    /// 鼠标移入控件的可见区域时触发
    /// </summary>
    protected override void OnMouseEnter(EventArgs e)
    {
        Color_Brush = Color.LightSteelBlue;
        Color_Pen = Color.LightSlateGray;
        Invalidate();
        base.OnMouseEnter(e);
    }

    /// <summary>
    /// 鼠标移出控件的可见区域时触发
    /// </summary>
    protected override void OnMouseLeave(EventArgs e)
    {
        Color_Brush = Color.MediumPurple;
        Color_Pen = Color.Indigo;
        Invalidate();
        base.OnMouseLeave(e);
    }

    private void ProtractText(Graphics g)
    {
        Graphics TitG = this.CreateGraphics();//创建Graphics类对象
        string TitS = base.Text;//获取图表标题的名称
        SizeF TitSize = TitG.MeasureString(TitS, this.Font);//将绘制的字符串进行格式化
        float TitWidth = TitSize.Width;//获取字符串的宽度
        float TitHeight = TitSize.Height;//获取字符串的高度
        float TitX = 0;//标题的横向坐标
        float TitY = 0;//标题的纵向坐标
        if (this.Height > TitHeight)
            TitY = (this.Height - TitHeight) / 2F;
        else
            TitY = 1;
        if (this.Width > TitWidth)
            TitX = (this.Width - TitWidth) / 2F;
        else
            TitX = 2;
        Rectangle rect = new Rectangle((int)Math.Floor(TitX), (int)Math.Floor(TitY), (int)Math.Ceiling(TitWidth), (int)Math.Ceiling(TitHeight));
        g.DrawString(TitS, base.Font,new SolidBrush(base.ForeColor), new PointF(TitX, TitY));

    }
}
internal static class KeyboardConstaint
{
    internal static readonly short VK_F1 = 0x70;
    internal static readonly short VK_F2 = 0x71;
    internal static readonly short VK_F3 = 0x72;
    internal static readonly short VK_F4 = 0x73;
    internal static readonly short VK_F5 = 0x74;
    internal static readonly short VK_F6 = 0x75;
    internal static readonly short VK_F7 = 0x76;
    internal static readonly short VK_F8 = 0x77;
    internal static readonly short VK_F9 = 0x78;
    internal static readonly short VK_F10 = 0x79;
    internal static readonly short VK_F11 = 0x7A;
    internal static readonly short VK_F12 = 0x7B;
    internal static readonly short VK_LEFT = 0x25;
    internal static readonly short VK_UP = 0x26;
    internal static readonly short VK_RIGHT = 0x27;
    internal static readonly short VK_DOWN = 0x28;
    internal static readonly short VK_NONE = 0x00;
    internal static readonly short VK_ESCAPE = 0x1B;
    internal static readonly short VK_EXECUTE = 0x2B;
    internal static readonly short VK_CANCEL = 0x03;
    internal static readonly short VK_RETURN = 0x0D;
    internal static readonly short VK_ACCEPT = 0x1E;
    internal static readonly short VK_BACK = 0x08;
    internal static readonly short VK_TAB = 0x09;
    internal static readonly short VK_DELETE = 0x2E;
    internal static readonly short VK_CAPITAL = 0x14;
    internal static readonly short VK_NUMLOCK = 0x90;
    internal static readonly short VK_SPACE = 0x20;
    internal static readonly short VK_DECIMAL = 0x6E;
    internal static readonly short VK_SUBTRACT = 0x6D;
    internal static readonly short VK_ADD = 0x6B;
    internal static readonly short VK_DIVIDE = 0x6F;
    internal static readonly short VK_MULTIPLY = 0x6A;
    internal static readonly short VK_INSERT = 0x2D;
    internal static readonly short VK_OEM_1 = 0xBA;  // ';:' for US
    internal static readonly short VK_OEM_PLUS = 0xBB;  // '+' any country
    internal static readonly short VK_OEM_MINUS = 0xBD;  // '-' any country
    internal static readonly short VK_OEM_2 = 0xBF;  // '/?' for US
    internal static readonly short VK_OEM_3 = 0xC0;  // '`~' for US
    internal static readonly short VK_OEM_4 = 0xDB;  //  '[{' for US
    internal static readonly short VK_OEM_5 = 0xDC;  //  '\|' for US
    internal static readonly short VK_OEM_6 = 0xDD;  //  ']}' for US
    internal static readonly short VK_OEM_7 = 0xDE;  //  ''"' for US
    internal static readonly short VK_OEM_PERIOD = 0xBE;  // '.>' any country
    internal static readonly short VK_OEM_COMMA = 0xBC;  // ',<' any country
    internal static readonly short VK_SHIFT = 0x10;
    internal static readonly short VK_CONTROL = 0x11;
    internal static readonly short VK_MENU = 0x12;
    internal static readonly short VK_LWIN = 0x5B;
    internal static readonly short VK_RWIN = 0x5C;
    internal static readonly short VK_APPS = 0x5D;
    internal static readonly short VK_LSHIFT = 0xA0;
    internal static readonly short VK_RSHIFT = 0xA1;
    internal static readonly short VK_LCONTROL = 0xA2;
    internal static readonly short VK_RCONTROL = 0xA3;
    internal static readonly short VK_LMENU = 0xA4;
    internal static readonly short VK_RMENU = 0xA5;
    internal static readonly short VK_SNAPSHOT = 0x2C;
    internal static readonly short VK_SCROLL = 0x91;
    internal static readonly short VK_PAUSE = 0x13;
    internal static readonly short VK_HOME = 0x24;
    internal static readonly short VK_NEXT = 0x22;
    internal static readonly short VK_PRIOR = 0x21;
    internal static readonly short VK_END = 0x23;
    internal static readonly short VK_NUMPAD0 = 0x60;
    internal static readonly short VK_NUMPAD1 = 0x61;
    internal static readonly short VK_NUMPAD2 = 0x62;
    internal static readonly short VK_NUMPAD3 = 0x63;
    internal static readonly short VK_NUMPAD4 = 0x64;
    internal static readonly short VK_NUMPAD5 = 0x65;
    internal static readonly short VK_NUMPAD5NOTHING = 0x0C;
    internal static readonly short VK_NUMPAD6 = 0x66;
    internal static readonly short VK_NUMPAD7 = 0x67;
    internal static readonly short VK_NUMPAD8 = 0x68;
    internal static readonly short VK_NUMPAD9 = 0x69;
    internal static readonly short KEYEVENTF_EXTENDEDKEY = 0x0001;
    internal static readonly short KEYEVENTF_KEYUP = 0x0002;
    internal static readonly int GWL_EXSTYLE = -20;
    internal static readonly int WS_DISABLED = 0X8000000;
    internal static readonly int WM_SETFOCUS = 0X0007;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
    public int dx;
    public int dy;
    public int mouseData;
    public int dwFlags;
    public int time;
    public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
    public short wVk;
    public short wScan;
    public int dwFlags;
    public int time;
    public IntPtr dwExtraInfo;
}

[StructLayout(LayoutKind.Explicit)]
internal struct Input
{
    [FieldOffset(0)]
    public int type;
    [FieldOffset(4)]
    public MOUSEINPUT mi;
    [FieldOffset(4)]
    public KEYBDINPUT ki;
    [FieldOffset(4)]
    public HARDWAREINPUT hi;
}

[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
    public int uMsg;
    public short wParamL;
    public short wParamH;
}

internal class INPUT
{
    public const int MOUSE = 0;
    public const int KEYBOARD = 1;
    public const int HARDWARE = 2;
}

internal static class NativeMethods
{
    [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    internal static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    internal static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("User32.dll", EntryPoint = "SendInput", CharSet = CharSet.Auto)]
    internal static extern UInt32 SendInput(UInt32 nInputs, Input[] pInputs, Int32 cbSize);

    [DllImport("Kernel32.dll", EntryPoint = "GetTickCount", CharSet = CharSet.Auto)]
    internal static extern int GetTickCount();

    [DllImport("User32.dll", EntryPoint = "GetKeyState", CharSet = CharSet.Auto)]
    internal static extern short GetKeyState(int nVirtKey);

    [DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    internal static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
}

需要的再直接Call我,直接发。

👉其他

📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。

温馨提示点击下方卡片获取更多意想不到的资源。
空名先生

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/92716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

guitar pro8吉他谱软件好用吗?2023GTP全新功能解析

我们常见的GTP格式吉他谱就是用这款软件制作出来的曲谱&#xff0c;也只能用这款软件打开查看。看介绍感觉还不错&#xff0c;原生支持Apple的芯片了。这也是一款能陪着我们一起进步&#xff0c;提升自己的软件。我们在练习吉他等乐器的过程中&#xff0c;音阶与和弦的熟练掌握…

ffmpeg-AVBuffer、AVBufferRef、引用计数机制

目录 引用计数 定义 优点 AVBuffer AVBufferRef av_buffer_create av_buffer_ref av_buffer_unref 参考&#xff1a; 引用计数 定义 引用计数是一种内存管理的方式&#xff0c;当一份内存可能被多个对象使用&#xff0c;可以通过引用计数的方式实现内存复用。 优点 …

深入理解Maven的各项配置

深入理解Maven的各项配置1. Introduction1.1 Big Data -- Postgres2. Install2.1 Maven Install2.2 Config Setting.xml2.3 Local Package Install Maven3. Project4.AwakeningMaven Document: https://maven.apache.org/. Maven Download: https://maven.apache.org/download.…

基于微信小程序的好物分享系统ssm框架-计算机毕业设计

项目介绍 我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;好物分享系统小程序被用户普遍使用&#xff0c;为方便用户…

【技术应用】mybatis数据库操作(insert、update、delete)返回值为0的场景

【技术应用】mybatis数据库操作insert、update、delete返回值为0的场景一、前言二、数据库异常处理三、insert操作返回值为: 0四、update操作返回值为: 0五、delete操作返回值为: 0六、总结一、前言 最近在review项目组成员代码时&#xff0c;发现代码中有很多mybatis执行数据…

涉及准考证相关需要关注的一系列问题,涉及防疫、考点信息、计算器等内容

12月14日起可以打印准考证&#xff01;这是一件操作并不复杂的工作&#xff0c;但打印下来以后可能会遇到一些细节问题&#xff0c;对此我们梳理出来供大家参考&#xff0c;有则改之&#xff0c;无则更好&#xff01; 1.有关省份个人健康申报表等如何填写&#xff1f;如您报考点…

web网页设计期末课程大作业:美食餐饮文化主题网站设计——美食汇5页HTML+CSS+JavaScript

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

事业编招聘:南方科技大学附属实验学校2022年·面向应届毕业生招聘在编教师公告

南方科技大学是在中国高等教育改革发展背景下创建的一所高起点公办创新型大学&#xff0c;2022年2月14日&#xff0c;教育部等三部委公布第二轮“双一流”建设高校及建设学科名单&#xff0c;南方科技大学入选“双一流”建设高校名单。 南方科技大学附属实验学校&#xff0c;地…

部署了一个个人博客(好歹服务器不是闲着了)

界面前台界面展示&#xff08;给到浏览用户&#xff09;后台界面展示&#xff08;简单介绍&#xff09;技术说明前台界面展示&#xff08;给到浏览用户&#xff09; 肯定首先将界面展示一下。声明一下这个不是我原创的界面&#xff0c;当然这个是可以改造的。这个在安全上还有…

血氧仪的分类与价格区别

有没有发现最近血氧仪、额温枪、壁挂式测温仪又开始火了&#xff1f;并且市场活跃度越来越高。而作为我们血氧仪方案提供商或者生产企业来说&#xff0c;您是不是和优优一样会时常听到客户发出如下反馈&#xff1a; “我刚问了另外一家&#xff0c;和你这个样子差不多的&#…

VC++2010中使用MSDN library 200X版本

前言 以前一直用VS2005 ,帮助文档调用很方便&#xff0c;现在要使用VS2010版本来写程序&#xff0c;这个帮助文档真是不方…… 自己写了一个F1的按键助手&#xff0c;这下我可 以使用VS2008中的帮助文档了&#xff0c;虽然帮助低一个版本&#xff0c;但是写C程序&#xff0c;…

七个步骤覆盖 API 接口测试

接口测试作为最常用的集成测试方法的一部分&#xff0c;通过直接调用被测试的接口来确定系统在功能性、可靠性、安全性和性能方面是否能达到预期&#xff0c;有些情况是功能测试无法覆盖的&#xff0c;所以接口测试是非常必要的。首先需要对接口测试的基本信息做一些了解&#…

阿里面试题库被“泄露“导致多人进大厂,惨遭多家大厂威胁下架

我有一个玩得特别好的朋友找我帮忙&#xff0c;说他儿子去大厂面试几次没刷下来&#xff0c;要求我帮他儿子出出主意&#xff0c;大概了解他儿子的情况后&#xff0c;我就给他推荐了这本软件测试10万总结&#xff0c;大概过了几个月他就给我发信息了&#xff0c;说他已经靠这份…

(一) Oriented R-CNN

文章目录0.基础介绍1.旋转框的中点偏移表示法2.Oriented R-CNN架构2.1 Oriented RPN2.2 Rotated RoI Alignment参考资料欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; 论文&#xff1a;Oriented R-CNN for Object Detection 代码&#xf…

Erlang - 入门之一日志系统如何打印输出使用lager框架

在合适的地方插入一句代码即可&#xff1a; lager:error("Some Message"), 就这样&#xff0c;谢谢阅读 。。。。。。。 。。。。。。。。。 。。。。。。。。。。。 。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。。。 没有什么比从直接“”…

web前端网页课程设计大作业 html+css+javascript天津旅游(11页) dw静态旅游网页设计实例 企业网站制作

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

草料二维码如何在多行业实现管理和自动化工作

二维码&#xff0c;在我们的日常生活中随处可见&#xff0c;不管是我们常用的微信支付&#xff0c;还是日常出入的场所码&#xff0c;已经渗透在我们生活的点点滴滴中。 如果我们自己也希望通过二维码&#xff0c;来传达文字、数据等信息&#xff0c;那么很多人都肯定给你推荐…

NS3笔记

NS3笔记1 Docker环境配置1.1 Docker安装1.2 镜像安装1.3 安装其他软件1.4 安装ns31 Docker环境配置 1.1 Docker安装 俺是macOS&#xff0c;直接参考这个网址。 1.2 镜像安装 俺打算安装Ubuntu18.04&#xff0c;镜像版本可以Ubuntu 镜像库 # 拉取镜像 docker pull ubuntu:18…

深入理解可升级智能合约

准备 为了理解可升级合约&#xff0c;必须理解proxy机制&#xff0c;要理解proxy机制&#xff0c;必须理解solidity的sstore和sload,以及关于以太坊架构和存储结构&#xff08;数据结构&#xff09;。 关于Solidity中的sstore和sload深入理解&#xff1a; 非常好的一篇剖析&…

SAP ABAP 散装笔记20220825

SAP ABAP 散装笔记20220825 引言&#xff1a; 散装笔记的标题系列中记录了我常用、备忘、易错的知识点。 关键字&#xff1a;SAP ABAP 散装笔记 知识点 文章目录SAP ABAP 散装笔记202208251. 获取域值和域值描述的两种方式2. 打开新的会话窗口&#xff08;并执行可能的事务码…