获得其他程序弹出菜单的内容(一个困扰许久的问题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();
WindowsAPI.PostMessage(cwnd, (int)WindowsAPI.WndMsg.WM_RBUTTONDOWN, (int)WindowsAPI.WndMsg.MK_RBUTTON, WindowsAPI.MAKELONG(, ));
WindowsAPI.PostMessage(cwnd, (int)WindowsAPI.WndMsg.WM_RBUTTONUP, (int)WindowsAPI.WndMsg.MK_RBUTTON, WindowsAPI.MAKELONG(, ));
}
System.Threading.Thread.Sleep();
hand = WindowsAPI.FindWindow("#32768", null);
IntPtr hMenu = WindowsAPI.SendMessage(hand, 0x01E1, , );
int n = WindowsAPI.GetMenuItemCount(hMenu);
var meg = new StringBuilder();
n = WindowsAPI.GetMenuString(hMenu, (uint)WindowsAPI.GetMenuItemID(hMenu, ), meg, , (uint));
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();
//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;
}, );
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();
//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;
}, ); return wndList;
}
源码就懒得发了,就这么几句,但是为了这几句代码,折腾的够呛,虽然以前用过VC++但是这么底层的API还真是没用过。。。
获得其他程序弹出菜单的内容(一个困扰许久的问题o(╯□╰)o)的更多相关文章
- Mui --- 弹出菜单
mui框架内置了弹出菜单插件,弹出菜单显示内容不限,但必须包裹在一个含.mui-popover类的div中,如下即为一个弹出菜单内容: <div id="popover" c ...
- iOS开发——动画篇Swift篇&炫酷弹出菜单
炫酷弹出菜单 这个是一个第三方按钮菜单组件,原版是使用Objective-C编写的名为AwesomeMenu的组件,地址是:https://github.com/levey/AwesomeMenu ...
- win32进阶之路:程序托盘图标+右键弹出菜单
开场白 本次介绍两个非常棒且实用的技巧:程序托盘图标和右键弹出菜单,效果如下图. 程序托盘图标用了迅雷的图标,右键点击时候会弹出三个选项的菜单. 程序托盘图标设置 我会用尽可能清晰明了的步骤介绍方式 ...
- MFC为应用程序添加托盘(右键托盘,弹出菜单)
源代码:http://download.csdn.net/detail/nuptboyzhb/4137784 1. 导入一个托盘图标的资源(.ico)格式:资源ID为IDI_ICON1 2 ...
- 微信小程序弹出操作菜单
微信小程序弹出操作菜单 比如在页面上放一个按钮,点击按钮弹出操作菜单,那么在按钮的 bindtap 事件里,执行下面的代码即可: wx.showActionSheet({ itemList: ['A' ...
- 【Android UI设计与开发】7.底部菜单栏(四)PopupWindow 实现显示仿腾讯新闻底部弹出菜单
前一篇文章中有用到 PopupWindow 来实现弹窗的功能.简单介绍以下吧. 官方文档是这样解释的:这就是一个弹出窗口,可以用来显示一个任意视图.出现的弹出窗口是一个浮动容器的当前活动. 1.首先来 ...
- 仿酷狗音乐播放器开发日志二十六 duilib在标题栏弹出菜单的方法
转载请说明原出处,谢谢~~ 上篇日志说明了怎么让自定义控件响应右键消息.之后我给主窗体的标题栏增加右键响应,观察原酷狗后可以发现,在整个标题栏都是可以响应右键并弹出菜单的.应该的效果如下: 本以为像上 ...
- JavaScript 实现触点式弹出菜单插件
之前做项目时经常用到一种触点式弹出菜单或者导航的功能,这个功能的主要应用场景是:web页面中多层分级导航或者子功能目录,但又考虑到页面区域有限,于是就考虑到在鼠标移动到某导航按钮上或者点击时,系统将在 ...
- web标准(复习)--4 纵向导航菜单及二级弹出菜单
今天我们开始学习纵向导航菜单及二级弹出菜单,包含以下内容和知识点: 纵向列表 标签的默认样式 css派生选择器 css选择器的分组 纵向二级列表 相对定位和绝对定位 一.纵向列表纵向列表或称为纵向导航 ...
随机推荐
- C#-命名空间(十五)
概念 命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式 在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突 命名空间的定义是有一定的规范,避免引起不必要的麻烦 命名 ...
- Oracle EBS R12 GL_IMPORT_REFERENCES 映射
非原创. 转自出处: http://alloracleapps.com/oracle_apps/gl_import_references-columns-mapping-11i-vs-r12/
- [Hive_add_4] Hive 命令行客户端 Beeline 的使用
0. 说明 Hive 命令行客户端 beeline 的使用,建立在启动 Hadoop 集群和启动 hiveserver2 的基础之上 1. 使用指南 在确保集群启动和 hiveserver2 启动的 ...
- LeetCode算法题-Guess Number Higher or Lower(Java实现)
这是悦乐书的第211次更新,第224篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第79题(顺位题号是374).我们正在玩数字游戏. 游戏如下:我从1到n中选择一个数字. ...
- LeetCode算法题-Add Digits(Java实现-3种解法)
这是悦乐书的第199次更新,第207篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第63题(顺位题号是258).给定非负整数num,重复添加其所有数字,直到结果只有一位数 ...
- March 08th, 2018 Week 10th Thursday
Easy come, easy go. 易得则易失. Easy come, easy go, I finally undestand the phrase through somewhat hard ...
- 删除window10没用的服务
最近学习了下resin,出了个问题,它默认端口是8080,跟Tomcat冲突了,我在使用的时候遇到了个奇怪的事情,resin4.0一直占用着我的8080端口,哪怕我用dos命令把它强制停止,不出五秒钟 ...
- 为JQuery EasyUI 表单组件加上“清除”功能
1.背景 在使用 EasyUI 各表单组件时,尤其是使用 ComboBox(下拉列表框).DateBox(日期输入框).DateTimeBox(日期时间输入框)这三个组件时,经常有这样的需求,下拉框或 ...
- 14.msql_python
# 1.安装 pip install pymysql import pymysql try: # 1.链接 数据库 链接对象 connection() conn = pymysql.Connect( ...
- P1316 丢瓶盖(二分+贪心)
思路:都在注解里 #include<iostream> #include<algorithm> using namespace std; ; int a[maxn], n, m ...