使用DLL时如何处理“System.NullReferenceException”类型的异常

我练习使用API32写了一个DLL,在任意窗口点击鼠标左键可查看该窗口的类名,可顺利通过调试。但程序运行一会就出现‘未处理的“System.NullReferenceException”类型的异常出现在 system.windows.forms.dll 中。其他信息: 未将对象引用设置到对象的实例。’谁能给分析一下,这是什么原因?
先将源码附上,请大家共同探讨。

//以下为DLL类库源码
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace MHook
{
///

1<summary>   
2/// Class1 的摘要说明。   
3/// </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
{
///

1<summary>   
2/// Form1 的摘要说明。   
3/// </summary>

public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
//private int hookHandle;
private System.Windows.Forms.Button button1;
///

1<summary>   
2/// 必需的设计器变量。   
3/// </summary>

private System.ComponentModel.Container components = null;

public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//

}

///

1<summary>   
2/// 清理所有正在使用的资源。   
3/// </summary>

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows 窗体设计器生成的代码
///

1<summary>   
2/// 设计器支持所需的方法 - 不要使用代码编辑器修改   
3/// 此方法的内容。   
4/// </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

///

1<summary>   
2/// 应用程序的主入口点。   
3/// </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)
{
;

}
}
}

Published At
Categories with Web编程
Tagged with
comments powered by Disqus