• 获得其他程序弹出菜单的内容(一个困扰许久的问题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还真是没用过。。。

  • 相关阅读:
    产生财务计帐周期
    判断指定年份是否为闰年
    判断是否是闰年
    Regex quick reference
    组合外键(FOREIGN KEY)
    多列组合为主键(PRIMARY KEY)
    获取字符串开始的地址(案例)
    获取字符串结尾的电话号码(案例)
    ms sql server line feed
    如何产生连续时间?(案例)
  • 原文地址:https://www.cnblogs.com/HelliX/p/5898857.html
Copyright © 2020-2023  润新知