首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

c# 全局钩子有关问题

2012-03-21 
c# 全局钩子问题using Systemusing System.Collections.Genericusing System.ComponentModelusing Syst

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







}
}

热点排行