|
写了个函数调试的中鼠标选取替代F9功能键的小插件,地址:https://club.excelhome.net/thread-1604722-1-1.html
要截取一些EXCEL子窗体的系统消息,发现NativeWindow在处理这些问题时挺方便,分享一下:
第一步,确定要截取消息的子窗口,获取其句柄,用原始的winapi函数FindWindowEx就行,这个编辑栏的类名是“EXCEL>”,可以通过spy++获取
第二步,句柄有了,但怎么截取这个窗口的鼠标和键盘消息呢?Winform下有个NativeWindow类:提供了窗口句柄和窗口过程的低级封装。利用NativeWindow不仅可以很方便的实现子窗体,同时可以捕获消息,重写窗口过程(默认处理函数WndProc),在捕获到消息后添加自己的代码就可以了。步骤大致如下:
1. 定义一个类Mywin继承NativeWindow,并在构造函数中使用AssignHandle方法将获取的句柄分配给此窗口。
2. 重载Wndproc方法,Wndproc有个引用类型的参数:ref Message m,通过m.Msg就可以得到所有刚刚指定的EditWinHwnd的窗体消息,截取对应的消息,加入自己的代码,在断点调试时可查看对应截取消息,如下图:
代码很少,如下(可忽略EXCELDNA部分,关键是下面红色字体的那个Mywin类):
using ExcelDna.Integration;
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelFuncTool
{
public class RF9
{
public static MyWin myWin;
public static IntPtr ExcelAppHwnd = new IntPtr(((Excel.Application)ExcelDnaUtil.Application).Hwnd);
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[ExcelCommand(MenuName = "FuncTool", MenuText = "开启")]
public static void StartHook()
{
myWin = new MyWin(FindWindowEx(ExcelAppHwnd, IntPtr.Zero, "EXCEL<", null));
}
[ExcelCommand(MenuName = "FuncTool", MenuText = "关闭")]
public static void EndtHook()
{
myWin.ReleaseHandle();
}
}
public class MyWin : NativeWindow
{
private IntPtr EditWinHwnd;
private const int WM_LBUTTONUP = 0X202;
private const int WM_LBUTTONDOWN = 513;
public struct Point{public int x;public int y;}
private Point mousePoint;
public MyWin(IntPtr hwnd)
{
EditWinHwnd = hwnd;
AssignHandle(EditWinHwnd);
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_LBUTTONDOWN:
mousePoint.x = (int)m.LParam & 0xffff;
mousePoint.y = (int)m.LParam >> 16;
break;
case WM_LBUTTONUP:
mousePoint.x -= (int)m.LParam & 0xffff;
mousePoint.y -= (int)m.LParam >> 16;
if (Math.Abs(mousePoint.x) >= 10){SendKeys.Send("{F9}");}
break;
}
base.WndProc(ref m);
}
}
}
|
评分
-
2
查看全部评分
-
|