读书人

c# 全局钩子有关问题

发布时间: 2012-03-21 13:33:14 作者: rapoo

c# 全局钩子问题
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace wa_hooktest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
internal enum HookType //枚举,钩子的类型
{

//MsgFilter = -1,

//JournalRecord = 0,

//JournalPlayback = 1,

Keyboard = 2,

//GetMessage = 3,

//CallWndProc = 4,

//CBT = 5,

//SysMsgFilter = 6,

//Mouse = 7,

//Hardware = 8,

//Debug = 9,

//Shell = 10,

//ForegroundIdle = 11,

//CallWndProcRet = 12,

KeyboardLL = 13,

//MouseLL = 14,

};

[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId(); //取得当前线程编号的API

[DllImport("User32.dll")]
internal extern static void UnhookWindowsHookEx(IntPtr handle); //取消Hook的API


[DllImport("User32.dll")]
internal extern static IntPtr SetWindowsHookEx(int idHook, [MarshalAs(UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr hinstance, int threadID); //设置Hook的API


[DllImport("User32.dll")]
internal extern static IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam); //取得下一个Hook的API
IntPtr _nextHookPtr; //记录Hook编号

public delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);
public IntPtr MyHookProc(int code, IntPtr wparam, IntPtr lparam)
{
if (code < 0)
{
return CallNextHookEx(_nextHookPtr, code, wparam, lparam);
} //返回,让后面的程序处理该消息

if (wparam.ToInt32() == 98 || wparam.ToInt32() == 66)
{//如果用户输入的是 b

this.textBox1.Text = "a";
return (IntPtr)1; //直接返回了,该消息就处理结束了
}
else
{
return IntPtr.Zero; //返回,让后面的程序处理该消息
}



//if (wparam.ToInt32() == 91)
//{
// return (IntPtr)1;
//}
//else {
// return IntPtr.Zero;
//}
}

public void SetHook()
{

if (_nextHookPtr != IntPtr.Zero) //已经勾过了

return;
//线程钩子
HookProc myhookProc = new HookProc(MyHookProc); //声明一个自己的Hook实现函数的委托对象

//_nextHookPtr = SetWindowsHookEx((int)HookType.Keyboard, myhookProc, IntPtr.Zero, GetCurrentThreadId()); //加到Hook链中

//全局钩子
_nextHookPtr = SetWindowsHookEx((int)HookType.KeyboardLL, myhookProc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0 ); //加到Hook链中



MessageBox.Show(_nextHookPtr.ToString());
}



public void UnHook()
{

if (_nextHookPtr != IntPtr.Zero)
{
UnhookWindowsHookEx(_nextHookPtr); //从Hook链中取消
_nextHookPtr = IntPtr.Zero;
}

}

private void Form1_Load(object sender, EventArgs e)
{
SetHook();
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
UnHook();
}
}
}

[解决办法]
类似的问题好多............前几天就有人文这个问题。你也不说明什么问题就发代码...
新建一个form4窗体.增加2个button,增加事件。。然后复制代码
其实不一样的地方就是红色的地方
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;

namespace WindowsApplication1
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class Form4 : Form
{
//委托
public delegate int HookProc(int nCode, int wParam, IntPtr lParam);
static int hHook = 0;
public const int WH_KEYBOARD_LL = 13;
//LowLevel键盘截获,如果是WH_KEYBOARD=2,并不能对系统键盘截取,Acrobat Reader会在你截取之前获得键盘。
HookProc KeyBoardHookProcedure;
//键盘Hook结构函数
[StructLayout(LayoutKind.Sequential)]
public class KeyBoardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
#region DllImport
//设置钩子
[DllImport("user32.dll")]
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")]
//调用下一个钩子
public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();

[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);

#endregion
#region 自定义事件
public void Hook_Start()
{
// 安装键盘钩子
if (hHook == 0)
{
KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);

//hHook = SetWindowsHookEx(2,
// KeyBoardHookProcedure,
// GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), GetCurrentThreadId());

hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
KeyBoardHookProcedure,
GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
//如果设置钩子失败.
if (hHook == 0)
{
Hook_Clear();
//throw new Exception("设置Hook失败!");
}
}
}

//取消钩子事件
public void Hook_Clear()


{
bool retKeyboard = true;
if (hHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hHook);
hHook = 0;
}
//如果去掉钩子失败.
if (!retKeyboard) throw new Exception("UnhookWindowsHookEx failed.");
}

//这里可以添加自己想要的信息处理
public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam)
{
if (nCode >= 0)
{

KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
if (kbh.vkCode == (int)Keys.S && (int)Control.ModifierKeys == (int)Keys.Control) // 截获F8
{
MessageBox.Show("快捷键已拦截!不能保存!");
return 1;

}
if (kbh.vkCode == (int)Keys.Y
&& (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt) //截获Ctrl+Alt+Y
{

//MessageBox.Show("不能全部保存!");
return 1;
}
if (kbh.vkCode == (int)Keys.X)
{
MessageBox.Show("不能全部保存!");
return 1;
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
#endregion

public Form4()
{

InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Hook_Start();
}

private void button2_Click(object sender, EventArgs e)
{
Hook_Clear();
}







}
}

读书人网 >C#

热点推荐