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