GR32_XPThemes.pas 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. unit GR32_XPThemes;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is Graphics32
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Alex A. Denisov
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2000-2009
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. * Andre Beckedorf
  32. *
  33. * ***** END LICENSE BLOCK ***** *)
  34. interface
  35. {$I GR32.inc}
  36. uses
  37. {$IFDEF FPC}
  38. LCLIntf, LCLType,
  39. {$IFDEF Windows}
  40. Windows,
  41. {$ENDIF}
  42. {$IFDEF UNIX}
  43. Unix, BaseUnix,
  44. {$ENDIF}
  45. {$ELSE}
  46. Windows,
  47. {$ENDIF}
  48. SysUtils;
  49. {$IFDEF Windows}
  50. { Internal support for Windows XP themes }
  51. var
  52. USE_THEMES: Boolean = False;
  53. SCROLLBAR_THEME: THandle = 0;
  54. GLOBALS_THEME: THandle = 0;
  55. const
  56. THEMEMGR_VERSION = 1;
  57. WM_THEMECHANGED = $031A;
  58. { "Scrollbar" Parts & States }
  59. { SCROLLBARPARTS }
  60. SBP_ARROWBTN = 1;
  61. SBP_THUMBBTNHORZ = 2;
  62. SBP_THUMBBTNVERT = 3;
  63. SBP_LOWERTRACKHORZ = 4;
  64. SBP_UPPERTRACKHORZ = 5;
  65. SBP_LOWERTRACKVERT = 6;
  66. SBP_UPPERTRACKVERT = 7;
  67. SBP_GRIPPERHORZ = 8;
  68. SBP_GRIPPERVERT = 9;
  69. SBP_SIZEBOX = 10;
  70. { ARROWBTNSTATES }
  71. ABS_UPNORMAL = 1;
  72. ABS_UPHOT = 2;
  73. ABS_UPPRESSED = 3;
  74. ABS_UPDISABLED = 4;
  75. ABS_DOWNNORMAL = 5;
  76. ABS_DOWNHOT = 6;
  77. ABS_DOWNPRESSED = 7;
  78. ABS_DOWNDISABLED = 8;
  79. ABS_LEFTNORMAL = 9;
  80. ABS_LEFTHOT = 10;
  81. ABS_LEFTPRESSED = 11;
  82. ABS_LEFTDISABLED = 12;
  83. ABS_RIGHTNORMAL = 13;
  84. ABS_RIGHTHOT = 14;
  85. ABS_RIGHTPRESSED = 15;
  86. ABS_RIGHTDISABLED = 16;
  87. { SCROLLBARSTATES }
  88. SCRBS_NORMAL = 1;
  89. SCRBS_HOT = 2;
  90. SCRBS_PRESSED = 3;
  91. SCRBS_DISABLED = 4;
  92. { SIZEBOXSTATES }
  93. SZB_RIGHTALIGN = 1;
  94. SZB_LEFTALIGN = 2;
  95. { Access to uxtheme.dll }
  96. type
  97. HIMAGELIST = THandle;
  98. HTHEME = THandle;
  99. _MARGINS = record
  100. cxLeftWidth: Integer; // width of left border that retains its size
  101. cxRightWidth: Integer; // width of right border that retains its size
  102. cyTopHeight: Integer; // height of top border that retains its size
  103. cyBottomHeight: Integer; // height of bottom border that retains its size
  104. end;
  105. MARGINS = _MARGINS;
  106. PMARGINS = ^MARGINS;
  107. TMargins = MARGINS;
  108. var
  109. OpenThemeData: function(hwnd: HWND; pszClassList: LPCWSTR): HTHEME; stdcall;
  110. CloseThemeData: function(hTheme: HTHEME): HRESULT; stdcall;
  111. DrawThemeBackground: function(hTheme: HTHEME; hdc: HDC; iPartId, iStateId: Integer;
  112. const Rect: TRect; pClipRect: PRect): HRESULT; stdcall;
  113. DrawThemeEdge: function(hTheme: HTHEME; hdc: HDC; iPartId, iStateId: Integer; const pDestRect: TRect; uEdge,
  114. uFlags: UINT; pContentRect: PRECT): HRESULT; stdcall;
  115. GetThemeColor: function(hTheme: HTHEME; iPartId, iStateId, iPropId: Integer; var pColor: COLORREF): HRESULT; stdcall;
  116. GetThemeMetric: function(hTheme: HTHEME; hdc: HDC; iPartId, iStateId, iPropId: Integer;
  117. var piVal: Integer): HRESULT; stdcall;
  118. GetThemeMargins: function(hTheme: HTHEME; hdc: HDC; iPartId, iStateId, iPropId: Integer; prc: PRECT;
  119. var pMargins: MARGINS): HRESULT; stdcall;
  120. SetWindowTheme: function(hwnd: HWND; pszSubAppName: LPCWSTR; pszSubIdList: LPCWSTR): HRESULT; stdcall;
  121. IsThemeActive: function: BOOL; stdcall;
  122. IsAppThemed: function: BOOL; stdcall;
  123. EnableTheming: function(fEnable: BOOL): HRESULT; stdcall;
  124. {$ENDIF}
  125. implementation
  126. {$IFDEF Windows}
  127. uses
  128. Messages, Forms, Classes;
  129. const
  130. UXTHEME_DLL = 'uxtheme.dll';
  131. var
  132. DllHandle: THandle;
  133. procedure FreeXPThemes;
  134. begin
  135. if DllHandle <> 0 then
  136. begin
  137. if not IsLibrary then
  138. FreeLibrary(DllHandle);
  139. DllHandle := 0;
  140. OpenThemeData := nil;
  141. CloseThemeData := nil;
  142. DrawThemeBackground := nil;
  143. DrawThemeEdge := nil;
  144. GetThemeColor := nil;
  145. GetThemeMetric := nil;
  146. GetThemeMargins := nil;
  147. SetWindowTheme := nil;
  148. IsThemeActive := nil;
  149. IsAppThemed := nil;
  150. EnableTheming := nil;
  151. end;
  152. end;
  153. function InitXPThemes: Boolean;
  154. begin
  155. if DllHandle = 0 then
  156. begin
  157. DllHandle := LoadLibrary(UXTHEME_DLL);
  158. if DllHandle > 0 then
  159. begin
  160. OpenThemeData := GetProcAddress(DllHandle, 'OpenThemeData');
  161. CloseThemeData := GetProcAddress(DllHandle, 'CloseThemeData');
  162. DrawThemeBackground := GetProcAddress(DllHandle, 'DrawThemeBackground');
  163. DrawThemeEdge := GetProcAddress(DllHandle, 'DrawThemeEdge');
  164. GetThemeColor := GetProcAddress(DllHandle, 'GetThemeColor');
  165. GetThemeMetric := GetProcAddress(DllHandle, 'GetThemeMetric');
  166. GetThemeMargins := GetProcAddress(DllHandle, 'GetThemeMargins');
  167. SetWindowTheme := GetProcAddress(DllHandle, 'SetWindowTheme');
  168. IsThemeActive := GetProcAddress(DllHandle, 'IsThemeActive');
  169. IsAppThemed := GetProcAddress(DllHandle, 'IsAppThemed');
  170. EnableTheming := GetProcAddress(DllHandle, 'EnableTheming');
  171. if (@OpenThemeData = nil) or (@CloseThemeData = nil) or (@IsThemeActive = nil) or
  172. (@IsAppThemed = nil) or (@EnableTheming = nil) then FreeXPThemes;
  173. end;
  174. end;
  175. Result := DllHandle > 0;
  176. end;
  177. function UseXPThemes: Boolean;
  178. begin
  179. Result := (DllHandle > 0) and IsAppThemed and IsThemeActive;
  180. end;
  181. type
  182. TThemeNexus = class
  183. private
  184. FWindowHandle: HWND;
  185. protected
  186. procedure WndProc(var Message: TMessage);
  187. procedure OpenVisualStyles;
  188. procedure CloseVisualStyles;
  189. public
  190. constructor Create;
  191. destructor Destroy; override;
  192. end;
  193. {$IFDEF SUPPORT_XPTHEMES}
  194. {$IFDEF XPTHEMES}
  195. var
  196. ThemeNexus: TThemeNexus;
  197. {$ENDIF}
  198. {$ENDIF}
  199. { TThemeNexus }
  200. constructor TThemeNexus.Create;
  201. begin
  202. FWindowHandle := {$IFDEF FPC}Classes.{$ENDIF}AllocateHWnd(WndProc);
  203. OpenVisualStyles;
  204. end;
  205. destructor TThemeNexus.Destroy;
  206. begin
  207. CloseVisualStyles;
  208. {$IFDEF FPC}Classes.{$ENDIF}DeallocateHWnd(FWindowHandle);
  209. inherited;
  210. end;
  211. procedure TThemeNexus.OpenVisualStyles;
  212. begin
  213. USE_THEMES := False;
  214. if InitXPThemes then
  215. begin
  216. USE_THEMES := UseXPThemes;
  217. if USE_THEMES then
  218. begin
  219. SCROLLBAR_THEME := OpenThemeData(FWindowHandle, 'SCROLLBAR');
  220. GLOBALS_THEME := OpenThemeData(FWindowHandle, 'GLOBALS');
  221. end;
  222. end;
  223. end;
  224. procedure TThemeNexus.CloseVisualStyles;
  225. begin
  226. if not IsLibrary and UseXPThemes then
  227. begin
  228. if SCROLLBAR_THEME <> 0 then
  229. begin
  230. CloseThemeData(SCROLLBAR_THEME);
  231. SCROLLBAR_THEME := 0;
  232. end;
  233. if GLOBALS_THEME <> 0 then
  234. begin
  235. CloseThemeData(GLOBALS_THEME);
  236. GLOBALS_THEME := 0;
  237. end;
  238. end;
  239. FreeXPThemes;
  240. end;
  241. procedure TThemeNexus.WndProc(var Message: TMessage);
  242. begin
  243. case Message.Msg of
  244. WM_THEMECHANGED:
  245. begin
  246. CloseVisualStyles;
  247. OpenVisualStyles;
  248. end;
  249. end;
  250. with Message do Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
  251. end;
  252. {$IFDEF SUPPORT_XPTHEMES}
  253. {$IFDEF XPTHEMES}
  254. initialization
  255. ThemeNexus := TThemeNexus.Create;
  256. finalization
  257. ThemeNexus.Free;
  258. {$ENDIF}
  259. {$ENDIF}
  260. {$ENDIF}
  261. end.