本人对钩子进行了研究,发现执行钩子函数后会破坏消息循环:具体情况如下,下面源代码中,钩子函数实现的功能是屏蔽按键并在一个TEXTBOX中显示ABC,然而我又在这个TEXTBOX添加了一个键盘按下事件(执行弹出一个提示框),我的测试目的是看下执行完钩子函数后,是否会接着执行这个TEXTBOX上的键盘事件。事实证明,在TEXTBOX中显示ABC后并没有弹出提示框,所以我认为安装钩子会影响到消息循环,不知道我的这个测试结果有什么错误没,或者我在理解钩子上有误差,请各位积极讨论并指点。还有一个问题是我把SETWINDOWSHOOKEX函数的最后一个参数设为0后会抛出异常,提示安装钩子失败,我记得那是设置全局钩子的啊 怎么会错呢?
public partial class Form1 : Form
{
// 安装钩子
[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(); public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
static int hKeyboardHook = 0;
HookProc KeyboardHookProcedure;
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
if (nCode >= 0)
{
textBox1.Text = "ABC";
return 1;
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
} // 安装钩子
public void HookStart()
{
if (hKeyboardHook == 0)
{
// 创建HookProc实例
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
// 设置线程钩子
hKeyboardHook = SetWindowsHookEx(2, KeyboardHookProcedure, IntPtr.Zero,GetCurrentThreadId()
);/*GetCurrentThreadId()*/
// 如果设置钩子失败
if (hKeyboardHook == 0)
{
HookStop();
throw new Exception("SetWindowsHookEx failed.");
}
}
}
// 卸载钩子
public void HookStop()
{
bool retKeyboard = true;
if (hKeyboardHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
}
if (!(retKeyboard && retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
}
public Form1()
{
InitializeComponent();
this.HookStart(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
this.HookStop();
} private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
MessageBox.Show("key press");
}
}
public partial class Form1 : Form
{
// 安装钩子
[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(); public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
static int hKeyboardHook = 0;
HookProc KeyboardHookProcedure;
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
if (nCode >= 0)
{
textBox1.Text = "ABC";
return 1;
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
} // 安装钩子
public void HookStart()
{
if (hKeyboardHook == 0)
{
// 创建HookProc实例
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
// 设置线程钩子
hKeyboardHook = SetWindowsHookEx(2, KeyboardHookProcedure, IntPtr.Zero,GetCurrentThreadId()
);/*GetCurrentThreadId()*/
// 如果设置钩子失败
if (hKeyboardHook == 0)
{
HookStop();
throw new Exception("SetWindowsHookEx failed.");
}
}
}
// 卸载钩子
public void HookStop()
{
bool retKeyboard = true;
if (hKeyboardHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
}
if (!(retKeyboard && retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");
}
public Form1()
{
InitializeComponent();
this.HookStart(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
this.HookStop();
} private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
MessageBox.Show("key press");
}
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货