ThemeManager.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. //#########################################################################################
  2. //★★★★★★★ http://www.cnpopsoft.com [华普软件] ★★★★★★★
  3. //★★★★★★★ 华普软件 - VB & C#.NET 专业论文与源码荟萃! ★★★★★★★
  4. //#########################################################################################
  5. /*
  6. * Copyright ?2005, Mathew Hall
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modification,
  10. * are permitted provided that the following conditions are met:
  11. *
  12. * - Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  25. * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  28. * OF SUCH DAMAGE.
  29. */
  30. using System;
  31. using System.Drawing;
  32. using System.Reflection;
  33. using System.Resources;
  34. using System.Runtime.InteropServices;
  35. using System.Windows.Forms;
  36. using XPTable.Win32;
  37. namespace XPTable.Themes
  38. {
  39. /// <summary>
  40. /// A class that contains methods for drawing Windows XP themed Control parts
  41. /// </summary>
  42. public abstract class ThemeManager
  43. {
  44. #region Constructor
  45. /// <summary>
  46. /// Initializes a new instance of the ThemeManager class with default settings
  47. /// </summary>
  48. protected ThemeManager()
  49. {
  50. }
  51. #endregion
  52. #region Methods
  53. #region Painting
  54. #region Button
  55. /// <summary>
  56. /// Draws a push button in the specified state, on the specified graphics
  57. /// surface, and within the specified bounds
  58. /// </summary>
  59. /// <param name="g">The Graphics to draw on</param>
  60. /// <param name="buttonRect">The Rectangle that represents the dimensions
  61. /// of the button</param>
  62. /// <param name="state">A PushButtonStates value that specifies the
  63. /// state to draw the button in</param>
  64. public static void DrawButton(Graphics g, Rectangle buttonRect, PushButtonStates state)
  65. {
  66. ThemeManager.DrawButton(g, buttonRect, buttonRect, state);
  67. }
  68. /// <summary>
  69. /// Draws a push button in the specified state, on the specified graphics
  70. /// surface, and within the specified bounds
  71. /// </summary>
  72. /// <param name="g">The Graphics to draw on</param>
  73. /// <param name="buttonRect">The Rectangle that represents the dimensions
  74. /// of the button</param>
  75. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  76. /// <param name="state">A PushButtonStates value that specifies the
  77. /// state to draw the button in</param>
  78. public static void DrawButton(Graphics g, Rectangle buttonRect, Rectangle clipRect, PushButtonStates state)
  79. {
  80. if (g == null || buttonRect.Width <= 0 || buttonRect.Height <= 0 || clipRect.Width <= 0 || clipRect.Height <= 0)
  81. {
  82. return;
  83. }
  84. if (ThemeManager.VisualStylesEnabled)
  85. {
  86. ThemeManager.DrawThemeBackground(g, ThemeClasses.Button, (int) ButtonParts.PushButton, (int) state, buttonRect, clipRect);
  87. }
  88. else
  89. {
  90. ControlPaint.DrawButton(g, buttonRect, ThemeManager.ConvertPushButtonStateToButtonState(state));
  91. }
  92. }
  93. /// <summary>
  94. /// Converts the specified PushButtonStates value to a ButtonState value
  95. /// </summary>
  96. /// <param name="state">The PushButtonStates value to be converted</param>
  97. /// <returns>A ButtonState value that represents the specified PushButtonStates
  98. /// value</returns>
  99. private static ButtonState ConvertPushButtonStateToButtonState(PushButtonStates state)
  100. {
  101. switch (state)
  102. {
  103. case PushButtonStates.Pressed:
  104. {
  105. return ButtonState.Pushed;
  106. }
  107. case PushButtonStates.Disabled:
  108. {
  109. return ButtonState.Inactive;
  110. }
  111. }
  112. return ButtonState.Normal;
  113. }
  114. #endregion
  115. #region CheckBox
  116. /// <summary>
  117. /// Draws a check box in the specified state, on the specified graphics
  118. /// surface, and within the specified bounds
  119. /// </summary>
  120. /// <param name="g">The Graphics to draw on</param>
  121. /// <param name="checkRect">The Rectangle that represents the dimensions
  122. /// of the check box</param>
  123. /// <param name="state">A CheckBoxStates value that specifies the
  124. /// state to draw the check box in</param>
  125. public static void DrawCheck(Graphics g, Rectangle checkRect, CheckBoxStates state)
  126. {
  127. ThemeManager.DrawCheck(g, checkRect, checkRect, state);
  128. }
  129. /// <summary>
  130. /// Draws a check box in the specified state, on the specified graphics
  131. /// surface, and within the specified bounds
  132. /// </summary>
  133. /// <param name="g">The Graphics to draw on</param>
  134. /// <param name="checkRect">The Rectangle that represents the dimensions
  135. /// of the check box</param>
  136. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  137. /// <param name="state">A CheckBoxStates value that specifies the
  138. /// state to draw the check box in</param>
  139. public static void DrawCheck(Graphics g, Rectangle checkRect, Rectangle clipRect, CheckBoxStates state)
  140. {
  141. if (g == null || checkRect.Width <= 0 || checkRect.Height <= 0)
  142. {
  143. return;
  144. }
  145. if (ThemeManager.VisualStylesEnabled)
  146. {
  147. ThemeManager.DrawThemeBackground(g, ThemeClasses.Button, (int) ButtonParts.CheckBox, (int) state, checkRect, clipRect);
  148. }
  149. else
  150. {
  151. if (IsMixed(state))
  152. {
  153. ControlPaint.DrawMixedCheckBox(g, checkRect, ThemeManager.ConvertCheckBoxStateToButtonState(state));
  154. }
  155. else
  156. {
  157. ControlPaint.DrawCheckBox(g, checkRect, ThemeManager.ConvertCheckBoxStateToButtonState(state));
  158. }
  159. }
  160. }
  161. /// <summary>
  162. /// Converts the specified CheckBoxStates value to a ButtonState value
  163. /// </summary>
  164. /// <param name="state">The CheckBoxStates value to be converted</param>
  165. /// <returns>A ButtonState value that represents the specified CheckBoxStates
  166. /// value</returns>
  167. private static ButtonState ConvertCheckBoxStateToButtonState(CheckBoxStates state)
  168. {
  169. switch (state)
  170. {
  171. case CheckBoxStates.UncheckedPressed:
  172. {
  173. return ButtonState.Pushed;
  174. }
  175. case CheckBoxStates.UncheckedDisabled:
  176. {
  177. return ButtonState.Inactive;
  178. }
  179. case CheckBoxStates.CheckedNormal:
  180. case CheckBoxStates.CheckedHot:
  181. {
  182. return ButtonState.Checked;
  183. }
  184. case CheckBoxStates.CheckedPressed:
  185. {
  186. return (ButtonState.Checked | ButtonState.Pushed);
  187. }
  188. case CheckBoxStates.CheckedDisabled:
  189. {
  190. return (ButtonState.Checked | ButtonState.Inactive);
  191. }
  192. case CheckBoxStates.MixedNormal:
  193. case CheckBoxStates.MixedHot:
  194. {
  195. return ButtonState.Checked;
  196. }
  197. case CheckBoxStates.MixedPressed:
  198. {
  199. return (ButtonState.Checked | ButtonState.Pushed);
  200. }
  201. case CheckBoxStates.MixedDisabled:
  202. {
  203. return (ButtonState.Checked | ButtonState.Inactive);
  204. }
  205. }
  206. return ButtonState.Normal;
  207. }
  208. /// <summary>
  209. /// Returns whether the specified CheckBoxStates value is in an
  210. /// indeterminate state
  211. /// </summary>
  212. /// <param name="state">The CheckBoxStates value to be checked</param>
  213. /// <returns>true if the specified CheckBoxStates value is in an
  214. /// indeterminate state, false otherwise</returns>
  215. private static bool IsMixed(CheckBoxStates state)
  216. {
  217. switch (state)
  218. {
  219. case CheckBoxStates.MixedNormal:
  220. case CheckBoxStates.MixedHot:
  221. case CheckBoxStates.MixedPressed:
  222. case CheckBoxStates.MixedDisabled:
  223. {
  224. return true;
  225. }
  226. }
  227. return false;
  228. }
  229. #endregion
  230. #region ColumnHeader
  231. /// <summary>
  232. /// Draws a column header in the specified state, on the specified graphics
  233. /// surface, and within the specified bounds
  234. /// </summary>
  235. /// <param name="g">The Graphics to draw on</param>
  236. /// <param name="headerRect">The Rectangle that represents the dimensions
  237. /// of the column header</param>
  238. /// <param name="state">A ColumnHeaderStates value that specifies the
  239. /// state to draw the column header in</param>
  240. public static void DrawColumnHeader(Graphics g, Rectangle headerRect, ColumnHeaderStates state)
  241. {
  242. ThemeManager.DrawColumnHeader(g, headerRect, headerRect, state);
  243. }
  244. /// <summary>
  245. /// Draws a column header in the specified state, on the specified graphics
  246. /// surface, and within the specified bounds
  247. /// </summary>
  248. /// <param name="g">The Graphics to draw on</param>
  249. /// <param name="headerRect">The Rectangle that represents the dimensions
  250. /// of the column header</param>
  251. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  252. /// <param name="state">A ColumnHeaderStates value that specifies the
  253. /// state to draw the column header in</param>
  254. public static void DrawColumnHeader(Graphics g, Rectangle headerRect, Rectangle clipRect, ColumnHeaderStates state)
  255. {
  256. if (g == null || headerRect.Width <= 0 || headerRect.Height <= 0 || clipRect.Width <= 0 || clipRect.Height <= 0)
  257. {
  258. return;
  259. }
  260. if (ThemeManager.VisualStylesEnabled)
  261. {
  262. ThemeManager.DrawThemeBackground(g, ThemeClasses.ColumnHeader, (int) ColumnHeaderParts.HeaderItem, (int) state, headerRect, clipRect);
  263. }
  264. else
  265. {
  266. g.FillRectangle(SystemBrushes.Control, headerRect);
  267. if (state == ColumnHeaderStates.Pressed)
  268. {
  269. g.DrawRectangle(SystemPens.ControlDark, headerRect.X, headerRect.Y, headerRect.Width-1, headerRect.Height-1);
  270. }
  271. else
  272. {
  273. ControlPaint.DrawBorder3D(g, headerRect.X, headerRect.Y, headerRect.Width, headerRect.Height, Border3DStyle.RaisedInner);
  274. }
  275. }
  276. }
  277. #endregion
  278. #region ComboBoxButton
  279. /// <summary>
  280. /// Draws a combobox button in the specified state, on the specified graphics
  281. /// surface, and within the specified bounds
  282. /// </summary>
  283. /// <param name="g">The Graphics to draw on</param>
  284. /// <param name="buttonRect">The Rectangle that represents the dimensions
  285. /// of the combobox button</param>
  286. /// <param name="state">A ComboBoxStates value that specifies the
  287. /// state to draw the combobox button in</param>
  288. public static void DrawComboBoxButton(Graphics g, Rectangle buttonRect, ComboBoxStates state)
  289. {
  290. ThemeManager.DrawComboBoxButton(g, buttonRect, buttonRect, state);
  291. }
  292. /// <summary>
  293. /// Draws a combobox button in the specified state, on the specified graphics
  294. /// surface, and within the specified bounds
  295. /// </summary>
  296. /// <param name="g">The Graphics to draw on</param>
  297. /// <param name="buttonRect">The Rectangle that represents the dimensions
  298. /// of the button</param>
  299. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  300. /// <param name="state">A ComboBoxStates value that specifies the
  301. /// state to draw the combobox button in</param>
  302. public static void DrawComboBoxButton(Graphics g, Rectangle buttonRect, Rectangle clipRect, ComboBoxStates state)
  303. {
  304. if (g == null || buttonRect.Width <= 0 || buttonRect.Height <= 0 || clipRect.Width <= 0 || clipRect.Height <= 0)
  305. {
  306. return;
  307. }
  308. if (ThemeManager.VisualStylesEnabled)
  309. {
  310. ThemeManager.DrawThemeBackground(g, ThemeClasses.ComboBox, (int) ComboBoxParts.DropDownButton, (int) state, buttonRect, clipRect);
  311. }
  312. else
  313. {
  314. ControlPaint.DrawComboButton(g, buttonRect, ThemeManager.ConvertComboBoxStateToButtonState(state));
  315. }
  316. }
  317. /// <summary>
  318. /// Converts the specified ComboBoxStates value to a ButtonState value
  319. /// </summary>
  320. /// <param name="state">The ComboBoxStates value to be converted</param>
  321. /// <returns>A ButtonState value that represents the specified ComboBoxStates
  322. /// value</returns>
  323. private static ButtonState ConvertComboBoxStateToButtonState(ComboBoxStates state)
  324. {
  325. switch (state)
  326. {
  327. case ComboBoxStates.Pressed:
  328. {
  329. return ButtonState.Pushed;
  330. }
  331. case ComboBoxStates.Disabled:
  332. {
  333. return ButtonState.Inactive;
  334. }
  335. }
  336. return ButtonState.Normal;
  337. }
  338. #endregion
  339. #region ProgressBar
  340. /// <summary>
  341. /// Draws a ProgressBar on the specified graphics surface, and within
  342. /// the specified bounds
  343. /// </summary>
  344. /// <param name="g">The Graphics to draw on</param>
  345. /// <param name="drawRect">The Rectangle that represents the dimensions
  346. /// of the ProgressBar</param>
  347. public static void DrawProgressBar(Graphics g, Rectangle drawRect)
  348. {
  349. ThemeManager.DrawProgressBar(g, drawRect, drawRect);
  350. }
  351. /// <summary>
  352. /// Draws a ProgressBar on the specified graphics surface, and within
  353. /// the specified bounds
  354. /// </summary>
  355. /// <param name="g">The Graphics to draw on</param>
  356. /// <param name="drawRect">The Rectangle that represents the dimensions
  357. /// of the ProgressBar</param>
  358. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  359. public static void DrawProgressBar(Graphics g, Rectangle drawRect, Rectangle clipRect)
  360. {
  361. if (g == null || drawRect.Width <= 0 || drawRect.Height <= 0 || clipRect.Width <= 0 || clipRect.Height <= 0)
  362. {
  363. return;
  364. }
  365. if (ThemeManager.VisualStylesEnabled)
  366. {
  367. ThemeManager.DrawThemeBackground(g, ThemeClasses.ProgressBar, (int) ProgressBarParts.Bar, 0, drawRect, clipRect);
  368. }
  369. else
  370. {
  371. // background
  372. g.FillRectangle(Brushes.White, drawRect);
  373. // 3d border
  374. //ControlPaint.DrawBorder3D(g, drawRect, Border3DStyle.SunkenInner);
  375. // flat border
  376. g.DrawRectangle(SystemPens.ControlDark, drawRect.Left, drawRect.Top, drawRect.Width-1, drawRect.Height-1);
  377. }
  378. }
  379. /// <summary>
  380. /// Draws the ProgressBar's chunks on the specified graphics surface, and within
  381. /// the specified bounds
  382. /// </summary>
  383. /// <param name="g">The Graphics to draw on</param>
  384. /// <param name="drawRect">The Rectangle that represents the dimensions
  385. /// of the ProgressBar</param>
  386. public static void DrawProgressBarChunks(Graphics g, Rectangle drawRect)
  387. {
  388. ThemeManager.DrawProgressBarChunks(g, drawRect, drawRect);
  389. }
  390. /// <summary>
  391. /// Draws the ProgressBar's chunks on the specified graphics surface, and within
  392. /// the specified bounds
  393. /// </summary>
  394. /// <param name="g">The Graphics to draw on</param>
  395. /// <param name="drawRect">The Rectangle that represents the dimensions
  396. /// of the ProgressBar</param>
  397. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  398. public static void DrawProgressBarChunks(Graphics g, Rectangle drawRect, Rectangle clipRect)
  399. {
  400. if (g == null || drawRect.Width <= 0 || drawRect.Height <= 0 || clipRect.Width <= 0 || clipRect.Height <= 0)
  401. {
  402. return;
  403. }
  404. if (ThemeManager.VisualStylesEnabled)
  405. {
  406. ThemeManager.DrawThemeBackground(g, ThemeClasses.ProgressBar, (int) ProgressBarParts.Chunk, 0, drawRect, clipRect);
  407. }
  408. else
  409. {
  410. g.FillRectangle(SystemBrushes.Highlight, drawRect);
  411. }
  412. }
  413. #endregion
  414. #region RadioButton
  415. /// <summary>
  416. /// Draws a RadioButton in the specified state, on the specified graphics
  417. /// surface, and within the specified bounds
  418. /// </summary>
  419. /// <param name="g">The Graphics to draw on</param>
  420. /// <param name="checkRect">The Rectangle that represents the dimensions
  421. /// of the RadioButton</param>
  422. /// <param name="state">A RadioButtonStates value that specifies the
  423. /// state to draw the RadioButton in</param>
  424. public static void DrawRadioButton(Graphics g, Rectangle checkRect, RadioButtonStates state)
  425. {
  426. ThemeManager.DrawRadioButton(g, checkRect, checkRect, state);
  427. }
  428. /// <summary>
  429. /// Draws a RadioButton in the specified state, on the specified graphics
  430. /// surface, and within the specified bounds
  431. /// </summary>
  432. /// <param name="g">The Graphics to draw on</param>
  433. /// <param name="checkRect">The Rectangle that represents the dimensions
  434. /// of the RadioButton</param>
  435. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  436. /// <param name="state">A RadioButtonStates value that specifies the
  437. /// state to draw the RadioButton in</param>
  438. public static void DrawRadioButton(Graphics g, Rectangle checkRect, Rectangle clipRect, RadioButtonStates state)
  439. {
  440. if (g == null || checkRect.Width <= 0 || checkRect.Height <= 0)
  441. {
  442. return;
  443. }
  444. if (ThemeManager.VisualStylesEnabled)
  445. {
  446. ThemeManager.DrawThemeBackground(g, ThemeClasses.Button, (int) ButtonParts.RadioButton, (int) state, checkRect, clipRect);
  447. }
  448. else
  449. {
  450. ControlPaint.DrawRadioButton(g, checkRect, ThemeManager.ConvertRadioButtonStateToButtonState(state));
  451. }
  452. }
  453. /// <summary>
  454. /// Converts the specified RadioButtonStates value to a ButtonState value
  455. /// </summary>
  456. /// <param name="state">The RadioButtonStates value to be converted</param>
  457. /// <returns>A ButtonState value that represents the specified RadioButtonStates
  458. /// value</returns>
  459. private static ButtonState ConvertRadioButtonStateToButtonState(RadioButtonStates state)
  460. {
  461. switch (state)
  462. {
  463. case RadioButtonStates.UncheckedPressed:
  464. {
  465. return ButtonState.Pushed;
  466. }
  467. case RadioButtonStates.UncheckedDisabled:
  468. {
  469. return ButtonState.Inactive;
  470. }
  471. case RadioButtonStates.CheckedNormal:
  472. case RadioButtonStates.CheckedHot:
  473. {
  474. return ButtonState.Checked;
  475. }
  476. case RadioButtonStates.CheckedPressed:
  477. {
  478. return (ButtonState.Checked | ButtonState.Pushed);
  479. }
  480. case RadioButtonStates.CheckedDisabled:
  481. {
  482. return (ButtonState.Checked | ButtonState.Inactive);
  483. }
  484. }
  485. return ButtonState.Normal;
  486. }
  487. #endregion
  488. #region TabPage
  489. /// <summary>
  490. /// Draws a TabPage body on the specified graphics surface, and within the
  491. /// specified bounds
  492. /// </summary>
  493. /// <param name="g">The Graphics to draw on</param>
  494. /// <param name="tabRect">The Rectangle that represents the dimensions
  495. /// of the TabPage body</param>
  496. internal static void DrawTabPageBody(Graphics g, Rectangle tabRect)
  497. {
  498. ThemeManager.DrawTabPageBody(g, tabRect, tabRect);
  499. }
  500. /// <summary>
  501. /// Draws a TabPage body on the specified graphics surface, and within the
  502. /// specified bounds
  503. /// </summary>
  504. /// <param name="g">The Graphics to draw on</param>
  505. /// <param name="tabRect">The Rectangle that represents the dimensions
  506. /// of the TabPage body</param>
  507. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  508. internal static void DrawTabPageBody(Graphics g, Rectangle tabRect, Rectangle clipRect)
  509. {
  510. if (g == null || tabRect.Width <= 0 || tabRect.Height <= 0 || clipRect.Width <= 0 || clipRect.Height <= 0)
  511. {
  512. return;
  513. }
  514. if (ThemeManager.VisualStylesEnabled)
  515. {
  516. ThemeManager.DrawThemeBackground(g, ThemeClasses.TabControl, (int) TabParts.Body, 0, tabRect, clipRect);
  517. }
  518. else
  519. {
  520. g.FillRectangle(SystemBrushes.Control, Rectangle.Intersect(clipRect, tabRect));
  521. }
  522. }
  523. #endregion
  524. #region TextBox
  525. /// <summary>
  526. /// Draws a TextBox in the specified state, on the specified graphics
  527. /// surface, and within the specified bounds
  528. /// </summary>
  529. /// <param name="g">The Graphics to draw on</param>
  530. /// <param name="textRect">The Rectangle that represents the dimensions
  531. /// of the TextBox</param>
  532. /// <param name="state">A TextBoxStates value that specifies the
  533. /// state to draw the TextBox in</param>
  534. public static void DrawTextBox(Graphics g, Rectangle textRect, TextBoxStates state)
  535. {
  536. ThemeManager.DrawTextBox(g, textRect, textRect, state);
  537. }
  538. /// <summary>
  539. /// Draws a TextBox in the specified state, on the specified graphics
  540. /// surface, and within the specified bounds
  541. /// </summary>
  542. /// <param name="g">The Graphics to draw on</param>
  543. /// <param name="textRect">The Rectangle that represents the dimensions
  544. /// of the TextBox</param>
  545. /// <param name="clipRect">The Rectangle that represents the clipping area</param>
  546. /// <param name="state">A TextBoxStates value that specifies the
  547. /// state to draw the TextBox in</param>
  548. public static void DrawTextBox(Graphics g, Rectangle textRect, Rectangle clipRect, TextBoxStates state)
  549. {
  550. if (g == null || textRect.Width <= 0 || textRect.Height <= 0 || clipRect.Width <= 0 || clipRect.Height <= 0)
  551. {
  552. return;
  553. }
  554. if (ThemeManager.VisualStylesEnabled)
  555. {
  556. ThemeManager.DrawThemeBackground(g, ThemeClasses.TextBox, (int) TextBoxParts.EditText, (int) state, textRect, clipRect);
  557. }
  558. else
  559. {
  560. ControlPaint.DrawBorder3D(g, textRect, Border3DStyle.Sunken);
  561. }
  562. }
  563. #endregion
  564. #region UpDown
  565. /// <summary>
  566. /// Draws an UpDown's up and down buttons in the specified state, on the specified
  567. /// graphics surface, and within the specified bounds
  568. /// </summary>
  569. /// <param name="g">The Graphics to draw on</param>
  570. /// <param name="upButtonRect">The Rectangle that represents the dimensions
  571. /// of the up button</param>
  572. /// <param name="upButtonState">An UpDownStates value that specifies the
  573. /// state to draw the up button in</param>
  574. /// <param name="downButtonRect">The Rectangle that represents the dimensions
  575. /// of the down button</param>
  576. /// <param name="downButtonState">An UpDownStates value that specifies the
  577. /// state to draw the down button in</param>
  578. public static void DrawUpDownButtons(Graphics g, Rectangle upButtonRect, UpDownStates upButtonState, Rectangle downButtonRect, UpDownStates downButtonState)
  579. {
  580. ThemeManager.DrawUpDownButtons(g, upButtonRect, upButtonRect, upButtonState, downButtonRect, downButtonRect, downButtonState);
  581. }
  582. /// <summary>
  583. /// Draws an UpDown's up and down buttons in the specified state, on the specified
  584. /// graphics surface, and within the specified bounds
  585. /// </summary>
  586. /// <param name="g">The Graphics to draw on</param>
  587. /// <param name="upButtonRect">The Rectangle that represents the dimensions
  588. /// of the up button</param>
  589. /// <param name="upButtonClipRect">The Rectangle that represents the clipping area
  590. /// for the up button</param>
  591. /// <param name="upButtonState">An UpDownStates value that specifies the
  592. /// state to draw the up button in</param>
  593. /// <param name="downButtonRect">The Rectangle that represents the dimensions
  594. /// of the down button</param>
  595. /// <param name="downButtonClipRect">The Rectangle that represents the clipping area
  596. /// for the down button</param>
  597. /// <param name="downButtonState">An UpDownStates value that specifies the
  598. /// state to draw the down button in</param>
  599. public static void DrawUpDownButtons(Graphics g, Rectangle upButtonRect, Rectangle upButtonClipRect, UpDownStates upButtonState, Rectangle downButtonRect, Rectangle downButtonClipRect, UpDownStates downButtonState)
  600. {
  601. if (g == null)
  602. {
  603. return;
  604. }
  605. if (upButtonRect.Width > 0 && upButtonRect.Height > 0 && upButtonClipRect.Width > 0 && upButtonClipRect.Height > 0)
  606. {
  607. if (ThemeManager.VisualStylesEnabled)
  608. {
  609. ThemeManager.DrawThemeBackground(g, ThemeClasses.UpDown, (int) UpDownParts.Up, (int) upButtonState, upButtonRect, upButtonClipRect);
  610. }
  611. else
  612. {
  613. ControlPaint.DrawScrollButton(g, upButtonRect, ScrollButton.Up, ThemeManager.ConvertUpDownStateToButtonState(upButtonState));
  614. }
  615. }
  616. if (downButtonRect.Width > 0 && downButtonRect.Height > 0 && downButtonClipRect.Width > 0 && downButtonClipRect.Height > 0)
  617. {
  618. if (ThemeManager.VisualStylesEnabled)
  619. {
  620. ThemeManager.DrawThemeBackground(g, ThemeClasses.UpDown, (int) UpDownParts.Down, (int) downButtonState, downButtonRect, downButtonClipRect);
  621. }
  622. else
  623. {
  624. ControlPaint.DrawScrollButton(g, downButtonRect, ScrollButton.Down, ThemeManager.ConvertUpDownStateToButtonState(downButtonState));
  625. }
  626. }
  627. }
  628. /// <summary>
  629. /// Converts the specified UpDownStates value to a ButtonState value
  630. /// </summary>
  631. /// <param name="state">The UpDownStates value to be converted</param>
  632. /// <returns>A ButtonState value that represents the specified UpDownStates
  633. /// value</returns>
  634. private static ButtonState ConvertUpDownStateToButtonState(UpDownStates state)
  635. {
  636. switch (state)
  637. {
  638. case UpDownStates.Pressed:
  639. {
  640. return ButtonState.Pushed;
  641. }
  642. case UpDownStates.Disabled:
  643. {
  644. return ButtonState.Inactive;
  645. }
  646. }
  647. return ButtonState.Normal;
  648. }
  649. #endregion
  650. #region Theme Background
  651. /// <summary>
  652. /// Draws the background image defined by the visual style for the specified control part
  653. /// </summary>
  654. /// <param name="g">The Graphics to draw on</param>
  655. /// <param name="windowClass">The class of the part to draw</param>
  656. /// <param name="part">The part to draw</param>
  657. /// <param name="partState">The state of the part to draw</param>
  658. /// <param name="drawRect">The Rectangle in which the part is drawn</param>
  659. public static void DrawThemeBackground(Graphics g, string windowClass, int part, int partState, Rectangle drawRect)
  660. {
  661. //
  662. ThemeManager.DrawThemeBackground(g, windowClass, part, partState, drawRect, drawRect);
  663. }
  664. /// <summary>
  665. /// Draws the background image defined by the visual style for the specified control part
  666. /// </summary>
  667. /// <param name="g">The Graphics to draw on</param>
  668. /// <param name="windowClass">The class of the part to draw</param>
  669. /// <param name="part">The part to draw</param>
  670. /// <param name="partState">The state of the part to draw</param>
  671. /// <param name="drawRect">The Rectangle in which the part is drawn</param>
  672. /// <param name="clipRect">The Rectangle that represents the clipping area for the part</param>
  673. public static void DrawThemeBackground(Graphics g, string windowClass, int part, int partState, Rectangle drawRect, Rectangle clipRect)
  674. {
  675. if (g == null || drawRect.Width <= 0 || drawRect.Height <= 0 || clipRect.Width <= 0 || clipRect.Height <= 0)
  676. {
  677. return;
  678. }
  679. // open theme data
  680. IntPtr hTheme = IntPtr.Zero;
  681. hTheme = NativeMethods.OpenThemeData(hTheme, windowClass);
  682. // make sure we have a valid handle
  683. if (hTheme != IntPtr.Zero)
  684. {
  685. // get a graphics object the UxTheme can draw into
  686. IntPtr hdc = g.GetHdc();
  687. // get the draw and clipping rectangles
  688. RECT dRect = RECT.FromRectangle(drawRect);
  689. RECT cRect = RECT.FromRectangle(clipRect);
  690. // draw the themed background
  691. NativeMethods.DrawThemeBackground(hTheme, hdc, part, partState, ref dRect, ref cRect);
  692. // clean up resources
  693. g.ReleaseHdc(hdc);
  694. }
  695. // close the theme handle
  696. NativeMethods.CloseThemeData(hTheme);
  697. }
  698. #endregion
  699. #endregion
  700. #endregion
  701. #region Properties
  702. /// <summary>
  703. /// Gets whether Visual Styles are supported by the system
  704. /// </summary>
  705. public static bool VisualStylesSupported
  706. {
  707. get
  708. {
  709. return OSFeature.Feature.IsPresent(OSFeature.Themes);
  710. }
  711. }
  712. /// <summary>
  713. /// Gets whether Visual Styles are enabled for the application
  714. /// </summary>
  715. public static bool VisualStylesEnabled
  716. {
  717. get
  718. {
  719. if (VisualStylesSupported)
  720. {
  721. // are themes enabled
  722. if (NativeMethods.IsThemeActive() && NativeMethods.IsAppThemed())
  723. {
  724. return GetComctlVersion().Major >= 6;
  725. }
  726. }
  727. return false;
  728. }
  729. }
  730. /// <summary>
  731. /// Returns a Version object that contains information about the verion
  732. /// of the CommonControls that the application is using
  733. /// </summary>
  734. /// <returns>A Version object that contains information about the verion
  735. /// of the CommonControls that the application is using</returns>
  736. private static Version GetComctlVersion()
  737. {
  738. DLLVERSIONINFO comctlVersion = new DLLVERSIONINFO();
  739. comctlVersion.cbSize = Marshal.SizeOf(typeof(DLLVERSIONINFO));
  740. if (NativeMethods.DllGetVersion(ref comctlVersion) == 0)
  741. {
  742. return new Version(comctlVersion.dwMajorVersion, comctlVersion.dwMinorVersion, comctlVersion.dwBuildNumber);
  743. }
  744. return new Version();
  745. }
  746. #endregion
  747. }
  748. }