// ------------------------------------------------------------------------------------// // TODO: write cool acknowledgement here // // // // original file name ThemeSrv.pas changed to themes.pas to be compatible with delphi // // adapted for Lazarus by Lazarus Team // // ------------------------------------------------------------------------------------// //---------------------------------------------------------------------------------------------------------------------- // Windows XP Theme Manager is freeware. You may freely use it in any software, including commercial software, provided // you accept the following conditions: // // 1) The software may not be included into component collections and similar compilations which are sold. If you want // to distribute this software for money then contact me first and ask for my permission. // 2) My copyright notices in the source code may not be removed or modified. // 3) If you modify and/or distribute the code to any third party then you must not veil the original author. It must // always be clearly identifiable that I, Mike Lischke, am the original author. // Although it is not required it would be a nice move to recognize my work by adding a citation to the application's // about box or a similar place. // // The original code is ThemeSrv.pas, released 03. February 2002. // // The initial developer of the original code is: // Mike Lischke (public@soft-gems.net, www.soft-gems.net). // // Portions created by Mike Lischke are // (C) 2001-2005 Mike Lischke. All Rights Reserved. //---------------------------------------------------------------------------------------------------------------------- // // This unit contains the implementation of TThemeServices which is a designed to manage all necessary aspects of // the Windows XP (and up) theme APIs. The component is responsible for loading and unloading of the theme DLL // and offers properties and methods to test for various aspects of the theme APIs and to ease painting of themed // window content. // // The TThemeServices class is designed to work for controls which need XP paint stuff. It does not manipulate // any VCL class (for this task TThemeManager is responsible) and can be used standalone (also as general support // tool in an application). Using the global ThemeServices function you can implicitely create and use a single // instance of the class. Theme Manager uses the same approach. //---------------------------------------------------------------------------------------------------------------------- // For version information and history see ThemeMgr.pas source file. //---------------------------------------------------------------------------------------------------------------------- unit Themes; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Types, Math, // LCL - Controls cannot be used here to prevent circular references LCLProc, LCLType, Graphics, TmSchema, // LazUtils GraphType; type // These are all elements which can be themed. TThemedElement = ( teButton, teClock, teComboBox, teEdit, teExplorerBar, teHeader, teListView, teMenu, tePage, teProgress, teRebar, teScrollBar, teSpin, teStartPanel, teStatus, teTab, teTaskBand, teTaskBar, teToolBar, teToolTip, teTrackBar, teTrayNotify, teTreeview, teWindow ); // 'Button' theme data TThemedButton = ( tbButtonDontCare, tbButtonRoot, // The root part of each element is sometimes used for special painting and does not // belong to a certain state. tbPushButtonNormal, tbPushButtonHot, tbPushButtonPressed, tbPushButtonDisabled, tbPushButtonDefaulted, tbRadioButtonUncheckedNormal, tbRadioButtonUncheckedHot, tbRadioButtonUncheckedPressed, tbRadioButtonUncheckedDisabled, tbRadioButtonCheckedNormal, tbRadioButtonCheckedHot, tbRadioButtonCheckedPressed, tbRadioButtonCheckedDisabled, tbCheckBoxUncheckedNormal, tbCheckBoxUncheckedHot, tbCheckBoxUncheckedPressed, tbCheckBoxUncheckedDisabled, tbCheckBoxCheckedNormal, tbCheckBoxCheckedHot, tbCheckBoxCheckedPressed, tbCheckBoxCheckedDisabled, tbCheckBoxMixedNormal, tbCheckBoxMixedHot, tbCheckBoxMixedPressed, tbCheckBoxMixedDisabled, tbGroupBoxNormal, tbGroupBoxDisabled, tbUserButton ); // 'Clock' theme data TThemedClock = ( tcClockDontCare, tcClockRoot, tcTimeNormal ); // 'ComboBox' theme data TThemedComboBox = ( tcComboBoxDontCare, tcComboBoxRoot, tcDropDownButtonNormal, tcDropDownButtonHot, tcDropDownButtonPressed, tcDropDownButtonDisabled ); // 'Edit' theme data TThemedEdit = ( teEditDontCare, teEditRoot, teEditTextNormal, teEditTextHot, teEditTextSelected, teEditTextDisabled, teEditTextFocused, teEditTextReadOnly, teEditTextAssist, teEditCaret ); // 'ExplorerBar' theme data TThemedExplorerBar = ( tebExplorerBarDontCare, tebExplorerBarRoot, tebHeaderBackgroundNormal, tebHeaderBackgroundHot, tebHeaderBackgroundPressed, tebHeaderCloseNormal, tebHeaderCloseHot, tebHeaderClosePressed, tebHeaderPinNormal, tebHeaderPinHot, tebHeaderPinPressed, tebHeaderPinSelectedNormal, tebHeaderPinSelectedHot, tebHeaderPinSelectedPressed, tebIEBarMenuNormal, tebIEBarMenuHot, tebIEBarMenuPressed, tebNormalGroupBackground, tebNormalGroupCollapseNormal, tebNormalGroupCollapseHot, tebNormalGroupCollapsePressed, tebNormalGroupExpandNormal, tebNormalGroupExpandHot, tebNormalGroupExpandPressed, tebNormalGroupHead, tebSpecialGroupBackground, tebSpecialGroupCollapseSpecial, tebSpecialGroupCollapseHot, tebSpecialGroupCollapsePressed, tebSpecialGroupExpandSpecial, tebSpecialGroupExpandHot, tebSpecialGroupExpandPressed, tebSpecialGroupHead ); // 'Header' theme data TThemedHeader = ( thHeaderDontCare, thHeaderRoot, thHeaderItemNormal, thHeaderItemHot, thHeaderItemPressed, thHeaderItemLeftNormal, thHeaderItemLeftHot, thHeaderItemLeftPressed, thHeaderItemRightNormal, thHeaderItemRightHot, thHeaderItemRightPressed, thHeaderSortArrowSortedUp, thHeaderSortArrowSortedDown ); // 'ListView' theme data TThemedListview = ( tlListviewDontCare, tlListviewRoot, tlListItemNormal, tlListItemHot, tlListItemSelected, tlListItemDisabled, tlListItemSelectedNotFocus, tlListGroup, tlListDetail, tlListSortDetail, tlEmptyText ); // 'Menu' theme data TThemedMenu = ( tmMenuDontCare, tmMenuRoot, tmMenuItemNormal, tmMenuItemSelected, tmMenuItemDemoted, tmMenuDropDown, tmMenuBarItem, tmMenuBarDropDown, tmChevron, tmSeparator, tmBarBackgroundActive, tmBarBackgroundInactive, tmBarItemNormal, tmBarItemHot, tmBarItemPushed, tmBarItemDisabled, tmBarItemDisabledHot, tmBarItemDisabledPushed, tmPopupBackground, tmPopupBorders, tmPopupCheckMarkNormal, tmPopupCheckMarkDisabled, tmPopupBulletNormal, tmPopupBulletDisabled, tmPopupCheckBackgroundDisabled, tmPopupCheckBackgroundNormal, tmPopupCheckBackgroundBitmap, tmPopupGutter, tmPopupItemNormal, tmPopupItemHot, tmPopupItemDisabled, tmPopupItemDisabledHot, tmPopupSeparator, tmPopupSubmenuNormal, tmPopupSubmenuDisabled, tmSystemCloseNormal, tmSystemCloseDisabled, tmSystemMaximizeNormal, tmSystemMaximizeDisabled, tmSystemMinimizeNormal, tmSystemMinimizeDisabled, tmSystemRestoreNormal, tmSystemRestoreDisabled ); // 'Page' theme data TThemedPage = ( tpPageDontCare, tpPageRoot, tpUpNormal, tpUpHot, tpUpPressed, tpUpDisabled, tpDownNormal, tpDownHot, tpDownPressed, tpDownDisabled, tpUpHorzNormal, tpUpHorzHot, tpUpHorzPressed, tpUpHorzDisabled, tpDownHorzNormal, tpDownHorzHot, tpDownHorzPressed, tpDownHorzDisabled ); // 'Progress' theme data TThemedProgress = ( tpProgressDontCare, tpProgressRoot, tpBar, tpBarVert, tpChunk, tpChunkVert ); // 'Rebar' theme data TThemedRebar = ( trRebarDontCare, trRebarRoot, trGripper, trGripperVert, trBandNormal, trBandHot, trBandPressed, trBandDisabled, trBandChecked, trBandHotChecked, trChevronNormal, trChevronHot, trChevronPressed, trChevronDisabled, trChevronVertNormal, trChevronVertHot, trChevronVertPressed, trChevronVertDisabled ); // 'ScrollBar' theme data TThemedScrollBar = ( tsScrollBarDontCare, tsScrollBarRoot, tsArrowBtnUpNormal, tsArrowBtnUpHot, tsArrowBtnUpPressed, tsArrowBtnUpDisabled, tsArrowBtnDownNormal, tsArrowBtnDownHot, tsArrowBtnDownPressed, tsArrowBtnDownDisabled, tsArrowBtnLeftNormal, tsArrowBtnLeftHot, tsArrowBtnLeftPressed, tsArrowBtnLeftDisabled, tsArrowBtnRightNormal, tsArrowBtnRightHot, tsArrowBtnRightPressed, tsArrowBtnRightDisabled, tsThumbBtnHorzNormal, tsThumbBtnHorzHot, tsThumbBtnHorzPressed, tsThumbBtnHorzDisabled, tsThumbBtnVertNormal, tsThumbBtnVertHot, tsThumbBtnVertPressed, tsThumbBtnVertDisabled, tsLowerTrackHorzNormal, tsLowerTrackHorzHot, tsLowerTrackHorzPressed, tsLowerTrackHorzDisabled, tsUpperTrackHorzNormal, tsUpperTrackHorzHot, tsUpperTrackHorzPressed, tsUpperTrackHorzDisabled, tsLowerTrackVertNormal, tsLowerTrackVertHot, tsLowerTrackVertPressed, tsLowerTrackVertDisabled, tsUpperTrackVertNormal, tsUpperTrackVertHot, tsUpperTrackVertPressed, tsUpperTrackVertDisabled, tsGripperHorzNormal, tsGripperHorzHot, tsGripperHorzPressed, tsGripperHorzDisabled, tsGripperVertNormal, tsGripperVertHot, tsGripperVertPressed, tsGripperVertDisabled, tsSizeBoxRightAlign, tsSizeBoxLeftAlign ); // 'Spin' theme data TThemedSpin = ( tsSpinDontCare, tsSpinRoot, tsUpNormal, tsUpHot, tsUpPressed, tsUpDisabled, tsDownNormal, tsDownHot, tsDownPressed, tsDownDisabled, tsUpHorzNormal, tsUpHorzHot, tsUpHorzPressed, tsUpHorzDisabled, tsDownHorzNormal, tsDownHorzHot, tsDownHorzPressed, tsDownHorzDisabled ); // 'StartPanel' theme data TThemedStartPanel = ( tspStartPanelDontCare, tspStartPanelRoot, tspUserPane, tspMorePrograms, tspMoreProgramsArrowNormal, tspMoreProgramsArrowHot, tspMoreProgramsArrowPressed, tspProgList, tspProgListSeparator, tspPlacesList, tspPlacesListSeparator, tspLogOff, tspLogOffButtonsNormal, tspLogOffButtonsHot, tspLogOffButtonsPressed, tspUserPicture, tspPreview ); // 'Status' theme data TThemedStatus = ( tsStatusDontCare, tsStatusRoot, tsPane, tsGripperPane, tsGripper ); // 'Tab' theme data TThemedTab = ( ttTabDontCare, ttTabRoot, ttTabItemNormal, ttTabItemHot, ttTabItemSelected, ttTabItemDisabled, ttTabItemFocused, ttTabItemLeftEdgeNormal, ttTabItemLeftEdgeHot, ttTabItemLeftEdgeSelected, ttTabItemLeftEdgeDisabled, ttTabItemLeftEdgeFocused, ttTabItemRightEdgeNormal, ttTabItemRightEdgeHot, ttTabItemRightEdgeSelected, ttTabItemRightEdgeDisabled, ttTabItemRightEdgeFocused, ttTabItemBothEdgeNormal, ttTabItemBothEdgeHot, ttTabItemBothEdgeSelected, ttTabItemBothEdgeDisabled, ttTabItemBothEdgeFocused, ttTopTabItemNormal, ttTopTabItemHot, ttTopTabItemSelected, ttTopTabItemDisabled, ttTopTabItemFocused, ttTopTabItemLeftEdgeNormal, ttTopTabItemLeftEdgeHot, ttTopTabItemLeftEdgeSelected, ttTopTabItemLeftEdgeDisabled, ttTopTabItemLeftEdgeFocused, ttTopTabItemRightEdgeNormal, ttTopTabItemRightEdgeHot, ttTopTabItemRightEdgeSelected, ttTopTabItemRightEdgeDisabled, ttTopTabItemRightEdgeFocused, ttTopTabItemBothEdgeNormal, ttTopTabItemBothEdgeHot, ttTopTabItemBothEdgeSelected, ttTopTabItemBothEdgeDisabled, ttTopTabItemBothEdgeFocused, ttPane, ttBody ); // 'TaskBand' theme data TThemedTaskBand = ( ttbTaskBandDontCare, ttbTaskBandRoot, ttbGroupCount, ttbFlashButton, ttpFlashButtonGroupMenu ); // 'TaskBar' theme data TThemedTaskBar = ( ttTaskBarDontCare, ttTaskBarRoot, ttbTimeNormal ); // 'ToolBar' theme data TThemedToolBar = ( ttbToolBarDontCare, ttbToolBarRoot, ttbButtonNormal, ttbButtonHot, ttbButtonPressed, ttbButtonDisabled, ttbButtonChecked, ttbButtonCheckedHot, ttbDropDownButtonNormal, ttbDropDownButtonHot, ttbDropDownButtonPressed, ttbDropDownButtonDisabled, ttbDropDownButtonChecked, ttbDropDownButtonCheckedHot, ttbSplitButtonNormal, ttbSplitButtonHot, ttbSplitButtonPressed, ttbSplitButtonDisabled, ttbSplitButtonChecked, ttbSplitButtonCheckedHot, ttbSplitButtonDropDownNormal, ttbSplitButtonDropDownHot, ttbSplitButtonDropDownPressed, ttbSplitButtonDropDownDisabled, ttbSplitButtonDropDownChecked, ttbSplitButtonDropDownCheckedHot, ttbSeparatorNormal, ttbSeparatorHot, ttbSeparatorPressed, ttbSeparatorDisabled, ttbSeparatorChecked, ttbSeparatorCheckedHot, ttbSeparatorVertNormal, ttbSeparatorVertHot, ttbSeparatorVertPressed, ttbSeparatorVertDisabled, ttbSeparatorVertChecked, ttbSeparatorVertCheckedHot ); // 'ToolTip' theme data TThemedToolTip = ( tttToolTipDontCare, tttToolTipRoot, tttStandardNormal, tttStandardLink, tttStandardTitleNormal, tttStandardTitleLink, tttBaloonNormal, tttBaloonLink, tttBaloonTitleNormal, tttBaloonTitleLink, tttCloseNormal, tttCloseHot, tttClosePressed ); // 'TrackBar' theme data TThemedTrackBar = ( ttbTrackBarDontCare, ttbTrackBarRoot, ttbTrack, ttbTrackVert, ttbThumbNormal, ttbThumbHot, ttbThumbPressed, ttbThumbFocused, ttbThumbDisabled, ttbThumbBottomNormal, ttbThumbBottomHot, ttbThumbBottomPressed, ttbThumbBottomFocused, ttbThumbBottomDisabled, ttbThumbTopNormal, ttbThumbTopHot, ttbThumbTopPressed, ttbThumbTopFocused, ttbThumbTopDisabled, ttbThumbVertNormal, ttbThumbVertHot, ttbThumbVertPressed, ttbThumbVertFocused, ttbThumbVertDisabled, ttbThumbLeftNormal, ttbThumbLeftHot, ttbThumbLeftPressed, ttbThumbLeftFocused, ttbThumbLeftDisabled, ttbThumbRightNormal, ttbThumbRightHot, ttbThumbRightPressed, ttbThumbRightFocused, ttbThumbRightDisabled, ttbThumbTics, ttbThumbTicsVert ); // 'TrayNotify' theme data TThemedTrayNotify = ( ttnTrayNotifyDontCare, ttnTrayNotifyRoot, ttnBackground, ttnAnimBackground ); // 'Treeview' theme data TThemedTreeview = ( ttTreeviewDontCare, ttTreeviewRoot, ttItemNormal, ttItemHot, ttItemSelected, ttItemDisabled, ttItemSelectedNotFocus, ttGlyphClosed, ttGlyphOpened, ttBranch, ttHotGlyphClosed, ttHotGlyphOpened ); // 'Window' theme data TThemedWindow = ( twWindowDontCare, twWindowRoot, twCaptionActive, twCaptionInactive, twCaptionDisabled, twSmallCaptionActive, twSmallCaptionInactive, twSmallCaptionDisabled, twMinCaptionActive, twMinCaptionInactive, twMinCaptionDisabled, twSmallMinCaptionActive, twSmallMinCaptionInactive, twSmallMinCaptionDisabled, twMaxCaptionActive, twMaxCaptionInactive, twMaxCaptionDisabled, twSmallMaxCaptionActive, twSmallMaxCaptionInactive, twSmallMaxCaptionDisabled, twFrameLeftActive, twFrameLeftInactive, twFrameRightActive, twFrameRightInactive, twFrameBottomActive, twFrameBottomInactive, twSmallFrameLeftActive, twSmallFrameLeftInactive, twSmallFrameRightActive, twSmallFrameRightInactive, twSmallFrameBottomActive, twSmallFrameBottomInactive, twSysButtonNormal, twSysButtonHot, twSysButtonPushed, twSysButtonDisabled, twSysButtonInactive, twMDISysButtonNormal, twMDISysButtonHot, twMDISysButtonPushed, twMDISysButtonDisabled, twMDISysButtonInactive, twMinButtonNormal, twMinButtonHot, twMinButtonPushed, twMinButtonDisabled, twMinButtonInactive, twMDIMinButtonNormal, twMDIMinButtonHot, twMDIMinButtonPushed, twMDIMinButtonDisabled, twMDIMinButtonInactive, twMaxButtonNormal, twMaxButtonHot, twMaxButtonPushed, twMaxButtonDisabled, twMaxButtonInactive, twCloseButtonNormal, twCloseButtonHot, twCloseButtonPushed, twCloseButtonDisabled, twCloseButtonInactive, twSmallCloseButtonNormal, twSmallCloseButtonHot, twSmallCloseButtonPushed, twSmallCloseButtonDisabled, twSmallCloseButtonInactive, twMDICloseButtonNormal, twMDICloseButtonHot, twMDICloseButtonPushed, twMDICloseButtonDisabled, twMDICloseButtonInactive, twRestoreButtonNormal, twRestoreButtonHot, twRestoreButtonPushed, twRestoreButtonDisabled, twRestoreButtonInactive, twMDIRestoreButtonNormal, twMDIRestoreButtonHot, twMDIRestoreButtonPushed, twMDIRestoreButtonDisabled, twMDIRestoreButtonInactive, twHelpButtonNormal, twHelpButtonHot, twHelpButtonPushed, twHelpButtonDisabled, twHelpButtonInactive, twMDIHelpButtonNormal, twMDIHelpButtonHot, twMDIHelpButtonPushed, twMDIHelpButtonDisabled, twMDIHelpButtonInactive, twHorzScrollNormal, twHorzScrollHot, twHorzScrollPushed, twHorzScrollDisabled, twHorzThumbNormal, twHorzThumbHot, twHorzThumbPushed, twHorzThumbDisabled, twVertScrollNormal, twVertScrollHot, twVertScrollPushed, twVertScrollDisabled, twVertThumbNormal, twVertThumbHot, twVertThumbPushed, twVertThumbDisabled, twDialog, twCaptionSizingTemplate, twSmallCaptionSizingTemplate, twFrameLeftSizingTemplate, twSmallFrameLeftSizingTemplate, twFrameRightSizingTemplate, twSmallFrameRightSizingTemplate, twFrameBottomSizingTemplate, twSmallFrameBottomSizingTemplate ); PThemedElementDetails = ^TThemedElementDetails; TThemedElementDetails = record Element: TThemedElement; Part, State: Integer; end; TThemeOption = ( toShowButtonImages, // show images on buttons toShowMenuImages, // show images on menus toUseGlyphEffects // use hot/down effects on (button) glyphs ); // TThemeServices is a small foot print class to provide the user with pure // Windows XP theme related abilities like painting elements and text or // retrieving certain info. TThemeServices = class(TObject) private FThemesAvailable, FUseThemes, FThemedControlsEnabled: Boolean; FOnThemeChange: TNotifyEvent; // Called when the current window theme has changed. FDottedBrush: HBrush; function GetThemesEnabled: Boolean; function GetDottedBrush: HBrush; protected function InitThemes: Boolean; virtual; procedure UnloadThemeData; virtual; function UseThemes: Boolean; virtual; function ThemedControlsEnabled: Boolean; virtual; function InternalColorToRGB(Details: TThemedElementDetails; Color: LongInt): COLORREF; virtual; procedure InternalDrawParentBackground(Window: HWND; Target: HDC; Bounds: PRect); virtual; public constructor Create; destructor Destroy; override; procedure IntfDoOnThemeChange; virtual; // state helpers function IsDisabled(Details: TThemedElementDetails): Boolean; function IsPushed(Details: TThemedElementDetails): Boolean; function IsHot(Details: TThemedElementDetails): Boolean; function IsChecked(Details: TThemedElementDetails): Boolean; function IsMixed(Details: TThemedElementDetails): Boolean; function GetElementDetails(Detail: TThemedButton): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedClock): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedComboBox): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedEdit): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedExplorerBar): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedHeader): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedListView): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedMenu): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedPage): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedProgress): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedRebar): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedScrollBar): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedSpin): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedStartPanel): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedStatus): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedTab): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedTaskBand): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedTaskBar): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedToolBar): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedToolTip): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedTrackBar): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedTrayNotify): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedTreeview): TThemedElementDetails; overload; function GetElementDetails(Detail: TThemedWindow): TThemedElementDetails; overload; function GetDetailSize(Details: TThemedElementDetails): TSize; virtual; function GetDetailRegion(DC: HDC; Details: TThemedElementDetails; const R: TRect): HRGN; virtual; function GetStockImage(StockID: LongInt; out Image, Mask: HBitmap): Boolean; virtual; function GetOption(AOption: TThemeOption): Integer; virtual; function GetTextExtent(DC: HDC; Details: TThemedElementDetails; const S: String; Flags: Cardinal; BoundingRect: PRect): TRect; virtual; function ColorToRGB(Color: LongInt; Details: PThemedElementDetails = nil): COLORREF; function ContentRect(DC: HDC; Details: TThemedElementDetails; BoundingRect: TRect): TRect; virtual; procedure DrawEdge(DC: HDC; Details: TThemedElementDetails; const R: TRect; Edge, Flags: Cardinal; AContentRect: PRect = nil); virtual; procedure DrawElement(DC: HDC; Details: TThemedElementDetails; const R: TRect; ClipRect: PRect = nil); virtual; procedure DrawIcon(DC: HDC; Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST; Index: Integer); virtual; overload; procedure DrawIcon(ACanvas: TPersistent; Details: TThemedElementDetails; const P: TPoint; AImageList: TPersistent; Index: Integer; AImageWidth: Integer = 0; ARefControl: TPersistent = nil); virtual; overload; procedure DrawParentBackground(Window: HWND; Target: HDC; Details: PThemedElementDetails; OnlyIfTransparent: Boolean; Bounds: PRect = nil); procedure DrawText(DC: HDC; Details: TThemedElementDetails; const S: String; R: TRect; Flags, Flags2: Cardinal); virtual; overload; procedure DrawText(ACanvas: TPersistent; Details: TThemedElementDetails; const S: String; R: TRect; Flags, Flags2: Cardinal); virtual; overload; function HasTransparentParts(Details: TThemedElementDetails): Boolean; virtual; procedure PaintBorder(Control: TObject; EraseLRCorner: Boolean); virtual; procedure UpdateThemes; property DottedBrush: HBRUSH read GetDottedBrush; property ThemesAvailable: Boolean read FThemesAvailable; property ThemesEnabled: Boolean read GetThemesEnabled; property OnThemeChange: TNotifyEvent read FOnThemeChange write FOnThemeChange; end; function ThemeServices: TThemeServices; function ThemedElementDetailsEqual(const D1, D2: TThemedElementDetails): Boolean; //---------------------------------------------------------------------------------------------------------------------- const // Do not modify the copyright in any way! Usage of this unit is prohibited without the copyright notice // in the compiled binary file. ThemeManagerCopyright: string = 'Theme manager © 2001-2005 Mike Lischke'; type TThemesImageDrawEvent = procedure(AImageList: TPersistent; ACanvas: TPersistent; AX, AY, AIndex: Integer; ADrawEffect: TGraphicsDrawEffect; AImageWidth: Integer; ARefControl: TPersistent); var ThemesImageDrawEvent: TThemesImageDrawEvent = nil; // set by unit ImgList if used implementation uses InterfaceBase, LCLIntf; //---------------------------------------------------------------------------------------------------------------------- function ThemeServices: TThemeServices; begin Result := WidgetSet.ThemeServices; end; function ThemedElementDetailsEqual(const D1, D2: TThemedElementDetails): Boolean; begin Result := CompareMem(@D1, @D2, SizeOf(TThemedElementDetails)); end; //----------------- TThemeServices ------------------------------------------------------------------------------------- constructor TThemeServices.Create; begin FDottedBrush := 0; FThemesAvailable := InitThemes; UpdateThemes; end; //---------------------------------------------------------------------------------------------------------------------- destructor TThemeServices.Destroy; begin UnloadThemeData; if FDottedBrush <> 0 then DeleteObject(FDottedBrush); inherited; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetThemesEnabled: Boolean; begin Result := FThemesAvailable and FUseThemes and FThemedControlsEnabled; end; function TThemeServices.GetDottedBrush: HBrush; const LineBitsDotted: array[0..7] of Word = ($55, $AA, $55, $AA, $55, $AA, $55, $AA); var DottedBitmap: HBitmap; begin if FDottedBrush = 0 then begin DottedBitmap := CreateBitmap(8, 8, 1, 1, @LineBitsDotted); if DottedBitmap <> 0 then begin FDottedBrush := CreatePatternBrush(DottedBitmap); DeleteObject(DottedBitmap); end; end; Result := FDottedBrush; end; //---------------------------------------------------------------------------------------------------------------------- procedure TThemeServices.IntfDoOnThemeChange; begin if Assigned(FOnThemeChange) then FOnThemeChange(Self); end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedButton): TThemedElementDetails; var Base: Integer; begin Result.Element := teButton; with Result do begin case Detail of tbPushButtonNormal..tbPushButtonDefaulted: begin Part := BP_PUSHBUTTON; Base := Ord(tbPushButtonNormal); end; tbRadioButtonUncheckedNormal..tbRadioButtonCheckedDisabled: begin Part := BP_RADIOBUTTON; Base := Ord(tbRadioButtonUncheckedNormal); end; tbCheckBoxUncheckedNormal..tbCheckBoxMixedDisabled: begin Part := BP_CHECKBOX; Base := Ord(tbCheckBoxUncheckedNormal); end; tbGroupBoxNormal..tbGroupBoxDisabled: begin Part := BP_GROUPBOX; Base := Ord(tbGroupBoxNormal); end; tbUserButton: begin Part := BP_USERBUTTON; Base := Ord(tbUserButton); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedClock): TThemedElementDetails; var Base: Integer; begin Result.Element := teClock; with Result do begin case Detail of tcTimeNormal: begin Part := CLP_TIME; Base := Ord(tcTimeNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedComboBox): TThemedElementDetails; var Base: Integer; begin Result.Element := teComboBox; with Result do begin case Detail of tcDropDownButtonNormal..tcDropDownButtonDisabled: begin Part := CP_DROPDOWNBUTTON; Base := Ord(tcDropDownButtonNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedEdit): TThemedElementDetails; var Base: Integer; begin Result.Element := teEdit; with Result do begin case Detail of teEditTextNormal..teEditTextAssist: begin Part := EP_EDITTEXT; Base := Ord(teEditTextNormal); end; teEditCaret: begin Part := EP_CARET; Base := Ord(teEditCaret); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedExplorerBar): TThemedElementDetails; var Base: Integer; begin Result.Element := teExplorerBar; with Result do begin case Detail of tebHeaderBackgroundNormal..tebHeaderBackgroundPressed: begin Part := EBP_HEADERBACKGROUND; Base := Ord(tebHeaderBackgroundNormal); end; tebHeaderCloseNormal..tebHeaderClosePressed: begin Part := EBP_HEADERCLOSE; Base := Ord(tebHeaderCloseNormal); end; tebHeaderPinNormal..tebHeaderPinSelectedPressed: begin Part := EBP_HEADERPIN; Base := Ord(tebHeaderPinSelectedNormal); end; tebIEBarMenuNormal..tebIEBarMenuPressed: begin Part := EBP_IEBARMENU; Base := Ord(tebIEBarMenuNormal); end; tebNormalGroupBackground: begin Part := EBP_NORMALGROUPBACKGROUND; Base := Ord(tebNormalGroupBackground); end; tebNormalGroupCollapseNormal..tebNormalGroupCollapsePressed: begin Part := EBP_NORMALGROUPCOLLAPSE; Base := Ord(tebNormalGroupCollapseNormal); end; tebNormalGroupExpandNormal..tebNormalGroupExpandPressed: begin Part := EBP_NORMALGROUPEXPAND; Base := Ord(tebNormalGroupExpandNormal); end; tebNormalGroupHead: begin Part := EBP_NORMALGROUPHEAD; Base := Ord(tebNormalGroupHead); end; tebSpecialGroupBackground: begin Part := EBP_SPECIALGROUPBACKGROUND; Base := Ord(tebSpecialGroupBackground); end; tebSpecialGroupCollapseSpecial..tebSpecialGroupCollapsePressed: begin Part := EBP_SPECIALGROUPCOLLAPSE; Base := Ord(tebSpecialGroupCollapseSpecial); end; tebSpecialGroupExpandSpecial..tebSpecialGroupExpandPressed: begin Part := EBP_SPECIALGROUPEXPAND; Base := Ord(tebSpecialGroupExpandSpecial); end; tebSpecialGroupHead: begin Part := EBP_SPECIALGROUPHEAD; Base := Ord(tebSpecialGroupHead); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedHeader): TThemedElementDetails; var Base: Integer; begin Result.Element := teHeader; with Result do begin case Detail of thHeaderItemNormal..thHeaderItemPressed: begin Part := HP_HEADERITEM; Base := Ord(thHeaderItemNormal); end; thHeaderItemLeftNormal..thHeaderItemLeftPressed: begin Part := HP_HEADERITEMLEFT; Base := Ord(thHeaderItemLeftNormal); end; thHeaderItemRightNormal..thHeaderItemRightPressed: begin Part := HP_HEADERITEMRIGHT; Base := Ord(thHeaderItemRightNormal); end; thHeaderSortArrowSortedUp..thHeaderSortArrowSortedDown: begin Part := HP_HEADERSORTARROW; Base := Ord(thHeaderSortArrowSortedUp); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedListView ): TThemedElementDetails; var Base: Integer; begin Result.Element := teListView; with Result do begin case Detail of tlListItemNormal..tlListItemSelectedNotFocus: begin Part := LVP_LISTITEM; Base := Ord(tlListItemNormal); end; tlListGroup: begin Part := LVP_LISTGROUP; Base := Ord(tlListGroup); end; tlListDetail: begin Part := LVP_LISTDETAIL; Base := Ord(tlListDetail); end; tlListSortDetail: begin Part := LVP_LISTSORTEDDETAIL; Base := Ord(tlListSortDetail); end; tlEmptyText: begin Part := LVP_EMPTYTEXT; Base := Ord(tlEmptyText); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedMenu): TThemedElementDetails; var Base: Integer; begin Result.Element := teMenu; with Result do begin case Detail of tmMenuItemNormal..tmMenuItemDemoted: begin Part := MENU_MENUITEM_TMSCHEMA; Base := Ord(tmMenuItemNormal); end; tmMenuDropDown: begin Part := MENU_MENUDROPDOWN_TMSCHEMA; Base := Ord(tmMenuDropDown); end; tmMenuBarItem: begin Part := MENU_MENUBARITEM_TMSCHEMA; Base := Ord(tmMenuBarItem); end; tmMenuBarDropDown: begin Part := MENU_MENUBARDROPDOWN_TMSCHEMA; Base := Ord(tmMenuBarDropDown); end; tmChevron: begin Part := MENU_CHEVRON_TMSCHEMA; Base := Ord(tmChevron); end; tmSeparator: begin Part := MENU_SEPARATOR_TMSCHEMA; Base := Ord(tmSeparator); end; tmBarBackgroundActive..tmBarBackgroundInactive: begin Part := MENU_BARBACKGROUND; Base := Ord(tmBarBackgroundActive); end; tmBarItemNormal..tmBarItemDisabledPushed: begin Part := MENU_BARITEM; Base := Ord(tmBarItemNormal); end; tmPopupBackground: begin Part := MENU_POPUPBACKGROUND; Base := Ord(tmPopupBackground); end; tmPopupBorders: begin Part := MENU_POPUPBORDERS; Base := Ord(tmPopupBorders); end; tmPopupCheckMarkNormal..tmPopupBulletDisabled: begin Part := MENU_POPUPCHECK; Base := Ord(tmPopupCheckMarkNormal); end; tmPopupCheckBackgroundDisabled..tmPopupCheckBackgroundBitmap: begin Part := MENU_POPUPCHECKBACKGROUND; Base := Ord(tmPopupCheckBackgroundDisabled); end; tmPopupGutter: begin Part := MENU_POPUPGUTTER; Base := Ord(tmPopupGutter); end; tmPopupItemNormal..tmPopupItemDisabledHot: begin Part := MENU_POPUPITEM; Base := Ord(tmPopupItemNormal); end; tmPopupSeparator: begin Part := MENU_POPUPSEPARATOR; Base := Ord(tmPopupSeparator); end; tmPopupSubmenuNormal..tmPopupSubmenuDisabled: begin Part := MENU_POPUPSUBMENU; Base := Ord(tmPopupSubmenuNormal); end; tmSystemCloseNormal..tmSystemCloseDisabled: begin Part := MENU_SYSTEMCLOSE; Base := Ord(tmSystemCloseNormal); end; tmSystemMaximizeNormal..tmSystemMaximizeDisabled: begin Part := MENU_SYSTEMMAXIMIZE; Base := Ord(tmSystemMaximizeNormal); end; tmSystemMinimizeNormal..tmSystemMinimizeDisabled: begin Part := MENU_SYSTEMMINIMIZE; Base := Ord(tmSystemMinimizeNormal); end; tmSystemRestoreNormal..tmSystemRestoreDisabled: begin Part := MENU_SYSTEMRESTORE; Base := Ord(tmSystemRestoreNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedPage): TThemedElementDetails; var Base: Integer; begin Result.Element := tePage; with Result do begin case Detail of tpUpNormal..tpUpDisabled: begin Part := PGRP_UP; Base := Ord(tpUpNormal); end; tpDownNormal..tpDownDisabled: begin Part := PGRP_DOWN; Base := Ord(tpDownNormal); end; tpUpHorzNormal..tpUpHorzDisabled: begin Part := PGRP_UPHORZ; Base := Ord(tpUpHorzNormal); end; tpDownHorzNormal..tpDownHorzDisabled: begin Part := PGRP_DOWNHORZ; Base := Ord(tpDownHorzNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedProgress): TThemedElementDetails; var Base: Integer; begin Result.Element := teProgress; with Result do begin case Detail of tpBar: begin Part := PP_BAR; Base := Ord(tpBar); end; tpBarVert: begin Part := PP_BARVERT; Base := Ord(tpBarVert); end; tpChunk: begin Part := PP_CHUNK; Base := Ord(tpChunk); end; tpChunkVert: begin Part := PP_CHUNKVERT; Base := Ord(tpChunkVert); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedRebar): TThemedElementDetails; var Base: Integer; begin Result.Element := teRebar; with Result do begin case Detail of trGripper: begin Part := RP_GRIPPER; Base := Ord(trGripper); end; trGripperVert: begin Part := RP_GRIPPERVERT; Base := Ord(trGripperVert); end; trBandNormal..trBandHotChecked: begin Part := RP_BAND; Base := Ord(trBandNormal); end; trChevronNormal..trChevronDisabled: begin Part := RP_CHEVRON; Base := Ord(trChevronNormal); end; trChevronVertNormal..trChevronVertDisabled: begin Part := RP_CHEVRONVERT; Base := Ord(trChevronVertNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedScrollBar): TThemedElementDetails; var Base: Integer; begin Result.Element := teScrollBar; with Result do begin case Detail of tsArrowBtnUpNormal..tsArrowBtnRightDisabled: begin Part := SBP_ARROWBTN; Base := Ord(tsArrowBtnUpNormal); end; tsThumbBtnHorzNormal..tsThumbBtnHorzDisabled: begin Part := SBP_THUMBBTNHORZ; Base := Ord(tsThumbBtnHorzNormal); end; tsThumbBtnVertNormal..tsThumbBtnVertDisabled: begin Part := SBP_THUMBBTNVERT; Base := Ord(tsThumbBtnVertNormal); end; tsLowerTrackHorzNormal..tsLowerTrackHorzDisabled: begin Part := SBP_LOWERTRACKHORZ; Base := Ord(tsLowerTrackHorzNormal); end; tsUpperTrackHorzNormal..tsUpperTrackHorzDisabled: begin Part := SBP_UPPERTRACKHORZ; Base := Ord(tsUpperTrackHorzNormal); end; tsLowerTrackVertNormal..tsLowerTrackVertDisabled: begin Part := SBP_LOWERTRACKVERT; Base := Ord(tsLowerTrackVertNormal); end; tsUpperTrackVertNormal..tsUpperTrackVertDisabled: begin Part := SBP_UPPERTRACKVERT; Base := Ord(tsUpperTrackVertNormal); end; tsGripperHorzNormal..tsGripperHorzDisabled: begin Part := SBP_GRIPPERHORZ; Base := Ord(tsGripperHorzNormal); end; tsGripperVertNormal..tsGripperVertDisabled: begin Part := SBP_GRIPPERVERT; Base := Ord(tsGripperVertNormal); end; tsSizeBoxRightAlign..tsSizeBoxLeftAlign: begin Part := SBP_SIZEBOX; Base := Ord(tsSizeBoxRightAlign); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedSpin): TThemedElementDetails; var Base: Integer; begin Result.Element := teSpin; with Result do begin case Detail of tsUpNormal..tsUpDisabled: begin Part := SPNP_UP; Base := Ord(tsUpNormal); end; tsDownNormal..tsDownDisabled: begin Part := SPNP_DOWN; Base := Ord(tsDownNormal); end; tsUpHorzNormal..tsUpHorzDisabled: begin Part := SPNP_UPHORZ; Base := Ord(tsUpHorzNormal); end; tsDownHorzNormal..tsDownHorzDisabled: begin Part := SPNP_DOWNHORZ; Base := Ord(tsDownHorzNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedStartPanel): TThemedElementDetails; var Base: Integer; begin Result.Element := teStartPanel; with Result do begin case Detail of tspUserPane: begin Part := SPP_USERPANE; Base := Ord(tspUserPane); end; tspMorePrograms: begin Part := SPP_MOREPROGRAMS; Base := Ord(tspMorePrograms); end; tspMoreProgramsArrowNormal..tspMoreProgramsArrowPressed: begin Part := SPP_MOREPROGRAMSARROW; Base := Ord(tspMoreProgramsArrowNormal); end; tspProgList: begin Part := SPP_PROGLIST; Base := Ord(tspProgList); end; tspProgListSeparator: begin Part := SPP_PROGLISTSEPARATOR; Base := Ord(tspProgListSeparator); end; tspPlacesList: begin Part := SPP_PLACESLIST; Base := Ord(tspPlacesList); end; tspPlacesListSeparator: begin Part := SPP_PLACESLISTSEPARATOR; Base := Ord(tspPlacesListSeparator); end; tspLogOff: begin Part := SPP_LOGOFF; Base := Ord(tspLogOff); end; tspLogOffButtonsNormal..tspLogOffButtonsPressed: begin Part := SPP_LOGOFFBUTTONS; Base := Ord(tspLogOffButtonsNormal); end; tspUserPicture: begin Part := SPP_USERPICTURE; Base := Ord(tspUserPicture); end; tspPreview: begin Part := SPP_PREVIEW; Base := Ord(tspPreview); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedStatus): TThemedElementDetails; var Base: Integer; begin Result.Element := teStatus; with Result do begin case Detail of tsPane: begin Part := SP_PANE; Base := Ord(tsPane); end; tsGripperPane: begin Part := SP_GRIPPERPANE; Base := Ord(tsGripperPane); end; tsGripper: begin Part := SP_GRIPPER; Base := Ord(tsGripper); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedTab): TThemedElementDetails; var Base: Integer; begin Result.Element := teTab; with Result do begin case Detail of ttTabItemNormal..ttTabItemFocused: begin Part := TABP_TABITEM; Base := Ord(ttTabItemNormal); end; ttTabItemLeftEdgeNormal..ttTabItemLeftEdgeFocused: begin Part := TABP_TABITEMLEFTEDGE; Base := Ord(ttTabItemLeftEdgeNormal); end; ttTabItemRightEdgeNormal..ttTabItemRightEdgeFocused: begin Part := TABP_TABITEMRIGHTEDGE; Base := Ord(ttTabItemRightEdgeNormal); end; ttTabItemBothEdgeNormal..ttTabItemBothEdgeFocused: begin Part := TABP_TABITEMBOTHEDGE; Base := Ord(ttTabItemBothEdgeNormal); end; ttTopTabItemNormal..ttTopTabItemFocused: begin Part := TABP_TOPTABITEM; Base := Ord(ttTopTabItemNormal); end; ttTopTabItemLeftEdgeNormal..ttTopTabItemLeftEdgeFocused: begin Part := TABP_TOPTABITEMLEFTEDGE; Base := Ord(ttTopTabItemLeftEdgeNormal); end; ttTopTabItemRightEdgeNormal..ttTopTabItemRightEdgeFocused: begin Part := TABP_TOPTABITEMRIGHTEDGE; Base := Ord(ttTopTabItemRightEdgeNormal); end; ttTopTabItemBothEdgeNormal..ttTopTabItemBothEdgeFocused: begin Part := TABP_TOPTABITEMBOTHEDGE; Base := Ord(ttTopTabItemBothEdgeNormal); end; ttPane: begin Part := TABP_PANE; Base := Ord(ttPane); end; ttBody: begin Part := TABP_BODY; Base := Ord(ttBody); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedTaskBand): TThemedElementDetails; var Base: Integer; begin Result.Element := teTaskBand; with Result do begin case Detail of ttbGroupCount: begin Part := TDP_GROUPCOUNT; Base := Ord(ttbGroupCount); end; ttbFlashButton: begin Part := TDP_FLASHBUTTON; Base := Ord(ttbFlashButton); end; ttpFlashButtonGroupMenu: begin Part := TDP_FLASHBUTTONGROUPMENU; Base := Ord(ttpFlashButtonGroupMenu); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedTaskBar): TThemedElementDetails; var Base: Integer; begin Result.Element := teTaskBar; with Result do begin case Detail of ttbTimeNormal: begin Part := CLP_TIME; Base := Ord(ttbTimeNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedToolBar): TThemedElementDetails; var Base: Integer; begin Result.Element := teToolBar; with Result do begin case Detail of ttbButtonNormal..ttbButtonCheckedHot: begin Part := TP_BUTTON; Base := Ord(ttbButtonNormal); end; ttbDropDownButtonNormal..ttbDropDownButtonCheckedHot: begin Part := TP_DROPDOWNBUTTON; Base := Ord(ttbDropDownButtonNormal); end; ttbSplitButtonNormal..ttbSplitButtonCheckedHot: begin Part := TP_SPLITBUTTON; Base := Ord(ttbSplitButtonNormal); end; ttbSplitButtonDropDownNormal..ttbSplitButtonDropDownCheckedHot: begin Part := TP_SPLITBUTTONDROPDOWN; Base := Ord(ttbSplitButtonDropDownNormal); end; ttbSeparatorNormal..ttbSeparatorCheckedHot: begin Part := TP_SEPARATOR; Base := Ord(ttbSeparatorNormal); end; ttbSeparatorVertNormal..ttbSeparatorVertCheckedHot: begin Part := TP_SEPARATORVERT; Base := Ord(ttbSeparatorVertNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedToolTip): TThemedElementDetails; var Base: Integer; begin Result.Element := teToolTip; with Result do begin case Detail of tttStandardNormal..tttStandardLink: begin Part := TTP_STANDARD; Base := Ord(tttStandardNormal); end; tttStandardTitleNormal..tttStandardTitleLink: begin Part := TTP_STANDARDTITLE; Base := Ord(tttStandardTitleNormal); end; tttBaloonNormal..tttBaloonLink: begin Part := TTP_BALLOON; Base := Ord(tttBaloonNormal); end; tttBaloonTitleNormal..tttBaloonTitleLink: begin Part := TTP_BALLOONTITLE; Base := Ord(tttBaloonTitleNormal); end; tttCloseNormal..tttClosePressed: begin Part := TTP_CLOSE; Base := Ord(tttCloseNormal); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedTrackBar): TThemedElementDetails; var Base: Integer; begin Result.Element := teTrackBar; with Result do begin case Detail of ttbTrack: begin Part := TKP_TRACK; Base := Ord(ttbTrack); end; ttbTrackVert: begin Part := TKP_TRACKVERT; Base := Ord(ttbTrackVert); end; ttbThumbNormal..ttbThumbDisabled: begin Part := TKP_THUMB; Base := Ord(ttbThumbNormal); end; ttbThumbBottomNormal..ttbThumbBottomDisabled: begin Part := TKP_THUMBBOTTOM; Base := Ord(ttbThumbBottomNormal); end; ttbThumbTopNormal..ttbThumbTopDisabled: begin Part := TKP_THUMBTOP; Base := Ord(ttbThumbTopNormal); end; ttbThumbVertNormal..ttbThumbVertDisabled: begin Part := TKP_THUMBVERT; Base := Ord(ttbThumbVertNormal); end; ttbThumbLeftNormal..ttbThumbLeftDisabled: begin Part := TKP_THUMBLEFT; Base := Ord(ttbThumbLeftNormal); end; ttbThumbRightNormal..ttbThumbRightDisabled: begin Part := TKP_THUMBRIGHT; Base := Ord(ttbThumbRightNormal); end; ttbThumbTics: begin Part := TKP_TICS; Base := Ord(ttbThumbTics); end; ttbThumbTicsVert: begin Part := TKP_TICSVERT; Base := Ord(ttbThumbTicsVert); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedTrayNotify): TThemedElementDetails; var Base: Integer; begin Result.Element := teTrayNotify; with Result do begin case Detail of ttnBackground: begin Part := TNP_BACKGROUND; Base := Ord(ttnBackground); end; ttnAnimBackground: begin Part := TNP_ANIMBACKGROUND; Base := Ord(ttnAnimBackground); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedTreeview): TThemedElementDetails; var Base: Integer; begin Result.Element := teTreeView; with Result do begin case Detail of ttItemNormal..ttItemSelectedNotFocus: begin Part := TVP_TREEITEM; Base := Ord(ttItemNormal); end; ttGlyphClosed..ttGlyphOpened: begin Part := TVP_GLYPH; Base := Ord(ttGlyphClosed); end; ttBranch: begin Part := TVP_BRANCH; Base := Ord(ttBranch); end; ttHotGlyphClosed..ttHotGlyphOpened: begin Part := TVP_HOTGLYPH; Base := Ord(ttHotGlyphClosed); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.GetElementDetails(Detail: TThemedWindow): TThemedElementDetails; var Base: Integer; begin Result.Element := teWindow; with Result do begin case Detail of twCaptionActive..twCaptionDisabled: begin Part := WP_CAPTION; Base := Ord(twCaptionActive); end; twSmallCaptionActive..twSmallCaptionDisabled: begin Part := WP_SMALLCAPTION; Base := Ord(twSmallCaptionActive); end; twMinCaptionActive..twMinCaptionDisabled: begin Part := WP_MINCAPTION; Base := Ord(twMinCaptionActive); end; twSmallMinCaptionActive..twSmallMinCaptionDisabled: begin Part := WP_SMALLMINCAPTION; Base := Ord(twSmallMinCaptionActive); end; twMaxCaptionActive..twMaxCaptionDisabled: begin Part := WP_MAXCAPTION; Base := Ord(twMaxCaptionActive); end; twSmallMaxCaptionActive..twSmallMaxCaptionDisabled: begin Part := WP_SMALLMAXCAPTION; Base := Ord(twSmallMaxCaptionActive); end; twFrameLeftActive..twFrameLeftInactive: begin Part := WP_FRAMELEFT; Base := Ord(twFrameLeftActive); end; twFrameRightActive..twFrameRightInactive: begin Part := WP_FRAMERIGHT; Base := Ord(twFrameRightActive); end; twFrameBottomActive..twFrameBottomInactive: begin Part := WP_FRAMEBOTTOM; Base := Ord(twFrameBottomActive); end; twSmallFrameLeftActive..twSmallFrameLeftInactive: begin Part := WP_SMALLFRAMELEFT; Base := Ord(twSmallFrameLeftActive); end; twSmallFrameRightActive..twSmallFrameRightInactive: begin Part := WP_SMALLFRAMERIGHT; Base := Ord(twSmallFrameRightActive); end; twSmallFrameBottomActive..twSmallFrameBottomInactive: begin Part := WP_SMALLFRAMEBOTTOM; Base := Ord(twSmallFrameBottomActive); end; twSysButtonNormal..twSysButtonInactive: begin Part := WP_SYSBUTTON; Base := Ord(twSysButtonNormal); end; twMDISysButtonNormal..twMDISysButtonInactive: begin Part := WP_MDISYSBUTTON; Base := Ord(twMDISysButtonNormal); end; twMinButtonNormal..twMinButtonInactive: begin Part := WP_MINBUTTON; Base := Ord(twMinButtonNormal); end; twMDIMinButtonNormal..twMDIMinButtonInactive: begin Part := WP_MDIMINBUTTON; Base := Ord(twMDIMinButtonNormal); end; twMaxButtonNormal..twMaxButtonInactive: begin Part := WP_MAXBUTTON; Base := Ord(twMaxButtonNormal); end; twCloseButtonNormal..twCloseButtonInactive: begin Part := WP_CLOSEBUTTON; Base := Ord(twCloseButtonNormal); end; twSmallCloseButtonNormal..twSmallCloseButtonInactive: begin Part := WP_SMALLCLOSEBUTTON; Base := Ord(twSmallCloseButtonNormal); end; twMDICloseButtonNormal..twMDICloseButtonInactive: begin Part := WP_MDICLOSEBUTTON; Base := Ord(twMDICloseButtonNormal); end; twRestoreButtonNormal..twRestoreButtonInactive: begin Part := WP_RESTOREBUTTON; Base := Ord(twRestoreButtonNormal); end; twMDIRestoreButtonNormal..twMDIRestoreButtonInactive: begin Part := WP_MDIRESTOREBUTTON; Base := Ord(twMDIRestoreButtonNormal); end; twHelpButtonNormal..twHelpButtonInactive: begin Part := WP_HELPBUTTON; Base := Ord(twHelpButtonNormal); end; twMDIHelpButtonNormal..twMDIHelpButtonInactive: begin Part := WP_MDIHELPBUTTON; Base := Ord(twMDIHelpButtonNormal); end; twHorzScrollNormal..twHorzScrollDisabled: begin Part := WP_HORZSCROLL; Base := Ord(twHorzScrollNormal); end; twHorzThumbNormal..twHorzThumbDisabled: begin Part := WP_HORZTHUMB; Base := Ord(twHorzThumbNormal); end; twVertScrollNormal..twVertScrollDisabled: begin Part := WP_VERTSCROLL; Base := Ord(twVertScrollNormal); end; twVertThumbNormal..twVertThumbDisabled: begin Part := WP_VERTTHUMB; Base := Ord(twVertThumbNormal); end; twDialog: begin Part := WP_DIALOG; Base := Ord(twDialog); end; twCaptionSizingTemplate: begin Part := WP_CAPTIONSIZINGTEMPLATE; Base := Ord(twCaptionSizingTemplate); end; twSmallCaptionSizingTemplate: begin Part := WP_SMALLCAPTIONSIZINGTEMPLATE; Base := Ord(twSmallCaptionSizingTemplate); end; twFrameLeftSizingTemplate: begin Part := WP_FRAMELEFTSIZINGTEMPLATE; Base := Ord(twFrameLeftSizingTemplate); end; twSmallFrameLeftSizingTemplate: begin Part := WP_SMALLFRAMELEFTSIZINGTEMPLATE; Base := Ord(twSmallFrameLeftSizingTemplate); end; twFrameRightSizingTemplate: begin Part := WP_FRAMERIGHTSIZINGTEMPLATE; Base := Ord(twFrameRightSizingTemplate); end; twSmallFrameRightSizingTemplate: begin Part := WP_SMALLFRAMERIGHTSIZINGTEMPLATE; Base := Ord(twSmallFrameRightSizingTemplate); end; twFrameBottomSizingTemplate: begin Part := WP_FRAMEBOTTOMSIZINGTEMPLATE; Base := Ord(twFrameBottomSizingTemplate); end; twSmallFrameBottomSizingTemplate: begin Part := WP_SMALLFRAMEBOTTOMSIZINGTEMPLATE; Base := Ord(twSmallFrameBottomSizingTemplate); end; else Part := 0; Base := 0; end; State := Ord(Detail) - Base + 1; end; end; function TThemeServices.GetDetailSize(Details: TThemedElementDetails): TSize; begin // default values here // -1 mean that we do not know size of detail Result := Size(-1, -1); case Details.Element of teButton: if Details.Part in [BP_RADIOBUTTON, BP_CHECKBOX] then Result := Size(13, 13) else if Details.Part = BP_PUSHBUTTON then Result := Size(75, 23); teRebar: if Details.Part = RP_GRIPPER then Result.cy := 30 else if Details.Part = RP_GRIPPERVERT then Result.cx := 30; teToolBar: if Details.Part in [TP_SPLITBUTTONDROPDOWN, TP_DROPDOWNBUTTON] then Result.cx := 12; teTreeView: if Details.Part in [TVP_GLYPH, TVP_HOTGLYPH] then Result := Size(9, 9); teWindow: if Details.Part in [WP_SMALLCLOSEBUTTON, WP_MDICLOSEBUTTON, WP_MDIHELPBUTTON, WP_MDIMINBUTTON, WP_MDIRESTOREBUTTON, WP_MDISYSBUTTON] then Result := Size(9, 9); teHeader: if Details.Part in [HP_HEADERSORTARROW] then Result := Size(8, 5); end; if (Result.cx>0) then Result.cx := MulDiv(Result.cx, ScreenInfo.PixelsPerInchX, 96); if (Result.cy>0) then Result.cy := MulDiv(Result.cy, ScreenInfo.PixelsPerInchY, 96); end; function TThemeServices.GetDetailRegion(DC: HDC; Details: TThemedElementDetails; const R: TRect): HRGN; begin Result := 0; end; function TThemeServices.GetStockImage(StockID: LongInt; out Image, Mask: HBitmap): Boolean; begin Result := False; end; function TThemeServices.GetOption(AOption: TThemeOption): Integer; begin case AOption of toShowButtonImages: Result := 1; toShowMenuImages: Result := 1; toUseGlyphEffects: begin // toUseGlyphEffects seems to be OS-dependent. // Linux: yes // Win, OSX: no {$IFDEF LINUX} Result := 1; {$ELSE} Result := 0; {$ENDIF} end; else Result := 0; end; end; function TThemeServices.GetTextExtent(DC: HDC; Details: TThemedElementDetails; const S: String; Flags: Cardinal; BoundingRect: PRect): TRect; begin if Assigned(BoundingRect) then Result := BoundingRect^ else Result := Rect(0, 0, 0, 0); LCLIntf.DrawText(DC, PChar(S), Length(S), Result, DT_CALCRECT or Flags); end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.ColorToRGB(Color: LongInt; Details: PThemedElementDetails = nil): COLORREF; begin if (Color and $80000000 = 0) then Result := Color else if Details = nil then Result := Graphics.ColorToRGB(Color) else Result := InternalColorToRGB(Details^, Color); end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.ContentRect(DC: HDC; Details: TThemedElementDetails; BoundingRect: TRect): TRect; begin Result := BoundingRect; if Details.Element in [teHeader, teButton] then InflateRect(Result, -2, -2) else InflateRect(Result, -1, -1); end; //---------------------------------------------------------------------------------------------------------------------- procedure TThemeServices.DrawEdge(DC: HDC; Details: TThemedElementDetails; const R: TRect; Edge, Flags: Cardinal; AContentRect: PRect = nil); var ARect: TRect; begin // deafult painting ARect := R; WidgetSet.DrawEdge(DC, ARect, Edge, Flags); if (Flags and DFCS_ADJUSTRECT <> 0) and (AContentRect <> nil) then AContentRect^ := R; end; //---------------------------------------------------------------------------------------------------------------------- procedure TThemeServices.DrawElement(DC: HDC; Details: TThemedElementDetails; const R: TRect; ClipRect: PRect = nil); procedure DrawDropDownArrow(const DropDownButtonRect: TRect); const cArrowWidth = 10; var ArrowRect: TRect; Points: array[1..3] of TPoint; OldBrush, Brush: HBrush; begin ArrowRect := DropDownButtonRect; ArrowRect.Left := (DropDownButtonRect.Left+DropDownButtonRect.Right-cArrowWidth-1) div 2; ArrowRect.Right := ArrowRect.Left+cArrowWidth; ArrowRect.Left := ArrowRect.Left + 3; ArrowRect.Right := Max(ArrowRect.Right - 3, ArrowRect.Left); ArrowRect.Top := (DropDownButtonRect.Top + DropDownButtonRect.Bottom + ArrowRect.Left - ArrowRect.Right) div 2; ArrowRect.Bottom := ArrowRect.Top + Min(2, ArrowRect.Right - ArrowRect.Left); Points[1] := Point(ArrowRect.Left, ArrowRect.Top); Points[2] := Point((ArrowRect.Left + ArrowRect.Right) div 2, ArrowRect.Bottom); Points[3] := Point(ArrowRect.Right, ArrowRect.Top); Brush := CreateSolidBrush(clBlack); OldBrush := SelectObject(DC, Brush); Polygon(Dc, @Points[1], 3, False); DeleteObject(SelectObject(DC, OldBrush)); end; procedure DrawVLine(ARect: TRect); begin ARect.Left := ((ARect.Left + ARect.Right) div 2) - 1; ARect.Right := ARect.Left + 2; inc(ARect.Top, 2); inc(ARect.Bottom, 2); LCLIntf.DrawEdge(DC, ARect, EDGE_ETCHED, BF_LEFT); end; procedure DrawHLine(ARect: TRect); begin ARect.Top := ((ARect.Top + ARect.Bottom) div 2) - 1; ARect.Bottom := ARect.Top + 2; inc(ARect.Left, 2); inc(ARect.Right, 2); LCLIntf.DrawEdge(DC, ARect, EDGE_ETCHED, BF_LEFT); end; procedure FillWithColor(ARect: TRect; AColor: TColor); var Brush: HBrush; begin Brush := CreateSolidBrush(ColorToRGB(AColor)); FillRect(DC, ARect, Brush); DeleteObject(Brush); end; procedure FillWithDottedBrush(ARect: TRect; Color1, Color2: TColor); var OldColor1, OldColor2: TColorRef; begin OldColor1 := SetBkColor(DC, ColorToRGB(Color1)); OldColor2 := SetTextColor(DC, ColorToRGB(Color2)); FillRect(DC, ARect, DottedBrush); SetBkColor(DC, OldColor1); SetTextColor(DC, OldColor2); end; procedure DrawTriangle(ADown: Boolean); var P: array[0..2] of TPoint; Brush: HBRUSH; OldBrush, OldPen: HGDIOBJ; Pen: HPEN; begin if ADown then begin P[0].x:=R.Left; P[0].y:=R.Top; P[1].x:=R.Left+(R.Right-1-R.Left) div 2; P[1].y:= R.Bottom-1; P[2].x:=R.Right-1; P[2].y:= R.Top; end else begin P[0].x:=R.Right-1; P[0].y:= R.Bottom-1; P[1].x:=R.Left+(R.Right-1-R.Left) div 2; P[1].y:= R.Top-1; P[2].x:=R.Left-1; P[2].y:=R.Bottom-1; end; Pen := CreatePen(PS_NULL, 0, 0); OldPen := SelectObject(DC, Pen); Brush := CreateSolidBrush(ColorToRGB(clBtnText)); OldBrush := SelectObject(DC, Brush); Polygon(DC, @P[0], 3, False); DeleteObject(SelectObject(DC, OldBrush)); DeleteObject(SelectObject(DC, OldPen)); end; var ADrawFlags: DWord; Bevel: TGraphicsBevelCut; ARect: TRect; Tmp: Integer; begin // default painting ARect := R; // in order to pass by reference case Details.Element of teButton: begin ADrawFlags := DFCS_BUTTONPUSH; if Details.Element = teButton then begin case Details.Part of BP_RADIOBUTTON: ADrawFlags := DFCS_BUTTONRADIO; BP_CHECKBOX: if IsMixed(Details) then ADrawFlags := DFCS_BUTTON3STATE else ADrawFlags := DFCS_BUTTONCHECK; end; end; if IsDisabled(Details) then ADrawFlags := ADrawFlags or DFCS_INACTIVE else if IsPushed(Details) then ADrawFlags := ADrawFlags or DFCS_PUSHED else if IsHot(Details) then ADrawFlags := ADrawFlags or DFCS_HOT; if IsChecked(Details) or IsMixed(Details) then ADrawFlags := ADrawFlags or DFCS_CHECKED; WidgetSet.DrawFrameControl(DC, ARect, DFC_BUTTON, ADrawFlags); end; teHeader: begin if Details.Part = HP_HEADERSORTARROW then DrawTriangle(Details.State = HSAS_SORTEDDOWN) else begin ADrawFlags := DFCS_BUTTONPUSH; if IsDisabled(Details) then ADrawFlags := ADrawFlags or DFCS_INACTIVE else if IsPushed(Details) then ADrawFlags := ADrawFlags or DFCS_PUSHED else if IsHot(Details) then ADrawFlags := ADrawFlags or DFCS_HOT; WidgetSet.DrawFrameControl(DC, ARect, DFC_BUTTON, ADrawFlags); end; end; teToolBar: begin case Details.Part of TP_BUTTON, TP_DROPDOWNBUTTON, TP_SPLITBUTTON: begin if IsPushed(Details) or IsChecked(Details) then Bevel := bvLowered else if IsHot(Details) then Bevel := bvRaised else Bevel := bvNone; Frame3D(DC, ARect, 1, Bevel); if IsChecked(Details) and not IsHot(Details) then begin InflateRect(ARect, -2, -2); FillWithDottedBrush(ARect, clBtnHighlight, clBtnFace) end; end; TP_SPLITBUTTONDROPDOWN: begin if IsPushed(Details) or IsChecked(Details) then Bevel := bvLowered else if IsHot(Details) then Bevel := bvRaised else Bevel := bvNone; Frame3D(DC, ARect, 1, Bevel); ARect:=R; InflateRect(ARect, -1, -1); DrawDropDownArrow(ARect); end; TP_SEPARATOR: DrawVline(ARect); TP_SEPARATORVERT: DrawHline(ARect); end; end; teWindow: begin case Details.Part of WP_MINBUTTON, WP_MDIMINBUTTON : ADrawFlags := DFCS_CAPTIONMIN; WP_MAXBUTTON : ADrawFlags := DFCS_CAPTIONMAX; WP_CLOSEBUTTON, WP_SMALLCLOSEBUTTON, WP_MDICLOSEBUTTON : ADrawFlags := DFCS_CAPTIONCLOSE; WP_RESTOREBUTTON, WP_MDIRESTOREBUTTON: ADrawFlags := DFCS_CAPTIONRESTORE; WP_HELPBUTTON, WP_MDIHELPBUTTON : ADrawFlags := DFCS_CAPTIONHELP; else ADrawFlags := 0; end; if Details.Part in [WP_MDIMINBUTTON, WP_MDIRESTOREBUTTON, WP_MDICLOSEBUTTON] then ADrawFlags := ADrawFlags or DFCS_FLAT; if IsDisabled(Details) then ADrawFlags := ADrawFlags or DFCS_INACTIVE else if IsPushed(Details) then ADrawFlags := ADrawFlags or DFCS_PUSHED else if IsHot(Details) then ADrawFlags := ADrawFlags or DFCS_HOT; WidgetSet.DrawFrameControl(DC, ARect, DFC_CAPTION, ADrawFlags); end; teTab: begin if Details.Part in [TABP_PANE, TABP_BODY] then FillWithColor(ARect, clBackground); end; teTreeView: begin if Details.Part in [TVP_GLYPH, TVP_HOTGLYPH] then begin with ARect do begin if not odd(Right - Left) then Dec(Right); if not odd(Bottom - Top) then Dec(Bottom); end; Rectangle(DC, ARect.Left, ARect.Top, ARect.Right, ARect.Bottom); Tmp := Integer((ARect.Bottom + ARect.Top) shr 1); MoveToEx(DC, ARect.Left + 2, Tmp, nil); LineTo(DC, ARect.Right - 2, Tmp); if Details.State = GLPS_CLOSED then begin Tmp := (ARect.Left + ARect.Right) shr 1; MoveToEx(DC, Tmp, ARect.Top + 2, nil); LineTo(DC, Tmp, ARect.Bottom - 2); end; end else if Details.Part = TVP_TREEITEM then begin case Details.State of TREIS_NORMAL: FillWithColor(ARect, clWindow); TREIS_HOT: FillWithColor(ARect, clHotLight); TREIS_SELECTED: FillWithColor(ARect, clHighlight); TREIS_DISABLED: FillWithColor(ARect, clWindow); TREIS_SELECTEDNOTFOCUS: FillWithColor(ARect, clBtnFace); TREIS_HOTSELECTED: FillWithColor(ARect, clHighlight); end; end; end; teToolTip: begin if Details.Part = TTP_STANDARD then begin FillWithColor(ARect, clInfoBk); LCLIntf.DrawEdge(DC, ARect, BDR_RAISEDOUTER, BF_RECT); end; end; end; end; //---------------------------------------------------------------------------------------------------------------------- procedure TThemeServices.DrawIcon(DC: HDC; Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST; Index: Integer); begin // overrided in TWin32ThemeServices (for compatability with Delphi) end; procedure TThemeServices.DrawIcon(ACanvas: TPersistent; Details: TThemedElementDetails; const P: TPoint; AImageList: TPersistent; Index: Integer; AImageWidth: Integer; ARefControl: TPersistent); var AEffect: TGraphicsDrawEffect; begin if not Assigned(ThemesImageDrawEvent) then exit; if IsDisabled(Details) then AEffect := gdeDisabled else if IsPushed(Details) then AEffect := gdeShadowed else if IsHot(Details) then AEffect := gdeHighlighted else AEffect := gdeNormal; ThemesImageDrawEvent(AImageList, ACanvas, P.X, P.Y, Index, AEffect, AImageWidth, ARefControl); end; //---------------------------------------------------------------------------------------------------------------------- procedure TThemeServices.DrawParentBackground(Window: HWND; Target: HDC; Details: PThemedElementDetails; OnlyIfTransparent: Boolean; Bounds: PRect = nil); var DoDraw: Boolean; begin if OnlyIfTransparent and Assigned(Details) then DoDraw := HasTransparentParts(Details^) else DoDraw := True; if DoDraw then InternalDrawParentBackground(Window, Target, Bounds); end; //---------------------------------------------------------------------------------------------------------------------- procedure TThemeServices.DrawText(DC: HDC; Details: TThemedElementDetails; const S: String; R: TRect; Flags, Flags2: Cardinal); begin // overrided in TWin32ThemeServices (for compatability with Delphi) end; function TThemeServices.IsDisabled(Details: TThemedElementDetails): Boolean; begin // teHeader should not be here, it has no disabled state Result := False; if (Details.Element in [teButton, teToolBar, teComboBox, teEdit]) or ((Details.Element = teRebar) and (Details.Part >= RP_BAND)) or ((Details.Element = teWindow) and (Details.Part >= WP_SYSBUTTON) and (Details.Part <= WP_MDIHELPBUTTON)) then Result := (Details.State mod 4) = 0; // usual disabled = 4 / 8 / 12 end; function TThemeServices.IsPushed(Details: TThemedElementDetails): Boolean; begin Result := False; if (Details.Element in [teButton, teToolBar, teHeader, teComboBox]) or ((Details.Element = teRebar) and (Details.Part >= RP_BAND)) or ((Details.Element = teWindow) and (Details.Part >= WP_SYSBUTTON) and (Details.Part <= WP_MDIHELPBUTTON)) then Result := Details.State in [3, 7, 11]; end; function TThemeServices.IsHot(Details: TThemedElementDetails): Boolean; begin Result := False; if (Details.Element in [teButton, teToolBar, teHeader, teComboBox]) or ((Details.Element = teRebar) and (Details.Part >= RP_BAND)) or ((Details.Element = teWindow) and (Details.Part >= WP_SYSBUTTON) and (Details.Part <= WP_MDIHELPBUTTON)) then Result := Details.State in [2, 6, 10] else if (Details.Element = teTreeview) and (Details.Part = TVP_HOTGLYPH) then Result := True; end; function TThemeServices.IsChecked(Details: TThemedElementDetails): Boolean; begin Result := False; if (Details.Element in [teButton]) then Result := (Details.State > 4) and (Details.State < 9) else if (Details.Element in [teToolBar]) then Result := (Details.State > 4); end; function TThemeServices.IsMixed(Details: TThemedElementDetails): Boolean; begin Result := False; if (Details.Element in [teButton]) then Result := Details.State > 8; end; function TThemeServices.InitThemes: Boolean; begin Result := False; end; procedure TThemeServices.UnloadThemeData; begin end; function TThemeServices.UseThemes: Boolean; begin Result := False; end; function TThemeServices.ThemedControlsEnabled: Boolean; begin Result := False; end; function TThemeServices.InternalColorToRGB(Details: TThemedElementDetails; Color: LongInt): COLORREF; begin Result := Graphics.ColorToRGB(Color); end; procedure TThemeServices.InternalDrawParentBackground(Window: HWND; Target: HDC; Bounds: PRect); begin // default painting end; procedure TThemeServices.DrawText(ACanvas: TPersistent; Details: TThemedElementDetails; const S: String; R: TRect; Flags, Flags2: Cardinal); var Canvas: TCanvas absolute ACanvas; TXTStyle: TTextStyle; OldColor: TColor; begin TXTStyle := Canvas.TextStyle; TXTStyle.Opaque := False; TXTStyle.Clipping := (Flags and DT_NOCLIP) = 0; TXTStyle.ShowPrefix := (Flags and DT_NOPREFIX) = 0; TXTStyle.SingleLine := (Flags and DT_SINGLELINE) <> 0; if (Flags and DT_CENTER) <> 0 then TXTStyle.Alignment := taCenter else if (Flags and DT_RIGHT) <> 0 then TXTStyle.Alignment := taRightJustify else TXTStyle.Alignment := taLeftJustify; if (Flags and DT_VCENTER) <> 0 then TXTStyle.Layout := tlCenter else if (Flags and DT_BOTTOM) <> 0 then TXTStyle.Layout := tlBottom else TXTStyle.Layout := tlTop; TXTStyle.RightToLeft := (Flags and DT_RTLREADING) <> 0; // set color here, otherwise SystemFont is wrong if the button was disabled before TXTStyle.SystemFont := Canvas.Font.IsDefault;//Match System Default Style TXTStyle.Wordbreak := (Flags and DT_WORDBREAK) <> 0; if not TXTStyle.Wordbreak then TXTStyle.EndEllipsis := (Flags and DT_END_ELLIPSIS) <> 0 else TXTStyle.EndEllipsis := False; OldColor := Canvas.Font.Color; if IsDisabled(Details) then if ThemesEnabled then Canvas.Font.Color := clGrayText else begin Canvas.Font.Color := clBtnHighlight; OffsetRect(R, 1, 1); Canvas.TextRect(R, R.Left, R.Top, S, TXTStyle); Canvas.Font.Color := clBtnShadow; OffsetRect(R, -1, -1); end; if (Details.Element = teTreeview) and (Details.Part = TVP_TREEITEM) then begin case Details.State of TREIS_SELECTED, TREIS_HOTSELECTED: Canvas.Font.Color := clHighlightText; TREIS_DISABLED: Canvas.Font.Color := clGrayText; TREIS_SELECTEDNOTFOCUS: Canvas.Font.Color := clBtnText; else Canvas.Font.Color := clWindowText; end; end; Canvas.TextRect(R, R.Left, R.Top, S, TXTStyle); Canvas.Font.Color := OldColor; end; //---------------------------------------------------------------------------------------------------------------------- function TThemeServices.HasTransparentParts(Details: TThemedElementDetails): Boolean; begin Result := True; end; //---------------------------------------------------------------------------------------------------------------------- procedure TThemeServices.PaintBorder(Control: TObject; EraseLRCorner: Boolean); begin // default painting end; //---------------------------------------------------------------------------------------------------------------------- procedure TThemeServices.UpdateThemes; begin if FUseThemes then UnloadThemeData; FUseThemes := UseThemes; if FUseThemes then FThemedControlsEnabled := ThemedControlsEnabled else FThemedControlsEnabled := False; end; //---------------------------------------------------------------------------------------------------------------------- end.