编程语言

img eclipse99

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

发表于2004/10/17 21:03:00  2195人阅读

我练习使用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)
  {
              ;
   
  }
 }
}

阅读全文
0 0

相关文章推荐

img
取 消
img