Componentes.Terceros.TB2k-TBX/official/2.1.6+2.1.beta1/TBX/TBXDefaultTheme.pas

1789 lines
59 KiB
ObjectPascal

unit TBXDefaultTheme;
// TBX Package
// Copyright 2001-2004 Alex A. Denisov. All Rights Reserved
// See TBX.chm for license and installation instructions
//
// $Id: TBXDefaultTheme.pas 16 2004-05-26 02:02:55Z Alex@ZEISS $
interface
{$I ..\..\Source\TB2Ver.inc}
{$I TBX.inc}
uses
Windows, Messages, Graphics, TBXThemes, ImgList;
type
TTBXDefaultTheme = class(TTBXTheme)
private
procedure TBXSysCommand(var Message: TMessage); message TBX_SYSCOMMAND;
protected
ToolbarColor: TColor;
ToolbarText: TColor;
DockPanelColor: TColor;
StatusBarColor: TColor;
procedure SetupColorCache; virtual;
public
constructor Create(const AName: string); override;
destructor Destroy; override;
{ Metrics Access, etc. }
function GetBooleanMetrics(Index: Integer): Boolean; override;
function GetImageOffset(Canvas: TCanvas; const ItemInfo: TTBXItemInfo; ImageList: TCustomImageList): TPoint; override;
function GetIntegerMetrics(Index: Integer): Integer; override;
procedure GetMargins(MarginID: Integer; out Margins: TTBXMargins); override;
function GetItemColor(const ItemInfo: TTBXItemInfo): TColor; override;
function GetItemTextColor(const ItemInfo: TTBXItemInfo): TColor; override;
function GetItemImageBackground(const ItemInfo: TTBXItemInfo): TColor; override;
function GetPopupShadowType: Integer; override;
procedure GetViewBorder(ViewType: Integer; out Border: TPoint); override;
function GetViewColor(ViewType: Integer): TColor; override;
procedure GetViewMargins(ViewType: Integer; out Margins: TTBXMargins); override;
{ Painting routines }
procedure PaintBackgnd(Canvas: TCanvas; const ADockRect, ARect, AClipRect: TRect; AColor: TColor; Transparent: Boolean; AViewType: Integer); override;
procedure PaintButton(Canvas: TCanvas; const ARect: TRect; const ItemInfo: TTBXItemInfo); override;
procedure PaintCaption(Canvas: TCanvas; const ARect: TRect; const ItemInfo: TTBXItemInfo; const ACaption: string; AFormat: Cardinal; Rotated: Boolean); override;
procedure PaintCheckMark(Canvas: TCanvas; ARect: TRect; const ItemInfo: TTBXItemInfo); override;
procedure PaintChevron(Canvas: TCanvas; ARect: TRect; const ItemInfo: TTBXItemInfo); override;
procedure PaintDock(Canvas: TCanvas; const ClientRect, DockRect: TRect; DockPosition: Integer); override;
procedure PaintDockPanelNCArea(Canvas: TCanvas; R: TRect; const DockPanelInfo: TTBXDockPanelInfo); override;
procedure PaintDropDownArrow(Canvas: TCanvas; const ARect: TRect; const ItemInfo: TTBXItemInfo); override;
procedure PaintEditButton(Canvas: TCanvas; const ARect: TRect; var ItemInfo: TTBXItemInfo; ButtonInfo: TTBXEditBtnInfo); override;
procedure PaintEditFrame(Canvas: TCanvas; const ARect: TRect; var ItemInfo: TTBXItemInfo; const EditInfo: TTBXEditInfo); override;
procedure PaintFloatingBorder(Canvas: TCanvas; const ARect: TRect; const WindowInfo: TTBXWindowInfo); override;
procedure PaintFrame(Canvas: TCanvas; const ARect: TRect; const ItemInfo: TTBXItemInfo); override;
procedure PaintImage(Canvas: TCanvas; ARect: TRect; const ItemInfo: TTBXItemInfo; ImageList: TCustomImageList; ImageIndex: Integer); override;
procedure PaintMDIButton(Canvas: TCanvas; ARect: TRect; const ItemInfo: TTBXItemInfo; ButtonKind: Cardinal); override;
procedure PaintMenuItem(Canvas: TCanvas; const ARect: TRect; var ItemInfo: TTBXItemInfo); override;
procedure PaintMenuItemFrame(Canvas: TCanvas; const ARect: TRect; const ItemInfo: TTBXItemInfo); override;
procedure PaintPageScrollButton(Canvas: TCanvas; const ARect: TRect; ButtonType: Integer; Hot: Boolean); override;
procedure PaintPopupNCArea(Canvas: TCanvas; R: TRect; const PopupInfo: TTBXPopupInfo); override;
procedure PaintSeparator(Canvas: TCanvas; ARect: TRect; ItemInfo: TTBXItemInfo; Horizontal, LineSeparator: Boolean); override;
procedure PaintToolbarNCArea(Canvas: TCanvas; R: TRect; const ToolbarInfo: TTBXToolbarInfo); override;
procedure PaintFrameControl(Canvas: TCanvas; R: TRect; Kind, State: Integer; Params: Pointer); override;
procedure PaintStatusBar(Canvas: TCanvas; R: TRect; Part: Integer); override;
end;
implementation
uses
Classes, Controls, CommCtrl, TBXUtils, TBXUxThemes, TB2Common, TB2Item, TBX, Forms;
var
SmCaptionFont: TFont;
procedure InitializeStock;
var
NonClientMetrics: TNonClientMetrics;
begin
SmCaptionFont := TFont.Create;
NonClientMetrics.cbSize := SizeOf(NonClientMetrics);
if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then
SmCaptionFont.Handle := CreateFontIndirect(NonClientMetrics.lfSmCaptionFont);
end;
procedure FinalizeStock;
begin
SmCaptionFont.Free;
SmCaptionFont := nil;
end;
procedure DrawButtonBitmap(Canvas: TCanvas; R: TRect);
const
Pattern: array [0..15] of Byte = ($C6, 0, $6C, 0, $38, 0, $38, 0, $6C, 0, $C6, 0, 0, 0, 0, 0);
begin
DrawGlyph(Canvas.Handle, R, 7, 6, Pattern[0], clBtnText);
end;
{ TTBXDefaultTheme }
constructor TTBXDefaultTheme.Create;
begin
inherited;
AddTBXSysChangeNotification(Self);
SetupColorCache;
end;
destructor TTBXDefaultTheme.Destroy;
begin
RemoveTBXSysChangeNotification(Self);
inherited;
end;
function TTBXDefaultTheme.GetBooleanMetrics(Index: Integer): Boolean;
begin
case Index of
TMB_OFFICEXPPOPUPALIGNMENT: Result := False;
TMB_EDITMENUFULLSELECT: Result := False;
TMB_EDITHEIGHTEVEN: Result := False;
TMB_PAINTDOCKBACKGROUND: Result := USE_THEMES;
TMB_SOLIDTOOLBARNCAREA: Result := False;
TMB_SOLIDTOOLBARCLIENTAREA: Result := False;
else
Result := False;
end;
end;
function TTBXDefaultTheme.GetIntegerMetrics(Index: Integer): Integer;
const
DEFAULT = -1;
var
Sz: TSize;
begin
case Index of
TMI_SPLITBTN_ARROWWIDTH:
if USE_THEMES then
begin
if GetThemePartSize(TOOLBAR_THEME, StockCompatibleBitmap.Canvas.Handle,
TP_SPLITBUTTONDROPDOWN, TS_NORMAL, nil, TS_TRUE, Sz) = S_OK then
begin
Result := Sz.cx + 2;
end
else Result := 11;
end
else Result := 11;
TMI_DROPDOWN_ARROWWIDTH: Result := 8;
TMI_DROPDOWN_ARROWMARGIN: Result := 3;
TMI_MENU_IMGTEXTSPACE: Result := 1;
TMI_MENU_LCAPTIONMARGIN: Result := 2;
TMI_MENU_RCAPTIONMARGIN: Result := 2;
TMI_MENU_SEPARATORSIZE: Result := DEFAULT;
TMI_MENU_MDI_DW: Result := 2;
TMI_MENU_MDI_DH: Result := 4;
TMI_TLBR_SEPARATORSIZE: Result := 6;
TMI_EDIT_FRAMEWIDTH: Result := 2;
TMI_EDIT_TEXTMARGINHORZ: Result := 2;
TMI_EDIT_TEXTMARGINVERT: Result := 1;
TMI_EDIT_BTNWIDTH: Result := 13;
TMI_EDIT_MENURIGHTINDENT: Result := 0;
else
Result := DEFAULT;
end;
end;
function TTBXDefaultTheme.GetViewColor(ViewType: Integer): TColor;
begin
Result := ToolbarColor;
if (ViewType and VT_TOOLBAR) = VT_TOOLBAR then Result := ToolbarColor
else if (ViewType and VT_POPUP) = VT_POPUP then
begin
if (ViewType and PVT_POPUPMENU) = PVT_POPUPMENU then Result := clPopup
else if (ViewType and PVT_LISTBOX) = PVT_LISTBOX then Result := clWindow
else if (ViewType and PVT_TOOLBOX) = PVT_TOOLBOX then Result := ToolbarColor
else if (ViewType and PVT_CHEVRONMENU) = PVT_CHEVRONMENU then Result := clPopup;
end
else if (ViewType and VT_DOCKPANEL) = VT_DOCKPANEL then Result := DockPanelColor
else if (ViewType and VT_STATUSBAR) = VT_STATUSBAR then Result := StatusBarColor
else Result := clBtnFace;
end;
function TTBXDefaultTheme.GetItemColor(const ItemInfo: TTBXItemInfo): TColor;
var
IsMenuItem: Boolean;
begin
with ItemInfo do
begin
IsMenuItem := ((ViewType and PVT_POPUPMENU) = PVT_POPUPMENU) and ((ItemOptions and IO_TOOLBARSTYLE) = 0);
if not USE_THEMES then
begin
if IsMenuItem and (ItemInfo.HoverKind <> hkNone) then Result := clHighlight
else Result := GetViewColor(ItemInfo.ViewType);
end
else
Result := GetViewColor(ItemInfo.ViewType);
end;
end;
function TTBXDefaultTheme.GetItemTextColor(const ItemInfo: TTBXItemInfo): TColor;
var
InMenuBar, ToolbarStyle, ShowInactive: Boolean;
begin
Result := clBtnText;
with ItemInfo do
begin
InMenuBar := (ViewType and TVT_MENUBAR) = TVT_MENUBAR;
ToolbarStyle := Boolean(ItemOptions and IO_TOOLBARSTYLE);
ShowInactive := InMenubar and not Boolean(ItemOptions and IO_APPACTIVE);
if not ToolbarStyle and not Enabled and (HoverKind = hkKeyboardHover) then Result := clGrayText
else if Enabled then
begin
if not ToolbarStyle or (InMenuBar and USE_FLATMENUS) then
begin
if HoverKind <> hkNone then Result := clHighlightText
else if ShowInactive then Result := clGrayText
else Result := clPopupText
end
else if ShowInactive then Result := clGrayText;
end
else Result := clGrayText;
end;
end;
function TTBXDefaultTheme.GetItemImageBackground(const ItemInfo: TTBXItemInfo): TColor;
var
IsFlatMenuItem, InFlatMenuBar, InFlatChevronBar: Boolean;
begin
with ItemInfo do
begin
InFlatMenuBar := ((ViewType and TVT_MENUBAR) = TVT_MENUBAR) and USE_FLATMENUS;
InFlatChevronBar := ((ViewType and PVT_CHEVRONMENU) = PVT_CHEVRONMENU) and USE_FLATMENUS;
IsFlatMenuItem := ((ViewType and PVT_POPUPMENU) = PVT_POPUPMENU) and ((ItemOptions and IO_TOOLBARSTYLE) = 0) and USE_FLATMENUS;
if InFlatMenuBar and (HoverKind <> hkNone) then Result := clHighlight
else if InFlatChevronBar or IsFlatMenuItem and (HoverKind <> hkNone) then Result := ToolbarColor
else Result := GetViewColor(ViewType);
end;
end;
procedure TTBXDefaultTheme.GetViewBorder(ViewType: Integer; out Border: TPoint);
const
XMetrics: array [Boolean] of Integer = (SM_CXDLGFRAME, SM_CXFRAME);
YMetrics: array [Boolean] of Integer = (SM_CYDLGFRAME, SM_CYFRAME);
var
Resizable: Boolean;
Sz: Integer;
begin
Sz := 0;
if (ViewType and VT_TOOLBAR) = VT_TOOLBAR then
begin
if (ViewType and TVT_FLOATING) = TVT_FLOATING then
begin
Resizable := (ViewType and TVT_RESIZABLE) = TVT_RESIZABLE;
Border.X := GetSystemMetrics(XMetrics[Resizable]);
Border.Y := GetSystemMetrics(YMetrics[Resizable]);
Exit;
end
else Sz := 2;
end
else if (ViewType and VT_POPUP) = VT_POPUP then
begin
{$IFNDEF OFFICE2K_COMBOS}
if (ViewType and PVT_LISTBOX) = PVT_LISTBOX then Sz := 1
else Sz := 3;
{$ELSE}
Sz := 3;
{$ENDIF}
end
else if (ViewType and VT_DOCKPANEL) = VT_DOCKPANEL then
begin
if (ViewType and DPVT_FLOATING) = DPVT_FLOATING then
begin
Resizable := (ViewType and DPVT_RESIZABLE) = DPVT_RESIZABLE;
Border.X := GetSystemMetrics(XMetrics[Resizable]);
Border.Y := GetSystemMetrics(YMetrics[Resizable]);
Exit;
end
else Sz := 2;
end;
Border.X := Sz;
Border.Y := Sz;
end;
procedure TTBXDefaultTheme.GetMargins(MarginID: Integer; out Margins: TTBXMargins);
var
R, R2: TRect;
begin
with Margins do
case MarginID of
MID_TOOLBARITEM:
begin
LeftWidth := 2; RightWidth := 2;
TopHeight := 2; BottomHeight := 2;
if USE_THEMES then
GetThemeMargins(TOOLBAR_THEME, StockBitmap1.Canvas.Handle, TP_BUTTON, TS_HOT, TMT_CAPTIONMARGINS,
nil, TMargins(Margins));
end;
MID_MENUITEM:
begin
LeftWidth := 0; RightWidth := 0;
TopHeight := 2; BottomHeight := 2;
end;
MID_STATUSPANE:
begin
if USE_THEMES then
begin
R := Rect(0, 0, 100, 100);
GetThemeBackgroundContentRect(STATUSBAR_THEME, StockBitmap1.Canvas.Handle, SP_PANE, 0, R, @R2);
LeftWidth := R2.Left - R.Left;
RightWidth := R.Right - R2.Right;
TopHeight := R2.Top - R.Top;
BottomHeight := R.Bottom - R2.Bottom;
end
else
begin
LeftWidth := 1; RightWidth := 3;
TopHeight := 1; BottomHeight := 1;
end;
end;
else
LeftWidth := 0; RightWidth := 0;
TopHeight := 0; BottomHeight := 0;
end;
end;
procedure TTBXDefaultTheme.PaintBackgnd(Canvas: TCanvas; const ADockRect, ARect, AClipRect: TRect;
AColor: TColor; Transparent: Boolean; AViewType: Integer);
var
DC: HDC;
R: TRect;
begin
DC := Canvas.Handle;
if not Transparent then
begin
IntersectRect(R, ARect, AClipRect);
FillRectEx(DC, R, AColor);
end;
end;
procedure TTBXDefaultTheme.PaintCaption(Canvas: TCanvas;
const ARect: TRect; const ItemInfo: TTBXItemInfo; const ACaption: string;
AFormat: Cardinal; Rotated: Boolean);
var
R: TRect;
C: TColor;
InMenuBar, ToolbarStyle: Boolean;
procedure _Draw(Color: TColor);
begin
Canvas.Font.Color := Color;
if not Rotated then Windows.DrawText(Canvas.Handle, PChar(ACaption), Length(ACaption), R, AFormat)
else DrawRotatedText(Canvas.Handle, ACaption, R, AFormat);
end;
begin
with ItemInfo, Canvas do
begin
R := ARect;
C := Font.Color;
{ Apply theme-dependent color only when Font.Color = clNone }
if C = clNone then C := GetItemTextColor(ItemInfo);
Brush.Style := bsClear;
InMenuBar := (ViewType and TVT_MENUBAR) = TVT_MENUBAR;
ToolbarStyle := Boolean(ItemOptions and IO_TOOLBARSTYLE);
if not ToolbarStyle and not Enabled and (HoverKind = hkKeyboardHover) then _Draw(C)
else if Enabled then
begin
if ToolbarStyle and (Pushed or Selected) and not (InMenuBar and USE_FLATMENUS) then
OffsetRect(R, 1, 1);
_Draw(C);
end
else if USE_THEMES then _Draw(C)
else
begin
OffsetRect(R, 1, 1);
_Draw(clBtnHighlight);
OffsetRect(R, -1, -1);
_Draw(clBtnShadow);
end;
Brush.Style := bsSolid;
end;
end;
procedure TTBXDefaultTheme.PaintCheckMark(Canvas: TCanvas; ARect: TRect; const ItemInfo: TTBXItemInfo);
var
DC: HDC;
X, Y: Integer;
C: TColor;
begin
DC := Canvas.Handle;
X := (ARect.Left + ARect.Right) div 2 - 1;
Y := (ARect.Top + ARect.Bottom) div 2 + 1;
if ItemInfo.Enabled
then C := clBtnText
else C := clGrayText;
if ItemInfo.ItemOptions and IO_RADIO > 0 then
begin
RoundRectEx(DC, X-2, Y-4, X+4, Y+2, 2, 2,
MixColors(C, clBtnHighlight, 128), clNone);
RoundRectEx(DC, X-2, Y-4, X+4, Y+2, 6, 6, C, C);
if ItemInfo.Enabled then
RoundRectEx(DC, X-3, Y-5, X+5, Y+3, 6, 6, clBtnHighlight, clNone);
end
else begin
PolyLineEx(DC, [Point(X-2, Y-2), Point(X, Y), Point(X+4, Y-4),
Point(X+4, Y-3), Point(X, Y+1), Point(X-2, Y-1), Point(X-2, Y-2)], C);
if ItemInfo.Enabled then
PolyLineEx(DC, [Point(X-3, Y-2), Point(X-3, Y-1), Point(X, Y+2),
Point(X+5, Y-3), Point(X+5, Y-5)], clBtnHighlight);
end;
end;
procedure TTBXDefaultTheme.PaintChevron(Canvas: TCanvas; ARect: TRect;
const ItemInfo: TTBXItemInfo);
const
Pattern: array [Boolean, 0..15] of Byte = (
($CC, 0, $66, 0, $33, 0, $66, 0, $CC, 0, 0, 0, 0, 0, 0, 0),
($88, 0, $D8, 0, $70, 0, $20, 0, $88, 0, $D8, 0, $70, 0, $20, 0));
var
DC: HDC;
R2: TRect;
P: PByte;
W, H: Integer;
begin
DC := Canvas.Handle;
R2 := ARect;
PaintButton(Canvas, R2, ItemInfo);
if not ItemInfo.IsVertical then
begin
Inc(R2.Top, 4);
R2.Bottom := R2.Top + 5;
W := 8;
H := 5;
end
else
begin
R2.Left := R2.Right - 9;
R2.Right := R2.Left + 5;
W := 5;
H := 8;
end;
if ItemInfo.Pushed then OffsetRect(R2, 1, 1);
P := @Pattern[ItemInfo.IsVertical][0];
if ItemInfo.Enabled then DrawGlyph(DC, R2, W, H, P^, clBtnText)
else
begin
OffsetRect(R2, 1, 1);
DrawGlyph(DC, R2, W, H, P^, clBtnHighlight);
OffsetRect(R2, -1, -1);
DrawGlyph(DC, R2, W, H, P^, clBtnShadow);
end;
end;
procedure TTBXDefaultTheme.PaintEditButton(Canvas: TCanvas; const ARect: TRect;
var ItemInfo: TTBXItemInfo; ButtonInfo: TTBXEditBtnInfo);
var
DC: HDC;
BtnDisabled, BtnHot, BtnPressed, Embedded: Boolean;
StateFlags: Integer;
R, BR: TRect;
C: TColor;
X, Y: Integer;
procedure DrawEnabled(var R: TRect);
begin
if BtnPressed then
Windows.DrawEdge(Canvas.Handle, R, BDR_SUNKENOUTER, BF_RECT or BF_ADJUST)
else if BtnHot then
Windows.DrawEdge(Canvas.Handle, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST)
else if not Embedded then
FrameRectEx(DC, R, clWindow, False);
end;
procedure DrawUp;
begin
X := (R.Left + R.Right) div 2 + Ord(BtnPressed);
Y := (R.Top * 3 + R.Bottom + 3) div 4 + Ord(BtnPressed);
if not BtnDisabled then
begin
if Boolean(ItemInfo.ItemOptions and IO_TOOLBARSTYLE) then C := clPopupText
else C := clBtnText;
end
else with Canvas do
begin
Inc(X); Inc(Y);
Pen.Color := clBtnHighlight; Brush.Color := clBtnHighlight;
Polygon([Point(X - 2, Y), Point(X + 2, Y), Point(X, Y - 2)]);
Dec(X); Dec(Y);
C := clBtnShadow;
end;
Canvas.Pen.Color := C; Canvas.Brush.Color := C;
Canvas.Polygon([Point(X - 2, Y), Point(X + 2, Y), Point(X, Y - 2)])
end;
procedure DrawDn;
begin
X := (R.Left + R.Right) div 2 + Ord(BtnPressed);
Y := (R.Top + R.Bottom * 3 - 4) div 4 + Ord(BtnPressed);
if not BtnDisabled then
begin
if Boolean(ItemInfo.ItemOptions and IO_TOOLBARSTYLE) then C := clPopupText
else C := clBtnText;
end
else with Canvas do
begin
Inc(X); Inc(Y);
Pen.Color := clBtnHighlight; Brush.Color := clBtnHighlight;
Polygon([Point(X - 2, Y), Point(X + 2, Y), Point(X, Y + 2)]);
Dec(X); Dec(Y);
C := clBtnShadow;
end;
Canvas.Pen.Color := C; Canvas.Brush.Color := C;
Canvas.Polygon([Point(X - 2, Y), Point(X + 2, Y), Point(X, Y + 2)])
end;
begin
DC := Canvas.Handle;
R := ARect;
with Canvas, ItemInfo do
begin
Embedded := ((ViewType and VT_TOOLBAR) = VT_TOOLBAR) and
((ViewType and TVT_EMBEDDED) = TVT_EMBEDDED);
if ButtonInfo.ButtonType = EBT_DROPDOWN then
begin
{ DropDown button }
BtnDisabled := (ButtonInfo.ButtonState and EBDS_DISABLED) <> 0;
BtnHot := (ButtonInfo.ButtonState and EBDS_HOT) <> 0;
BtnPressed := (ButtonInfo.ButtonState and EBDS_PRESSED) <> 0;
if USE_THEMES then
begin
if BtnDisabled then StateFlags := CBXS_DISABLED
else if BtnPressed then StateFlags := CBXS_PRESSED
else if BtnHot then StateFlags := CBXS_HOT
else StateFlags := CBXS_NORMAL;
if BtnHot then InflateRect(R, 1, 1);
DrawThemeBackground(COMBO_THEME, Handle, CP_DROPDOWNBUTTON, StateFlags, R, nil);
end
else
begin
Inc(R.Left, 2);
if not BtnDisabled then with R do
begin
if Embedded then FillRectEx(DC, R, clBtnFace);
if BtnPressed or BtnHot then
DrawLineEx(DC, Left - 1, Top, Left - 1, Bottom + 1, ToolbarColor)
else if Embedded then
DrawLineEx(DC, Left - 1, Top, Left - 1, Bottom, clBtnShadow)
else
DrawLineEx(DC, Left - 1, Top, Left - 1, Bottom, clWindow);
DrawEnabled(R);
end;
PaintDropDownArrow(Canvas, R, ItemInfo);
end;
end
else if ButtonInfo.ButtonType = EBT_SPIN then
begin
{ Paint spin buttons }
BtnDisabled := (ButtonInfo.ButtonState and EBSS_DISABLED) <> 0;
BtnHot := (ButtonInfo.ButtonState and EBSS_HOT) <> 0;
if USE_THEMES then
begin
if BtnHot then InflateRect(R, 1, 1);
{ Upper with XP themes }
BR := R;
BR.Bottom := (R.Top + R.Bottom - 1) div 2;
BtnPressed := (ButtonInfo.ButtonState and EBSS_UP) <> 0;
if BtnDisabled then StateFlags := UPS_DISABLED
else if BtnPressed then StateFlags := UPS_PRESSED
else if BtnHot then StateFlags := UPS_HOT
else StateFlags := UPS_NORMAL;
DrawThemeBackground(SPIN_THEME, Handle, SPNP_UP, StateFlags, BR, nil);
{ Lower with XP themes }
BR := R;
BR.Top := (R.Top + R.Bottom) div 2;
BtnPressed := (ButtonInfo.ButtonState and EBSS_DOWN) <> 0;
if BtnDisabled then StateFlags := DNS_DISABLED
else if BtnPressed then StateFlags := DNS_PRESSED
else if BtnHot then StateFlags := DNS_HOT
else StateFlags := DNS_NORMAL;
DrawThemeBackground(SPIN_THEME, Handle, SPNP_DOWN, StateFlags, BR, nil);
end
else
begin
Inc(R.Left, 2);
if not BtnDisabled then with R do
if BtnPressed or BtnHot then
DrawLineEx(DC, Left - 1, Top - 1, Left - 1, Bottom + 1, ToolbarColor)
else if Embedded then
DrawLineEx(DC, Left - 1, Top, Left - 1, Bottom, clBtnShadow)
else
DrawLineEx(DC, Left - 1, Top, Left - 1, Bottom, clWindow);
BR := R;
BR.Bottom := (R.Top + R.Bottom + 1) div 2;
BtnPressed := (ButtonInfo.ButtonState and EBSS_UP) <> 0;
if BtnHot or BtnPressed then Dec(BR.Bottom);
if not BtnDisabled then DrawEnabled(BR);
DrawUp;
BR := R;
BR.Top := (R.Top + R.Bottom) div 2;
BtnPressed := (ButtonInfo.ButtonState and EBSS_DOWN) <> 0;
if BtnHot or BtnPressed then Inc(BR.Top);
if not BtnDisabled then DrawEnabled(BR);
DrawDn;
end;
end;
end;
end;
procedure TTBXDefaultTheme.PaintEditFrame(Canvas: TCanvas;
const ARect: TRect; var ItemInfo: TTBXItemInfo; const EditInfo: TTBXEditInfo);
var
R: TRect;
W: Integer;
begin
R := ARect;
PaintFrame(Canvas, R, ItemInfo);
W := EditFrameWidth;
InflateRect(R, -W, -W);
with EditInfo do if RightBtnWidth > 0 then Dec(R.Right, RightBtnWidth - 2);
Canvas.Brush.Color := clWindow;
if ItemInfo.Enabled then Canvas.FillRect(R);
with EditInfo do if LeftBtnWidth > 0 then Inc(R.Left, LeftBtnWidth - 2);
if EditInfo.RightBtnWidth > 0 then
begin
R := ARect;
InflateRect(R, -W, -W);
R.Left := R.Right - EditInfo.RightBtnWidth;
PaintEditButton(Canvas, R, ItemInfo, EditInfo.RightBtnInfo);
end;
end;
procedure TTBXDefaultTheme.PaintDropDownArrow(Canvas: TCanvas;
const ARect: TRect; const ItemInfo: TTBXItemInfo);
var
X, Y: Integer;
procedure Draw(AColor: TColor);
begin
Canvas.Pen.Color := AColor;
Canvas.Brush.Color := AColor;
if ItemInfo.IsVertical then Canvas.Polygon([Point(X, Y + 2), Point(X, Y - 2), Point(X - 2, Y)])
else Canvas.Polygon([Point(X - 2, Y), Point(X + 2, Y), Point(X, Y + 2)]);
end;
begin
with ItemInfo, ARect do
begin
X := (Left + Right) div 2;
Y := (Top + Bottom) div 2 - 1;
if (Pushed or Selected) and (ComboPart <> cpSplitRight) then
begin
Inc(X); Inc(Y);
end;
if Enabled then
begin
if Boolean(ItemOptions and IO_TOOLBARSTYLE) then Draw(clPopupText)
else Draw(clBtnText);
end
else
begin
Inc(X); Inc(Y);
Draw(clBtnHighlight);
Dec(X); Dec(Y);
Draw(clBtnShadow);
end;
end;
end;
procedure TTBXDefaultTheme.PaintButton(Canvas: TCanvas; const ARect: TRect; const ItemInfo: TTBXItemInfo);
const
XPPart: array [TTBXComboPart] of Integer = (TP_BUTTON, TP_DROPDOWNBUTTON,
TP_SPLITBUTTON, TP_SPLITBUTTONDROPDOWN);
Edge: array [Boolean] of Integer = (BDR_RAISEDINNER, EDGE_RAISED);
var
R: TRect;
Flags, RegionFlags: Cardinal;
InMenuBar, ShowHover, Embedded, ShowFlatSL: Boolean;
Region: HRGN;
DC: HDC;
Brush, OldBrush: HBrush;
begin
R := ARect;
DC := Canvas.Handle;
with ItemInfo do
begin
ShowHover := (Enabled and (HoverKind <> hkNone)) or
(not Enabled and (HoverKind = hkKeyboardHover));
InMenuBar := (ViewType and TVT_MENUBAR) = TVT_MENUBAR;
Embedded := ((ViewType and VT_TOOLBAR) = VT_TOOLBAR) and
((ViewType and TVT_EMBEDDED) = TVT_EMBEDDED);
if not InMenuBar and USE_THEMES then
begin
{ The support for XP themes in menus is not yet implemented since standard
XP themes seem to have no theming for menus }
if not Enabled then
begin
if HoverKind = hkKeyboardHover then Flags := TS_HOT
else Flags := TS_DISABLED;
end
else if ItemInfo.Pushed then Flags := TS_PRESSED
else if ItemInfo.Selected then
begin
if HoverKind <> hkNone then Flags := TS_HOTCHECKED
else Flags := TS_CHECKED;
end
else if HoverKind <> hkNone then Flags := TS_HOT
else Flags := TS_NORMAL;
if Embedded or Boolean(ItemOptions and IO_DESIGNING) then
begin
{ There is no state for non-transparent normal toolbar button, trying to
simulate it with regions... }
RegionFlags := TS_HOT;
if ComboPart = cpSplitRight then Dec(R.Left);
GetThemeBackgroundRegion(TOOLBAR_THEME, Canvas.Handle, XPPart[ComboPart], RegionFlags, R, Region);
if ComboPart = cpSplitRight then Inc(R.Left);
if Embedded or not Boolean(ItemOptions and IO_DESIGNING) then
begin
Brush := CreateBrushEx(ToolbarColor);
OldBrush := SelectObject(DC, Brush);
FillRgn(DC, Region, Brush);
SelectObject(DC, OldBrush);
DeleteObject(Brush);
end;
Brush := CreateBrushEx(clBtnShadow);
OldBrush := SelectObject(DC, Brush);
FrameRgn(DC, Region, Brush, 1, 1);
SelectObject(DC, OldBrush);
DeleteObject(Brush);
DeleteObject(Region);
end;
DrawThemeBackground(TOOLBAR_THEME, DC, XPPart[ComboPart], Flags, R, nil);
end
else
begin
if InMenuBar and USE_FLATMENUS then
begin
if ((Pushed or Selected) and Enabled) or ShowHover then
FillRectEx(DC, R, clHighlight);
Exit;
end;
{$IFDEF NARROWCOMBOBUTTON}
if (ItemInfo.ComboPart = cpSplitRight) and not (InMenuBar or USE_THEMES) then Dec(R.Right, 2);
{$ENDIF}
if USE_FLATMENUS and (((Pushed or Selected) and Enabled) or ShowHover) then
FillRectEx(DC, R, ToolbarColor);
if Embedded then with Canvas do
begin
Flags := BF_RECT or BF_MIDDLE or BF_ADJUST;
if not ShowHover or (Pushed or Selected or not Enabled) then Flags := Flags or BF_FLAT;
ShowFlatSL := (ComboPart = cpSplitLeft) and not (ShowHover or Pushed);
if ShowFlatSL then Inc(R.Right);
Windows.DrawEdge(Handle, R, EDGE_RAISED, Flags);
if Selected and Enabled and (HoverKind = hkNone) then
DitherRect(DC, R, ToolbarColor, clBtnHighlight);
if ShowFlatSL then Dec(R.Right);
end
else if (Pushed or Selected) and Enabled then with Canvas do
begin
Windows.DrawEdge(Handle, R, BDR_SUNKENOUTER, BF_RECT or BF_ADJUST);
if not Pushed and (HoverKind = hkNone) then
DitherRect(DC, R, ToolbarColor, clBtnHighlight);
end
else if ShowHover or Boolean(ItemOptions and IO_DESIGNING) then
Windows.DrawEdge(Canvas.Handle, R, BDR_RAISEDINNER, BF_RECT);
if ComboPart = cpSplitRight then PaintDropDownArrow(Canvas, R, ItemInfo);
end;
end;
end;
procedure TTBXDefaultTheme.PaintFloatingBorder(Canvas: TCanvas; const ARect: TRect; const WindowInfo: TTBXWindowInfo);
const
SPI_GETGRADIENTCAPTIONS = $1008;
DC_GRADIENT = $20;
ActiveCaptionFlags: array [Boolean] of Integer = (0, DC_ACTIVE);
GradientCaptionFlags: array [Boolean] of Integer = (0, DC_GRADIENT);
CaptionBkColors: array [Boolean, Boolean] of Integer =
((COLOR_INACTIVECAPTION, COLOR_ACTIVECAPTION),
(COLOR_GRADIENTINACTIVECAPTION, COLOR_GRADIENTACTIVECAPTION));
ButtonStateFlags: array [Boolean] of Integer = (0, DFCS_PUSHED);
var
R, R2: TRect;
DC: HDC;
Flags: Integer;
Gradient, ShowCloseBtn: Boolean;
B: BOOL;
begin
DC := Canvas.Handle;
with WindowInfo do
if not USE_THEMES then
begin
R := ARect;
if (WRP_BORDER and RedrawPart) <> 0 then
begin
R2 := R;
with FloatingBorderSize do InflateRect(R2, -X, -Y);
SaveDC(DC);
with R2 do ExcludeClipRect(DC, Left, Top, Right, Bottom);
Windows.DrawEdge(DC, R, EDGE_RAISED, BF_RECT or BF_MIDDLE);
RestoreDC(DC, -1);
end;
if not WindowInfo.ShowCaption then Exit;
Gradient := SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, @B, 0) and B;
ShowCloseBtn := (CDBS_VISIBLE and CloseButtonState) <> 0;
R := GetTBXCloseButtonRect(WindowInfo, True);
if (WRP_CAPTION and RedrawPart) <> 0 then
begin
if ShowCloseBtn then
begin
SaveDC(DC);
with R do ExcludeClipRect(DC, Left, Top, Right, Bottom);
end;
R2 := GetTBXCaptionRect(WindowInfo, True, ShowCloseBtn);
DrawCaption(ParentHandle, DC, R2, DC_TEXT or DC_SMALLCAP or
ActiveCaptionFlags[Active] or GradientCaptionFlags[Gradient]);
if ShowCloseBtn then RestoreDC(DC, -1);
R2 := GetTBXCaptionRect(WindowInfo, True, False);
R2.Top := R2.Bottom;
Inc(R2.Bottom);
FillRect(DC, R2, GetSysColorBrush(COLOR_BTNFACE));
end;
if ShowCloseBtn then
begin
R2 := R;
InflateRect(R2, -2, -2);
if (WRP_CAPTION and RedrawPart) <> 0 then
begin
SaveDC(DC);
with R2 do ExcludeClipRect(DC, Left, Top, Right, Bottom);
FillRect(DC, R, GetSysColorBrush(CaptionBkColors[Gradient, WindowInfo.Active]));
RestoreDC(DC, -1);
end;
if (WRP_CLOSEBTN and RedrawPart) <> 0 then
DrawFrameControl(DC, R2, DFC_CAPTION, DFCS_CAPTIONCLOSE or
ButtonStateFlags[(CDBS_PRESSED and CloseButtonState) <> 0]);
end;
end
else { Use WindowsXP visual styles }
begin
if (WRP_BORDER and RedrawPart) <> 0 then
begin
if Active then Flags := FS_ACTIVE else Flags := FS_INACTIVE;
R := ARect;
R.Top := R.Bottom - FloatingBorderSize.Y;
DrawThemeBackground(WINDOW_THEME, DC, WP_SMALLFRAMEBOTTOM, Flags, R, nil);
R.Top := ARect.Top;
R.Bottom := R.Top + FloatingBorderSize.Y;
{if WindowInfo.ShowCaption then} { TODO : how to paint a captionless window frame }
Inc(R.Bottom, GetSystemMetrics(SM_CYSMCAPTION));
DrawThemeBackground(WINDOW_THEME, DC, WP_SMALLCAPTION, Flags, R, nil);
R.Top := R.Bottom;
R.Bottom := ARect.Bottom - FloatingBorderSize.Y;
R.Right := R.Left + FloatingBorderSize.X;
DrawThemeBackground(WINDOW_THEME, DC, WP_SMALLFRAMELEFT, Flags, R, nil);
R.Right := ARect.Right;
R.Left := R.Right - FloatingBorderSize.X;
DrawThemeBackground(WINDOW_THEME, DC, WP_SMALLFRAMERIGHT, Flags, R, nil);
end;
if not ShowCaption then Exit;
{ Get the caption area }
R := ARect;
with FloatingBorderSize do InflateRect(R, -X, -Y);
Dec(R.Bottom, ClientHeight);
if (WRP_CAPTION and RedrawPart) <> 0 then
begin
R2 := R;
if ((CDBS_VISIBLE and CloseButtonState) <> 0) and ((WRP_CLOSEBTN and RedrawPart) <> 0) then
Dec(R2.Right, GetSystemMetrics(SM_CYSMCAPTION));
Canvas.Font.Assign(SmCaptionFont);
if Active then Canvas.Font.Color := clCaptionText
else Canvas.Font.Color := clInactiveCaptionText;
Canvas.Brush.Style := bsClear;
{ This is strange... the DrawThemeText function refuses to work...
Use standard API... }
DrawText(Canvas.Handle, WindowInfo.Caption, -1, R2,
DT_SINGLELINE or DT_VCENTER or DT_END_ELLIPSIS or DT_HIDEPREFIX);
Canvas.Brush.Style := bsSolid;
end;
if (CDBS_VISIBLE and CloseButtonState) <> 0 then
begin
Dec(R.Bottom);
R.Left := R.Right - R.Bottom + R.Top;
InflateRect(R, -2, -2);
if (CDBS_PRESSED and CloseButtonState) <> 0 then Flags := CBS_PUSHED
else if (CDBS_HOT and CloseButtonState) <> 0 then Flags := CBS_HOT
else Flags := CBS_NORMAL;
DrawThemeBackground(WINDOW_THEME, DC, WP_SMALLCLOSEBUTTON, Flags, R, nil);
end;
end;
end;
procedure TTBXDefaultTheme.PaintFrame(Canvas: TCanvas; const ARect: TRect; const ItemInfo: TTBXItemInfo);
var
DC: HDC;
R: TRect;
E, Embedded: Boolean;
Flags, Border: Integer;
C: TColor;
begin
R := ARect;
DC := Canvas.Handle;
with ItemInfo do
begin
E := (Enabled and (HoverKind <> hkNone)) or
(not Enabled and (HoverKind = hkKeyboardHover));
Embedded := ((ViewType and VT_TOOLBAR) = VT_TOOLBAR) and
((ViewType and TVT_EMBEDDED) = TVT_EMBEDDED);
if USE_THEMES then
begin
InflateRect(R, -1, -1);
if Embedded then C := clBtnShadow
else C := ToolbarColor;
FrameRectEx(DC, R, C, False);
InflateRect(R, 1, 1);
if Pushed or Selected or E or ((ItemOptions and IO_DESIGNING) <> 0)
then DrawThemeBackground(COMBO_THEME, DC, 0, 0, R, nil);
InflateRect(R, -2, -2);
FrameRectEx(DC, R, clWindow, False);
end
else
begin
if Embedded then
begin
Flags := BF_RECT;
if not (Pushed or Selected or E) then
begin
InflateRect(R, -1, -1);
Flags := Flags or BF_FLAT;
Border := BDR_SUNKENOUTER;
end
else Border := EDGE_SUNKEN;
Windows.DrawEdge(DC, R, Border, Flags);
if (Pushed or Selected or E) then InflateRect(R, -1, -1);
end
else
begin
if Pushed or Selected or E or ((ItemOptions and IO_DESIGNING) <> 0) then
Windows.DrawEdge(DC, R, BDR_SUNKENOUTER, BF_RECT);
InflateRect(R, -1, -1);
FrameRectEx(DC, R, ToolbarColor, True);
FrameRectEx(DC, R, clWindow, False);
end;
end;
end;
end;
function TTBXDefaultTheme.GetImageOffset(Canvas: TCanvas; const ItemInfo: TTBXItemInfo;
ImageList: TCustomImageList): TPoint;
const
Offsets: array [Boolean] of TPoint = ((X:0; Y:0), (X:1; Y:1));
begin
with ItemInfo do
Result := Offsets[Pushed or Selected];
end;
procedure TTBXDefaultTheme.PaintImage(Canvas: TCanvas; ARect: TRect;
const ItemInfo: TTBXItemInfo; ImageList: TCustomImageList; ImageIndex: Integer);
var
BgColor: TColor;
HiContrast: Boolean;
IsMenuItem: Boolean;
begin
with ItemInfo do
begin
if ImageList is TTBCustomImageList then
begin
if Pushed or Selected then OffsetRect(ARect, 1, 1);
TTBCustomImageList(ImageList).DrawState(Canvas, ARect.Left, ARect.Top,
ImageIndex, Enabled, (HoverKind <> hkNone), Selected);
Exit;
end;
IsMenuItem := ((ViewType and PVT_POPUPMENU) = PVT_POPUPMENU) and
((ItemOptions and IO_TOOLBARSTYLE) = 0);
if (IsMenuItem and USE_FLATMENUS) or (not IsMenuItem and USE_THEMES) then
begin
{ The icon painting here is not really made by the uxtheme.dll, this is
just a simulation until I figure out how to work with DrawThemedIcon function }
if Pushed or Selected then OffsetRect(ARect, 1, 1);
BgColor := GetItemImageBackground(ItemInfo);
HiContrast := not IsMenuItem and IsDarkColor(BGColor);
if not Enabled then
DrawTBXIconShadow(Canvas, ARect, ImageList, ImageIndex, 0)
else if Selected or Pushed or (HoverKind <> hkNone) then
DrawTBXIcon(Canvas, ARect, ImageList, ImageIndex, HiContrast)
else if HiContrast or TBXHiContrast or TBXLoColor then
DrawTBXIcon(Canvas, ARect, ImageList, ImageIndex, HiContrast)
else
HighlightTBXIcon(Canvas, ARect, ImageList, ImageIndex, clWindow, 178);
end
else
begin
if Pushed or Selected then OffsetRect(ARect, 1, 1);
ImageList.Draw(Canvas, ARect.Left, ARect.Top, ImageIndex, Enabled);
end;
end;
end;
procedure TTBXDefaultTheme.PaintMDIButton(Canvas: TCanvas; ARect: TRect;
const ItemInfo: TTBXItemInfo; ButtonKind: Cardinal);
const
PushedFlags: array[Boolean] of UINT = (0, DFCS_PUSHED);
var
XPPart, XPFlags: Cardinal;
begin
if USE_THEMES then
begin
case ButtonKind of
DFCS_CAPTIONMIN: XPPart := WP_MDIMINBUTTON;
DFCS_CAPTIONRESTORE: XPPart := WP_MDIRESTOREBUTTON;
DFCS_CAPTIONCLOSE: XPPart := WP_MDICLOSEBUTTON;
else
XPPart := 0;
end;
if ItemInfo.Pushed then XPFlags := CBS_PUSHED
else if ItemInfo.HoverKind <> hkNone then XPFlags := CBS_HOT
else XPFlags := CBS_NORMAL;
DrawThemeBackground(WINDOW_THEME, Canvas.Handle, XPPart, XPFLags, ARect, nil);
end
else
begin
DrawFrameControl(Canvas.Handle, ARect, DFC_CAPTION,
ButtonKind or PushedFlags[ItemInfo.Pushed]);
end;
end;
procedure TTBXDefaultTheme.PaintMenuItemFrame(Canvas: TCanvas;
const ARect: TRect; const ItemInfo: TTBXItemInfo);
var
DC: HDC;
begin
DC := Canvas.Handle;
with ItemInfo do if (Enabled and (HoverKind <> hkNone)) or
(not Enabled and (HoverKind = hkKeyboardHover)) then
FillRectEx(DC, ARect, clHighlight);
end;
procedure TTBXDefaultTheme.PaintMenuItem(Canvas: TCanvas; const ARect: TRect; var ItemInfo: TTBXItemInfo);
var
DC: HDC;
R: TRect;
ShowImageOrCheck: Boolean;
ShowHover: Boolean;
IsComboItem: Boolean;
X, Y: Integer;
ArrowWidth: Integer;
procedure DrawArrow(AColor: TColor);
begin
PolygonEx(DC, [Point(X, Y - 3), Point(X, Y + 3), Point(X + 3, Y)], AColor, AColor);
end;
begin
DC := Canvas.Handle;
with ItemInfo do
begin
ShowImageOrCheck := (ImageWidth > 0) or Selected;
ShowHover := (Enabled and (HoverKind <> hkNone)) or
(not Enabled and (HoverKind = hkKeyboardHover));
ArrowWidth := GetSystemMetrics(SM_CXMENUCHECK);
R := ARect;
if ShowImageOrCheck then Inc(R.Left, ItemInfo.PopupMargin + MenuImageTextSpace);
IsComboItem := ((ItemOptions and IO_COMBO) <> 0);
if IsComboItem and Enabled then Dec(R.Right, ArrowWidth);
PaintMenuItemFrame(Canvas, R, ItemInfo);
if IsComboItem then
begin
R.Left := ARect.Right - ArrowWidth;
R.Right := ARect.Right;
if Enabled and (HoverKind <> hkNone) then
Windows.DrawEdge(DC, R, BDR_SUNKENOUTER, BF_RECT)
else
begin
Dec(R.Left);
if not ShowHover then DrawEdge(DC, R, EDGE_ETCHED, BF_LEFT)
else DrawEdge(DC, R, BDR_SUNKENOUTER, BF_LEFT);
end;
end;
if (ItemOptions and IO_SUBMENUITEM) <> 0 then
begin
Y := ARect.Bottom div 2;
X := ARect.Right - ArrowWidth * 2 div 3 - 2;
if not Enabled then
begin
if HoverKind = hkKeyboardHover then DrawArrow(clBtnShadow)
else
begin
Inc(X); Inc(Y);
DrawArrow(clBtnHighlight);
Dec(X); Dec(Y);
DrawArrow(clBtnShadow);
end;
end
else if (HoverKind <> hkNone) and not IsComboItem then DrawArrow(clHighlightText)
else DrawArrow(clPopupText);
end;
if Enabled and ShowImageOrCheck and ((HoverKind <> hkNone) or Selected) then
begin
R.Left := ARect.Left;
R.Right := R.Left + ItemInfo.PopupMargin;
if USE_FLATMENUS then FillRectEx(DC, R, ToolbarColor);
PaintButton(Canvas, R, ItemInfo);
end;
end;
end;
procedure TTBXDefaultTheme.PaintPopupNCArea(Canvas: TCanvas; R: TRect; const PopupInfo: TTBXPopupInfo);
var
DC: HDC;
begin
DC := Canvas.Handle;
{$IFNDEF OFFICE2K_COMBOS}
if (PopupInfo.ViewType and PVT_LISTBOX) = PVT_LISTBOX then
begin
FrameRectEx(DC, R, clWindowFrame, True);
FrameRectEx(DC, R, clWindow, True);
FrameRectEx(DC, R, clWindow, False);
end
else
{$ENDIF}
if USE_FLATMENUS and ((PopupInfo.ViewType and PVT_TOOLBOX) <> PVT_TOOLBOX) then
begin
FrameRectEx(DC, R, clBtnShadow, True);
FrameRectEx(DC, R, clPopup, True);
FrameRectEx(DC, R, clPopup, False);
end
else if (PopupInfo.ViewType and PVT_TOOLBOX) = PVT_TOOLBOX then
begin
Windows.DrawEdge(DC, R, EDGE_RAISED, BF_RECT or BF_ADJUST);
FrameRectEx(DC, R, ToolbarColor, False);
end
else
begin
Windows.DrawEdge(DC, R, EDGE_RAISED, BF_RECT or BF_ADJUST);
FrameRectEx(DC, R, clPopup, False);
end;
end;
procedure TTBXDefaultTheme.PaintSeparator(Canvas: TCanvas; ARect: TRect;
ItemInfo: TTBXItemInfo; Horizontal, LineSeparator: Boolean);
const
XPFlags: array [Boolean] of Integer = (TP_SEPARATOR, TP_SEPARATORVERT);
var
D: Integer;
begin
{ Note: for blank separators, Enabled = False }
with ItemInfo, ARect do if Enabled then
begin
if not USE_THEMES or ((ViewType and PVT_POPUPMENU) = PVT_POPUPMENU) then
begin
D := 0;
if LineSeparator then
if (ViewType and TVT_FLOATING) <> 0 then D := 1
else D := 4;
if Horizontal then
begin
if (ItemOptions and IO_TOOLBARSTYLE) = 0 then D := 12;
Top := (Top + Bottom) div 2 - 1;
Inc(Left, D); Dec(Right, D);
Windows.DrawEdge(Canvas.Handle, ARect, EDGE_ETCHED, BF_TOP);
end
else
begin
Left := (Left + Right) div 2 - 1;
Inc(Top, D); Dec(Bottom, D);
Windows.DrawEdge(Canvas.Handle, ARect, EDGE_ETCHED, BF_LEFT);
end;
end
else
DrawThemeBackground(TOOLBAR_THEME, Canvas.Handle, XPFlags[Horizontal], TS_NORMAL, ARect, nil);
end;
end;
procedure TTBXDefaultTheme.PaintToolbarNCArea(Canvas: TCanvas; R: TRect; const ToolbarInfo: TTBXToolbarInfo);
const
DragHandleSizes: array [Boolean, DHS_DOUBLE..DHS_SINGLE] of Integer = ((9, 0, 6), (14, 14, 14));
DragHandleOffsets: array [Boolean, DHS_DOUBLE..DHS_SINGLE] of Integer = ((2, 0, 2), (3, 0, 5));
GripperPart: array [Boolean] of Cardinal = (RP_GRIPPER, RP_GRIPPERVERT);
Pattern: array [0..15] of Byte = (0, 0, $CC, 0, $78, 0, $30, 0, $78, 0, $CC, 0, 0, 0, 0, 0);
var
// DC: HDC;
DHSize: Integer;
// Sz: TSize;
R2: TRect;
Flags: Cardinal;
Z: Integer;
BtnVisible, Horz, CloseButtondown, CloseButtonHover: Boolean;
begin
{ DC := Canvas.Handle;
if ToolbarInfo.EffectiveColor <> clNone then FillRectEx(DC, R, ToolbarInfo.EffectiveColor); }
Canvas.FillRect(R);
{ Border }
if ToolbarInfo.BorderStyle = bsSingle then
if USE_THEMES then
begin
Frame3D(Canvas.Handle, R, Lighten(ToolbarInfo.EffectiveColor, 24), Lighten(ToolbarInfo.EffectiveColor, -32), False);
// DrawThemeEdge(TOOLBAR_THEME, Canvas.Handle, RP_BAND, 0, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST, @R)
end
else
Windows.DrawEdge(Canvas.Handle, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST);
if not ToolbarInfo.AllowDrag then Exit;
BtnVisible := (ToolbarInfo.CloseButtonState and CDBS_VISIBLE) <> 0;
Horz := not ToolbarInfo.IsVertical;
DHSize := GetTBXDragHandleSize(ToolbarInfo);
if Horz then R.Right := R.Left + DHSize
else R.Bottom := R.Top + DHSize;
{ Drag handle area }
if ToolbarInfo.DragHandleStyle <> DHS_NONE then
begin
if USE_THEMES then
begin
R2 := R;
if BtnVisible then
if Horz then Inc(R2.Top, DHSize - 1)
else Dec(R2.Right, DHSize - 1);
{ Since GetThemePartSize does not seem to work properly, assume we use default
WindowsXP themes where the gripper pattern repeats itself every 4 pixels }
if Horz then
begin
R2.Left := (R2.Left + R2.Right - 6) div 2;
R2.Right := R2.Left + 6;
Z := R2.Bottom - R2.Top;
R2.Top := R2.Top - 1 + (Z and $3) shr 1;
R2.Bottom := R2.Top + Z and not $3 + 1;
end
else
begin
R2.Top := (R2.Top + R2.Bottom - 6) div 2;
R2.Bottom := R2.Top + 6;
Z := R2.Right - R2.Left;
R2.Left := R2.Left - 1 + (Z and $3) shr 1;
R2.Right := R2.Left + Z and not $3 + 2;
end;
DrawThemeBackground(REBAR_THEME, Canvas.Handle, GripperPart[ToolbarInfo.IsVertical], 0, R2, nil)
end
else
begin
R2 := R;
if Horz then
begin
Inc(R2.Left, DragHandleOffsets[BtnVisible, ToolbarInfo.DragHandleStyle]);
if BtnVisible then Inc(R2.Top, DHSize - 2);
R2.Right := R2.Left + 3;
InflateRect(R2, 0, -1);
end
else
begin
Inc(R2.Top, DragHandleOffsets[BtnVisible, ToolbarInfo.DragHandleStyle]);
if BtnVisible then Dec(R2.Right, DHSize - 2);
R2.Bottom := R2.Top + 3;
InflateRect(R2, -1, 0);
end;
Windows.DrawEdge(Canvas.Handle, R2, BDR_RAISEDINNER, BF_RECT);
Canvas.Pixels[R2.Left, R2.Bottom - 1] := clBtnHighlight;
if ToolbarInfo.DragHandleStyle = DHS_DOUBLE then
begin
if Horz then OffsetRect(R2, 3, 0)
else OffsetRect(R2, 0, 3);
Windows.DrawEdge(Canvas.Handle, R2, BDR_RAISEDINNER, BF_RECT);
Canvas.Pixels[R2.Left, R2.Bottom - 1] := clBtnHighlight;
end;
end;
end;
{ Close Button }
if BtnVisible then
begin
CloseButtonDown := (ToolbarInfo.CloseButtonState and CDBS_PRESSED) <> 0;
CloseButtonHover := (ToolbarInfo.CloseButtonState and CDBS_HOT) <> 0;
R2 := GetTBXDockedCloseButtonRect(ToolbarInfo);
Z := 2;
if USE_THEMES then Z := 1;
if Horz then
begin
Dec(R2.Bottom, Z);
Dec(R2.Right, Z);
end
else
begin
Dec(R2.Bottom, Z);
Inc(R2.Left, Z);
end;
if USE_THEMES then
begin
Flags := TS_NORMAL;
if CloseButtonDown then Flags := TS_PRESSED
else if CloseButtonHover then Flags := TS_HOT;
DrawThemeBackground(TOOLBAR_THEME, Canvas.Handle, TP_BUTTON, Flags, R2, nil);
if CloseButtonDown then OffsetRect(R2, 1, 1);
DrawGlyph(Canvas.Handle, R2, 7, 7, Pattern[0], clBtnText);
end
else
begin
if CloseButtonDown then
begin
Windows.DrawEdge(Canvas.Handle, R2, BDR_SUNKENOUTER, BF_RECT);
OffsetRect(R2, 1, 1);
end
else if CloseButtonHover then
Windows.DrawEdge(Canvas.Handle, R2, BDR_RAISEDINNER, BF_RECT);
DrawGlyph(Canvas.Handle, R2, 7, 7, Pattern[0], clBtnText);
end;
end;
end;
procedure TTBXDefaultTheme.PaintDock(Canvas: TCanvas; const ClientRect, DockRect: TRect; DockPosition: Integer);
var
R: TRect;
begin
if not USE_THEMES then Exit;
if DockPosition in [DP_LEFT, DP_RIGHT] then
begin
R := DockRect;
Inc(R.Bottom, 1);
DrawThemeBackground(REBAR_THEME, Canvas.Handle, 0, 0, R, nil);
end
else DrawThemeBackground(REBAR_THEME, Canvas.Handle, 0, 0, DockRect, nil);
end;
procedure TTBXDefaultTheme.PaintDockPanelNCArea(Canvas: TCanvas; R: TRect; const DockPanelInfo: TTBXDockPanelInfo);
var
DC: HDC;
Sz: Integer;
R2: TRect;
Flags: Integer;
CloseButtonDown, CloseButtonHover: Boolean;
procedure CaptionFill(R: TRect);
const
GRAD: array [Boolean] of TGradientKind = (gkHorz, gkVert);
begin
if USE_THEMES then
GradFill(DC, R, Lighten(ToolbarColor, 12), Lighten(ToolbarColor, -12), GRAD[DockPanelInfo.IsVertical])
else
FillRectEx(DC, R, ToolbarColor);
end;
begin
DC := Canvas.Handle;
with Canvas, DockPanelInfo do
begin
Sz := GetSystemMetrics(SM_CYSMCAPTION);
{ Border }
FrameRectEx(DC, R, ToolbarColor, True);
R2 := R;
if ShowCaption then
if IsVertical then Inc(R2.Top, Sz)
else Inc(R2.Left, Sz);
FrameRectEx(DC, R2, clWindow, False);
if not ShowCaption then Exit;
{ Caption area }
if IsVertical then R.Bottom := R.Top + Sz
else R.Right := R.Left + Sz;
Windows.DrawEdge(Handle, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST);
{ Close button }
if (CDBS_VISIBLE and CloseButtonState) <> 0 then
begin
CloseButtonDown := (CloseButtonState and CDBS_PRESSED) <> 0;
CloseButtonHover := (CloseButtonState and CDBS_HOT) <> 0;
R2 := R;
Brush.Color := ToolbarColor;
if IsVertical then
begin
R2.Left := R2.Right - Sz;
R.Right := R2.Left;
CaptionFill(R2);
InflateRect(R2, -1, -1);
Inc(R2.Left);
end
else
begin
R2.Top := R2.Bottom - Sz;
R.Bottom := R2.Top;
CaptionFill(R2);
InflateRect(R2, -1, -1);
Dec(R2.Bottom);
end;
if USE_THEMES then
begin
Flags := TS_NORMAL;
if CloseButtonDown then Flags := TS_PRESSED
else if CloseButtonHover then Flags := TS_HOT;
DrawThemeBackground(TOOLBAR_THEME, DC, TP_BUTTON, Flags, R2, nil);
if CloseButtonDown then OffsetRect(R2, 1, 1);
InflateRect(R2, -2, -2);
end
else
begin
if CloseButtonDown then
begin
Windows.DrawEdge(DC, R2, BDR_SUNKENOUTER, BF_RECT);
OffsetRect(R2, 1, 1);
end
else if CloseButtonHover then
Windows.DrawEdge(DC, R2, BDR_RAISEDINNER, BF_RECT);
InflateRect(R2, -2, -2);
end;
DrawButtonBitmap(Canvas, R2);
end;
{ Caption }
CaptionFill(R);
if IsVertical then InflateRect(R, -2, 0)
else Inflaterect(R, 0, -2);
Font.Assign(SmCaptionFont);
Font.Color := clBtnText;
Brush.Style := bsClear;
Flags := DT_SINGLELINE or DT_VCENTER or DT_END_ELLIPSIS or DT_NOPREFIX;
if IsVertical then DrawText(Canvas.Handle, Caption, -1, R, Flags)
else DrawRotatedText(Canvas.Handle, string(Caption), R, Flags);
Brush.Style := bsSolid;
end;
end;
function TTBXDefaultTheme.GetPopupShadowType: Integer;
begin
Result := PST_WINDOWSXP;
end;
procedure TTBXDefaultTheme.GetViewMargins(ViewType: Integer; out Margins: TTBXMargins);
begin
with Margins do
if ((ViewType and VT_TOOLBAR) = VT_TOOLBAR) and
((ViewType and TVT_FLOATING) = TVT_FLOATING) then
begin
LeftWidth := 4;
TopHeight := 2;
RightWidth := 4;
BottomHeight := 1;
end
else
begin
LeftWidth := 0;
TopHeight := 0;
RightWidth := 0;
BottomHeight := 0;
end;
end;
procedure TTBXDefaultTheme.PaintPageScrollButton(Canvas: TCanvas;
const ARect: TRect; ButtonType: Integer; Hot: Boolean);
var
R: TRect;
Flags: Integer;
X, Y, Sz: Integer;
begin
R := ARect;
if USE_THEMES then
begin
if Hot then Flags := TS_PRESSED
else Flags := TS_HOT;
DrawThemeBackground(TOOLBAR_THEME, Canvas.Handle, TP_BUTTON, Flags, ARect, nil);
X := (R.Left + R.Right) div 2;
Y := (R.Top + R.Bottom) div 2;
Sz := Min(X - R.Left, Y - R.Top) * 3 div 4;
if Hot then Canvas.Pen.Color := clBtnText;
Canvas.Brush.Color := Canvas.Pen.Color;
case ButtonType of
PSBT_UP:
begin
Inc(Y, Sz div 2);
Canvas.Polygon([Point(X + Sz, Y), Point(X, Y - Sz), Point(X - Sz, Y)]);
end;
PSBT_DOWN:
begin
Y := (R.Top + R.Bottom - 1) div 2;
Dec(Y, Sz div 2);
Canvas.Polygon([Point(X + Sz, Y), Point(X, Y + Sz), Point(X - Sz, Y)]);
end;
PSBT_LEFT:
begin
Inc(X, Sz div 2);
Canvas.Polygon([Point(X, Y + Sz), Point(X - Sz, Y), Point(X, Y - Sz)]);
end;
PSBT_RIGHT:
begin
X := (R.Left + R.Right - 1) div 2;
Dec(X, Sz div 2);
Canvas.Polygon([Point(X, Y + Sz), Point(X + Sz, Y), Point(X, Y - Sz)]);
end;
end;
end
else
begin
if Hot then Flags := DFCS_FLAT
else Flags := 0;
case ButtonType of
PSBT_UP: Flags := Flags or DFCS_SCROLLUP;
PSBT_DOWN: Flags := Flags or DFCS_SCROLLDOWN;
PSBT_LEFT: Flags := Flags or DFCS_SCROLLLEFT;
PSBT_RIGHT: Flags := Flags or DFCS_SCROLLRIGHT;
end;
Windows.DrawFrameControl(Canvas.Handle, R, DFC_SCROLL, Flags);
end;
end;
procedure TTBXDefaultTheme.PaintFrameControl(Canvas: TCanvas; R: TRect; Kind, State: Integer; Params: Pointer);
var
DC: HDC;
X, Y, Flags: Integer;
C: TColor;
Pen, OldPen: HPen;
Brush, OldBrush: HBrush;
function FrameColor: TColor;
begin
if Boolean(State and PFS_DISABLED) then Result := clBtnShadow
else if Boolean(State and (PFS_PUSHED or PFS_HOT)) then Result := clNone
else Result := clBtnShadow;
end;
procedure DiagLine(C: TColor);
begin
with R do
DrawLineEx(DC, Right - 2 - X, Bottom - 2, Right - 1, Bottom - X - 3, C);
Inc(X);
end;
begin
DC := Canvas.Handle;
case Kind of
PFC_CHECKBOX:
begin
if USE_THEMES then
begin
if Boolean(State and PFS_CHECKED) then Flags := CBS_CHECKEDNORMAL
else if Boolean(State and PFS_MIXED) then Flags := CBS_MIXEDNORMAL
else Flags := CBS_UNCHECKEDNORMAL;
if Boolean(State and PFS_DISABLED) then Inc(Flags, 3)
else if Boolean(State and PFS_PUSHED) then Inc(Flags, 2)
else if Boolean(State and PFS_HOT) then Inc(Flags);
DrawThemeBackground(BUTTON_THEME, DC, BP_CHECKBOX, Flags, R, nil);
end
else
begin
C := FrameColor;
if C = clNone then
begin
if Boolean(State and PFS_MIXED) then Flags := DFCS_BUTTON3STATE or DFCS_CHECKED
else Flags := DFCS_BUTTONCHECK;
if Boolean(State and PFS_CHECKED) then Flags := Flags or DFCS_CHECKED;
if Boolean(State and PFS_PUSHED) then Flags := Flags or DFCS_PUSHED;
DrawFrameControl(DC, R, DFC_BUTTON, Flags);
end
else
begin
InflateRect(R, -1, -1);
FrameRectEx(DC, R, C, True);
if Boolean(State and (PFS_DISABLED or PFS_PUSHED)) then FillRectEx(DC, R, clBtnFace)
else if Boolean(State and PFS_MIXED) then DitherRect(DC, R, clWindow, clBtnFace)
else FillRectEx(DC, R, clWindow);
if Boolean(State and (PFS_CHECKED or PFS_MIXED)) then
begin
X := (R.Left + R.Right) div 2 - 1;
Y := (R.Top + R.Bottom) div 2 + 1;
if Boolean(State and PFS_DISABLED) then C := clGrayText
else if Boolean(State and PFS_MIXED) then C := clBtnShadow
else C := clBtnText;
PolygonEx(DC, [Point(X-2, Y), Point(X, Y+2), Point(X+4, Y-2),
Point(X+4, Y-4), Point(X, Y), Point(X-2, Y-2), Point(X-2, Y)], C, C);
end;
end;
end;
end;
PFC_RADIOBUTTON:
begin
if USE_THEMES then
begin
if Boolean(State and PFS_CHECKED) then Flags := RBS_CHECKEDNORMAL
else Flags := RBS_UNCHECKEDNORMAL;
if Boolean(State and PFS_DISABLED) then Inc(Flags, 3)
else if Boolean(State and PFS_PUSHED) then Inc(Flags, 2)
else if Boolean(State and PFS_HOT) then Inc(Flags);
DrawThemeBackground(BUTTON_THEME, DC, BP_RADIOBUTTON, Flags, R, nil);
end
else
begin
C := FrameColor;
if C = clNone then
begin
Flags := DFCS_BUTTONRADIO;
if Boolean(State and PFS_CHECKED) then Flags := Flags or DFCS_CHECKED;
if Boolean(State and PFS_PUSHED) then Flags := Flags or DFCS_PUSHED;
DrawFrameControl(DC, R, DFC_BUTTON, Flags);
end
else
begin
Pen := CreatePenEx(C);
if Boolean(State and (PFS_DISABLED or PFS_PUSHED)) then C := clBtnFace
else C := clWindow;
Brush := CreateBrushEx(C);
InflateRect(R, -1, -1); Inc(R.Left); Dec(R.Bottom);
OldPen := SelectObject(DC, Pen);
OldBrush := SelectObject(DC, Brush);
with R do
Windows.RoundRect(DC, Left, Top, Right, Bottom, Right - Left - 2, Bottom - Top - 2);
SelectObject(DC, OldPen);
SelectObject(DC, OldBrush);
DeleteObject(Pen);
DeleteObject(Brush);
if Boolean(State and PFS_CHECKED) then
begin
InflateRect(R, -3, -3);
Pen := CreatePenEx(clBtnText);
Brush := CreateBrushEx(clBtnText);
OldPen := SelectObject(DC, Pen);
OldBrush := SelectObject(DC, Brush);
with R do Windows.RoundRect(DC, Left, Top, Right, Bottom, Right - Left, Bottom - Top);
SelectObject(DC, OldPen);
SelectObject(DC, OldBrush);
DeleteObject(Pen);
DeleteObject(Brush);
end;
end;
end;
end;
end;
end;
procedure TTBXDefaultTheme.PaintStatusBar(Canvas: TCanvas; R: TRect; Part: Integer);
var
DC: HDC;
D, Sz, I, Flags: Integer;
procedure DiagLine(C: TColor);
begin
with R do
DrawLineEx(DC, Right - 2 - D, Bottom - 2, Right - 1, Bottom - D - 3, C);
Inc(D);
end;
begin
DC := Canvas.Handle;
case Part of
SBP_BODY:
begin
if USE_THEMES then
DrawThemeBackground(STATUSBAR_THEME, DC, 0, 0, R, nil)
else
FillRectEx(DC, R, StatusBarColor);
end;
SBP_PANE, SBP_LASTPANE:
begin
if USE_THEMES then
begin
if Part = SBP_LASTPANE then Flags := SP_GRIPPERPANE
else Flags := SP_PANE;
DrawThemeBackground(STATUSBAR_THEME, DC, Flags, 0, R, nil);
end
else
begin
if Part = SBP_PANE then Dec(R.Right, 2);
Frame3D(DC, R, clBtnShadow, clBtnHighlight, False);
end;
end;
SBP_GRIPPER:
begin
if USE_THEMES then
DrawThemeBackground(STATUSBAR_THEME, DC, SP_GRIPPER, 0, R, nil)
else
begin
D := 0;
Sz := Min(R.Right - R.Left, R.Bottom - R.Top);
for I := 1 to 3 do
case Sz of
0..8:
begin
DiagLine(clBtnShadow);
DiagLine(clBtnHighlight);
end;
9..11:
begin
DiagLine(StatusBarColor);
DiagLine(clBtnShadow);
DiagLine(clBtnHighlight);
end;
12..14:
begin
DiagLine(clBtnShadow);
DiagLine(clBtnShadow);
DiagLine(clBtnHighlight);
end;
else
DiagLine(StatusBarColor);
DiagLine(clBtnShadow);
DiagLine(clBtnShadow);
DiagLine(clBtnHighlight);
end;
with Canvas, R do
begin
Pen.Color := StatusBarColor;
PolylineEx(DC, [
Point(Right - D - 1, Bottom - 1),
Point(Right - 1, Bottom - 1),
Point(Right - 1, Bottom - D - 2)],
StatusBarColor);
end;
end;
end;
end;
end;
procedure TTBXDefaultTheme.SetupColorCache;
begin
ToolbarColor := clBtnFace;
ToolbarText := clBtnText;
StatusBarColor := clBtnFace;
if USE_THEMES then
begin
GetThemeColor(TOOLBAR_THEME, 0, 0, TMT_FILLCOLOR, Cardinal(ToolbarColor));
GetThemeColor(TOOLBAR_THEME, 0, 0, TMT_TEXTCOLOR, Cardinal(ToolbarText));
GetThemeColor(STATUSBAR_THEME, 0, 0, TMT_FILLCOLOR, Cardinal(StatusBarColor));
end;
DockPanelColor := NearestMixedColor(ToolbarColor, clWindow, 64);
end;
procedure TTBXDefaultTheme.TBXSysCommand(var Message: TMessage);
begin
if Message.WParam = TSC_VIEWCHANGE then SetupColorCache;
end;
initialization
InitializeStock;
finalization
FinalizeStock;
end.