天天看点

在C#中如何监视自己打开的其他程序

我们在做项目的时候,可能会碰到需要监视我们打开的其他的程序的关闭消息,比如我们打开个记事本或者帮助文件需要知道他们什么时候关闭

其实做到这个很简单,主要应用如下几个API

GetWindowLong (http://msdn.microsoft.com/en-us/library/ms633584(VS.85).aspx)

SetWindowLong (http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx)

CallWindowProc (http://msdn.microsoft.com/en-us/library/ms633571(VS.85).aspx)

下面我们举个简单的例子来说明下

假定要求如下:

程序没有主窗体,打开一个帮助文件,关闭帮助文件的时候程序退出

打开帮助文件,我们使用HtmlHelp (http://msdn.microsoft.com/en-us/library/aa164218(office.10).aspx)这个API

首先我们声明一个delagate,供SetWindowLong 使用

  1. public delegate int CallWindowProcDelegate(int Wnd, int Msg, int WParam, int LParam);
  2. public static CallWindowProcDelegate MyCallWindowProc;

然后我们声明几个需要用到的消息

  1. public const int HH_DISPLAY_INDEX = 0x0002; //显示帮助文件的时候,显示Index的Tab
  2. public const int GWL_WNDPROC = -4; //供GetWindowLong 和SetWindowLong 使用

然后定义一个私有变量,保存GetWindowLong 获得的值

  1. public static int oldWindow = 0;

接下来声明需要用到的API

  1. [DllImport("user32.dll")]
  2. protected static extern int GetWindowLong(int hwindow, int unindex);
  3. [DllImport("user32.dll")]
  4. protected static extern int CallWindowProc(int lpPrevWndFunc, int hWnd, int Msg, int wParam, int lParam);  
  5. [DllImport("user32.dll")]
  6. protected static extern int SetWindowLong(int hwindow, int unindex, CallWindowProcDelegate lnewvalue);//这个是关键
  7. [DllImport("hhctrl.ocx", CharSet = CharSet.Unicode, EntryPoint = "HtmlHelpW")]
  8. protected static extern int HtmlHelp(int caller,String file,uint command,String str);

在Main方法中:

  1. int handle = HtmlHelp(0, "e://CDMHELP.chm", HH_DISPLAY_INDEX, "");
  2. oldWindow = GetWindowLong(handle, GWL_WNDPROC);
  3. MyCallWindowProc = new CallWindowProcDelegate(WndProc);
  4. SetWindowLong(handle, GWL_WNDPROC, MyCallWindowProc);
  5. Application.Run();

WndProc方法

  1. private static int WndProc(int Wnd, int Msg, int WParam, int LParam)
  2. {
  3.     //在这里可以对你需要的消息进行监控,最后别忘了调用下面这句话
  4.     return CallWindowProc(oldWindow, Wnd, Msg, WParam, LParam);
  5. }

完整代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using System.Threading;
  6. using System.Diagnostics;
  7. using System.Runtime.InteropServices;
  8. namespace testApplication1
  9. {
  10.     public class test
  11.     {
  12.         public delegate int CallWindowProcDelegate(int Wnd, int Msg, int WParam, int LParam);
  13.         public static CallWindowProcDelegate MyCallWindowProc;
  14.         public const int HH_DISPLAY_INDEX = 0x0002;
  15.         public const int GWL_WNDPROC = -4;
  16.         public static int oldWindow = 0;
  17.         [STAThread]
  18.         static void Main(string[] args)
  19.         {
  20.             int handle = HtmlHelp(0, "e://CDMHELP.chm", HH_DISPLAY_INDEX, "");
  21.             oldWindow = GetWindowLong(handle, GWL_WNDPROC);
  22.             MyCallWindowProc = new CallWindowProcDelegate(WndProc);
  23.             SetWindowLong(handle, GWL_WNDPROC, MyCallWindowProc);
  24.             Application.Run();
  25.         }
  26.         private static int WndProc(int Wnd, int Msg, int WParam, int LParam)
  27.         {
  28.             //在这里监控消息
  29.             return CallWindowProc(oldWindow, Wnd, Msg, WParam, LParam);
  30.         }
  31.         [DllImport("user32.dll")]
  32.         public static extern int GetWindowLong(int hwindow, int nindex);
  33.         [DllImport("user32.dll")]
  34.         static extern int CallWindowProc(int lpPrevWndFunc, int hWnd, int Msg, int wParam, int lParam);  
  35.         [DllImport("user32.dll")]
  36.         public static extern int SetWindowLong(int hwindow, int nindex, CallWindowProcDelegate lnewvalue);
  37.         [DllImport("hhctrl.ocx", CharSet = CharSet.Unicode, EntryPoint = "HtmlHelpW")]
  38.         protected static extern int HtmlHelp(int caller,String file,uint command,String str);
  39.     }
  40. }

当然你也可以把SetWindowLong声明如下:

 [DllImport("user32.dll")]

public static extern int SetWindowLong(int hwindow, int unindex, int lnewvalue);

然后调用的时候使用

Marshal.GetFunctionPointerForDelegate(new CallWindowProcDelegate(WndProc).ToInt32());

欢迎转载,请注明出处~~

继续阅读