我们在做项目的时候,可能会碰到需要监视我们打开的其他的程序的关闭消息,比如我们打开个记事本或者帮助文件需要知道他们什么时候关闭
其实做到这个很简单,主要应用如下几个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 使用
- public delegate int CallWindowProcDelegate(int Wnd, int Msg, int WParam, int LParam);
- public static CallWindowProcDelegate MyCallWindowProc;
然后我们声明几个需要用到的消息
- public const int HH_DISPLAY_INDEX = 0x0002; //显示帮助文件的时候,显示Index的Tab
- public const int GWL_WNDPROC = -4; //供GetWindowLong 和SetWindowLong 使用
然后定义一个私有变量,保存GetWindowLong 获得的值
- public static int oldWindow = 0;
接下来声明需要用到的API
- [DllImport("user32.dll")]
- protected static extern int GetWindowLong(int hwindow, int unindex);
- [DllImport("user32.dll")]
- protected static extern int CallWindowProc(int lpPrevWndFunc, int hWnd, int Msg, int wParam, int lParam);
- [DllImport("user32.dll")]
- protected static extern int SetWindowLong(int hwindow, int unindex, CallWindowProcDelegate lnewvalue);//这个是关键
- [DllImport("hhctrl.ocx", CharSet = CharSet.Unicode, EntryPoint = "HtmlHelpW")]
- protected static extern int HtmlHelp(int caller,String file,uint command,String str);
在Main方法中:
- int handle = HtmlHelp(0, "e://CDMHELP.chm", HH_DISPLAY_INDEX, "");
- oldWindow = GetWindowLong(handle, GWL_WNDPROC);
- MyCallWindowProc = new CallWindowProcDelegate(WndProc);
- SetWindowLong(handle, GWL_WNDPROC, MyCallWindowProc);
- Application.Run();
WndProc方法
- private static int WndProc(int Wnd, int Msg, int WParam, int LParam)
- {
- //在这里可以对你需要的消息进行监控,最后别忘了调用下面这句话
- return CallWindowProc(oldWindow, Wnd, Msg, WParam, LParam);
- }
完整代码如下:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Windows.Forms;
- using System.Threading;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
- namespace testApplication1
- {
- public class test
- {
- public delegate int CallWindowProcDelegate(int Wnd, int Msg, int WParam, int LParam);
- public static CallWindowProcDelegate MyCallWindowProc;
- public const int HH_DISPLAY_INDEX = 0x0002;
- public const int GWL_WNDPROC = -4;
- public static int oldWindow = 0;
- [STAThread]
- static void Main(string[] args)
- {
- int handle = HtmlHelp(0, "e://CDMHELP.chm", HH_DISPLAY_INDEX, "");
- oldWindow = GetWindowLong(handle, GWL_WNDPROC);
- MyCallWindowProc = new CallWindowProcDelegate(WndProc);
- SetWindowLong(handle, GWL_WNDPROC, MyCallWindowProc);
- Application.Run();
- }
- private static int WndProc(int Wnd, int Msg, int WParam, int LParam)
- {
- //在这里监控消息
- return CallWindowProc(oldWindow, Wnd, Msg, WParam, LParam);
- }
- [DllImport("user32.dll")]
- public static extern int GetWindowLong(int hwindow, int nindex);
- [DllImport("user32.dll")]
- static extern int CallWindowProc(int lpPrevWndFunc, int hWnd, int Msg, int wParam, int lParam);
- [DllImport("user32.dll")]
- public static extern int SetWindowLong(int hwindow, int nindex, CallWindowProcDelegate lnewvalue);
- [DllImport("hhctrl.ocx", CharSet = CharSet.Unicode, EntryPoint = "HtmlHelpW")]
- protected static extern int HtmlHelp(int caller,String file,uint command,String str);
- }
- }
当然你也可以把SetWindowLong声明如下:
[DllImport("user32.dll")]
public static extern int SetWindowLong(int hwindow, int unindex, int lnewvalue);
然后调用的时候使用
Marshal.GetFunctionPointerForDelegate(new CallWindowProcDelegate(WndProc).ToInt32());
欢迎转载,请注明出处~~