ComboBoxEx.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using System.IO;
  6. using System.Drawing;
  7. using System.Drawing.Drawing2D;
  8. using System.ComponentModel;
  9. using System.Runtime.InteropServices;
  10. namespace LYFZ.ComponentLibrary
  11. {
  12. public class ComboBoxEx : System.Windows.Forms.ComboBox
  13. {
  14. #region Fields
  15. private IntPtr _editHandle;
  16. private ControlState _buttonState;
  17. private Color _baseColor = Color.FromArgb(51, 161, 224);
  18. private Color _borderColor = Color.FromArgb(51, 161, 224);
  19. private Color _arrowColor = Color.FromArgb(19, 88, 128);
  20. private bool _bPainting;
  21. #endregion
  22. #region Constructors
  23. public ComboBoxEx()
  24. : base()
  25. {
  26. SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
  27. this.Font = new Font("宋体",10.5f,GraphicsUnit.Point);
  28. }
  29. #endregion
  30. #region Properties
  31. [DefaultValue(typeof(Color), "51, 161, 224")]
  32. public Color BaseColor
  33. {
  34. get { return _baseColor; }
  35. set
  36. {
  37. if (_baseColor != value)
  38. {
  39. _baseColor = value;
  40. base.Invalidate();
  41. }
  42. }
  43. }
  44. [DefaultValue(typeof(Color), "51, 161, 224")]
  45. public Color BorderColor
  46. {
  47. get { return _borderColor; }
  48. set
  49. {
  50. if (_borderColor != value)
  51. {
  52. _borderColor = value;
  53. base.Invalidate();
  54. }
  55. }
  56. }
  57. [DefaultValue(typeof(Color), "19, 88, 128")]
  58. public Color ArrowColor
  59. {
  60. get { return _arrowColor; }
  61. set
  62. {
  63. if (_arrowColor != value)
  64. {
  65. _arrowColor = value;
  66. base.Invalidate();
  67. }
  68. }
  69. }
  70. internal ControlState ButtonState
  71. {
  72. get { return _buttonState; }
  73. set
  74. {
  75. if (_buttonState != value)
  76. {
  77. _buttonState = value;
  78. Invalidate(ButtonRect);
  79. }
  80. }
  81. }
  82. internal Rectangle ButtonRect
  83. {
  84. get
  85. {
  86. return GetDropDownButtonRect();
  87. }
  88. }
  89. internal bool ButtonPressed
  90. {
  91. get
  92. {
  93. if (IsHandleCreated)
  94. {
  95. return GetComboBoxButtonPressed();
  96. }
  97. return false;
  98. }
  99. }
  100. internal IntPtr EditHandle
  101. {
  102. get { return _editHandle; }
  103. }
  104. bool isCustomColor = false;
  105. /// <summary>
  106. ///
  107. /// </summary>
  108. [DescriptionAttribute("设置是否可以自定义下拉框颜色"), CategoryAttribute("组件扩展属性")]
  109. public bool IsCustomColor
  110. {
  111. get { return isCustomColor; }
  112. set { isCustomColor = value; Invalidate(false); }
  113. }
  114. internal Rectangle EditRect
  115. {
  116. get
  117. {
  118. if (DropDownStyle == ComboBoxStyle.DropDownList)
  119. {
  120. Rectangle rect = new Rectangle(
  121. 3, 3, Width - ButtonRect.Width - 6, Height - 6);
  122. if (RightToLeft == RightToLeft.Yes)
  123. {
  124. rect.X += ButtonRect.Right;
  125. }
  126. return rect;
  127. }
  128. if (IsHandleCreated && EditHandle != IntPtr.Zero)
  129. {
  130. NativeMethods.RECT rcClient = new NativeMethods.RECT();
  131. NativeMethods.GetWindowRect(EditHandle, ref rcClient);
  132. return RectangleToClient(rcClient.Rect);
  133. }
  134. return Rectangle.Empty;
  135. }
  136. }
  137. #endregion
  138. #region Override Methods
  139. protected override void OnCreateControl()
  140. {
  141. base.OnCreateControl();
  142. NativeMethods.ComboBoxInfo cbi = GetComboBoxInfo();
  143. _editHandle = cbi.hwndEdit;
  144. }
  145. protected override void OnMouseMove(MouseEventArgs e)
  146. {
  147. base.OnMouseMove(e);
  148. Point point = e.Location;
  149. if (ButtonRect.Contains(point))
  150. {
  151. ButtonState = ControlState.Hover;
  152. }
  153. else
  154. {
  155. ButtonState = ControlState.Normal;
  156. }
  157. }
  158. protected override void OnMouseEnter(EventArgs e)
  159. {
  160. base.OnMouseEnter(e);
  161. Point point = PointToClient(Cursor.Position);
  162. if (ButtonRect.Contains(point))
  163. {
  164. ButtonState = ControlState.Hover;
  165. }
  166. }
  167. protected override void OnMouseLeave(EventArgs e)
  168. {
  169. base.OnMouseLeave(e);
  170. ButtonState = ControlState.Normal;
  171. }
  172. protected override void OnMouseUp(MouseEventArgs e)
  173. {
  174. base.OnMouseUp(e);
  175. ButtonState = ControlState.Normal;
  176. }
  177. protected override void WndProc(ref Message m)
  178. {
  179. switch (m.Msg)
  180. {
  181. case NativeMethods.WM_PAINT:
  182. WmPaint(ref m);
  183. break;
  184. default:
  185. base.WndProc(ref m);
  186. break;
  187. }
  188. }
  189. #endregion
  190. #region Windows Message Methods
  191. private void WmPaint(ref Message m)
  192. {
  193. if (base.DropDownStyle == ComboBoxStyle.Simple)
  194. {
  195. base.WndProc(ref m);
  196. return;
  197. }
  198. if (base.DropDownStyle == ComboBoxStyle.DropDown)
  199. {
  200. if (!_bPainting)
  201. {
  202. NativeMethods.PAINTSTRUCT ps =
  203. new NativeMethods.PAINTSTRUCT();
  204. _bPainting = true;
  205. NativeMethods.BeginPaint(m.HWnd, ref ps);
  206. RenderComboBox(ref m);
  207. NativeMethods.EndPaint(m.HWnd, ref ps);
  208. _bPainting = false;
  209. m.Result = NativeMethods.TRUE;
  210. }
  211. else
  212. {
  213. base.WndProc(ref m);
  214. }
  215. }
  216. else
  217. {
  218. base.WndProc(ref m);
  219. RenderComboBox(ref m);
  220. }
  221. }
  222. #endregion
  223. #region Render Methods
  224. private void RenderComboBox(ref Message m)
  225. {
  226. Rectangle rect = new Rectangle(Point.Empty, Size);
  227. Rectangle buttonRect = ButtonRect;
  228. ControlState state = ButtonPressed ?
  229. ControlState.Pressed : ButtonState;
  230. using (Graphics g = Graphics.FromHwnd(m.HWnd))
  231. {
  232. RenderComboBoxBackground(g, rect, buttonRect);
  233. RenderConboBoxDropDownButton(g, ButtonRect, state);
  234. RenderConboBoxBorder(g, rect);
  235. }
  236. }
  237. private void RenderConboBoxBorder(
  238. Graphics g, Rectangle rect)
  239. {
  240. Color borderColor = base.Enabled ?
  241. _borderColor : SystemColors.ControlDarkDark;
  242. using (Pen pen = new Pen(borderColor))
  243. {
  244. rect.Width--;
  245. rect.Height--;
  246. g.DrawRectangle(pen, rect);
  247. }
  248. }
  249. private void RenderComboBoxBackground(
  250. Graphics g,
  251. Rectangle rect,
  252. Rectangle buttonRect)
  253. {
  254. Color backColor = base.Enabled ?
  255. base.BackColor : SystemColors.Control;
  256. using (SolidBrush brush = new SolidBrush(backColor))
  257. {
  258. buttonRect.Inflate(-1, -1);
  259. rect.Inflate(-1, -1);
  260. using (Region region = new Region(rect))
  261. {
  262. region.Exclude(buttonRect);
  263. region.Exclude(EditRect);
  264. g.FillRegion(brush, region);
  265. }
  266. }
  267. }
  268. private void RenderConboBoxDropDownButton(
  269. Graphics g,
  270. Rectangle buttonRect,
  271. ControlState state)
  272. {
  273. Color baseColor;
  274. Color backColor = Color.FromArgb(160, 250, 250, 250);
  275. Color borderColor = base.Enabled ?
  276. _borderColor : SystemColors.ControlDarkDark;
  277. Color arrowColor = base.Enabled ?
  278. _arrowColor : SystemColors.ControlDarkDark;
  279. Rectangle rect = buttonRect;
  280. if (!isCustomColor) {
  281. _baseColor = LYFZ.ComponentLibrary.GetUIResources.ComboBoxExBaseColor;
  282. _borderColor = LYFZ.ComponentLibrary.GetUIResources.ComboBoxExBorderColor;
  283. _arrowColor = LYFZ.ComponentLibrary.GetUIResources.ComboBoxExArrowColor;
  284. }
  285. if (base.Enabled)
  286. {
  287. switch (state)
  288. {
  289. case ControlState.Hover:
  290. baseColor = RenderHelper.GetColor(
  291. _baseColor, 0, -33, -22, -13);
  292. break;
  293. case ControlState.Pressed:
  294. baseColor = RenderHelper.GetColor(
  295. _baseColor, 0, -65, -47, -25);
  296. break;
  297. default:
  298. baseColor = _baseColor;
  299. break;
  300. }
  301. }
  302. else
  303. {
  304. baseColor = SystemColors.ControlDark;
  305. }
  306. rect.Inflate(-1, -1);
  307. RenderScrollBarArrowInternal(
  308. g,
  309. rect,
  310. baseColor,
  311. borderColor,
  312. backColor,
  313. arrowColor,
  314. RoundStyle.None,
  315. true,
  316. false,
  317. ArrowDirection.Down,
  318. LinearGradientMode.Vertical);
  319. }
  320. internal void RenderScrollBarArrowInternal(
  321. Graphics g,
  322. Rectangle rect,
  323. Color baseColor,
  324. Color borderColor,
  325. Color innerBorderColor,
  326. Color arrowColor,
  327. RoundStyle roundStyle,
  328. bool drawBorder,
  329. bool drawGlass,
  330. ArrowDirection arrowDirection,
  331. LinearGradientMode mode)
  332. {
  333. RenderHelper.RenderBackgroundInternal(
  334. g,
  335. rect,
  336. baseColor,
  337. borderColor,
  338. innerBorderColor,
  339. roundStyle,
  340. 0,
  341. .45F,
  342. drawBorder,
  343. drawGlass,
  344. mode);
  345. using (SolidBrush brush = new SolidBrush(arrowColor))
  346. {
  347. RenderArrowInternal(
  348. g,
  349. rect,
  350. arrowDirection,
  351. brush);
  352. }
  353. }
  354. internal void RenderArrowInternal(
  355. Graphics g,
  356. Rectangle dropDownRect,
  357. ArrowDirection direction,
  358. Brush brush)
  359. {
  360. Point point = new Point(
  361. dropDownRect.Left + (dropDownRect.Width / 2),
  362. dropDownRect.Top + (dropDownRect.Height / 2));
  363. Point[] points = null;
  364. switch (direction)
  365. {
  366. case ArrowDirection.Left:
  367. points = new Point[] {
  368. new Point(point.X + 2, point.Y - 3),
  369. new Point(point.X + 2, point.Y + 3),
  370. new Point(point.X - 1, point.Y) };
  371. break;
  372. case ArrowDirection.Up:
  373. points = new Point[] {
  374. new Point(point.X - 3, point.Y + 2),
  375. new Point(point.X + 3, point.Y + 2),
  376. new Point(point.X, point.Y - 2) };
  377. break;
  378. case ArrowDirection.Right:
  379. points = new Point[] {
  380. new Point(point.X - 2, point.Y - 3),
  381. new Point(point.X - 2, point.Y + 3),
  382. new Point(point.X + 1, point.Y) };
  383. break;
  384. default:
  385. points = new Point[] {
  386. new Point(point.X - 2, point.Y - 1),
  387. new Point(point.X + 3, point.Y - 1),
  388. new Point(point.X, point.Y + 2) };
  389. break;
  390. }
  391. g.FillPolygon(brush, points);
  392. }
  393. #endregion
  394. #region Help Methods
  395. private NativeMethods.ComboBoxInfo GetComboBoxInfo()
  396. {
  397. NativeMethods.ComboBoxInfo cbi = new NativeMethods.ComboBoxInfo();
  398. cbi.cbSize = Marshal.SizeOf(cbi);
  399. NativeMethods.GetComboBoxInfo(base.Handle, ref cbi);
  400. return cbi;
  401. }
  402. private bool GetComboBoxButtonPressed()
  403. {
  404. NativeMethods.ComboBoxInfo cbi = GetComboBoxInfo();
  405. return cbi.stateButton ==
  406. NativeMethods.ComboBoxButtonState.STATE_SYSTEM_PRESSED;
  407. }
  408. private Rectangle GetDropDownButtonRect()
  409. {
  410. NativeMethods.ComboBoxInfo cbi = GetComboBoxInfo();
  411. return cbi.rcButton.Rect;
  412. }
  413. /// <summary>
  414. /// 控件的状态。
  415. /// </summary>
  416. public enum ControlState
  417. {
  418. /// <summary>
  419. /// 正常。
  420. /// </summary>
  421. Normal,
  422. /// <summary>
  423. /// 鼠标进入。
  424. /// </summary>
  425. Hover,
  426. /// <summary>
  427. /// 鼠标按下。
  428. /// </summary>
  429. Pressed,
  430. /// <summary>
  431. /// 获得焦点。
  432. /// </summary>
  433. Focused,
  434. }
  435. #endregion
  436. #region 只读
  437. [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
  438. public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
  439. int GW_CHILD = 5;
  440. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  441. //wParam=1为只读;wParam=0为可写
  442. public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
  443. public const int EM_SETREADONLY = 0xcf;
  444. private bool _readonly = false;
  445. /// <summary>
  446. /// 只读
  447. /// </summary>
  448. public bool ReadOnly
  449. {
  450. get { return _readonly; }
  451. set
  452. {
  453. _readonly = value;
  454. if (_readonly)
  455. {
  456. IntPtr editHandle = GetWindow(this.Handle, GW_CHILD);
  457. SendMessage(editHandle, EM_SETREADONLY, 1, 0);
  458. }
  459. else
  460. {
  461. IntPtr editHandle = GetWindow(this.Handle, GW_CHILD);
  462. SendMessage(editHandle, EM_SETREADONLY, 0, 0);
  463. }
  464. }
  465. }
  466. #endregion
  467. }
  468. internal class NativeMethods
  469. {
  470. #region Const
  471. public static readonly IntPtr FALSE = IntPtr.Zero;
  472. public static readonly IntPtr TRUE = new IntPtr(1);
  473. public const int WM_PAINT = 0x000F;
  474. #endregion
  475. #region ComboBoxButtonState
  476. public enum ComboBoxButtonState
  477. {
  478. STATE_SYSTEM_NONE = 0,
  479. STATE_SYSTEM_INVISIBLE = 0x00008000,
  480. STATE_SYSTEM_PRESSED = 0x00000008
  481. }
  482. #endregion
  483. #region RECT
  484. [StructLayout(LayoutKind.Sequential)]
  485. public struct RECT
  486. {
  487. public int Left;
  488. public int Top;
  489. public int Right;
  490. public int Bottom;
  491. public RECT(int left, int top, int right, int bottom)
  492. {
  493. Left = left;
  494. Top = top;
  495. Right = right;
  496. Bottom = bottom;
  497. }
  498. public RECT(Rectangle rect)
  499. {
  500. Left = rect.Left;
  501. Top = rect.Top;
  502. Right = rect.Right;
  503. Bottom = rect.Bottom;
  504. }
  505. public Rectangle Rect
  506. {
  507. get
  508. {
  509. return new Rectangle(
  510. Left,
  511. Top,
  512. Right - Left,
  513. Bottom - Top);
  514. }
  515. }
  516. public Size Size
  517. {
  518. get
  519. {
  520. return new Size(Right - Left, Bottom - Top);
  521. }
  522. }
  523. public static RECT FromXYWH(int x, int y, int width, int height)
  524. {
  525. return new RECT(x,
  526. y,
  527. x + width,
  528. y + height);
  529. }
  530. public static RECT FromRectangle(Rectangle rect)
  531. {
  532. return new RECT(rect.Left,
  533. rect.Top,
  534. rect.Right,
  535. rect.Bottom);
  536. }
  537. }
  538. #endregion
  539. #region PAINTSTRUCT
  540. [StructLayout(LayoutKind.Sequential)]
  541. public struct PAINTSTRUCT
  542. {
  543. public IntPtr hdc;
  544. public int fErase;
  545. public RECT rcPaint;
  546. public int fRestore;
  547. public int fIncUpdate;
  548. public int Reserved1;
  549. public int Reserved2;
  550. public int Reserved3;
  551. public int Reserved4;
  552. public int Reserved5;
  553. public int Reserved6;
  554. public int Reserved7;
  555. public int Reserved8;
  556. }
  557. #endregion
  558. #region ComboBoxInfo Struct
  559. [StructLayout(LayoutKind.Sequential)]
  560. public struct ComboBoxInfo
  561. {
  562. public int cbSize;
  563. public RECT rcItem;
  564. public RECT rcButton;
  565. public ComboBoxButtonState stateButton;
  566. public IntPtr hwndCombo;
  567. public IntPtr hwndEdit;
  568. public IntPtr hwndList;
  569. }
  570. #endregion
  571. #region API Methods
  572. [DllImport("user32.dll")]
  573. public static extern bool GetComboBoxInfo(
  574. IntPtr hwndCombo, ref ComboBoxInfo info);
  575. [DllImport("user32.dll")]
  576. public static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect);
  577. [DllImport("user32.dll")]
  578. public static extern IntPtr BeginPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
  579. [DllImport("user32.dll")]
  580. public static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
  581. #endregion
  582. }
  583. internal class RenderHelper
  584. {
  585. internal static void RenderBackgroundInternal(
  586. Graphics g,
  587. Rectangle rect,
  588. Color baseColor,
  589. Color borderColor,
  590. Color innerBorderColor,
  591. RoundStyle style,
  592. bool drawBorder,
  593. bool drawGlass,
  594. LinearGradientMode mode)
  595. {
  596. RenderBackgroundInternal(
  597. g,
  598. rect,
  599. baseColor,
  600. borderColor,
  601. innerBorderColor,
  602. style,
  603. 8,
  604. drawBorder,
  605. drawGlass,
  606. mode);
  607. }
  608. internal static void RenderBackgroundInternal(
  609. Graphics g,
  610. Rectangle rect,
  611. Color baseColor,
  612. Color borderColor,
  613. Color innerBorderColor,
  614. RoundStyle style,
  615. int roundWidth,
  616. bool drawBorder,
  617. bool drawGlass,
  618. LinearGradientMode mode)
  619. {
  620. RenderBackgroundInternal(
  621. g,
  622. rect,
  623. baseColor,
  624. borderColor,
  625. innerBorderColor,
  626. style,
  627. 8,
  628. 0.45f,
  629. drawBorder,
  630. drawGlass,
  631. mode);
  632. }
  633. internal static void RenderBackgroundInternal(
  634. Graphics g,
  635. Rectangle rect,
  636. Color baseColor,
  637. Color borderColor,
  638. Color innerBorderColor,
  639. RoundStyle style,
  640. int roundWidth,
  641. float basePosition,
  642. bool drawBorder,
  643. bool drawGlass,
  644. LinearGradientMode mode)
  645. {
  646. if (drawBorder)
  647. {
  648. rect.Width--;
  649. rect.Height--;
  650. }
  651. using (LinearGradientBrush brush = new LinearGradientBrush(
  652. rect, Color.Transparent, Color.Transparent, mode))
  653. {
  654. Color[] colors = new Color[4];
  655. colors[0] = GetColor(baseColor, 0, 35, 24, 9);
  656. colors[1] = GetColor(baseColor, 0, 13, 8, 3);
  657. colors[2] = baseColor;
  658. colors[3] = GetColor(baseColor, 0, 35, 24, 9);
  659. ColorBlend blend = new ColorBlend();
  660. blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
  661. blend.Colors = colors;
  662. brush.InterpolationColors = blend;
  663. if (style != RoundStyle.None)
  664. {
  665. using (GraphicsPath path =
  666. GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
  667. {
  668. g.FillPath(brush, path);
  669. }
  670. if (baseColor.A > 80)
  671. {
  672. Rectangle rectTop = rect;
  673. if (mode == LinearGradientMode.Vertical)
  674. {
  675. rectTop.Height = (int)(rectTop.Height * basePosition);
  676. }
  677. else
  678. {
  679. rectTop.Width = (int)(rect.Width * basePosition);
  680. }
  681. using (GraphicsPath pathTop = GraphicsPathHelper.CreatePath(
  682. rectTop, roundWidth, RoundStyle.Top, false))
  683. {
  684. using (SolidBrush brushAlpha =
  685. new SolidBrush(Color.FromArgb(128, 255, 255, 255)))
  686. {
  687. g.FillPath(brushAlpha, pathTop);
  688. }
  689. }
  690. }
  691. if (drawGlass)
  692. {
  693. RectangleF glassRect = rect;
  694. if (mode == LinearGradientMode.Vertical)
  695. {
  696. glassRect.Y = rect.Y + rect.Height * basePosition;
  697. glassRect.Height = (rect.Height - rect.Height * basePosition) * 2;
  698. }
  699. else
  700. {
  701. glassRect.X = rect.X + rect.Width * basePosition;
  702. glassRect.Width = (rect.Width - rect.Width * basePosition) * 2;
  703. }
  704. ControlPaintEx.DrawGlass(g, glassRect, 170, 0);
  705. }
  706. if (drawBorder)
  707. {
  708. using (GraphicsPath path =
  709. GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
  710. {
  711. using (Pen pen = new Pen(borderColor))
  712. {
  713. g.DrawPath(pen, path);
  714. }
  715. }
  716. rect.Inflate(-1, -1);
  717. using (GraphicsPath path =
  718. GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
  719. {
  720. using (Pen pen = new Pen(innerBorderColor))
  721. {
  722. g.DrawPath(pen, path);
  723. }
  724. }
  725. }
  726. }
  727. else
  728. {
  729. g.FillRectangle(brush, rect);
  730. if (baseColor.A > 80)
  731. {
  732. Rectangle rectTop = rect;
  733. if (mode == LinearGradientMode.Vertical)
  734. {
  735. rectTop.Height = (int)(rectTop.Height * basePosition);
  736. }
  737. else
  738. {
  739. rectTop.Width = (int)(rect.Width * basePosition);
  740. }
  741. using (SolidBrush brushAlpha =
  742. new SolidBrush(Color.FromArgb(128, 255, 255, 255)))
  743. {
  744. g.FillRectangle(brushAlpha, rectTop);
  745. }
  746. }
  747. if (drawGlass)
  748. {
  749. RectangleF glassRect = rect;
  750. if (mode == LinearGradientMode.Vertical)
  751. {
  752. glassRect.Y = rect.Y + rect.Height * basePosition;
  753. glassRect.Height = (rect.Height - rect.Height * basePosition) * 2;
  754. }
  755. else
  756. {
  757. glassRect.X = rect.X + rect.Width * basePosition;
  758. glassRect.Width = (rect.Width - rect.Width * basePosition) * 2;
  759. }
  760. ControlPaintEx.DrawGlass(g, glassRect, 200, 0);
  761. }
  762. if (drawBorder)
  763. {
  764. using (Pen pen = new Pen(borderColor))
  765. {
  766. g.DrawRectangle(pen, rect);
  767. }
  768. rect.Inflate(-1, -1);
  769. using (Pen pen = new Pen(innerBorderColor))
  770. {
  771. g.DrawRectangle(pen, rect);
  772. }
  773. }
  774. }
  775. }
  776. }
  777. internal static Color GetColor(Color colorBase, int a, int r, int g, int b)
  778. {
  779. int a0 = colorBase.A;
  780. int r0 = colorBase.R;
  781. int g0 = colorBase.G;
  782. int b0 = colorBase.B;
  783. if (a + a0 > 255) { a = 255; } else { a = Math.Max(0, a + a0); }
  784. if (r + r0 > 255) { r = 255; } else { r = Math.Max(0, r + r0); }
  785. if (g + g0 > 255) { g = 255; } else { g = Math.Max(0, g + g0); }
  786. if (b + b0 > 255) { b = 255; } else { b = Math.Max(0, b + b0); }
  787. return Color.FromArgb(a, r, g, b);
  788. }
  789. }
  790. public sealed class ControlPaintEx
  791. {
  792. public static void DrawCheckedFlag(Graphics graphics, Rectangle rect, Color color)
  793. {
  794. PointF[] points = new PointF[3];
  795. points[0] = new PointF(
  796. rect.X + rect.Width / 4.5f,
  797. rect.Y + rect.Height / 2.5f);
  798. points[1] = new PointF(
  799. rect.X + rect.Width / 2.5f,
  800. rect.Bottom - rect.Height / 3f);
  801. points[2] = new PointF(
  802. rect.Right - rect.Width / 4.0f,
  803. rect.Y + rect.Height / 4.5f);
  804. using (Pen pen = new Pen(color, 2F))
  805. {
  806. graphics.DrawLines(pen, points);
  807. }
  808. }
  809. public static void DrawGlass(
  810. Graphics g, RectangleF glassRect, int alphaCenter, int alphaSurround)
  811. {
  812. DrawGlass(g, glassRect, Color.White, alphaCenter, alphaSurround);
  813. }
  814. public static void DrawGlass(
  815. Graphics g,
  816. RectangleF glassRect,
  817. Color glassColor,
  818. int alphaCenter,
  819. int alphaSurround)
  820. {
  821. using (GraphicsPath path = new GraphicsPath())
  822. {
  823. path.AddEllipse(glassRect);
  824. using (PathGradientBrush brush = new PathGradientBrush(path))
  825. {
  826. brush.CenterColor = Color.FromArgb(alphaCenter, glassColor);
  827. brush.SurroundColors = new Color[] {
  828. Color.FromArgb(alphaSurround, glassColor) };
  829. brush.CenterPoint = new PointF(
  830. glassRect.X + glassRect.Width / 2,
  831. glassRect.Y + glassRect.Height / 2);
  832. g.FillPath(brush, path);
  833. }
  834. }
  835. }
  836. public static void DrawBackgroundImage(
  837. Graphics g,
  838. Image backgroundImage,
  839. Color backColor,
  840. ImageLayout backgroundImageLayout,
  841. Rectangle bounds,
  842. Rectangle clipRect)
  843. {
  844. DrawBackgroundImage(
  845. g,
  846. backgroundImage,
  847. backColor,
  848. backgroundImageLayout,
  849. bounds,
  850. clipRect,
  851. Point.Empty,
  852. RightToLeft.No);
  853. }
  854. public static void DrawBackgroundImage(
  855. Graphics g,
  856. Image backgroundImage,
  857. Color backColor,
  858. ImageLayout backgroundImageLayout,
  859. Rectangle bounds,
  860. Rectangle clipRect,
  861. Point scrollOffset)
  862. {
  863. DrawBackgroundImage(
  864. g,
  865. backgroundImage,
  866. backColor,
  867. backgroundImageLayout,
  868. bounds,
  869. clipRect,
  870. scrollOffset,
  871. RightToLeft.No);
  872. }
  873. public static void DrawBackgroundImage(
  874. Graphics g,
  875. Image backgroundImage,
  876. Color backColor,
  877. ImageLayout backgroundImageLayout,
  878. Rectangle bounds,
  879. Rectangle clipRect,
  880. Point scrollOffset,
  881. RightToLeft rightToLeft)
  882. {
  883. if (g == null)
  884. {
  885. throw new ArgumentNullException("g");
  886. }
  887. if (backgroundImageLayout == ImageLayout.Tile)
  888. {
  889. using (TextureBrush brush = new TextureBrush(backgroundImage, WrapMode.Tile))
  890. {
  891. if (scrollOffset != Point.Empty)
  892. {
  893. Matrix transform = brush.Transform;
  894. transform.Translate((float)scrollOffset.X, (float)scrollOffset.Y);
  895. brush.Transform = transform;
  896. }
  897. g.FillRectangle(brush, clipRect);
  898. return;
  899. }
  900. }
  901. Rectangle rect = CalculateBackgroundImageRectangle(
  902. bounds,
  903. backgroundImage,
  904. backgroundImageLayout);
  905. if ((rightToLeft == RightToLeft.Yes) &&
  906. (backgroundImageLayout == ImageLayout.None))
  907. {
  908. rect.X += clipRect.Width - rect.Width;
  909. }
  910. using (SolidBrush brush2 = new SolidBrush(backColor))
  911. {
  912. g.FillRectangle(brush2, clipRect);
  913. }
  914. if (!clipRect.Contains(rect))
  915. {
  916. if ((backgroundImageLayout == ImageLayout.Stretch) ||
  917. (backgroundImageLayout == ImageLayout.Zoom))
  918. {
  919. rect.Intersect(clipRect);
  920. g.DrawImage(backgroundImage, rect);
  921. }
  922. else if (backgroundImageLayout == ImageLayout.None)
  923. {
  924. rect.Offset(clipRect.Location);
  925. Rectangle destRect = rect;
  926. destRect.Intersect(clipRect);
  927. Rectangle rectangle3 = new Rectangle(Point.Empty, destRect.Size);
  928. g.DrawImage(
  929. backgroundImage,
  930. destRect,
  931. rectangle3.X,
  932. rectangle3.Y,
  933. rectangle3.Width,
  934. rectangle3.Height,
  935. GraphicsUnit.Pixel);
  936. }
  937. else
  938. {
  939. Rectangle rectangle4 = rect;
  940. rectangle4.Intersect(clipRect);
  941. Rectangle rectangle5 = new Rectangle(
  942. new Point(rectangle4.X - rect.X, rectangle4.Y - rect.Y),
  943. rectangle4.Size);
  944. g.DrawImage(
  945. backgroundImage,
  946. rectangle4,
  947. rectangle5.X,
  948. rectangle5.Y,
  949. rectangle5.Width,
  950. rectangle5.Height,
  951. GraphicsUnit.Pixel);
  952. }
  953. }
  954. else
  955. {
  956. System.Drawing.Imaging.ImageAttributes imageAttr = new System.Drawing.Imaging.ImageAttributes();
  957. imageAttr.SetWrapMode(WrapMode.TileFlipXY);
  958. g.DrawImage(
  959. backgroundImage,
  960. rect,
  961. 0,
  962. 0,
  963. backgroundImage.Width,
  964. backgroundImage.Height,
  965. GraphicsUnit.Pixel,
  966. imageAttr);
  967. imageAttr.Dispose();
  968. }
  969. }
  970. internal static Rectangle CalculateBackgroundImageRectangle(
  971. Rectangle bounds,
  972. Image backgroundImage,
  973. ImageLayout imageLayout)
  974. {
  975. Rectangle rectangle = bounds;
  976. if (backgroundImage != null)
  977. {
  978. switch (imageLayout)
  979. {
  980. case ImageLayout.None:
  981. rectangle.Size = backgroundImage.Size;
  982. return rectangle;
  983. case ImageLayout.Tile:
  984. return rectangle;
  985. case ImageLayout.Center:
  986. {
  987. rectangle.Size = backgroundImage.Size;
  988. Size size = bounds.Size;
  989. if (size.Width > rectangle.Width)
  990. {
  991. rectangle.X = (size.Width - rectangle.Width) / 2;
  992. }
  993. if (size.Height > rectangle.Height)
  994. {
  995. rectangle.Y = (size.Height - rectangle.Height) / 2;
  996. }
  997. return rectangle;
  998. }
  999. case ImageLayout.Stretch:
  1000. rectangle.Size = bounds.Size;
  1001. return rectangle;
  1002. case ImageLayout.Zoom:
  1003. {
  1004. Size size2 = backgroundImage.Size;
  1005. float num = ((float)bounds.Width) / ((float)size2.Width);
  1006. float num2 = ((float)bounds.Height) / ((float)size2.Height);
  1007. if (num >= num2)
  1008. {
  1009. rectangle.Height = bounds.Height;
  1010. rectangle.Width = (int)((size2.Width * num2) + 0.5);
  1011. if (bounds.X >= 0)
  1012. {
  1013. rectangle.X = (bounds.Width - rectangle.Width) / 2;
  1014. }
  1015. return rectangle;
  1016. }
  1017. rectangle.Width = bounds.Width;
  1018. rectangle.Height = (int)((size2.Height * num) + 0.5);
  1019. if (bounds.Y >= 0)
  1020. {
  1021. rectangle.Y = (bounds.Height - rectangle.Height) / 2;
  1022. }
  1023. return rectangle;
  1024. }
  1025. }
  1026. }
  1027. return rectangle;
  1028. }
  1029. }
  1030. }