我想附加到一个单独的应用程序(例如Microsoft Excel),并检测某个菜单项何时被点击(或新版本中的function区命令,无论)。
我以为我可以使用user32.dll的RegisterWindowMessage来做到这一点,但我不知道要拦截哪些消息。 理想情况下,我想概括一下,并检测如下内容:
"menu item XXX was clicked in the app YYY"
我发现这个CodeProject文章显示如何注册事件的钩子,如控件的创build,应用程序的启动/停止等,但我找不到如何获得button点击或菜单点击的例子。
这甚至有可能吗? 我在正确的轨道上,还是我需要采取不同的方法?
Windowshibernate如何工作
移动位置并更改外部程序的大小
将批处理shell脚本输出读入C#.Net程序
在C#中,什么是HttpClient.getStringAsync()方法的同步替代?
CLR在哪里安装?
如何引用外部类中的string(C#)
C#中的本地窗口层次结构和类名
Linux和Windows数据系统可以共存吗?
如何在Windows Server 2003上从IIS 6提供文件?
好吧,所以我无法抗拒这里的挑战:)写了一个小程序,做你想做的。
它是如何工作的 : SetwindowsHookEx让你放置一个全局的鼠标钩子。 现在 ,你得到X , Y ,然后使用WindowFromPoint来获取目标窗口的hWnd 。 从这里你可以做任何你喜欢的事情,就我而言,我发了一个WM_GETTEXT来获得它的头衔。
这是程序看起来像实现的东西。 一旦您单击Begin ,它将全局查找右键单击事件,并将它们添加到列表框。 注意 :它需要是一个窗口窗体应用程序,挂钩将无法与控制台应用程序。
用法(只需创建一个默认的WinForms项目并将其更改为此):
public partial class MainForm : Form { public MainForm() { InitializeComponent(); } RMouselistner _native; private void button1_Click(object sender,EventArgs e) {//start _native = new RMouselistner(); _native.RButtonClicked += new EventHandler<SysMouseEventInfo>(_native_RButtonClicked); } private void button2_Click(object sender,EventArgs e) {//stop _native.Close(); } void _native_RButtonClicked(object sender,SysMouseEventInfo e) { listBox1.Items.Add(e.WindowTitle); } }
public class SysMouseEventInfo : EventArgs { public string WindowTitle { get; set; } } public class RMouselistner { public RMouselistner() { this.CallBack += new HookProc(MouseEvents); //modulee mod = Assembly.GetExecutingAssembly().Getmodulees()[0]; //IntPtr hMod = Marshal.GetHINSTANCE(mod); using (Process process = Process.GetCurrentProcess()) using (Processmodulee module = process.Mainmodulee) { IntPtr hmodulee = GetmoduleeHandle(module.moduleeName); _hook = SetwindowsHookEx(WH_MOUSE_LL,this.CallBack,hmodulee,0); //if (_hook != IntPtr.Zero) //{ // Console.WriteLine("Started"); //} } } int WH_MOUSE_LL = 14; int HC_ACTION = 0; HookProc CallBack = null; IntPtr _hook = IntPtr.Zero; public event EventHandler<SysMouseEventInfo> RButtonClicked; int MouseEvents(int code,IntPtr wParam,IntPtr lParam) { //Console.WriteLine("Called"); if (code < 0) return CallNextHookEx(_hook,code,wParam,lParam); if (code == this.HC_ACTION) { // Left button pressed somewhere if (wParam.ToInt32() == (uint)WM.WM_RBUTTONDOWN) { MsllHOOKSTRUCT ms = new MsllHOOKSTRUCT(); ms = (MsllHOOKSTRUCT)Marshal.PtrToStructure(lParam,typeof(MsllHOOKSTRUCT)); IntPtr win = WindowFromPoint(ms.pt); string title = GetwindowTextRaw(win); if (RButtonClicked != null) { RButtonClicked(this,new SysMouseEventInfo { WindowTitle = title }); } } } return CallNextHookEx(_hook,lParam); } public void Close() { if (_hook != IntPtr.Zero) { UnhookWindowsHookEx(_hook); } } public delegate int HookProc(int code,IntPtr lParam); [System.Runtime.InteropServices.DllImport("user32.dll",EntryPoint = "SetwindowsHookEx",SetLastError = true)] public static extern IntPtr SetwindowsHookEx(int idHook,HookProc lpfn,IntPtr hMod,uint dwThreadId); [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern int CallNextHookEx(IntPtr hhk,int nCode,IntPtr lParam); [System.Runtime.InteropServices.DllImport("kernel32.dll",CharSet = System.Runtime.InteropServices.CharSet.Auto)] public static extern IntPtr GetmoduleeHandle(string lpmoduleeName); [DllImport("user32.dll")] static extern IntPtr WindowFromPoint(int xPoint,int yPoint); [DllImport("user32.dll")] static extern IntPtr WindowFromPoint(POINT Point); [DllImport("user32.dll",SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll",CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd,UInt32 Msg,[Out] StringBuilder lParam); public static string GetwindowTextRaw(IntPtr hwnd) { // Allocate correct string length first //int length = (int)SendMessage(hwnd,(int)WM.WM_GETTEXTLENGTH,IntPtr.Zero,IntPtr.Zero); StringBuilder sb = new StringBuilder(65535);//THIS Could BE BAD. Maybe you shoudl get the length SendMessage(hwnd,(int)WM.WM_GETTEXT,(IntPtr)sb.Capacity,sb); return sb.ToString(); } } [StructLayout(LayoutKind.Sequential)] public struct MsllHOOKSTRUCT { public POINT pt; public int mouseData; public int flags; public int time; public UIntPtr dwExtraInfo; } enum WM : uint {//all windows messages here WM_RBUTTONDOWN = 0x0204,WM_GETTEXT = 0x000D,WM_GETTEXTLENGTH = 0x000E } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; public POINT(int x,int y) { this.X = x; this.Y = y; } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。