You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

835 lines
31 KiB

  1. using Apewer;
  2. using Apewer.Internals.Interop;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.IO;
  7. using System.Runtime.InteropServices;
  8. using System.Security;
  9. using System.Reflection;
  10. #if NETFX || NETCORE
  11. using System.Drawing.Drawing2D;
  12. using System.Drawing.Imaging;
  13. using System.Drawing.Text;
  14. using System.Windows.Forms;
  15. #endif
  16. namespace Apewer.Surface
  17. {
  18. /// <summary>窗体实用工具。</summary>
  19. [SecuritySafeCritical]
  20. public class FormsUtility
  21. {
  22. private const string FontYahei = "Microsoft Yahei";
  23. private const string FontSimsun = "Simsun";
  24. private static string _fontname = "";
  25. /// <summary>线程锁。</summary>
  26. public static object ThreadLocker = new object();
  27. /// <summary>存在微软雅黑字体。</summary>
  28. public static bool MsyhExist
  29. {
  30. get { return File.Exists("c:\\windows\\fonts\\msyh.ttc"); }
  31. }
  32. /// <summary>获取默认字体名称。</summary>
  33. public static string DefaultFontName
  34. {
  35. get
  36. {
  37. if (!string.IsNullOrEmpty(_fontname)) return _fontname;
  38. try
  39. {
  40. if (File.Exists("c:\\windows\\fonts\\msyh.ttc")) return FontYahei;
  41. else return FontSimsun;
  42. }
  43. catch { return FontSimsun; }
  44. }
  45. }
  46. /// <summary>获取所有可枚举的颜色。</summary>
  47. public static Color[] EnumerableColor
  48. {
  49. get
  50. {
  51. var list = new List<Color>();
  52. list.Add(Color.AliceBlue);
  53. list.Add(Color.AntiqueWhite);
  54. list.Add(Color.Aqua);
  55. list.Add(Color.Aquamarine);
  56. list.Add(Color.Azure);
  57. list.Add(Color.Beige);
  58. list.Add(Color.Bisque);
  59. list.Add(Color.Black);
  60. list.Add(Color.BlanchedAlmond);
  61. list.Add(Color.Blue);
  62. list.Add(Color.BlueViolet);
  63. list.Add(Color.Brown);
  64. list.Add(Color.BurlyWood);
  65. list.Add(Color.CadetBlue);
  66. list.Add(Color.Chartreuse);
  67. list.Add(Color.Chocolate);
  68. list.Add(Color.Coral);
  69. list.Add(Color.CornflowerBlue);
  70. list.Add(Color.Cornsilk);
  71. list.Add(Color.Crimson);
  72. list.Add(Color.Cyan);
  73. list.Add(Color.DarkBlue);
  74. list.Add(Color.DarkCyan);
  75. list.Add(Color.DarkGoldenrod);
  76. list.Add(Color.DarkGray);
  77. list.Add(Color.DarkGreen);
  78. list.Add(Color.DarkKhaki);
  79. list.Add(Color.DarkMagenta);
  80. list.Add(Color.DarkOliveGreen);
  81. list.Add(Color.DarkOrange);
  82. list.Add(Color.DarkOrchid);
  83. list.Add(Color.DarkRed);
  84. list.Add(Color.DarkSalmon);
  85. list.Add(Color.DarkSeaGreen);
  86. list.Add(Color.DarkSlateBlue);
  87. list.Add(Color.DarkSlateGray);
  88. list.Add(Color.DarkTurquoise);
  89. list.Add(Color.DarkViolet);
  90. list.Add(Color.DeepPink);
  91. list.Add(Color.DeepSkyBlue);
  92. list.Add(Color.DimGray);
  93. list.Add(Color.DodgerBlue);
  94. list.Add(Color.Firebrick);
  95. list.Add(Color.FloralWhite);
  96. list.Add(Color.ForestGreen);
  97. list.Add(Color.Fuchsia);
  98. list.Add(Color.Gainsboro);
  99. list.Add(Color.GhostWhite);
  100. list.Add(Color.Gold);
  101. list.Add(Color.Goldenrod);
  102. list.Add(Color.Gray);
  103. list.Add(Color.Green);
  104. list.Add(Color.GreenYellow);
  105. list.Add(Color.Honeydew);
  106. list.Add(Color.HotPink);
  107. list.Add(Color.IndianRed);
  108. list.Add(Color.Indigo);
  109. list.Add(Color.Ivory);
  110. list.Add(Color.Khaki);
  111. list.Add(Color.Lavender);
  112. list.Add(Color.LavenderBlush);
  113. list.Add(Color.LawnGreen);
  114. list.Add(Color.LemonChiffon);
  115. list.Add(Color.LightBlue);
  116. list.Add(Color.LightCoral);
  117. list.Add(Color.LightCyan);
  118. list.Add(Color.LightGoldenrodYellow);
  119. list.Add(Color.LightGray);
  120. list.Add(Color.LightGreen);
  121. list.Add(Color.LightPink);
  122. list.Add(Color.LightSalmon);
  123. list.Add(Color.LightSeaGreen);
  124. list.Add(Color.LightSkyBlue);
  125. list.Add(Color.LightSlateGray);
  126. list.Add(Color.LightSteelBlue);
  127. list.Add(Color.LightYellow);
  128. list.Add(Color.Lime);
  129. list.Add(Color.LimeGreen);
  130. list.Add(Color.Linen);
  131. list.Add(Color.Magenta);
  132. list.Add(Color.Maroon);
  133. list.Add(Color.MediumAquamarine);
  134. list.Add(Color.MediumBlue);
  135. list.Add(Color.MediumOrchid);
  136. list.Add(Color.MediumPurple);
  137. list.Add(Color.MediumSeaGreen);
  138. list.Add(Color.MediumSlateBlue);
  139. list.Add(Color.MediumSpringGreen);
  140. list.Add(Color.MediumTurquoise);
  141. list.Add(Color.MediumVioletRed);
  142. list.Add(Color.MidnightBlue);
  143. list.Add(Color.MintCream);
  144. list.Add(Color.MistyRose);
  145. list.Add(Color.Moccasin);
  146. list.Add(Color.NavajoWhite);
  147. list.Add(Color.Navy);
  148. list.Add(Color.OldLace);
  149. list.Add(Color.Olive);
  150. list.Add(Color.OliveDrab);
  151. list.Add(Color.Orange);
  152. list.Add(Color.OrangeRed);
  153. list.Add(Color.Orchid);
  154. list.Add(Color.PaleGoldenrod);
  155. list.Add(Color.PaleGreen);
  156. list.Add(Color.PaleTurquoise);
  157. list.Add(Color.PaleVioletRed);
  158. list.Add(Color.PapayaWhip);
  159. list.Add(Color.PeachPuff);
  160. list.Add(Color.Peru);
  161. list.Add(Color.Pink);
  162. list.Add(Color.Plum);
  163. list.Add(Color.PowderBlue);
  164. list.Add(Color.Purple);
  165. list.Add(Color.Red);
  166. list.Add(Color.RosyBrown);
  167. list.Add(Color.RoyalBlue);
  168. list.Add(Color.SaddleBrown);
  169. list.Add(Color.Salmon);
  170. list.Add(Color.SandyBrown);
  171. list.Add(Color.SeaGreen);
  172. list.Add(Color.SeaShell);
  173. list.Add(Color.Sienna);
  174. list.Add(Color.Silver);
  175. list.Add(Color.SkyBlue);
  176. list.Add(Color.SlateBlue);
  177. list.Add(Color.SlateGray);
  178. list.Add(Color.Snow);
  179. list.Add(Color.SpringGreen);
  180. list.Add(Color.SteelBlue);
  181. list.Add(Color.Tan);
  182. list.Add(Color.Teal);
  183. list.Add(Color.Thistle);
  184. list.Add(Color.Tomato);
  185. //list.Add(Color.Transparent);
  186. list.Add(Color.Turquoise);
  187. list.Add(Color.Violet);
  188. list.Add(Color.Wheat);
  189. list.Add(Color.White);
  190. list.Add(Color.WhiteSmoke);
  191. list.Add(Color.Yellow);
  192. list.Add(Color.YellowGreen);
  193. return list.ToArray();
  194. }
  195. }
  196. /// <summary>用于填充背景色。</summary>
  197. public static Color GraceWall { get { return Color.FromArgb(0xff, 0xf7, 0xf7, 0xf7); } }
  198. /// <summary>用于控件边框。</summary>
  199. public static Color GraceBorder { get { return Color.FromArgb(0xff, 0xdf, 0xdf, 0xdf); } }
  200. /// <summary>用于无效的文本、备注文本。</summary>
  201. public static Color GraceLocked { get { return Color.FromArgb(0xff, 0x7f, 0x7f, 0x7f); } }
  202. /// <summary>用于次级文本。</summary>
  203. public static Color GraceMinor { get { return Color.FromArgb(0xff, 0x3f, 0x3f, 0x3f); } }
  204. /// <summary>用于焦点状态的控件边框。</summary>
  205. public static Color GraceSilver { get { return Color.FromArgb(0xff, 0xbf, 0xbf, 0xbf); } }
  206. /// <summary>系统定义的颜色。</summary>
  207. public static Color Transparent { get { return Color.Transparent; } }
  208. /// <summary>系统定义的颜色。</summary>
  209. public static Color Black { get { return Color.Black; } }
  210. /// <summary>系统定义的颜色。</summary>
  211. public static Color White { get { return Color.White; } }
  212. /// <summary>系统定义的颜色。</summary>
  213. public static Color Gray { get { return Color.Gray; } }
  214. /// <summary>系统定义的颜色。</summary>
  215. public static Color DarkGray { get { return Color.DarkGray; } }
  216. /// <summary>系统定义的颜色。</summary>
  217. public static Color LightGray { get { return Color.LightGray; } }
  218. /// <summary>系统定义的颜色。</summary>
  219. public static Color Red { get { return Color.Red; } }
  220. /// <summary>系统定义的颜色。</summary>
  221. public static Color Green { get { return Color.Green; } }
  222. /// <summary>系统定义的颜色。</summary>
  223. public static Color Blue { get { return Color.Blue; } }
  224. /// <summary>系统定义的颜色。</summary>
  225. public static Color Orange { get { return Color.DarkOrange; } }
  226. /// <summary>系统定义的颜色。</summary>
  227. public static Color Purple { get { return Color.Purple; } }
  228. /// <summary>随机主题色。</summary>
  229. public static Color RandomColor
  230. {
  231. get { var colors = EnumerableColor; return colors[NumberUtility.RandomInteger(colors.Length - 1)]; }
  232. }
  233. /// <summary>计算 Alpha 合成颜色(基色),基色均需计算。</summary>
  234. /// <param name="alpha">前景色 Alpha 值。</param>
  235. /// <param name="back">背景色(基色)。</param>
  236. /// <param name="fore">前景色(基色)。</param>
  237. /// <param name="depth">颜色深度,最大值。</param>
  238. /// <returns>合成后的颜色(基色)。</returns>
  239. public static int AlphaColor(int alpha, int fore, int back, int depth = 255)
  240. {
  241. int b = back, f = fore;
  242. if (b > depth) b = depth; if (b < 0) b = 0;
  243. if (f > depth) f = depth; if (f < 0) f = 0;
  244. int v = fore * alpha / depth + back * (depth - alpha) / depth;
  245. if (v > depth) v = depth; if (v < 0) v = 0;
  246. return v;
  247. }
  248. /// <summary>从程序集获取资源。发生错误时返回 NULL 值,不引发异常。</summary>
  249. public static Stream OpenResourceStream(string name, Assembly assembly = null)
  250. {
  251. var stream = null as Stream;
  252. try
  253. {
  254. if (assembly == null) assembly = Assembly.GetCallingAssembly();
  255. stream = assembly.GetManifestResourceStream(name);
  256. }
  257. catch { }
  258. return null;
  259. }
  260. /// <summary>从程序集获取资源,读取到内存流。发生错误时返回 NULL 值,不引发异常。</summary>
  261. public static MemoryStream GetResourceStream(string name, Assembly assembly = null)
  262. {
  263. var stream = OpenResourceStream(name, assembly);
  264. if (stream == null) return null;
  265. var memory = new MemoryStream();
  266. BinaryUtility.Read(stream, memory);
  267. stream.Dispose();
  268. memory.ResetPosition();
  269. return memory;
  270. }
  271. /// <summary>从程序集获取资源,读取到内存流。发生错误时返回 NULL 值,不引发异常。</summary>
  272. public static byte[] GetResource(string name, Assembly assembly = null)
  273. {
  274. var stream = OpenResourceStream(name, assembly);
  275. if (stream == null) return null;
  276. var bytes = BinaryUtility.Read(stream);
  277. stream.Dispose();
  278. return bytes;
  279. }
  280. #if NETFX || NETCORE
  281. /// <summary>获取默认字体。</summary>
  282. public static Font DefaultFont
  283. {
  284. get { return new Font(DefaultFontName, 9); }
  285. }
  286. /// <summary>获取大小为 9 的默认字体。</summary>
  287. public static Font NewFont()
  288. {
  289. return new Font(DefaultFontName, 9);
  290. }
  291. /// <summary>获取指定大小的默认字体。</summary>
  292. public static Font NewFont(float size)
  293. {
  294. return new Font(DefaultFontName, size);
  295. }
  296. /// <summary>获取指定大小的默认字体。</summary>
  297. public static Font NewFont(float size, bool bold)
  298. {
  299. return new Font(DefaultFontName, size, bold ? FontStyle.Bold : FontStyle.Regular);
  300. }
  301. /// <summary>窗体启动初始化。</summary>
  302. [STAThread]
  303. public static void StartInitialization()
  304. {
  305. Control.CheckForIllegalCrossThreadCalls = false;
  306. Application.EnableVisualStyles();
  307. Application.SetCompatibleTextRenderingDefault(false);
  308. }
  309. /// <summary>禁用跨线程调用检查。</summary>
  310. public static void CrossThread()
  311. {
  312. Control.CheckForIllegalCrossThreadCalls = false;
  313. }
  314. /// <summary>移动窗体。</summary>
  315. public static void MoveForm(Form form)
  316. {
  317. if (form != null) MoveForm(form.Handle);
  318. }
  319. /// <summary>移动窗体。</summary>
  320. public static void MoveForm(IntPtr form)
  321. {
  322. User32.ReleaseCapture();
  323. User32.SendMessage(form, 0x112, new IntPtr(Constant.SC_MOVE + 2), new IntPtr(0));
  324. }
  325. /// <summary>启用鼠标穿透。</summary>
  326. public static void MousePenetration(Form form)
  327. {
  328. if (form != null) MousePenetration(form.Handle);
  329. }
  330. /// <summary>启用鼠标穿透。</summary>
  331. public static void MousePenetration(IntPtr form)
  332. {
  333. int intExTemp = User32.GetWindowLong(form, Constant.GWL_EXSTYLE);
  334. int oldGWLEx = User32.SetWindowLong(form, Constant.GWL_EXSTYLE, Constant.WS_EX_TRANSPARENT | Constant.WS_EX_LAYERED);
  335. }
  336. /// <summary>绘制内边框。</summary>
  337. /// <param name="image">源图像。</param>
  338. /// <param name="border">边框颜色。</param>
  339. public static bool PaintBorder(ref Image image, Color border)
  340. {
  341. if (image != null)
  342. {
  343. var g = Graphics.FromImage(image);
  344. var p = new Pen(border);
  345. g.DrawRectangle(p, 0, 0, image.Width - 1, image.Height - 1);
  346. p.Dispose();
  347. g.Dispose();
  348. return true;
  349. }
  350. else return false;
  351. }
  352. /// <summary>绘制内边框。</summary>
  353. /// <param name="image">源图像。</param>
  354. /// <param name="border">边框颜色。</param>
  355. public static bool PaintBorder(ref Bitmap image, Color border)
  356. {
  357. if (image != null)
  358. {
  359. var g = Graphics.FromImage(image);
  360. var p = new Pen(border);
  361. g.DrawRectangle(p, 0, 0, image.Width - 1, image.Height - 1);
  362. p.Dispose();
  363. g.Dispose();
  364. return true;
  365. }
  366. else return false;
  367. }
  368. /// <summary>绘制内边框。</summary>
  369. /// <param name="image">源图像。</param>
  370. /// <param name="border">边框颜色。</param>
  371. /// <param name="wall">背景颜色。</param>
  372. public static bool PaintBorder(ref Image image, Color border, Color wall)
  373. {
  374. if (image != null)
  375. {
  376. var g = Graphics.FromImage(image);
  377. var p = new Pen(border);
  378. g.Clear(wall);
  379. g.DrawRectangle(p, 0, 0, image.Width - 1, image.Height - 1);
  380. p.Dispose();
  381. g.Dispose();
  382. return true;
  383. }
  384. else return false;
  385. }
  386. /// <summary>建立带有圆角样式的路径。</summary>
  387. /// <param name="rect">建立矩形路径的区域。</param>
  388. /// <param name="radius">圆角的大小。</param>
  389. /// <returns>建立的路径。</returns>
  390. public static GraphicsPath CreatePath(Rectangle rect, int radius = 0)
  391. {
  392. GraphicsPath path = new GraphicsPath();
  393. int r = (radius < 0) ? 0 : radius;
  394. switch (r)
  395. {
  396. case 0:
  397. path.AddRectangle(rect);
  398. break;
  399. default:
  400. path.AddArc(rect.X, rect.Y, r, r, 180, 90);
  401. path.AddArc(rect.Right - r - 1, rect.Y, r, r, 270, 90);
  402. path.AddArc(rect.Right - r - 1, rect.Bottom - r - 1, r, r, 0, 90);
  403. path.AddArc(rect.X, rect.Bottom - r - 1, r, r, 90, 90);
  404. break;
  405. }
  406. path.CloseFigure();
  407. return path;
  408. }
  409. /// <summary>恢复任务栏中窗体标题的右键菜单。</summary>
  410. public static void SetTaskMenu(Form form)
  411. {
  412. if (form != null)
  413. {
  414. var hwnd = form.Handle;
  415. var href = new HandleRef(form, hwnd);
  416. int windowLong = (User32.GetWindowLong(hwnd, -16));
  417. User32.SetWindowLong(hwnd, -16, windowLong | Constant.WS_SYSMENU | Constant.WS_MINIMIZEBOX);
  418. }
  419. }
  420. /// <summary>在主界面中移动控件,由目标控件取代当前控件,形成切换控件的动画。</summary>
  421. /// <param name="current">当前显示的控件。</param>
  422. /// <param name="target">将要显示的目标控件。</param>
  423. public static void AnimateGoPanel(Control current, Control target)
  424. {
  425. AnimateGoPanel(current.Location, current.Size, 0, 10, current, target, true);
  426. }
  427. /// <summary>在主界面中移动控件,由目标控件取代当前控件,形成切换控件的动画。</summary>
  428. /// <param name="current">当前显示的控件。</param>
  429. /// <param name="target">将要显示的目标控件。</param>
  430. /// <param name="next">向左移动。</param>
  431. public static void AnimateGoPanel(Control current, Control target, bool next)
  432. {
  433. AnimateGoPanel(current.Location, current.Size, 0, 10, current, target, next);
  434. }
  435. /// <summary>在主界面中移动控件,由目标控件取代当前控件,形成切换控件的动画。</summary>
  436. /// <param name="point">控件左上角坐标。</param>
  437. /// <param name="size">控件大小。</param>
  438. /// <param name="span">当前控件和目标控件的间距,若值小于 0 则更正为 0 。</param>
  439. /// <param name="frame">移动的次数,若值小于 0 则更正为 20。</param>
  440. /// <param name="current">当前显示的控件。</param>
  441. /// <param name="target">将要显示的目标控件。</param>
  442. /// <param name="next">向左移动。</param>
  443. public static void AnimateGoPanel(System.Drawing.Point point, System.Drawing.Size size, int span, int frame, Control current, Control target, bool next = true)
  444. {
  445. int s = (span < 0) ? span : 0;
  446. int step = (current.Width + s) / ((frame < 1) ? 20 : frame);
  447. int x = point.X;
  448. int y = point.Y;
  449. current.Size = size;
  450. target.Size = size;
  451. current.Location = point;
  452. if (next)
  453. {
  454. target.Location = new System.Drawing.Point(size.Width, point.Y);
  455. current.Visible = true;
  456. target.Visible = true;
  457. Application.DoEvents();
  458. while (target.Left > x)
  459. {
  460. s = ((target.Left - x) < step) ? (target.Left - x) : step;
  461. target.Left -= s;
  462. current.Left -= s;
  463. Application.DoEvents();
  464. System.Threading.Thread.Sleep(1);
  465. }
  466. }
  467. else
  468. {
  469. target.Location = new System.Drawing.Point(x - size.Width, x);
  470. current.Visible = true;
  471. target.Visible = true;
  472. Application.DoEvents();
  473. while (target.Left < x)
  474. {
  475. s = ((x - target.Left) < step) ? x - target.Left : step;
  476. target.Left += s;
  477. current.Left += s;
  478. Application.DoEvents();
  479. System.Threading.Thread.Sleep(1);
  480. }
  481. }
  482. current.Visible = false;
  483. }
  484. /// <summary>将窗体最大化,不覆盖任务栏。</summary>
  485. /// <param name="form">窗体。</param>
  486. public static void ToMaximum(Form form)
  487. {
  488. if (form != null)
  489. {
  490. var s = Screen.FromControl(form);
  491. var r = s.WorkingArea;
  492. if ((form.MaximumSize.Width < r.Width) || (form.MaximumSize.Height < r.Height))
  493. {
  494. form.MaximumSize = r.Size;
  495. }
  496. form.Location = r.Location;
  497. form.Size = r.Size;
  498. }
  499. }
  500. /// <summary>用指定图像绘制窗体,窗体与图像的大小必须一致。</summary>
  501. /// <param name="form">要绘制的窗体。</param>
  502. /// <param name="image">要使用的图像。</param>
  503. public static void UpdateShadow(Form form, Image image)
  504. {
  505. if ((form != null) && (image != null))
  506. {
  507. Bitmap vbitmap;
  508. if ((form.Width != image.Width) || (form.Height != image.Height))
  509. {
  510. vbitmap = new Bitmap(image.GetThumbnailImage(form.Width, form.Height, null, IntPtr.Zero));
  511. }
  512. else
  513. {
  514. vbitmap = new Bitmap(image);
  515. }
  516. var screendc = User32.GetDC(IntPtr.Zero);
  517. var location = new Internals.Interop.Point(form.Left, form.Top);
  518. var size = new Internals.Interop.Size(form.Width, form.Height);
  519. var compatibledc = Gdi32.CreateCompatibleDC(screendc);
  520. var handle = vbitmap.GetHbitmap(Color.FromArgb(0));
  521. var oldbitmap = Gdi32.SelectObject(compatibledc, handle);
  522. var srcloc = new Internals.Interop.Point(0, 0);
  523. var blendfunction = new BlendFunction();
  524. blendfunction.blendop = Constant.AC_SRC_OVER;
  525. blendfunction.sourceconstantalpha = byte.Parse("255");
  526. blendfunction.alphaformat = Constant.AC_SRC_ALPHA;
  527. blendfunction.blendflags = 0;
  528. User32.UpdateLayeredWindow(form.Handle, screendc, ref location, ref size, compatibledc, ref srcloc, 0, ref blendfunction, Constant.ULW_ALPHA);
  529. if (handle != IntPtr.Zero)
  530. {
  531. Gdi32.SelectObject(compatibledc, oldbitmap);
  532. Gdi32.DeleteObject(handle);
  533. }
  534. User32.ReleaseDC(IntPtr.Zero, screendc);
  535. Gdi32.DeleteDC(compatibledc);
  536. }
  537. }
  538. /// <summary>为窗体启用阴影。</summary>
  539. /// <param name="form">要启用阴影的窗体。</param>
  540. public static void EnableShadow(Form form)
  541. {
  542. if (form == null) return;
  543. int vformclass = User32.GetClassLong(form.Handle, Constant.GCL_STYLE);
  544. User32.SetClassLong(form.Handle, Constant.GCL_STYLE, vformclass | Constant.CS_DROPSHADOW);
  545. }
  546. /// <summary>获取屏幕的截图。</summary>
  547. public static Bitmap[] ScreenShot()
  548. {
  549. var list = new List<Bitmap>();
  550. var all = Screen.AllScreens;
  551. foreach (var screen in all)
  552. {
  553. int vw = screen.Bounds.Width;
  554. int vh = screen.Bounds.Height;
  555. int vd = screen.BitsPerPixel;
  556. Bitmap b = new Bitmap(vw, vh, PixelFormat.Format32bppArgb);
  557. Graphics g = Graphics.FromImage(b);
  558. g.CopyFromScreen(0, 0, 0, 0, new System.Drawing.Size(vw, vh));
  559. g.Dispose();
  560. list.Add(b);
  561. }
  562. return list.ToArray();
  563. }
  564. /// <summary>获取指定屏幕的截图。</summary>
  565. /// <param name="screen">屏幕号。</param>
  566. internal static Bitmap ScreenShot(int screen)
  567. {
  568. var a = Screen.AllScreens;
  569. if ((a.Length > 0) && (screen >= 0) && (screen < a.Length))
  570. {
  571. try
  572. {
  573. int w = a[screen].Bounds.Width;
  574. int h = a[screen].Bounds.Height;
  575. int d = a[screen].BitsPerPixel;
  576. Bitmap b = new Bitmap(w, h, PixelFormat.Format32bppArgb);
  577. Graphics g = Graphics.FromImage(b);
  578. g.CopyFromScreen(0, 0, 0, 0, new System.Drawing.Size(w, h));
  579. g.Dispose();
  580. return b;
  581. }
  582. catch { }
  583. }
  584. return new Bitmap(0, 0, PixelFormat.Format32bppArgb);
  585. }
  586. /// <summary>获取指定屏幕的截图。</summary>
  587. /// <param name="screen">屏幕,若为 Null 则选择主屏幕。</param>
  588. internal static Bitmap ScreenShot(Screen screen)
  589. {
  590. if (screen == null)
  591. {
  592. try
  593. {
  594. int w = Screen.PrimaryScreen.Bounds.Width;
  595. int h = Screen.PrimaryScreen.Bounds.Height;
  596. int d = Screen.PrimaryScreen.BitsPerPixel;
  597. Bitmap b = new Bitmap(w, h, PixelFormat.Format32bppArgb);
  598. Graphics g = Graphics.FromImage(b);
  599. g.CopyFromScreen(0, 0, 0, 0, new System.Drawing.Size(w, h));
  600. g.Dispose();
  601. return b;
  602. }
  603. catch { }
  604. }
  605. return new Bitmap(0, 0, PixelFormat.Format32bppArgb);
  606. }
  607. /// <summary></summary>
  608. /// <param name="location"></param>
  609. /// <param name="size"></param>
  610. /// <param name="radius"></param>
  611. /// <returns></returns>
  612. public static GraphicsPath GetRadiusPath(PointF location, SizeF size, float radius)
  613. {
  614. var loc = location;
  615. var rds = Math.Abs(radius);
  616. var path = new GraphicsPath();
  617. float x, y, r;
  618. r = rds * 2;
  619. // 左上角。
  620. x = loc.X;
  621. y = loc.Y;
  622. path.AddArc(x, y, r, r, 180, 90);
  623. // 右上角。
  624. x = loc.X + size.Width - rds * 2;
  625. y = loc.Y;
  626. path.AddArc(x, y, r, r, 270, 90);
  627. // 左下角。
  628. x = loc.X;
  629. y = loc.Y + size.Height - rds * 2;
  630. path.AddArc(x, y, r, r, 0, 90);
  631. // 右下角。
  632. x = loc.X + size.Width - rds * 2;
  633. y = loc.Y + size.Height - rds * 2;
  634. path.AddArc(x, y, r, r, 90, 90);
  635. // 边框直线:上、下、左、右。
  636. path.AddLine((float)(loc.X + rds), (float)loc.Y, (float)(loc.X + size.Width - rds), (float)loc.Y);
  637. path.AddLine((float)(loc.X + rds), (float)(loc.Y + size.Height), (float)(loc.X + size.Width - rds), (float)(loc.Y + size.Height));
  638. path.AddLine((float)loc.X, (float)(loc.Y + rds), (float)loc.X, (float)(loc.Y + size.Height - rds));
  639. path.AddLine((float)(loc.X + size.Width), (float)(loc.Y + rds), (float)(loc.X + size.Width), (float)(loc.Y + size.Height - rds));
  640. return path;
  641. }
  642. /// <summary>从文件加载字体,并获取字体。</summary>
  643. public static FontFamily LoadFont(string path)
  644. {
  645. if (!File.Exists(path)) return null;
  646. var vpfc = new PrivateFontCollection();
  647. vpfc.AddFontFile(path);
  648. var vff = vpfc.Families[0];
  649. return vff;
  650. }
  651. /// <summary></summary>
  652. public static void Invoke(Control control, Action action, bool async = false)
  653. {
  654. if (control == null || action == null) return;
  655. // control.Invoke(action);
  656. if (async)
  657. {
  658. control.BeginInvoke(new Action(delegate ()
  659. {
  660. action.Invoke();
  661. }));
  662. }
  663. else
  664. {
  665. control.Invoke(new Action(delegate ()
  666. {
  667. action.Invoke();
  668. }));
  669. }
  670. }
  671. /// <summary></summary>
  672. public static void BeginInvoke(Control control, Action action)
  673. {
  674. if (control == null || action == null) return;
  675. control.BeginInvoke(new Action(delegate ()
  676. {
  677. action.Invoke();
  678. }));
  679. }
  680. /// <summary>设置窗体置顶。</summary>
  681. public static void SetTopMost(IntPtr form, bool value = true)
  682. {
  683. if (form == null || form == IntPtr.Zero) return;
  684. User32.SetWindowPos(form, new IntPtr(value ? -1 : -2), 0, 0, 0, 0, 3);
  685. }
  686. /// <summary>设置窗体置顶。</summary>
  687. public static void SetTopMost(Form form, bool value = true)
  688. {
  689. if (form != null) SetTopMost(form.Handle, value);
  690. }
  691. /// <summary>获取指定文件中的图标总数。</summary>
  692. public static int GetIconsCount(string path)
  693. {
  694. if (!File.Exists(path)) return 0;
  695. var count = User32.PrivateExtractIcons(path, 0, 0, 0, null, null, 0, 0);
  696. return count;
  697. }
  698. /// <summary>获取指定文件中的图标。</summary>
  699. public static Bitmap[] GetIconsBitmap(string path = null, int size = 256)
  700. {
  701. if (string.IsNullOrEmpty(path)) path = Application.ExecutablePath;
  702. if (!File.Exists(path)) return null;
  703. var count = User32.PrivateExtractIcons(path, 0, 0, 0, null, null, 0, 0);
  704. var ptrs = new IntPtr[count];
  705. var ids = new int[count];
  706. var succeed = User32.PrivateExtractIcons(path, 0, size, size, ptrs, ids, count, 0);
  707. var images = new Bitmap[count];
  708. for (var i = 0; i < succeed; i++)
  709. {
  710. if (ptrs[i] == IntPtr.Zero) continue;
  711. using (var icon = Icon.FromHandle(ptrs[i]))
  712. {
  713. var bitmap = icon.ToBitmap();
  714. images[i] = bitmap;
  715. }
  716. User32.DestroyIcon(ptrs[i]);
  717. }
  718. return images;
  719. }
  720. /// <summary>从文件获取图标。</summary>
  721. public static Icon GetExecutableIcon(string path)
  722. {
  723. try { return Icon.ExtractAssociatedIcon(path); }
  724. catch { return null; }
  725. }
  726. #endif
  727. }
  728. }