翼度科技»论坛 编程开发 .net 查看内容

根据窗口句柄,移动/激活窗口

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
根据窗口句柄,移动/激活窗口

1.获取窗口句柄

获取窗口句柄上篇随笔有写,不再做赘述
2.引入User32函数MoveWindow/ShowWindow

引入MoveWindow,用于移动窗口,设置  SetLastError = true,若移动窗口失败,方便查找问题
  1.         /// <summary>
  2.         /// 设置目标窗体大小,位置
  3.         /// </summary>
  4.         /// <param name="hWnd">目标句柄</param>
  5.         /// <param name="x">目标窗体新位置X轴坐标</param>
  6.         /// <param name="y">目标窗体新位置Y轴坐标</param>
  7.         /// <param name="nWidth">目标窗体新宽度</param>
  8.         /// <param name="nHeight">目标窗体新高度</param>
  9.         /// <param name="BRePaint">是否刷新窗体</param>
  10.         /// <returns></returns>
  11.         [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  12.         public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool BRePaint);
复制代码
引入ShowWindow,用于激活窗口
  1.         /// <summary>
  2.         /// 显示Window
  3.         /// </summary>
  4.         /// <param name="hwnd">句柄</param>
  5.         /// <param name="nCmdShow">
  6.         /// 0    隐藏窗口并激活另一个窗口。
  7.         /// 1    激活并显示窗口。 如果窗口最小化或最大化,系统会将其还原到其原始大小和位置。 首次显示窗口时,应用程序应指定此标志。
  8.         /// 2    激活窗口并将其显示为最小化窗口。
  9.         /// 3    激活窗口并显示最大化的窗口。
  10.         /// 4    在其最近的大小和位置显示一个窗口。 此值类似于 SW_SHOWNORMAL,但窗口未激活。
  11.         /// 5    激活窗口并以当前大小和位置显示窗口。
  12.         /// 6    最小化指定的窗口,并按 Z 顺序激活下一个顶级窗口。
  13.         /// 7    将窗口显示为最小化窗口。 此值类似于 SW_SHOWMINIMIZED,但窗口未激活。
  14.         /// 8    以当前大小和位置显示窗口。 此值类似于 SW_SHOW,但窗口未激活。
  15.         /// 9    激活并显示窗口。 如果窗口最小化或最大化,系统会将其还原到其原始大小和位置。 还原最小化窗口时,应用程序应指定此标志。
  16.         /// 10    根据启动应用程序的程序传递给 CreateProcess 函数的 STARTUPINFO 结构中指定的SW_值设置显示状态。
  17.         /// 11    即使拥有窗口的线程未响应,也会最小化窗口。 仅当将窗口从不同的线程最小化时,才应使用此标志。
  18.         /// </param>
  19.         /// <returns></returns>
  20.         [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
  21.         public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
复制代码
 
3.移动并激活窗口的一些细节

 移动并激活窗口后,可能会因为一些原因,导致窗口移动了,也激活了,但被叠在其他窗口下面。
预设两种方案:
  1).遍历所有窗口,并用ShowWindow隐藏
  2).模拟按下Win + M 最小化所有窗口,再激活需要调整的窗口
这里只对第二种方案做示例:
  1).引入User32函数keybd_event
  1.         [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
  2.         public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
  3.         /// <summary>
  4.         ///
  5.         /// </summary>
  6.         /// <param name="bVk">虚拟键值</param>
  7.         /// <param name="bScan">0</param>
  8.         /// <param name="dwFlags">按下0,释放2</param>
  9.         /// <param name="dwExtraInfo">0</param>
  10.         [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "keybd_event")]
  11.         public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
复制代码
  2).模拟按键
  1.     keybd_event(0x5B, 0, 0, 0);
  2.     keybd_event(77, 0, 0, 0);
  3.     keybd_event(0x5B, 0, 0x02, 0);
  4.     keybd_event(77, 0, 0x02, 0);<br>    //0x5B == Win键<br>    //77   == M键
复制代码
4.示例:将两个窗口在屏幕上并排显示,实现分屏效果
  1.             var width = Screen.PrimaryScreen.WorkingArea.Width / 2;
  2.             var height = Screen.PrimaryScreen.WorkingArea.Height;
  3.             keybd_event(0x5B, 0, 0, 0);
  4.             keybd_event(77, 0, 0, 0);
  5.             keybd_event(0x5B, 0, 0x02, 0);
  6.             keybd_event(77, 0, 0x02, 0);
  7.             Task.Run(() =>
  8.             {
  9.                 Task.Delay(500).Wait();
  10.                 ShowWindow(WindowsHandle1, 1);
  11.                 MoveWindow(WindowsHandle1, 0, 0, width, height, true);
  12.                 ShowWindow(WindowsHandle2, 1);
  13.                 MoveWindow(WindowsHandle2, width, 0, width, height, true);
  14.             });
复制代码
  5.获取MoveWindow的LastError
  1. //上方调用MoveWindow
  2. int i = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
复制代码

来源:https://www.cnblogs.com/niuniuyouguo/archive/2023/05/29/17439682.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具