c# 通过win32控制窗口

  1. 引入需要的接口

        /// <summary>
        /// 查找窗口
        /// </summary>
        /// <param name="hwnd">窗口句柄</param>
        /// <param name="title">窗口标题</param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(IntPtr hwnd, string title);

        /// <summary>
        /// 移动窗口
        /// </summary>
        /// <param name="hwnd">窗口句柄</param>
        /// <param name="x">起始位置X</param>
        /// <param name="y">起始位置Y</param>
        /// <param name="nWidth">窗口宽度</param>
        /// <param name="nHeight">窗口高度</param>
        /// <param name="rePaint">是否重绘</param>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern void MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool rePaint);

        /// <summary>
        /// 获取窗口矩形
        /// </summary>
        /// <param name="hwnd">窗口句柄</param>
        /// <param name="rect"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetWindowRect(IntPtr hwnd, out Rectangle rect);

        /// <summary>
        /// 向窗口发送信息
        /// </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 int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam);

        public const int WM_CLOSE = 0x10; //关闭命令
        public const int WM_KEYDOWN = 0x0100;//按下键
        public const int WM_KEYUP = 0x0101;//按键起来
        public const int VK_RETURN = 0x0D;//回车键
        public const int WM_SETTEXT = 0x000C;//发送消息
        public const int WM_INITDIALOG = 0x0110;//初始化
        public const int WM_LBUTTONDOWN = 0x0201;//按下鼠标左键 
        public const int WM_LBUTTONUP = 0x0202;//释放鼠标左键
        public const int WM_LBUTTONDBLCLK = 0x203; //双击鼠标左键
        public const int WM_RBUTTONDOWN = 0x204;//按下鼠标右键
        public const int WM_RBUTTONUP = 0x205;//释放鼠标右键
        public const int WM_RBUTTONDBLCLK = 0x206;//双击鼠标右键
        public static bool IsWorking = false;
        /// <summary>
        /// 对话框标题
        /// </summary>
        public static string[] titles = new string[4] { "Error", "提示", "错误", "警告" };



        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("User32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
      
  1. 封装的常用方法
 /// <summary>
 /// 查找和移动窗口
 /// </summary>
 /// <param name="title">窗口标题</param>
 /// <param name="x">起始位置X</param>
 /// <param name="y">起始位置Y</param>
 public static void FindAndMoveWindow(string title, int x, int y)
 {
     Thread t = new Thread(() =>
     {
         IntPtr msgBox = IntPtr.Zero;
         while ((msgBox = FindWindow(IntPtr.Zero, title)) == IntPtr.Zero) ;
         Rectangle r = new Rectangle();
         GetWindowRect(msgBox, out r);
         MoveWindow(msgBox, x, y, r.Width - r.X, r.Height - r.Y, true);
     });
     t.Start();
 }
 /// <summary>
 /// 查找和关闭窗口
 /// </summary>
 /// <param name="title">标题</param>
 public static void FindAndKillWindow(string title)
 {
     IntPtr ptr = FindWindow(IntPtr.Zero, title);
     if (ptr != IntPtr.Zero)
     {
         int ret = PostMessage(ptr, WM_CLOSE, 0, 0);
         Thread.Sleep(1000);
         ptr = FindWindow(IntPtr.Zero, title);
         if (ptr != IntPtr.Zero)
         {
             PostMessage(ptr, WM_KEYDOWN, VK_RETURN, 0);
             PostMessage(ptr, WM_KEYUP, VK_RETURN, 0);
         }
     }
 }

 /// <summary>
 /// 查找和关闭窗口
 /// </summary>
 public static void FindAndKillWindow()
 {
     Thread t = new Thread(() =>
     {
         while (IsWorking)
         {
             //按标题查找
             foreach (string title in titles)
             {
                 FindAndKillWindow(title);
             }
             Thread.Sleep(3000);
         }
     });
     t.Start();
 }
 /// <summary>
 /// 查找窗口
 /// </summary>
 /// <param name="title">窗口标题</param>
 /// <returns>True表示找到窗口,false则未找到</returns>
 public static IntPtr? FindWindows(string title)
 {
     IntPtr ptr = FindWindow(IntPtr.Zero, title);
     if (ptr != IntPtr.Zero)
     {
         return ptr;
     }
     return null;
 }
 public static bool FindWindows()
 {
     Thread t = new Thread(() =>
     {
         while (IsWorking)
         {
             //按标题查找
             foreach (string title in titles)
             {
                 FindWindows(title);
             }
             Thread.Sleep(3000);
         }
     });
     t.Start();
     return false;
 }
  1. 根据窗口的关系获取控件
    可以通过spy++获取控件的类型名称
  var ptr=FindWindows("打开");

  //IntPtr hwnd = FindWindow("#32770 (对话框)", "MainWindow");     //FindWindow只查找顶层窗口
  //IntPtr htextbox = FindWindowEx(ptr.Value, IntPtr.Zero, "wxWindowClassNR", null);//(当前为第一层)IntPtr.Zero则表示获得第一个子窗口。第三个参数表示你需要找的子窗口的类型,第四个参数一般为null。
  //IntPtr htextbox2 = FindWindowEx(hwnd, IntPtr.Zero, "wxWindowClassNR", null);//(当前为第一层)IntPtr.Zero则表示获得第一个子窗口。第三个参数表示你需要找的子窗口的类型,第四个参数一般为null。
  //IntPtr htextbox2 = FindWindowEx(hwnd, htextbox, "EDIT", null);//填上次获得的句柄,可以得到下一个的句柄。

  //SendMessage(ptr.Value, WM_SETTEXT, IntPtr.Zero, "123232");//发送消息

   IntPtr htextbox2 = FindWindowEx(ptr.Value, IntPtr.Zero, "ComboBoxEx32", null);//填上次获得的句柄,可以得到下一个的句柄。
  IntPtr htextbox22 = FindWindowEx(htextbox2, IntPtr.Zero, "ComboBox", null);//填上次获得的句柄,可以得到下一个的句柄。
  IntPtr edit = FindWindowEx(htextbox22, IntPtr.Zero, "Edit", null);//填上次获得的句柄,可以得到下一个的句柄。
  //SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "D:\\work\\code");//发送消息
  //SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "C:\\Users\\xx\\Desktop\\t\\WeChat_20241109200005.mp4");//发送消息
  SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "C:\\Users\\xx\\Desktop\\t\\test.mp4");//发送消息

  IntPtr openBtn = FindWindowEx(ptr.Value, IntPtr.Zero, "Button", null);//填上次获得的句柄,可以得到下一个的句柄。

  //SendMessage(openBtn, WM_KEYDOWN, IntPtr.Zero, "D:\\work\\code");//发送消息

  SendMessage(openBtn, WM_LBUTTONDOWN, IntPtr.Zero, null);//鼠标按下按钮
  SendMessage(openBtn, WM_LBUTTONUP, IntPtr.Zero, null);//释放鼠标

[参考]
c#获取句柄,并对第三方软件的输入框和按钮进行控制

posted @ 2024-11-13 23:38  Hey,Coder!  阅读(3)  评论(0编辑  收藏  举报