软件编程
位置:首页>> 软件编程>> C#编程>> C#实现虚拟键盘的实例详解

C#实现虚拟键盘的实例详解

作者:芝麻粒儿  发布时间:2021-09-21 08:59:47 

标签:C#,虚拟,键盘

实践过程

效果

C#实现虚拟键盘的实例详解

代码

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);
}

来源:https://blog.csdn.net/qq_27489007/article/details/128306815

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com