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
可以吧 exe文件发出来吗?
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; } }
FindWindowEx是查找子窗口句柄的。
要用 FindWindow
@小小高: 谢谢指点,用SPY++也只能获取到QT5程序的窗口句柄,然后使用FindWindow是获取不到的。最后用EnumDesktopWindows能获取到了。但是,QT窗口里的控件是没有句柄的,所以也获取不到了。
@数据酷软件: 是要得到控件的内容吗?
@小小高: SendMessage(txt, WM_SETTEXT, (IntPtr)0, textBox1.Text.Trim() + Environment.NewLine);不是,是要发送文本给它。现在确定就是QT的程序控件是没有句柄的
@数据酷软件: 好吧
@小小高: 现在是用剪贴板+模拟鼠标点击,模拟键盘按下CTRL C,CTRL+V实现的。
@数据酷软件: 这个办法也是没得办法的办法了
QT的程序控件是没有句柄的,用剪贴板+模拟鼠标点击,模拟键盘按下CTRL C,CTRL+V实现需求。
好难/ 这样要是QT句柄改变. 整个代码都变了.