C#钩子函数如果直接用按钮引用,则没有问题,如果把这个函数放到多线程里,就会发现钩子钩不上了,这个问题我搞了一个星期也没搞定,后来还是查资料的时候无意中看到类似的问题,试了一下,发现真的可以完美解决此问题,现在把解决方法记下!
解决方法:
只要在线程中加入下面这段代码就行了:
tagMSG Msgs;
while (GetMessage(out Msgs, IntPtr.Zero, 0, 0) > 0)
{
TranslateMessage(ref Msgs);
DispatchMessage(ref Msgs);
}
其中结构体和函数的定义如下:
[DllImport("user32", EntryPoint = "GetMessage")]
public static extern int GetMessage(
out tagMSG lpMsg,
IntPtr 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
);
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}
public struct tagMSG
{
public int hwnd;
public uint message;
public int wParam;
public long lParam;
public uint time;
public int pt;
}
举个例子吧,下面1钩子不成功,2,3钩子成功:
1.(多线程失败)
private void Form1_Load(object sender, EventArgs e)
{
Thread th = new Thread(new ThreadStart(temp));
th.IsBackground = true;
//th.SetApartmentState(ApartmentState.STA);
th.Start();
}
private void temp()
{
hookKeyBoard = new HookKeyBoard();
hookKeyBoard.HookKeyBoardHandler += HookKeyBoardHandler;
hookKeyBoard.SetHook();
CheckForIllegalCrossThreadCalls = false;
}
2.(不利用多线程成功)
private void Form1_Load(object sender, EventArgs e)
{
hookKeyBoard = new HookKeyBoard();
hookKeyBoard.HookKeyBoardHandler += HookKeyBoardHandler;
hookKeyBoard.SetHook();
CheckForIllegalCrossThreadCalls = false;
}
3. (多线程成功)
private void Form1_Load(object sender, EventArgs e)
{
Thread th = new Thread(new ThreadStart(temp));
th.IsBackground = true;
//th.SetApartmentState(ApartmentState.STA);
th.Start();
}
private void temp()
{
hookKeyBoard = new HookKeyBoard();
hookKeyBoard.HookKeyBoardHandler += HookKeyBoardHandler;
hookKeyBoard.SetHook();
CheckForIllegalCrossThreadCalls = false;
tagMSG Msgs;
while (GetMessage(out Msgs, IntPtr.Zero, 0, 0) > 0)
{
TranslateMessage(ref Msgs);
DispatchMessage(ref Msgs);
}
}
写得够明白了吧,呵呵!