公司给客户开发的web程序A,有个表单里面是项目信息,客户有另一个web程序B(另一个公司开发的),也有一个表单里面是项目信息,现在客户要求,填写A时要把比较长的内容(比如项目名称)自动填写到B的表单上,由于浏览器的同源策略以及对剪切板访问的限制,顾通过js操作剪切板这个思路基本走不通。
后来上网查阅相关内容改用如下思路:
1.程序A中通过JS操作剪切板将项目信息存放到剪切板
2.C#开发一个winform程序,该程序加了一个定时器,每秒取一次剪切板,将项目信息读取存放到一个数组中,在该程序中通过键盘钩子监听ALT+P按键,先点击程序B的表单使获得焦点,按下ALT+P按键时,将数组内容通过剪切板和模拟键盘ctrl+v和tab操作,依次复制到目标表单中。
目前遇到的问题是当按下ALT+P时,程序B的表单立刻失去焦点(我把表单换成一个空的文本文件用记事本打开测试,记事本也失去焦点),由于失去焦点,模拟按键ctrl+v和tab操作也无法完成后续动作,我在响应函数加了System.Windows.Forms.MessageBox.Show弹窗,当点击弹窗确认按钮时却运行正常,请问大神这是什么原因因为字数限制只能截取部分代码了,后面会贴出来的,谢谢大家//3.判断输入键值(实现KeyDown事件)
private void hook_KeyDown(object sender, KeyEventArgs e)
{
//判断按下的键(Alt + P)
if (e.KeyValue == (int)Keys.P && (int)Control.ModifierKeys == (int)Keys.Alt)
{
//System.Windows.Forms.MessageBox.Show("按下了指定快捷键组合");
strArr[0] = this.textBox1.Text;
strArr[1] = this.textBox2.Text;
strArr[2] = this.textBox3.Text;
strArr[3] = this.textBox4.Text;
//radioButton1对应公开招标单选按钮
if (this.radioButton1.Checked)
{
publicBid();
}
////radioButton2对应竞价采购单选按钮
if (this.radioButton2.Checked) {
priceBid();
}
}
}[System.Runtime.InteropServices.DllImport("user32")]
private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
//移动鼠标
const int MOUSEEVENTF_MOVE = 0x0001;
//模拟鼠标左键按下
const int MOUSEEVENTF_LEFTDOWN = 0x0002;
//模拟鼠标左键抬起
const int MOUSEEVENTF_LEFTUP = 0x0004;
//模拟鼠标右键按下
const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
//模拟鼠标右键抬起
const int MOUSEEVENTF_RIGHTUP = 0x0010;
//模拟鼠标中键按下
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
//模拟鼠标中键抬起
const int MOUSEEVENTF_MIDDLEUP = 0x0040;
//标示是否采用绝对坐标
const int MOUSEEVENTF_ABSOLUTE = 0x8000; private void publicBid()
{ //mouse_event模拟鼠标单击是为了强制让表单B获取焦点,实际上加了也没用
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
foreach (string v in strArr)
{
//System.Windows.Forms.MessageBox.Show(v);
Clipboard.SetText(v);
ctrlVClick();
tabClick();
}
} private void priceBid()
{
//mouse_event模拟鼠标单击是为了强制让表单B获取焦点,实际上加了也没用
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
for (int i = 0; i < hitNumbers; i++)
{
//System.Windows.Forms.MessageBox.Show(strArr[i]);
Clipboard.SetText(strArr[i]);
ctrlVClick();
tabClick();
if (i == 2)
{
tabClick();
}
}
}下面是程序运行截图
后来上网查阅相关内容改用如下思路:
1.程序A中通过JS操作剪切板将项目信息存放到剪切板
2.C#开发一个winform程序,该程序加了一个定时器,每秒取一次剪切板,将项目信息读取存放到一个数组中,在该程序中通过键盘钩子监听ALT+P按键,先点击程序B的表单使获得焦点,按下ALT+P按键时,将数组内容通过剪切板和模拟键盘ctrl+v和tab操作,依次复制到目标表单中。
目前遇到的问题是当按下ALT+P时,程序B的表单立刻失去焦点(我把表单换成一个空的文本文件用记事本打开测试,记事本也失去焦点),由于失去焦点,模拟按键ctrl+v和tab操作也无法完成后续动作,我在响应函数加了System.Windows.Forms.MessageBox.Show弹窗,当点击弹窗确认按钮时却运行正常,请问大神这是什么原因因为字数限制只能截取部分代码了,后面会贴出来的,谢谢大家//3.判断输入键值(实现KeyDown事件)
private void hook_KeyDown(object sender, KeyEventArgs e)
{
//判断按下的键(Alt + P)
if (e.KeyValue == (int)Keys.P && (int)Control.ModifierKeys == (int)Keys.Alt)
{
//System.Windows.Forms.MessageBox.Show("按下了指定快捷键组合");
strArr[0] = this.textBox1.Text;
strArr[1] = this.textBox2.Text;
strArr[2] = this.textBox3.Text;
strArr[3] = this.textBox4.Text;
//radioButton1对应公开招标单选按钮
if (this.radioButton1.Checked)
{
publicBid();
}
////radioButton2对应竞价采购单选按钮
if (this.radioButton2.Checked) {
priceBid();
}
}
}[System.Runtime.InteropServices.DllImport("user32")]
private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
//移动鼠标
const int MOUSEEVENTF_MOVE = 0x0001;
//模拟鼠标左键按下
const int MOUSEEVENTF_LEFTDOWN = 0x0002;
//模拟鼠标左键抬起
const int MOUSEEVENTF_LEFTUP = 0x0004;
//模拟鼠标右键按下
const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
//模拟鼠标右键抬起
const int MOUSEEVENTF_RIGHTUP = 0x0010;
//模拟鼠标中键按下
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
//模拟鼠标中键抬起
const int MOUSEEVENTF_MIDDLEUP = 0x0040;
//标示是否采用绝对坐标
const int MOUSEEVENTF_ABSOLUTE = 0x8000; private void publicBid()
{ //mouse_event模拟鼠标单击是为了强制让表单B获取焦点,实际上加了也没用
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
foreach (string v in strArr)
{
//System.Windows.Forms.MessageBox.Show(v);
Clipboard.SetText(v);
ctrlVClick();
tabClick();
}
} private void priceBid()
{
//mouse_event模拟鼠标单击是为了强制让表单B获取焦点,实际上加了也没用
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
for (int i = 0; i < hitNumbers; i++)
{
//System.Windows.Forms.MessageBox.Show(strArr[i]);
Clipboard.SetText(strArr[i]);
ctrlVClick();
tabClick();
if (i == 2)
{
tabClick();
}
}
}下面是程序运行截图
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Macros
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
var k_hook = new KeyboardHook();
k_hook.KeyDownEvent += new KeyEventHandler(hook_KeyDown);
k_hook.Start();//安装键盘钩子
} //3.判断输入键值(实现KeyDown事件)
private void hook_KeyDown(object sender, KeyEventArgs e)
{
//判断按下的键(Alt + P)
if (e.KeyValue == (int)Keys.P && (int)Control.ModifierKeys == (int)Keys.Alt)
{
//System.Windows.Forms.MessageBox.Show("按下了指定快捷键组合");
strArr[0] = this.textBox1.Text;
strArr[1] = this.textBox2.Text;
strArr[2] = this.textBox3.Text;
strArr[3] = this.textBox4.Text;
if (this.radioButton1.Checked)
{
publicBid();
}
if (this.radioButton2.Checked) {
priceBid();
}
}
}
public String[] strArr=new String[4];
public const int hitNumbers=4;
#region bVk参数 常量定义 public const byte vbKeyLButton = 0x1; // 鼠标左键
public const byte vbKeyRButton = 0x2; // 鼠标右键
public const byte vbKeyCancel = 0x3; // CANCEL 键
public const byte vbKeyMButton = 0x4; // 鼠标中键
public const byte vbKeyBack = 0x8; // BACKSPACE 键
public const byte vbKeyTab = 0x9; // TAB 键
public const byte vbKeyClear = 0xC; // CLEAR 键
public const byte vbKeyReturn = 0xD; // ENTER 键
public const byte vbKeyShift = 0x10; // SHIFT 键
public const byte vbKeyControl = 0x11; // CTRL 键
public const byte vbKeyAlt = 18; // Alt 键 (键码18)
public const byte vbKeyMenu = 0x12; // MENU 键
public const byte vbKeyPause = 0x13; // PAUSE 键
public const byte vbKeyCapital = 0x14; // CAPS LOCK 键
public const byte vbKeyEscape = 0x1B; // ESC 键
public const byte vbKeySpace = 0x20; // SPACEBAR 键
public const byte vbKeyPageUp = 0x21; // PAGE UP 键
public const byte vbKeyEnd = 0x23; // End 键
public const byte vbKeyHome = 0x24; // HOME 键
public const byte vbKeyLeft = 0x25; // LEFT ARROW 键
public const byte vbKeyUp = 0x26; // UP ARROW 键
public const byte vbKeyRight = 0x27; // RIGHT ARROW 键
public const byte vbKeyDown = 0x28; // DOWN ARROW 键
public const byte vbKeySelect = 0x29; // Select 键
public const byte vbKeyPrint = 0x2A; // PRINT SCREEN 键
public const byte vbKeyExecute = 0x2B; // EXECUTE 键
public const byte vbKeySnapshot = 0x2C; // SNAPSHOT 键
public const byte vbKeyDelete = 0x2E; // Delete 键
public const byte vbKeyHelp = 0x2F; // HELP 键
public const byte vbKeyNumlock = 0x90; // NUM LOCK 键 //常用键 字母键A到Z
public const byte vbKeyA = 65;
public const byte vbKeyB = 66;
public const byte vbKeyC = 67;
public const byte vbKeyD = 68;
public const byte vbKeyE = 69;
public const byte vbKeyF = 70;
public const byte vbKeyG = 71;
public const byte vbKeyH = 72;
public const byte vbKeyI = 73;
public const byte vbKeyJ = 74;
public const byte vbKeyK = 75;
public const byte vbKeyL = 76;
public const byte vbKeyM = 77;
public const byte vbKeyN = 78;
public const byte vbKeyO = 79;
public const byte vbKeyP = 80;
public const byte vbKeyQ = 81;
public const byte vbKeyR = 82;
public const byte vbKeyS = 83;
public const byte vbKeyT = 84;
public const byte vbKeyU = 85;
public const byte vbKeyV = 86;
public const byte vbKeyW = 87;
public const byte vbKeyX = 88;
public const byte vbKeyY = 89;
public const byte vbKeyZ = 90; //数字键盘0到9
public const byte vbKey0 = 48; // 0 键
public const byte vbKey1 = 49; // 1 键
public const byte vbKey2 = 50; // 2 键
public const byte vbKey3 = 51; // 3 键
public const byte vbKey4 = 52; // 4 键
public const byte vbKey5 = 53; // 5 键
public const byte vbKey6 = 54; // 6 键
public const byte vbKey7 = 55; // 7 键
public const byte vbKey8 = 56; // 8 键
public const byte vbKey9 = 57; // 9 键
public const byte vbKeyNumpad0 = 0x60; //0 键
public const byte vbKeyNumpad1 = 0x61; //1 键
public const byte vbKeyNumpad2 = 0x62; //2 键
public const byte vbKeyNumpad3 = 0x63; //3 键
public const byte vbKeyNumpad4 = 0x64; //4 键
public const byte vbKeyNumpad5 = 0x65; //5 键
public const byte vbKeyNumpad6 = 0x66; //6 键
public const byte vbKeyNumpad7 = 0x67; //7 键
public const byte vbKeyNumpad8 = 0x68; //8 键
public const byte vbKeyNumpad9 = 0x69; //9 键
public const byte vbKeyMultiply = 0x6A; // MULTIPLICATIONSIGN(*)键
public const byte vbKeyAdd = 0x6B; // PLUS SIGN(+) 键
public const byte vbKeySeparator = 0x6C; // ENTER 键
public const byte vbKeySubtract = 0x6D; // MINUS SIGN(-) 键
public const byte vbKeyDecimal = 0x6E; // DECIMAL POINT(.) 键
public const byte vbKeyDivide = 0x6F; // DIVISION SIGN(/) 键
//F1到F12按键
public const byte vbKeyF1 = 0x70; //F1 键
public const byte vbKeyF2 = 0x71; //F2 键
public const byte vbKeyF3 = 0x72; //F3 键
public const byte vbKeyF4 = 0x73; //F4 键
public const byte vbKeyF5 = 0x74; //F5 键
public const byte vbKeyF6 = 0x75; //F6 键
public const byte vbKeyF7 = 0x76; //F7 键
public const byte vbKeyF8 = 0x77; //F8 键
public const byte vbKeyF9 = 0x78; //F9 键
public const byte vbKeyF10 = 0x79; //F10 键
public const byte vbKeyF11 = 0x7A; //F11 键
public const byte vbKeyF12 = 0x7B; //F12 键 #endregion #region
[System.Runtime.InteropServices.DllImport("user32")]
private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
//移动鼠标
const int MOUSEEVENTF_MOVE = 0x0001;
//模拟鼠标左键按下
const int MOUSEEVENTF_LEFTDOWN = 0x0002;
//模拟鼠标左键抬起
const int MOUSEEVENTF_LEFTUP = 0x0004;
//模拟鼠标右键按下
const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
//模拟鼠标右键抬起
const int MOUSEEVENTF_RIGHTUP = 0x0010;
//模拟鼠标中键按下
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
//模拟鼠标中键抬起
const int MOUSEEVENTF_MIDDLEUP = 0x0040;
//标示是否采用绝对坐标
const int MOUSEEVENTF_ABSOLUTE = 0x8000;
#endregion #region 引用win32api方法 /// <summary>
/// 导入模拟键盘的方法
/// </summary>
/// <param name="bVk" >按键的虚拟键值</param>
/// <param name= "bScan" >扫描码,一般不用设置,用0代替就行</param>
/// <param name= "dwFlags" >选项标志:0:表示按下,2:表示松开</param>
/// <param name= "dwExtraInfo">一般设置为0</param>
[DllImport("user32.dll")]
public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
#endregion private void tabClick()
{
keybd_event(vbKeyTab, 0, 0, 0);
keybd_event(vbKeyTab, 0, 2, 0);
} private void ctrlVClick()
{
keybd_event(vbKeyControl, 0, 0, 0);
keybd_event(vbKeyV, 0, 0, 0);
keybd_event(vbKeyControl, 0, 2, 0);
keybd_event(vbKeyV, 0, 2, 0);
} private void publicBid()
{
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
foreach (string v in strArr)
{
//System.Windows.Forms.MessageBox.Show(v);
Clipboard.SetText(v);
ctrlVClick();
tabClick();
}
} private void priceBid()
{
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
for (int i = 0; i < hitNumbers; i++)
{
//System.Windows.Forms.MessageBox.Show(strArr[i]);
Clipboard.SetText(strArr[i]);
ctrlVClick();
tabClick();
if (i == 2)
{
tabClick();
}
}
} private void timer1_Tick(object sender, EventArgs e)
{
// GetDataObject检索当前剪贴板上的数据
IDataObject iData = Clipboard.GetDataObject();
//将数据与指定的格式进行匹配,返回bool
if (iData.GetDataPresent(DataFormats.Text))
{
// GetData检索数据并指定一个格式
//this.textBox1.Text = (string)iData.GetData(DataFormats.Text);
String myStr = (string)iData.GetData(DataFormats.Text);
if (!string.IsNullOrEmpty(myStr))
{
if(myStr.Contains("|")){
strArr = myStr.Split(new Char[] { '|' });
if (strArr.Length == 4)
{
this.textBox1.Text = strArr[0] == "NULL" ? "" : strArr[0];
this.textBox2.Text = strArr[1] == "NULL" ? "" : strArr[1];
this.textBox3.Text = strArr[2] == "NULL" ? "" : strArr[2];
this.textBox4.Text = strArr[3] == "NULL" ? "" : strArr[3];
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Reflection;namespace Macros
{
class KeyboardHook
{
public event KeyEventHandler KeyDownEvent;
public event KeyPressEventHandler KeyPressEvent;
public event KeyEventHandler KeyUpEvent;
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
static int hKeyboardHook = 0; //声明键盘钩子处理的初始值
//值在Microsoft SDK的Winuser.h里查询
//转载自http://www.bianceng.cn/Programming/csharp/201410/45484.htm
public const int WH_KEYBOARD_LL = 13; //线程键盘钩子监听鼠标消息设为2,全局键盘监听鼠标消息设为13
HookProc KeyboardHookProcedure; //声明KeyboardHookProcedure作为HookProc类型
//键盘结构
[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct
{
public int vkCode; //定一个虚拟键码。该代码必须有一个价值的范围1至254
public int scanCode; // 指定的硬件扫描码的关键
public int flags; // 键标志
public int time; // 指定的时间戳记的这个讯息
public int dwExtraInfo; // 指定额外信息相关的信息
}
//使用此功能,安装了一个钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//调用此函数卸载钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//使用此功能,通过信息钩子继续下一个钩子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
// 取得当前线程编号(线程钩子需要用到)
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
//使用WINDOWS API函数代替获取当前实例的函数,防止钩子失效
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
public void Start()
{
// 安装键盘钩子
if (hKeyboardHook == 0)
{
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
//hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
//************************************
//键盘线程钩子
//SetWindowsHookEx( 2,KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId());//指定要监听的线程idGetCurrentThreadId(),
//键盘全局钩子,需要引用空间(using System.Reflection;)
//SetWindowsHookEx( 13,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
//
//关于SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)函数将钩子加入到钩子链表中,说明一下四个参数:
//idHook 钩子类型,即确定钩子监听何种消息,上面的代码中设为2,即监听键盘消息并且是线程钩子,如果是全局钩子监听键盘消息应设为13,
//线程钩子监听鼠标消息设为7,全局钩子监听鼠标消息设为14。lpfn 钩子子程的地址指针。如果dwThreadId参数为0 或是一个由别的进程创建的
//线程的标识,lpfn必须指向DLL中的钩子子程。 除此以外,lpfn可以指向当前进程的一段钩子子程代码。钩子函数的入口地址,当钩子钩到任何
//消息后便调用这个函数。hInstance应用程序实例的句柄。标识包含lpfn所指的子程的DLL。如果threadId 标识当前进程创建的一个线程,而且子
//程代码位于当前进程,hInstance必须为NULL。可以很简单的设定其为本应用程序的实例句柄。threaded 与安装的钩子子程相关联的线程的标识符
//如果为0,钩子子程与所有的线程关联,即为全局钩子
//************************************
//如果SetWindowsHookEx失败
if (hKeyboardHook == 0)
{
Stop();
throw new Exception("安装键盘钩子失败");
}
}
}
public void Stop()
{
bool retKeyboard = true;
if (hKeyboardHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
}
if (!(retKeyboard)) throw new Exception("卸载钩子失败!");
}
//ToAscii职能的转换指定的虚拟键码和键盘状态的相应字符或字符
[DllImport("user32")]
public static extern int ToAscii(int uVirtKey, //[in] 指定虚拟关键代码进行翻译。
int uScanCode, // [in] 指定的硬件扫描码的关键须翻译成英文。高阶位的这个值设定的关键,如果是(不压)
byte[] lpbKeyState, // [in] 指针,以256字节数组,包含当前键盘的状态。每个元素(字节)的数组包含状态的一个关键。如果高阶位的字节是一套,关键是下跌(按下)。在低比特,如果设置表明,关键是对切换。在此功能,只有肘位的CAPS LOCK键是相关的。在切换状态的NUM个锁和滚动锁定键被忽略。
byte[] lpwTransKey, // [out] 指针的缓冲区收到翻译字符或字符。
int fuState); // [in] Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise.
//获取按键的状态
[DllImport("user32")]
public static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern short GetKeyState(int vKey);
private const int WM_KEYDOWN = 0x100;//KEYDOWN
private const int WM_KEYUP = 0x101;//KEYUP
private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
private const int WM_SYSKEYUP = 0x105;//SYSKEYUP
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
// 侦听键盘事件
if ((nCode >= 0) && (KeyDownEvent != null || KeyUpEvent != null || KeyPressEvent != null))
{
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
// raise KeyDown
if (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyDownEvent(this, e);
}
//键盘按下
if (KeyPressEvent != null && wParam == WM_KEYDOWN)
{
byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
{
KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
KeyPressEvent(this, e);
}
}
// 键盘抬起
if (KeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
{
Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyUpEvent(this, e);
}
}
//如果返回1,则结束消息,这个消息到此为止,不再传递。
//如果返回0或调用CallNextHookEx函数则消息出了这个钩子继续往下传递,也就是传给消息真正的接受者
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
~KeyboardHook()
{
Stop();
}
}
}