我练习使用API32写了一个DLL,在任意窗口点击鼠标左键可查看该窗口的类名,可顺利通过调试。但程序运行一会就出现‘未处理的“System.NullReferenceException”类型的异常出现在 system.windows.forms.dll 中。其他信息: 未将对象引用设置到对象的实例。’谁能给分析一下,这是什么原因? 先将源码附上,请大家共同探讨。
//以下为DLL类库源码 using System; using System.Runtime.InteropServices; using System.Text;
namespace MHook { /// <summary> /// Class1 的摘要说明。 /// </summary> public class MouseHook { public MouseHook() { // // TODO: 在此处添加构造函数逻辑 // }
#region //********API32函数声明**************
// **********************************************************************
// Win32: SetWindowsHookEx() [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] private static extern IntPtr SetWindowsHookEx(HookType code, HookProc func, IntPtr hInstance, int threadID);
// Win32: UnhookWindowsHookEx() [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] private static extern int UnhookWindowsHookEx(IntPtr hhook);
// Win32: CallNextHookEx() [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] private static extern int CallNextHookEx(IntPtr hhook, int nCode, int wParam, IntPtr lParam);
// Win32: GetModuleHandle() [DllImport("kernel32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] private static extern IntPtr GetModuleHandle(string lpModuleName);
// Win32: GetForegroundWindow() [DllImport( "user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] private static extern IntPtr GetForegroundWindow();
// Win32: GetWindowThreadProcessId() [DllImport("user32.dll",CharSet=CharSet.Auto)] private static extern int GetWindowThreadProcessId ( IntPtr hwnd, int lpdwProcessId );
// Win32: GetCurrentThreadId [DllImport("kernel32.dll", EntryPoint="GetCurrentThreadId")] public static extern int GetCurrentThreadId ();
// Win32: AttachThreadInput() [DllImport("user32.dll",CharSet=CharSet.Auto)] private static extern int AttachThreadInput ( int idAttach, int idAttachTo, int fAttach );
// Win32: GetFocus() [DllImport("user32.dll",CharSet=CharSet.Auto)] private static extern IntPtr GetFocus ();
// Win32: SendMessage() [DllImport("user32.dll",CharSet=CharSet.Auto)] private static extern int SendMessage ( HandleRef hwnd, int wMsg, int wParam, int lParam );
[DllImport("user32.dll", EntryPoint="SendMessage",CharSet=CharSet.Auto)] public static extern int SendMessageString ( HandleRef hwnd, int wMsg, int wParam, StringBuilder lParam ); // Win32: GetWindowText() [DllImport("user32.dll",CharSet=CharSet.Auto)] private static extern int GetWindowText ( IntPtr hwnd, StringBuilder lpString, int nMaxCount );
// Win32: GetClassName() [DllImport("user32.dll",CharSet=CharSet.Auto)] private static extern int GetClassName ( IntPtr hwnd, StringBuilder lpClassName, int nMaxCount );
#endregion
//enum HookType private enum HookType : int { //WH_JOURNALRECORD = 0, //WH_JOURNALPLAYBACK = 1, //WH_KEYBOARD = 2, //WH_GETMESSAGE = 3, //WH_CALLWNDPROC = 4, //WH_CBT = 5, //WH_SYSMSGFILTER = 6, //WH_MOUSE = 7, //WH_HARDWARE = 8, //WH_DEBUG = 9, //WH_SHELL = 10, //WH_FOREGROUNDIDLE = 11, //WH_CALLWNDPROCRET = 12, //WH_KEYBOARD_LL = 13, WH_MOUSE_LL = 14 }
// Filter function delegate private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
// ********************************************************************** //指向钩子处理函数,该函数是自定义的而由Window系统调用的函数,即回调函数 // **********************************************************************
private const int WM_LBUTTONUP=0x0202; private const int WM_SETTEXT=0x000C; private const int WM_PAINT= 0x000F;
private static IntPtr hookWnd =IntPtr.Zero; private static HandleRef txtHandle; private static StringBuilder lpClassName = new StringBuilder("Hello!",256); //*************************************************************************
public static bool SetHook(HandleRef myHandle) { IntPtr dllInstance = GetModuleHandle("MHook.dll"); if (dllInstance==IntPtr.Zero) { return false; }
else { txtHandle = myHandle; hookWnd=SetWindowsHookEx( HookType.WH_MOUSE_LL, new HookProc(MouseHook.MyMouseProc), dllInstance, 0); if (hookWnd==IntPtr.Zero) { return false; } return true; }
}
public static void StopHook() { UnhookWindowsHookEx(hookWnd ); } private static int MyMouseProc(int nCode, int wParam, IntPtr lParam) {
if(nCode<0) { return CallNextHookEx(hookWnd,nCode,wParam,lParam); }
else if(wParam==WM_LBUTTONUP) { myProc(); return CallNextHookEx(hookWnd,nCode,wParam,lParam);
} else { //调用钩子函数链,以便使其他应用程序能够正常工作 return CallNextHookEx(hookWnd,nCode,wParam,lParam); } }
private static bool myProc() { //获得当前活动窗口句柄 IntPtr foreWnd = GetForegroundWindow(); if (foreWnd==IntPtr.Zero) { return false; } //获得活动窗口的线程号 int threadforeground = GetWindowThreadProcessId(foreWnd, 0); if (threadforeground==0) { return false; }
//获得与自己程序的窗口相关的线程号 int threadthis = GetCurrentThreadId(); if (threadthis==0) { return false; }
//将两个线程的输入联系起来,GetFocus函数获得其它线程中的焦点窗口 int attchFlag =AttachThreadInput(threadthis,threadforeground,1); //得到当前的具有输入焦点的子窗口 IntPtr subWnd = GetFocus(); if (subWnd==IntPtr.Zero) { return false; } //获得当前的具有输入焦点的子窗口的主窗口的类名 int getClassFlag = GetClassName(subWnd,lpClassName,lpClassName.Capacity); if (getClassFlag==0) { return false; }
AttachThreadInput(threadthis, threadforeground, 0);
int sendMsgFlag1 = SendMessageString(txtHandle,WM_SETTEXT,0,lpClassName); if (sendMsgFlag1==0) { return false; } int sendMsgFlag2 = SendMessage(txtHandle,WM_PAINT,0,0); if (sendMsgFlag2==0) { return false; } return true; }
} }
//以下是主程序,很简单,只是简单调用了DLL中函数 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using MHook; using System.Runtime.InteropServices;
namespace testhook { /// <summary> /// Form1 的摘要说明。 /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.TextBox textBox1; //private int hookHandle; private System.Windows.Forms.Button button1; /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.Container components = null;
public Form1() { // // Windows 窗体设计器支持所必需的 // InitializeComponent();
// // TODO: 在 InitializeComponent 调用后添加任何构造函数代码 // }
/// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); }
#region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); this.button1 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(48, 104); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(384, 28); this.textBox1.TabIndex = 0; this.textBox1.Text = "textBox1"; // // button1 // this.button1.Location = new System.Drawing.Point(128, 168); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(136, 40); this.button1.TabIndex = 1; this.button1.Text = "button1"; this.button1.Click += new System.EventHandler(this.button1_Click); // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(10, 21); this.ClientSize = new System.Drawing.Size(480, 267); this.Controls.Add(this.button1); this.Controls.Add(this.textBox1); this.Name = "Form1"; this.Text = "Form1"; this.TopMost = true; this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing); this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false);
} #endregion
/// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); }
private void Form1_Load(object sender, System.EventArgs e) { HandleRef hrTextBox=new HandleRef(textBox1,textBox1.Handle); if((MouseHook.SetHook(hrTextBox))==false) MessageBox.Show ("安装钩子失败!");
}
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e) { MouseHook.StopHook(); }
private void button1_Click(object sender, System.EventArgs e) { ; } } }

|