User32.cs 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105
  1. using System;
  2. using System.Drawing;
  3. using System.Runtime.InteropServices;
  4. using System.Text;
  5. using System.Windows.Forms;
  6. namespace Microsoft.Win32
  7. {
  8. /// <summary>
  9. /// User32扩展
  10. /// </summary>
  11. public static partial class Util
  12. {
  13. /// <summary>
  14. /// 开始更新,禁止控件重绘
  15. /// </summary>
  16. /// <param name="hWnd">控件句柄</param>
  17. public static void BeginUpdate(IntPtr hWnd)
  18. {
  19. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_SETREDRAW, 0, 0);
  20. }
  21. /// <summary>
  22. /// 开始更新,允许控件重绘
  23. /// </summary>
  24. /// <param name="hWnd">控件句柄</param>
  25. public static void EndUpdate(IntPtr hWnd)
  26. {
  27. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_SETREDRAW, 1, 0);
  28. }
  29. /// <summary>
  30. /// 开始拖动窗口
  31. /// </summary>
  32. /// <param name="hWnd">窗口句柄</param>
  33. public static void BeginDrag(IntPtr hWnd)
  34. {
  35. UnsafeNativeMethods.ReleaseCapture();
  36. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_SYSCOMMAND, NativeMethods.SC_MOVE | NativeMethods.HTCAPTION, 0);
  37. }
  38. /// <summary>
  39. /// 在指定句柄窗口内按下鼠标,不等待消息处理完成立即返回
  40. /// </summary>
  41. /// <param name="hWnd">窗口句柄</param>
  42. /// <param name="pt">相对于窗口的点</param>
  43. public static void PostMouseDown(IntPtr hWnd, Point pt)
  44. {
  45. IntPtr lParam = Util.MAKELPARAM(pt.X, pt.Y);
  46. UnsafeNativeMethods.PostMessage(hWnd, NativeMethods.WM_MOUSEMOVE, IntPtr.Zero, lParam);
  47. UnsafeNativeMethods.PostMessage(hWnd, NativeMethods.WM_LBUTTONDOWN, IntPtr.Zero, lParam);
  48. }
  49. /// <summary>
  50. /// 在指定句柄窗口内弹起鼠标,不等待消息处理完成立即返回
  51. /// </summary>
  52. /// <param name="hWnd">窗口句柄</param>
  53. /// <param name="pt">相对于窗口的点</param>
  54. public static void PostMouseUp(IntPtr hWnd, Point pt)
  55. {
  56. IntPtr lParam = Util.MAKELPARAM(pt.X, pt.Y);
  57. UnsafeNativeMethods.PostMessage(hWnd, NativeMethods.WM_LBUTTONUP, IntPtr.Zero, lParam);
  58. }
  59. /// <summary>
  60. /// 在指定句柄窗口内单击鼠标,不等待消息处理完成立即返回
  61. /// </summary>
  62. /// <param name="hWnd">窗口句柄</param>
  63. /// <param name="pt">相对于窗口的点</param>
  64. public static void PostMouseClick(IntPtr hWnd, Point pt)
  65. {
  66. IntPtr lParam = Util.MAKELPARAM(pt.X, pt.Y);
  67. UnsafeNativeMethods.PostMessage(hWnd, NativeMethods.WM_MOUSEMOVE, IntPtr.Zero, lParam);
  68. UnsafeNativeMethods.PostMessage(hWnd, NativeMethods.WM_LBUTTONDOWN, IntPtr.Zero, lParam);
  69. UnsafeNativeMethods.PostMessage(hWnd, NativeMethods.WM_LBUTTONUP, IntPtr.Zero, lParam);
  70. }
  71. /// <summary>
  72. /// 在指定句柄窗口内按下鼠标,等待消息处理完成后再返回
  73. /// </summary>
  74. /// <param name="hWnd">窗口句柄</param>
  75. /// <param name="pt">相对于窗口的点</param>
  76. public static void SendMouseDown(IntPtr hWnd, Point pt)
  77. {
  78. IntPtr lParam = Util.MAKELPARAM(pt.X, pt.Y);
  79. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_MOUSEMOVE, IntPtr.Zero, lParam);
  80. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_LBUTTONDOWN, IntPtr.Zero, lParam);
  81. }
  82. /// <summary>
  83. /// 在指定句柄窗口内弹起鼠标,等待消息处理完成后再返回
  84. /// </summary>
  85. /// <param name="hWnd">窗口句柄</param>
  86. /// <param name="pt">相对于窗口的点</param>
  87. public static void SendMouseUp(IntPtr hWnd, Point pt)
  88. {
  89. IntPtr lParam = Util.MAKELPARAM(pt.X, pt.Y);
  90. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_LBUTTONUP, IntPtr.Zero, lParam);
  91. }
  92. /// <summary>
  93. /// 在指定句柄窗口内单击鼠标,等待消息处理完成后再返回
  94. /// </summary>
  95. /// <param name="hWnd">窗口句柄</param>
  96. /// <param name="pt">相对于窗口的点</param>
  97. public static void SendMouseClick(IntPtr hWnd, Point pt)
  98. {
  99. IntPtr lParam = Util.MAKELPARAM(pt.X, pt.Y);
  100. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_MOUSEMOVE, IntPtr.Zero, lParam);
  101. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_LBUTTONDOWN, IntPtr.Zero, lParam);
  102. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_LBUTTONUP, IntPtr.Zero, lParam);
  103. }
  104. /// <summary>
  105. /// 按下键盘键
  106. /// </summary>
  107. /// <param name="vKey">虚拟键码</param>
  108. public static void SendKeyDown(short vKey)
  109. {
  110. NativeMethods.INPUT[] input = new NativeMethods.INPUT[1];
  111. input[0].type = NativeMethods.INPUT_KEYBOARD;
  112. input[0].ki.wVk = vKey;
  113. input[0].ki.time = UnsafeNativeMethods.GetTickCount();
  114. UnsafeNativeMethods.SendInput((uint)input.Length, input, Marshal.SizeOf(input[0]));
  115. }
  116. /// <summary>
  117. /// 弹起键盘键
  118. /// </summary>
  119. /// <param name="vKey">虚拟键码</param>
  120. public static void SendKeyUp(short vKey)
  121. {
  122. NativeMethods.INPUT[] input = new NativeMethods.INPUT[1];
  123. input[0].type = NativeMethods.INPUT_KEYBOARD;
  124. input[0].ki.wVk = vKey;
  125. input[0].ki.dwFlags = NativeMethods.KEYEVENTF_KEYUP;
  126. input[0].ki.time = UnsafeNativeMethods.GetTickCount();
  127. UnsafeNativeMethods.SendInput((uint)input.Length, input, Marshal.SizeOf(input[0]));
  128. }
  129. /// <summary>
  130. /// 按一下并弹起键盘键
  131. /// </summary>
  132. /// <param name="vKey">虚拟键码</param>
  133. public static void SendKeyClick(short vKey)
  134. {
  135. SendKeyDown(vKey);
  136. SendKeyUp(vKey);
  137. }
  138. /// <summary>
  139. /// 显示或隐藏光标.
  140. /// </summary>
  141. /// <param name="visible">显示为true,否则为false.</param>
  142. public static void ShowCursor(bool visible)
  143. {
  144. if (visible)
  145. {
  146. while (UnsafeNativeMethods.ShowCursor(true) < 0) { }
  147. }
  148. else
  149. {
  150. while (UnsafeNativeMethods.ShowCursor(false) >= 0) { }
  151. }
  152. }
  153. /// <summary>
  154. /// 获取光标是否显示.显示为true,否则为false.
  155. /// </summary>
  156. public static bool GetCursorVisible()
  157. {
  158. UnsafeNativeMethods.ShowCursor(false);
  159. return UnsafeNativeMethods.ShowCursor(true) >= 0;
  160. }
  161. /// <summary>
  162. /// 获取指定窗口的所有者窗口。
  163. /// </summary>
  164. /// <param name="hWnd">指定窗口。</param>
  165. /// <returns>所有者窗口。</returns>
  166. public static IntPtr GetOwner(IntPtr hWnd)
  167. {
  168. return UnsafeNativeMethods.GetWindow(hWnd, NativeMethods.GW_OWNER);
  169. }
  170. /// <summary>
  171. /// 为指定窗口设置新的的所有者窗口。
  172. /// </summary>
  173. /// <param name="hWnd">指定窗口。</param>
  174. /// <param name="hWndNewOwner">新的所有者窗口。</param>
  175. public static void SetOwner(IntPtr hWnd, IntPtr hWndNewOwner)
  176. {
  177. UnsafeNativeMethods.SetWindowLong(hWnd, NativeMethods.GWL_HWNDPARENT, (int)hWndNewOwner);
  178. }
  179. /// <summary>
  180. /// 获取指定窗口的父窗口。
  181. /// </summary>
  182. /// <param name="hWnd">指定窗口。</param>
  183. /// <returns>父窗口。</returns>
  184. public static IntPtr GetParent(IntPtr hWnd)
  185. {
  186. return UnsafeNativeMethods.GetAncestor(hWnd, NativeMethods.GA_PARENT);
  187. }
  188. /// <summary>
  189. /// 为指定窗口设置新的父窗口。
  190. /// </summary>
  191. /// <param name="hWnd">指定窗口。</param>
  192. /// <param name="hWndNewParent">新的父窗口。</param>
  193. public static void SetParent(IntPtr hWnd, IntPtr hWndNewParent)
  194. {
  195. UnsafeNativeMethods.SetParent(hWnd, hWndNewParent);
  196. }
  197. /// <summary>
  198. /// 获取指定窗口包含的滚动条。
  199. /// </summary>
  200. /// <param name="hWnd">窗口句柄。</param>
  201. /// <returns>返回值见 System.Windows.Forms.ScrollBars 定义</returns>
  202. public static int GetScrollBars(IntPtr hWnd)
  203. {
  204. int wndStyle = UnsafeNativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_STYLE);
  205. bool hsVisible = (wndStyle & NativeMethods.WS_HSCROLL) != 0;
  206. bool vsVisible = (wndStyle & NativeMethods.WS_VSCROLL) != 0;
  207. if (hsVisible)
  208. return vsVisible ? 3 : 1;
  209. else
  210. return vsVisible ? 2 : 0;
  211. }
  212. /// <summary>
  213. /// 获取指定窗口是否有左滚动条样式。
  214. /// </summary>
  215. /// <param name="hWnd">窗口句柄。</param>
  216. /// <returns>窗口有左滚动条样式返回 true,否则返回 false。</returns>
  217. public static bool GetLeftScrollBar(IntPtr hWnd)
  218. {
  219. int wndExStyle = UnsafeNativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_EXSTYLE);
  220. return (wndExStyle & NativeMethods.WS_EX_LEFTSCROLLBAR) != 0;
  221. }
  222. /// <summary>
  223. /// 获取指定窗口边框宽度。
  224. /// </summary>
  225. /// <param name="hWnd">窗口句柄。</param>
  226. /// <returns>窗口边框宽度。</returns>
  227. public static int GetBorderWidth(IntPtr hWnd)
  228. {
  229. int wndExStyle = UnsafeNativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_EXSTYLE);
  230. if ((wndExStyle & NativeMethods.WS_EX_STATICEDGE) != 0)
  231. return 3;
  232. else if ((wndExStyle & NativeMethods.WS_EX_WINDOWEDGE) != 0)
  233. return 2;
  234. else if ((wndExStyle & NativeMethods.WS_EX_CLIENTEDGE) != 0)
  235. return 2;
  236. else if ((UnsafeNativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_STYLE) & NativeMethods.WS_BORDER) != 0)
  237. return 1;
  238. else
  239. return 0;
  240. }
  241. /// <summary>
  242. /// 从 GDI+ Region 创建一个 GDI Region。
  243. /// </summary>
  244. /// <param name="hWnd">控件句柄。</param>
  245. /// <param name="region">System.Drawing.Region 对象。</param>
  246. /// <returns>GDI Region 句柄。</returns>
  247. public static IntPtr GetHRgn(IntPtr hWnd, Region region)
  248. {
  249. using (Graphics g = Graphics.FromHwndInternal(hWnd))
  250. {
  251. return region.GetHrgn(g);
  252. }
  253. }
  254. /// <summary>
  255. /// 获取窗口的客户区相对于窗口左上角的矩形.(特别注意:如果有非客户区起点一般不为0,0 如果没有非客户区该值同ClientRectangle相等).该函数非常特别尽量不要调用,在非客户区操作时可能使用到,其余问题请咨询编写人员. by Tim 2013.11.23
  256. /// </summary>
  257. /// <param name="hWnd">指定窗口句柄</param>
  258. /// <returns>客户区相对于窗口坐标系的坐标和大小</returns>
  259. public static NativeMethods.RECT GetClientRect(IntPtr hWnd)
  260. {
  261. NativeMethods.RECT wndRect = new NativeMethods.RECT();//窗口相对于屏幕的坐标和大小
  262. NativeMethods.RECT clientRect = new NativeMethods.RECT();//以0,0开始的客户区坐标和大小
  263. UnsafeNativeMethods.GetWindowRect(hWnd, ref wndRect);//窗口
  264. UnsafeNativeMethods.GetClientRect(hWnd, ref clientRect);//客户区
  265. UnsafeNativeMethods.MapWindowPoints(hWnd, NativeMethods.HWND_DESKTOP, ref clientRect, 2);//客户区映射到屏幕
  266. //偏移
  267. clientRect.left -= wndRect.left;
  268. clientRect.top -= wndRect.top;
  269. clientRect.right -= wndRect.left;
  270. clientRect.bottom -= wndRect.top;
  271. //返回
  272. return clientRect;
  273. }
  274. /// <summary>
  275. /// 闪烁指定窗口。
  276. /// </summary>
  277. /// <param name="hWnd">指定窗口句柄。</param>
  278. /// <param name="count">闪烁次数。</param>
  279. /// <returns>返回闪烁前窗口是否已被激活。</returns>
  280. public static bool FlashWindow(IntPtr hWnd, int count)
  281. {
  282. NativeMethods.FLASHWINFO fwi = new NativeMethods.FLASHWINFO();
  283. fwi.cbSize = Marshal.SizeOf(fwi);
  284. fwi.hwnd = hWnd;
  285. fwi.dwFlags = NativeMethods.FLASHW_TRAY;
  286. fwi.uCount = count;
  287. fwi.dwTimeout = 0;
  288. return UnsafeNativeMethods.FlashWindowEx(ref fwi);
  289. }
  290. #region 扩展
  291. /// <summary>
  292. /// 将窗口置顶
  293. /// </summary>
  294. /// <param name="lpClassName">窗口类名</param>
  295. /// <param name="lpWindowName">窗口标题</param>
  296. public static void BringToFront(string lpClassName, string lpWindowName)
  297. {
  298. IntPtr hWnd = UnsafeNativeMethods.FindWindow(lpClassName, lpWindowName);
  299. if (hWnd != IntPtr.Zero)
  300. UnsafeNativeMethods.SetWindowPos(hWnd, NativeMethods.HWND_TOP, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE);
  301. }
  302. /// <summary>
  303. /// 将窗口置底
  304. /// </summary>
  305. /// <param name="lpClassName">窗口类名</param>
  306. /// <param name="lpWindowName">窗口标题</param>
  307. public static void SendToBack(string lpClassName, string lpWindowName)
  308. {
  309. IntPtr hWnd = UnsafeNativeMethods.FindWindow(lpClassName, lpWindowName);
  310. if (hWnd != IntPtr.Zero)
  311. UnsafeNativeMethods.SetWindowPos(hWnd, NativeMethods.HWND_BOTTOM, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE);
  312. }
  313. /// <summary>
  314. /// 跨进程,向指定窗口发送WM_COPYDATA消息
  315. /// </summary>
  316. /// <param name="lpWindowName">窗口标题</param>
  317. /// <param name="flag">区分标记</param>
  318. /// <param name="data">要发送的字符串数据</param>
  319. public static void SendCopyData(string lpWindowName, int flag, string data)
  320. {
  321. IntPtr hWnd = UnsafeNativeMethods.FindWindow(null, lpWindowName);
  322. if (hWnd == IntPtr.Zero)
  323. return;
  324. byte[] arr = Encoding.UTF8.GetBytes(data);
  325. NativeMethods.COPYDATASTRUCT cds = new NativeMethods.COPYDATASTRUCT();
  326. cds.dwData = flag;
  327. cds.cbData = arr.Length + 1;
  328. cds.lpData = data;
  329. UnsafeNativeMethods.SendMessage(hWnd, NativeMethods.WM_COPYDATA, IntPtr.Zero, ref cds);
  330. }
  331. /// <summary>
  332. /// 向指定标题的窗口发送WM_CLOSE消息
  333. /// </summary>
  334. /// <param name="lpWindowName">窗口标题</param>
  335. public static void CloseWindow(string lpWindowName)
  336. {
  337. IntPtr hWnd = UnsafeNativeMethods.FindWindow(null, lpWindowName);
  338. if (hWnd == IntPtr.Zero)
  339. return;
  340. UnsafeNativeMethods.PostMessage(hWnd, NativeMethods.WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
  341. }
  342. /// <summary>
  343. /// 设置窗口显示状态
  344. /// </summary>
  345. /// <param name="lpWindowName">窗口标题</param>
  346. /// <param name="nCmdShow">显示指令</param>
  347. public static void ShowWindow(string lpWindowName, int nCmdShow)
  348. {
  349. IntPtr hWnd = UnsafeNativeMethods.FindWindow(null, lpWindowName);
  350. if (hWnd == IntPtr.Zero)
  351. return;
  352. UnsafeNativeMethods.ShowWindow(hWnd, nCmdShow);
  353. }
  354. /// <summary>
  355. /// 设置控件TopMost(使窗口成为“TopMost”类型的窗口,这种类型的窗口总是在其它窗口的前面)
  356. /// </summary>
  357. /// <param name="hWnd">要设置的窗口</param>
  358. public static void SetTopMost(IntPtr hWnd)
  359. {
  360. try
  361. {
  362. UnsafeNativeMethods.SetWindowPos(hWnd, NativeMethods.HWND_TOPMOST, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOACTIVATE);
  363. }
  364. catch
  365. {
  366. }
  367. }
  368. /// <summary>
  369. /// 设置控件NoTopMost(将窗口放在所有“TopMost”类型窗口的后面,其它类型窗口的前面)
  370. /// </summary>
  371. /// <param name="hWnd">要设置的窗口</param>
  372. public static void SetNoTopMost(IntPtr hWnd)
  373. {
  374. try
  375. {
  376. UnsafeNativeMethods.SetWindowPos(hWnd, NativeMethods.HWND_NOTOPMOST, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOACTIVATE);
  377. }
  378. catch
  379. {
  380. }
  381. }
  382. /// <summary>
  383. /// 设置窗口的拥有窗口,可以跨进程
  384. /// </summary>
  385. /// <param name="child"></param>
  386. /// <param name="lpParentWindowName"></param>
  387. public static void SetOwner(Control child, string lpParentWindowName)
  388. {
  389. IntPtr hWndNewParent = UnsafeNativeMethods.FindWindow(null, lpParentWindowName);
  390. if (hWndNewParent != IntPtr.Zero)
  391. SetOwner(child.Handle, hWndNewParent);
  392. }
  393. /// <summary>
  394. /// 设置窗口的拥有窗口,可以跨进程
  395. /// </summary>
  396. /// <param name="lpChildWindowName"></param>
  397. /// <param name="parent"></param>
  398. public static void SetOwner(string lpChildWindowName, Control parent)
  399. {
  400. IntPtr hWndChild = UnsafeNativeMethods.FindWindow(null, lpChildWindowName);
  401. if (hWndChild != IntPtr.Zero)
  402. SetOwner(hWndChild, parent.Handle);
  403. }
  404. /// <summary>
  405. /// 跨进程,向指定窗口发送指定消息,立即返回
  406. /// </summary>
  407. /// <param name="lpWindowName">窗口标题</param>
  408. /// <param name="msg">消息</param>
  409. /// <param name="lParam">lParam</param>
  410. public static void PostMessage(string lpWindowName, int msg, int lParam)
  411. {
  412. IntPtr hWnd = UnsafeNativeMethods.FindWindow(null, lpWindowName);
  413. if (hWnd == IntPtr.Zero)
  414. return;
  415. UnsafeNativeMethods.PostMessage(hWnd, msg, IntPtr.Zero, (IntPtr)lParam);
  416. }
  417. /// <summary>
  418. /// 跨进程,向指定窗口发送指定消息,立即返回
  419. /// </summary>
  420. /// <param name="lpWindowName">窗口标题</param>
  421. /// <param name="msg">消息</param>
  422. /// <param name="wParam">wParm</param>
  423. /// <param name="lParam">lParm</param>
  424. public static void PostMessage(string lpWindowName, int msg, int wParam, int lParam)
  425. {
  426. IntPtr hWnd = UnsafeNativeMethods.FindWindow(null, lpWindowName);
  427. if (hWnd == IntPtr.Zero)
  428. return;
  429. UnsafeNativeMethods.PostMessage(hWnd, msg, (IntPtr)wParam, (IntPtr)lParam);
  430. }
  431. /// <summary>
  432. /// 跨进程,向指定窗口发送指定消息,立即返回
  433. /// </summary>
  434. /// <param name="hWnd">窗口句柄</param>
  435. /// <param name="msg">消息</param>
  436. /// <param name="lParam">lParam</param>
  437. public static void PostMessage(IntPtr hWnd, int msg, int lParam)
  438. {
  439. if (hWnd == IntPtr.Zero)
  440. return;
  441. UnsafeNativeMethods.PostMessage(hWnd, msg, IntPtr.Zero, (IntPtr)lParam);
  442. }
  443. /// <summary>
  444. /// 跨进程,向指定窗口发送指定消息,立即返回
  445. /// </summary>
  446. /// <param name="hWnd">窗口句柄</param>
  447. /// <param name="msg">消息</param>
  448. /// <param name="wParam">wParam</param>
  449. /// <param name="lParam">lParam</param>
  450. public static void PostMessage(IntPtr hWnd, int msg, int wParam, int lParam)
  451. {
  452. if (hWnd == IntPtr.Zero)
  453. return;
  454. UnsafeNativeMethods.PostMessage(hWnd, msg, (IntPtr)wParam, (IntPtr)lParam);
  455. }
  456. #endregion
  457. #region 窗口
  458. /// <summary>
  459. /// 从 lParam 提取坐标
  460. /// </summary>
  461. /// <param name="lParam">消息中的 lParam 参数</param>
  462. /// <returns>鼠标相对窗口坐标</returns>
  463. public static Point GetMousePosition(IntPtr lParam)
  464. {
  465. return new Point(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  466. }
  467. /// <summary>
  468. /// 获取该控件的右下角相对于其容器的左上角的坐标。
  469. /// </summary>
  470. /// <param name="hWnd">控件句柄。</param>
  471. /// <returns>System.Drawing.Point,它表示控件的右下角相对于其容器的左上角。</returns>
  472. public static Point GetBottomRight(IntPtr hWnd)
  473. {
  474. NativeMethods.RECT lpRect = new NativeMethods.RECT();
  475. UnsafeNativeMethods.GetWindowRect(hWnd, ref lpRect);
  476. NativeMethods.POINT pt = new NativeMethods.POINT(lpRect.bottom, lpRect.right);
  477. //父窗口不为空转换坐标
  478. IntPtr hWndParent = GetParent(hWnd);
  479. if (hWndParent != IntPtr.Zero)
  480. UnsafeNativeMethods.MapWindowPoints(NativeMethods.HWND_DESKTOP, hWndParent, ref pt, 1);
  481. return new Point(pt.x, pt.y);
  482. }
  483. /// <summary>
  484. /// 获取一个值,该值指示是否将控件显示为顶级窗口。
  485. /// </summary>
  486. /// <param name="hWnd">控件句柄。</param>
  487. /// <returns>如果为 true,则将控件显示为顶级窗口;否则,为 false。</returns>
  488. public static bool GetTopLevel(IntPtr hWnd)
  489. {
  490. int dwStyle = UnsafeNativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_STYLE);
  491. return ((dwStyle & NativeMethods.WS_CHILD) == 0);
  492. }
  493. /// <summary>
  494. /// 获取一个值,该值指示控件是否有与它关联的句柄。
  495. /// </summary>
  496. /// <param name="hWnd">控件句柄。</param>
  497. /// <returns>如果已经为控件分配了句柄,则为 true;否则为 false。</returns>
  498. public static bool GetIsHandleCreated(IntPtr hWnd)
  499. {
  500. return (hWnd != IntPtr.Zero);
  501. }
  502. /// <summary>
  503. /// 获取一个值,该值指示是否显示该控件及其所有父控件。
  504. /// </summary>
  505. /// <param name="hWnd">控件句柄。</param>
  506. /// <returns>如果显示该控件及其所有父控件,则为 true;否则为 false。默认为 true。</returns>
  507. public static bool GetVisible(IntPtr hWnd)
  508. {
  509. return UnsafeNativeMethods.IsWindowVisible(hWnd);
  510. }
  511. /// <summary>
  512. /// 设置一个值,该值指示是否显示该控件及其所有父控件。
  513. /// </summary>
  514. /// <param name="hWnd">控件句柄。</param>
  515. /// <param name="value">如果显示该控件及其所有父控件,则为 true;否则为 false。默认为 true。</param>
  516. public static void SetVisible(IntPtr hWnd, bool value)
  517. {
  518. UnsafeNativeMethods.SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE | (value ? NativeMethods.SWP_SHOWWINDOW : NativeMethods.SWP_HIDEWINDOW));
  519. }
  520. /// <summary>
  521. /// 获取一个值,该值指示控件是否可以对用户交互作出响应。
  522. /// </summary>
  523. /// <param name="hWnd">控件句柄。</param>
  524. /// <returns>如果控件可以对用户交互作出响应,则为 true;否则为 false。默认为 true。</returns>
  525. public static bool GetEnabled(IntPtr hWnd)
  526. {
  527. return UnsafeNativeMethods.IsWindowEnabled(hWnd);
  528. }
  529. /// <summary>
  530. /// 设置一个值,该值指示控件是否可以对用户交互作出响应。
  531. /// </summary>
  532. /// <param name="hWnd">控件句柄。</param>
  533. /// <param name="value">如果控件可以对用户交互作出响应,则为 true;否则为 false。默认为 true。</param>
  534. public static void SetEnabled(IntPtr hWnd, bool value)
  535. {
  536. UnsafeNativeMethods.EnableWindow(hWnd, value);
  537. }
  538. /// <summary>
  539. /// 获取一个值,该值指示控件是否有输入焦点。
  540. /// </summary>
  541. /// <param name="hWnd">控件句柄。</param>
  542. /// <returns>如果控件有焦点,则为 true;否则为 false。</returns>
  543. public static bool GetFocused(IntPtr hWnd)
  544. {
  545. return (GetIsHandleCreated(hWnd) && (UnsafeNativeMethods.GetFocus() == hWnd));
  546. }
  547. /// <summary>
  548. /// 获取一个值,该值指示控件是否可以接收焦点。
  549. /// </summary>
  550. /// <param name="hWnd">控件句柄。</param>
  551. /// <returns>如果控件可以接收焦点,则为 true;否则为 false。</returns>
  552. public static bool GetCanFocus(IntPtr hWnd)
  553. {
  554. if (!GetIsHandleCreated(hWnd))
  555. return false;
  556. return UnsafeNativeMethods.IsWindowVisible(hWnd) && UnsafeNativeMethods.IsWindowEnabled(hWnd);
  557. }
  558. /// <summary>
  559. /// 获取一个值,该值指示控件或它的一个子控件当前是否有输入焦点。
  560. /// </summary>
  561. /// <param name="hWnd">控件句柄。</param>
  562. /// <returns>如果控件或它的一个子控件当前已经有输入焦点,则为 true;否则为 false。</returns>
  563. public static bool GetContainsFocus(IntPtr hWnd)
  564. {
  565. if (!GetIsHandleCreated(hWnd))
  566. return false;
  567. IntPtr focus = UnsafeNativeMethods.GetFocus();
  568. if (focus == IntPtr.Zero)
  569. return false;
  570. return ((focus == hWnd) || UnsafeNativeMethods.IsChild(hWnd, focus));
  571. }
  572. /// <summary>
  573. /// 获取一个值,该值指示控件是否已捕获鼠标。
  574. /// </summary>
  575. /// <param name="hWnd">控件句柄。</param>
  576. /// <returns>如果控件已捕获鼠标,则为 true;否则为 false。</returns>
  577. public static bool GetCapture(IntPtr hWnd)
  578. {
  579. return (GetIsHandleCreated(hWnd) && (UnsafeNativeMethods.GetCapture() == hWnd));
  580. }
  581. /// <summary>
  582. /// 设置一个值,该值指示控件是否已捕获鼠标。
  583. /// </summary>
  584. /// <param name="hWnd">控件句柄。</param>
  585. /// <param name="value">如果控件已捕获鼠标,则为 true;否则为 false。</param>
  586. public static void SetCapture(IntPtr hWnd, bool value)
  587. {
  588. if (value)
  589. UnsafeNativeMethods.SetCapture(hWnd);
  590. else
  591. UnsafeNativeMethods.ReleaseCapture();
  592. }
  593. /// <summary>
  594. /// 获取该控件的左上角相对于其容器的左上角的坐标。
  595. /// </summary>
  596. /// <param name="hWnd">控件句柄。</param>
  597. /// <returns>System.Drawing.Point,它表示控件的左上角相对于其容器的左上角。</returns>
  598. public static Point GetLocation(IntPtr hWnd)
  599. {
  600. NativeMethods.RECT lpRect = new NativeMethods.RECT();
  601. UnsafeNativeMethods.GetWindowRect(hWnd, ref lpRect);
  602. NativeMethods.POINT pt = new NativeMethods.POINT(lpRect.left, lpRect.top);
  603. //父窗口不为空转换坐标
  604. IntPtr hWndParent = GetParent(hWnd);
  605. if (hWndParent != IntPtr.Zero)
  606. UnsafeNativeMethods.MapWindowPoints(NativeMethods.HWND_DESKTOP, hWndParent, ref pt, 1);
  607. return new Point(pt.x, pt.y);
  608. }
  609. /// <summary>
  610. /// 设置该控件的左上角相对于其容器的左上角的坐标。
  611. /// </summary>
  612. /// <param name="hWnd">控件句柄。</param>
  613. /// <param name="value">System.Drawing.Point,它表示控件的左上角相对于其容器的左上角。</param>
  614. public static void SetLocation(IntPtr hWnd, Point value)
  615. {
  616. UnsafeNativeMethods.SetWindowPos(hWnd, IntPtr.Zero, value.X, value.Y, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
  617. }
  618. /// <summary>
  619. /// 获取控件的高度和宽度。
  620. /// </summary>
  621. /// <param name="hWnd">控件句柄。</param>
  622. /// <returns>System.Drawing.Size,表示控件的高度和宽度(以像素为单位)。</returns>
  623. public static Size GetSize(IntPtr hWnd)
  624. {
  625. NativeMethods.RECT lpRect = new NativeMethods.RECT();
  626. UnsafeNativeMethods.GetWindowRect(hWnd, ref lpRect);
  627. return lpRect.Size;
  628. }
  629. /// <summary>
  630. /// 设置控件的高度和宽度。
  631. /// </summary>
  632. /// <param name="hWnd">控件句柄。</param>
  633. /// <param name="value">System.Drawing.Size,表示控件的高度和宽度(以像素为单位)。</param>
  634. public static void SetSize(IntPtr hWnd, Size value)
  635. {
  636. UnsafeNativeMethods.SetWindowPos(hWnd, IntPtr.Zero, 0, 0, value.Width, value.Height, NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
  637. }
  638. /// <summary>
  639. /// 获取控件(包括其非工作区元素)相对于其父控件的大小和位置(以像素为单位)。
  640. /// </summary>
  641. /// <param name="hWnd">控件句柄。</param>
  642. /// <returns>相对于父控件的 System.Drawing.Rectangle,表示控件(包括其非工作区元素)的大小和位置(以像素为单位)。</returns>
  643. public static Rectangle GetBounds(IntPtr hWnd)
  644. {
  645. NativeMethods.RECT lpRect = new NativeMethods.RECT();
  646. UnsafeNativeMethods.GetWindowRect(hWnd, ref lpRect);
  647. //父窗口不为空转换坐标
  648. IntPtr hWndParent = GetParent(hWnd);
  649. if (hWndParent != IntPtr.Zero)
  650. UnsafeNativeMethods.MapWindowPoints(NativeMethods.HWND_DESKTOP, hWndParent, ref lpRect, 2);
  651. return lpRect.ToRectangle();
  652. }
  653. /// <summary>
  654. /// 设置控件(包括其非工作区元素)相对于其父控件的大小和位置(以像素为单位)。
  655. /// </summary>
  656. /// <param name="hWnd">控件句柄。</param>
  657. /// <param name="value">相对于父控件的 System.Drawing.Rectangle,表示控件(包括其非工作区元素)的大小和位置(以像素为单位)。</param>
  658. public static void SetBounds(IntPtr hWnd, Rectangle value)
  659. {
  660. UnsafeNativeMethods.SetWindowPos(hWnd, IntPtr.Zero, value.X, value.Y, value.Width, value.Height, NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);
  661. }
  662. /// <summary>
  663. /// 获取控件左边缘与其容器的工作区左边缘之间的距离(以像素为单位)。
  664. /// </summary>
  665. /// <param name="hWnd">控件句柄。</param>
  666. /// <returns>System.Int32 表示控件左边缘与其容器的工作区左边缘之间的距离(以像素为单位)。</returns>
  667. public static int GetLeft(IntPtr hWnd)
  668. {
  669. return GetLocation(hWnd).X;
  670. }
  671. /// <summary>
  672. /// 设置控件左边缘与其容器的工作区左边缘之间的距离(以像素为单位)。
  673. /// </summary>
  674. /// <param name="hWnd">控件句柄。</param>
  675. /// <param name="value">System.Int32 表示控件左边缘与其容器的工作区左边缘之间的距离(以像素为单位)。</param>
  676. public static void SetLeft(IntPtr hWnd, int value)
  677. {
  678. Point pt = GetLocation(hWnd);
  679. pt.X = value;
  680. SetLocation(hWnd, pt);
  681. }
  682. /// <summary>
  683. /// 获取控件上边缘与其容器的工作区上边缘之间的距离(以像素为单位)。
  684. /// </summary>
  685. /// <param name="hWnd">控件句柄。</param>
  686. /// <returns>System.Int32 表示控件下边缘与其容器的工作区上边缘之间的距离(以像素为单位)。</returns>
  687. public static int GetTop(IntPtr hWnd)
  688. {
  689. return GetLocation(hWnd).Y;
  690. }
  691. /// <summary>
  692. /// 设置控件上边缘与其容器的工作区上边缘之间的距离(以像素为单位)。
  693. /// </summary>
  694. /// <param name="hWnd">控件句柄。</param>
  695. /// <param name="value">System.Int32 表示控件上边缘与其容器的工作区上边缘之间的距离(以像素为单位)。</param>
  696. public static void SetTop(IntPtr hWnd, int value)
  697. {
  698. Point pt = GetLocation(hWnd);
  699. pt.Y = value;
  700. SetLocation(hWnd, pt);
  701. }
  702. /// <summary>
  703. /// 获取控件右边缘与其容器的工作区左边缘之间的距离(以像素为单位)。
  704. /// </summary>
  705. /// <param name="hWnd">控件句柄。</param>
  706. /// <returns>System.Int32 表示控件右边缘与其容器的工作区左边缘之间的距离(以像素为单位)。</returns>
  707. public static int GetRight(IntPtr hWnd)
  708. {
  709. return GetBottomRight(hWnd).X;
  710. }
  711. /// <summary>
  712. /// 获取控件下边缘与其容器的工作区上边缘之间的距离(以像素为单位)。
  713. /// </summary>
  714. /// <param name="hWnd">控件句柄。</param>
  715. /// <returns>System.Int32 表示控件下边缘与其容器的工作区上边缘之间的距离(以像素为单位)。</returns>
  716. public static int GetBottom(IntPtr hWnd)
  717. {
  718. return GetBottomRight(hWnd).Y;
  719. }
  720. /// <summary>
  721. /// 获取控件的宽度。
  722. /// </summary>
  723. /// <param name="hWnd">控件句柄。</param>
  724. /// <returns>控件的宽度(以像素为单位)。</returns>
  725. public static int GetWidth(IntPtr hWnd)
  726. {
  727. return GetSize(hWnd).Width;
  728. }
  729. /// <summary>
  730. /// 设置控件的宽度。
  731. /// </summary>
  732. /// <param name="hWnd">控件句柄。</param>
  733. /// <param name="value">控件的宽度(以像素为单位)。</param>
  734. public static void SetWidth(IntPtr hWnd, int value)
  735. {
  736. Size sz = GetSize(hWnd);
  737. sz.Width = value;
  738. SetSize(hWnd, sz);
  739. }
  740. /// <summary>
  741. /// 获取控件的高度。
  742. /// </summary>
  743. /// <param name="hWnd">控件句柄。</param>
  744. /// <returns>控件的高度(以像素为单位)。</returns>
  745. public static int GetHeight(IntPtr hWnd)
  746. {
  747. return GetSize(hWnd).Height;
  748. }
  749. /// <summary>
  750. /// 设置控件的高度。
  751. /// </summary>
  752. /// <param name="hWnd">控件句柄。</param>
  753. /// <param name="value">控件的高度(以像素为单位)。</param>
  754. public static void SetHeight(IntPtr hWnd, int value)
  755. {
  756. Size sz = GetSize(hWnd);
  757. sz.Height = value;
  758. SetSize(hWnd, sz);
  759. }
  760. /// <summary>
  761. /// 获取控件的工作区的高度和宽度。
  762. /// </summary>
  763. /// <param name="hWnd">控件句柄。</param>
  764. /// <returns>一个 System.Drawing.Size,表示控件的工作区的维数。</returns>
  765. public static Size GetClientSize(IntPtr hWnd)
  766. {
  767. NativeMethods.RECT lpRect = new NativeMethods.RECT();
  768. UnsafeNativeMethods.GetClientRect(hWnd, ref lpRect);
  769. return lpRect.Size;
  770. }
  771. /// <summary>
  772. /// 设置控件的工作区的高度和宽度。
  773. /// </summary>
  774. /// <param name="hWnd">控件句柄。</param>
  775. /// <param name="value">一个 System.Drawing.Size,表示控件的工作区的维数。</param>
  776. public static void SetClientSize(IntPtr hWnd, Size value)
  777. {
  778. NativeMethods.RECT lpRect = new NativeMethods.RECT(0, 0, value.Width, value.Height);
  779. int dwStyle = UnsafeNativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_STYLE);
  780. int dwExStyle = UnsafeNativeMethods.GetWindowLong(hWnd, NativeMethods.GWL_EXSTYLE);
  781. UnsafeNativeMethods.AdjustWindowRectEx(ref lpRect, dwStyle, false, dwExStyle);
  782. SetSize(hWnd, lpRect.Size);
  783. }
  784. /// <summary>
  785. /// 获取表示控件的工作区的矩形。
  786. /// </summary>
  787. /// <param name="hWnd">控件句柄。</param>
  788. /// <returns>一个 System.Drawing.Rectangle,它表示控件的工作区。</returns>
  789. public static Rectangle GetClientRectangle(IntPtr hWnd)
  790. {
  791. NativeMethods.RECT lpRect = new NativeMethods.RECT();
  792. UnsafeNativeMethods.GetClientRect(hWnd, ref lpRect);
  793. return lpRect.ToRectangle();
  794. }
  795. /// <summary>
  796. /// 获取与此控件关联的文本。
  797. /// </summary>
  798. /// <param name="hWnd">控件句柄。</param>
  799. /// <returns>与该控件关联的文本。</returns>
  800. public static string GetText(IntPtr hWnd)
  801. {
  802. if (!GetIsHandleCreated(hWnd))
  803. return string.Empty;
  804. int windowTextLength = UnsafeNativeMethods.GetWindowTextLength(hWnd);
  805. if (UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_DBCSENABLED) != 0)
  806. windowTextLength = (windowTextLength * 2) + 1;
  807. StringBuilder lpString = new StringBuilder(windowTextLength + 1);
  808. UnsafeNativeMethods.GetWindowText(hWnd, lpString, lpString.Capacity);
  809. return lpString.ToString();
  810. }
  811. /// <summary>
  812. /// 设置与此控件关联的文本。
  813. /// </summary>
  814. /// <param name="hWnd">控件句柄。</param>
  815. /// <param name="value">与该控件关联的文本。</param>
  816. public static void SetText(IntPtr hWnd, string value)
  817. {
  818. if (GetIsHandleCreated(hWnd))
  819. return;
  820. UnsafeNativeMethods.SetWindowText(hWnd, value);
  821. }
  822. /// <summary>
  823. /// 将与此控件关联的文本重置为其默认值。
  824. /// </summary>
  825. /// <param name="hWnd">控件句柄。</param>
  826. public static void ResetText(IntPtr hWnd)
  827. {
  828. SetText(hWnd, string.Empty);
  829. }
  830. /// <summary>
  831. /// 向用户显示控件。
  832. /// </summary>
  833. /// <param name="hWnd">控件句柄。</param>
  834. public static void Show(IntPtr hWnd)
  835. {
  836. SetVisible(hWnd, true);
  837. }
  838. /// <summary>
  839. /// 对用户隐藏控件。
  840. /// </summary>
  841. /// <param name="hWnd">控件句柄。</param>
  842. public static void Hide(IntPtr hWnd)
  843. {
  844. SetVisible(hWnd, false);
  845. }
  846. /// <summary>
  847. /// 将控件带到 Z 顺序的前面。
  848. /// </summary>
  849. /// <param name="hWnd">控件句柄。</param>
  850. public static void BringToFront(IntPtr hWnd)
  851. {
  852. UnsafeNativeMethods.SetWindowPos(hWnd, NativeMethods.HWND_TOP, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE);
  853. }
  854. /// <summary>
  855. /// 将控件发送到 Z 顺序的后面。
  856. /// </summary>
  857. /// <param name="hWnd">控件句柄。</param>
  858. public static void SendToBack(IntPtr hWnd)
  859. {
  860. UnsafeNativeMethods.SetWindowPos(hWnd, NativeMethods.HWND_BOTTOM, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE);
  861. }
  862. /// <summary>
  863. /// 为控件设置输入焦点。
  864. /// </summary>
  865. /// <param name="hWnd">控件句柄。</param>
  866. /// <returns>如果输入焦点请求成功,则为 true;否则为 false。</returns>
  867. public static bool Focus(IntPtr hWnd)
  868. {
  869. if (GetCanFocus(hWnd))
  870. UnsafeNativeMethods.SetFocus(hWnd);
  871. return GetFocused(hWnd);
  872. }
  873. /// <summary>
  874. /// 为控件创建 System.Drawing.Graphics。
  875. /// </summary>
  876. /// <param name="hWnd">控件句柄。</param>
  877. /// <returns>控件的 System.Drawing.Graphics。</returns>
  878. public static Graphics CreateGraphics(IntPtr hWnd)
  879. {
  880. return Graphics.FromHwndInternal(hWnd);
  881. }
  882. /// <summary>
  883. /// 将指定屏幕点的位置计算成工作区坐标。
  884. /// </summary>
  885. /// <param name="hWnd">控件句柄。</param>
  886. /// <param name="p">要转换的屏幕坐标 System.Drawing.Point。</param>
  887. /// <returns>一个 System.Drawing.Point,它表示转换后的 System.Drawing.Point、p(以工作区坐标表示)。</returns>
  888. public static Point PointToClient(IntPtr hWnd, Point p)
  889. {
  890. NativeMethods.POINT pt = new NativeMethods.POINT(p.X, p.Y);
  891. UnsafeNativeMethods.MapWindowPoints(NativeMethods.HWND_DESKTOP, hWnd, ref pt, 1);
  892. return new Point(pt.x, pt.y);
  893. }
  894. /// <summary>
  895. /// 将指定工作区点的位置计算成屏幕坐标。
  896. /// </summary>
  897. /// <param name="hWnd">控件句柄。</param>
  898. /// <param name="p">要转换的工作区坐标 System.Drawing.Point。</param>
  899. /// <returns>一个 System.Drawing.Point,它表示转换后的 System.Drawing.Point、p(以屏幕坐标表示)。</returns>
  900. public static Point PointToScreen(IntPtr hWnd, Point p)
  901. {
  902. NativeMethods.POINT pt = new NativeMethods.POINT(p.X, p.Y);
  903. UnsafeNativeMethods.MapWindowPoints(hWnd, NativeMethods.HWND_DESKTOP, ref pt, 1);
  904. return new Point(pt.x, pt.y);
  905. }
  906. /// <summary>
  907. /// 计算指定屏幕矩形的大小和位置(以工作区坐标表示)。
  908. /// </summary>
  909. /// <param name="hWnd">控件句柄。</param>
  910. /// <param name="r">要转换的屏幕坐标 System.Drawing.Rectangle。</param>
  911. /// <returns>一个 System.Drawing.Rectangle,它表示转换后的 System.Drawing.Rectangle、r(以工作区坐标表示)。</returns>
  912. public static Rectangle RectangleToClient(IntPtr hWnd, Rectangle r)
  913. {
  914. NativeMethods.RECT rect = new NativeMethods.RECT(r);
  915. UnsafeNativeMethods.MapWindowPoints(NativeMethods.HWND_DESKTOP, hWnd, ref rect, 2);
  916. return rect.ToRectangle();
  917. }
  918. /// <summary>
  919. /// 计算指定工作区矩形的大小和位置(以屏幕坐标表示)。
  920. /// </summary>
  921. /// <param name="hWnd">控件句柄。</param>
  922. /// <param name="r">要转换的工作区坐标 System.Drawing.Rectangle。</param>
  923. /// <returns>一个 System.Drawing.Rectangle,它表示转换后的 System.Drawing.Rectangle、r(以屏幕坐标表示)。</returns>
  924. public static Rectangle RectangleToScreen(IntPtr hWnd, Rectangle r)
  925. {
  926. NativeMethods.RECT rect = new NativeMethods.RECT(r);
  927. UnsafeNativeMethods.MapWindowPoints(hWnd, NativeMethods.HWND_DESKTOP, ref rect, 2);
  928. return rect.ToRectangle();
  929. }
  930. /// <summary>
  931. /// 使控件的整个图面无效并导致重绘控件。
  932. /// </summary>
  933. /// <param name="hWnd">控件句柄。</param>
  934. public static void Invalidate(IntPtr hWnd)
  935. {
  936. Invalidate(hWnd, false);
  937. }
  938. /// <summary>
  939. /// 使控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向控件发送绘制消息。
  940. /// </summary>
  941. /// <param name="hWnd">控件句柄。</param>
  942. /// <param name="rc">一个 System.Drawing.Rectangle,表示要使之无效的区域。</param>
  943. public static void Invalidate(IntPtr hWnd, Rectangle rc)
  944. {
  945. Invalidate(hWnd, rc, false);
  946. }
  947. /// <summary>
  948. /// 使控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向控件发送绘制消息。
  949. /// </summary>
  950. /// <param name="hWnd">控件句柄。</param>
  951. /// <param name="region">要使之无效的 System.Drawing.Region。</param>
  952. public static void Invalidate(IntPtr hWnd, Region region)
  953. {
  954. Invalidate(hWnd, region, false);
  955. }
  956. /// <summary>
  957. /// 使控件的特定区域无效并向控件发送绘制消息。还可以使分配给该控件的子控件无效。
  958. /// </summary>
  959. /// <param name="hWnd">控件句柄。</param>
  960. /// <param name="invalidateChildren">若要使控件的子控件无效,则为 true;否则为 false。</param>
  961. public static void Invalidate(IntPtr hWnd, bool invalidateChildren)
  962. {
  963. if (GetIsHandleCreated(hWnd))
  964. {
  965. if (invalidateChildren)
  966. {
  967. UnsafeNativeMethods.RedrawWindow(hWnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RDW_ALLCHILDREN | NativeMethods.RDW_INVALIDATE);//.Net Framework :多NativeMethods.RDW_ERASE
  968. }
  969. else
  970. {
  971. UnsafeNativeMethods.InvalidateRect(hWnd, IntPtr.Zero, false);//.Net Framework :支持透明为true,否则false
  972. }
  973. }
  974. }
  975. /// <summary>
  976. /// 使控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向控件发送绘制消息。还可以使分配给该控件的子控件无效。
  977. /// </summary>
  978. /// <param name="hWnd">控件句柄。</param>
  979. /// <param name="rc">一个 System.Drawing.Rectangle,表示要使之无效的区域。</param>
  980. /// <param name="invalidateChildren">若要使控件的子控件无效,则为 true;否则为 false。</param>
  981. public static void Invalidate(IntPtr hWnd, Rectangle rc, bool invalidateChildren)
  982. {
  983. if (rc.IsEmpty)
  984. {
  985. Invalidate(hWnd, invalidateChildren);
  986. }
  987. else if (GetIsHandleCreated(hWnd))
  988. {
  989. if (invalidateChildren)
  990. {
  991. NativeMethods.RECT rcUpdate = NativeMethods.RECT.FromXYWH(rc.X, rc.Y, rc.Width, rc.Height);
  992. UnsafeNativeMethods.RedrawWindow(hWnd, ref rcUpdate, IntPtr.Zero, NativeMethods.RDW_ALLCHILDREN | NativeMethods.RDW_INVALIDATE);//.Net Framework :多NativeMethods.RDW_ERASE
  993. }
  994. else
  995. {
  996. NativeMethods.RECT rect = NativeMethods.RECT.FromXYWH(rc.X, rc.Y, rc.Width, rc.Height);
  997. UnsafeNativeMethods.InvalidateRect(hWnd, ref rect, false);//.Net Framework :支持透明为true,否则false
  998. }
  999. }
  1000. }
  1001. /// <summary>
  1002. /// 使控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向控件发送绘制消息。还可以使分配给该控件的子控件无效。
  1003. /// </summary>
  1004. /// <param name="hWnd">控件句柄。</param>
  1005. /// <param name="region">要使之无效的 System.Drawing.Region。</param>
  1006. /// <param name="invalidateChildren">若要使控件的子控件无效,则为 true;否则为 false。</param>
  1007. public static void Invalidate(IntPtr hWnd, Region region, bool invalidateChildren)
  1008. {
  1009. if (region == null)
  1010. {
  1011. Invalidate(hWnd, invalidateChildren);
  1012. }
  1013. else if (GetIsHandleCreated(hWnd))
  1014. {
  1015. IntPtr hRgn = GetHRgn(hWnd, region);
  1016. try
  1017. {
  1018. if (invalidateChildren)
  1019. {
  1020. UnsafeNativeMethods.RedrawWindow(hWnd, IntPtr.Zero, hRgn, NativeMethods.RDW_ALLCHILDREN | NativeMethods.RDW_INVALIDATE);//.Net Framework :多NativeMethods.RDW_ERASE
  1021. }
  1022. else
  1023. {
  1024. UnsafeNativeMethods.InvalidateRgn(hWnd, hRgn, false);//.Net Framework :支持透明为true,否则false
  1025. }
  1026. }
  1027. finally
  1028. {
  1029. UnsafeNativeMethods.DeleteObject(hRgn);
  1030. }
  1031. }
  1032. }
  1033. /// <summary>
  1034. /// 用当前大小和位置更新控件的边界。
  1035. /// </summary>
  1036. /// <param name="hWnd">控件句柄。</param>
  1037. public static void Update(IntPtr hWnd)
  1038. {
  1039. UnsafeNativeMethods.UpdateWindow(hWnd);
  1040. }
  1041. /// <summary>
  1042. /// 强制控件使其工作区无效并立即重绘自己和任何子控件。
  1043. /// </summary>
  1044. /// <param name="hWnd">控件句柄。</param>
  1045. public static void Refresh(IntPtr hWnd)
  1046. {
  1047. Invalidate(hWnd, true);
  1048. Update(hWnd);
  1049. }
  1050. #endregion
  1051. }
  1052. }