首页 新闻 会员 周边

Qt5QWindowIcon类窗体,就是QT写的程序如何用C#获取到句柄

0
悬赏园豆:200 [已解决问题] 解决于 2019-11-21 13:21

IntPtr handle = FindWindowEx((IntPtr)0, (IntPtr)0, "Qt5QWindowIcon", "IPC加密工具 V2.0.1 build 2019-11-06 13:59:05");这样获取不到。
IntPtr handle = FindWindowEx((IntPtr)0, (IntPtr)0, null, "IPC加密工具 V2.0.1 build 2019-11-06 13:59:05");这样也获取不到。
用spy++可以查看到目标窗体的类名是:Qt5QWindowIcon

问题补充:

数据酷软件的主页 数据酷软件 | 初学一级 | 园豆:130
提问于:2019-11-20 12:18
< >
分享
最佳答案
0

可以吧 exe文件发出来吗?

收获园豆:200
小小高 | 小虾三级 |园豆:1095 | 2019-11-20 13:51
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace windowsApiAcitonSimulation.Win32Action
{
    public class WindowsApiHelp
    {
        #region windows api 方法


        /// <summary>
        /// 根据类名和窗口名获取句柄
        /// </summary>
        /// <param name="lpClassName"></param>
        /// <param name="lpWindowName"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        /// <summary>
        /// 查找子窗口句柄
        /// </summary>
        /// <param name="hwndParent"></param>
        /// <param name="hwndChildAfter"></param>
        /// <param name="lpszClass"></param>
        /// <param name="lpszWindow"></param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        /// <summary>
        /// 给窗口发送windows消息,主要是赋值
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="Msg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
        /// <summary>
        /// 给窗口发送windows消息,主要单击双击按钮
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="wMsg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("USER32.DLL", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        /// <summary>
        /// 给窗体发送消息不用等待窗体响应
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="Msg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool PostMessage(HandleRef hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        /// <summary>
        /// 窗体前置
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        // Activate an application window.
        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
        /// <summary>
        /// 得到句柄的ClassName
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="lpClassName"></param>
        /// <param name="nMaxCount"></param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
        #endregion





        #region 通过当前句柄得到所有子句柄
        /// <summary>
        /// Returns a list of child windows
        /// </summary>
        /// <param name="parent">Parent of the windows to return</param>
        /// <returns>List of child windows</returns>
        public static List<IntPtr> GetChildWindows(IntPtr parent)
        {
            List<IntPtr> result = new List<IntPtr>();
            GCHandle listHandle = GCHandle.Alloc(result);
            try
            {
                EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
                EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
            }
            finally
            {
                if (listHandle.IsAllocated)
                    listHandle.Free();
            }
            return result;
        }
        public delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
        /// <summary>
        /// Delegate for the EnumChildWindows method
        /// </summary>
        /// <param name="hWnd">Window handle</param>
        /// <param name="parameter">Caller-defined variable; we use it for a pointer to our list</param>
        /// <returns>True to continue enumerating, false to bail.</returns>
        public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
        /// <summary>
        /// Callback method to be used when enumerating windows.
        /// </summary>
        /// <param name="handle">Handle of the next window</param>
        /// <param name="pointer">Pointer to a GCHandle that holds a reference to the list to fill</param>
        /// <returns>True to continue the enumeration, false to bail</returns>
        private static bool EnumWindow(IntPtr handle, IntPtr pointer)
        {
            GCHandle gch = GCHandle.FromIntPtr(pointer);
            List<IntPtr> list = gch.Target as List<IntPtr>;
            if (list == null)
            {
                throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
            }
            list.Add(handle);
            //  You can modify this to check to see if you want to cancel the operation, then return a null here
            return true;
        }
        #endregion



        /// <summary>
        /// 得到子句柄通过parent句柄和ClassName
        /// </summary>
        /// <param name="ptr"></param>
        /// <returns></returns>
        public static IntPtr getIntPtrByClassName(IntPtr parentPtr, string className)
        {
            IntPtr flag = IntPtr.Zero;
            foreach (var item in GetChildWindows(parentPtr))
            {
                int nRet;
                // Pre-allocate 256 characters, since this is the maximum class name length.
                StringBuilder sb = new StringBuilder(256);
                //Get the window class name
                nRet = GetClassName(item, sb, sb.Capacity);
                if (nRet != 0)
                {
                    if (sb.ToString() == className)
                    {
                        flag = item;
                        break;
                    }
                }
            }
            return flag;
        }

        /// <summary>
        /// 句柄鼠标左键单击
        /// </summary>
        /// <param name="ptr"></param>
        public static void LeftClickButtonByHandle(IntPtr ptr)
        {
            var handle = new HandleRef(null, ptr);
            PostMessage(handle, WindowsMessages.WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
            PostMessage(handle, WindowsMessages.WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
        }
        /// <summary>
        /// 句柄鼠标左键双击
        /// </summary>
        /// <param name="ptr"></param>
        public static void LeftDBClickButtonByHandle(IntPtr ptr)
        {
            var handle = new HandleRef(null, ptr);
            PostMessage(handle, WindowsMessages.WM_LBUTTONDBLCLK, IntPtr.Zero, IntPtr.Zero);
        }
        /// <summary>
        /// 句柄鼠标右键单击
        /// </summary>
        /// <param name="ptr"></param>
        public static void RightClickButtonByHandle(IntPtr ptr)
        {
            var handle = new HandleRef(null, ptr);
            PostMessage(handle, WindowsMessages.WM_RBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
            PostMessage(handle, WindowsMessages.WM_RBUTTONUP, IntPtr.Zero, IntPtr.Zero);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace windowsApiAcitonSimulation.Win32Action
{
    public class WindowsMessages
    {
        //双击鼠标左键 
        public static int WM_LBUTTONDBLCLK = 0x203;
        //按下鼠标左键   
        public static int WM_LBUTTONDOWN = 0x201;
        //按下鼠标右键
        public static int WM_RBUTTONDOWN = 0x0204;
        //释放鼠标右键
        public static int WM_RBUTTONUP = 0x0205;
        //释放鼠标左键   
        public static int WM_LBUTTONUP = 0x202;
        //设置文本   
        public static int WM_SETTEXT = 0x0C;
        //得到文本   
        public static int WM_GETTEXT = 0x0D;
        //单击按钮
        public static int BM_CLICK = 0xF5;
        //关闭窗口
        public static int WM_CLOSE = 0x10;
    }
}
小小高 | 园豆:1095 (小虾三级) | 2019-11-20 13:55

FindWindowEx是查找子窗口句柄的。

要用 FindWindow

小小高 | 园豆:1095 (小虾三级) | 2019-11-20 13:56

@小小高: 谢谢指点,用SPY++也只能获取到QT5程序的窗口句柄,然后使用FindWindow是获取不到的。最后用EnumDesktopWindows能获取到了。但是,QT窗口里的控件是没有句柄的,所以也获取不到了。

数据酷软件 | 园豆:130 (初学一级) | 2019-11-21 12:57

@数据酷软件: 是要得到控件的内容吗?

小小高 | 园豆:1095 (小虾三级) | 2019-11-21 13:00

@小小高: SendMessage(txt, WM_SETTEXT, (IntPtr)0, textBox1.Text.Trim() + Environment.NewLine);不是,是要发送文本给它。现在确定就是QT的程序控件是没有句柄的

数据酷软件 | 园豆:130 (初学一级) | 2019-11-21 13:03

@数据酷软件: 好吧

小小高 | 园豆:1095 (小虾三级) | 2019-11-21 13:04

@小小高: 现在是用剪贴板+模拟鼠标点击,模拟键盘按下CTRL C,CTRL+V实现的。

数据酷软件 | 园豆:130 (初学一级) | 2019-11-21 13:08

@数据酷软件: 这个办法也是没得办法的办法了

小小高 | 园豆:1095 (小虾三级) | 2019-11-21 13:11
其他回答(2)
0

QT的程序控件是没有句柄的,用剪贴板+模拟鼠标点击,模拟键盘按下CTRL C,CTRL+V实现需求。

数据酷软件 | 园豆:130 (初学一级) | 2019-11-21 13:14
0

好难/ 这样要是QT句柄改变. 整个代码都变了.

zfz12345 | 园豆:202 (菜鸟二级) | 2020-03-27 15:45
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册