Hwnd.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. using System.Windows.Forms;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8. namespace WinSystem
  9. {
  10. /// <summary>
  11. /// 句柄操作
  12. /// </summary>
  13. public class Hwnd
  14. {
  15. /// <summary>
  16. /// 获取焦点所在窗口句柄
  17. /// </summary>
  18. /// <param name="hwnd">焦点所在窗口或父窗口句柄</param>
  19. /// <returns>焦点所在窗口句柄</returns>
  20. public static IntPtr getFocusByhwnd(IntPtr hwnd)
  21. {
  22. int idAttachTo = AppDomain.GetCurrentThreadId();
  23. int pid = 0;
  24. int idAttach = Win32Api.GetWindowThreadProcessId(hwnd, out pid);
  25. Win32Api.AttachThreadInput(idAttach, idAttachTo, true);
  26. IntPtr nowFocus = Win32Api.GetFocus();
  27. Win32Api.AttachThreadInput(idAttach, idAttachTo, false);
  28. return nowFocus;
  29. }
  30. /// <summary>
  31. /// 判断焦点是否在指定窗口句柄
  32. /// </summary>
  33. /// <param name="hwnd">窗口句柄</param>
  34. /// <returns>焦点在指定句柄true,焦点不在指定句柄false</returns>
  35. public static bool isFocus(IntPtr hwnd)
  36. {
  37. return hwnd!=IntPtr.Zero && hwnd == getFocusByhwnd(hwnd);
  38. }
  39. /// <summary>
  40. /// 判断鼠标点击的是否是指定窗口句柄
  41. /// </summary>
  42. /// <param name="intptr">指定窗口句柄</param>
  43. /// <param name="ef">松开鼠标事件数据</param>
  44. /// <param name="eb">按下鼠标事件数据</param>
  45. /// <param name="rect">点击确认范围</param>
  46. /// <returns>true:是 false:否</returns>
  47. public static bool isClickHwndIn(IntPtr intptr, MouseEventArgs ef, MouseEventArgs eb, Win32Api.RECT rect)
  48. {
  49. Win32Api.RECT recta;
  50. Win32Api.GetWindowRect(intptr, out recta);
  51. ////int t2 = rect.top + 48;
  52. Win32Api.RECT rect1;
  53. rect1.left = rect.left < 0 ? recta.left : (recta.left + rect.left);
  54. rect1.right = rect.right < 0 ? recta.right : (recta.left + rect.right);
  55. rect1.top = rect.top < 0 ? recta.top : (recta.top + rect.top);
  56. rect1.bottom = rect.bottom < 0 ? recta.bottom : (recta.top + rect.bottom); ;
  57. return (ef.X <= rect1.right && ef.X >= rect1.left && ef.Y <= rect1.bottom && ef.Y >= rect1.top &&
  58. eb.X <= rect1.right && eb.X >= rect1.left && eb.Y <= rect1.bottom && eb.Y >= rect1.top &&
  59. intptr == Win32Api.WindowFromPoint(new Point(ef.X, ef.Y)));
  60. //return (MouseButtons.Left.Equals(e.Button) || MouseButtons.Right.Equals(e.Button))
  61. // && intptr == Win32Api.WindowFromPoint(new System.Drawing.Point(e.X, e.Y))
  62. // && isFocus(intptr);
  63. }
  64. /// <summary>
  65. /// 判断鼠标点击的是否是指定窗口句柄
  66. /// </summary>
  67. /// <param name="intptr">指定窗口句柄</param>
  68. /// <param name="e">鼠标事件数据</param>
  69. /// <returns>true:是 false:否</returns>
  70. public static bool isClickHwnd(IntPtr intptr, System.Windows.Forms.MouseEventArgs e)
  71. {
  72. return (MouseButtons.Left.Equals(e.Button) || MouseButtons.Right.Equals(e.Button))
  73. && intptr == Win32Api.WindowFromPoint(new System.Drawing.Point(e.X, e.Y))
  74. && isFocus(intptr);
  75. }
  76. /// <summary>
  77. /// 查找窗口标题是以指定字符串开头的窗口
  78. /// </summary>
  79. /// <param name="titleStart">要比较的字符串</param>
  80. /// <returns>窗口句柄</returns>
  81. public static IntPtr FindFormStartWith(string titleStart)
  82. {
  83. string title="";
  84. return FindFormStartWith(titleStart,out title);
  85. }
  86. /// <summary>
  87. /// 查找窗口标题是以指定字符串开头的窗口
  88. /// </summary>
  89. /// <param name="titleStart">要比较的字符串</param>
  90. /// <param name="title">窗口完整标题</param>
  91. /// <returns>窗口句柄</returns>
  92. public static IntPtr FindFormStartWith(string titleStart,out string title)
  93. {
  94. IntPtr intptr = IntPtr.Zero;
  95. do
  96. {
  97. intptr = Win32Api.FindWindowEx(IntPtr.Zero, (uint)intptr, null, null);
  98. StringBuilder sb = new StringBuilder(256);
  99. Win32Api.GetWindowText(intptr, sb, 256);
  100. title = sb.ToString();
  101. if (title.StartsWith(titleStart))
  102. return intptr;
  103. } while (intptr != IntPtr.Zero);
  104. return IntPtr.Zero;
  105. }
  106. /// <summary>
  107. /// 根据句柄截取图像并保存成指定文件(bmp格式),图像可以是被窗口挡着的,但对非GDI程序无效
  108. /// </summary>
  109. /// <param name="intptr">窗口句柄</param>
  110. /// <param name="filePath">保存路径</param>
  111. public static void GetWindowCapture(IntPtr intptr, string filePath)
  112. {
  113. GetWindowCapture(intptr).Save(filePath, ImageFormat.Bmp);
  114. }
  115. /// <summary>
  116. /// 根据句柄截取图像,图像可以是被窗口挡着的,但对非GDI程序无效
  117. /// </summary>
  118. /// <param name="intptr">窗口句柄</param>
  119. public static Bitmap GetWindowCapture(IntPtr intptr)
  120. {
  121. IntPtr hscrdc = Win32Api.GetWindowDC(intptr);
  122. Win32Api.RECT windowRect = new Win32Api.RECT();
  123. Win32Api.GetWindowRect(intptr, out windowRect);
  124. int width = windowRect.right - windowRect.left;
  125. int height = windowRect.bottom - windowRect.top;
  126. IntPtr hbitmap = Win32Api.CreateCompatibleBitmap(hscrdc, width, height);
  127. IntPtr hmemdc = Win32Api.CreateCompatibleDC(hscrdc);
  128. Win32Api.SelectObject(hmemdc, hbitmap);
  129. Win32Api.PrintWindow(intptr, hmemdc, 0);
  130. Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
  131. Win32Api.DeleteDC(hscrdc);//删除用过的对象
  132. Win32Api.DeleteDC(hmemdc);//删除用过的对象
  133. return bmp;
  134. }
  135. /// <summary>
  136. /// 寻找多个窗口中,第一个出现的窗口(用于等待多个窗口中的一个出现),若多窗口同时存在,随机返回一个
  137. /// </summary>
  138. /// <param name="title">窗口标题,最多支持二级窗口</param>
  139. /// <param name="outTime">超时时间</param>
  140. /// <returns>第几个窗口,失败返回-1</returns>
  141. private static int FindOneFormCount(List<string[]> title, int outTime)
  142. {
  143. startTime = DateTime.Now;
  144. thn = -1;
  145. //intp = IntPtr.Zero;
  146. loco1 = title;
  147. sleeper = new Thread[loco1.Count];
  148. for (int i = 0; i < loco1.Count; i++)
  149. {
  150. sleeper[i] = new Thread(new ParameterizedThreadStart(SleepThread));
  151. sleeper[i].IsBackground = true;
  152. }
  153. for (int i = 0; i < sleeper.Length; i++)
  154. {
  155. sleeper[i].Start(i);
  156. }
  157. Thread.Sleep(100);
  158. stoper = new Thread(
  159. delegate() {
  160. int time = (int)outTime - (DateTime.Now - startTime).Milliseconds;
  161. Thread.Sleep(time > 0 ? time : 1);
  162. for (int i = 0; i < sleeper.Length; i++)
  163. {
  164. if (sleeper[i].IsAlive) sleeper[i].Abort();
  165. }
  166. }
  167. );
  168. stoper.IsBackground = true;
  169. //int time = outTime - 100;
  170. //stoper.Start(time>0?time:0);
  171. stoper.Start(outTime);
  172. foreach (string[] ss in loco1)
  173. {
  174. lock (ss) { }
  175. }
  176. if (stoper.IsAlive) stoper.Abort();
  177. return thn;
  178. }
  179. private static List<string[]> loco1 = new List<string[]>();
  180. private static string str = "";
  181. private static int thn = -1;
  182. private static DateTime startTime;
  183. private static Thread[] sleeper;
  184. private static Thread stoper;
  185. private static void SleepThread(object p)
  186. {
  187. int i = (int)p;
  188. lock (loco1[i])
  189. {
  190. string[] name = (string[])loco1[i];
  191. IntPtr pay_hwnd = IntPtr.Zero;
  192. while (thn == -1 && pay_hwnd == IntPtr.Zero)
  193. {
  194. pay_hwnd = IntPtr.Zero;
  195. if (name.Length == 1)
  196. {
  197. pay_hwnd = Win32Api.FindWindowEx(IntPtr.Zero, 0, null, name[0]);
  198. }
  199. else if (name.Length == 2)
  200. {
  201. if (name[0].Equals(""))
  202. {
  203. IntPtr inp = IntPtr.Zero;
  204. bool start = false;
  205. while ((inp != IntPtr.Zero || !start) && pay_hwnd == IntPtr.Zero)
  206. {
  207. if (thn != -1) break;
  208. start = true;
  209. inp = Win32Api.FindWindowEx(IntPtr.Zero, (uint)inp, null, name[0]);
  210. pay_hwnd = Win32Api.FindWindowEx(inp, 0, null, name[1]);
  211. }
  212. }
  213. else
  214. {
  215. pay_hwnd = Win32Api.FindWindowEx(IntPtr.Zero, 0, null, name[0]);
  216. pay_hwnd = Win32Api.FindWindowEx(pay_hwnd, 0, null, name[1]);
  217. }
  218. }
  219. if (thn == -1)
  220. Thread.Sleep(100);
  221. }
  222. if (pay_hwnd != IntPtr.Zero)
  223. {
  224. lock (str)
  225. {
  226. if (thn == -1)
  227. {
  228. thn = i;
  229. }
  230. }
  231. }
  232. }
  233. }
  234. }
  235. }