获得其他程序弹出菜单的内容(一个困扰许久的问题o(╯□╰)o)

刚开始到现在公司的时候接到一个任务:开发一个activex控件,自动操作本地exe程序,当时遇到弹出菜单无法获取的问题,还好不影响,最近又遇到这个问题,绕不过去了,于是昨天花了一个上午百度了个遍,总算解决了。。。网上也有人遇到类似的问题,但是都没人给出一个完整解决方案来,所以记录下来,以备后用。

核心代码:windows系统其实只有一个弹出菜单,类型为#32768,但是FindWindow获取的是窗口句柄,需要发送MN_GETHMENU 0x01E1消息转换成菜单句柄,然后通过菜单的API进行其他操作,这里是获取的菜单的文字内容

            var hand = WindowsAPI.FindWindow("Notepad", "无标题 - 记事本");
            WindowsAPI.SetForegroundWindow(hand);
            var cwnd = WindowsAPI.FindWindowEx(hand, IntPtr.Zero, "Edit", null);

            {
                System.Threading.Thread.Sleep(100);
                WindowsAPI.PostMessage(cwnd, (int)WindowsAPI.WndMsg.WM_RBUTTONDOWN, (int)WindowsAPI.WndMsg.MK_RBUTTON, WindowsAPI.MAKELONG(100, 100));
                WindowsAPI.PostMessage(cwnd, (int)WindowsAPI.WndMsg.WM_RBUTTONUP, (int)WindowsAPI.WndMsg.MK_RBUTTON, WindowsAPI.MAKELONG(100, 100));
            }
            System.Threading.Thread.Sleep(100);
            hand = WindowsAPI.FindWindow("#32768", null);
            IntPtr hMenu = WindowsAPI.SendMessage(hand, 0x01E1, 0, 0);

            int n = WindowsAPI.GetMenuItemCount(hMenu);
            var meg = new StringBuilder(100);
            n = WindowsAPI.GetMenuString(hMenu, (uint)WindowsAPI.GetMenuItemID(hMenu, 0), meg, 100, (uint)0);
            MessageBox.Show(meg.ToString());

API封装

        //查找指定窗体
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        //发送窗口消息
        [DllImport("user32.dll", EntryPoint = "SendMessage")]
        public static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, int wParam, uint lParam);

        public enum WndMsg
        {
            WM_CLICK = 0x00F5,
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x202,
            WM_RBUTTONDOWN = 0x0204,
            WM_RBUTTONUP = 0x205,
            MK_LBUTTON = 0x0001,
            MK_RBUTTON = 0x0002,
            WM_SETTEXT = 0x000C,
            BM_CLICK = 0xF5
        }

        [DllImport("USER32.dll", EntryPoint = "GetMenuItemCount", CharSet = CharSet.Unicode)]
        public static extern int GetMenuItemCount(IntPtr hMenu);
        [DllImport("User32.dll")]
        public static extern IntPtr GetSystemMenu(IntPtr hWnd, Int32 bRevert);

        [DllImport("User32.dll")]
        public static extern int GetMenuString(IntPtr hMenu, uint uIDItem, StringBuilder lpString, int nMaxCount, uint uFlag);

        [DllImport("User32.dll")]
        public static extern int GetMenuItemID(IntPtr hMenu, int nPos);

其他一些常用API封装

        //读写ini文件
        [DllImport("kernel32")]
        public static extern bool WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        public static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retStr, int size, string filePath);

        private delegate bool WNDENUMPROC(IntPtr hWnd, int lParam);

        [DllImport("user32.dll", ExactSpelling = true)]
        private static extern bool EnumChildWindows(IntPtr hwndParent, WNDENUMPROC lpEnumFunc, int lParam);

        [DllImport("user32.dll")]
        private static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);
        //[DllImport("user32.dll")]
        //private static extern IntPtr FindWindowW(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll")]
        private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
        public struct WindowInfo
        {
            public IntPtr hWnd;
            public string szWindowName;
            public string szClassName;
        }
        //遍历窗口子窗口控件
        public static List<WindowInfo> GetAllChildWindows(IntPtr handle)
        {
            List<WindowInfo> wndList = new List<WindowInfo>();
            EnumChildWindows(handle, delegate(IntPtr hWnd, int lParam)
            {
                WindowInfo wnd = new WindowInfo();
                StringBuilder sb = new StringBuilder(256);
                //get hwnd
                wnd.hWnd = hWnd;
                //get window name
                GetWindowTextW(hWnd, sb, sb.Capacity);
                wnd.szWindowName = sb.ToString();
                //get window class
                GetClassNameW(hWnd, sb, sb.Capacity);
                wnd.szClassName = sb.ToString();
                //add it into list
                wndList.Add(wnd);
                return true;
            }, 0);
            return wndList;
        }
        public static List<WindowInfo> GetAllDesktopWindows()
        {
            List<WindowInfo> wndList = new List<WindowInfo>();

            //enum all desktop windows
            EnumWindows(delegate(IntPtr hWnd, int lParam)
            {
                WindowInfo wnd = new WindowInfo();
                StringBuilder sb = new StringBuilder(256);
                //get hwnd
                wnd.hWnd = hWnd;
                //get window name
                GetWindowTextW(hWnd, sb, sb.Capacity);
                wnd.szWindowName = sb.ToString();
                //get window class
                GetClassNameW(hWnd, sb, sb.Capacity);
                wnd.szClassName = sb.ToString();
                //add it into list
                wndList.Add(wnd);
                return true;
            }, 0);

            return wndList;
        }

源码就懒得发了,就这么几句,但是为了这几句代码,折腾的够呛,虽然以前用过VC++但是这么底层的API还真是没用过。。。

时间: 2024-10-10 00:48:16

获得其他程序弹出菜单的内容(一个困扰许久的问题o(╯□╰)o)的相关文章

MUI组件三:列表、遮罩蒙版、数字输入框、侧滑导航和弹出菜单

1.list(列表) 列表是常用的UI控件,mui封装的列表组件比较简单,只需要在ul节点上添加.mui-table-view类.在li节点上添加.mui-table-view-cell类即可,如下为示例代码 <ul class="mui-table-view"> <li class="mui-table-view-cell">Item 1</li> <li class="mui-table-view-cell&q

iOS开发——动画篇Swift篇&amp;炫酷弹出菜单

炫酷弹出菜单 这个是一个第三方按钮菜单组件,原版是使用Objective-C编写的名为AwesomeMenu的组件,地址是:https://github.com/levey/AwesomeMenu 这里改造成了Swift版,效果图如下: 使用代码: 1 import UIKit 2 3 class ViewController: UIViewController,HanggeSwiftMenuDelegate { 4 5 override func viewDidLoad() { 6 super

MFC右键弹出菜单

右键弹出菜单是指右键抬起的时候弹出的菜单.通常放置在Dialog的OnRButtonUp响应函数里. 下面就给出右键弹出菜单的实例: 1 添加右键事件及响应函数 可以用Class Wizard...来添加一个右键消息WM_RBUTTONUP,为其添加Handler,会自动生成OnRButtonUp响应函数 2 为弹出菜单添加资源 可以用"Resource View"中的"String Table"添加一个新的弹出菜单资源,这里假设资源ID : IDC_MENU_UP

弹出菜单的创建与使用

-------------siwuxie095 工程名:TestSwingPopupMenu 包名:com.siwuxie095.popupmenu 类名:MyFrame.java 工程结构目录如下: MyFrame.java: package com.siwuxie095.popupmenu; import java.awt.BorderLayout; import java.awt.Component; import java.awt.EventQueue; import java.awt.

自己写了一个弹出菜单,有间隙也可以

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

css+html+js实现多级下拉和弹出菜单

本文将使用css+html+js实现横向菜单.具有多级弹出菜单下拉. 首先我们来看看效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > 首先应该写html部分的代码,代码比較简单,代码例如以下: <body> <div id="men

iOS_21团购_顶部菜单和弹出菜单联动

最后效果图: 各控件关系图1: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >\ 各控件关系图2: 点击Dock上面的buttonDockItem, 创建经导航控制器包装的DealListController, 而且加入到主控制器的右側空间 // // Deal

web标准(复习)--4 纵向导航菜单及二级弹出菜单

今天我们开始学习纵向导航菜单及二级弹出菜单,包含以下内容和知识点: 纵向列表 标签的默认样式 css派生选择器 css选择器的分组 纵向二级列表 相对定位和绝对定位 一.纵向列表纵向列表或称为纵向导航,在网站的产品列表中应用比较广泛,如淘宝网左侧的淘宝服务,今天我们就学习一下纵向导航的制作 先新建一个页面,然后插入一个ID为menu的div,然后在设计视图中选中文字,点击工具栏的ul图标,即会自动插入ul和li,然后修改文字内容为你需要的内容. <style type="text/css&

Swing-JPopupMenu弹出菜单用法-入门

弹出菜单是GUI程序中非常常见的一种控件.它通常由鼠标右击事件触发,比如在windows系统桌面上右击时,会弹出一个包含“刷新”.“属性”等菜单的弹出菜单.Swing中的弹出菜单是JPopupMenu,它的基本性质与JMenu类似,可以使用add方法给它内部添加JMenu或者JMenuItem.手动显示JPopupMenu时,需使用show(parentComponent, x, y)方法,指定父控件和显示坐标.用户的操作习惯是在右击某个 控件时显示弹出菜单,那么需要使用component.se