git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.SpTBXLib@4 aa3591e4-a9f2-482a-ba07-9d38a056ee4e
10074 lines
340 KiB
ObjectPascal
10074 lines
340 KiB
ObjectPascal
unit SpTBXItem;
|
||
|
||
{==============================================================================
|
||
Version 2.4.4
|
||
|
||
The contents of this file are subject to the SpTBXLib License; you may
|
||
not use or distribute this file except in compliance with the
|
||
SpTBXLib License.
|
||
A copy of the SpTBXLib License may be found in SpTBXLib-LICENSE.txt or at:
|
||
http://www.silverpointdevelopment.com/sptbxlib/SpTBXLib-LICENSE.htm
|
||
|
||
Alternatively, the contents of this file may be used under the terms of the
|
||
Mozilla Public License Version 1.1 (the "MPL v1.1"), in which case the provisions
|
||
of the MPL v1.1 are applicable instead of those in the SpTBXLib License.
|
||
A copy of the MPL v1.1 may be found in MPL-LICENSE.txt or at:
|
||
http://www.mozilla.org/MPL/
|
||
|
||
If you wish to allow use of your version of this file only under the terms of
|
||
the MPL v1.1 and not to allow others to use your version of this file under the
|
||
SpTBXLib License, indicate your decision by deleting the provisions
|
||
above and replace them with the notice and other provisions required by the
|
||
MPL v1.1. If you do not delete the provisions above, a recipient may use your
|
||
version of this file under either the SpTBXLib License or the MPL v1.1.
|
||
|
||
Software distributed under the License is distributed on an "AS IS" basis,
|
||
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
||
the specific language governing rights and limitations under the License.
|
||
|
||
The initial developer of this code is Robert Lee.
|
||
|
||
Requirements:
|
||
For Delphi/C++Builder 2009 or newer:
|
||
- Jordan Russell's Toolbar 2000
|
||
http://www.jrsoftware.org
|
||
For Delphi/C++Builder 7-2007:
|
||
- Jordan Russell's Toolbar 2000
|
||
http://www.jrsoftware.org
|
||
- Troy Wolbrink's TNT Unicode Controls
|
||
http://www.tntware.com/delphicontrols/unicode/
|
||
|
||
Wish list for TB2K:
|
||
- tboSameHeight option for toolbar items, used to stretch the item
|
||
to the highest possible size.
|
||
- It would be nice to have a way to get the TTBItemViewer width and height
|
||
even when the Item is not visible (TTBItemViewer.BoundsRect is not valid
|
||
when the item is not visible).
|
||
As a workaround we should use TTBItemViewer.CalcSize method.
|
||
- It would be nice to allow component writers to override
|
||
TTBCustomToolbar.CreateWrapper so they can create custom TTBControlItem
|
||
items descendants as the dropped control wrappers.
|
||
- It would be nice to have access to the TTBPopupMenu Viewer before the
|
||
popup is showed to initialize the items, for example to set the focus
|
||
on a TTBEditItem.
|
||
|
||
Development notes:
|
||
- All the Windows and Delphi bugs fixes are marked with '[Bugfix]'.
|
||
- All the theme changes and adjustments are marked with '[Theme-Change]'.
|
||
- All the compatibility changes are marked with '[Backward-Compatibility]'.
|
||
- TSpTBXCompoundItemsControl is used as the base class for TB2K items enabled
|
||
Controls, it uses the ITBItems interface and streams the items to the DFM.
|
||
- When a control is dropped on the toolbar a TTBControlItem is created by
|
||
TTBCustomToolbar.CreateWrapper, unfortunately it is created with the
|
||
Toolbar.Owner instead of the Form (Owner.Owner for TSpTBXCompoundItemsControl
|
||
like the TSpTBXTabSet or TSpTBXStatusBar). The workaround is to handle the
|
||
CM_CONTROLCHANGE message in the compound toolbar, stream all the
|
||
TTBControlItem.Control to the DFM (the TSpTBXCompoundItemsControl must be
|
||
the parent in the DFM), and finally reset the TTBControlItem.Control
|
||
parentship to the Toolbar in TSpTBXCompoundItemsControl.Loaded.
|
||
|
||
To Do:
|
||
-
|
||
|
||
History:
|
||
2 December 2009 - version 2.4.4
|
||
- Fixed bug in SpSetFormWindowState utility function, the Form
|
||
was not restored correctly, thanks to Alex Yagolnik for
|
||
reporting this.
|
||
- Fixed incorrect TSpTBXPopupWindow items margins, thanks to
|
||
Pedro Vugluskra for reporting this.
|
||
|
||
13 September 2009 - version 2.4.3
|
||
- Fixed incorrect menu items painting on Vista, thanks to
|
||
Ma<4D>l H<>rz and Sertac Akyuz for reporting this.
|
||
- Fixed TSpTBXToolbar flicker when adding/deleting items.
|
||
- Fixed incorrect TSpTBXStatusBar painting when XP theming was
|
||
disabled, thanks to Warren Postma for reporting this.
|
||
- Fixed incorrect TSpTBXDock painting when the Background
|
||
property was used.
|
||
- Made the NC area of the TSpTBXTitleBar clickeable when the
|
||
form is maximized.
|
||
|
||
8 May 2009 - version 2.4.2
|
||
- Added Dutch translation for the Customizer demo, thanks to
|
||
Alfred Vink.
|
||
- Added Tooltips Vista theming.
|
||
|
||
15 March 2009 - version 2.4.1
|
||
- Fixed incorrect TntAction checking, thanks to Costas Stergiou
|
||
for reporting this.
|
||
|
||
17 January 2009 - version 2.4
|
||
- Replaced the default Windows taskbar PopupMenu with a skninned
|
||
PopupMenu when TSpTBXTitleBar is used on the Main form.
|
||
- Fixed incorrect menu separator painting when it was used on
|
||
a ToolBoxPopup submenu, thanks to Yury Plashenkov for
|
||
reporting this.
|
||
- Fixed incorrect menu item margins, thanks to Eduardo Mauro
|
||
for reporting this.
|
||
|
||
26 September 2008 - version 2.3
|
||
- New Toolbar item added, TSpTBXColorItem.
|
||
- Fixed incorrect Alt-Space handling on TSpTBXTitleBar, the
|
||
System PopupMenu was still showed even when SystemMenu was
|
||
setted to False, thanks to Ilya Zaytsev for reporting this.
|
||
- Fixed incorrect items text sizing when SystemFont was setted
|
||
to False, thanks to Minoru Yoshida for reporting this.
|
||
- Fixed a Delphi 7 bug, D7 hints didn't support multi-monitors,
|
||
thanks to Costas Stergiou for reporting this.
|
||
|
||
29 July 2008 - version 2.2
|
||
- Fixed AV raised when Screen.MonitorFromWindow failed, thanks
|
||
to Andrew Denton for reporting this.
|
||
- Added OnClosePopup event to TSpTBXPopupMenu.
|
||
|
||
26 June 2008 - version 2.1
|
||
- Added Turkish translation for the Customizer demo, thanks to
|
||
Zylar.
|
||
- Fixed incorrect keyboard handling on TSpTBXTitleBar, Alt+Space
|
||
didn't popup the system menu, thanks to Costas Stergiou for
|
||
reporting this.
|
||
|
||
3 May 2008 - version 2.0
|
||
- SpTBXLib is now decoupled from TBX and uses the latest version
|
||
of TB2K, with NO PATCHES REQUIRED.
|
||
- Added HideEmptyPopup property to TSpTBXSubmenuItem, when
|
||
the submenu has no items and this property is set the
|
||
popup window will not be showed.
|
||
- Added Swedish translation for the Customizer demo, thanks to
|
||
Mattias Andersson.
|
||
|
||
2 April 2008 - version 1.9.5
|
||
- Fixed incorrect item stretching when the toolbar was
|
||
vertical and tboImageAboveCaption was set, thanks to
|
||
John for reporting this.
|
||
- Fixed incorrect item painting when no themes were
|
||
used, thanks to Denis for reporting this.
|
||
- Fixed incorrect TSpTBXToolPalette.Images handling, thanks
|
||
to Minoru Yoshida for reporting this.
|
||
- Fixed incorrect menu gutter painting when hints were showed,
|
||
thanks to Michele and Beta Xiong for reporting this.
|
||
- Fixed incorrect floating border painting when the default
|
||
size was changed thanks to Costas Stergiou and Serge
|
||
for reporting this.
|
||
- Fixed incorrect floating border painting on Vista,
|
||
the borders should not be transparent, thanks to
|
||
Costas Stergiou for reporting this.
|
||
|
||
3 February 2008 - version 1.9.4
|
||
- No changes.
|
||
|
||
19 January 2008 - version 1.9.3
|
||
- Completed the Brazilian Portuguese translation of the Customizer
|
||
demo, thanks to Mauricio Magnani.
|
||
- Added TSpTBXToolWindow component.
|
||
- Fixed incorrect gutter painting on the popup menus.
|
||
- Fixed item stretching problems
|
||
|
||
26 December 2007 - version 1.9.2
|
||
- New component added: TSpTBXToolWindow, a fully customizable
|
||
ToolWindow with unicode support.
|
||
- Added State parameter to the toolbar items OnDrawCaption event.
|
||
- Fixed AV on Delphi 2005, Margins and Paddings were introduced
|
||
on Delphi 2006, thanks to Stefan for reporting this.
|
||
- Minor bug fixes.
|
||
|
||
1 December 2007 - version 1.9.1
|
||
- Added Invalidate method to TSpTBXItem.
|
||
- Added OnClosePopup event to TSpTBXSubmenuItem.
|
||
- Fixed tboNoRotation use on vertical toolbar items, when
|
||
tboImageAboveCaption is not set the glyph should appear
|
||
aligned with the caption.
|
||
|
||
20 November 2007 - version 1.9
|
||
- New theme engine.
|
||
- Added SpTBXHintWindowClass global variable, it specifies which
|
||
THintWindow class is used to show the hints.
|
||
- Added TSpTBXToolPalette and TSpTBXColorPalette items.
|
||
- Added TSpTBXToolWindow component.
|
||
- Removed TSpTBXComboBoxItem, TSpTBXDropDownItem, TSpTBXStringList
|
||
and TSpTBXUndoList.
|
||
|
||
8 February 2007 - version 1.8.3
|
||
- No changes.
|
||
|
||
17 December 2006 - version 1.8.2
|
||
- Added Toolbar public property to TSpTBXStatusBar.
|
||
|
||
24 November 2006 - version 1.8.1
|
||
- Added properties to TSpTBXRightAlignSpacer: ImageIndex, Images,
|
||
OnAdjustFont, OnClick, OnDrawHint, OnDrawImage, OnDrawItem.
|
||
- Added unicode shortcut-text support for menu items, thanks
|
||
Steve for reporting this.
|
||
- Fixed incorrect TSpTBXTitleBar positioning when the
|
||
taskbar is moved around the screen, thanks to
|
||
Costas Stergiou for reporting this.
|
||
- Fixed incorrect TSpTBXStatusBar size grip painting when
|
||
Windows XP themes are disabled, thanks to Alexey Naumov
|
||
for reporting this.
|
||
|
||
27 August 2006 - version 1.8
|
||
- Fixed incorrect DropdownCombo item painting, thanks to
|
||
Fran<61>ois Rivierre for reporting this.
|
||
- Fixed incorrect TSpTBXTitleBar SystemMenu painting,
|
||
GetMenuStringW doesn't work correctly on Win2K/WinXP,
|
||
when a DBCS code page is active (e.g. Japanese), thanks
|
||
to Jordan Russell for reporting this.
|
||
http://news.jrsoftware.org/read/article.php?id=12268&group=jrsoftware.toolbar2000.thirdparty
|
||
- Fixed bug in TSpTBXLabelItem, clicking a TSpTBXLabelItem
|
||
on a popup menu causes the menu to close, thanks to
|
||
Piotr Janus for reporting this.
|
||
|
||
15 June 2006 - version 1.7
|
||
- Added vertical caption painting to toolbar items.
|
||
- Added CaptionGlow and CaptionGlowColor properties to
|
||
toolbar Items.
|
||
- Added Margins property to toolbar items.
|
||
- Fixed incorrect TSpTBXTitleBar resizing when the form is
|
||
maximized and the titlebar is activated and deactivated
|
||
multiple times, thanks to Costas Stergiou for reporting this.
|
||
|
||
4 May 2006 - version 1.6
|
||
- Fixed incorrect TSpTBXStatusBar behavior, the size grip
|
||
disappeared when the parent was a TSpTBXTitleBar, thanks to
|
||
Costas Stergiou for reporting this.
|
||
- Fixed incorrect TSpTBXStatusBar's size grip painting when the
|
||
Default theme was used.
|
||
- Fixed incorrect TSpTBXLabelItem painting when the label was used
|
||
in a submenu, thanks to Costas Stergiou for reporting this.
|
||
- Added OnSystemMenuPopup event to TSpTBXTitleBar.
|
||
|
||
12 April 2006 - version 1.5
|
||
- Fixed incorrect TSpTBXStatusBar behavior, it didn't resized
|
||
the form if the mouse click was on the non-client area of the
|
||
status bar, thanks to Frank de Groot for reporting this.
|
||
- Fixed incorrect mouse handling in TSpTBXTitlebar, thanks to
|
||
Marten Pape for reporting this.
|
||
- Fixed incorrect TSpTBXLabelItem alignment on menus, thanks to
|
||
Costas Stergiou for reporting this.
|
||
- Added ClickedItem parameter to TSpTBXSubmenuItem.OnClosePopup
|
||
event.
|
||
|
||
27 February 2006 - version 1.4
|
||
- Added SizeGrip property to TSpTBXStatusBar.
|
||
- Added FullScreenMaximize property to TSpTBXTitleBar.
|
||
|
||
10 February 2006 - version 1.3
|
||
- Fixed AV in TSpTBXTitleBar at designtime, thanks to
|
||
Alexey Naumov for reporting this.
|
||
- Fixed incorrect system popupmenu visibility in TSpTBXTitleBar.
|
||
- Added Active property to TSpTBXTitleBar.
|
||
- Added OnDrawBackground event to TSpTBXTitleBar.
|
||
- Added OnClosePopup event to TSpTBXSubmenuItem.
|
||
|
||
28 December 2005 - version 1.2
|
||
- Fixed incorrect items anchoring.
|
||
- Fixed range check errrors.
|
||
|
||
18 October 2005 - version 1.1
|
||
- Fixed incorrect TSpTBXStatusBar margins when the form is
|
||
maximazed.
|
||
- Fixed incorrect accel char handling in TSpTBXToolbar.
|
||
- Fixed incorrect TntAction support, the previous version of
|
||
TntActions didn't supported unicode enabled ActionLinks.
|
||
- Fixed incorrect tab stop chars handling in TSpTBXItem.
|
||
- Added MaxSize property to TSpTBXToolbar, determines
|
||
the maximum height the toolbar can have.
|
||
- Added TBX themes support to TSpTBXTitleBar's system menu.
|
||
- Added radio item painting support.
|
||
|
||
18 August 2005 - version 1.0
|
||
- Added DisplayOptions property to TSpTBXToolbar, determines
|
||
whether the item's image is to be displayed.
|
||
- Added Customizable property to TSpTBXToolbar, determines
|
||
whether the toolbar is customizable or not.
|
||
- Added TitleBarSize property to the Options of the
|
||
TSpTBXTitlebar.
|
||
|
||
10 June 2005 - version 0.9
|
||
- SpTBXLib may now alternatively, at your option, be used and/or
|
||
distributed under the terms of the SpTBXLib License.
|
||
Please see the updated LICENSE.TXT file for more information.
|
||
|
||
20 May 2005 - version 0.8
|
||
- Fixed incorrect caption centering in TSpTBXItem.
|
||
- Fixed incorrect TSpTBXItem hint when accessing TntApplication,
|
||
thanks to Erik Maly for reporting this.
|
||
- Changed the Options property of TSpTBXTitleBar to use a base class
|
||
for default buttons.
|
||
- Added ChevronVertical property to TSpTBXToolbar, it changes the
|
||
layout of the chevron popup to be vertical.
|
||
- Added Wrapping property to TSpTBXItem, it determines the wrapping
|
||
type of the item's caption.
|
||
- Added FixedSize property to TSpTBXTitleBar, it determines if
|
||
the TitleBar can be resized.
|
||
|
||
16 February 2005 - version 0.7
|
||
- Fixed TSpTBXThemeGroupItem theme sync bug, it now correctly selects
|
||
the current TBX theme.
|
||
- Fixed unicode support in W9x.
|
||
- Fixed TSpTBXTitleBar painting flicker.
|
||
- Fixed TSpTBXStatusBar right align margin.
|
||
- Added TBXStyleBackground property to TSpTBXTitleBar, when setted to
|
||
true it paints a TBX style background.
|
||
- Added AutoCheck property to TSpTBXItem.
|
||
|
||
23 December 2004 - version 0.6
|
||
- Fixed hint bug, ampersands were not removed in auto-generated hints.
|
||
- Fixed incorrect caption painting when the font is italic, this bug
|
||
is present in TBX items, TLabel, TBitBtn, TSpeedButton, TGroupBox,
|
||
TRadioGroup, and any other control that uses DrawText to draw the
|
||
caption. To reproduce this, drop a TBitBtn, change the caption to
|
||
'WWW' and the font to italic, the last W is cropped.
|
||
- Fixed incorrect caption painting when the Default theme is used,
|
||
the caption was not painted in a down state when the toolbarstyle
|
||
item was pushed, thanks Daniel Rikowski for reporting this.
|
||
- Changed the default value of DisplayMode to nbdmDefault.
|
||
- New component added, TSpTBXTitleBar: a fully customizable
|
||
TitleBar with Unicode text and TBX themes support.
|
||
- New component added, TSpTBXPopupMenu: a TTBXPopupMenu descendant
|
||
with an OnPopupMenuInit event to setup the items before the popup
|
||
is showed, it could be used for example to set the focus to an
|
||
EditItem.
|
||
- Added SpChangeThemeType utility function, this makes it easier to
|
||
switch the theme type of any given control and its children.
|
||
|
||
30 August 2004 - version 0.5
|
||
- Reworked the hint show event of the items.
|
||
|
||
21 July 2004 - version 0.4
|
||
- Fixed TTBControlItem.Control streaming bug on TSpTBXStatusBar.
|
||
- Fixed bad sync of the items unicode caption and hint properties
|
||
when an Action was assigned.
|
||
|
||
12 July 2004 - version 0.3.1
|
||
- Unchanged.
|
||
|
||
9 July 2004 - version 0.3
|
||
- Fixed incorrect TSpTBXItem caption painting when DisplayMode
|
||
was nbdmDefault, thanks to Cyril for reporting this.
|
||
- Added anchors support for TTBControlItem items, if the associated
|
||
Control is client aligned or has akRight in its Anchors property.
|
||
- The theme items in TSpTBXThemeGroupItem are now sorted.
|
||
- Added OnUpdate event to TSpTBXThemeGroupItem, this event is fired
|
||
every time the theme items list is recreated, use this event
|
||
to sort or change the items properties.
|
||
|
||
27 June 2004 - version 0.2
|
||
- Fixed Toolbar custom painting event.
|
||
- Fixed incorrect Shortcut painting in submenus.
|
||
- Fixed incorrect Shortcut hint painting.
|
||
- Removed thtBitmapSkin from TSpTBXThemeType.
|
||
- Published more properties for TSpTBXLabelItem.
|
||
- New Toolbar item added, TSpTBXSeparator.
|
||
- New component added, TSpTBXStatusBar: a fully customizable
|
||
StatusBar with Unicode text and TBX themes support.
|
||
|
||
22 June 2004 - version 0.1
|
||
- Initial release.
|
||
|
||
==============================================================================}
|
||
|
||
interface
|
||
|
||
{$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation
|
||
{$I TB2Ver.inc}
|
||
|
||
uses
|
||
Windows, Messages, Classes, SysUtils, Forms, Controls, Graphics, ImgList,
|
||
Menus, StdCtrls, ActnList,
|
||
{$IFNDEF UNICODE}
|
||
TntClasses, TntControls,
|
||
{$ENDIF}
|
||
TB2Item, TB2Dock, TB2Toolbar, TB2ToolWindow,
|
||
SpTBXSkins;
|
||
|
||
{$IFDEF UNICODE}
|
||
type
|
||
TTntStringList = TStringList;
|
||
{$ENDIF}
|
||
|
||
const
|
||
C_SpTBXRadioGroupIndex = 8888; // Default GroupItem of TSpTBXRadioGroupItem
|
||
CM_SPPOPUPCLOSE = CM_BASE + 1111; // Message sent to the PopupControl to update its state after the Popup is closed
|
||
rvSpTBXDisplayMode = 'DisplayMode'; // Constant used to save the Toolbar DisplayMode with the Customizer. Do not localize!
|
||
CPDefaultCols = 8; // ColorPalette constant
|
||
CPDefaultRows = 5; // ColorPalette constant
|
||
|
||
type
|
||
TSpTBXCustomItem = class;
|
||
TSpTBXToolbar = class;
|
||
TSpTBXStatusToolbar = class;
|
||
TSpTBXPopupMenu = class;
|
||
|
||
TSpTBXPaintStage = (
|
||
pstPrePaint, // Pre paint stage
|
||
pstPostPaint // Post paint stage
|
||
);
|
||
|
||
TSpTBXToolbarDisplayMode = (
|
||
tbdmSelectiveCaption, // The caption is displayed if the Item.DisplayMode = nbdmImageAndText
|
||
tbdmImageOnly, // Only the images are displayed
|
||
tbdmImageAboveCaption, // The images are displayed above the caption
|
||
tbdmTextOnly // Show the caption only
|
||
);
|
||
|
||
TSpTBXToolbarState = (
|
||
tstResizing, // The toolbar is being resized
|
||
tstRightAligning, // The toolbar items are being right aligned
|
||
tstAnchoring // The toolbar items are being anchored
|
||
);
|
||
|
||
TSpTBXToolbarStates = set of TSpTBXToolbarState;
|
||
|
||
TSpBorderIcon = (
|
||
briSystemMenu, // SystemMenu item on the title bar
|
||
briMinimize, // Minimize item on the title bar
|
||
briMaximize, // Maximize item on the title bar
|
||
briClose // Close item on the title bar
|
||
);
|
||
|
||
TSpBorderIcons = set of TSpBorderIcon;
|
||
|
||
TTextWrapping = (
|
||
twNone, // No wrapping
|
||
twEndEllipsis, // End ellipsis '...'
|
||
twPathEllipsis, // Path ellipsis '\..\..'
|
||
twWrap // Word wrap
|
||
);
|
||
|
||
TSpTBXSearchItemViewerType = (
|
||
sivtNormal, // Normal search
|
||
sivtInmediate, // Search for the inmediate ItemViewer
|
||
sivtInmediateSkipNonVisible// Search for the next inmediate ItemViewer, skipping non visible ones
|
||
);
|
||
|
||
TSpTBXGetImageIndexEvent = procedure(Sender: TObject;
|
||
var AImageList: TCustomImageList; var AItemIndex: Integer) of object;
|
||
|
||
TSpTBXDrawEvent = procedure(Sender: TObject; ACanvas: TCanvas;
|
||
ARect: TRect; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean) of object;
|
||
|
||
TSpTBXDrawImageEvent = procedure(Sender: TObject; ACanvas: TCanvas;
|
||
State: TSpTBXSkinStatesType; const PaintStage: TSpTBXPaintStage;
|
||
var AImageList: TCustomImageList; var AImageIndex: Integer;
|
||
var ARect: TRect; var PaintDefault: Boolean) of object;
|
||
|
||
TSpTBXDrawItemEvent = procedure(Sender: TObject; ACanvas: TCanvas;
|
||
ARect: TRect; ItemInfo: TSpTBXMenuItemInfo; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean) of object;
|
||
|
||
TSpTBXDrawPosEvent = procedure(Sender: TObject; ACanvas: TCanvas;
|
||
X, Y: Integer; var PaintDefault: Boolean) of object;
|
||
|
||
TSpTBXDrawTextEvent = procedure(Sender: TObject; ACanvas: TCanvas;
|
||
ClientAreaRect: TRect; State: TSpTBXSkinStatesType; var ACaption: WideString;
|
||
var CaptionRect: TRect; var CaptionFormat: Cardinal; IsTextRotated: Boolean;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean) of object;
|
||
|
||
TSpTBXDrawHintEvent = procedure(Sender: TObject; AHintBitmap: TBitmap;
|
||
var AHint: WideString; var PaintDefault: Boolean) of object;
|
||
|
||
TSpTBXItemNotificationEvent = procedure(Sender: TObject;
|
||
Ancestor: TTBCustomItem; Relayed: Boolean; Action: TTBItemChangedAction;
|
||
Index: Integer; Item: TTBCustomItem) of object;
|
||
|
||
TSpTBXRadioGroupFillStringsEvent = procedure(Sender: TObject;
|
||
Strings: TTntStringList) of object;
|
||
|
||
TSpTBXPopupEvent = procedure(Sender: TObject; PopupView: TTBView) of object;
|
||
|
||
{ TSpTBXFontSettings }
|
||
|
||
TSpTBXFontSize = 25..1000;
|
||
|
||
TSpTBXFontSettings = class(TPersistent)
|
||
private
|
||
FColor: TColor;
|
||
FName: TFontName;
|
||
FSize: TSpTBXFontSize;
|
||
FStyle: TFontStyles;
|
||
FOnChange: TNotifyEvent;
|
||
procedure SetColor(Value: TColor);
|
||
procedure SetName(const Value: TFontName);
|
||
procedure SetSize(Value: TSpTBXFontSize);
|
||
procedure SetStyle(const Value: TFontStyles);
|
||
protected
|
||
procedure Modified;
|
||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||
public
|
||
constructor Create;
|
||
procedure Apply(AFont: TFont);
|
||
procedure Assign(Src: TPersistent); override;
|
||
published
|
||
property Color: TColor read FColor write SetColor default clNone;
|
||
property Name: TFontName read FName write SetName; // default ''
|
||
property Size: TSpTBXFontSize read FSize write SetSize default 100; // Size Percent
|
||
property Style: TFontStyles read FStyle write SetStyle default [];
|
||
end;
|
||
|
||
{ TSpTBXCustomDragObject }
|
||
|
||
TSpTBXCustomDragObject = class(TDragObjectEx)
|
||
private
|
||
FDragCursorAccept: TCursor;
|
||
FDragCursorCancel: TCursor;
|
||
FSourceControl: TControl;
|
||
FSourceItem: TTBCustomItem;
|
||
protected
|
||
function GetDragCursor(Accepted: Boolean; X: Integer; Y: Integer): TCursor; override;
|
||
procedure Finished(Target: TObject; X, Y: Integer; Accepted: Boolean); override;
|
||
public
|
||
constructor Create(ASourceControl: TControl; AItem: TTBCustomItem); virtual;
|
||
property DragCursorAccept: TCursor read FDragCursorAccept write FDragCursorAccept;
|
||
property DragCursorCancel: TCursor read FDragCursorCancel write FDragCursorCancel;
|
||
property SouceItem: TTBCustomItem read FSourceItem;
|
||
property SourceControl: TControl read FSourceControl;
|
||
end;
|
||
|
||
{ TSpTBXItemDragObject }
|
||
|
||
TSpTBXItemDragObject = class(TSpTBXCustomDragObject);
|
||
|
||
{ TSpTBXCustomItemActionLink }
|
||
|
||
{$IFNDEF UNICODE}
|
||
TSpTBXCustomItemActionLink = class(TTBCustomItemActionLink)
|
||
protected
|
||
FUnicodeClient: TSpTBXCustomItem;
|
||
procedure AssignClient(AClient: TObject); override;
|
||
function IsCaptionLinked: Boolean; override;
|
||
function IsHintLinked: Boolean; override;
|
||
procedure SetCaption(const Value: string); override;
|
||
procedure SetHint(const Value: string); override;
|
||
end;
|
||
{$ELSE}
|
||
TSpTBXCustomItemActionLink = class(TTBCustomItemActionLink);
|
||
{$ENDIF}
|
||
|
||
{ TSpTBXCustomControl }
|
||
|
||
{$IFNDEF UNICODE}
|
||
TSpTBXCustomControl = class(TCustomControl)
|
||
private
|
||
function IsCaptionStored: Boolean;
|
||
function IsHintStored: Boolean;
|
||
function GetCaption: TWideCaption;
|
||
function GetHint: WideString;
|
||
procedure SetCaption(const Value: TWideCaption);
|
||
procedure SetHint(const Value: WideString);
|
||
protected
|
||
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
|
||
procedure CreateWindowHandle(const Params: TCreateParams); override;
|
||
procedure DefineProperties(Filer: TFiler); override;
|
||
// Don't let the streaming system store the WideStrings, use DefineProperties instead
|
||
property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; // Hides the inherited Caption
|
||
property Hint: WideString read GetHint write SetHint stored IsHintStored; // Hides the inherited Hint
|
||
end;
|
||
{$ELSE}
|
||
TSpTBXCustomControl = class(TCustomControl);
|
||
{$ENDIF}
|
||
|
||
{ TSpTBXItem }
|
||
|
||
TSpTBXCustomItem = class(TTBCustomItem)
|
||
private
|
||
{$IFNDEF UNICODE}
|
||
FCaption: WideString;
|
||
FHint: WideString;
|
||
{$ENDIF}
|
||
FCaptionGlow: TSpGlowDirection;
|
||
FCaptionGlowColor: TColor;
|
||
FAlignment: TAlignment;
|
||
FAnchored: Boolean;
|
||
FControl: TControl;
|
||
FCustomWidth: Integer;
|
||
FCustomHeight: Integer;
|
||
FFontSettings: TSpTBXFontSettings;
|
||
FMargins: Integer;
|
||
FMinHeight: Integer;
|
||
FMinWidth: Integer;
|
||
FStretch: Boolean;
|
||
FToolbarStylePopup: Boolean;
|
||
FToolBoxPopup: Boolean;
|
||
FWrapping: TTextWrapping;
|
||
FOnClosePopup: TNotifyEvent;
|
||
FOnInitPopup: TSpTBXPopupEvent;
|
||
FOnDrawCaption: TSpTBXDrawTextEvent;
|
||
FOnDrawHint: TSpTBXDrawHintEvent;
|
||
FOnDrawItem: TSpTBXDrawItemEvent;
|
||
FOnDrawImage: TSpTBXDrawImageEvent;
|
||
{$IFNDEF UNICODE}
|
||
function IsCaptionStored: Boolean;
|
||
function IsHintStored: Boolean;
|
||
procedure SetCaption(const Value: WideString);
|
||
procedure SetHint(const Value: WideString);
|
||
{$ENDIF}
|
||
procedure FontSettingsChanged(Sender: TObject);
|
||
procedure SetAlignment(const Value: TAlignment);
|
||
procedure SetAnchored(const Value: Boolean);
|
||
procedure SetCaptionGlow(const Value: TSpGlowDirection);
|
||
procedure SetCaptionGlowColor(const Value: TColor);
|
||
procedure SetControl(const Value: TControl);
|
||
procedure SetCustomWidth(Value: Integer);
|
||
procedure SetCustomHeight(Value: Integer);
|
||
procedure SetFontSettings(const Value: TSpTBXFontSettings);
|
||
procedure SetMargins(Value: Integer);
|
||
procedure SetMinHeight(const Value: Integer);
|
||
procedure SetMinWidth(const Value: Integer);
|
||
procedure SetStretch(const Value: Boolean);
|
||
procedure SetToolBoxPopup(const Value: Boolean);
|
||
procedure SetWrapping(const Value: TTextWrapping);
|
||
protected
|
||
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
|
||
function DialogChar(CharCode: Word): Boolean; virtual;
|
||
procedure DefineProperties(Filer: TFiler); override;
|
||
procedure DoDrawAdjustFont(AFont: TFont; State: TSpTBXSkinStatesType); virtual;
|
||
procedure DoDrawHint(AHintBitmap: TBitmap; var AHint: Widestring; var PaintDefault: Boolean); virtual;
|
||
procedure DoDrawButton(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual;
|
||
procedure DoDrawCaption(ACanvas: TCanvas; ClientAreaRect: TRect; State: TSpTBXSkinStatesType;
|
||
var ACaption: WideString; var CaptionRect: TRect; var CaptionFormat: Cardinal;
|
||
IsTextRotated: Boolean; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual;
|
||
procedure DoDrawImage(ACanvas: TCanvas; State: TSpTBXSkinStatesType;
|
||
const PaintStage: TSpTBXPaintStage; var AImageList: TCustomImageList;
|
||
var AImageIndex: Integer; var ARect: TRect; var PaintDefault: Boolean); virtual;
|
||
procedure DoPopupShowingChanged(APopupWindow: TTBPopupWindow; IsVisible: Boolean); virtual;
|
||
function GetActionLinkClass: TTBCustomItemActionLinkClass; override;
|
||
function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
|
||
function GetPopupWindowClass: TTBPopupWindowClass; override;
|
||
procedure ToggleControl; virtual;
|
||
procedure UpdateProps; virtual;
|
||
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||
|
||
property Alignment: TAlignment read FAlignment write SetAlignment default taCenter;
|
||
property Anchored: Boolean read FAnchored write SetAnchored default False;
|
||
property CaptionGlow: TSpGlowDirection read FCaptionGlow write SetCaptionGlow default gldNone;
|
||
property CaptionGlowColor: TColor read FCaptionGlowColor write SetCaptionGlowColor default clYellow;
|
||
property Control: TControl read FControl write SetControl;
|
||
property CustomWidth: Integer read FCustomWidth write SetCustomWidth default -1;
|
||
property CustomHeight: Integer read FCustomHeight write SetCustomHeight default -1;
|
||
property FontSettings: TSpTBXFontSettings read FFontSettings write SetFontSettings;
|
||
property Margins: Integer read FMargins write SetMargins default 0;
|
||
property MinHeight: Integer read FMinHeight write SetMinHeight default 0;
|
||
property MinWidth: Integer read FMinWidth write SetMinWidth default 0;
|
||
property ToolbarStylePopup: Boolean read FToolbarStylePopup write FToolbarStylePopup default False; // Used on submenus
|
||
property ToolBoxPopup: Boolean read FToolBoxPopup write SetToolBoxPopup default False; // Used on submenus
|
||
property Stretch: Boolean read FStretch write SetStretch default True; // Hidden, all items are stretched by default
|
||
property OnClosePopup: TNotifyEvent read FOnClosePopup write FOnClosePopup;
|
||
property OnInitPopup: TSpTBXPopupEvent read FOnInitPopup write FOnInitPopup;
|
||
property OnDrawCaption: TSpTBXDrawTextEvent read FOnDrawCaption write FOnDrawCaption;
|
||
property OnDrawHint: TSpTBXDrawHintEvent read FOnDrawHint write FOnDrawHint;
|
||
property OnDrawImage: TSpTBXDrawImageEvent read FOnDrawImage write FOnDrawImage;
|
||
property OnDrawItem: TSpTBXDrawItemEvent read FOnDrawItem write FOnDrawItem;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
procedure Click; override;
|
||
function GetShortCutText: WideString; // Reintroduce to support unicode shortcut text
|
||
procedure InitiateAction; override;
|
||
procedure Invalidate;
|
||
published
|
||
{$IFNDEF UNICODE}
|
||
// Don't let the streaming system store the WideStrings, use DefineProperties instead
|
||
property Caption: WideString read FCaption write SetCaption stored IsCaptionStored; // Hides the inherited Caption
|
||
property Hint: WideString read FHint write SetHint stored IsHintStored; // Hides the inherited Hint
|
||
{$ELSE}
|
||
property Caption;
|
||
property Hint;
|
||
{$ENDIF}
|
||
property Wrapping: TTextWrapping read FWrapping write SetWrapping default twWrap;
|
||
end;
|
||
|
||
TSpTBXItemViewer = class(TTBItemViewer)
|
||
private
|
||
function GetItem: TSpTBXCustomItem;
|
||
procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW;
|
||
procedure InternalCalcSize(const Canvas: TCanvas; CalcStretch: Boolean; var AWidth, AHeight: Integer);
|
||
protected
|
||
FAnchorSize: TPoint;
|
||
FAnchorDelta: Integer;
|
||
|
||
function IsOnToolBoxPopup: Boolean;
|
||
|
||
// Custom Painting methods
|
||
procedure DoDrawAdjustFont(AFont: TFont; State: TSpTBXSkinStatesType); virtual;
|
||
procedure DoDrawButton(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual;
|
||
procedure DoDrawCaption(ACanvas: TCanvas; ClientAreaRect: TRect;
|
||
State: TSpTBXSkinStatesType; var ACaption: WideString; var CaptionRect: TRect;
|
||
var CaptionFormat: Cardinal; IsTextRotated: Boolean; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean); virtual;
|
||
procedure DoDrawImage(ACanvas: TCanvas; State: TSpTBXSkinStatesType;
|
||
const PaintStage: TSpTBXPaintStage; var AImageList: TCustomImageList;
|
||
var AImageIndex: Integer; var ARect: TRect; var PaintDefault: Boolean); virtual;
|
||
procedure DoDrawHint(AHintBitmap: TBitmap; CursorPos: TPoint; var CursorRect: TRect; var AHint: Widestring; var PaintDefault: Boolean); virtual;
|
||
|
||
// Painting methods
|
||
function CaptionShown: Boolean; override;
|
||
function GetImageShown: Boolean; virtual;
|
||
function GetImageSize: TSize; virtual;
|
||
function GetRightImageSize: TSize; virtual;
|
||
function GetTextColor(State: TSpTBXSkinStatesType): TColor; virtual;
|
||
procedure DrawItemImage(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo; ImgIndex: Integer); virtual;
|
||
procedure DrawItemRightImage(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo); virtual;
|
||
procedure CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); override;
|
||
procedure GetTextInfo(ACanvas: TCanvas; State: TSpTBXSkinStatesType; out TextInfo: TSpTBXTextInfo);
|
||
procedure Paint(const Canvas: TCanvas; const ClientAreaRect: TRect; IsSelected, IsPushed, UseDisabledShadow: Boolean); override;
|
||
|
||
// Hints
|
||
procedure Entering; override;
|
||
procedure InternalMouseMove(Shift: TShiftState; X, Y: Integer); virtual;
|
||
public
|
||
function GetCaptionText: WideString; reintroduce; virtual; // Hides the inherited TB2K GetCaptionText function
|
||
function GetHintText: Widestring; reintroduce; virtual; // Hides the inherited TB2K GetHintText function
|
||
function IsToolbarStyle: Boolean; // Hides the inherited TB2K IsToolbarStyle function
|
||
property Item: TSpTBXCustomItem read GetItem; // Hides the inherited TB2K Item property
|
||
end;
|
||
|
||
TSpTBXItem = class(TSpTBXCustomItem)
|
||
published
|
||
property Action;
|
||
property AutoCheck;
|
||
property Checked;
|
||
property DisplayMode;
|
||
property Enabled;
|
||
property GroupIndex;
|
||
property HelpContext;
|
||
property ImageIndex;
|
||
property Images;
|
||
property InheritOptions;
|
||
property MaskOptions;
|
||
property Options;
|
||
property RadioItem;
|
||
property ShortCut;
|
||
property Visible;
|
||
// property OnDrawImage; use custom OnDrawImage
|
||
property OnClick;
|
||
property OnSelect;
|
||
// TSpTBXCustomItem properties
|
||
property Alignment;
|
||
property Anchored;
|
||
property CaptionGlow;
|
||
property CaptionGlowColor;
|
||
property Control;
|
||
property CustomWidth;
|
||
property CustomHeight;
|
||
property FontSettings;
|
||
property Margins;
|
||
property MinHeight;
|
||
property MinWidth;
|
||
property OnDrawCaption;
|
||
property OnDrawHint;
|
||
property OnDrawImage;
|
||
property OnDrawItem;
|
||
end;
|
||
|
||
{ TSpTBXRootItem }
|
||
|
||
TSpTBXRootItem = class(TTBRootItem)
|
||
private
|
||
FToolBoxPopup: Boolean;
|
||
FOnInitPopup: TSpTBXPopupEvent;
|
||
FOnClosePopup: TNotifyEvent;
|
||
procedure SetToolBoxPopup(const Value: Boolean);
|
||
protected
|
||
procedure DoPopupShowingChanged(APopupWindow: TTBPopupWindow; IsVisible: Boolean); virtual;
|
||
function GetPopupWindowClass: TTBPopupWindowClass; override;
|
||
property ToolBoxPopup: Boolean read FToolBoxPopup write SetToolBoxPopup default False;
|
||
public
|
||
property OnInitPopup: TSpTBXPopupEvent read FOnInitPopup write FOnInitPopup;
|
||
property OnClosePopup: TNotifyEvent read FOnClosePopup write FOnClosePopup;
|
||
end;
|
||
|
||
{ TSpTBXSubmenuItem }
|
||
|
||
TSpTBXSubmenuItem = class(TSpTBXItem)
|
||
private
|
||
FHideEmptyPopup: Boolean;
|
||
function GetDropdownCombo: Boolean;
|
||
procedure SetDropdownCombo(Value: Boolean);
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
published
|
||
property DropdownCombo: Boolean read GetDropdownCombo write SetDropdownCombo default False;
|
||
property HideEmptyPopup: Boolean read FHideEmptyPopup write FHideEmptyPopup default False;
|
||
property LinkSubitems;
|
||
property SubMenuImages;
|
||
property ToolbarStylePopup;
|
||
property ToolBoxPopup;
|
||
property OnPopup;
|
||
property OnClosePopup;
|
||
property OnInitPopup;
|
||
end;
|
||
|
||
{ TSpTBXColorItem }
|
||
|
||
TSpTBXColorItem = class(TSpTBXCustomItem)
|
||
private
|
||
FColor: TColor;
|
||
procedure SetColor(Value: TColor);
|
||
protected
|
||
function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
published
|
||
property Action;
|
||
property AutoCheck;
|
||
property Checked;
|
||
property DisplayMode;
|
||
property Enabled;
|
||
property GroupIndex;
|
||
property HelpContext;
|
||
property InheritOptions;
|
||
property MaskOptions;
|
||
property Options;
|
||
property ShortCut;
|
||
property Visible;
|
||
property OnClick;
|
||
property OnSelect;
|
||
// TSpTBXCustomItem properties
|
||
property Alignment;
|
||
property Anchored;
|
||
property CaptionGlow;
|
||
property CaptionGlowColor;
|
||
property Control;
|
||
property CustomWidth;
|
||
property CustomHeight;
|
||
property FontSettings;
|
||
property Margins;
|
||
property MinHeight;
|
||
property MinWidth;
|
||
property OnDrawCaption;
|
||
property OnDrawHint;
|
||
property OnDrawImage;
|
||
property OnDrawItem;
|
||
// TSpTBXColorItem properties
|
||
property Color: TColor read FColor write SetColor default clWhite;
|
||
end;
|
||
|
||
TSpTBXColorItemViewer = class(TSpTBXItemViewer)
|
||
protected
|
||
procedure DoDrawImage(ACanvas: TCanvas; State: TSpTBXSkinStatesType;
|
||
const PaintStage: TSpTBXPaintStage; var AImageList: TCustomImageList;
|
||
var AImageIndex: Integer; var ARect: TRect; var PaintDefault: Boolean); override;
|
||
function GetImageShown: Boolean; override;
|
||
function GetImageSize: TSize; override;
|
||
end;
|
||
|
||
{ TSpTBXLabelItem }
|
||
|
||
TSpTBXCustomLabelItem = class(TSpTBXCustomItem)
|
||
protected
|
||
function DialogChar(CharCode: Word): Boolean; override;
|
||
procedure DoDrawButton(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); override;
|
||
function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
|
||
procedure ToggleControl; override;
|
||
procedure UpdateProps; override;
|
||
property Alignment default taLeftJustify;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
end;
|
||
|
||
TSpTBXLabelItemViewer = class(TSpTBXItemViewer)
|
||
protected
|
||
procedure CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); override;
|
||
function DoExecute: Boolean; override;
|
||
end;
|
||
|
||
TSpTBXLabelItem = class(TSpTBXCustomLabelItem)
|
||
published
|
||
property Enabled;
|
||
property ImageIndex;
|
||
property Images;
|
||
property InheritOptions;
|
||
property MaskOptions;
|
||
property Options;
|
||
property Visible;
|
||
property OnClick;
|
||
// TSpTBXCustomItem properties
|
||
property Alignment;
|
||
property Anchored;
|
||
property CaptionGlow;
|
||
property CaptionGlowColor;
|
||
property Control;
|
||
property CustomWidth;
|
||
property CustomHeight;
|
||
property FontSettings;
|
||
property Margins;
|
||
property MinHeight;
|
||
property MinWidth;
|
||
property OnDrawCaption;
|
||
property OnDrawHint;
|
||
property OnDrawImage;
|
||
property OnDrawItem;
|
||
end;
|
||
|
||
{ TSpTBXSeparatorItem }
|
||
|
||
TSpTBXSeparatorItem = class(TTBSeparatorItem)
|
||
protected
|
||
function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
|
||
end;
|
||
|
||
TSpTBXSeparatorItemViewer = class(TTBSeparatorItemViewer)
|
||
protected
|
||
procedure CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); override;
|
||
function IsStatusBarSeparator: Boolean;
|
||
procedure Paint(const Canvas: TCanvas; const ClientAreaRect: TRect; IsSelected, IsPushed, UseDisabledShadow: Boolean); override;
|
||
end;
|
||
|
||
{ TSpTBXRightAlignSpacerItem }
|
||
|
||
TSpTBXRightAlignSpacerItem = class(TSpTBXCustomLabelItem)
|
||
published
|
||
property ImageIndex;
|
||
property Images;
|
||
property MaskOptions;
|
||
property Options;
|
||
property OnClick;
|
||
// TSpTBXCustomItem properties
|
||
property Alignment;
|
||
property CaptionGlow;
|
||
property CaptionGlowColor;
|
||
property CustomWidth;
|
||
property CustomHeight;
|
||
property FontSettings;
|
||
property OnDrawCaption;
|
||
property OnDrawHint;
|
||
property OnDrawImage;
|
||
property OnDrawItem;
|
||
end;
|
||
|
||
{ TSpTBXRadioGroupItem }
|
||
|
||
TSpTBXRadioGroupItem = class(TTBGroupItem)
|
||
private
|
||
FDefaultIndex: Integer;
|
||
FLastClickedIndex: Integer;
|
||
FOnClick: TNotifyEvent;
|
||
FOnFillStrings: TSpTBXRadioGroupFillStringsEvent;
|
||
FOnUpdate: TNotifyEvent;
|
||
protected
|
||
FStrings: TTntStringList;
|
||
procedure Loaded; override;
|
||
procedure ItemClickEvent(Sender: TObject); virtual;
|
||
procedure DoClick(AItem: TSpTBXItem); virtual;
|
||
procedure DoFillStrings; virtual;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
procedure Recreate;
|
||
property DefaultIndex: Integer read FDefaultIndex write FDefaultIndex;
|
||
property LastClickedIndex: Integer read FLastClickedIndex;
|
||
published
|
||
property OnClick: TNotifyEvent read FOnClick write FOnClick;
|
||
property OnFillStrings: TSpTBXRadioGroupFillStringsEvent read FOnFillStrings write FOnFillStrings;
|
||
property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate;
|
||
end;
|
||
|
||
{ TSpTBXSkinGroupItem }
|
||
|
||
TSpTBXSkinGroupItem = class(TSpTBXRadioGroupItem)
|
||
private
|
||
FOnSkinChange: TNotifyEvent;
|
||
procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE;
|
||
protected
|
||
procedure DoClick(AItem: TSpTBXItem); override;
|
||
procedure DoSkinChange; virtual;
|
||
procedure DoFillStrings; override;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
published
|
||
property OnSkinChange: TNotifyEvent read FOnSkinChange write FOnSkinChange;
|
||
end;
|
||
|
||
{ TSpTBXSystemMenuItem }
|
||
|
||
TSpTBXSystemMenuItem = class(TSpTBXCustomItem)
|
||
private
|
||
FMDISystemMenu: Boolean;
|
||
FShowSize: Boolean;
|
||
procedure CommandClick(Sender: TObject);
|
||
protected
|
||
function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
|
||
function GetSystemMenuParentForm: TCustomForm;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
procedure Click; override;
|
||
published
|
||
property MDISystemMenu: Boolean read FMDISystemMenu write FMDISystemMenu default False;
|
||
property ShowSize: Boolean read FShowSize write FShowSize default True;
|
||
end;
|
||
|
||
TSpTBXSystemMenuItemViewer = class(TSpTBXItemViewer)
|
||
protected
|
||
procedure CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); override;
|
||
procedure Paint(const Canvas: TCanvas; const ClientAreaRect: TRect; IsSelected, IsPushed, UseDisabledShadow: Boolean); override;
|
||
end;
|
||
|
||
{ TSpTBXToolPalette }
|
||
|
||
TSpTBXRowColCount = 1..100;
|
||
|
||
TSpTBXTPGetCellHint = procedure(Sender: TObject; ACol, ARow: Integer; var AHint: WideString) of object;
|
||
|
||
TSpTBXTPDrawCellImage = procedure(Sender: TObject; ACanvas: TCanvas;
|
||
ARect: TRect; ACol, ARow: Integer; Selected, HotTrack, Enabled: Boolean) of object;
|
||
|
||
TSpTBXTPCellClick = procedure(Sender: TObject; ACol, ARow: Integer; var Allow: Boolean) of object;
|
||
|
||
TSpTBXCPGetColorInfo = procedure(Sender: TObject; ACol, ARow: Integer; var Color: TColor; var Name: WideString) of object;
|
||
|
||
TSpTBXCustomToolPalette = class(TSpTBXCustomItem)
|
||
private
|
||
FCustomImages: Boolean;
|
||
FColCount: TSpTBXRowColCount;
|
||
FRowCount: TSpTBXRowColCount;
|
||
FSelectedCell: TPoint;
|
||
FOnChange: TNotifyEvent;
|
||
FOnCellClick: TSpTBXTPCellClick;
|
||
FOnDrawCellImage: TSpTBXTPDrawCellImage;
|
||
FOnGetCellHint: TSpTBXTPGetCellHint;
|
||
procedure SetSelectedCell(Value: TPoint);
|
||
protected
|
||
function DoCellClick(ACol, ARow: Integer): Boolean; virtual;
|
||
procedure DoChange; virtual;
|
||
procedure DoDrawCellImage(ACanvas: TCanvas; const ARect: TRect; ACol, ARow: Integer; ItemInfo: TSpTBXMenuItemInfo); virtual;
|
||
procedure DoGetCellHint(ACol, ARow: Integer; var AHint: WideString); virtual;
|
||
function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
|
||
procedure HandleClickCell(ACol, ARow: Integer); virtual;
|
||
procedure SetColCount(Value: TSpTBXRowColCount); virtual;
|
||
procedure SetRowCount(Value: TSpTBXRowColCount); virtual;
|
||
property CustomImages: Boolean read FCustomImages write FCustomImages;
|
||
property ColCount: TSpTBXRowColCount read FColCount write SetColCount default 1;
|
||
property RowCount: TSpTBXRowColCount read FRowCount write SetRowCount default 1;
|
||
property SelectedCell: TPoint read FSelectedCell write SetSelectedCell;
|
||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||
property OnCellClick: TSpTBXTPCellClick read FOnCellClick write FOnCellClick;
|
||
property OnDrawCellImage: TSpTBXTPDrawCellImage read FOnDrawCellImage write FOnDrawCellImage;
|
||
property OnGetCellHint: TSpTBXTPGetCellHint read FOnGetCellHint write FOnGetCellHint;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
end;
|
||
|
||
TSpTBXToolPalette = class(TSpTBXCustomToolPalette)
|
||
public
|
||
property SelectedCell;
|
||
published
|
||
property ColCount;
|
||
property HelpContext;
|
||
property Images;
|
||
property Options;
|
||
property RowCount;
|
||
property Visible;
|
||
property OnChange;
|
||
property OnCellClick;
|
||
property OnDrawCellImage;
|
||
property OnGetCellHint;
|
||
end;
|
||
|
||
TSpTBXToolViewer = class(TSpTBXItemViewer)
|
||
private
|
||
FCellHeight: Integer;
|
||
FCellWidth: Integer;
|
||
FColCount: Integer;
|
||
FRowCount: Integer;
|
||
FHotCell: TPoint;
|
||
function GetItem: TSpTBXCustomToolPalette;
|
||
protected
|
||
FIndent: Integer;
|
||
FMouseIsDown: Boolean;
|
||
procedure CalcCellSize(ACanvas: TCanvas; var AWidth, AHeight: Integer); virtual;
|
||
procedure CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); override;
|
||
function GetImageIndex(Col, Row: Integer): Integer;
|
||
function GetImageSize: TSize; override;
|
||
function GetImageShown: Boolean; override;
|
||
function GetCellAt(X, Y: Integer; out Col, Row: Integer): Boolean;
|
||
function GetCellRect(ClientAreaRect: TRect; Col, Row: Integer): TRect; virtual;
|
||
function GetCellHint(Col, Row: Integer): WideString;
|
||
procedure DoDrawHint(AHintBitmap: TBitmap; CursorPos: TPoint; var CursorRect: TRect; var AHint: Widestring; var PaintDefault: Boolean); override;
|
||
procedure DrawCellImage(ACanvas: TCanvas; const ARect: TRect; Col, Row: Integer; ItemInfo: TSpTBXMenuItemInfo); virtual;
|
||
procedure Entering; override;
|
||
procedure InvalidateCell(ACol, ARow: Integer);
|
||
function IsCellVisible(Cell: TPoint): Boolean; virtual;
|
||
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
||
procedure MouseDown(Shift: TShiftState; X, Y: Integer;var MouseDownOnMenu: Boolean); override;
|
||
procedure MouseMove(X, Y: Integer); override;
|
||
procedure MouseUp(X, Y: Integer; MouseWasDownOnMenu: Boolean); override;
|
||
procedure Paint(const Canvas: TCanvas; const ClientAreaRect: TRect; IsSelected, IsPushed, UseDisabledShadow: Boolean); override;
|
||
public
|
||
constructor Create(AView: TTBView; AItem: TTBCustomItem; AGroupLevel: Integer); override;
|
||
property Item: TSpTBXCustomToolPalette read GetItem; // Hides the inherited TB2K Item property
|
||
end;
|
||
|
||
{ TSpTBXColorPalette }
|
||
|
||
TSpTBXColorPalette = class(TSpTBXCustomToolPalette)
|
||
private
|
||
FColor: TColor;
|
||
FCustomColors: Boolean;
|
||
FOnGetColor: TSpTBXCPGetColorInfo;
|
||
procedure SetColor(Value: TColor);
|
||
procedure SetCustomColors(const Value: Boolean);
|
||
protected
|
||
procedure DoChange; override;
|
||
procedure DoGetCellHint(ACol, ARow: Integer; var AHint: WideString); override;
|
||
procedure DoDrawCellImage(ACanvas: TCanvas; const ARect: TRect; ACol, ARow: Integer; ItemInfo: TSpTBXMenuItemInfo); override;
|
||
function GetCellColor(ACol, ARow: Integer): TColor;
|
||
procedure GetCellInfo(ACol, ARow: Integer; out AColor: TColor; out AName: WideString);
|
||
procedure SetColCount(Value: TSpTBXRowColCount); override;
|
||
procedure SetRowCount(Value: TSpTBXRowColCount); override;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
function FindCell(AColor: TColor): TPoint;
|
||
published
|
||
property CustomColors: Boolean read FCustomColors write SetCustomColors default False; // Must be published before ColCount
|
||
property ColCount default CPDefaultCols;
|
||
property Color: TColor read FColor write SetColor default clNone;
|
||
property HelpContext;
|
||
property InheritOptions;
|
||
property MaskOptions;
|
||
property Options default [tboShowHint];
|
||
property RowCount default CPDefaultRows;
|
||
property Visible;
|
||
property OnChange;
|
||
property OnCellClick;
|
||
property OnGetCellHint;
|
||
property OnGetColor: TSpTBXCPGetColorInfo read FOnGetColor write FOnGetColor;
|
||
end;
|
||
|
||
{ TSpTBXItemCacheList }
|
||
|
||
TSpTBXItemCache = class(TCollectionItem)
|
||
private
|
||
FDock: TTBDock;
|
||
FName: TComponentName;
|
||
FItem: TTBCustomItem;
|
||
FWidth, FHeight: Integer;
|
||
FParentWidth, FParentHeight: Integer;
|
||
function GetName: TComponentName;
|
||
public
|
||
procedure Assign(Source: TPersistent); override;
|
||
property Item: TTBCustomItem read FItem write FItem;
|
||
published
|
||
property Dock: TTBDock read FDock write FDock;
|
||
property Name: TComponentName read GetName write FName;
|
||
property Width: Integer read FWidth write FWidth default 0;
|
||
property Height: Integer read FHeight write FHeight default 0;
|
||
property ParentWidth: Integer read FParentWidth write FParentWidth default 0;
|
||
property ParentHeight: Integer read FParentHeight write FParentHeight default 0;
|
||
end;
|
||
|
||
TSpTBXItemCacheCollection = class(TCollection)
|
||
private
|
||
function GetItem(Index: Integer): TSpTBXItemCache;
|
||
procedure SetItem(Index: Integer; const Value: TSpTBXItemCache);
|
||
public
|
||
function Add(AItem: TTBCustomItem): Integer; virtual;
|
||
function IndexOf(AItem: TTBCustomItem): Integer;
|
||
property Items[Index: Integer]: TSpTBXItemCache read GetItem write SetItem; default;
|
||
end;
|
||
|
||
{ TSpTBXDock }
|
||
|
||
TSpTBXDock = class(TTBDock)
|
||
private
|
||
FMoving: Boolean;
|
||
FResizing: Boolean;
|
||
FPrevWidth: Integer;
|
||
FPrevHeight: Integer;
|
||
FOnDrawBackground: TSpTBXDrawEvent;
|
||
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
|
||
procedure WMMove(var Message: TWMMove); message WM_MOVE;
|
||
procedure WMSize(var Message: TWMSize); message WM_SIZE;
|
||
procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE;
|
||
protected
|
||
function CanResize(var NewWidth: Integer; var NewHeight: Integer): Boolean; override;
|
||
procedure DrawBackground(DC: HDC; const DrawRect: TRect); override;
|
||
procedure DoDrawBackground(ACanvas: TCanvas; ARect: TRect; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual;
|
||
procedure Resize; override;
|
||
function UsingBackground: Boolean; override;
|
||
function UsingBitmap: Boolean;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
property PrevWidth: Integer read FPrevWidth;
|
||
property PrevHeight: Integer read FPrevHeight;
|
||
published
|
||
property Color default clNone;
|
||
property OnCanResize;
|
||
property OnDrawBackground: TSpTBXDrawEvent read FOnDrawBackground write FOnDrawBackground;
|
||
end;
|
||
|
||
TSpTBXDockClass = class of TSpTBXDock;
|
||
|
||
{ TSpTBXToolbar }
|
||
|
||
TSpTBXToolbarView = class(TTBToolbarView)
|
||
private
|
||
FMaxSize: Integer;
|
||
procedure SetMaxSize(const Value: Integer);
|
||
protected
|
||
FTallestItemSize: Integer;
|
||
FUpdating: Integer;
|
||
procedure DoUpdatePositions(var ASize: TPoint); override;
|
||
public
|
||
constructor Create(AOwner: TComponent; AParentView: TTBView;
|
||
AParentItem: TTBCustomItem; AWindow: TWinControl;
|
||
AIsToolbar, ACustomizing, AUsePriorityList: Boolean); override;
|
||
procedure BeginUpdate; virtual; // Hides inherited BeginUpdate
|
||
procedure EndUpdate; virtual; // Hides inherited EndUpdate
|
||
function IsUpdating: Boolean;
|
||
property MaxSize: Integer read FMaxSize write SetMaxSize;
|
||
end;
|
||
|
||
TSpTBXToolbar = class(TTBCustomToolbar)
|
||
private
|
||
FChevronVertical: Boolean;
|
||
FCompoundToolbar: Boolean;
|
||
FCustomizable: Boolean;
|
||
FCustomizingCount: Integer;
|
||
FItemMovingCount: Integer;
|
||
FDisplayMode: TSpTBXToolbarDisplayMode;
|
||
FLastDropMark: TRect;
|
||
FLastSelectableWidth: Integer;
|
||
FMenuBar: Boolean;
|
||
FOnDrawBackground: TSpTBXDrawEvent;
|
||
FOnItemNotification: TSpTBXItemNotificationEvent;
|
||
{$IFNDEF UNICODE}
|
||
function IsCaptionStored: Boolean;
|
||
function GetCaption: TWideCaption;
|
||
procedure SetCaption(const Value: TWideCaption);
|
||
function GetHint: WideString;
|
||
procedure SetHint(const Value: WideString);
|
||
{$ENDIF}
|
||
procedure SetDisplayMode(const Value: TSpTBXToolbarDisplayMode);
|
||
function GetMaxSize: Integer;
|
||
procedure SetMaxSize(const Value: Integer);
|
||
procedure SetMenuBar(const Value: Boolean);
|
||
function CreateWrapper(Index: Integer; Ctl: TControl): TTBControlItem;
|
||
function IsAnchoredControlItem(Item: TTBCustomItem): TTBControlItem;
|
||
procedure CMControlChange(var Message: TCMControlChange); message CM_CONTROLCHANGE;
|
||
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
|
||
procedure CMMouseleave(var Message: TMessage); message CM_MOUSELEAVE;
|
||
procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
|
||
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
|
||
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
|
||
procedure WMSize(var Message: TWMSize); message WM_SIZE;
|
||
procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE;
|
||
procedure SetCustomizable(const Value: Boolean);
|
||
protected
|
||
FBeginDragIV: TTBItemViewer;
|
||
FAnchoredControlItems: TSpTBXItemCacheCollection;
|
||
FState: TSpTBXToolbarStates;
|
||
FDefaultToolbarBorderSize: Integer;
|
||
|
||
// Component
|
||
procedure CreateWindowHandle(const Params: TCreateParams); override;
|
||
procedure DefineProperties(Filer: TFiler); override;
|
||
procedure Resize; override;
|
||
procedure AnchorItems(UpdateControlItems: Boolean = True); virtual;
|
||
procedure RightAlignItems; virtual;
|
||
|
||
// Painting
|
||
procedure DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; const Clip: HRGN); override;
|
||
function GetItemsTextColor(State: TSpTBXSkinStatesType): TColor; virtual;
|
||
procedure InternalDrawBackground(ACanvas: TCanvas; ARect: TRect; PaintOnNCArea: Boolean; PaintBorders: Boolean = True); virtual;
|
||
procedure DoDrawBackground(ACanvas: TCanvas; ARect: TRect; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual;
|
||
|
||
// Get class
|
||
function GetChevronItemClass: TTBChevronItemClass; override;
|
||
function GetFloatingWindowParentClass: TTBFloatingWindowParentClass; override;
|
||
function GetRightAlignMargin: Integer; virtual;
|
||
function GetViewClass: TTBToolbarViewClass; override;
|
||
|
||
// Hints
|
||
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
||
|
||
// Customizer
|
||
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); override;
|
||
function CanDragCustomize(Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean; virtual;
|
||
procedure DoStartDrag(var DragObject: TDragObject); override;
|
||
procedure DragOver(Source: TObject; X: Integer; Y: Integer; State: TDragState; var Accept: Boolean); override;
|
||
|
||
// Misc
|
||
function CanItemClick(Item: TTBCustomItem; Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean; virtual;
|
||
procedure DoItemClick(Item: TTBCustomItem; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
|
||
procedure DoItemNotification(Ancestor: TTBCustomItem; Relayed: Boolean; Action: TTBItemChangedAction; Index: Integer; Item: TTBCustomItem); virtual;
|
||
|
||
property CompoundToolbar: Boolean read FCompoundToolbar write FCompoundToolbar;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
procedure DragDrop(Source: TObject; X: Integer; Y: Integer); override;
|
||
procedure ReadPositionData(const Data: TTBReadPositionData); override;
|
||
procedure WritePositionData(const Data: TTBWritePositionData); override;
|
||
procedure BeginUpdate; // Hides inherited BeginUpdate
|
||
procedure EndUpdate; // Hides inherited EndUpdate
|
||
function IsUpdating: Boolean;
|
||
procedure BeginCustomize;
|
||
procedure EndCustomize;
|
||
procedure BeginItemMove;
|
||
procedure EndItemMove;
|
||
function GetFloatingBorderSize: TPoint; override;
|
||
function IsCustomizing: Boolean;
|
||
function IsItemMoving: Boolean;
|
||
function IsVertical: Boolean;
|
||
property DefaultToolbarBorderSize: Integer read FDefaultToolbarBorderSize;
|
||
property MaxSize: Integer read GetMaxSize write SetMaxSize default -1;
|
||
published
|
||
property ActivateParent;
|
||
property Align;
|
||
property AutoResize;
|
||
property BorderStyle;
|
||
property ChevronHint;
|
||
property ChevronMoveItems;
|
||
property ChevronPriorityForNewItems;
|
||
property CloseButton;
|
||
property CloseButtonWhenDocked;
|
||
property CurrentDock;
|
||
property DefaultDock;
|
||
property DockableTo;
|
||
property DockMode;
|
||
property DockPos;
|
||
property DockRow;
|
||
property DragHandleStyle;
|
||
property FloatingMode;
|
||
property Font;
|
||
property FullSize;
|
||
property HideWhenInactive;
|
||
property Images;
|
||
property Items;
|
||
property LastDock;
|
||
property LinkSubitems;
|
||
property Options;
|
||
property ParentFont;
|
||
property ParentShowHint;
|
||
property PopupMenu;
|
||
property ProcessShortCuts;
|
||
property Resizable;
|
||
property ShowCaption;
|
||
property ShowHint;
|
||
property ShrinkMode;
|
||
property SmoothDrag;
|
||
property Stretch;
|
||
property SystemFont;
|
||
property TabOrder;
|
||
property TabStop;
|
||
property UpdateActions;
|
||
property UseLastDock;
|
||
property Visible;
|
||
property Color default clNone;
|
||
property OnClose;
|
||
property OnCloseQuery;
|
||
property OnContextPopup;
|
||
property OnDblClick;
|
||
property OnDragDrop;
|
||
property OnDragOver;
|
||
property OnMouseDown;
|
||
property OnMouseMove;
|
||
property OnMouseUp;
|
||
property OnMove;
|
||
property OnRecreated;
|
||
property OnRecreating;
|
||
property OnDockChanged;
|
||
property OnDockChanging;
|
||
property OnDockChangingHidden;
|
||
property OnResize;
|
||
property OnShortCut;
|
||
property OnVisibleChanged;
|
||
{$IFNDEF UNICODE}
|
||
// Don't let the streaming system store the WideStrings, use DefineProperties instead
|
||
property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; // Hides the inherited Caption
|
||
property Hint: WideString read GetHint write SetHint stored False; // Hint is set dynamically in MouseMove, don't save it
|
||
{$ELSE}
|
||
property Caption;
|
||
property Hint;
|
||
{$ENDIF}
|
||
property ChevronVertical: Boolean read FChevronVertical write FChevronVertical default True;
|
||
property Customizable: Boolean read FCustomizable write SetCustomizable default True;
|
||
property DisplayMode: TSpTBXToolbarDisplayMode read FDisplayMode write SetDisplayMode default tbdmSelectiveCaption;
|
||
property MenuBar: Boolean read FMenuBar write SetMenuBar default False; // Hides the inherited MenuBar
|
||
property OnDrawBackground: TSpTBXDrawEvent read FOnDrawBackground write FOnDrawBackground;
|
||
property OnItemNotification: TSpTBXItemNotificationEvent read FOnItemNotification write FOnItemNotification;
|
||
end;
|
||
|
||
TSpTBXToolbarClass = class of TSpTBXToolbar;
|
||
|
||
{ TSpTBXToolWindow }
|
||
|
||
TSpTBXCustomToolWindow = class(TTBCustomDockableWindow)
|
||
private
|
||
FMinClientWidth, FMinClientHeight, FMaxClientWidth, FMaxClientHeight: Integer;
|
||
FOnDrawBackground: TSpTBXDrawEvent;
|
||
{$IFNDEF UNICODE}
|
||
function IsCaptionStored: Boolean;
|
||
function GetCaption: TWideCaption;
|
||
procedure SetCaption(const Value: TWideCaption);
|
||
{$ENDIF}
|
||
function GetClientAreaWidth: Integer;
|
||
procedure SetClientAreaWidth(Value: Integer);
|
||
function GetClientAreaHeight: Integer;
|
||
procedure SetClientAreaHeight(Value: Integer);
|
||
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
|
||
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
|
||
procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE;
|
||
procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED;
|
||
protected
|
||
FBarSize: TSize;
|
||
FDefaultToolbarBorderSize: Integer;
|
||
procedure CreateWindowHandle(const Params: TCreateParams); override;
|
||
procedure DefineProperties(Filer: TFiler); override;
|
||
function GetFloatingWindowParentClass: TTBFloatingWindowParentClass; override;
|
||
|
||
// Sizing
|
||
function CalcSize(ADock: TTBDock): TPoint; virtual;
|
||
function DoArrange(CanMoveControls: Boolean; PreviousDockType: TTBDockType; NewFloating: Boolean; NewDock: TTBDock): TPoint; override;
|
||
procedure GetBaseSize(var ASize: TPoint); override;
|
||
procedure GetMinMaxSize(var AMinClientWidth, AMinClientHeight, AMaxClientWidth, AMaxClientHeight: Integer); override;
|
||
procedure SetClientAreaSize(AWidth, AHeight: Integer); virtual;
|
||
procedure SizeChanging(const AWidth, AHeight: Integer); override;
|
||
|
||
// Painting
|
||
procedure Paint; override;
|
||
procedure DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; const Clip: HRGN); override;
|
||
procedure InternalDrawBackground(ACanvas: TCanvas; ARect: TRect; PaintOnNCArea: Boolean; PaintBorders: Boolean = True); virtual;
|
||
procedure DoDrawBackground(ACanvas: TCanvas; ARect: TRect; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual;
|
||
|
||
property ClientAreaHeight: Integer read GetClientAreaHeight write SetClientAreaHeight;
|
||
property ClientAreaWidth: Integer read GetClientAreaWidth write SetClientAreaWidth;
|
||
property MaxClientHeight: Integer read FMaxClientHeight write FMaxClientHeight default 0;
|
||
property MaxClientWidth: Integer read FMaxClientWidth write FMaxClientWidth default 0;
|
||
property MinClientHeight: Integer read FMinClientHeight write FMinClientHeight default 32;
|
||
property MinClientWidth: Integer read FMinClientWidth write FMinClientWidth default 32;
|
||
property OnDrawBackground: TSpTBXDrawEvent read FOnDrawBackground write FOnDrawBackground;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
function GetFloatingBorderSize: TPoint; override;
|
||
procedure InvalidateBackground(InvalidateChildren: Boolean = True); virtual;
|
||
function IsVertical: Boolean;
|
||
procedure ReadPositionData(const Data: TTBReadPositionData); override;
|
||
procedure WritePositionData(const Data: TTBWritePositionData); override;
|
||
property DefaultToolbarBorderSize: Integer read FDefaultToolbarBorderSize;
|
||
published
|
||
{$IFNDEF UNICODE}
|
||
// Don't let the streaming system store the WideStrings, use DefineProperties instead
|
||
property Caption: TWideCaption read GetCaption write SetCaption stored IsCaptionStored; // Hides the inherited Caption
|
||
{$ELSE}
|
||
property Caption;
|
||
{$ENDIF}
|
||
property Color default clNone;
|
||
end;
|
||
|
||
TSpTBXToolWindow = class(TSpTBXCustomToolWindow)
|
||
published
|
||
property ActivateParent;
|
||
property Align;
|
||
property Anchors;
|
||
property BorderStyle;
|
||
property Caption;
|
||
property Color;
|
||
property CloseButton;
|
||
property CloseButtonWhenDocked;
|
||
property CurrentDock;
|
||
property DefaultDock;
|
||
property DockableTo;
|
||
property DockMode;
|
||
property DockPos;
|
||
property DockRow;
|
||
property DragHandleStyle;
|
||
property FloatingMode;
|
||
property Font;
|
||
property FullSize;
|
||
property HideWhenInactive;
|
||
property LastDock;
|
||
property ParentFont;
|
||
property ParentShowHint;
|
||
property PopupMenu;
|
||
property Resizable;
|
||
property ShowCaption;
|
||
property ShowHint;
|
||
property Stretch;
|
||
property SmoothDrag;
|
||
property TabOrder;
|
||
property UseLastDock;
|
||
property Visible;
|
||
property OnClose;
|
||
property OnCloseQuery;
|
||
property OnContextPopup;
|
||
property OnDblClick;
|
||
property OnDragDrop;
|
||
property OnDragOver;
|
||
property OnDockChanged;
|
||
property OnDockChanging;
|
||
property OnDockChangingHidden;
|
||
property OnMouseDown;
|
||
property OnMouseMove;
|
||
property OnMouseUp;
|
||
property OnMove;
|
||
property OnRecreated;
|
||
property OnRecreating;
|
||
property OnResize;
|
||
property OnVisibleChanged;
|
||
// TSpTBXCustomToolWindow properties
|
||
property ClientAreaHeight;
|
||
property ClientAreaWidth;
|
||
property MaxClientHeight;
|
||
property MaxClientWidth;
|
||
property MinClientHeight;
|
||
property MinClientWidth;
|
||
property OnDrawBackground;
|
||
end;
|
||
|
||
{ TSpTBXFloatingWindowParent }
|
||
|
||
TSpTBXFloatingWindowParent = class(TTBFloatingWindowParent)
|
||
private
|
||
FCloseButtonHover: Boolean;
|
||
FCloseOnAltF4: Boolean;
|
||
procedure UpdateDwmNCSize;
|
||
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
|
||
procedure WMActivateApp(var Message: TWMActivateApp); message WM_ACTIVATEAPP;
|
||
procedure WMClose(var Message: TWMClose); message WM_CLOSE;
|
||
procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND;
|
||
procedure WMNCMouseLeave(var Message: TMessage); message WM_NCMOUSELEAVE;
|
||
procedure WMNCMouseMove(var Message: TWMNCMouseMove); message WM_NCMOUSEMOVE;
|
||
procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE;
|
||
protected
|
||
procedure CancelNCHover;
|
||
procedure CreateWnd; override;
|
||
procedure DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; const Clip: HRGN; RedrawWhat: TTBToolWindowNCRedrawWhat); override;
|
||
procedure RedrawCloseButton;
|
||
procedure VisibleChanging; override;
|
||
property CloseButtonHover: Boolean read FCloseButtonHover;
|
||
public
|
||
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
|
||
destructor Destroy; override;
|
||
property CloseOnAltF4: Boolean read FCloseOnAltF4 write FCloseOnAltF4;
|
||
end;
|
||
|
||
{ TSpTBXPopupWindow }
|
||
|
||
TSpTBXPopupWindow = class(TTBPopupWindow)
|
||
private
|
||
FPaintingClientArea: Boolean;
|
||
FMaximumImageSize: TSize;
|
||
function CanDrawGutter: Boolean;
|
||
procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
|
||
procedure CMShowingchanged(var Message: TMessage); message CM_SHOWINGCHANGED;
|
||
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
|
||
procedure WMNCPaint(var Message: TMessage); message WM_NCPAINT;
|
||
procedure WMPrint(var Message: TMessage); message WM_PRINT;
|
||
protected
|
||
function GetViewClass: TTBViewClass; override;
|
||
procedure DoPopupShowingChanged(IsVisible: Boolean); virtual;
|
||
procedure PaintBackground(ACanvas: TCanvas; ARect: TRect); virtual;
|
||
public
|
||
constructor CreatePopupWindow(AOwner: TComponent; const AParentView: TTBView;
|
||
const AItem: TTBCustomItem; const ACustomizing: Boolean); override;
|
||
destructor Destroy; override;
|
||
property MaximumImageSize: TSize read FMaximumImageSize;
|
||
end;
|
||
|
||
TSpTBXPopupWindowView = class(TTBPopupView)
|
||
protected
|
||
procedure AutoSize(AWidth, AHeight: Integer); override;
|
||
public
|
||
procedure SetIsToolbar(const Value: Boolean);
|
||
published
|
||
property IsToolbar;
|
||
end;
|
||
|
||
{ TSpTBXChevronItem }
|
||
|
||
TSpTBXChevronItem = class(TTBChevronItem)
|
||
protected
|
||
function GetPopupWindowClass: TTBPopupWindowClass; override;
|
||
public
|
||
function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override;
|
||
end;
|
||
|
||
TSpTBXChevronItemViewer = class(TTBItemViewer)
|
||
protected
|
||
procedure Paint(const Canvas: TCanvas; const ClientAreaRect: TRect;
|
||
IsSelected, IsPushed, UseDisabledShadow: Boolean); override;
|
||
public
|
||
function GetTextColor(State: TSpTBXSkinStatesType): TColor; virtual;
|
||
end;
|
||
|
||
TSpTBXChevronPopupWindow = class(TSpTBXPopupWindow)
|
||
private
|
||
procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
|
||
end;
|
||
|
||
{ TSpTBXPopupMenu }
|
||
|
||
ISpTBXPopupMenu = interface
|
||
['{C576A225-6E42-49F6-96E5-712510C5D85C}']
|
||
function InternalPopup(X, Y: Integer; ForceFocus: Boolean; PopupControl: TControl = nil): Boolean;
|
||
end;
|
||
|
||
TSpTBXPopupMenu = class(TTBPopupMenu, ISpTBXPopupMenu)
|
||
private
|
||
FClickedItem: TTBCustomItem;
|
||
FReturnClickedItemOnly: Boolean;
|
||
FToolBoxPopup: Boolean;
|
||
function GetOnInitPopup: TSpTBXPopupEvent;
|
||
procedure SetOnInitPopup(const Value: TSpTBXPopupEvent);
|
||
function GetOnClosePopup: TNotifyEvent;
|
||
procedure SetOnClosePopup(const Value: TNotifyEvent);
|
||
protected
|
||
function InternalPopup(X, Y: Integer; ForceFocus: Boolean; PopupControl: TControl = nil): Boolean; virtual;
|
||
function GetRootItemClass: TTBRootItemClass; override;
|
||
public
|
||
procedure Popup(X: Integer; Y: Integer); override;
|
||
function PopupEx(X, Y: Integer; PopupControl: TControl = nil; ReturnClickedItemOnly: Boolean = False): TTBCustomItem; virtual;
|
||
published
|
||
property ToolBoxPopup: Boolean read FToolBoxPopup write FToolBoxPopup default False;
|
||
property OnInitPopup: TSpTBXPopupEvent read GetOnInitPopup write SetOnInitPopup;
|
||
property OnClosePopup: TNotifyEvent read GetOnClosePopup write SetOnClosePopup;
|
||
end;
|
||
|
||
{ TSpTBXCompoundItemsControl }
|
||
|
||
TSpTBXCompoundItemsControl = class(TSpTBXCustomControl, ITBItems)
|
||
private
|
||
FSkinType: TSpTBXSkinType;
|
||
procedure DockRequestDock(Sender: TObject; Bar: TTBCustomDockableWindow; var Accept: Boolean);
|
||
function GetRootItems: TTBRootItem;
|
||
function GetView: TSpTBXToolbarView;
|
||
function GetImages: TCustomImageList;
|
||
procedure SetImages(const Value: TCustomImageList);
|
||
procedure SetSkinType(const Value: TSpTBXSkinType);
|
||
procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE;
|
||
protected
|
||
FDock: TSpTBXDock;
|
||
FToolbar: TSpTBXToolbar;
|
||
procedure CreateParams(var Params: TCreateParams); override;
|
||
function GetDockClass: TSpTBXDockClass; virtual;
|
||
function GetToolbarClass: TSpTBXToolbarClass; virtual;
|
||
function GetItems: TTBCustomItem; virtual; // For ITBItems interface
|
||
procedure Loaded; override;
|
||
procedure SetName(const Value: TComponentName); override;
|
||
property Images: TCustomImageList read GetImages write SetImages;
|
||
property SkinType: TSpTBXSkinType read FSkinType write SetSkinType default sknSkin;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; // For ITBItems interface
|
||
procedure InvalidateBackground(InvalidateChildren: Boolean = True); virtual;
|
||
property View: TSpTBXToolbarView read GetView;
|
||
published
|
||
property Items: TTBRootItem read GetRootItems;
|
||
end;
|
||
|
||
{ TSpTBXCompoundBar }
|
||
|
||
TSpTBXCompoundBar = class(TSpTBXCompoundItemsControl)
|
||
private
|
||
FOnDrawDockBackground: TSpTBXDrawEvent;
|
||
procedure DrawDockBackground(Sender: TObject; ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
procedure DrawToolbarBackground(Sender: TObject; ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
procedure DockResize(Sender: TObject);
|
||
protected
|
||
procedure DoDrawDockBackground(ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual;
|
||
property OnDrawDockBackground: TSpTBXDrawEvent read FOnDrawDockBackground write FOnDrawDockBackground;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
end;
|
||
|
||
{ TSpTBXButtonOptions }
|
||
|
||
TSpTBXButtonOptions = class(TPersistent)
|
||
private
|
||
FEditableItems: TTBGroupItem;
|
||
FCloseButton: TSpTBXItem;
|
||
FMinimizeButton: TSpTBXItem;
|
||
FMaximizeButton: TSpTBXItem;
|
||
FRightAlignSpacer: TSpTBXRightAlignSpacerItem;
|
||
FCaptionImageIndex: Integer;
|
||
FCloseImageIndex: Integer;
|
||
FMinimizeImageIndex: Integer;
|
||
FMaximizeImageIndex: Integer;
|
||
FRestoreImageIndex: Integer;
|
||
FCaptionLabel: WideString;
|
||
FCaption: Boolean;
|
||
FClose: Boolean;
|
||
FMinimize: Boolean;
|
||
FMaximize: Boolean;
|
||
FButtonBorders: Boolean;
|
||
FTitleBarMaxSize: Integer;
|
||
procedure SetCaptionImageIndex(Value: Integer);
|
||
procedure SetCloseImageIndex(Value: Integer);
|
||
procedure SetCaptionLabel(const Value: WideString);
|
||
procedure SetMaximizeImageIndex(Value: Integer);
|
||
procedure SetRestoreImageIndex(Value: Integer);
|
||
procedure SetMinimizeImageIndex(Value: Integer);
|
||
procedure SetCaption(const Value: Boolean);
|
||
procedure SetClose(const Value: Boolean);
|
||
procedure SetMaximize(const Value: Boolean);
|
||
procedure SetMinimize(const Value: Boolean);
|
||
procedure SetTitleBarMaxSize(const Value: Integer);
|
||
protected
|
||
FParentControl: TWinControl;
|
||
FToolbar: TSpTBXToolbar;
|
||
procedure ButtonsDrawImage(Sender: TObject; ACanvas: TCanvas;
|
||
State: TSpTBXSkinStatesType; const PaintStage: TSpTBXPaintStage;
|
||
var AImageList: TCustomImageList; var AImageIndex: Integer; var ARect:
|
||
TRect; var PaintDefault: Boolean); virtual;
|
||
procedure ButtonsDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect;
|
||
ItemInfo: TSpTBXMenuItemInfo; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean); virtual;
|
||
procedure ButtonsClick(Sender: TObject); virtual; abstract;
|
||
procedure CreateButtons; virtual;
|
||
procedure UpdateButtonsVisibility; virtual;
|
||
procedure SetupButton(B: TSpTBXCustomItem); virtual;
|
||
function Restoring(B: TSpTBXCustomItem): Boolean; virtual; abstract;
|
||
public
|
||
constructor Create(AParent: TWinControl); virtual;
|
||
procedure SetupButtonIcon(B: TSpTBXCustomItem); virtual;
|
||
procedure MoveItemToTheLeft(B: TTBCustomItem);
|
||
property EditableItems: TTBGroupItem read FEditableItems;
|
||
property RightAlignSpacer: TSpTBXRightAlignSpacerItem read FRightAlignSpacer;
|
||
property MinimizeButton: TSpTBXItem read FMinimizeButton;
|
||
property MaximizeButton: TSpTBXItem read FMaximizeButton;
|
||
property CloseButton: TSpTBXItem read FCloseButton;
|
||
property CaptionLabel: WideString read FCaptionLabel write SetCaptionLabel;
|
||
published
|
||
property ButtonBorders: Boolean read FButtonBorders write FButtonBorders default True;
|
||
property Caption: Boolean read FCaption write SetCaption default True;
|
||
property Close: Boolean read FClose write SetClose default True;
|
||
property Minimize: Boolean read FMinimize write SetMinimize default True;
|
||
property Maximize: Boolean read FMaximize write SetMaximize default True;
|
||
property CaptionImageIndex: Integer read FCaptionImageIndex write SetCaptionImageIndex default -1;
|
||
property CloseImageIndex: Integer read FCloseImageIndex write SetCloseImageIndex default -1;
|
||
property MinimizeImageIndex: Integer read FMinimizeImageIndex write SetMinimizeImageIndex default -1;
|
||
property MaximizeImageIndex: Integer read FMaximizeImageIndex write SetMaximizeImageIndex default -1;
|
||
property RestoreImageIndex: Integer read FRestoreImageIndex write SetRestoreImageIndex default -1;
|
||
property TitleBarMaxSize: Integer read FTitleBarMaxSize write SetTitleBarMaxSize default 21;
|
||
end;
|
||
|
||
{ TSpTBXStatusBar }
|
||
|
||
TSpTBXStatusToolbar = class(TSpTBXToolbar)
|
||
private
|
||
FSizeGrip: Boolean;
|
||
FSkinType: TSpTBXSkinType;
|
||
procedure SetSizeGrip(const Value: Boolean);
|
||
procedure WMNCLButtonDown(var Message: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
|
||
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
|
||
protected
|
||
FParentForm: TCustomForm;
|
||
procedure DoItemNotification(Ancestor: TTBCustomItem; Relayed: Boolean; Action: TTBItemChangedAction; Index: Integer; Item: TTBCustomItem); override;
|
||
function GetItemsTextColor(State: TSpTBXSkinStatesType): TColor; override;
|
||
function GetRightAlignMargin: Integer; override;
|
||
function GetParentFormWindowState: TWindowState;
|
||
function IsPointInGrip(P: TPoint): Boolean;
|
||
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); override;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
function GetGripRect: TRect;
|
||
function NeedsSeparatorRepaint: Boolean;
|
||
published
|
||
property SizeGrip: Boolean read FSizeGrip write SetSizeGrip default True;
|
||
end;
|
||
|
||
TSpTBXCustomStatusBar = class(TSpTBXCompoundBar)
|
||
private
|
||
function GetSizeGrip: Boolean;
|
||
procedure SetSizeGrip(const Value: Boolean);
|
||
function GetStatusToolbar: TSpTBXStatusToolbar;
|
||
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
|
||
protected
|
||
FPrevState: TWindowState;
|
||
function CanResize(var NewWidth: Integer; var NewHeight: Integer): Boolean; override;
|
||
procedure DoDrawDockBackground(ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); override;
|
||
procedure DrawSeparators(ACanvas: TCanvas; ARect: TRect); virtual;
|
||
function GetToolbarClass: TSpTBXToolbarClass; override;
|
||
property Align default alBottom;
|
||
property SizeGrip: Boolean read GetSizeGrip write SetSizeGrip default True;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
property Toolbar: TSpTBXStatusToolbar read GetStatusToolbar;
|
||
end;
|
||
|
||
TSpTBXStatusBar = class(TSpTBXCustomStatusBar)
|
||
published
|
||
property Align;
|
||
property Anchors;
|
||
property BiDiMode;
|
||
property DragCursor;
|
||
property DragKind;
|
||
property DragMode;
|
||
property Enabled;
|
||
property Font;
|
||
property ParentColor;
|
||
property ParentBiDiMode;
|
||
property ParentFont;
|
||
property ParentShowHint;
|
||
property PopupMenu;
|
||
property ShowHint;
|
||
property Visible;
|
||
property OnCanResize;
|
||
property OnContextPopup;
|
||
property OnDragDrop;
|
||
property OnDragOver;
|
||
property OnEndDock;
|
||
property OnEndDrag;
|
||
property OnMouseDown;
|
||
property OnMouseMove;
|
||
property OnMouseUp;
|
||
property OnResize;
|
||
property OnStartDock;
|
||
property OnStartDrag;
|
||
// TSpTBXCustomStatusBar properties
|
||
property Images;
|
||
property SizeGrip;
|
||
property SkinType;
|
||
property OnDrawDockBackground;
|
||
end;
|
||
|
||
{ TSpTBXTitleBar }
|
||
|
||
TSpTBXCustomTitleBar = class;
|
||
|
||
TSpTBXTitleToolbar = class(TSpTBXToolbar)
|
||
private
|
||
procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
|
||
protected
|
||
function GetItemsTextColor(State: TSpTBXSkinStatesType): TColor; override;
|
||
function GetTitleBar: TSpTBXCustomTitleBar;
|
||
function GetRightAlignMargin: Integer; override;
|
||
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); override;
|
||
end;
|
||
|
||
TSpTBXTitleBarButtonOptions = class(TSpTBXButtonOptions)
|
||
private
|
||
FSystemMenu: Boolean;
|
||
FSystemButton: TSpTBXSystemMenuItem;
|
||
procedure SetSystemMenu(const Value: Boolean);
|
||
protected
|
||
FTitleBar: TSpTBXCustomTitleBar;
|
||
procedure ButtonsDrawItem(Sender: TObject; ACanvas: TCanvas;
|
||
ARect: TRect; ItemInfo: TSpTBXMenuItemInfo; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean); override;
|
||
procedure ButtonsClick(Sender: TObject); override;
|
||
procedure CreateButtons; override;
|
||
function Restoring(B: TSpTBXCustomItem): Boolean; override;
|
||
public
|
||
constructor Create(AParent: TWinControl); override;
|
||
property SystemButton: TSpTBXSystemMenuItem read FSystemButton;
|
||
published
|
||
property SystemMenu: Boolean read FSystemMenu write SetSystemMenu default True;
|
||
end;
|
||
|
||
TSpTBXCustomTitleBar = class(TSpTBXCompoundBar)
|
||
private
|
||
FActive: Boolean;
|
||
FFixedSize: Boolean;
|
||
FFullScreenMaximize: Boolean;
|
||
FMouseActive: Boolean;
|
||
FOptions: TSpTBXTitleBarButtonOptions;
|
||
FOldAppWndProc: Pointer;
|
||
FNewAppWndProc: Pointer;
|
||
FOnDrawBackground: TSpTBXDrawEvent;
|
||
FOnSystemMenuPopup: TSpTBXPopupEvent;
|
||
FOldParentFormWndProc: TWndMethod;
|
||
procedure AppWndProc(var Msg: TMessage);
|
||
procedure NewParentFormWndProc(var Message: TMessage);
|
||
procedure SetActive(const Value: Boolean);
|
||
procedure SetMouseActive(const Value: Boolean);
|
||
procedure SetFullScreenMaximize(const Value: Boolean);
|
||
function GetWindowState: TWindowState;
|
||
procedure SetWindowState(const Value: TWindowState);
|
||
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
|
||
procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND;
|
||
procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
|
||
procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE;
|
||
procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED;
|
||
protected
|
||
FParentForm: TCustomForm;
|
||
// Component
|
||
procedure Loaded; override;
|
||
function GetFloatingBorderSize: TPoint;
|
||
function GetItems: TTBCustomItem; override; // For ITBItems interface
|
||
function GetToolbarClass: TSpTBXToolbarClass; override;
|
||
procedure ChangeTitleBarState(Activate: Boolean);
|
||
procedure UpdateSkinMetrics;
|
||
|
||
// Painting
|
||
procedure DoDrawDockBackground(ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); override;
|
||
procedure DoDrawBackground(ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual;
|
||
|
||
// Sizing
|
||
procedure AdjustClientRect(var Rect: TRect); override;
|
||
procedure GetSizeCursor(MousePos: TPoint; var SizeCursor, SizeCode: Integer);
|
||
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); override;
|
||
|
||
property Active: Boolean read FActive write SetActive default True;
|
||
property Align default alClient;
|
||
property FixedSize: Boolean read FFixedSize write FFixedSize default False;
|
||
property FullScreenMaximize: Boolean read FFullScreenMaximize write SetFullScreenMaximize default False;
|
||
property Options: TSpTBXTitleBarButtonOptions read FOptions write FOptions;
|
||
property WindowState: TWindowState read GetWindowState write SetWindowState;
|
||
property OnDrawBackground: TSpTBXDrawEvent read FOnDrawBackground write FOnDrawBackground;
|
||
property OnSystemMenuPopup: TSpTBXPopupEvent read FOnSystemMenuPopup write FOnSystemMenuPopup;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
function GetClientAreaRect: TRect;
|
||
function IsActive: Boolean;
|
||
property MouseActive: Boolean read FMouseActive write SetMouseActive default True;
|
||
property Toolbar: TSpTBXToolbar read FToolbar;
|
||
published
|
||
property Caption;
|
||
end;
|
||
|
||
TSpTBXTitleBar = class(TSpTBXCustomTitleBar)
|
||
published
|
||
property Align;
|
||
property Anchors;
|
||
property Color;
|
||
property BiDiMode;
|
||
property Constraints;
|
||
property DockSite;
|
||
property DragCursor;
|
||
property DragKind;
|
||
property DragMode;
|
||
property Enabled;
|
||
property Font;
|
||
property ParentColor;
|
||
property ParentBiDiMode;
|
||
property ParentFont;
|
||
property ParentShowHint;
|
||
property PopupMenu;
|
||
property ShowHint;
|
||
property Visible;
|
||
property OnCanResize;
|
||
property OnContextPopup;
|
||
property OnDockDrop;
|
||
property OnDockOver;
|
||
property OnDragDrop;
|
||
property OnDragOver;
|
||
property OnEndDock;
|
||
property OnEndDrag;
|
||
property OnEnter;
|
||
property OnExit;
|
||
property OnGetSiteInfo;
|
||
property OnMouseDown;
|
||
property OnMouseMove;
|
||
property OnMouseUp;
|
||
property OnResize;
|
||
property OnStartDock;
|
||
property OnStartDrag;
|
||
property OnUnDock;
|
||
// TSpTBXCustomTitleBar properties
|
||
property Active;
|
||
property FixedSize;
|
||
property FullScreenMaximize;
|
||
property Images;
|
||
property Options;
|
||
property OnDrawBackground;
|
||
property OnDrawDockBackground;
|
||
property OnSystemMenuPopup;
|
||
end;
|
||
|
||
{ TBitmapHint }
|
||
|
||
TBitmapHint = class(THintWindow)
|
||
private
|
||
FHintBitmap: TBitmap;
|
||
FActivating: Boolean;
|
||
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
|
||
protected
|
||
procedure Paint; override;
|
||
public
|
||
property Activating: Boolean read FActivating;
|
||
procedure ActivateHint(Rect: TRect; const AHint: string); override;
|
||
procedure ActivateHintData(Rect: TRect; const AHint: string; AData: Pointer); override;
|
||
end;
|
||
|
||
{ Item helpers }
|
||
procedure SpFillItemInfo(ACanvas: TCanvas; IV: TTBItemViewer; out ItemInfo: TSpTBXMenuItemInfo);
|
||
function SpGetBoundsRect(IV: TTBItemViewer; Root: TTBRootItem): TRect;
|
||
procedure SpGetAllItems(AParentItem: TTBCustomItem; ItemsList: TTntStringList; ClearFirst: Boolean = True);
|
||
function SpGetMenuMaximumImageSize(View: TTBView): TSize;
|
||
function SpGetItemViewerFromPoint(Root: TTBRootItem; View: TTBView; P: TPoint; ProcessGroupItems: Boolean = True): TTBItemViewer;
|
||
function SpGetNextItemSameEdge(View: TTBView; IV: TTBItemViewer; GoForward: Boolean; SearchType: TSpTBXSearchItemViewerType): TTBItemViewer;
|
||
function SpGetFirstRightAlignSpacer(View: TTBView): TSpTBXItemViewer;
|
||
function SpGetRightAlignedItems(View: TTBView; RightAlignedList: TList; IsRotated: Boolean; out VisibleTotalWidth, RightAlignedTotalWidth: Integer): TSpTBXItemViewer;
|
||
procedure SpInvalidateItem(View: TTBView; Item: TTBCustomItem);
|
||
function SpFindItemViewer(View: TTBView; Item: TTBCustomItem): TTBItemViewer;
|
||
function SpFindControlItem(Item: TTBCustomItem; Ctl: TControl; Recurse: Boolean = True): TTBControlItem;
|
||
procedure SpGetDropPosItemViewer(Root: TTBRootItem; View: TTBView; P: TPoint; out DestIV: TTBItemViewer; out DestItemPos: Integer; out DropMark: TRect); overload;
|
||
procedure SpGetDropPosItemViewer(Root: TTBRootItem; View: TTBView; P: TPoint; SourceItemPos: Integer; out DestIV: TTBItemViewer; out DestItemPos: Integer); overload;
|
||
function SpGetDragHandleSize(Toolbar: TTBCustomDockableWindow): Integer;
|
||
function SpIsVerticalToolbar(Toolbar: TTBCustomDockableWindow): Boolean;
|
||
function SpIsDockUsingBitmap(Dock: TTBDock): Boolean;
|
||
|
||
{ Painting helpers }
|
||
procedure SpDrawXPToolbarButton(ACanvas: TCanvas; ARect: TRect; State: TSpTBXSkinStatesType; SkinType: TSpTBXSkinType; ComboPart: TSpTBXComboPart = cpNone);
|
||
procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo);
|
||
procedure SpDrawXPMenuSeparator(ACanvas: TCanvas; ARect: TRect; MenuItemStyle, Vertical: Boolean);
|
||
procedure SpDrawXPMenuItemImage(ACanvas: TCanvas; ARect: TRect; const ItemInfo: TSpTBXMenuItemInfo; ImageList: TCustomImageList; ImageIndex: Integer);
|
||
procedure SpDrawXPMenuGutter(ACanvas: TCanvas; ARect: TRect; SkinType: TSpTBXSkinType);
|
||
procedure SpDrawXPMenuPopupWindow(ACanvas: TCanvas; ARect, OpenIVRect: TRect; DrawGutter: Boolean; ImageSize: Integer; SkinType: TSpTBXSkinType);
|
||
procedure SpDrawXPStatusBar(ACanvas: TCanvas; ARect, AGripRect: TRect; SkinType: TSpTBXSkinType);
|
||
procedure SpDrawXPTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean; DrawBorders: Boolean = True);
|
||
procedure SpDrawXPTitleBarBody(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean; BorderSize: TPoint; DrawBody: Boolean = True);
|
||
procedure SpDrawXPDock(ACanvas: TCanvas; ARect: TRect; SkinType: TSpTBXSkinType; Vertical: Boolean = False);
|
||
procedure SpDrawXPToolbar(ACanvas: TCanvas; ARect: TRect; SkinType: TSpTBXSkinType; Docked, Floating, Vertical, PaintSkinBackground, PaintBorders: Boolean; SkinComponent: TSpTBXSkinComponentsType = skncToolbar); overload;
|
||
procedure SpDrawXPToolbar(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARect: TRect; PaintOnNCArea: Boolean; PaintBorders: Boolean = True; SkinComponent: TSpTBXSkinComponentsType = skncToolbar); overload;
|
||
procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARect: TRect);
|
||
procedure SpDrawXPTooltipBackground(ACanvas: TCanvas; ARect: TRect);
|
||
|
||
{ Menu helpers }
|
||
function SpCalcPopupPosition(const X, Y, Width, Height: Integer; PopupControl: TControl = nil; IsVertical: Boolean = False): TPoint;
|
||
function SpHMenuGetCaption(Menu: HMenu; Index: Integer): WideString;
|
||
function SpHMenuToTBMenuItem(Menu: HMenu; ParentItem: TTBCustomItem): Boolean;
|
||
function SpShowSystemPopupMenu(ParentForm: TCustomForm; ScreenPos: TPoint; DoDefault: Boolean = True): Integer;
|
||
function SpFillSystemSpTBXPopup(ParentForm: TCustomForm; ParentItem: TTBCustomItem; ShowSize, ShowMinimize, ShowMaximize, ShowClose: Boolean; ClickEvent: TNotifyEvent = nil): Boolean;
|
||
function SpShowSystemSpTBXPopupMenu(ParentForm: TCustomForm; ScreenPos: TPoint; ShowSize, ShowMinimize, ShowMaximize, ShowClose: Boolean; PopupEvent: TSpTBXPopupEvent; DoDefault: Boolean = True): Integer;
|
||
|
||
{ Misc helpers }
|
||
procedure SpActivateDwmNC(WinControl: TWinControl; Activate: Boolean);
|
||
function SpIsDwmCompositionEnabled: Boolean;
|
||
function SpCanFocus(WinControl: TWinControl): Boolean;
|
||
function SpIsFocused(WinControl: TWinControl; out FocusedChild: TWinControl): Boolean;
|
||
function SpFocusFirstChild(WinControl: TWinControl): TWinControl;
|
||
function SpFindControl(Parent: TWinControl; Child: TControl): Integer;
|
||
function SpFindParent(Control: TControl; ParentClass: TClass): TWinControl;
|
||
function SpHasBorders(WinControl: TWinControl): Boolean;
|
||
function SpGetFormWindowState(F: TCustomForm; out RestoreBoundsRect: TRect): TWindowState;
|
||
procedure SpSetFormWindowState(F: TCustomForm; WindowState: TWindowState; RestoreBoundsRect: TRect);
|
||
function SpGetTaskBar(out State, Edge: Cardinal; out Bounds: TRect): Boolean;
|
||
procedure SpRecalcNCArea(WinControl: TWinControl);
|
||
|
||
{ Customizer helpers }
|
||
procedure SpCustomizeAllToolbars(AParentComponent: TComponent; Reset: Boolean);
|
||
procedure SpBeginUpdateAllToolbars(AParentComponent: TComponent);
|
||
procedure SpEndUpdateAllToolbars(AParentComponent: TComponent);
|
||
|
||
{ Unicode helpers }
|
||
procedure SpPersistent_AfterInherited_DefineProperties(Filer: TFiler; Instance: TPersistent);
|
||
|
||
var
|
||
SmCaptionFont: TFont;
|
||
SpStockHintBitmap: TBitmap;
|
||
MDIButtonsImgList: TImageList = nil;
|
||
SpTBXHintWindowClass: THintWindowClass = TBitmapHint;
|
||
|
||
const
|
||
CDefaultToolbarBorderSize = 2; // Default size of Floating Toolbar borders
|
||
crSpTBXNewHandPoint = 100; // Cursor ID to replace crHandPoint for IDC_HAND
|
||
crSpTBXCustomization = 101; // Cursor ID used for item D&D customization accepted
|
||
crSpTBXCustomizationCancel = 102; // Cursor ID used for item D&D customization cancelled
|
||
|
||
implementation
|
||
|
||
{$R SpTBXGlyphs.res}
|
||
|
||
uses
|
||
Themes, UxTheme,
|
||
TypInfo, Types, ComCtrls, CommCtrl, ShellApi,
|
||
{$IFDEF JR_D11} DwmApi, {$ENDIF}
|
||
{$IFNDEF UNICODE} TntWindows, TntSysUtils, TntActnList, TntForms, {$ENDIF}
|
||
TB2Anim, TB2Common;
|
||
|
||
const
|
||
ROP_DSPDxax = $00E20746;
|
||
// Constants for TSpTBXToolWindow registry values. Do not localize!
|
||
rvClientWidth = 'ClientWidth';
|
||
rvClientHeight = 'ClientHeight';
|
||
// ColorPalette constants:
|
||
CPDefaultColors: array[0..CPDefaultCols * CPDefaultRows - 1] of TIdentMapEntry = (
|
||
(Value: $000000; Name: 'Black'),
|
||
(Value: $003399; Name: 'Brown'),
|
||
(Value: $003333; Name: 'Olive Green'),
|
||
(Value: $003300; Name: 'Dark Green'),
|
||
(Value: $663300; Name: 'Dark Teal'),
|
||
(Value: $800000; Name: 'Dark blue'),
|
||
(Value: $993333; Name: 'Indigo'),
|
||
(Value: $333333; Name: 'Gray-80%'),
|
||
|
||
(Value: $000080; Name: 'Dark Red'),
|
||
(Value: $0066FF; Name: 'Orange'),
|
||
(Value: $008080; Name: 'Dark Yellow'),
|
||
(Value: $008000; Name: 'Green'),
|
||
(Value: $808000; Name: 'Teal'),
|
||
(Value: $FF0000; Name: 'Blue'),
|
||
(Value: $996666; Name: 'Blue-Gray'),
|
||
(Value: $808080; Name: 'Gray-50%'),
|
||
|
||
(Value: $0000FF; Name: 'Red'),
|
||
(Value: $0099FF; Name: 'Light Orange'),
|
||
(Value: $00CC99; Name: 'Lime'),
|
||
(Value: $669933; Name: 'Sea Green'),
|
||
(Value: $CCCC33; Name: 'Aqua'),
|
||
(Value: $FF6633; Name: 'Light Blue'),
|
||
(Value: $800080; Name: 'Violet'),
|
||
(Value: $969696; Name: 'Gray-40%'),
|
||
|
||
(Value: $FF00FF; Name: 'Pink'),
|
||
(Value: $00CCFF; Name: 'Gold'),
|
||
(Value: $00FFFF; Name: 'Yellow'),
|
||
(Value: $00FF00; Name: 'Bright Green'),
|
||
(Value: $FFFF00; Name: 'Turquoise'),
|
||
(Value: $FFCC00; Name: 'Sky Blue'),
|
||
(Value: $663399; Name: 'Plum'),
|
||
(Value: $C0C0C0; Name: 'Gray-25%'),
|
||
|
||
(Value: $CC99FF; Name: 'Rose'),
|
||
(Value: $99CCFF; Name: 'Tan'),
|
||
(Value: $99FFFF; Name: 'Light Yellow'),
|
||
(Value: $CCFFCC; Name: 'Light Green'),
|
||
(Value: $FFFFCC; Name: 'Light Turquoise'),
|
||
(Value: $FFCC99; Name: 'Pale Blue'),
|
||
(Value: $FF99CC; Name: 'Lavender'),
|
||
(Value: $FFFFFF; Name: 'White'));
|
||
|
||
type
|
||
TTBCustomItemAccess = class(TTBCustomItem);
|
||
TTBItemViewerAccess = class(TTBItemViewer);
|
||
TTBViewAccess = class(TTBView);
|
||
TTBDockAccess = class(TTBDock);
|
||
TTBCustomDockableWindowAccess = class(TTBCustomDockableWindow);
|
||
TTBBasicBackgroundAccess = class(TTBBasicBackground);
|
||
TControlAccess = class(TControl);
|
||
TWinControlAccess = class(TWinControl);
|
||
TCustomFormAccess = class(TCustomForm);
|
||
TActionLinkAccess = class(TActionLink);
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ Item Helpers }
|
||
|
||
procedure SpFillItemInfo(ACanvas: TCanvas; IV: TTBItemViewer; out ItemInfo: TSpTBXMenuItemInfo);
|
||
var
|
||
Item: TTBCustomItemAccess;
|
||
View: TTBViewAccess;
|
||
|
||
IsHoverItem, IsOpen, IsPushed: Boolean;
|
||
IsSplit, IsComboPushed: Boolean;
|
||
IsToolbarStyle, ImageIsShown: Boolean;
|
||
ImgSize, RightImageSize: TSize;
|
||
begin
|
||
Item := TTBCustomItemAccess(IV.Item);
|
||
View := TTBViewAccess(IV.View);
|
||
|
||
if IV is TSpTBXItemViewer then
|
||
IsToolbarStyle := TSpTBXItemViewer(IV).IsToolbarStyle
|
||
else
|
||
IsToolbarStyle := IV.IsToolbarStyle;
|
||
IsOpen := IV = View.OpenViewer;
|
||
IsHoverItem := IV = View.Selected;
|
||
IsPushed := IsHoverItem and (IsOpen or (View.MouseOverSelected and View.Capture and IsToolbarStyle));
|
||
IsSplit := tbisCombo in Item.ItemStyle;
|
||
IsComboPushed := IsSplit and IsPushed and not View.Capture;
|
||
if IsComboPushed then IsPushed := False;
|
||
|
||
ImgSize.cx := 0;
|
||
ImgSize.cy := 0;
|
||
RightImageSize.cx := 0;
|
||
RightImageSize.cy := 0;
|
||
ImageIsShown := False;
|
||
if IV is TSpTBXItemViewer then begin
|
||
if TSpTBXItemViewer(IV).GetImageShown then begin
|
||
ImgSize := TSpTBXItemViewer(IV).GetImageSize;
|
||
if (ImgSize.cx > 0) and (ImgSize.cy > 0) then
|
||
ImageIsShown := True;
|
||
end;
|
||
RightImageSize := TSpTBXItemViewer(IV).GetRightImageSize;
|
||
end;
|
||
|
||
FillChar(ItemInfo, SizeOf(ItemInfo), 0);
|
||
ItemInfo.Enabled := Item.Enabled or View.Customizing;
|
||
ItemInfo.Pushed := IsPushed;
|
||
ItemInfo.Checked := Item.Checked;
|
||
ItemInfo.HotTrack := IsHoverItem;
|
||
ItemInfo.ImageShown := ImageIsShown;
|
||
ItemInfo.ImageOrCheckShown := ImageIsShown or (not IsToolbarStyle and Item.Checked);
|
||
ItemInfo.ImageSize := ImgSize;
|
||
ItemInfo.RightImageSize := RightImageSize;
|
||
ItemInfo.IsDesigning := csDesigning in View.ComponentState;
|
||
ItemInfo.IsOnMenuBar := vsMenuBar in View.Style;
|
||
ItemInfo.IsVertical := (View.Orientation = tbvoVertical) and not IsSplit;
|
||
ItemInfo.IsOnToolbox := False;
|
||
if IV is TSpTBXItemViewer then
|
||
ItemInfo.IsOnToolbox := TSpTBXItemViewer(IV).IsOnToolBoxPopup;
|
||
ItemInfo.IsOpen := IsOpen;
|
||
ItemInfo.IsSplit := IsSplit;
|
||
ItemInfo.ComboRect := Rect(0, 0, 0, 0);
|
||
// HasArrow = tboDropdownArrow or (Submenu and Combo)
|
||
ItemInfo.HasArrow := (tboDropdownArrow in Item.Options) or
|
||
((tbisSubmenu in Item.ItemStyle) and (tbisCombo in Item.ItemStyle));
|
||
ItemInfo.ToolbarStyle := IsToolbarStyle;
|
||
|
||
if ItemInfo.ToolbarStyle then
|
||
begin
|
||
if ItemInfo.HasArrow then
|
||
ItemInfo.ComboPart := cpCombo;
|
||
if ItemInfo.IsSplit then
|
||
ItemInfo.ComboPart := cpSplitLeft;
|
||
end
|
||
else begin
|
||
// Only for menu items
|
||
if View.Window is TSpTBXPopupWindow then
|
||
CurrentSkin.GetMenuItemMargins(ACanvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, ItemInfo.MenuMargins)
|
||
else
|
||
CurrentSkin.GetMenuItemMargins(ACanvas, ImgSize.cx, ItemInfo.MenuMargins);
|
||
end;
|
||
|
||
if tbisClicksTransparent in Item.ItemStyle then
|
||
ItemInfo.State := CurrentSkin.GetState(ItemInfo.Enabled, False, False, False)
|
||
else
|
||
ItemInfo.State := CurrentSkin.GetState(ItemInfo.Enabled, ItemInfo.Pushed, ItemInfo.HotTrack, ItemInfo.Checked);
|
||
|
||
ItemInfo.ComboState := sknsNormal;
|
||
if IsSplit then begin
|
||
ItemInfo.ComboState := ItemInfo.State;
|
||
if IsComboPushed then
|
||
ItemInfo.ComboState := sknsPushed
|
||
else
|
||
case ItemInfo.State of
|
||
sknsPushed: ItemInfo.ComboState := sknsHotTrack;
|
||
sknsChecked: ItemInfo.ComboState := sknsNormal;
|
||
sknsCheckedAndHotTrack: ItemInfo.ComboState := sknsHotTrack;
|
||
end;
|
||
end;
|
||
|
||
ItemInfo.SkinType := SkinManager.GetSkinType;
|
||
|
||
// [Theme-Change]
|
||
// The Default theme paints the caption of the pushed button in a down
|
||
// state, this only happens when the Item is on a toolbar and:
|
||
// 1) Windows themes are enabled and the item is not on a menubar
|
||
// 2) Windows themes are disabled
|
||
ItemInfo.IsSunkenCaption := False;
|
||
if (ItemInfo.Pushed or ItemInfo.Checked) and ItemInfo.ToolbarStyle then
|
||
ItemInfo.IsSunkenCaption := (not ItemInfo.IsOnMenuBar and (ItemInfo.SkinType = sknWindows)) or
|
||
(ItemInfo.SkinType = sknNone);
|
||
end;
|
||
|
||
function SpGetBoundsRect(IV: TTBItemViewer; Root: TTBRootItem): TRect;
|
||
// Returns the Bounds Rect of an ItemViewer.
|
||
// If the ItemViewer is a GroupItemViewer then it returns the sum
|
||
// of all the ItemViewers inside it.
|
||
var
|
||
G: TTBItemViewer;
|
||
V: TTBView;
|
||
I, J: Integer;
|
||
R: TRect;
|
||
FirstItemFound: Boolean;
|
||
begin
|
||
Result := Rect(0, 0, 0, 0);
|
||
if Assigned(IV) then
|
||
if IV.Item is TTBGroupItem then begin
|
||
// Sum all the ItemViewers of the GroupItem
|
||
V := IV.View;
|
||
J := IV.Index + 1;
|
||
FirstItemFound := False;
|
||
for I := J to V.ViewerCount - 1 do begin
|
||
G := V.Viewers[I];
|
||
if (G.Item.Parent = Root) then
|
||
Break
|
||
else
|
||
if G.Item.Visible and not (G.Item is TTBGroupItem) then
|
||
if not FirstItemFound then begin
|
||
FirstItemFound := True;
|
||
Result := G.BoundsRect;
|
||
end
|
||
else begin
|
||
R := G.BoundsRect;
|
||
Result.Left := Min(Result.Left, R.Left);
|
||
Result.Top := Min(Result.Top, R.Top);
|
||
Result.Right := Max(Result.Right, R.Right);
|
||
Result.Bottom := Max(Result.Bottom, R.Bottom);
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
Result := IV.BoundsRect;
|
||
end;
|
||
|
||
procedure SpGetAllItems(AParentItem: TTBCustomItem; ItemsList: TTntStringList; ClearFirst: Boolean = True);
|
||
// Returns a StringList with all the items, subitems and linked items from AParentItem.
|
||
// The ItemsList.Strings[] contains the items name
|
||
// The ItemsList.Objects[] contains the items reference
|
||
|
||
procedure Iterate(AParentItem: TTBCustomItem; LinkDepth: Integer);
|
||
var
|
||
I: Integer;
|
||
NewParentItem, Item: TTBCustomItem;
|
||
begin
|
||
NewParentItem := AParentItem;
|
||
if Assigned(NewParentItem.LinkSubitems) then begin
|
||
NewParentItem := NewParentItem.LinkSubitems;
|
||
Inc(LinkDepth);
|
||
if LinkDepth > 25 then
|
||
Exit; { prevent infinite link recursion }
|
||
end;
|
||
for I := 0 to NewParentItem.Count - 1 do begin
|
||
Item := NewParentItem.Items[I];
|
||
ItemsList.AddObject(Item.Name, Item);
|
||
Iterate(Item, LinkDepth);
|
||
end;
|
||
end;
|
||
|
||
begin
|
||
if ClearFirst then
|
||
ItemsList.Clear;
|
||
Iterate(AParentItem, 0);
|
||
end;
|
||
|
||
function SpGetMenuMaximumImageSize(View: TTBView): TSize;
|
||
// Iterates the viewers and returns the maximum image size
|
||
var
|
||
I: Integer;
|
||
IV: TTBItemViewer;
|
||
IL: TCustomImageList;
|
||
ImageShown: Boolean;
|
||
begin
|
||
Result.cx := 0;
|
||
Result.cy := 0;
|
||
for I := 0 to View.ViewerCount - 1 do begin
|
||
IV := View.Viewers[I];
|
||
if IV is TSpTBXItemViewer then
|
||
ImageShown := TSpTBXItemViewer(IV).GetImageShown
|
||
else
|
||
ImageShown := TTBItemViewerAccess(IV).ImageShown;
|
||
|
||
if ImageShown then begin
|
||
IL := TTBItemViewerAccess(IV).GetImageList;
|
||
if Assigned(IL) then begin
|
||
if IL.Width > Result.cx then
|
||
Result.cx := IL.Width;
|
||
if IL.Height > Result.cy then
|
||
Result.cy := IL.Height;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function SpGetItemViewerFromPoint(Root: TTBRootItem; View: TTBView; P: TPoint;
|
||
ProcessGroupItems: Boolean = True): TTBItemViewer;
|
||
// Returns the ItemViewer at the given position
|
||
// If ProcessGroupItems is true and the ItemViewer is on a GroupItem return
|
||
// the GroupItem's ItemViewer instead.
|
||
var
|
||
IV: TTBItemViewer;
|
||
I, X: Integer;
|
||
G: TTBItemViewer;
|
||
begin
|
||
Result := nil;
|
||
if Assigned(Root) and Assigned(View) then begin
|
||
IV := View.ViewerFromPoint(P);
|
||
|
||
// If the Item is not on the Root it must be part of a GroupItem
|
||
if ProcessGroupItems and Assigned(IV) and not (IV.Item is TTBChevronItem) and (IV.Item.Parent <> Root) then begin
|
||
// Get the parent GroupItem ItemViewer
|
||
X := IV.Index;
|
||
for I := X downto 0 do begin
|
||
G := IV.View.Viewers[I];
|
||
if G.Item is TTBGroupItem then begin
|
||
Result := G;
|
||
Break;
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
Result := IV;
|
||
end;
|
||
end;
|
||
|
||
function SpGetNextItemSameEdge(View: TTBView; IV: TTBItemViewer; GoForward: Boolean;
|
||
SearchType: TSpTBXSearchItemViewerType): TTBItemViewer;
|
||
// Returns the left or right Tab item depending on GoForward
|
||
// SearchType can be:
|
||
// sivtNormal: Normal search
|
||
// sivtInmediate: Search for the inmediate ItemViewer
|
||
// sivtInmediateSkipNonVisible: Search for the next inmediate ItemViewer, skipping non visible ones
|
||
var
|
||
Temp: TTBItemViewer;
|
||
I: Integer;
|
||
begin
|
||
Result := nil;
|
||
if IV = nil then
|
||
Result := View.NextSelectable(nil, GoForward)
|
||
else begin
|
||
View.ValidatePositions;
|
||
I := View.IndexOf(IV);
|
||
while not Assigned(Result) do begin
|
||
if GoForward then Inc(I)
|
||
else Dec(I);
|
||
|
||
if (I > View.ViewerCount - 1) or (I < 0) then
|
||
Break
|
||
else begin
|
||
Temp := View.Viewers[I];
|
||
// Skip non visible items, search for same edge items
|
||
if Temp.Item.Visible and (Temp.OffEdge = IV.OffEdge) and (Temp.BoundsRect.Top = IV.BoundsRect.Top) then begin
|
||
Result := Temp; // Found IV
|
||
Break;
|
||
end
|
||
else begin
|
||
case SearchType of
|
||
sivtInmediate:
|
||
Break; // Inmediate not found, exit
|
||
sivtInmediateSkipNonVisible:
|
||
if Temp.Item.Visible then Break; // Inmediate not found and visible, exit
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function SpGetFirstRightAlignSpacer(View: TTBView): TSpTBXItemViewer;
|
||
var
|
||
I: Integer;
|
||
IV: TTBItemViewer;
|
||
begin
|
||
Result := nil;
|
||
for I := 0 to View.ViewerCount - 1 do begin
|
||
IV := View.Viewers[I];
|
||
if IV.Item.Visible and (IV.Item is TSpTBXRightAlignSpacerItem) then
|
||
Result := IV as TSpTBXItemViewer;
|
||
end;
|
||
end;
|
||
|
||
function SpGetRightAlignedItems(View: TTBView; RightAlignedList: TList;
|
||
IsRotated: Boolean; out VisibleTotalWidth, RightAlignedTotalWidth: Integer): TSpTBXItemViewer;
|
||
|
||
function GetWidth(R: TRect): Integer;
|
||
begin
|
||
if IsRotated then
|
||
Result := R.Bottom - R.Top
|
||
else
|
||
Result := R.Right - R.Left;
|
||
end;
|
||
|
||
var
|
||
I: Integer;
|
||
IV: TTBItemViewer;
|
||
begin
|
||
Result := nil;
|
||
|
||
if Assigned(RightAlignedList) then
|
||
RightAlignedList.Clear;
|
||
VisibleTotalWidth := 0;
|
||
RightAlignedTotalWidth := 0;
|
||
|
||
for I := 0 to View.ViewerCount - 1 do begin
|
||
IV := View.Viewers[I];
|
||
if IV.Item.Visible then
|
||
VisibleTotalWidth := VisibleTotalWidth + GetWidth(IV.BoundsRect);
|
||
if not Assigned(Result) and (IV.Item.Visible) and (IV.Item is TSpTBXRightAlignSpacerItem) then
|
||
Result := IV as TSpTBXItemViewer;
|
||
if Assigned(Result) then begin
|
||
if Assigned(RightAlignedList) then
|
||
RightAlignedList.Add(IV);
|
||
RightAlignedTotalWidth := RightAlignedTotalWidth + GetWidth(IV.BoundsRect);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpInvalidateItem(View: TTBView; Item: TTBCustomItem);
|
||
var
|
||
IV: TTBItemViewer;
|
||
begin
|
||
IV := View.Find(Item);
|
||
if Assigned(IV) then View.Invalidate(IV);
|
||
end;
|
||
|
||
function SpFindItemViewer(View: TTBView; Item: TTBCustomItem): TTBItemViewer;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
Result := nil;
|
||
if Assigned(Item) then
|
||
for I := 0 to View.ViewerCount - 1 do
|
||
if View.Viewers[I].Item = Item then begin
|
||
Result := View.Viewers[I];
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
function SpFindControlItem(Item: TTBCustomItem; Ctl: TControl; Recurse: Boolean): TTBControlItem;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
Result := nil;
|
||
for I := 0 to Item.Count - 1 do begin
|
||
if Recurse and (Item[I] is TTBGroupItem) then begin
|
||
Result := SpFindControlItem(Item[I], Ctl, True);
|
||
if Assigned(Result) then
|
||
Break;
|
||
end;
|
||
if (Item[I] is TTBControlItem) and (TTBControlItem(Item[I]).Control = Ctl) then begin
|
||
Result := TTBControlItem(Item[I]);
|
||
Break;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpGetDropPosItemViewer(Root: TTBRootItem; View: TTBView; P: TPoint;
|
||
out DestIV: TTBItemViewer; out DestItemPos: Integer; out DropMark: TRect);
|
||
// Returns the ItemViewer and Item index at the given position for Drag & Drop
|
||
// operations that needs a DropMark rect.
|
||
// Use this when the items are dropped when the drag operation is finished.
|
||
var
|
||
DestR: TRect;
|
||
const
|
||
DropMarkSize = 4;
|
||
begin
|
||
DestItemPos := -1;
|
||
DestIV := SpGetItemViewerFromPoint(Root, View, P);
|
||
DropMark := Rect(0, 0, 0, 0);
|
||
if Assigned(DestIV) then begin
|
||
// Get the destination item position
|
||
DestItemPos := Root.IndexOf(DestIV.Item);
|
||
DestR := SpGetBoundsRect(DestIV, Root);
|
||
if View.Orientation = tbvoVertical then begin
|
||
if P.Y > ((DestR.Bottom - DestR.Top) div 2) + DestR.Top then begin
|
||
Inc(DestItemPos);
|
||
DropMark := Rect(0, DestR.Bottom, View.BaseSize.X, DestR.Bottom + DropMarkSize);
|
||
end
|
||
else
|
||
DropMark := Rect(0, DestR.Top, View.BaseSize.X, DestR.Top + DropMarkSize);
|
||
end
|
||
else
|
||
if P.X > ((DestR.Right - DestR.Left) div 2) + DestR.Left then begin
|
||
Inc(DestItemPos);
|
||
DropMark := Rect(DestR.Right, 0, DestR.Right + DropMarkSize, View.BaseSize.Y);
|
||
end
|
||
else
|
||
DropMark := Rect(DestR.Left, 0, DestR.Left + DropMarkSize, View.BaseSize.Y);
|
||
end;
|
||
end;
|
||
|
||
procedure SpGetDropPosItemViewer(Root: TTBRootItem; View: TTBView; P: TPoint;
|
||
SourceItemPos: Integer; out DestIV: TTBItemViewer; out DestItemPos: Integer);
|
||
// Returns the ItemViewer and Item index at the given position for inmediate
|
||
// Drag & Drop operations without a DropMark.
|
||
// Use this when the items are moved while the mouse is being dragged.
|
||
var
|
||
DestR: TRect;
|
||
begin
|
||
DestItemPos := -1;
|
||
DestIV := SpGetItemViewerFromPoint(Root, View, P);
|
||
if Assigned(DestIV) then begin
|
||
// Get the destination item position
|
||
DestItemPos := Root.IndexOf(DestIV.Item);
|
||
DestR := SpGetBoundsRect(DestIV, Root);
|
||
|
||
if View.Orientation = tbvoVertical then begin
|
||
if P.Y > ((DestR.Bottom - DestR.Top) div 2) + DestR.Top then begin
|
||
if DestItemPos - 1 <> SourceItemPos then Inc(DestItemPos);
|
||
end
|
||
else begin
|
||
if DestItemPos - 1 = SourceItemPos then Dec(DestItemPos);
|
||
end;
|
||
end
|
||
else
|
||
if P.X > ((DestR.Right - DestR.Left) div 2) + DestR.Left then begin
|
||
if DestItemPos - 1 <> SourceItemPos then Inc(DestItemPos);
|
||
end
|
||
else begin
|
||
if DestItemPos - 1 = SourceItemPos then Dec(DestItemPos);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function SpGetDragHandleSize(Toolbar: TTBCustomDockableWindow): Integer;
|
||
const
|
||
DragHandleSizes: array [Boolean, 0..2] of Integer = ((9, 0, 6), (14, 14, 14));
|
||
var
|
||
T: TTBCustomDockableWindowAccess;
|
||
begin
|
||
Result := 0;
|
||
if Assigned(Toolbar.CurrentDock) then
|
||
if Toolbar.CurrentDock.AllowDrag then begin
|
||
T := TTBCustomDockableWindowAccess(Toolbar);
|
||
Result := DragHandleSizes[T.CloseButtonWhenDocked, Ord(T.DragHandleStyle)]
|
||
end;
|
||
end;
|
||
|
||
function SpIsVerticalToolbar(Toolbar: TTBCustomDockableWindow): Boolean;
|
||
begin
|
||
if Assigned(Toolbar.CurrentDock) then
|
||
Result := Toolbar.CurrentDock.Position in [dpLeft, dpRight]
|
||
else
|
||
Result := False;
|
||
end;
|
||
|
||
function SpIsDockUsingBitmap(Dock: TTBDock): Boolean;
|
||
var
|
||
Background: TTBBasicBackgroundAccess;
|
||
begin
|
||
Background := TTBBasicBackgroundAccess(Dock.Background);
|
||
Result := Assigned(Background) and Background.UsingBackground;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ Painting helpers }
|
||
|
||
procedure SpDrawXPToolbarButton(ACanvas: TCanvas; ARect: TRect; State: TSpTBXSkinStatesType;
|
||
SkinType: TSpTBXSkinType; ComboPart: TSpTBXComboPart = cpNone);
|
||
// Paints a toolbar button depending on the State and SkinType
|
||
var
|
||
Flags: Integer;
|
||
ForceRectBorders: TAnchors;
|
||
const
|
||
XPPart: array [TSpTBXComboPart] of Integer = (TP_BUTTON, TP_DROPDOWNBUTTON,
|
||
TP_SPLITBUTTON, TP_SPLITBUTTONDROPDOWN);
|
||
begin
|
||
case SkinType of
|
||
sknNone:
|
||
begin
|
||
case State of
|
||
sknsNormal, sknsDisabled: ; // Do nothing
|
||
sknsHotTrack:
|
||
Windows.DrawEdge(ACanvas.Handle, ARect, BDR_RAISEDINNER, BF_RECT);
|
||
sknsPushed, sknsCheckedAndHotTrack:
|
||
Windows.DrawEdge(ACanvas.Handle, ARect, BDR_SUNKENOUTER, BF_RECT);
|
||
sknsChecked:
|
||
begin
|
||
ACanvas.Brush.Bitmap := AllocPatternBitmap(clBtnFace, clBtnHighlight);;
|
||
ACanvas.Brush.Bitmap.HandleType := bmDDB; // Needed for Win95, or else brush is solid white
|
||
ACanvas.FillRect(ARect);
|
||
ACanvas.Brush.Style := bsClear;
|
||
Windows.DrawEdge(ACanvas.Handle, ARect, BDR_SUNKENOUTER, BF_RECT);
|
||
end;
|
||
end;
|
||
end;
|
||
sknWindows:
|
||
begin
|
||
Flags := TS_NORMAL;
|
||
case State of
|
||
sknsDisabled: Flags := TS_DISABLED;
|
||
sknsHotTrack: Flags := TS_HOT;
|
||
sknsPushed: Flags := TS_PRESSED;
|
||
sknsChecked: Flags := TS_CHECKED;
|
||
sknsCheckedAndHotTrack: Flags := TS_HOTCHECKED;
|
||
end;
|
||
DrawThemeBackground(ThemeServices.Theme[teToolBar], ACanvas.Handle, XPPart[ComboPart], Flags, ARect, nil);
|
||
end;
|
||
sknSkin:
|
||
begin
|
||
ForceRectBorders := [];
|
||
if ComboPart = cpSplitLeft then ForceRectBorders := [akRight]
|
||
else
|
||
if ComboPart = cpSplitRight then ForceRectBorders := [akLeft];
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncToolbarItem, State, True, True, False, ForceRectBorders);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo);
|
||
// Paints a menu or toolbar item depending on the ItemInfo
|
||
|
||
procedure ToolbarItemDraw(ARect: TRect);
|
||
var
|
||
ForceRectBorders: TAnchors;
|
||
Flags: Integer;
|
||
begin
|
||
ForceRectBorders := [];
|
||
if ItemInfo.IsSplit then
|
||
if ItemInfo.ComboPart = cpSplitLeft then ForceRectBorders := [akRight]
|
||
else
|
||
if ItemInfo.ComboPart = cpSplitRight then ForceRectBorders := [akLeft];
|
||
|
||
case ItemInfo.SkinType of
|
||
sknNone:
|
||
begin
|
||
if ItemInfo.Checked then
|
||
if not ItemInfo.HotTrack or (not ItemInfo.Enabled and ItemInfo.ToolbarStyle) then
|
||
ItemInfo.State := sknsChecked; // Paint Disabled&Checked as Checked
|
||
|
||
if ItemInfo.State = sknsNormal then begin
|
||
if ItemInfo.IsDesigning then
|
||
Windows.DrawEdge(ACanvas.Handle, ARect, BDR_RAISEDINNER, BF_RECT);
|
||
end
|
||
else
|
||
SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.SkinType, ItemInfo.ComboPart);
|
||
end;
|
||
sknWindows:
|
||
if ItemInfo.IsDesigning then
|
||
SpDrawRectangle(ACanvas, ARect, 2, clBtnShadow, clBtnShadow, clNone, clNone, ForceRectBorders)
|
||
else
|
||
if ItemInfo.IsOnMenuBar then begin
|
||
if SpIsWinVistaOrUp then begin
|
||
// Use the new API on Windows Vista
|
||
Flags := MBI_NORMAL;
|
||
case ItemInfo.State of
|
||
sknsDisabled: Flags := MBI_DISABLED;
|
||
sknsHotTrack: Flags := MBI_HOT;
|
||
sknsPushed: Flags := MBI_PUSHED;
|
||
end;
|
||
|
||
DrawThemeBackground(ThemeServices.Theme[teMenu], ACanvas.Handle, MENU_BARITEM, Flags, ARect, nil);
|
||
end
|
||
else
|
||
if ItemInfo.State in [sknsHotTrack, sknsPushed, sknsChecked, sknsCheckedAndHotTrack] then
|
||
SpFillRect(ACanvas, ARect, clHighlight);
|
||
end
|
||
else
|
||
SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.SkinType, ItemInfo.ComboPart);
|
||
sknSkin:
|
||
if ItemInfo.IsOpen and CurrentSkin.OfficePopup then begin
|
||
// Paints skncOpenToolbarItem skin, hide the bottom border
|
||
ARect.Bottom := ARect.Bottom + 2;
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncOpenToolbarItem, sknsNormal, True, True)
|
||
end
|
||
else
|
||
if ItemInfo.IsDesigning then
|
||
SpDrawRectangle(ACanvas, ARect, 2, clBtnShadow, clBtnShadow, clNone, clNone, ForceRectBorders)
|
||
else
|
||
if ItemInfo.IsOnMenuBar then
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncMenuBarItem, ItemInfo.State, True, True, False, ForceRectBorders)
|
||
else
|
||
SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.SkinType, ItemInfo.ComboPart);
|
||
end;
|
||
end;
|
||
|
||
procedure MenuItemDraw(ARect: TRect);
|
||
var
|
||
Flags: Integer;
|
||
begin
|
||
case ItemInfo.SkinType of
|
||
sknNone:
|
||
SpFillRect(ACanvas, ARect, clHighlight);
|
||
sknWindows:
|
||
if SpIsWinVistaOrUp then begin
|
||
// Use the new API on Windows Vista
|
||
if ItemInfo.Enabled then Flags := MPI_HOT
|
||
else Flags := MPI_DISABLEDHOT;
|
||
DrawThemeBackground(ThemeServices.Theme[teMenu], ACanvas.Handle, MENU_POPUPITEM, Flags, ARect, nil);
|
||
end
|
||
else
|
||
SpFillRect(ACanvas, ARect, clHighlight);
|
||
sknSkin:
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncMenuItem, sknsHotTrack, True, True);
|
||
end;
|
||
end;
|
||
|
||
var
|
||
R: TRect;
|
||
DrawCheckBoxFrame: Boolean;
|
||
C: TColor;
|
||
SelectionDelta: Integer;
|
||
Flags: Integer;
|
||
begin
|
||
if ItemInfo.ToolbarStyle then begin // Toolbar Item
|
||
if ItemInfo.IsSplit then begin
|
||
if ItemInfo.IsOpen and CurrentSkin.OfficePopup then begin
|
||
// If it's Split, Open and OfficePopup paint the skncOpenToolbarItem skin
|
||
ARect.Right := ItemInfo.ComboRect.Right;
|
||
ToolbarItemDraw(ARect);
|
||
end
|
||
else begin
|
||
// Draw the left side button
|
||
if (ItemInfo.SkinType = sknSkin) or ItemInfo.IsDesigning then
|
||
Inc(ARect.Right, 2);
|
||
ItemInfo.ComboPart := cpSplitLeft;
|
||
ToolbarItemDraw(ARect);
|
||
|
||
// Draw the right side button
|
||
ItemInfo.ComboPart := cpSplitRight;
|
||
ItemInfo.State := ItemInfo.ComboState;
|
||
ToolbarItemDraw(ItemInfo.ComboRect);
|
||
end;
|
||
end
|
||
else
|
||
ToolbarItemDraw(ARect);
|
||
end
|
||
else begin // Menu item
|
||
// DrawCheckBoxFrame is true when the item is checked
|
||
if (ItemInfo.SkinType = sknSkin) or (SpIsWinVistaOrUp and (ItemInfo.SkinType = sknWindows)) then
|
||
DrawCheckBoxFrame := ItemInfo.Enabled and ItemInfo.Checked
|
||
else begin
|
||
if ItemInfo.SkinType = sknNone then
|
||
DrawCheckBoxFrame := ItemInfo.Checked or ItemInfo.ImageOrCheckShown
|
||
else
|
||
DrawCheckBoxFrame := ItemInfo.Enabled and (ItemInfo.Checked or ItemInfo.ImageOrCheckShown);
|
||
end;
|
||
|
||
R := ARect;
|
||
|
||
// Draw the item selection rectangle hottrack
|
||
// Office doesn't draw the hottrack when the item is disabled, check
|
||
// if OfficeMenu is set.
|
||
if ItemInfo.Enabled or not CurrentSkin.OfficeMenu then
|
||
if ItemInfo.HotTrack then begin
|
||
if DrawCheckBoxFrame then begin
|
||
SelectionDelta := 0;
|
||
case ItemInfo.SkinType of
|
||
sknNone:
|
||
SelectionDelta := ItemInfo.MenuMargins.GutterSize + 1; // Don't draw the hottrack selection behind the checkbox
|
||
sknWindows:
|
||
if not SpIsWinVistaOrUp then
|
||
SelectionDelta := ItemInfo.MenuMargins.GutterSize + 1; // Don't draw the hottrack selection behind the checkbox
|
||
sknSkin:
|
||
SelectionDelta := 3; // Don't draw the hottrack selection behind the checkbox left borders
|
||
end;
|
||
Inc(R.Left, SelectionDelta);
|
||
end;
|
||
MenuItemDraw(R);
|
||
end;
|
||
|
||
// Draw the checkbox frame (the checkbox glyph is painted in the ItemViewer.Paint method)
|
||
if DrawCheckBoxFrame then begin
|
||
R := ARect;
|
||
R.Right := R.Left + ItemInfo.MenuMargins.GutterSize;
|
||
if SpIsWinVistaOrUp and (ItemInfo.SkinType = sknWindows) then begin
|
||
// Use the new API on Windows Vista
|
||
// The checkbox frame is not painted
|
||
if ItemInfo.State = sknsDisabled then Flags := MCB_DISABLED
|
||
else if ItemInfo.ImageShown then Flags := MCB_BITMAP
|
||
else Flags := MCB_NORMAL;
|
||
DrawThemeBackground(ThemeServices.Theme[teMenu], ACanvas.Handle, MENU_POPUPCHECKBACKGROUND, Flags, R, nil);
|
||
end
|
||
else
|
||
if ItemInfo.SkinType = sknSkin then
|
||
CurrentSkin.PaintBackground(ACanvas, R, skncMenuItem, ItemInfo.State, True, True)
|
||
else
|
||
ToolbarItemDraw(R);
|
||
end;
|
||
|
||
// Draw the combo item separator
|
||
if ItemInfo.IsSplit then begin
|
||
if ItemInfo.SkinType = sknSkin then begin
|
||
C := SkinManager.CurrentSkin.Options(skncMenuItem, ItemInfo.State).Borders.Color1;
|
||
if C = clNone then
|
||
C := clBtnShadow;
|
||
end
|
||
else
|
||
C := clBtnShadow;
|
||
R := ARect;
|
||
R.Left := ARect.Right - 10 - 4;
|
||
SpDrawLine(ACanvas, R.Left, R.Top + 1, R.Left, R.Bottom - 1, C);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPMenuSeparator(ACanvas: TCanvas; ARect: TRect; MenuItemStyle, Vertical: Boolean);
|
||
const
|
||
ToolbarXPFlags: array [Boolean] of Integer = (TP_SEPARATORVERT, TP_SEPARATOR);
|
||
var
|
||
R: TRect;
|
||
C: TColor;
|
||
D: Integer;
|
||
VistaSeparatorSize: tagSize;
|
||
begin
|
||
R := ARect;
|
||
case SkinManager.GetSkinType of
|
||
sknNone:
|
||
if not Vertical then begin
|
||
R.Top := (R.Top + R.Bottom) div 2 - 1;
|
||
DrawEdge(ACanvas.Handle, R, EDGE_ETCHED, BF_TOP);
|
||
end
|
||
else begin
|
||
R.Left := (R.Left + R.Right) div 2 - 1;
|
||
DrawEdge(ACanvas.Handle, R, EDGE_ETCHED, BF_LEFT);
|
||
end;
|
||
sknWindows:
|
||
if MenuItemStyle and SpIsWinVistaOrUp then begin
|
||
// Use the new API in Windows Vista
|
||
GetThemePartSize(ThemeServices.Theme[teMenu], 0, MENU_POPUPSEPARATOR, 0, nil, TS_TRUE, VistaSeparatorSize);
|
||
R := SpCenterRectVert(R, VistaSeparatorSize.cy);
|
||
DrawThemeBackground(ThemeServices.Theme[teMenu], ACanvas.Handle, MENU_POPUPSEPARATOR, 0, R, nil);
|
||
end
|
||
else begin
|
||
if MenuItemStyle then begin
|
||
D := 0;
|
||
if Vertical then begin
|
||
R.Left := (R.Left + R.Right) div 2 - 1;
|
||
Inc(R.Top, D); Dec(R.Bottom, D);
|
||
Windows.DrawEdge(ACanvas.Handle, R, EDGE_ETCHED, BF_LEFT);
|
||
end
|
||
else begin
|
||
R.Top := (R.Top + R.Bottom) div 2 - 1;
|
||
Inc(R.Left, D); Dec(R.Right, D);
|
||
Windows.DrawEdge(ACanvas.Handle, R, EDGE_ETCHED, BF_TOP);
|
||
end;
|
||
end
|
||
else
|
||
DrawThemeBackground(ThemeServices.Theme[teToolbar], ACanvas.Handle, ToolbarXPFlags[Vertical], TS_NORMAL, R, nil);
|
||
end;
|
||
sknSkin:
|
||
if not Vertical then begin
|
||
// ??? what happens when 2 items have different imagelist sizes? how is the gutter measured?
|
||
R.Top := (R.Bottom + R.Top) div 2 - 1;
|
||
R.Bottom := R.Top;
|
||
C := SkinManager.CurrentSkin.Options(skncSeparator, sknsNormal).Body.Color1;
|
||
SpDrawLine(ACanvas, R.Left, R.Top, R.Right, R.Bottom, C);
|
||
OffsetRect(R, 0, 1);
|
||
C := SkinManager.CurrentSkin.Options(skncSeparator, sknsNormal).Body.Color2;
|
||
SpDrawLine(ACanvas, R.Left, R.Top, R.Right, R.Bottom, C);
|
||
end
|
||
else begin
|
||
R.Left := (R.Right + R.Left) div 2 - 1;
|
||
R.Right := R.Left;
|
||
InflateRect(R, 0, -3);
|
||
C := SkinManager.CurrentSkin.Options(skncSeparator, sknsNormal).Body.Color1;
|
||
SpDrawLine(ACanvas, R.Left, R.Top, R.Right, R.Bottom, C);
|
||
OffsetRect(R, 1, 0);
|
||
C := SkinManager.CurrentSkin.Options(skncSeparator, sknsNormal).Body.Color2;
|
||
SpDrawLine(ACanvas, R.Left, R.Top, R.Right, R.Bottom, C);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPMenuItemImage(ACanvas: TCanvas; ARect: TRect;
|
||
const ItemInfo: TSpTBXMenuItemInfo; ImageList: TCustomImageList; ImageIndex: Integer);
|
||
begin
|
||
if ImageList is TTBCustomImageList then begin
|
||
if ItemInfo.IsSunkenCaption then
|
||
OffsetRect(ARect, 1, 1);
|
||
TTBCustomImageList(ImageList).DrawState(ACanvas, ARect.Left, ARect.Top,
|
||
ImageIndex, ItemInfo.Enabled, ItemInfo.HotTrack, ItemInfo.Checked);
|
||
Exit;
|
||
end;
|
||
|
||
if ItemInfo.Enabled and SkinManager.CurrentSkin.OfficeIcons then begin
|
||
// Draw icon shadow
|
||
if ItemInfo.HotTrack and not ItemInfo.Pushed then begin
|
||
OffsetRect(ARect, 1, 1);
|
||
SpDrawIconShadow(ACanvas, ARect, ImageList, ImageIndex);
|
||
OffsetRect(ARect, -2, -2);
|
||
end;
|
||
SpDrawImageList(ACanvas, ARect, ImageList, ImageIndex, ItemInfo.Enabled, True);
|
||
end
|
||
else begin
|
||
if ItemInfo.IsSunkenCaption then
|
||
OffsetRect(ARect, 1, 1);
|
||
SpDrawImageList(ACanvas, ARect, ImageList, ImageIndex, ItemInfo.Enabled, True);
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPMenuGutter(ACanvas: TCanvas; ARect: TRect; SkinType: TSpTBXSkinType);
|
||
var
|
||
Op: TSpTBXSkinOptionCategory;
|
||
C: TColor;
|
||
begin
|
||
SkinType := SpTBXSkinType(SkinType);
|
||
// If it's Windows theme and we're not on Vista do default painting
|
||
if (SkinType = sknWindows) and not SpIsWinVistaOrUp then
|
||
SkinType := sknNone;
|
||
|
||
case SkinType of
|
||
sknNone:; // No gutter on Windows 9x, 2000
|
||
sknWindows:
|
||
begin
|
||
// Only Windows Vista painting, XP just fills the background
|
||
if SpIsWinVistaOrUp then
|
||
DrawThemeBackground(ThemeServices.Theme[teMenu], ACanvas.Handle, MENU_POPUPGUTTER, 0, ARect, nil);
|
||
end;
|
||
sknSkin:
|
||
begin
|
||
Op := CurrentSkin.Options(skncGutter, sknsNormal);
|
||
if not Op.Body.IsEmpty then
|
||
SpPaintSkinBackground(ACanvas, ARect, Op, False);
|
||
|
||
// Paint only the right side border, like a Separator line
|
||
ARect.Left := ARect.Right;
|
||
C := Op.Borders.Color2;
|
||
if C <> clNone then begin
|
||
SpDrawLine(ACanvas, ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, C);
|
||
OffsetRect(ARect, -1, 0);
|
||
end;
|
||
C := Op.Borders.Color1;
|
||
if C <> clNone then
|
||
SpDrawLine(ACanvas, ARect.Left, ARect.Top, ARect.Right, ARect.Bottom, C);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPMenuPopupWindow(ACanvas: TCanvas; ARect, OpenIVRect: TRect;
|
||
DrawGutter: Boolean; ImageSize: Integer; SkinType: TSpTBXSkinType);
|
||
var
|
||
GutterR: TRect;
|
||
MarginsInfo: TSpTBXMenuItemMarginsInfo;
|
||
SaveIndex: Integer;
|
||
begin
|
||
SkinType := SpTBXSkinType(SkinType);
|
||
// If it's Windows theme and we're not on Vista do default painting
|
||
if (SkinType = sknWindows) and not SpIsWinVistaOrUp then
|
||
SkinType := sknNone;
|
||
|
||
case SkinType of
|
||
sknNone: // Windows 9x, 2000 and XP
|
||
if not AreFlatMenusEnabled then begin
|
||
DrawEdge(ACanvas.Handle, ARect, EDGE_RAISED, BF_RECT or BF_ADJUST);
|
||
SpFillRect(ACanvas, ARect, clBtnFace);
|
||
end
|
||
else
|
||
SpFillRect(ACanvas, ARect, clMenu, clBtnShadow);
|
||
sknWindows: // Only Windows Vista painting, XP just fills the background
|
||
begin
|
||
// Use the new API in Windows Vista
|
||
DrawThemeBackground(ThemeServices.Theme[teMenu], ACanvas.Handle, MENU_POPUPBACKGROUND, 0, ARect, nil);
|
||
|
||
// Now paint the borders, clip the background
|
||
SaveIndex := SaveDC(ACanvas.Handle);
|
||
try
|
||
ExcludeClipRect(ACanvas.Handle, ARect.Left + 2, ARect.Top + 2, ARect.Right - 2, ARect.Bottom - 2);
|
||
DrawThemeBackground(ThemeServices.Theme[teMenu], ACanvas.Handle, MENU_POPUPBORDERS, 0, ARect, nil);
|
||
finally
|
||
RestoreDC(ACanvas.Handle, SaveIndex);
|
||
end;
|
||
|
||
// Paint the gutter
|
||
if DrawGutter then begin
|
||
CurrentSkin.GetMenuItemMargins(ACanvas, ImageSize, MarginsInfo);
|
||
GutterR := ARect;
|
||
InflateRect(GutterR, -1, -4);
|
||
GutterR.Right := GutterR.Left + MarginsInfo.GutterSize + MarginsInfo.LeftCaptionMargin + 1 + 4; // +1 because the popup has 2 pixel border, and +4 gutter separator has 4 pixel spacing
|
||
SpDrawXPMenuGutter(ACanvas, GutterR, SkinType);
|
||
end;
|
||
end;
|
||
sknSkin:
|
||
begin
|
||
// Paint the background, if OfficePopup is true just clip the top
|
||
// border corresponding to the Open ItemViewer Rect
|
||
if OpenIVRect.Top < 0 then begin
|
||
OpenIVRect.Top := ARect.Top;
|
||
OpenIVRect.Bottom := ARect.Top + 1;
|
||
InflateRect(OpenIVRect, -1, 0);
|
||
|
||
// First paint the background
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncPopup, sknsNormal, True, False);
|
||
// Now paint the borders, clip the top border
|
||
SaveIndex := SaveDC(ACanvas.Handle);
|
||
try
|
||
ExcludeClipRect(ACanvas.Handle, OpenIVRect.Left, OpenIVRect.Top, OpenIVRect.Right, OpenIVRect.Bottom);
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncPopup, sknsNormal, False, True);
|
||
finally
|
||
RestoreDC(ACanvas.Handle, SaveIndex);
|
||
end;
|
||
end
|
||
else
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncPopup, sknsNormal, True, True);
|
||
|
||
// Paint the gutter
|
||
if DrawGutter and not CurrentSkin.Options(skncGutter, sknsNormal).IsEmpty then begin
|
||
if ImageSize <= 0 then ImageSize := 16;
|
||
CurrentSkin.GetMenuItemMargins(ACanvas, ImageSize, MarginsInfo);
|
||
GutterR := ARect;
|
||
InflateRect(GutterR, -1, -1);
|
||
GutterR.Right := GutterR.Left + MarginsInfo.GutterSize + MarginsInfo.LeftCaptionMargin + 1; // +1 because the popup has 2 pixel border
|
||
SpDrawXPMenuGutter(ACanvas, GutterR, SkinType);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPStatusBar(ACanvas: TCanvas; ARect, AGripRect: TRect; SkinType: TSpTBXSkinType);
|
||
var
|
||
R: TRect;
|
||
C1, C2: TColor;
|
||
begin
|
||
case SpTBXSkinType(SkinType) of
|
||
sknNone:
|
||
begin
|
||
if not IsRectEmpty(ARect) then begin
|
||
SpFillRect(ACanvas, ARect, clBtnFace);
|
||
SpDrawRectangle(ACanvas, ARect, 0, clBtnShadow, clWindow);
|
||
end;
|
||
if not IsRectEmpty(AGripRect) then begin
|
||
InflateRect(AGripRect, 0, -1);
|
||
DrawFrameControl(ACanvas.Handle, AGripRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
|
||
end;
|
||
end;
|
||
sknWindows:
|
||
begin
|
||
if not IsRectEmpty(ARect) then
|
||
DrawThemeBackground(ThemeServices.Theme[teStatus], ACanvas.Handle, 0, 0, ARect, nil);
|
||
if not IsRectEmpty(AGripRect) then
|
||
DrawThemeBackground(ThemeServices.Theme[teStatus], ACanvas.Handle, SP_GRIPPER, 0, AGripRect, nil)
|
||
end;
|
||
sknSkin:
|
||
begin
|
||
if not IsRectEmpty(ARect) then
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncStatusBar, sknsNormal, True, True);
|
||
if not IsRectEmpty(AGripRect) then begin
|
||
R := AGripRect;
|
||
C1 := SkinManager.CurrentSkin.Options(skncStatusBarGrip).Body.Color1;
|
||
C2 := SkinManager.CurrentSkin.Options(skncStatusBarGrip).Body.Color2;
|
||
// Draw 3 cells at the bottom
|
||
R.Left := R.Right - 12;
|
||
R.Top := R.Bottom - 4;
|
||
SpDrawXPGrip(ACanvas, R, C1, C2);
|
||
// Draw 2 cells at the top
|
||
R.Bottom := R.Top;
|
||
R.Top := R.Bottom - 4;
|
||
R.Left := R.Left + 4;
|
||
SpDrawXPGrip(ACanvas, R, C1, C2);
|
||
// Draw 1 cell at the top
|
||
R.Bottom := R.Top;
|
||
R.Top := R.Bottom - 4;
|
||
R.Left := R.Left + 4;
|
||
SpDrawXPGrip(ACanvas, R, C1, C2);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean; DrawBorders: Boolean = True);
|
||
const
|
||
XpFlags: array [Boolean] of Integer = (FS_INACTIVE, FS_ACTIVE);
|
||
W9xFlags: array [Boolean] of Integer = (0, DC_ACTIVE);
|
||
W9xGradientFlag: array [Boolean] of Integer = (0, DC_GRADIENT);
|
||
var
|
||
Gradient: Boolean;
|
||
B: BOOL;
|
||
begin
|
||
case SkinManager.GetSkinType of
|
||
sknNone:
|
||
begin
|
||
Gradient := SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, @B, 0) and B;
|
||
Windows.DrawCaption(GetDesktopWindow, ACanvas.Handle, ARect, DC_TEXT or W9xFlags[IsActive] or W9xGradientFlag[Gradient]);
|
||
end;
|
||
sknWindows:
|
||
// If WP_CAPTION is used instead of WP_SMALLCAPTION the top borders are rounded
|
||
DrawThemeBackground(ThemeServices.Theme[teWindow], ACanvas.Handle, WP_SMALLCAPTION, XpFlags[IsActive], ARect, nil);
|
||
sknSkin:
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncWindowTitleBar, sknsNormal, True, DrawBorders);
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPTitleBarBody(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean;
|
||
BorderSize: TPoint; DrawBody: Boolean = True);
|
||
var
|
||
R, MirrorR: TRect;
|
||
SaveIndex, Flags: Integer;
|
||
B: TBitmap;
|
||
begin
|
||
case SkinManager.GetSkinType of
|
||
sknNone:
|
||
begin
|
||
if DrawBody then
|
||
ACanvas.FillRect(ARect);
|
||
SaveIndex := SaveDC(ACanvas.Handle);
|
||
try
|
||
R := ARect;
|
||
InflateRect(R, -BorderSize.X, -BorderSize.Y);
|
||
ExcludeClipRect(ACanvas.Handle, R.Left, R.Top, R.Right, R.Bottom);
|
||
if not DrawBody then
|
||
ACanvas.FillRect(ARect);
|
||
Windows.DrawEdge(ACanvas.Handle, ARect, EDGE_RAISED, BF_RECT);
|
||
finally
|
||
RestoreDC(ACanvas.Handle, SaveIndex);
|
||
end;
|
||
end;
|
||
sknWindows:
|
||
begin
|
||
if IsActive then
|
||
Flags := FS_ACTIVE
|
||
else
|
||
Flags := FS_INACTIVE;
|
||
R := ARect;
|
||
R.Top := R.Bottom - BorderSize.Y;
|
||
DrawThemeBackground(ThemeServices.Theme[teWindow], ACanvas.Handle, WP_SMALLFRAMEBOTTOM, Flags, R, nil);
|
||
R.Top := ARect.Top + BorderSize.Y;
|
||
R.Bottom := ARect.Bottom - BorderSize.Y;
|
||
R.Right := R.Left + BorderSize.X;
|
||
DrawThemeBackground(ThemeServices.Theme[teWindow], ACanvas.Handle, WP_SMALLFRAMELEFT, Flags, R, nil);
|
||
R.Right := ARect.Right;
|
||
R.Left := R.Right - BorderSize.X;
|
||
DrawThemeBackground(ThemeServices.Theme[teWindow], ACanvas.Handle, WP_SMALLFRAMERIGHT, Flags, R, nil);
|
||
|
||
// Don't know how to paint a captionless window frame
|
||
// We have to mirror the bottom frame and paint it on the top
|
||
B := TBitmap.Create;
|
||
try
|
||
R := ARect;
|
||
R.Bottom := R.Top + BorderSize.Y;
|
||
B.Width := R.Right - R.Left;
|
||
B.Height := R.Bottom - R.Top;
|
||
DrawThemeBackground(ThemeServices.Theme[teWindow], B.Canvas.Handle, WP_SMALLFRAMEBOTTOM, Flags, R, nil);
|
||
|
||
// Mirror
|
||
MirrorR := Rect(0, B.Height - 1, B.Width, -1);
|
||
ACanvas.CopyRect(R, B.Canvas, MirrorR);
|
||
finally
|
||
B.Free;
|
||
end;
|
||
end;
|
||
sknSkin:
|
||
begin
|
||
CurrentSkin.PaintWindowFrame(ACanvas, ARect, IsActive, DrawBody, BorderSize.X);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPDock(ACanvas: TCanvas; ARect: TRect; SkinType: TSpTBXSkinType; Vertical: Boolean = False);
|
||
begin
|
||
SkinType := SpTBXSkinType(SkinType);
|
||
case SkinType of
|
||
sknNone:
|
||
begin
|
||
ACanvas.Brush.Color := clBtnFace;
|
||
ACanvas.FillRect(ARect);
|
||
end;
|
||
sknWindows:
|
||
begin
|
||
if Vertical then Inc(ARect.Bottom, 1); // Fix WindowsXP bug
|
||
DrawThemeBackground(ThemeServices.Theme[teRebar], ACanvas.Handle, 0, 0, ARect, nil);
|
||
end;
|
||
sknSkin:
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncDock, sknsNormal, True, True, Vertical);
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPToolbar(ACanvas: TCanvas; ARect: TRect; SkinType: TSpTBXSkinType;
|
||
Docked, Floating, Vertical, PaintSkinBackground, PaintBorders: Boolean;
|
||
SkinComponent: TSpTBXSkinComponentsType = skncToolbar);
|
||
begin
|
||
SkinType := SpTBXSkinType(SkinType);
|
||
case SkinType of
|
||
sknNone:
|
||
if PaintBorders and Docked then
|
||
Windows.DrawEdge(ACanvas.Handle, ARect, BDR_RAISEDINNER, BF_RECT or BF_ADJUST);
|
||
sknWindows:
|
||
if PaintBorders and Docked then
|
||
SpDrawRectangle(ACanvas, ARect, 0, SpLighten(clBtnFace, 24), SpLighten(clBtnFace, -32));
|
||
sknSkin:
|
||
if Docked or Floating then begin
|
||
if Floating and CurrentSkin.Options(SkinComponent, sknsNormal).Body.IsEmpty then // Floating and doesn't have a Body
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, skncDock, sknsNormal, True, False)
|
||
else begin
|
||
if Floating then PaintBorders := False;
|
||
CurrentSkin.PaintBackground(ACanvas, ARect, SkinComponent, sknsNormal, PaintSkinBackground, PaintBorders, Vertical);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPToolbar(W: TTBCustomDockableWindow; ACanvas: TCanvas;
|
||
ARect: TRect; PaintOnNCArea: Boolean; PaintBorders: Boolean = True;
|
||
SkinComponent: TSpTBXSkinComponentsType = skncToolbar);
|
||
var
|
||
R: TRect;
|
||
PaintDefault, DrawSkinBody: Boolean;
|
||
Toolbar: TTBCustomDockableWindowAccess;
|
||
IsVertical: Boolean;
|
||
begin
|
||
if CurrentSkin.Options(SkinComponent, sknsNormal).Body.IsEmpty then
|
||
SkinComponent := skncToolbar;
|
||
|
||
Toolbar := TTBCustomDockableWindowAccess(W);
|
||
IsVertical := SpIsVerticalToolbar(Toolbar);
|
||
DrawSkinBody := True;
|
||
|
||
if Toolbar.Docked then begin
|
||
// Prepare R
|
||
R := Toolbar.CurrentDock.ClientRect;
|
||
OffsetRect(R, -Toolbar.Left, -Toolbar.Top);
|
||
if not PaintOnNCArea then begin
|
||
if W is TSpTBXToolbar then
|
||
OffsetRect(R, -TSpTBXToolbar(W).DefaultToolbarBorderSize, -TSpTBXToolbar(W).DefaultToolbarBorderSize)
|
||
else
|
||
OffsetRect(R, -CDefaultToolbarBorderSize, -CDefaultToolbarBorderSize);
|
||
if IsVertical then
|
||
Dec(R.Top, SpGetDragHandleSize(Toolbar))
|
||
else
|
||
Dec(R.Left, SpGetDragHandleSize(Toolbar));
|
||
end;
|
||
// Draw the Dock background
|
||
if Toolbar.CurrentDock is TSpTBXDock then
|
||
TSpTBXDock(Toolbar.CurrentDock).DrawBackground(ACanvas.Handle, R);
|
||
|
||
DrawSkinBody := not (Toolbar.CurrentDock.BackgroundOnToolbars and SpIsDockUsingBitmap(Toolbar.CurrentDock));
|
||
end
|
||
else begin
|
||
if Toolbar.Floating then begin
|
||
if SkinManager.GetSkinType <> sknSkin then begin
|
||
if Toolbar.Color = clNone then ACanvas.Brush.Color := clBtnFace
|
||
else ACanvas.Brush.Color := Toolbar.Color;
|
||
ACanvas.FillRect(ARect);
|
||
end;
|
||
end
|
||
else begin
|
||
// Draw the parent background if the toolbar is not docked nor floating
|
||
// SpDrawParentBackground doesn't seem to work correctly here
|
||
// (when a toolbar is inside a toolwindow), use PerformEraseBackground instead
|
||
Controls.PerformEraseBackground(Toolbar, ACanvas.Handle);
|
||
end;
|
||
end;
|
||
|
||
// Default painting
|
||
PaintDefault := True;
|
||
if W is TSpTBXToolbar then begin
|
||
if TSpTBXToolbar(W).MenuBar then
|
||
SkinComponent := skncMenuBar;
|
||
TSpTBXToolbar(W).DoDrawBackground(ACanvas, ARect, pstPrePaint, PaintDefault);
|
||
end
|
||
else
|
||
if W is TSpTBXCustomToolWindow then
|
||
TSpTBXCustomToolWindow(W).DoDrawBackground(ACanvas, ARect, pstPrePaint, PaintDefault);
|
||
|
||
if PaintDefault then begin
|
||
R := ARect;
|
||
if Toolbar.Color <> clNone then begin
|
||
ACanvas.Brush.Color := Toolbar.Color;
|
||
ACanvas.FillRect(R);
|
||
end
|
||
else
|
||
SpDrawXPToolbar(ACanvas, R, SkinManager.GetSkinType, Toolbar.Docked, Toolbar.Floating, IsVertical, DrawSkinBody, PaintBorders, SkinComponent);
|
||
end;
|
||
|
||
PaintDefault := True;
|
||
if W is TSpTBXToolbar then
|
||
TSpTBXToolbar(W).DoDrawBackground(ACanvas, ARect, pstPostPaint, PaintDefault)
|
||
else
|
||
if W is TSpTBXCustomToolWindow then
|
||
TSpTBXCustomToolWindow(W).DoDrawBackground(ACanvas, ARect, pstPostPaint, PaintDefault);
|
||
end;
|
||
|
||
procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARect: TRect);
|
||
const
|
||
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
|
||
GripR, CloseR: TRect;
|
||
GripSize, Z: Integer;
|
||
Vertical: Boolean;
|
||
C1, C2, PatternColor: TColor;
|
||
Flags: Integer;
|
||
Toolbar: TTBCustomDockableWindowAccess;
|
||
State: TSpTBXSkinStatesType;
|
||
begin
|
||
Toolbar := TTBCustomDockableWindowAccess(W);
|
||
|
||
GripSize := SpGetDragHandleSize(Toolbar);
|
||
if GripSize <= 0 then Exit;
|
||
|
||
Vertical := SpIsVerticalToolbar(Toolbar);
|
||
|
||
GripR := ARect;
|
||
if Vertical then begin
|
||
GripR.Bottom := GripR.Top + GripSize;
|
||
InflateRect(GripR, -2, 0);
|
||
end
|
||
else begin
|
||
GripR.Right := GripR.Left + GripSize;
|
||
InflateRect(GripR, 0, -2);
|
||
end;
|
||
|
||
if Toolbar.DragHandleStyle <> dhNone then begin
|
||
if Toolbar.CloseButtonWhenDocked then begin
|
||
if Vertical then begin
|
||
CloseR.Left := ARect.Right - GripSize;
|
||
CloseR.Right := CloseR.Left + GripSize - 2;
|
||
CloseR.Top := ARect.Top + 2;
|
||
CloseR.Bottom := CloseR.Top + GripSize - 2;
|
||
Dec(GripR.Right, GripSize - 1);
|
||
end
|
||
else begin
|
||
CloseR.Left := ARect.Left + 2;
|
||
CloseR.Right := CloseR.Left + GripSize - 2;
|
||
CloseR.Top := ARect.Top + 2;
|
||
CloseR.Bottom := CloseR.Top + GripSize - 2;
|
||
Inc(GripR.Top, GripSize - 1);
|
||
end;
|
||
end;
|
||
|
||
case SkinManager.GetSkinType of
|
||
sknNone:
|
||
begin
|
||
OffsetRect(CloseR, -1, -1);
|
||
if Vertical then begin
|
||
if Toolbar.CloseButtonWhenDocked then
|
||
if Toolbar.DragHandleStyle = dhDouble then Inc(GripR.Top, 1)
|
||
else Inc(GripR.Top, 3);
|
||
Inc(GripR.Top, 3);
|
||
GripR.Bottom := GripR.Top + 3;
|
||
end
|
||
else begin
|
||
if Toolbar.CloseButtonWhenDocked then
|
||
if Toolbar.DragHandleStyle = dhDouble then Inc(GripR.Left, 1)
|
||
else Inc(GripR.Left, 3);
|
||
Inc(GripR.Left, 3);
|
||
GripR.Right := GripR.Left + 3;
|
||
end;
|
||
Windows.DrawEdge(ACanvas.Handle, GripR, BDR_RAISEDINNER, BF_RECT);
|
||
ACanvas.Pixels[GripR.Left, GripR.Bottom - 1] := clBtnHighlight;
|
||
if Toolbar.DragHandleStyle = dhDouble then begin
|
||
if Vertical then OffsetRect(GripR, 0, 3)
|
||
else OffsetRect(GripR, 3, 0);
|
||
Windows.DrawEdge(ACanvas.Handle, GripR, BDR_RAISEDINNER, BF_RECT);
|
||
ACanvas.Pixels[GripR.Left, GripR.Bottom - 1] := clBtnHighlight;
|
||
end;
|
||
|
||
// Close button
|
||
if Toolbar.CloseButtonWhenDocked then begin
|
||
if Toolbar.CloseButtonDown then
|
||
Windows.DrawEdge(ACanvas.Handle, CloseR, BDR_SUNKENOUTER, BF_RECT)
|
||
else
|
||
if Toolbar. CloseButtonHover then
|
||
Windows.DrawEdge(ACanvas.Handle, CloseR, BDR_RAISEDINNER, BF_RECT);
|
||
if Toolbar.CloseButtonDown then OffsetRect(CloseR, 1, 1);
|
||
SpDrawGlyphPattern(ACanvas.Handle, CloseR, 7, 7, Pattern[0], clBtnText);
|
||
end;
|
||
end;
|
||
sknWindows:
|
||
begin
|
||
// Since GetThemePartSize does not seem to work properly, assume we use default
|
||
// WindowsXP themes where the gripper pattern repeats itself every 4 pixels
|
||
if Vertical then begin
|
||
OffsetRect(GripR, -1, 0);
|
||
GripR := SpCenterRectVert(GripR, 6);
|
||
Z := GripR.Right - GripR.Left;
|
||
GripR.Left := GripR.Left - 1 + (Z and $3) shr 1;
|
||
GripR.Right := GripR.Left + Z and not $3 + 2;
|
||
end
|
||
else begin
|
||
OffsetRect(GripR, 0, -1);
|
||
GripR := SpCenterRectHoriz(GripR, 6);
|
||
Z := GripR.Bottom - GripR.Top;
|
||
GripR.Top := GripR.Top - 1 + (Z and $3) shr 1;
|
||
GripR.Bottom := GripR.Top + Z and not $3 + 1;
|
||
end;
|
||
DrawThemeBackground(ThemeServices.Theme[teRebar], ACanvas.Handle, GripperPart[Vertical], 0, GripR, nil);
|
||
|
||
// Close button
|
||
if Toolbar.CloseButtonWhenDocked then begin
|
||
Flags := TS_NORMAL;
|
||
if Toolbar.CloseButtonDown then Flags := TS_PRESSED
|
||
else if Toolbar.CloseButtonHover then Flags := TS_HOT;
|
||
DrawThemeBackground(ThemeServices.Theme[teToolbar], ACanvas.Handle, TP_BUTTON, Flags, CloseR, nil);
|
||
if Toolbar.CloseButtonDown then OffsetRect(CloseR, 1, 1);
|
||
SpDrawGlyphPattern(ACanvas.Handle, CloseR, 7, 7, Pattern[0], clBtnText);
|
||
end;
|
||
end;
|
||
sknSkin:
|
||
begin
|
||
if Vertical then begin
|
||
InflateRect(GripR, -3, 0);
|
||
OffsetRect(GripR, 0, 2);
|
||
GripR := SpCenterRectVert(GripR, 4);
|
||
end
|
||
else begin
|
||
InflateRect(GripR, 0, -3);
|
||
OffsetRect(GripR, 2, 0);
|
||
GripR := SpCenterRectHoriz(GripR, 4);
|
||
end;
|
||
C1 := SkinManager.CurrentSkin.Options(skncToolbarGrip).Body.Color1;
|
||
C2 := SkinManager.CurrentSkin.Options(skncToolbarGrip).Body.Color2;
|
||
SpDrawXPGrip(ACanvas, GripR, C1, C2);
|
||
|
||
// Close button
|
||
if Toolbar.CloseButtonWhenDocked then begin
|
||
State := sknsNormal;
|
||
if Toolbar.CloseButtonDown then State := sknsPushed
|
||
else if Toolbar.CloseButtonHover then State := sknsHotTrack;
|
||
CurrentSkin.PaintBackground(ACanvas, CloseR, skncToolbarItem, State, True, True);
|
||
if Toolbar.CloseButtonDown then OffsetRect(CloseR, 1, 1);
|
||
PatternColor := CurrentSkin.GetTextColor(skncToolbarItem, State);
|
||
SpDrawGlyphPattern(ACanvas.Handle, CloseR, 7, 7, Pattern[0], PatternColor);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpDrawXPTooltipBackground(ACanvas: TCanvas; ARect: TRect);
|
||
var
|
||
ClipRect: TRect;
|
||
begin
|
||
if SpIsWinVistaOrUp and ThemeServices.ThemesEnabled then begin
|
||
// Paint Vista gradient background if themes enabled
|
||
ClipRect := ARect;
|
||
InflateRect(ARect, 4, 4);
|
||
DrawThemeBackground(ThemeServices.Theme[teToolTip], ACanvas.Handle, TTP_STANDARD, TTSS_NORMAL, ARect, @ClipRect);
|
||
end
|
||
else
|
||
ACanvas.FillRect(ARect);
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ Menu helpers }
|
||
|
||
function SpCalcPopupPosition(const X, Y, Width, Height: Integer;
|
||
PopupControl: TControl = nil; IsVertical: Boolean = False): TPoint;
|
||
var
|
||
R, MonitorR: TRect;
|
||
begin
|
||
if Assigned(PopupControl) then begin
|
||
Result := Point(0, 0);
|
||
if PopupControl.Parent = nil then Exit;
|
||
|
||
R := PopupControl.BoundsRect;
|
||
R.TopLeft := PopupControl.Parent.ClientToScreen(R.TopLeft);
|
||
R.BottomRight := PopupControl.Parent.ClientToScreen(R.BottomRight);
|
||
|
||
if IsVertical then
|
||
Result := Point(R.Right, R.Top)
|
||
else
|
||
Result := Point(R.Left, R.Bottom);
|
||
|
||
MonitorR := GetRectOfMonitorContainingPoint(Result, True);
|
||
|
||
if IsVertical then begin
|
||
if Result.X + Width > MonitorR.Right then
|
||
Result.X := R.Left - Width;
|
||
if Result.Y + Height > MonitorR.Bottom then
|
||
if R.Bottom > MonitorR.Bottom then
|
||
Result.Y := MonitorR.Bottom - Height
|
||
else
|
||
Result.Y := R.Bottom - Height;
|
||
end
|
||
else begin
|
||
if Result.X + Width > MonitorR.Right then
|
||
if R.Right > MonitorR.Right then
|
||
Result.X := MonitorR.Right - Width
|
||
else
|
||
Result.X := R.Right - Width;
|
||
if Result.Y + Height > MonitorR.Bottom then
|
||
Result.Y := R.Top - Height;
|
||
end;
|
||
end
|
||
else begin
|
||
Result := Point(X, Y);
|
||
MonitorR := GetRectOfMonitorContainingPoint(Result, True);
|
||
if X + Width > MonitorR.Right then
|
||
Result.X := X - Width;
|
||
if Y + Height > MonitorR.Bottom then
|
||
Result.Y := Y - Height;
|
||
end;
|
||
end;
|
||
|
||
function SpHMenuGetCaption(Menu: HMenu; Index: Integer): WideString;
|
||
var
|
||
AnsiBuf: array[0..MAX_PATH] of AnsiChar;
|
||
WideBuf: array[0..MAX_PATH] of WideChar;
|
||
Size: Integer;
|
||
begin
|
||
Result := '';
|
||
if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then begin
|
||
FillChar(AnsiBuf, MAX_PATH, #0);
|
||
GetMenuStringA(Menu, Index, @AnsiBuf, MAX_PATH, MF_BYPOSITION);
|
||
Size := lstrlenA(@AnsiBuf);
|
||
Result := WideString(AnsiBuf);
|
||
SetLength(Result, Size);
|
||
end
|
||
else begin
|
||
// [Bugfix] Windows bug:
|
||
// GetMenuStringW when a DBCS code page is active (e.g. Japanese)
|
||
// the result of the function is incorrect (it returns Size * 2)
|
||
// http://news.jrsoftware.org/read/article.php?id=12268&group=jrsoftware.toolbar2000.thirdparty
|
||
FillChar(WideBuf, MAX_PATH, #0);
|
||
GetMenuStringW(Menu, Index, @WideBuf, MAX_PATH, MF_BYPOSITION);
|
||
Size := lstrlenW(@WideBuf);
|
||
Result := WideBuf;
|
||
SetLength(Result, Size);
|
||
end;
|
||
end;
|
||
|
||
function SpHMenuToTBMenuItem(Menu: HMenu; ParentItem: TTBCustomItem): Boolean;
|
||
var
|
||
MenuInfo: TMenuItemInfo;
|
||
I, C: Integer;
|
||
Item: TSpTBXItem;
|
||
HasSubMenu: Boolean;
|
||
begin
|
||
Result := False;
|
||
if not Assigned(ParentItem) or not IsMenu(Menu) then Exit;
|
||
|
||
C := GetMenuItemCount(Menu);
|
||
|
||
for I := 0 to C - 1 do begin
|
||
FillChar(MenuInfo, SizeOf(MenuInfo), #0);
|
||
MenuInfo.cbSize := SizeOf(MenuInfo);
|
||
MenuInfo.fMask := MIIM_TYPE or MIIM_STATE or MIIM_ID or MIIM_SUBMENU;
|
||
GetMenuItemInfo(Menu, I, True, MenuInfo);
|
||
|
||
if MenuInfo.fType and MFT_SEPARATOR <> 0 then
|
||
ParentItem.Add(TSpTBXSeparatorItem.Create(nil))
|
||
else begin
|
||
HasSubmenu := IsMenu(MenuInfo.hSubMenu);
|
||
if HasSubmenu then
|
||
Item := TSpTBXSubmenuItem.Create(nil)
|
||
else
|
||
Item := TSpTBXItem.Create(nil);
|
||
|
||
Item.Caption := SpHMenuGetCaption(Menu, I);
|
||
Item.Tag := MenuInfo.wID;
|
||
if MenuInfo.fState and MFS_DISABLED <> 0 then
|
||
Item.Enabled := False;
|
||
if MenuInfo.fState and MFS_CHECKED <> 0 then
|
||
Item.Checked := True;
|
||
if MenuInfo.fState and MFS_DEFAULT <> 0 then
|
||
Item.Options := Item.Options + [tboDefault];
|
||
ParentItem.Add(Item);
|
||
end;
|
||
end;
|
||
|
||
Result := True;
|
||
end;
|
||
|
||
function SpShowSystemPopupMenu(ParentForm: TCustomForm; ScreenPos: TPoint; DoDefault: Boolean = True): Integer;
|
||
var
|
||
SysMenu: HMENU;
|
||
begin
|
||
ReleaseCapture;
|
||
SysMenu := GetSystemMenu(ParentForm.Handle, False);
|
||
case ParentForm.WindowState of
|
||
wsMaximized:
|
||
begin
|
||
EnableMenuItem(SysMenu, SC_RESTORE, MF_ENABLED);
|
||
EnableMenuItem(SysMenu, SC_MAXIMIZE, MF_GRAYED);
|
||
EnableMenuItem(SysMenu, SC_MOVE, MF_GRAYED);
|
||
EnableMenuItem(SysMenu, SC_SIZE, MF_GRAYED);
|
||
end;
|
||
wsNormal:
|
||
begin
|
||
EnableMenuItem(SysMenu, SC_RESTORE, MF_GRAYED);
|
||
EnableMenuItem(SysMenu, SC_MAXIMIZE, MF_ENABLED);
|
||
EnableMenuItem(SysMenu, SC_MOVE, MF_ENABLED);
|
||
EnableMenuItem(SysMenu, SC_SIZE, MF_ENABLED);
|
||
end;
|
||
end;
|
||
Result := Integer(TrackPopupMenuEx(SysMenu, TPM_LEFTALIGN or TPM_RETURNCMD or
|
||
TPM_RIGHTBUTTON or TPM_HORIZONTAL or TPM_VERTICAL, ScreenPos.X, ScreenPos.Y, ParentForm.Handle, nil));
|
||
if DoDefault then
|
||
case Result of
|
||
SC_MAXIMIZE: ParentForm.WindowState := wsMaximized;
|
||
SC_RESTORE: ParentForm.WindowState := wsNormal;
|
||
else
|
||
// WindowState := wsMinimized will not minimize the app correctly
|
||
SendMessage(ParentForm.Handle, WM_SYSCOMMAND, Result, 0);
|
||
end;
|
||
end;
|
||
|
||
function SpFillSystemSpTBXPopup(ParentForm: TCustomForm; ParentItem: TTBCustomItem;
|
||
ShowSize, ShowMinimize, ShowMaximize, ShowClose: Boolean; ClickEvent: TNotifyEvent = nil): Boolean;
|
||
var
|
||
Menu: HMENU;
|
||
I: Integer;
|
||
Item: TTBCustomItem;
|
||
begin
|
||
Result := False;
|
||
Menu := GetSystemMenu(ParentForm.Handle, False);
|
||
|
||
if SpHMenuToTBMenuItem(Menu, ParentItem) then begin
|
||
for I := 0 to ParentItem.Count - 1 do begin
|
||
Item := ParentItem.Items[I];
|
||
Item.OnClick := ClickEvent;
|
||
case Item.Tag of
|
||
SC_MINIMIZE:
|
||
begin
|
||
Item.Visible := ShowMinimize;
|
||
Item.Enabled := ParentForm.WindowState <> wsMinimized;
|
||
Item.Images := MDIButtonsImgList;
|
||
Item.ImageIndex := 2;
|
||
end;
|
||
SC_RESTORE:
|
||
begin
|
||
Item.Visible := ShowMaximize;
|
||
Item.Enabled := ParentForm.WindowState <> wsNormal;
|
||
Item.Images := MDIButtonsImgList;
|
||
Item.ImageIndex := 3;
|
||
end;
|
||
SC_MAXIMIZE:
|
||
begin
|
||
Item.Visible := ShowMaximize;
|
||
Item.Enabled := ParentForm.WindowState <> wsMaximized;
|
||
Item.Images := MDIButtonsImgList;
|
||
Item.ImageIndex := 1;
|
||
end;
|
||
SC_CLOSE:
|
||
begin
|
||
Item.Visible := ShowClose;
|
||
Item.Options := Item.Options + [tboDefault];
|
||
Item.Images := MDIButtonsImgList;
|
||
Item.ImageIndex := 0;
|
||
end;
|
||
SC_MOVE:
|
||
begin
|
||
Item.Enabled := ParentForm.WindowState <> wsMaximized;
|
||
end;
|
||
SC_SIZE:
|
||
begin
|
||
Item.Visible := ShowSize;
|
||
Item.Enabled := ParentForm.WindowState <> wsMaximized;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
Result := True;
|
||
end;
|
||
end;
|
||
|
||
function SpShowSystemSpTBXPopupMenu(ParentForm: TCustomForm; ScreenPos: TPoint;
|
||
ShowSize, ShowMinimize, ShowMaximize, ShowClose: Boolean;
|
||
PopupEvent: TSpTBXPopupEvent; DoDefault: Boolean = True): Integer;
|
||
var
|
||
Popup: TSpTBXPopupMenu;
|
||
ClickedItem: TTBCustomItem;
|
||
begin
|
||
Result := 0;
|
||
ReleaseCapture;
|
||
|
||
Popup := TSpTBXPopupMenu.Create(ParentForm);
|
||
try
|
||
if SpFillSystemSpTBXPopup(ParentForm, Popup.Items, ShowSize, ShowMinimize, ShowMaximize, ShowClose) then begin
|
||
if Assigned(PopupEvent) then
|
||
Popup.OnInitPopup := PopupEvent;
|
||
Popup.PopupComponent := ParentForm;
|
||
ClickedItem := Popup.PopupEx(ScreenPos.X, ScreenPos.Y, nil, True);
|
||
if Assigned(ClickedItem) then begin
|
||
Result := ClickedItem.Tag;
|
||
// If it's not a SystemMenu item fire the OnClick event of the item
|
||
// We can't use PostClick because the Item will be destroyed by the
|
||
// time the message is handled.
|
||
if (Result < SC_SIZE) or (Result > SC_CONTEXTHELP) then
|
||
ClickedItem.Click;
|
||
end;
|
||
end;
|
||
finally
|
||
Popup.Free;
|
||
end;
|
||
|
||
if DoDefault and (Result > 0) then
|
||
case Result of
|
||
SC_MAXIMIZE:
|
||
ParentForm.WindowState := wsMaximized;
|
||
SC_RESTORE:
|
||
ParentForm.WindowState := wsNormal;
|
||
SC_SIZE, SC_MOVE, SC_MINIMIZE, SC_CLOSE:
|
||
begin
|
||
// WindowState := wsMinimized will not minimize the app correctly
|
||
SendMessage(ParentForm.Handle, WM_SYSCOMMAND, Result, 0);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ Misc helpers }
|
||
|
||
procedure SpActivateDwmNC(WinControl: TWinControl; Activate: Boolean);
|
||
{$IFDEF JR_D11}
|
||
var
|
||
ncrp: Cardinal;
|
||
{$ENDIF}
|
||
begin
|
||
{$IFDEF JR_D11}
|
||
// Use the new API on Windows Vista
|
||
if DwmCompositionEnabled and WinControl.HandleAllocated then begin
|
||
if Activate then
|
||
ncrp := DWMNCRP_USEWINDOWSTYLE
|
||
else
|
||
ncrp := DWMNCRP_DISABLED;
|
||
DwmSetWindowAttribute(WinControl.Handle, DWMWA_NCRENDERING_POLICY, @ncrp, SizeOf(ncrp));
|
||
end;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function SpIsDwmCompositionEnabled: Boolean;
|
||
begin
|
||
{$IFDEF JR_D11}
|
||
// Use the new API on Windows Vista
|
||
Result := DwmCompositionEnabled;
|
||
{$ELSE}
|
||
Result := False;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
function SpCanFocus(WinControl: TWinControl): Boolean;
|
||
var
|
||
Form: TCustomForm;
|
||
begin
|
||
Result := False;
|
||
if Assigned(WinControl) and not WinControl.Focused then begin
|
||
Form := GetParentForm(WinControl);
|
||
if Assigned(Form) and Form.Enabled and Form.Visible then
|
||
Result := WinControl.CanFocus;
|
||
end;
|
||
end;
|
||
|
||
function SpIsFocused(WinControl: TWinControl; out FocusedChild: TWinControl): Boolean;
|
||
var
|
||
Form: TCustomForm;
|
||
begin
|
||
Result := False;
|
||
FocusedChild := nil;
|
||
if WinControl.Focused then
|
||
Result := True
|
||
else begin
|
||
Form := GetParentForm(WinControl);
|
||
if Assigned(Form) and Form.Enabled and Form.Visible then
|
||
if Assigned(Form.ActiveControl) and Form.ActiveControl.Focused then
|
||
if IsChild(WinControl.Handle, Form.ActiveControl.Handle) then begin
|
||
Result := True;
|
||
FocusedChild := Form.ActiveControl;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function SpFocusFirstChild(WinControl: TWinControl): TWinControl;
|
||
var
|
||
Form: TCustomForm;
|
||
begin
|
||
Result := nil;
|
||
Form := GetParentForm(WinControl);
|
||
if Assigned(Form) and Form.Enabled and Form.Visible then begin
|
||
TWinControlAccess(WinControl).SelectFirst;
|
||
Result := Form.ActiveControl;
|
||
end;
|
||
end;
|
||
|
||
function SpFindControl(Parent: TWinControl; Child: TControl): Integer;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
Result := -1;
|
||
for I := 0 to Parent.ControlCount - 1 do
|
||
if Parent.Controls[I] = Child then begin
|
||
Result := I;
|
||
Break;
|
||
end;
|
||
end;
|
||
|
||
function SpFindParent(Control: TControl; ParentClass: TClass): TWinControl;
|
||
var
|
||
P: TWinControl;
|
||
begin
|
||
Result := nil;
|
||
if Assigned(Control) then begin
|
||
P := Control.Parent;
|
||
while Assigned(P) do
|
||
if P is ParentClass then begin
|
||
Result := P;
|
||
Break;
|
||
end
|
||
else
|
||
P := P.Parent;
|
||
end;
|
||
end;
|
||
|
||
function SpHasBorders(WinControl: TWinControl): Boolean;
|
||
var
|
||
Style, ExStyle: Integer;
|
||
begin
|
||
Result := False;
|
||
Style := GetWindowLong(WinControl.Handle, GWL_STYLE);
|
||
ExStyle := GetWindowLong(WinControl.Handle, GWL_EXSTYLE);
|
||
|
||
if (Style and WS_BORDER <> 0) or (ExStyle and WS_EX_CLIENTEDGE <> 0) then
|
||
Result := True;
|
||
end;
|
||
|
||
function SpGetFormWindowState(F: TCustomForm; out RestoreBoundsRect: TRect): TWindowState;
|
||
// This method is more accurate than Form.WindowState
|
||
var
|
||
P: TWindowPlacement;
|
||
begin
|
||
Result := wsNormal;
|
||
RestoreBoundsRect := Rect(0, 0, 0, 0);
|
||
if Assigned(F) and (F.HandleAllocated) then begin
|
||
P.Length := SizeOf(TWindowPlacement);
|
||
if GetWindowPlacement(F.Handle, @P) then begin
|
||
case P.showCmd of
|
||
SW_SHOWMINIMIZED: Result := wsMinimized;
|
||
SW_SHOWMAXIMIZED: Result := wsMaximized;
|
||
end;
|
||
// rcNormalPosition contains the window's coordinates when the window is in the restored position
|
||
with P.rcNormalPosition do
|
||
RestoreBoundsRect := Rect(Left, Top, Right - Left, Bottom - Top);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpSetFormWindowState(F: TCustomForm; WindowState: TWindowState; RestoreBoundsRect: TRect);
|
||
// This method is more accurate than Form.WindowState
|
||
var
|
||
P: TWindowPlacement;
|
||
R: TRect;
|
||
begin
|
||
if Assigned(F) and (F.HandleAllocated) then begin
|
||
P.Length := SizeOf(TWindowPlacement);
|
||
case WindowState of
|
||
wsMinimized: P.showCmd := SW_SHOWMINIMIZED;
|
||
wsMaximized: P.showCmd := SW_SHOWMAXIMIZED;
|
||
else
|
||
P.showCmd := SW_SHOWNORMAL;
|
||
end;
|
||
with RestoreBoundsRect do
|
||
R := Bounds(Left, Top, Right, Bottom);
|
||
// rcNormalPosition contains the window's coordinates when the window is in the restored position
|
||
if not IsRectEmpty(R) then
|
||
P.rcNormalPosition := R;
|
||
|
||
SetWindowPlacement(F.Handle, @P);
|
||
end;
|
||
end;
|
||
|
||
function SpGetTaskBar(out State, Edge: Cardinal; out Bounds: TRect): Boolean;
|
||
// Returns the TaskBar state and bounds
|
||
// State can be: 0, ABS_ALWAYSONTOP, ABS_AUTOHIDE
|
||
// Edge can be: ABE_LEFT, ABE_RIGHT, ABE_TOP, ABE_BOTTOM
|
||
// ABM_GETSTATE
|
||
|
||
var
|
||
AppData: TAppBarData;
|
||
begin
|
||
Result := False;
|
||
State := 0;
|
||
Edge := 0;
|
||
Bounds := Rect(0, 0, 0, 0);
|
||
|
||
// 'Shell_TrayWnd' is the name of the task bar's window
|
||
AppData.Hwnd := FindWindow('Shell_TrayWnd', nil);
|
||
if AppData.Hwnd <> 0 then begin
|
||
AppData.cbSize := SizeOf(TAppBarData);
|
||
if SHAppBarMessage(ABM_GETTASKBARPOS, AppData) <> 0 then begin
|
||
Edge := AppData.uEdge;
|
||
Bounds := AppData.rc;
|
||
|
||
AppData.cbSize := SizeOf(TAppBarData);
|
||
State := SHAppBarMessage(ABM_GETSTATE, AppData);
|
||
|
||
Result := True;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpRecalcNCArea(WinControl: TWinControl);
|
||
begin
|
||
if WinControl.HandleAllocated then
|
||
SetWindowPos(WinControl.Handle, 0, 0, 0, 0, 0, SWP_FRAMECHANGED or
|
||
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ Customizer helpers }
|
||
|
||
procedure SpCustomizeAllToolbars(AParentComponent: TComponent; Reset: Boolean);
|
||
var
|
||
I: Integer;
|
||
TB: TSpTBXToolbar;
|
||
begin
|
||
if Assigned(AParentComponent) then begin
|
||
for I := 0 to AParentComponent.ComponentCount - 1 do
|
||
if AParentComponent.Components[I] is TSpTBXToolbar then begin
|
||
TB := AParentComponent.Components[I] as TSpTBXToolbar;
|
||
if Reset then
|
||
TB.EndCustomize
|
||
else
|
||
TB.BeginCustomize;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpBeginUpdateAllToolbars(AParentComponent: TComponent);
|
||
var
|
||
I: Integer;
|
||
TB: TTBCustomToolbar;
|
||
begin
|
||
if Assigned(AParentComponent) then begin
|
||
for I := 0 to AParentComponent.ComponentCount - 1 do
|
||
if AParentComponent.Components[I] is TTBCustomToolbar then begin
|
||
TB := AParentComponent.Components[I] as TTBCustomToolbar;
|
||
TB.BeginUpdate;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure SpEndUpdateAllToolbars(AParentComponent: TComponent);
|
||
var
|
||
I: Integer;
|
||
TB: TTBCustomToolbar;
|
||
begin
|
||
if Assigned(AParentComponent) then begin
|
||
for I := 0 to AParentComponent.ComponentCount - 1 do
|
||
if AParentComponent.Components[I] is TTBCustomToolbar then begin
|
||
TB := AParentComponent.Components[I] as TTBCustomToolbar;
|
||
TB.View.UpdatePositions;
|
||
TB.EndUpdate;
|
||
TB.Invalidate;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ Unicode helpers }
|
||
|
||
procedure SpPersistent_AfterInherited_DefineProperties(Filer: TFiler; Instance: TPersistent);
|
||
begin
|
||
{$IFNDEF UNICODE}
|
||
// Don't let the streaming system store the WideStrings,
|
||
// we need to store them manually
|
||
TntPersistent_AfterInherited_DefineProperties(Filer, Instance);
|
||
{$ENDIF}
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXFontSettings }
|
||
|
||
constructor TSpTBXFontSettings.Create;
|
||
begin
|
||
FSize := 100;
|
||
FColor := clNone;
|
||
end;
|
||
|
||
procedure TSpTBXFontSettings.Apply(AFont: TFont);
|
||
begin
|
||
AFont.Charset := DEFAULT_CHARSET;
|
||
AFont.Color := FColor;
|
||
if FSize <> 100 then
|
||
AFont.Size := (AFont.Size * FSize + 50) div 100;
|
||
if FName <> '' then
|
||
AFont.Name := Name;
|
||
if FStyle <> [] then
|
||
AFont.Style := FStyle;
|
||
end;
|
||
|
||
procedure TSpTBXFontSettings.Assign(Src: TPersistent);
|
||
var
|
||
F: TSpTBXFontSettings;
|
||
begin
|
||
if Src is TPersistent then begin
|
||
F := TSpTBXFontSettings(Src);
|
||
FColor := F.Color;
|
||
FName := F.Name;
|
||
FSize := F.Size;
|
||
FStyle := F.Style;
|
||
Modified;
|
||
end
|
||
else
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXFontSettings.Modified;
|
||
begin
|
||
if Assigned(FOnChange) then FOnChange(Self);
|
||
end;
|
||
|
||
procedure TSpTBXFontSettings.SetColor(Value: TColor);
|
||
begin
|
||
if FColor <> Value then begin
|
||
FColor := Value;
|
||
Modified;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXFontSettings.SetName(const Value: TFontName);
|
||
begin
|
||
if FName <> Value then begin
|
||
FName := Value;
|
||
Modified;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXFontSettings.SetSize(Value: TSpTBXFontSize);
|
||
begin
|
||
if FSize <> Value then begin
|
||
FSize := Value;
|
||
Modified;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXFontSettings.SetStyle(const Value: TFontStyles);
|
||
begin
|
||
if FStyle <> Value then begin
|
||
FStyle := Value;
|
||
Modified;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomDragObject }
|
||
|
||
constructor TSpTBXCustomDragObject.Create(ASourceControl: TControl; AItem: TTBCustomItem);
|
||
begin
|
||
FSourceControl := ASourceControl;
|
||
FSourceItem := AItem;
|
||
FDragCursorAccept := crSpTBXCustomization;
|
||
FDragCursorCancel := crNo;
|
||
end;
|
||
|
||
procedure TSpTBXCustomDragObject.Finished(Target: TObject; X, Y: Integer;
|
||
Accepted: Boolean);
|
||
begin
|
||
inherited;
|
||
if not Accepted then begin
|
||
if Assigned(FSourceControl) then
|
||
TControlAccess(FSourceControl).DragCanceled;
|
||
Target := nil;
|
||
end;
|
||
|
||
if Assigned(FSourceControl) then
|
||
TControlAccess(FSourceControl).DoEndDrag(Target, X, Y);
|
||
end;
|
||
|
||
function TSpTBXCustomDragObject.GetDragCursor(Accepted: Boolean; X,
|
||
Y: Integer): TCursor;
|
||
begin
|
||
if Accepted then Result := FDragCursorAccept
|
||
else Result := FDragCursorCancel;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomItemActionLink }
|
||
|
||
{$IFNDEF UNICODE}
|
||
procedure TSpTBXCustomItemActionLink.AssignClient(AClient: TObject);
|
||
begin
|
||
inherited AssignClient(AClient);
|
||
FUnicodeClient := AClient as TSpTBXCustomItem;
|
||
end;
|
||
|
||
function TSpTBXCustomItemActionLink.IsCaptionLinked: Boolean;
|
||
begin
|
||
if (Action is TCustomAction) and Supports(Action, ITntAction) then
|
||
Result := FUnicodeClient.Caption = TntActnList.TntAction_GetCaption(Action as TCustomAction)
|
||
else
|
||
Result := inherited IsCaptionLinked;
|
||
end;
|
||
|
||
function TSpTBXCustomItemActionLink.IsHintLinked: Boolean;
|
||
begin
|
||
if (Action is TCustomAction) and Supports(Action, ITntAction) then
|
||
Result := FUnicodeClient.Hint = TntActnList.TntAction_GetHint(Action as TCustomAction)
|
||
else
|
||
Result := inherited IsCaptionLinked;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItemActionLink.SetCaption(const Value: String);
|
||
begin
|
||
if IsCaptionLinked then
|
||
if (Action is TCustomAction) and Supports(Action, ITntAction) then
|
||
FUnicodeClient.Caption := TntActnList.TntAction_GetNewCaption(Action as TCustomAction, Value)
|
||
else
|
||
FUnicodeClient.Caption := Value;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItemActionLink.SetHint(const Value: String);
|
||
begin
|
||
if IsHintLinked then
|
||
if (Action is TCustomAction) and Supports(Action, ITntAction) then
|
||
FUnicodeClient.Hint := TntActnList.TntAction_GetNewHint(Action as TCustomAction, Value)
|
||
else
|
||
FUnicodeClient.Hint := Value;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomControl }
|
||
|
||
{$IFNDEF UNICODE}
|
||
procedure TSpTBXCustomControl.CreateWindowHandle(const Params: TCreateParams);
|
||
begin
|
||
CreateUnicodeHandle(Self, Params, '');
|
||
end;
|
||
|
||
procedure TSpTBXCustomControl.DefineProperties(Filer: TFiler);
|
||
begin
|
||
inherited;
|
||
// Don't let the streaming system store the WideStrings,
|
||
// we need to store them manually
|
||
SpPersistent_AfterInherited_DefineProperties(Filer, Self);
|
||
end;
|
||
|
||
procedure TSpTBXCustomControl.ActionChange(Sender: TObject; CheckDefaults: Boolean);
|
||
begin
|
||
if (Action is TCustomAction) and Supports(Action, ITntAction) then begin
|
||
if not CheckDefaults or (Self.Caption = '') then
|
||
Self.Caption := TntActnList.TntAction_GetCaption(Action as TCustomAction);
|
||
if not CheckDefaults or (Self.Hint = '') then
|
||
Self.Hint := TntActnList.TntAction_GetHint(Action as TCustomAction);
|
||
end;
|
||
// Call inherited after we changed the unicode Caption and Hint
|
||
inherited;
|
||
end;
|
||
|
||
function TSpTBXCustomControl.IsCaptionStored: Boolean;
|
||
begin
|
||
Result := TntControl_IsCaptionStored(Self);
|
||
end;
|
||
|
||
function TSpTBXCustomControl.IsHintStored: Boolean;
|
||
begin
|
||
Result := TntControl_IsHintStored(Self);
|
||
end;
|
||
|
||
function TSpTBXCustomControl.GetCaption: TWideCaption;
|
||
begin
|
||
Result := TntControl_GetText(Self);
|
||
end;
|
||
|
||
function TSpTBXCustomControl.GetHint: WideString;
|
||
begin
|
||
Result := TntControl_GetHint(Self);
|
||
end;
|
||
|
||
procedure TSpTBXCustomControl.SetCaption(const Value: TWideCaption);
|
||
begin
|
||
TntControl_SetText(Self, Value);
|
||
end;
|
||
|
||
procedure TSpTBXCustomControl.SetHint(const Value: WideString);
|
||
begin
|
||
TntControl_SetHint(Self, Value);
|
||
end;
|
||
{$ENDIF}
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomItem }
|
||
|
||
constructor TSpTBXCustomItem.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
FFontSettings := TSpTBXFontSettings.Create;
|
||
FFontSettings.OnChange := FontSettingsChanged;
|
||
|
||
{$IFNDEF UNICODE}
|
||
FCaption := '';
|
||
{$ENDIF}
|
||
FAlignment := taCenter;
|
||
FCaptionGlowColor := clYellow;
|
||
FCustomWidth := -1;
|
||
FCustomHeight := -1;
|
||
FMargins := 0;
|
||
SetStretch(True);
|
||
FWrapping := twWrap;
|
||
end;
|
||
|
||
destructor TSpTBXCustomItem.Destroy;
|
||
begin
|
||
FreeAndNil(FFontSettings);
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.Notification(AComponent: TComponent;
|
||
Operation: TOperation);
|
||
begin
|
||
inherited;
|
||
if (Operation = opRemove) and (AComponent = Control) then Control := nil;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.DefineProperties(Filer: TFiler);
|
||
begin
|
||
inherited;
|
||
// Don't let the streaming system store the WideStrings,
|
||
// we need to store them manually
|
||
SpPersistent_AfterInherited_DefineProperties(Filer, Self);
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.ActionChange(Sender: TObject; CheckDefaults: Boolean);
|
||
begin
|
||
{$IFNDEF UNICODE}
|
||
if (Action is TCustomAction) and Supports(Action, ITntAction) then begin
|
||
if not CheckDefaults or (Self.Caption = '') then
|
||
Self.Caption := TntActnList.TntAction_GetCaption(Action as TCustomAction);
|
||
if not CheckDefaults or (Self.Hint = '') then
|
||
Self.Hint := TntActnList.TntAction_GetHint(Action as TCustomAction);
|
||
inherited;
|
||
Exit;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
if Action is TCustomAction then
|
||
with TCustomAction(Sender) do begin
|
||
if not CheckDefaults or (Self.Caption = '') then
|
||
Self.Caption := Caption;
|
||
if not CheckDefaults or (Self.Hint = '') then
|
||
Self.Hint := Hint;
|
||
end;
|
||
inherited;
|
||
end;
|
||
|
||
function TSpTBXCustomItem.DialogChar(CharCode: Word): Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.DoDrawAdjustFont(AFont: TFont; State: TSpTBXSkinStatesType);
|
||
begin
|
||
// Do nothing
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.DoDrawHint(AHintBitmap: TBitmap; var AHint: Widestring; var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawHint) then FOnDrawHint(Self, AHintBitmap, AHint, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.DoDrawButton(ACanvas: TCanvas; ARect: TRect;
|
||
ItemInfo: TSpTBXMenuItemInfo; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawItem) then FOnDrawItem(Self, ACanvas, ARect, ItemInfo, PaintStage, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.DoDrawCaption(ACanvas: TCanvas; ClientAreaRect: TRect;
|
||
State: TSpTBXSkinStatesType; var ACaption: WideString; var CaptionRect: TRect; var CaptionFormat: Cardinal;
|
||
IsTextRotated: Boolean; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawCaption) then FOnDrawCaption(Self, ACanvas, ClientAreaRect,
|
||
State, ACaption, CaptionRect, CaptionFormat, IsTextRotated, PaintStage, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.DoDrawImage(ACanvas: TCanvas;
|
||
State: TSpTBXSkinStatesType; const PaintStage: TSpTBXPaintStage;
|
||
var AImageList: TCustomImageList; var AImageIndex: Integer;
|
||
var ARect: TRect; var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawImage) then FOnDrawImage(Self, ACanvas, State, PaintStage,
|
||
AImageList, AImageIndex, ARect, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.DoPopupShowingChanged(APopupWindow: TTBPopupWindow; IsVisible: Boolean);
|
||
// This method is called by TSpTBXPopupWindow when the popup is Opened and Closed
|
||
begin
|
||
if Assigned(APopupWindow) then begin
|
||
if IsVisible then begin
|
||
if Assigned(FOnInitPopup) then FOnInitPopup(Self, APopupWindow.View);
|
||
end
|
||
else begin
|
||
if Assigned(FOnClosePopup) then FOnClosePopup(Self);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.FontSettingsChanged(Sender: TObject);
|
||
begin
|
||
Change(True);
|
||
end;
|
||
|
||
function TSpTBXCustomItem.GetActionLinkClass: TTBCustomItemActionLinkClass;
|
||
begin
|
||
Result := TSpTBXCustomItemActionLink;
|
||
end;
|
||
|
||
function TSpTBXCustomItem.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
|
||
begin
|
||
Result := TSpTBXItemViewer;
|
||
end;
|
||
|
||
function TSpTBXCustomItem.GetPopupWindowClass: TTBPopupWindowClass;
|
||
begin
|
||
Result := TSpTBXPopupWindow;
|
||
end;
|
||
|
||
function TSpTBXCustomItem.GetShortCutText: WideString;
|
||
var
|
||
P: Integer;
|
||
begin
|
||
P := Pos(#9, Caption);
|
||
if (P = 0) or (P = Length(Caption)) then begin
|
||
if ShortCut <> 0 then
|
||
Result := ShortCutToText(ShortCut)
|
||
else
|
||
Result := '';
|
||
end
|
||
else
|
||
Result := Copy(Caption, P+1, Maxint);
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.Click;
|
||
begin
|
||
if Assigned(FControl) then ToggleControl;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.InitiateAction;
|
||
begin
|
||
inherited;
|
||
UpdateProps;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.Invalidate;
|
||
begin
|
||
Change(False);
|
||
end;
|
||
|
||
{$IFNDEF UNICODE}
|
||
function TSpTBXCustomItem.IsCaptionStored: Boolean;
|
||
begin
|
||
Result := (ActionLink = nil) or not TActionLinkAccess(ActionLink).IsCaptionLinked;
|
||
end;
|
||
|
||
function TSpTBXCustomItem.IsHintStored: Boolean;
|
||
begin
|
||
Result := (ActionLink = nil) or not TActionLinkAccess(ActionLink).IsHintLinked;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetCaption(const Value: WideString);
|
||
var
|
||
S, PrevS: string;
|
||
begin
|
||
if FCaption <> Value then begin
|
||
FCaption := Value;
|
||
// We need to compare the Ansi inherited Caption
|
||
// to force the change.
|
||
// Sometimes '???' = '???' and the change is not executed.
|
||
S := inherited Caption;
|
||
PrevS := Value;
|
||
if S <> PrevS then
|
||
inherited Caption := Value
|
||
else
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetHint(const Value: WideString);
|
||
begin
|
||
if FHint <> Value then begin
|
||
FHint := Value;
|
||
inherited Hint := Value;
|
||
end;
|
||
end;
|
||
{$ENDIF}
|
||
|
||
procedure TSpTBXCustomItem.SetAlignment(const Value: TAlignment);
|
||
begin
|
||
if FAlignment <> Value then begin
|
||
FAlignment := Value;
|
||
Change(False);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetAnchored(const Value: Boolean);
|
||
begin
|
||
if FAnchored <> Value then begin
|
||
FAnchored := Value;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetCaptionGlow(const Value: TSpGlowDirection);
|
||
begin
|
||
if FCaptionGlow <> Value then begin
|
||
FCaptionGlow := Value;
|
||
Change(False);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetCaptionGlowColor(const Value: TColor);
|
||
begin
|
||
if FCaptionGlowColor <> Value then begin
|
||
FCaptionGlowColor := Value;
|
||
Change(False);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetControl(const Value: TControl);
|
||
begin
|
||
if FControl <> Value then
|
||
begin
|
||
FControl := Value;
|
||
if Assigned(Value) then
|
||
Value.FreeNotification(Self);
|
||
UpdateProps;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetCustomWidth(Value: Integer);
|
||
begin
|
||
if Value < -1 then Value := -1;
|
||
if FCustomWidth <> Value then begin
|
||
FCustomWidth := Value;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetCustomHeight(Value: Integer);
|
||
begin
|
||
if Value < -1 then Value := -1;
|
||
if FCustomHeight <> Value then begin
|
||
FCustomHeight := Value;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetFontSettings(const Value: TSpTBXFontSettings);
|
||
begin
|
||
FFontSettings.Assign(Value);
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetMargins(Value: Integer);
|
||
begin
|
||
if FMargins <> Value then begin
|
||
FMargins := Value;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetMinHeight(const Value: Integer);
|
||
begin
|
||
if Value <> FMinHeight then begin
|
||
FMinHeight := Value;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetMinWidth(const Value: Integer);
|
||
begin
|
||
if Value <> FMinWidth then begin
|
||
FMinWidth := Value;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetStretch(const Value: Boolean);
|
||
begin
|
||
if FStretch <> Value then begin
|
||
FStretch := Value;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetToolBoxPopup(const Value: Boolean);
|
||
begin
|
||
FToolBoxPopup := Value;
|
||
if FToolBoxPopup then
|
||
Options := Options + [tboToolbarStyle]
|
||
else
|
||
Options := Options - [tboToolbarStyle];
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.SetWrapping(const Value: TTextWrapping);
|
||
begin
|
||
if FWrapping <> Value then begin
|
||
FWrapping := Value;
|
||
Change(False);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.ToggleControl;
|
||
begin
|
||
FControl.Visible := not FControl.Visible;
|
||
end;
|
||
|
||
procedure TSpTBXCustomItem.UpdateProps;
|
||
begin
|
||
if Assigned(Control) then
|
||
if (ComponentState * [csDesigning, csLoading, csDestroying] = []) then
|
||
Checked := Control.Visible;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXItemViewer }
|
||
|
||
function TSpTBXItemViewer.CaptionShown: Boolean;
|
||
var
|
||
T: TSpTBXToolbar;
|
||
begin
|
||
Result := inherited CaptionShown;
|
||
|
||
if Assigned(View) and Assigned(View.Owner) and (View.Owner is TSpTBXToolbar) then begin
|
||
T := View.Owner as TSpTBXToolbar;
|
||
case T.DisplayMode of
|
||
tbdmImageOnly:
|
||
if GetImageShown then Result := False;
|
||
tbdmTextOnly:
|
||
Result := True;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXItemViewer.GetImageShown: Boolean;
|
||
begin
|
||
Result := (Item.ImageIndex >= 0) and
|
||
((Item.DisplayMode in [nbdmDefault, nbdmImageAndText]) or
|
||
(IsToolbarStyle and (Item.DisplayMode = nbdmTextOnlyInMenus)));
|
||
|
||
if Assigned(View) and Assigned(View.Owner) and (View.Owner is TSpTBXToolbar) then
|
||
if TSpTBXToolbar(View.Owner).DisplayMode = tbdmTextOnly then
|
||
Result := False;
|
||
end;
|
||
|
||
function TSpTBXItemViewer.GetImageSize: TSize;
|
||
var
|
||
IL: TCustomImageList;
|
||
begin
|
||
IL := GetImageList;
|
||
if Assigned(IL) then begin
|
||
Result.cx := IL.Width;
|
||
Result.cy := IL.Height;
|
||
end
|
||
else begin
|
||
Result.cx := 0;
|
||
Result.cy := 0;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXItemViewer.GetRightImageSize: TSize;
|
||
begin
|
||
Result.cx := 0;
|
||
Result.cy := 0;
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.DoDrawButton(ACanvas: TCanvas; ARect: TRect;
|
||
ItemInfo: TSpTBXMenuItemInfo; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
Item.DoDrawButton(ACanvas, ARect, ItemInfo, PaintStage, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.DoDrawCaption(ACanvas: TCanvas; ClientAreaRect: TRect;
|
||
State: TSpTBXSkinStatesType; var ACaption: WideString; var CaptionRect: TRect; var CaptionFormat: Cardinal;
|
||
IsTextRotated: Boolean; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
Item.DoDrawCaption(ACanvas, ClientAreaRect, State, ACaption, CaptionRect,
|
||
CaptionFormat, IsTextRotated, PaintStage, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.DoDrawHint(AHintBitmap: TBitmap; CursorPos: TPoint;
|
||
var CursorRect: TRect; var AHint: Widestring; var PaintDefault: Boolean);
|
||
begin
|
||
Item.DoDrawHint(AHintBitmap, AHint, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.DoDrawImage(ACanvas: TCanvas;
|
||
State: TSpTBXSkinStatesType; const PaintStage: TSpTBXPaintStage;
|
||
var AImageList: TCustomImageList; var AImageIndex: Integer;
|
||
var ARect: TRect; var PaintDefault: Boolean);
|
||
begin
|
||
Item.DoDrawImage(ACanvas, State, PaintStage, AImageList, AImageIndex, ARect, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.DoDrawAdjustFont(AFont: TFont; State: TSpTBXSkinStatesType);
|
||
begin
|
||
Item.FontSettings.Apply(AFont);
|
||
|
||
if tboDefault in Item.EffectiveOptions then
|
||
AFont.Style := AFont.Style + [fsBold];
|
||
|
||
if AFont.Color = clNone then
|
||
AFont.Color := GetTextColor(State);
|
||
|
||
Item.DoDrawAdjustFont(AFont, State);
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.DrawItemImage(ACanvas: TCanvas; ARect: TRect;
|
||
ItemInfo: TSpTBXMenuItemInfo; ImgIndex: Integer);
|
||
var
|
||
PaintDefault: Boolean;
|
||
ImgList: TCustomImageList;
|
||
PatternColor: TColor;
|
||
begin
|
||
ImgList := GetImageList;
|
||
|
||
PaintDefault := True;
|
||
DoDrawImage(ACanvas, ItemInfo.State, pstPrePaint, ImgList, ImgIndex, ARect, PaintDefault);
|
||
if PaintDefault and Assigned(ImgList) then
|
||
if ImgList = MDIButtonsImgList then begin
|
||
if (Item.Enabled) and not IsToolbarStyle and (SkinManager.GetSkinType <> sknSkin) then
|
||
PatternColor := clMenuText
|
||
else
|
||
PatternColor := GetTextColor(ItemInfo.State);
|
||
SpDrawGlyphPattern(ACanvas, ARect, ImgIndex, PatternColor);
|
||
end
|
||
else
|
||
if (ImgIndex >= 0) and (ImgIndex < ImgList.Count) then
|
||
SpDrawXPMenuItemImage(ACanvas, ARect, ItemInfo, ImgList, ImgIndex);
|
||
PaintDefault := True;
|
||
DoDrawImage(ACanvas, ItemInfo.State, pstPostPaint, ImgList, ImgIndex, ARect, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.DrawItemRightImage(ACanvas: TCanvas; ARect: TRect;
|
||
ItemInfo: TSpTBXMenuItemInfo);
|
||
begin
|
||
// Do nothing
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.InternalCalcSize(const Canvas: TCanvas;
|
||
CalcStretch: Boolean; var AWidth, AHeight: Integer);
|
||
var
|
||
I, W, H: Integer;
|
||
DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize: Integer;
|
||
ImgSize, RightImgSize: TSize;
|
||
GlyphTop, ToolbarStyle: Boolean;
|
||
WS: WideString;
|
||
TextMetric: TTextMetric;
|
||
MenuMargins: TSpTBXMenuItemMarginsInfo;
|
||
State: TSpTBXSkinStatesType;
|
||
IsHoverItem, IsOpen, IsPushed: Boolean;
|
||
TextInfo: TSpTBXTextInfo;
|
||
TB: TSpTBXToolbar;
|
||
begin
|
||
CurrentSkin.GetDropDownArrowSize(DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize);
|
||
|
||
ToolbarStyle := IsToolbarStyle;
|
||
|
||
ImgSize := GetImageSize;
|
||
if (ImgSize.CX <= 0) or (ImgSize.CY <= 0) then begin
|
||
ImgSize.CX := 0;
|
||
ImgSize.CY := 0;
|
||
end;
|
||
RightImgSize := GetRightImageSize;
|
||
if (RightImgSize.CX <= 0) or (RightImgSize.CY <= 0) then begin
|
||
RightImgSize.CX := 0;
|
||
RightImgSize.CY := 0;
|
||
end;
|
||
|
||
GlyphTop := False;
|
||
if tboImageAboveCaption in Item.EffectiveOptions then
|
||
GlyphTop := True;
|
||
|
||
// Setup font and get the text info
|
||
IsOpen := Self = View.OpenViewer;
|
||
IsHoverItem := Self = View.Selected;
|
||
IsPushed := IsHoverItem and (IsOpen or (View.MouseOverSelected and View.Capture));
|
||
State := CurrentSkin.GetState(Item.Enabled, IsPushed, IsHoverItem, Item.Checked);
|
||
GetTextInfo(Canvas, State, TextInfo);
|
||
|
||
// Measure size
|
||
if ToolbarStyle then begin
|
||
AWidth := 6;
|
||
AHeight := 6;
|
||
|
||
if CaptionShown then begin
|
||
Inc(AWidth, TextInfo.TextSize.CX);
|
||
Inc(AHeight, TextInfo.TextSize.CY);
|
||
if not TextInfo.IsTextRotated then Inc(AWidth, 4)
|
||
else Inc(AHeight, 4);
|
||
end;
|
||
|
||
if GetImageShown and (ImgSize.CX > 0) and (ImgSize.CY > 0) then begin
|
||
if not GlyphTop then begin
|
||
if not TextInfo.IsTextRotated then begin
|
||
Inc(AWidth, ImgSize.CX);
|
||
Inc(AWidth);
|
||
if AHeight < ImgSize.CY + 6 then AHeight := ImgSize.CY + 6;
|
||
end
|
||
else begin
|
||
Inc(AHeight, ImgSize.CY);
|
||
Inc(AHeight);
|
||
if AWidth < ImgSize.CX + 6 then AWidth := ImgSize.CX + 6;
|
||
end;
|
||
end
|
||
else begin
|
||
Inc(AHeight, ImgSize.CY);
|
||
if AWidth < ImgSize.CX + 7 then AWidth := ImgSize.CX + 7;
|
||
end;
|
||
end;
|
||
|
||
if (RightImgSize.cx > 0) and (RightImgSize.cy > 0) then begin
|
||
if View.Orientation = tbvoVertical then
|
||
Inc(AHeight, 4 + RightImgSize.cy)
|
||
else
|
||
Inc(AWidth, 4 + RightImgSize.cx);
|
||
end;
|
||
|
||
if (tbisSubmenu in Item.ItemStyle) and (tbisCombo in Item.ItemStyle) then
|
||
Inc(AWidth, SplitBtnArrowSize)
|
||
else begin
|
||
if tboDropdownArrow in Item.Options then
|
||
if not GlyphTop or (ImgSize.CX = 0) or TextInfo.IsTextRotated then begin
|
||
if View.Orientation = tbvoVertical then Inc(AHeight, DropDownArrowSize)
|
||
else Inc(AWidth, DropDownArrowSize);
|
||
end
|
||
else
|
||
if GlyphTop and (TextInfo.IsTextRotated xor (View.Orientation <> tbvoVertical)) then begin
|
||
W := ImgSize.CX + DropDownArrowSize + 2;
|
||
if W > AWidth - 7 then AWidth := W + 7;
|
||
end
|
||
else begin
|
||
H := ImgSize.CY + DropDownArrowSize + 2;
|
||
if H > AHeight - 7 then AHeight := H + 7;
|
||
end;
|
||
end;
|
||
|
||
// Widen MenuBar SubMenuItems
|
||
if (tbisSubmenu in Item.ItemStyle) and (vsMenuBar in View.Style) then
|
||
Inc(AWidth, 6);
|
||
|
||
// Toolbar.Stretch property doesn't work correctly, I don't know how to fix
|
||
// it without changing the TB2K source.
|
||
// http://news.jrsoftware.org/read/article.php?id=8176&group=jrsoftware.toolbar2000#8176
|
||
if CalcStretch and Item.Stretch and (View is TSpTBXToolbarView) and (View.ViewerCount > 2) then begin
|
||
if View.Orientation = tbvoVertical then begin
|
||
if AWidth < TSpTBXToolbarView(View).FTallestItemSize then AWidth := TSpTBXToolbarView(View).FTallestItemSize;
|
||
end
|
||
else
|
||
if AHeight < TSpTBXToolbarView(View).FTallestItemSize then AHeight := TSpTBXToolbarView(View).FTallestItemSize;
|
||
end;
|
||
end
|
||
else begin // Menu Item
|
||
GetTextMetrics(Canvas.Handle, TextMetric);
|
||
Inc(TextInfo.TextSize.cy, TextMetric.tmExternalLeading);
|
||
|
||
AWidth := TextInfo.TextSize.cx;
|
||
AHeight := TextInfo.TextSize.cy;
|
||
|
||
if ImgSize.cy = 0 then ImgSize.cy := 16;
|
||
if AHeight < ImgSize.cy then AHeight := ImgSize.cy;
|
||
|
||
if View.Window is TSpTBXPopupWindow then
|
||
CurrentSkin.GetMenuItemMargins(Canvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, MenuMargins)
|
||
else
|
||
CurrentSkin.GetMenuItemMargins(Canvas, ImgSize.cx, MenuMargins);
|
||
|
||
Inc(AWidth, MenuMargins.Margins.Left + MenuMargins.Margins.Right);
|
||
Inc(AHeight, MenuMargins.Margins.Top + MenuMargins.Margins.Bottom);
|
||
|
||
Inc(AWidth, MenuMargins.GutterSize + MenuMargins.ImageTextSpace + MenuMargins.LeftCaptionMargin + MenuMargins.RightCaptionMargin);
|
||
WS := Item.GetShortCutText;
|
||
if Length(WS) > 0 then
|
||
Inc(AWidth, (AHeight - 6) + SpGetTextSize(Canvas.Handle, WS, True).cx);
|
||
Inc(AWidth, AHeight); { Note: maybe this should be controlled by the theme }
|
||
end;
|
||
|
||
if AWidth < Item.MinWidth then AWidth := Item.MinWidth;
|
||
if AHeight < Item.MinHeight then AHeight := Item.MinHeight;
|
||
|
||
// Handle Custom size and anchors
|
||
if IsRotated then begin
|
||
// Reverse
|
||
H := AWidth + Item.Margins;
|
||
W := AHeight;
|
||
end
|
||
else begin
|
||
W := AWidth + Item.Margins;
|
||
H := AHeight;
|
||
end;
|
||
|
||
if Item.CustomWidth > -1 then
|
||
W := Item.CustomWidth;
|
||
if Item.CustomHeight > -1 then
|
||
H := Item.CustomHeight;
|
||
|
||
if IsToolbarStyle and Item.Anchored then
|
||
W := W + FAnchorDelta;
|
||
if W < Item.MinWidth then W := Item.MinWidth;
|
||
if H < Item.MinHeight then H := Item.MinHeight;
|
||
// Apply View.MaxSize to the height of the item
|
||
if View.Window is TSpTBXToolbar then begin
|
||
TB := View.Window as TSpTBXToolbar;
|
||
I := TB.MaxSize - TB.NonClientHeight;
|
||
if (I > -1) and (H > I) then
|
||
H := I;
|
||
end;
|
||
|
||
if IsRotated then begin
|
||
// Reverse
|
||
AWidth := H;
|
||
AHeight := W;
|
||
end
|
||
else begin
|
||
AWidth := W;
|
||
AHeight := H;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.InternalMouseMove(Shift: TShiftState; X, Y: Integer);
|
||
begin
|
||
// Do nothing
|
||
end;
|
||
|
||
function TSpTBXItemViewer.IsOnToolBoxPopup: Boolean;
|
||
// Returns True if the item is on a submenu with ToolBoxPopup set to True.
|
||
begin
|
||
Result := False;
|
||
if Assigned(View) and Assigned(View.ParentItem) then
|
||
if View.ParentItem is TSpTBXCustomItem then
|
||
Result := TSpTBXCustomItem(View.ParentItem).ToolBoxPopup
|
||
else
|
||
if View.ParentItem is TSpTBXRootItem then
|
||
Result := TSpTBXRootItem(View.ParentItem).ToolBoxPopup;
|
||
end;
|
||
|
||
function TSpTBXItemViewer.IsToolbarStyle: Boolean;
|
||
// Returns True if the item is on a toolbar or has tboToolbarStyle.
|
||
// We should return False if the item is a ToolBoxPopup and the parent doesn't have tboToolbarStyle,
|
||
// the main ToolBoxPopup should be painted as a menu item on submenus/popups.
|
||
begin
|
||
Result := inherited IsToolbarStyle;
|
||
// if ToolBoxPopup and tboToolbarStyle is set see if the item is the parent
|
||
// ToolBox submenu.
|
||
if Result and Item.ToolBoxPopup and not View.IsToolbar and Assigned(View) and Assigned(View.ParentItem) then
|
||
if not (tboToolbarStyle in View.ParentItem.EffectiveOptions) then begin
|
||
// The parent item doesn't have tboToolbarStyle, so the current item
|
||
// is the main ToolBoxPopup submenu.
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer);
|
||
begin
|
||
InternalCalcSize(Canvas, True, AWidth, AHeight);
|
||
end;
|
||
|
||
function TSpTBXItemViewer.GetCaptionText: WideString;
|
||
begin
|
||
Result := SpStripShortcut(Item.Caption);
|
||
end;
|
||
|
||
function TSpTBXItemViewer.GetTextColor(State: TSpTBXSkinStatesType): TColor;
|
||
begin
|
||
Result := Item.FontSettings.Color;
|
||
if Result = clNone then begin
|
||
if IsToolbarStyle then begin
|
||
if View.Window is TSpTBXToolbar then
|
||
Result := TSpTBXToolbar(View.Window).GetItemsTextColor(State);
|
||
if Result = clNone then
|
||
Result := CurrentSkin.GetTextColor(skncToolbarItem, State);
|
||
end
|
||
else
|
||
Result := CurrentSkin.GetTextColor(skncMenuItem, State);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.GetTextInfo(ACanvas: TCanvas; State: TSpTBXSkinStatesType; out TextInfo: TSpTBXTextInfo);
|
||
var
|
||
ToolbarStyle: Boolean;
|
||
I: Integer;
|
||
const
|
||
WordWraps: array [TTextWrapping] of Cardinal = (0,
|
||
DT_SINGLELINE or DT_END_ELLIPSIS,
|
||
DT_SINGLELINE or DT_PATH_ELLIPSIS, DT_WORDBREAK);
|
||
|
||
function GetRealTextSize(TextFlags: Cardinal): TSize;
|
||
var
|
||
R, CaptionRect: TRect;
|
||
begin
|
||
TextFlags := TextFlags and not DT_SINGLELINE;
|
||
TextFlags := TextFlags and not (DT_WORDBREAK or DT_END_ELLIPSIS or DT_PATH_ELLIPSIS);
|
||
if (TextFlags and (DT_WORDBREAK or DT_END_ELLIPSIS or DT_PATH_ELLIPSIS)) <> 0 then begin
|
||
// will never get here, TextFlags doesn't have wrapping
|
||
CaptionRect := BoundsRect;
|
||
R := Rect(0, 0, CaptionRect.Right - CaptionRect.Left, 80);
|
||
end
|
||
else
|
||
R := Rect(0, 0, 1, 1);
|
||
SpDrawXPText(ACanvas, TextInfo.Text, R, TextFlags or DT_CALCRECT, gldNone, clYellow, TextInfo.TextAngle);
|
||
Result.CX := R.Right;
|
||
Result.CY := R.Bottom;
|
||
end;
|
||
|
||
begin
|
||
ToolbarStyle := IsToolbarStyle;
|
||
FillChar(TextInfo, SizeOf(TextInfo), 0);
|
||
|
||
// Setup Font
|
||
ACanvas.Font.Assign(View.GetFont);
|
||
DoDrawAdjustFont(ACanvas.Font, State); // Let the Item adjust the font
|
||
|
||
// Text Flags
|
||
TextInfo.TextFlags := 0;
|
||
if not AreKeyboardCuesEnabled and (vsUseHiddenAccels in View.Style) and
|
||
not (vsShowAccels in View.State) then TextInfo.TextFlags := DT_HIDEPREFIX;
|
||
TextInfo.TextFlags := TextInfo.TextFlags or DT_VCENTER or WordWraps[Item.Wrapping];
|
||
|
||
TextInfo.IsCaptionShown := CaptionShown;
|
||
if TextInfo.IsCaptionShown then begin
|
||
TextInfo.Text := GetCaptionText;
|
||
|
||
TextInfo.IsTextRotated := IsRotated;
|
||
if TextInfo.IsTextRotated or not ToolbarStyle then
|
||
TextInfo.TextFlags := TextInfo.TextFlags or DT_SINGLELINE;
|
||
|
||
TextInfo.TextSize := GetRealTextSize(TextInfo.TextFlags);
|
||
if TextInfo.IsTextRotated then begin
|
||
I := TextInfo.TextSize.cx;
|
||
TextInfo.TextSize.cx := TextInfo.TextSize.cy;
|
||
TextInfo.TextSize.cy := I;
|
||
end;
|
||
end
|
||
else begin
|
||
TextInfo.Text := '';
|
||
TextInfo.IsTextRotated := False;
|
||
TextInfo.TextSize.cx := 0;
|
||
TextInfo.TextSize.cy := 0;
|
||
end;
|
||
|
||
if TextInfo.IsTextRotated then
|
||
TextInfo.TextAngle := tra270
|
||
else
|
||
TextInfo.TextAngle := tra0;
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TRect;
|
||
IsSelected, IsPushed, UseDisabledShadow: Boolean);
|
||
var
|
||
View: TTBViewAccess;
|
||
ItemInfo: TSpTBXMenuItemInfo;
|
||
TextInfo: TSpTBXTextInfo;
|
||
TextAlignment: TAlignment;
|
||
TextMetrics: TTextMetric;
|
||
PaintDefault, IsSpecialDropDown: Boolean;
|
||
|
||
R, CaptionRect, ImageRect, RightImageRect: TRect;
|
||
P: TPoint;
|
||
|
||
DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize, ImgAndArrowWidth: Integer;
|
||
WS: WideString;
|
||
TextC, DropDownC: TColor;
|
||
|
||
GlyphLayout: TSpGlyphLayout;
|
||
const
|
||
WordWraps: array [TTextWrapping] of Cardinal = (0,
|
||
DT_SINGLELINE or DT_END_ELLIPSIS,
|
||
DT_SINGLELINE or DT_PATH_ELLIPSIS, DT_WORDBREAK);
|
||
begin
|
||
CaptionRect := Rect(0, 0, 0, 0);
|
||
ImageRect := Rect(0, 0, 0, 0);
|
||
RightImageRect := Rect(0, 0, 0, 0);
|
||
CurrentSkin.GetDropDownArrowSize(DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize);
|
||
|
||
View := TTBViewAccess(Self.View);
|
||
SpFillItemInfo(Canvas, Self, ItemInfo);
|
||
|
||
GlyphLayout := ghlGlyphLeft;
|
||
if tboImageAboveCaption in Item.EffectiveOptions then GlyphLayout := ghlGlyphTop;
|
||
|
||
{ Setup font and get the text info }
|
||
GetTextInfo(Canvas, ItemInfo.State, TextInfo);
|
||
TextC := Canvas.Font.Color;
|
||
TextAlignment := Item.Alignment;
|
||
|
||
// Special DropDown, toolbar item with arrow, image and text. The Image is above the caption
|
||
// the arrow must be aligned with the image, above the text
|
||
IsSpecialDropDown := ItemInfo.HasArrow and not ItemInfo.IsSplit and ItemInfo.ToolbarStyle and
|
||
(tboImageAboveCaption in Item.EffectiveOptions) and
|
||
(ItemInfo.ImageSize.cx > 0) and not (TextInfo.IsTextRotated) and (Length(Item.Caption) > 0);
|
||
|
||
{ Border & Arrows }
|
||
R := ClientAreaRect;
|
||
if ItemInfo.ToolbarStyle then begin
|
||
if ItemInfo.HasArrow then begin
|
||
if ItemInfo.IsSplit then begin
|
||
ItemInfo.ComboRect := R;
|
||
Dec(R.Right, SplitBtnArrowSize);
|
||
ItemInfo.ComboRect.Left := R.Right;
|
||
end
|
||
else
|
||
if not IsSpecialDropDown then begin
|
||
if View.Orientation <> tbvoVertical then
|
||
ItemInfo.ComboRect := Rect(R.Right - DropDownArrowSize - DropDownArrowMargin, 0,
|
||
R.Right - DropDownArrowMargin, R.Bottom)
|
||
else
|
||
ItemInfo.ComboRect := Rect(0, R.Bottom - DropDownArrowSize - DropDownArrowMargin,
|
||
R.Right, R.Bottom - DropDownArrowMargin);
|
||
end
|
||
else begin
|
||
// Special DropDown, toolbar item with arrow, image and text. The Image is above the caption
|
||
// the arrow must be aligned with the image, above the text
|
||
ImgAndArrowWidth := ItemInfo.ImageSize.cx + DropDownArrowSize + 2;
|
||
ItemInfo.ComboRect.Right := (R.Left + R.Right + ImgAndArrowWidth + 2) div 2;
|
||
ItemInfo.ComboRect.Left := ItemInfo.ComboRect.Right - DropDownArrowSize;
|
||
ItemInfo.ComboRect.Top := (R.Top + R.Bottom - ItemInfo.ImageSize.cy - 2 - TextInfo.TextSize.CY) div 2;
|
||
ItemInfo.ComboRect.Bottom := ItemInfo.ComboRect.Top + ItemInfo.ImageSize.cy;
|
||
end;
|
||
end;
|
||
|
||
PaintDefault := True;
|
||
DoDrawButton(Canvas, R, ItemInfo, pstPrePaint, PaintDefault);
|
||
if PaintDefault then
|
||
SpDrawXPMenuItem(Canvas, R, ItemInfo);
|
||
PaintDefault := True;
|
||
DoDrawButton(Canvas, R, ItemInfo, pstPostPaint, PaintDefault);
|
||
|
||
// Draw dropdown arrow
|
||
if PaintDefault and ItemInfo.HasArrow then begin
|
||
P.X := (ItemInfo.ComboRect.Left + ItemInfo.ComboRect.Right) div 2 - 1;
|
||
P.Y := (ItemInfo.ComboRect.Top + ItemInfo.ComboRect.Bottom) div 2 - 1;
|
||
// Don't draw the arrow if is a split button in Windows XP, it's
|
||
// painted by the Windows theme.
|
||
if not (ItemInfo.IsSplit and (ItemInfo.SkinType = sknWindows)) then begin
|
||
DropDownC := TextC;
|
||
if ItemInfo.IsSplit and ItemInfo.Enabled then
|
||
DropDownC := GetTextColor(ItemInfo.ComboState);
|
||
if ItemInfo.IsSunkenCaption then
|
||
P := Point(P.X + 1, P.Y + 1);
|
||
SpDrawArrow(Canvas, P.X, P.Y, DropDownC, not ItemInfo.IsVertical, False, 2);
|
||
end;
|
||
if not ItemInfo.IsSplit and not IsSpecialDropDown then begin
|
||
if View.Orientation <> tbvoVertical then Dec(R.Right, DropDownArrowSize)
|
||
else Dec(R.Bottom, DropDownArrowSize);
|
||
end;
|
||
end;
|
||
|
||
InflateRect(R, -4, -4); // Adjust
|
||
end
|
||
else begin // Menu items
|
||
PaintDefault := True;
|
||
DoDrawButton(Canvas, R, ItemInfo, pstPrePaint, PaintDefault);
|
||
if PaintDefault then
|
||
SpDrawXPMenuItem(Canvas, R, ItemInfo);
|
||
PaintDefault := True;
|
||
DoDrawButton(Canvas, R, ItemInfo, pstPostPaint, PaintDefault);
|
||
|
||
// Draw the submenu arrows
|
||
if PaintDefault and (tbisSubmenu in Item.ItemStyle) then
|
||
SpDrawArrow(Canvas, R.Right - 10, R.Bottom div 2, TextC, False, False, 3);
|
||
|
||
// Don't apply the margins if the menu item has
|
||
// tbisClicksTransparent itemstyle (like a SpTBXLabelItem)
|
||
// the caption will be automatically centered.
|
||
if not (tbisClicksTransparent in Item.ItemStyle) then begin
|
||
Inc(R.Left, ItemInfo.MenuMargins.Margins.Left);
|
||
Dec(R.Right, ItemInfo.MenuMargins.Margins.Right);
|
||
Inc(R.Top, ItemInfo.MenuMargins.Margins.Top);
|
||
Dec(R.Bottom, ItemInfo.MenuMargins.Margins.Bottom);
|
||
end;
|
||
end;
|
||
|
||
{ Caption }
|
||
if TextInfo.IsCaptionShown then
|
||
begin
|
||
WS := GetCaptionText;
|
||
|
||
if ItemInfo.ToolbarStyle then begin
|
||
TextInfo.TextFlags := TextInfo.TextFlags and not DT_VCENTER;
|
||
// When ItemInfo.RightImageSize is valid use taLeftJustify
|
||
if (ItemInfo.RightImageSize.cx > 0) and (ItemInfo.RightImageSize.cy > 0) then
|
||
TextAlignment := taLeftJustify;
|
||
case TextAlignment of
|
||
taCenter:
|
||
if GlyphLayout = ghlGlyphTop then TextInfo.TextFlags := TextInfo.TextFlags or DT_CENTER;
|
||
taRightJustify:
|
||
TextInfo.TextFlags := TextInfo.TextFlags or DT_RIGHT;
|
||
end;
|
||
SpCalcXPText(Canvas, R, WS, TextAlignment, TextInfo.TextFlags, ItemInfo.ImageSize, ItemInfo.RightImageSize, GlyphLayout, False, CaptionRect, ImageRect, RightImageRect, TextInfo.TextAngle);
|
||
|
||
if ItemInfo.IsSunkenCaption then
|
||
OffsetRect(CaptionRect, 1, 1);
|
||
end
|
||
else begin
|
||
if tbisClicksTransparent in Item.ItemStyle then begin
|
||
// The caption should be centered on the menu popup if the item has
|
||
// tbisClicksTransparent itemstyle (SpTBXLabelItem)
|
||
TextInfo.TextFlags := TextInfo.TextFlags or DT_CENTER;
|
||
CaptionRect := R;
|
||
end
|
||
else begin
|
||
TextInfo.TextFlags := TextInfo.TextFlags or DT_LEFT or DT_VCENTER;
|
||
GetTextMetrics(Canvas.Handle, TextMetrics);
|
||
CaptionRect := R;
|
||
Inc(CaptionRect.Left, ItemInfo.MenuMargins.GutterSize + ItemInfo.MenuMargins.ImageTextSpace + ItemInfo.MenuMargins.LeftCaptionMargin);
|
||
if (CaptionRect.Bottom - CaptionRect.Top) - (TextMetrics.tmHeight + TextMetrics.tmExternalLeading) = ItemInfo.MenuMargins.Margins.Bottom then
|
||
Dec(CaptionRect.Bottom);
|
||
Inc(CaptionRect.Top, TextMetrics.tmExternalLeading);
|
||
CaptionRect.Right := CaptionRect.Left + TextInfo.TextSize.CX;
|
||
end;
|
||
end;
|
||
|
||
Canvas.Font.Color := TextC;
|
||
PaintDefault := True;
|
||
DoDrawCaption(Canvas, ClientAreaRect, ItemInfo.State, WS, CaptionRect, TextInfo.TextFlags, TextInfo.IsTextRotated, pstPrePaint, PaintDefault);
|
||
if PaintDefault then begin
|
||
if (not IsSelected or ItemInfo.ToolbarStyle) and
|
||
(ItemInfo.State = sknsDisabled) and (ItemInfo.SkinType = sknNone) then
|
||
begin
|
||
OffsetRect(CaptionRect, 1, 1);
|
||
Canvas.Font.Color := clBtnHighlight;
|
||
SpDrawXPText(Canvas, WS, CaptionRect, TextInfo.TextFlags, Item.CaptionGlow, Item.CaptionGlowColor, TextInfo.TextAngle);
|
||
OffsetRect(CaptionRect, -1, -1);
|
||
Canvas.Font.Color := clGrayText;
|
||
end;
|
||
SpDrawXPText(Canvas, WS, CaptionRect, TextInfo.TextFlags, Item.CaptionGlow, Item.CaptionGlowColor, TextInfo.TextAngle);
|
||
end;
|
||
PaintDefault := True;
|
||
DoDrawCaption(Canvas, ClientAreaRect, ItemInfo.State, WS, CaptionRect, TextInfo.TextFlags, TextInfo.IsTextRotated, pstPostPaint, PaintDefault);
|
||
end;
|
||
|
||
{ Shortcut }
|
||
if not ItemInfo.ToolbarStyle then
|
||
begin
|
||
WS := Item.GetShortCutText;
|
||
if Length(WS) > 0 then
|
||
begin
|
||
CaptionRect := R;
|
||
CaptionRect.Left := CaptionRect.Right - (CaptionRect.Bottom - CaptionRect.Top) - SpGetTextSize(Canvas.Handle, WS, True).cx;
|
||
if (CaptionRect.Bottom - CaptionRect.Top) - (TextMetrics.tmHeight + TextMetrics.tmExternalLeading) = ItemInfo.MenuMargins.Margins.Bottom then
|
||
Dec(CaptionRect.Bottom);
|
||
Inc(CaptionRect.Top, TextMetrics.tmExternalLeading);
|
||
Canvas.Font.Color := TextC;
|
||
PaintDefault := True;
|
||
DoDrawCaption(Canvas, ClientAreaRect, ItemInfo.State, WS, CaptionRect, TextInfo.TextFlags, TextInfo.IsTextRotated, pstPrePaint, PaintDefault);
|
||
if PaintDefault then
|
||
SpDrawXPText(Canvas, WS, CaptionRect, TextInfo.TextFlags, Item.CaptionGlow, Item.CaptionGlowColor, TextInfo.TextAngle);
|
||
PaintDefault := True;
|
||
DoDrawCaption(Canvas, ClientAreaRect, ItemInfo.State, WS, CaptionRect, TextInfo.TextFlags, TextInfo.IsTextRotated, pstPostPaint, PaintDefault);
|
||
end;
|
||
end;
|
||
|
||
{ Image, or check box }
|
||
if ItemInfo.ImageOrCheckShown then begin
|
||
if ItemInfo.ToolBarStyle then begin
|
||
if IsRectEmpty(ImageRect) then
|
||
ImageRect := R;
|
||
if IsSpecialDropDown then OffsetRect(ImageRect, (-DropDownArrowSize + 1) div 2, 0);
|
||
end
|
||
else begin
|
||
ImageRect := R;
|
||
ImageRect.Right := ImageRect.Left + ItemInfo.MenuMargins.GutterSize;
|
||
end;
|
||
|
||
if ItemInfo.ImageShown then begin
|
||
ImageRect := SpCenterRect(ImageRect, ItemInfo.ImageSize.cx, ItemInfo.ImageSize.cy);
|
||
DrawItemImage(Canvas, ImageRect, ItemInfo, Item.ImageIndex);
|
||
end
|
||
else begin
|
||
if not ItemInfo.ToolbarStyle and Item.Checked then begin
|
||
if Item.RadioItem then
|
||
CurrentSkin.PaintMenuRadioMark(Canvas, ImageRect, True, True, ItemInfo.State)
|
||
else
|
||
CurrentSkin.PaintMenuCheckMark(Canvas, ImageRect, True, False, True, ItemInfo.State);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{ Right Image }
|
||
if ItemInfo.ToolbarStyle and (ItemInfo.RightImageSize.cx > 0) and (ItemInfo.RightImageSize.cy > 0) then begin
|
||
if IsRectEmpty(RightImageRect) then begin
|
||
RightImageRect.Left := R.Right - ItemInfo.RightImageSize.cx;
|
||
RightImageRect.Right := RightImageRect.Left + ItemInfo.RightImageSize.cx;
|
||
RightImageRect.Top := R.Top + (R.Bottom - R.Top - ItemInfo.RightImageSize.cy) div 2;
|
||
RightImageRect.Bottom := RightImageRect.Top + ItemInfo.RightImageSize.cy;
|
||
end;
|
||
DrawItemRightImage(Canvas, RightImageRect, ItemInfo);
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXItemViewer.GetItem: TSpTBXCustomItem;
|
||
var
|
||
TBItem: TTBCustomItem;
|
||
begin
|
||
TBItem := inherited Item;
|
||
if Assigned(TBItem) then
|
||
Result := TBItem as TSpTBXCustomItem
|
||
else
|
||
Result := nil;
|
||
end;
|
||
|
||
function TSpTBXItemViewer.GetHintText: Widestring;
|
||
var
|
||
I: Integer;
|
||
S: string;
|
||
begin
|
||
// Get the short hint
|
||
I := Pos('|', Item.Hint);
|
||
if I = 0 then
|
||
Result := Item.Hint
|
||
else
|
||
Result := Copy(Item.Hint, 1, I - 1);
|
||
// Use the caption if there is no hint
|
||
if (Result = '') and not(tboNoAutoHint in Item.EffectiveOptions) and
|
||
(not(tbisSubmenu in Item.ItemStyle) or (tbisCombo in Item.ItemStyle) or
|
||
not CaptionShown) then
|
||
begin
|
||
Result := SpStripAccelChars(SpStripTrailingPunctuation(Item.Caption));
|
||
end;
|
||
|
||
// Call associated action's OnHint event handler to post-process the hint
|
||
if Assigned(Item.ActionLink) and (Item.ActionLink.Action is TCustomAction) and
|
||
Assigned(TCustomAction(Item.ActionLink.Action).OnHint) then
|
||
begin
|
||
S := Result;
|
||
if TCustomAction(Item.ActionLink.Action).DoHint(S) then
|
||
Result := S
|
||
else
|
||
Result := '';
|
||
// Note: TControlActionLink.DoShowHint actually misinterprets the result of DoHint, but we get it right...
|
||
end;
|
||
|
||
// Add shortcut text
|
||
if (Result <> '') and Application.HintShortCuts and (Item.ShortCut <> scNone) then
|
||
Result := Result + ' (' + ShortCutToText(Item.ShortCut) + ')';
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.Entering;
|
||
begin
|
||
// When a Popupmenu is opened the TB2K modal handler will reset
|
||
// the TApplication.Hint in UpdateAppHint subprocedure of
|
||
// TTBModalHandler.Create, this in turn sets TTntApplication.Hint
|
||
// to AnsiString:
|
||
// ...
|
||
// if Assigned(View.FSelected) then
|
||
// Application.Hint := GetLongHint(View.FSelected.Item.Hint)
|
||
// else
|
||
// Application.Hint := '';
|
||
// ...
|
||
// We need to set TTntApplication.Hint before TB2K.
|
||
// TTntStatusBar uses TTntApplication.Hint when AutoHint is true.
|
||
|
||
inherited;
|
||
{$IFNDEF UNICODE}
|
||
if View.IsPopup then
|
||
TntApplication.Hint := Item.Hint;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TSpTBXItemViewer.CMHintShow(var Message: TMessage);
|
||
// Handle the CM_HINTSHOW message to show unicode hints using
|
||
// a custom THintWindow.
|
||
var
|
||
HintInfo: PHintInfo;
|
||
WideHint, PrevWideHint: Widestring;
|
||
R, TextR, CursorR: TRect;
|
||
PaintDefault: Boolean;
|
||
begin
|
||
HintInfo := TCMHintShow(Message).HintInfo;
|
||
WideHint := GetHintText;
|
||
CursorR := BoundsRect;
|
||
|
||
// Prepare the HintInfo
|
||
HintInfo.HintStr := WideHint;
|
||
HintInfo.CursorRect := CursorR;
|
||
HintInfo.HintWindowClass := SpTBXHintWindowClass; // Custom HintWindow class
|
||
HintInfo.HintData := SpStockHintBitmap; // TApplication.ActivateHint will pass the data to the HintWindow
|
||
HintInfo.HideTimeout := 60000; // 1 minute
|
||
|
||
// Prepare the HintBitmap
|
||
SpStockHintBitmap.Canvas.Font.Assign(Screen.HintFont);
|
||
SpStockHintBitmap.Canvas.Font.Color := clInfoText;
|
||
SpStockHintBitmap.Canvas.Pen.Color := clBlack;
|
||
SpStockHintBitmap.Canvas.Brush.Color := clInfoBk;
|
||
TextR := Rect(0, 0, 1, 1);
|
||
SpDrawXPText(SpStockHintBitmap.Canvas, WideHint, TextR, DT_NOPREFIX or DT_CALCRECT);
|
||
SpStockHintBitmap.Width := TextR.Right + 8;
|
||
SpStockHintBitmap.Height := TextR.Bottom + 4;
|
||
R := Rect(0, 0, SpStockHintBitmap.Width, SpStockHintBitmap.Height);
|
||
SpDrawXPTooltipBackground(SpStockHintBitmap.Canvas, R);
|
||
|
||
// Draw the hint in the HintBitmap
|
||
PrevWideHint := WideHint;
|
||
PaintDefault := True;
|
||
DoDrawHint(SpStockHintBitmap, HintInfo.CursorPos, CursorR, WideHint, PaintDefault);
|
||
if PaintDefault then begin
|
||
HintInfo.HintStr := WideHint;
|
||
HintInfo.CursorRect := CursorR;
|
||
|
||
// Adjust the bounds and repaint the background if it's needed
|
||
if WideHint <> PrevWideHint then begin
|
||
TextR := Rect(0, 0, 1, 1);
|
||
SpDrawXPText(SpStockHintBitmap.Canvas, WideHint, TextR, DT_NOPREFIX or DT_CALCRECT);
|
||
SpStockHintBitmap.Width := TextR.Right + 8;
|
||
SpStockHintBitmap.Height := TextR.Bottom + 4;
|
||
R := Rect(0, 0, SpStockHintBitmap.Width, SpStockHintBitmap.Height);
|
||
SpDrawXPTooltipBackground(SpStockHintBitmap.Canvas, R);
|
||
end
|
||
else
|
||
R := Rect(0, 0, SpStockHintBitmap.Width, SpStockHintBitmap.Height);
|
||
|
||
// Draw the hint
|
||
OffsetRect(TextR, ((R.Right - TextR.Right) div 2) - 2, (R.Bottom - TextR.Bottom) div 2);
|
||
SpDrawXPText(SpStockHintBitmap.Canvas, WideHint, TextR, DT_NOPREFIX);
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXRootItem }
|
||
|
||
procedure TSpTBXRootItem.DoPopupShowingChanged(APopupWindow: TTBPopupWindow; IsVisible: Boolean);
|
||
// This method is called by TSpTBXPopupWindow when the popup is Opened
|
||
begin
|
||
if Assigned(APopupWindow) then begin
|
||
if IsVisible then begin
|
||
if Assigned(FOnInitPopup) then FOnInitPopup(Self, APopupWindow.View);
|
||
end
|
||
else begin
|
||
if Assigned(FOnClosePopup) then FOnClosePopup(Self);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXRootItem.GetPopupWindowClass: TTBPopupWindowClass;
|
||
begin
|
||
Result := TSpTBXPopupWindow;
|
||
end;
|
||
|
||
procedure TSpTBXRootItem.SetToolBoxPopup(const Value: Boolean);
|
||
begin
|
||
FToolBoxPopup := Value;
|
||
if FToolBoxPopup then
|
||
Options := Options + [tboToolbarStyle]
|
||
else
|
||
Options := Options - [tboToolbarStyle];
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXSubmenuItem }
|
||
|
||
constructor TSpTBXSubmenuItem.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
ItemStyle := ItemStyle + [tbisSubMenu, tbisSubitemsEditable];
|
||
end;
|
||
|
||
function TSpTBXSubmenuItem.GetDropdownCombo: Boolean;
|
||
begin
|
||
Result := tbisCombo in ItemStyle;
|
||
end;
|
||
|
||
procedure TSpTBXSubmenuItem.SetDropdownCombo(Value: Boolean);
|
||
begin
|
||
if (tbisCombo in ItemStyle) <> Value then begin
|
||
if Value then ItemStyle := ItemStyle + [tbisCombo]
|
||
else ItemStyle := ItemStyle - [tbisCombo];
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXColorItem }
|
||
|
||
constructor TSpTBXColorItem.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
FColor := clWhite;
|
||
end;
|
||
|
||
function TSpTBXColorItem.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
|
||
begin
|
||
Result := TSpTBXColorItemViewer;
|
||
end;
|
||
|
||
procedure TSpTBXColorItem.SetColor(Value: TColor);
|
||
begin
|
||
if FColor <> Value then begin
|
||
FColor := Value;
|
||
Change(False);
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXColorItemViewer }
|
||
|
||
procedure TSpTBXColorItemViewer.DoDrawImage(ACanvas: TCanvas;
|
||
State: TSpTBXSkinStatesType; const PaintStage: TSpTBXPaintStage;
|
||
var AImageList: TCustomImageList; var AImageIndex: Integer; var ARect: TRect;
|
||
var PaintDefault: Boolean);
|
||
var
|
||
C: TColor;
|
||
begin
|
||
if PaintStage = pstPrePaint then begin
|
||
if State = sknsDisabled then begin
|
||
Inc(ARect.Right);
|
||
Inc(ARect.Bottom);
|
||
DrawEdge(ACanvas.Handle, ARect, BDR_SUNKENOUTER or BDR_RAISEDINNER, BF_RECT);
|
||
end
|
||
else begin
|
||
if not IsToolbarStyle then
|
||
InflateRect(ARect, -2, -2);
|
||
C := TSpTBXColorItem(Item).Color;
|
||
if C <> clNone then begin
|
||
ACanvas.Brush.Color := clBtnShadow;
|
||
ACanvas.FrameRect(ARect);
|
||
InflateRect(ARect, -1, -1);
|
||
ACanvas.Brush.Color := C;
|
||
ACanvas.FillRect(ARect);
|
||
end;
|
||
end;
|
||
end;
|
||
inherited;
|
||
end;
|
||
|
||
function TSpTBXColorItemViewer.GetImageShown: Boolean;
|
||
begin
|
||
Result := ((Item.DisplayMode in [nbdmDefault, nbdmImageAndText]) or
|
||
(IsToolbarStyle and (Item.DisplayMode = nbdmTextOnlyInMenus)));
|
||
end;
|
||
|
||
function TSpTBXColorItemViewer.GetImageSize: TSize;
|
||
begin
|
||
if IsToolbarStyle then begin
|
||
Result.cx := 12;
|
||
Result.cy := 12;
|
||
end
|
||
else begin
|
||
Result.cx := 16;
|
||
Result.cy := 16;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomLabelItem }
|
||
|
||
constructor TSpTBXCustomLabelItem.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
ItemStyle := ItemStyle - [tbisSelectable, tbisRedrawOnSelChange,
|
||
tbisRedrawOnMouseOverChange] + [tbisClicksTransparent];
|
||
Alignment := taLeftJustify;
|
||
Stretch := False;
|
||
DisplayMode := nbdmImageAndText;
|
||
end;
|
||
|
||
function TSpTBXCustomLabelItem.DialogChar(CharCode: Word): Boolean;
|
||
begin
|
||
Result := inherited DialogChar(CharCode);
|
||
if Enabled and Visible and Assigned(Control) and (Control is TWinControl) and
|
||
IsAccel(CharCode, Caption) and SpCanFocus(TWinControl(Control)) then
|
||
begin
|
||
TWinControl(Control).SetFocus;
|
||
Result := True;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomLabelItem.DoDrawButton(ACanvas: TCanvas; ARect: TRect;
|
||
ItemInfo: TSpTBXMenuItemInfo; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
PaintDefault := True;
|
||
inherited DoDrawButton(ACanvas, ARect, ItemInfo, PaintStage, PaintDefault);
|
||
PaintDefault := False;
|
||
end;
|
||
|
||
function TSpTBXCustomLabelItem.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
|
||
begin
|
||
Result := TSpTBXLabelItemViewer;
|
||
end;
|
||
|
||
procedure TSpTBXCustomLabelItem.ToggleControl;
|
||
begin
|
||
// Do nothing, the Control property is not valid
|
||
end;
|
||
|
||
procedure TSpTBXCustomLabelItem.UpdateProps;
|
||
begin
|
||
// Do nothing, the Control property is not valid
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXLabelItemViewer }
|
||
|
||
procedure TSpTBXLabelItemViewer.CalcSize(const Canvas: TCanvas; var AWidth,
|
||
AHeight: Integer);
|
||
var
|
||
TextMetrics: TTextMetric;
|
||
begin
|
||
inherited CalcSize(Canvas, AWidth, AHeight);
|
||
if not IsToolbarStyle and (Length(GetCaptionText) > 0) and (Item.CustomHeight <= -1) then begin
|
||
GetTextMetrics(Canvas.Handle, TextMetrics);
|
||
AHeight := TextMetrics.tmHeight;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXLabelItemViewer.DoExecute: Boolean;
|
||
begin
|
||
// Clicking a TSpTBXLabelItem on a popup menu causes the menu to close.
|
||
// This is caused by TTBXItemViewer.MouseUp, which calls
|
||
// TTBItemViewer.DoExecute
|
||
// The TBXLabelItem doesn't fire the click because the ItemViewer descends
|
||
// from TTBItemViewer instead of TTBXItemViewer.
|
||
// TTBXItemViewer.MouseUp is the culprit of firing the DoExecute
|
||
Result := False;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXSeparatorItem }
|
||
|
||
function TSpTBXSeparatorItem.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
|
||
begin
|
||
Result := TSpTBXSeparatorItemViewer;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXSeparatorItemViewer }
|
||
|
||
procedure TSpTBXSeparatorItemViewer.CalcSize(const Canvas: TCanvas; var AWidth,
|
||
AHeight: Integer);
|
||
begin
|
||
if not IsToolbarStyle then begin
|
||
if CurrentSkin.OfficeMenu then
|
||
AHeight := 4 // For Office XP, 2003, 2007
|
||
else
|
||
AHeight := 10;
|
||
end
|
||
else begin
|
||
AWidth := 6;
|
||
AHeight := 6;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXSeparatorItemViewer.IsStatusBarSeparator: Boolean;
|
||
var
|
||
C: TComponent;
|
||
begin
|
||
Result := False;
|
||
C := Item.GetParentComponent;
|
||
if Assigned(C) and (C is TSpTBXStatusToolbar) then
|
||
Result := TSpTBXStatusToolbar(C).NeedsSeparatorRepaint;
|
||
end;
|
||
|
||
procedure TSpTBXSeparatorItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TRect;
|
||
IsSelected, IsPushed, UseDisabledShadow: Boolean);
|
||
var
|
||
Vertical, MenuItemStyle: Boolean;
|
||
MarginsInfo: TSpTBXMenuItemMarginsInfo;
|
||
R: TRect;
|
||
begin
|
||
if TTBSeparatorItem(Item).Blank or IsStatusBarSeparator then
|
||
Exit;
|
||
|
||
R := ClientAreaRect;
|
||
MenuItemStyle := View.IsPopup;
|
||
if MenuItemStyle then begin
|
||
Vertical := False;
|
||
case SkinManager.GetSkinType of
|
||
sknNone:
|
||
begin
|
||
// Add separator spacing when it's not on a ToolBoxPopup
|
||
if not (tboToolbarStyle in Item.EffectiveOptions) then
|
||
InflateRect(R, -tbMenuSeparatorOffset, 0);
|
||
end;
|
||
sknWindows, sknSkin:
|
||
begin
|
||
// Draw the separator from the gutter end if the separator is not on
|
||
// a ToolBoxPopup and we are using the default Vista theme or the
|
||
// skin has a gutter specified.
|
||
if not (tboToolbarStyle in Item.EffectiveOptions) then
|
||
if SpIsWinVistaOrUp or not CurrentSkin.Options(skncGutter, sknsNormal).IsEmpty then begin
|
||
if View.Window is TSpTBXPopupWindow then
|
||
CurrentSkin.GetMenuItemMargins(Canvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, MarginsInfo)
|
||
else
|
||
CurrentSkin.GetMenuItemMargins(Canvas, 0, MarginsInfo);
|
||
if SpIsWinVistaOrUp then
|
||
R.Left := MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace
|
||
else
|
||
R.Left := MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace + MarginsInfo.LeftCaptionMargin;
|
||
end;
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
Vertical := View.Orientation <> tbvoVertical;
|
||
|
||
SpDrawXPMenuSeparator(Canvas, R, MenuItemStyle, Vertical);
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXRadioGroupItem }
|
||
|
||
constructor TSpTBXRadioGroupItem.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
FDefaultIndex := 0;
|
||
FLastClickedIndex := 0;
|
||
FStrings := TTntStringList.Create;
|
||
end;
|
||
|
||
destructor TSpTBXRadioGroupItem.Destroy;
|
||
begin
|
||
FStrings.Free;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXRadioGroupItem.DoClick(AItem: TSpTBXItem);
|
||
begin
|
||
if Assigned(FOnClick) then FOnClick(AItem);
|
||
end;
|
||
|
||
procedure TSpTBXRadioGroupItem.DoFillStrings;
|
||
begin
|
||
if Assigned(FOnFillStrings) then FOnFillStrings(Self, FStrings);
|
||
end;
|
||
|
||
procedure TSpTBXRadioGroupItem.ItemClickEvent(Sender: TObject);
|
||
var
|
||
Item: TSpTBXItem;
|
||
begin
|
||
Item := Sender as TSpTBXItem;
|
||
if not Item.Checked and (Item.Tag > -1) and (Item.Tag < FStrings.Count) then
|
||
begin
|
||
Item.Checked := True;
|
||
FLastClickedIndex := IndexOf(Item);
|
||
DoClick(Item);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXRadioGroupItem.Loaded;
|
||
begin
|
||
inherited;
|
||
if not (csDesigning in ComponentState) then
|
||
Recreate;
|
||
end;
|
||
|
||
procedure TSpTBXRadioGroupItem.Recreate;
|
||
var
|
||
I: Integer;
|
||
A: TSpTBXItem;
|
||
begin
|
||
// Delete FStrings items
|
||
FStrings.Clear;
|
||
for I := Count - 1 downto 0 do
|
||
if Items[I].GroupIndex = C_SpTBXRadioGroupIndex then
|
||
Delete(I);
|
||
|
||
DoFillStrings;
|
||
|
||
// Create group items
|
||
for I := 0 to FStrings.Count - 1 do begin
|
||
A := TSpTBXItem.Create(Self);
|
||
A.Caption := FStrings[I];
|
||
A.AutoCheck := False;
|
||
A.GroupIndex := C_SpTBXRadioGroupIndex;
|
||
A.Tag := I;
|
||
A.OnClick := ItemClickEvent;
|
||
Insert(I, A);
|
||
if I = FDefaultIndex then A.Click;
|
||
end;
|
||
|
||
if Assigned(FOnUpdate) then FOnUpdate(Self);
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXSkinGroupItem }
|
||
|
||
constructor TSpTBXSkinGroupItem.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
SkinManager.AddSkinNotification(Self);
|
||
end;
|
||
|
||
destructor TSpTBXSkinGroupItem.Destroy;
|
||
begin
|
||
SkinManager.RemoveSkinNotification(Self);
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXSkinGroupItem.DoClick(AItem: TSpTBXItem);
|
||
begin
|
||
SkinManager.SetSkin(FStrings[AItem.Tag]);
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXSkinGroupItem.DoSkinChange;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
I := FStrings.IndexOf(SkinManager.CurrentSkinName);
|
||
if I > -1 then
|
||
Items[I].Click;
|
||
|
||
if Assigned(FOnSkinChange) then FOnSkinChange(Self);
|
||
end;
|
||
|
||
procedure TSpTBXSkinGroupItem.DoFillStrings;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
{$IFNDEF UNICODE}
|
||
SkinManager.SkinsList.GetSkinNames(FStrings.AnsiStrings);
|
||
{$ELSE}
|
||
SkinManager.SkinsList.GetSkinNames(FStrings);
|
||
{$ENDIF}
|
||
|
||
// Sort the list and move the Default skin to the top
|
||
FStrings.Sort;
|
||
I := FStrings.IndexOf('Default');
|
||
if I > -1 then FStrings.Move(I, 0);
|
||
inherited;
|
||
FDefaultIndex := FStrings.IndexOf(SkinManager.CurrentSkinName);
|
||
end;
|
||
|
||
procedure TSpTBXSkinGroupItem.WMSpSkinChange(var Message: TMessage);
|
||
begin
|
||
DoSkinChange;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXSystemMenuItem }
|
||
|
||
constructor TSpTBXSystemMenuItem.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
ItemStyle := ItemStyle + [tbisSubMenu, tbisDontSelectFirst] - [tbisRedrawOnSelChange, tbisRedrawOnMouseOverChange];
|
||
Caption := '&-';
|
||
FShowSize := True;
|
||
end;
|
||
|
||
function TSpTBXSystemMenuItem.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
|
||
begin
|
||
Result := TSpTBXSystemMenuItemViewer;
|
||
end;
|
||
|
||
function TSpTBXSystemMenuItem.GetSystemMenuParentForm: TCustomForm;
|
||
var
|
||
C: TComponent;
|
||
begin
|
||
Result := nil;
|
||
C := GetParentComponent;
|
||
if Assigned(C) and (C is TControl) then
|
||
Result := GetParentForm(TControl(C));
|
||
|
||
if not Assigned(Result) and Assigned(Application.MainForm) then begin
|
||
if FMDISystemMenu then
|
||
Result := Application.MainForm.ActiveMDIChild
|
||
else
|
||
Result := Application.MainForm;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXSystemMenuItem.Click;
|
||
var
|
||
Form: TCustomForm;
|
||
begin
|
||
inherited;
|
||
Clear;
|
||
|
||
Form := GetSystemMenuParentForm;
|
||
if Assigned(Form) then
|
||
SpFillSystemSpTBXPopup(Form, Self, True, True, True, True, CommandClick);
|
||
end;
|
||
|
||
procedure TSpTBXSystemMenuItem.CommandClick(Sender: TObject);
|
||
var
|
||
Form: TCustomForm;
|
||
I: Integer;
|
||
begin
|
||
Form := GetSystemMenuParentForm;
|
||
if Assigned(Form) and Assigned(Sender) then begin
|
||
I := TComponent(Sender).Tag;
|
||
if I = SC_MAXIMIZE then
|
||
Form.WindowState := wsMaximized
|
||
else
|
||
SendMessage(Form.Handle, WM_SYSCOMMAND, I, GetMessagePos);
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXSystemMenuItemViewer }
|
||
|
||
procedure TSpTBXSystemMenuItemViewer.CalcSize(const Canvas: TCanvas;
|
||
var AWidth, AHeight: Integer);
|
||
begin
|
||
AWidth := GetSystemMetrics(SM_CXSMICON) + 2;
|
||
AHeight := GetSystemMetrics(SM_CYSMICON) + 2;
|
||
end;
|
||
|
||
procedure TSpTBXSystemMenuItemViewer.Paint(const Canvas: TCanvas;
|
||
const ClientAreaRect: TRect; IsSelected, IsPushed, UseDisabledShadow: Boolean);
|
||
|
||
function GetIconHandle: HICON;
|
||
var
|
||
Form: TForm;
|
||
begin
|
||
Result := 0;
|
||
if Assigned(Application.MainForm) then begin
|
||
if TSpTBXSystemMenuItem(Item).MDISystemMenu then
|
||
Form := Application.MainForm.ActiveMDIChild
|
||
else
|
||
Form := Application.MainForm;
|
||
if Assigned(Form) then
|
||
Result := Form.Icon.Handle;
|
||
end;
|
||
if Result = 0 then
|
||
Result := Application.Icon.Handle;
|
||
if Result = 0 then
|
||
Result := LoadIcon(0, IDI_APPLICATION);
|
||
end;
|
||
|
||
var
|
||
R: TRect;
|
||
TempIcon: HICON;
|
||
begin
|
||
R := ClientAreaRect;
|
||
InflateRect(R, -1, -1);
|
||
TempIcon := CopyImage(GetIconHandle, IMAGE_ICON, R.Right - R.Left, R.Bottom - R.Top, LR_COPYFROMRESOURCE);
|
||
try
|
||
DrawIconEx(Canvas.Handle, R.Left, R.Top, TempIcon, 0, 0, 0, 0, DI_NORMAL);
|
||
finally
|
||
DestroyIcon(TempIcon);
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomToolPalette }
|
||
|
||
constructor TSpTBXCustomToolPalette.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
FColCount := 1;
|
||
FRowCount := 1;
|
||
FSelectedCell.X := -1;
|
||
end;
|
||
|
||
function TSpTBXCustomToolPalette.DoCellClick(ACol, ARow: Integer): Boolean;
|
||
begin
|
||
Result := True;
|
||
if Assigned(FOnCellClick) then FOnCellClick(Self, ACol, ARow, Result);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolPalette.DoChange;
|
||
begin
|
||
if Assigned(FOnChange) then FOnChange(Self);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolPalette.DoDrawCellImage(ACanvas: TCanvas;
|
||
const ARect: TRect; ACol, ARow: Integer; ItemInfo: TSpTBXMenuItemInfo);
|
||
begin
|
||
if Assigned(FOnDrawCellImage) then
|
||
FOnDrawCellImage(Self, ACanvas, ARect, ACol, ARow, ItemInfo.Checked,
|
||
ItemInfo.HotTrack, ItemInfo.Enabled);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolPalette.DoGetCellHint(ACol, ARow: Integer; var AHint: WideString);
|
||
begin
|
||
if Assigned(FOnGetCellHint) then FOnGetCellHint(Self, ACol, ARow, AHint);
|
||
end;
|
||
|
||
function TSpTBXCustomToolPalette.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
|
||
begin
|
||
Result := TSpTBXToolViewer;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolPalette.HandleClickCell(ACol, ARow: Integer);
|
||
begin
|
||
if DoCellClick(ACol, ARow) then SetSelectedCell(Point(ACol, ARow));
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolPalette.SetColCount(Value: TSpTBXRowColCount);
|
||
begin
|
||
if FColCount <> Value then begin
|
||
FColCount := Value;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolPalette.SetRowCount(Value: TSpTBXRowColCount);
|
||
begin
|
||
if FRowCount <> Value then begin
|
||
FRowCount := Value;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolPalette.SetSelectedCell(Value: TPoint);
|
||
begin
|
||
FSelectedCell := Value;
|
||
Change(True);
|
||
DoChange;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXToolViewer }
|
||
|
||
constructor TSpTBXToolViewer.Create(AView: TTBView; AItem: TTBCustomItem;
|
||
AGroupLevel: Integer);
|
||
begin
|
||
inherited;
|
||
FColCount := TSpTBXCustomToolPalette(AItem).ColCount;
|
||
FRowCount := TSpTBXCustomToolPalette(AItem).RowCount;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.CalcCellSize(ACanvas: TCanvas; var AWidth, AHeight: Integer);
|
||
var
|
||
ImageSize: TSize;
|
||
begin
|
||
ImageSize := GetImageSize;
|
||
AWidth := ImageSize.cx + 6;
|
||
AHeight := ImageSize.cy + 6;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer);
|
||
var
|
||
W, H: Integer;
|
||
MarginsInfo: TSpTBXMenuItemMarginsInfo;
|
||
begin
|
||
if IsToolbarStyle then
|
||
FIndent := 0
|
||
else begin
|
||
if View.Window is TSpTBXPopupWindow then
|
||
CurrentSkin.GetMenuItemMargins(Canvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, MarginsInfo)
|
||
else
|
||
CurrentSkin.GetMenuItemMargins(Canvas, 0, MarginsInfo);
|
||
FIndent := MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace + MarginsInfo.LeftCaptionMargin - 3;
|
||
end;
|
||
|
||
FColCount := Item.ColCount;
|
||
FRowCount := Item.RowCount;
|
||
CalcCellSize(Canvas, W, H);
|
||
AWidth := FIndent + W * FColCount;
|
||
if not IsToolbarStyle then
|
||
Inc(AWidth, MarginsInfo.RightCaptionMargin);
|
||
AHeight := H * FRowCount;
|
||
if AWidth < 8 then AWidth := 8;
|
||
if AHeight < 8 then AHeight := 8;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.DoDrawHint(AHintBitmap: TBitmap; CursorPos: TPoint;
|
||
var CursorRect: TRect; var AHint: Widestring; var PaintDefault: Boolean);
|
||
var
|
||
Col, Row: Integer;
|
||
begin
|
||
if GetCellAt(CursorPos.X - BoundsRect.Left, CursorPos.Y - BoundsRect.Top, Col, Row) then begin
|
||
AHint := GetCellHint(Col, Row);
|
||
CursorRect := GetCellRect(CursorRect, Col, Row);
|
||
inherited DoDrawHint(AHintBitmap, CursorPos, CursorRect, AHint, PaintDefault);
|
||
end
|
||
else
|
||
PaintDefault := False;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.DrawCellImage(ACanvas: TCanvas; const ARect: TRect;
|
||
Col, Row: Integer; ItemInfo: TSpTBXMenuItemInfo);
|
||
var
|
||
I: Integer;
|
||
IL: TCustomImageList;
|
||
begin
|
||
if not Item.CustomImages then begin
|
||
I := GetImageIndex(Col, Row);
|
||
IL := Item.Images;
|
||
SpDrawImageList(ACanvas, ARect, IL, I, ItemInfo.Enabled, True);
|
||
end;
|
||
Item.DoDrawCellImage(ACanvas, ARect, Col, Row, ItemInfo);
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.Entering;
|
||
begin
|
||
FHotCell := Point(-1, 0);
|
||
if (View is TSpTBXPopupWindowView) and Assigned(View.Selected) then begin
|
||
if View.Selected.Index > Index then begin
|
||
FHotCell := Point(FColCount - 1, FRowCount - 1);
|
||
while (FHotCell.X > 0) and not IsCellVisible(FHotCell) do
|
||
Dec(FHotCell.X);
|
||
end
|
||
else
|
||
if View.Selected.Index < Index then
|
||
FHotCell := Point(0, 0);
|
||
end;
|
||
inherited;
|
||
end;
|
||
|
||
function TSpTBXToolViewer.GetCellAt(X, Y: Integer; out Col, Row: Integer): Boolean;
|
||
begin
|
||
if (FCellWidth = 0) or (FCellHeight = 0) then begin
|
||
Col := 0;
|
||
Row := 0;
|
||
end
|
||
else begin
|
||
Col := (X - FIndent) div FCellWidth;
|
||
Row := Y div FCellHeight;
|
||
end;
|
||
Result := (Col >= 0) and (Row >= 0) and (Col < FColCount) and (Row < FRowCount);
|
||
end;
|
||
|
||
function TSpTBXToolViewer.GetCellHint(Col, Row: Integer): WideString;
|
||
begin
|
||
Result := '';
|
||
Item.DoGetCellHint(Col, Row, Result);
|
||
end;
|
||
|
||
function TSpTBXToolViewer.GetCellRect(ClientAreaRect: TRect; Col, Row: Integer): TRect;
|
||
begin
|
||
Result := Bounds(ClientAreaRect.Left + FIndent + Col * FCellWidth, ClientAreaRect.Top + Row * FCellHeight, FCellWidth, FCellHeight);
|
||
end;
|
||
|
||
function TSpTBXToolViewer.GetImageIndex(Col, Row: Integer): Integer;
|
||
begin
|
||
Result := Col + Row * FColCount;
|
||
end;
|
||
|
||
function TSpTBXToolViewer.GetImageShown: Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
function TSpTBXToolViewer.GetImageSize: TSize;
|
||
var
|
||
IL: TCustomImageList;
|
||
begin
|
||
if Item.CustomImages then
|
||
IL := nil
|
||
else
|
||
IL := Item.Images;
|
||
|
||
if Assigned(IL) then begin
|
||
Result.cx := IL.Width;
|
||
Result.cy := IL.Height;
|
||
end
|
||
else begin
|
||
Result.cx := 12;
|
||
Result.cy := 12;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXToolViewer.GetItem: TSpTBXCustomToolPalette;
|
||
var
|
||
TBItem: TTBCustomItem;
|
||
begin
|
||
TBItem := inherited Item;
|
||
if Assigned(TBItem) then
|
||
Result := TBItem as TSpTBXCustomToolPalette
|
||
else
|
||
Result := nil;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.InvalidateCell(ACol, ARow: Integer);
|
||
var
|
||
R: TRect;
|
||
begin
|
||
R := GetCellRect(BoundsRect, ACol, ARow);
|
||
InvalidateRect(View.Window.Handle, @R, False);
|
||
end;
|
||
|
||
function TSpTBXToolViewer.IsCellVisible(Cell: TPoint): Boolean;
|
||
var
|
||
IL: TCustomImageList;
|
||
begin
|
||
Result := (Cell.X >= 0) and (Cell.Y >= 0) and (Cell.X < FColCount) and (Cell.Y < FRowCount);
|
||
if Result and not Item.CustomImages then begin
|
||
IL := Item.Images;
|
||
if Assigned(IL) then
|
||
Result := (Cell.X + Cell.Y * FColCount) < IL.Count;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.KeyDown(var Key: Word; Shift: TShiftState);
|
||
var
|
||
OldPos, Pos: TPoint;
|
||
begin
|
||
if IsCellVisible(FHotCell) then
|
||
OldPos := FHotCell
|
||
else
|
||
if IsCellVisible(Item.SelectedCell) then
|
||
OldPos := Item.SelectedCell
|
||
else
|
||
OldPos.X := -1;
|
||
|
||
if OldPos.X >= 0 then begin
|
||
Pos := OldPos;
|
||
case Key of
|
||
VK_LEFT:
|
||
begin
|
||
Dec(Pos.X);
|
||
if Pos.X < 0 then begin
|
||
Pos.X := FColCount - 1;
|
||
Dec(Pos.Y);
|
||
end;
|
||
end;
|
||
VK_UP: Dec(Pos.Y);
|
||
VK_RIGHT:
|
||
begin
|
||
Inc(Pos.X);
|
||
if Pos.X >= FColCount then
|
||
begin
|
||
Pos.X := 0;
|
||
Inc(Pos.Y);
|
||
end;
|
||
end;
|
||
VK_DOWN: Inc(Pos.Y);
|
||
VK_PRIOR: Pos.Y := 0;
|
||
VK_NEXT: Pos.Y := FRowCount - 1;
|
||
VK_HOME: Pos.X := 0;
|
||
VK_END: Pos.Y := FColCount - 1;
|
||
VK_RETURN:
|
||
if IsCellVisible(FHotCell) then begin
|
||
Item.HandleClickCell(FHotCell.X, FHotCell.Y);
|
||
Exit;
|
||
end;
|
||
else
|
||
inherited;
|
||
Exit;
|
||
end;
|
||
end
|
||
else begin
|
||
OldPos := Point(-1, 0);
|
||
Pos := Point(0, 0);
|
||
end;
|
||
|
||
if ((OldPos.X <> Pos.X) or (OldPos.Y <> Pos.Y)) and IsCellVisible(Pos) then begin
|
||
Key := 0;
|
||
FHotCell := Pos;
|
||
Item.Change(False);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.MouseDown(Shift: TShiftState; X, Y: Integer;
|
||
var MouseDownOnMenu: Boolean);
|
||
begin
|
||
FMouseIsDown := True;
|
||
MouseMove(X, Y);
|
||
inherited;
|
||
View.SetCapture;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.MouseMove(X, Y: Integer);
|
||
var
|
||
OldHotCell: TPoint;
|
||
begin
|
||
OldHotCell := FHotCell;
|
||
if not GetCellAt(X, Y, FHotCell.X, FHotCell.Y) then
|
||
FHotCell := Point(-1, 0);
|
||
|
||
if (FHotCell.X <> OldHotCell.X) or (FHotCell.Y <> OldHotCell.Y) then
|
||
if Show and not IsRectEmpty(BoundsRect) {and not (Item is TTBControlItem)} then begin
|
||
Include(State, tbisInvalidated);
|
||
InvalidateCell(OldHotCell.X, OldHotCell.Y);
|
||
InvalidateCell(FHotCell.X, FHotCell.Y);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.MouseUp(X, Y: Integer; MouseWasDownOnMenu: Boolean);
|
||
var
|
||
Col, Row: Integer;
|
||
begin
|
||
FMouseIsDown := False;
|
||
if GetCellAt(X, Y, Col, Row) then
|
||
Item.HandleClickCell(Col, Row);
|
||
View.EndModalWithClick(Self);
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXToolViewer.Paint(const Canvas: TCanvas;
|
||
const ClientAreaRect: TRect; IsSelected, IsPushed,
|
||
UseDisabledShadow: Boolean);
|
||
var
|
||
I, J: Integer;
|
||
ItemInfo: TSpTBXMenuItemInfo;
|
||
CellRect: TRect;
|
||
ItemHotTrack: Boolean;
|
||
ImageSize: TSize;
|
||
begin
|
||
CalcCellSize(Canvas, FCellWidth, FCellHeight);
|
||
|
||
SpFillItemInfo(Canvas, Self, ItemInfo);
|
||
ItemInfo.ToolbarStyle := True;
|
||
ItemHotTrack := False;
|
||
if IsSelected then
|
||
if not ItemInfo.Enabled and not View.MouseOverSelected then ItemHotTrack := True
|
||
else if ItemInfo.Enabled then ItemHotTrack := True;
|
||
|
||
for J := 0 to FRowCount - 1 do
|
||
for I := 0 to FColCount - 1 do
|
||
if IsCellVisible(Point(I, J)) then begin
|
||
ItemInfo.HotTrack := False;
|
||
ItemInfo.Pushed := False;
|
||
if ItemHotTrack and (FHotCell.X = I) and (FHotCell.Y = J) then begin
|
||
ItemInfo.HotTrack := True;
|
||
if IsPushed then ItemInfo.Pushed := True
|
||
end;
|
||
if (Item.SelectedCell.X = I) and (Item.SelectedCell.Y = J) then
|
||
ItemInfo.Checked := True
|
||
else
|
||
ItemInfo.Checked := False;
|
||
ItemInfo.State := CurrentSkin.GetState(ItemInfo.Enabled, ItemInfo.Pushed, ItemInfo.HotTrack, ItemInfo.Checked);
|
||
CellRect := GetCellRect(ClientAreaRect, I, J);
|
||
|
||
// Paint the cell
|
||
SpDrawXPMenuItem(Canvas, CellRect, ItemInfo);
|
||
ImageSize := GetImageSize;
|
||
CellRect := SpCenterRect(CellRect, ImageSize.cx, ImageSize.cy);
|
||
DrawCellImage(Canvas, CellRect, I, J, ItemInfo);
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXColorPalette }
|
||
|
||
constructor TSpTBXColorPalette.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
CustomImages := True;
|
||
FCustomColors := False;
|
||
ColCount := CPDefaultCols;
|
||
RowCount := CPDefaultRows; // 40 Default Colors
|
||
Options := Options + [tboShowHint];
|
||
FColor := clNone;
|
||
end;
|
||
|
||
procedure TSpTBXColorPalette.DoChange;
|
||
begin
|
||
if SelectedCell.X >= 0 then
|
||
FColor := GetCellColor(SelectedCell.X, SelectedCell.Y);
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXColorPalette.DoDrawCellImage(ACanvas: TCanvas;
|
||
const ARect: TRect; ACol, ARow: Integer; ItemInfo: TSpTBXMenuItemInfo);
|
||
var
|
||
R: TRect;
|
||
begin
|
||
R := ARect;
|
||
ACanvas.Brush.Color := clBtnShadow;
|
||
ACanvas.FrameRect(R);
|
||
InflateRect(R, -1, -1);
|
||
if ItemInfo.Enabled then begin
|
||
ACanvas.Brush.Color := GetCellColor(ACol, ARow);
|
||
ACanvas.FillRect(R);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXColorPalette.DoGetCellHint(ACol, ARow: Integer; var AHint: WideString);
|
||
var
|
||
C: TColor;
|
||
begin
|
||
GetCellInfo(ACol, ARow, C, AHint);
|
||
end;
|
||
|
||
function TSpTBXColorPalette.FindCell(AColor: TColor): TPoint;
|
||
var
|
||
I, J: Integer;
|
||
C: TColor;
|
||
begin
|
||
if AColor <> clNone then
|
||
AColor := ColorToRGB(AColor);
|
||
for J := 0 to RowCount - 1 do
|
||
for I := 0 to ColCount - 1 do begin
|
||
C := GetCellColor(I, J);
|
||
if C <> clNone then
|
||
C := ColorToRGB(C);
|
||
if C = AColor then begin
|
||
Result.X := I;
|
||
Result.Y := J;
|
||
Exit;
|
||
end;
|
||
end;
|
||
Result.X := -1;
|
||
Result.Y := 0;
|
||
end;
|
||
|
||
function TSpTBXColorPalette.GetCellColor(ACol, ARow: Integer): TColor;
|
||
var
|
||
W: WideString;
|
||
begin
|
||
GetCellInfo(ACol, ARow, Result, W);
|
||
end;
|
||
|
||
procedure TSpTBXColorPalette.GetCellInfo(ACol, ARow: Integer;
|
||
out AColor: TColor; out AName: WideString);
|
||
var
|
||
I: Integer;
|
||
begin
|
||
AColor := clNone;
|
||
AName := '';
|
||
if not FCustomColors then begin
|
||
I := ACol + ARow * ColCount;
|
||
if (I > -1) and (I < CPDefaultCols * CPDefaultRows) then begin
|
||
AColor := CPDefaultColors[I].Value;
|
||
AName := CPDefaultColors[I].Name;
|
||
end;
|
||
end;
|
||
|
||
if Assigned(FOnGetColor) then FOnGetColor(Self, ACol, ARow, AColor, AName);
|
||
end;
|
||
|
||
procedure TSpTBXColorPalette.SetColor(Value: TColor);
|
||
begin
|
||
FColor := Value;
|
||
SelectedCell := FindCell(Value);
|
||
end;
|
||
|
||
procedure TSpTBXColorPalette.SetCustomColors(const Value: Boolean);
|
||
begin
|
||
if FCustomColors <> Value then begin
|
||
FCustomColors := Value;
|
||
if not Value then begin
|
||
RowCount := CPDefaultCols;
|
||
ColCount := CPDefaultRows;
|
||
end;
|
||
Change(True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXColorPalette.SetColCount(Value: TSpTBXRowColCount);
|
||
begin
|
||
if FCustomColors then
|
||
inherited SetColCount(Value)
|
||
else
|
||
inherited SetColCount(CPDefaultCols);
|
||
end;
|
||
|
||
procedure TSpTBXColorPalette.SetRowCount(Value: TSpTBXRowColCount);
|
||
begin
|
||
if FCustomColors then
|
||
inherited SetRowCount(Value)
|
||
else
|
||
inherited SetRowCount(CPDefaultRows);
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXItemCache }
|
||
|
||
procedure TSpTBXItemCache.Assign(Source: TPersistent);
|
||
var
|
||
C: TSpTBXItemCache;
|
||
begin
|
||
if Source is TSpTBXItemCache then
|
||
begin
|
||
C := Source as TSpTBXItemCache;
|
||
Dock := C.Dock;
|
||
Item := C.Item;
|
||
Width := C.Width;
|
||
Height := C.Height;
|
||
ParentWidth := C.ParentWidth;
|
||
ParentHeight := C.ParentHeight;
|
||
end
|
||
else inherited Assign(Source);
|
||
end;
|
||
|
||
function TSpTBXItemCache.GetName: TComponentName;
|
||
begin
|
||
if Assigned(FItem) then
|
||
Result := FItem.Name
|
||
else
|
||
Result := FName;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXItemCacheCollection }
|
||
|
||
function TSpTBXItemCacheCollection.Add(AItem: TTBCustomItem): Integer;
|
||
var
|
||
F: TSpTBXItemCache;
|
||
begin
|
||
F := TSpTBXItemCache(inherited Add);
|
||
F.Item := AItem;
|
||
Result := F.Index;
|
||
end;
|
||
|
||
function TSpTBXItemCacheCollection.GetItem(Index: Integer): TSpTBXItemCache;
|
||
begin
|
||
Result := TSpTBXItemCache(inherited Items[Index]);
|
||
end;
|
||
|
||
function TSpTBXItemCacheCollection.IndexOf(AItem: TTBCustomItem): Integer;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
Result := -1;
|
||
if Assigned(AItem) then
|
||
for I := 0 to Count - 1 do
|
||
if Items[I].Item = AItem then begin
|
||
Result := I;
|
||
Break;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXItemCacheCollection.SetItem(Index: Integer;
|
||
const Value: TSpTBXItemCache);
|
||
begin
|
||
inherited Items[Index] := Value;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXDock }
|
||
|
||
constructor TSpTBXDock.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
Color := clNone;
|
||
SkinManager.AddSkinNotification(Self);
|
||
end;
|
||
|
||
destructor TSpTBXDock.Destroy;
|
||
begin
|
||
SkinManager.RemoveSkinNotification(Self);
|
||
inherited;
|
||
end;
|
||
|
||
function TSpTBXDock.CanResize(var NewWidth, NewHeight: Integer): Boolean;
|
||
begin
|
||
FPrevWidth := Width;
|
||
FPrevHeight := Height;
|
||
Result := inherited CanResize(NewWidth, NewHeight);
|
||
end;
|
||
|
||
procedure TSpTBXDock.DoDrawBackground(ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawBackground) then FOnDrawBackground(Self, ACanvas, ARect, PaintStage, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXDock.DrawBackground(DC: HDC; const DrawRect: TRect);
|
||
var
|
||
ACanvas: TCanvas;
|
||
PaintDefault: Boolean;
|
||
begin
|
||
// OnDrawBackground should be used to paint all the toolbars + dock, it is
|
||
// used by TSpTBXStatusBar and TSpTBXDockablePanel to paint the whole client
|
||
// area with custom painting.
|
||
// OnDrawBackground is triggered by the Dock and by the docked Toolbar.
|
||
if (csDestroying in ComponentState) then Exit;
|
||
|
||
ACanvas := TCanvas.Create;
|
||
try
|
||
ACanvas.Handle := DC;
|
||
ACanvas.Lock;
|
||
|
||
PaintDefault := True;
|
||
DoDrawBackground(ACanvas, DrawRect, pstPrePaint, PaintDefault);
|
||
if PaintDefault then begin
|
||
// Paint the Bitmap if it's assigned, or use the skin or the Color
|
||
if UsingBitmap then
|
||
inherited
|
||
else
|
||
if Color = clNone then
|
||
SpDrawXPDock(ACanvas, DrawRect, SkinManager.GetSkinType, Position in [dpLeft, dpRight])
|
||
else begin
|
||
ACanvas.Brush.Color := Color;
|
||
ACanvas.FillRect(DrawRect);
|
||
end;
|
||
end;
|
||
|
||
PaintDefault := True;
|
||
DoDrawBackground(ACanvas, DrawRect, pstPostPaint, PaintDefault);
|
||
finally
|
||
ACanvas.Unlock;
|
||
ACanvas.Handle := 0;
|
||
ACanvas.Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXDock.Resize;
|
||
var
|
||
I, J: Integer;
|
||
ResizeToolbars: Boolean;
|
||
V: TTBItemViewer;
|
||
R: TRect;
|
||
begin
|
||
inherited Resize;
|
||
|
||
// For anchored and right aligned items
|
||
if Position in [dpLeft, dpRight] then
|
||
ResizeToolbars := Height < FPrevHeight
|
||
else
|
||
ResizeToolbars := Width < FPrevWidth;
|
||
if ResizeToolbars then
|
||
for I := 0 to ToolbarCount - 1 do
|
||
if Toolbars[I] is TSpTBXToolbar then
|
||
TSpTBXToolbar(Toolbars[I]).Resize;
|
||
|
||
// Invalidate the dock and the toolbars
|
||
for J := 0 to ToolbarCount - 1 do begin
|
||
Invalidate;
|
||
if Toolbars[J] is TSpTBXToolbar then begin
|
||
with TSpTBXToolbar(Toolbars[J]) do begin
|
||
// Invalidate Control Items
|
||
for I := 0 to View.ViewerCount - 1 do begin
|
||
V := View.Viewers[I];
|
||
if V.Show and not IsRectEmpty(V.BoundsRect) and not (V.Item is TTBControlItem) then
|
||
View.Invalidate(V);
|
||
end;
|
||
// Invalidate Toolbar
|
||
Update;
|
||
if HandleAllocated then
|
||
RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_ERASE);
|
||
// Invalidate Items
|
||
for I := 0 to View.ViewerCount - 1 do begin
|
||
V := View.Viewers[I];
|
||
if V.Show and not IsRectEmpty(V.BoundsRect) and not (V.Item is TTBControlItem) then begin
|
||
R := V.BoundsRect;
|
||
ValidateRect(Handle, @R);
|
||
end;
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
if Toolbars[J] is TSpTBXCustomToolWindow then
|
||
with TSpTBXCustomToolWindow(Toolbars[J]) do begin
|
||
if HandleAllocated then
|
||
RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_ERASE);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXDock.UsingBackground: Boolean;
|
||
begin
|
||
// UsingBackground is used by TTB2Dock to repaint the Dock and Toolbars
|
||
// To check if the Dock is using a Bitmap use SpIsDockUsingBitmap instead
|
||
Result := True;
|
||
end;
|
||
|
||
function TSpTBXDock.UsingBitmap: Boolean;
|
||
begin
|
||
Result := SpIsDockUsingBitmap(Self);
|
||
end;
|
||
|
||
procedure TSpTBXDock.WMEraseBkgnd(var Message: TWMEraseBkgnd);
|
||
begin
|
||
DrawBackground(Message.DC, ClientRect);
|
||
Message.Result := 1;
|
||
end;
|
||
|
||
procedure TSpTBXDock.WMMove(var Message: TWMMove);
|
||
begin
|
||
FMoving := True;
|
||
inherited;
|
||
FMoving := False;
|
||
end;
|
||
|
||
procedure TSpTBXDock.WMSize(var Message: TWMSize);
|
||
begin
|
||
FResizing := True;
|
||
inherited;
|
||
FResizing := False;
|
||
end;
|
||
|
||
procedure TSpTBXDock.WMSpSkinChange(var Message: TMessage);
|
||
begin
|
||
Invalidate;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXToolbarView }
|
||
|
||
constructor TSpTBXToolbarView.Create(AOwner: TComponent; AParentView: TTBView;
|
||
AParentItem: TTBCustomItem; AWindow: TWinControl;
|
||
AIsToolbar, ACustomizing, AUsePriorityList: Boolean);
|
||
begin
|
||
inherited;
|
||
FMaxSize := -1;
|
||
end;
|
||
|
||
procedure TSpTBXToolbarView.DoUpdatePositions(var ASize: TPoint);
|
||
var
|
||
I, W, H: Integer;
|
||
CtlCanvas: TControlCanvas;
|
||
begin
|
||
// Find the tallest item size so we can stretch the items
|
||
// vertically (if Toolbar.Stretch is true)
|
||
FTallestItemSize := 0;
|
||
|
||
if Assigned(Window) and Window.HandleAllocated and
|
||
(Window.ClientWidth > 0) and (Window.ClientHeight > 0) and
|
||
(ViewerCount > 2) and not IsUpdating then
|
||
begin
|
||
CtlCanvas := TControlCanvas.Create;
|
||
try
|
||
CtlCanvas.Control := Window;
|
||
for I := 0 to ViewerCount - 1 do begin
|
||
W := 0;
|
||
H := 0;
|
||
if TTBCustomItem(Viewers[I].Item).Visible then
|
||
if Viewers[I] is TSpTBXItemViewer then
|
||
TSpTBXItemViewer(Viewers[I]).InternalCalcSize(CtlCanvas, False, W, H)
|
||
else
|
||
TTBItemViewerAccess(Viewers[I]).CalcSize(CtlCanvas, W, H);
|
||
if Orientation = tbvoVertical then begin
|
||
if W > FTallestItemSize then FTallestItemSize := W;
|
||
end
|
||
else
|
||
if H > FTallestItemSize then FTallestItemSize := H;
|
||
end;
|
||
finally
|
||
CtlCanvas.Free;
|
||
end;
|
||
end;
|
||
|
||
inherited DoUpdatePositions(ASize);
|
||
end;
|
||
|
||
procedure TSpTBXToolbarView.BeginUpdate;
|
||
begin
|
||
Inc(FUpdating);
|
||
inherited BeginUpdate;
|
||
end;
|
||
|
||
procedure TSpTBXToolbarView.EndUpdate;
|
||
begin
|
||
Dec(FUpdating);
|
||
inherited EndUpdate;
|
||
if FUpdating = 0 then
|
||
if Assigned(Owner) and (Owner is TSpTBXToolbar) then begin
|
||
TSpTBXToolbar(Owner).RightAlignItems;
|
||
TSpTBXToolbar(Owner).AnchorItems;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXToolbarView.IsUpdating: Boolean;
|
||
begin
|
||
Result := FUpdating > 0;
|
||
end;
|
||
|
||
procedure TSpTBXToolbarView.SetMaxSize(const Value: Integer);
|
||
begin
|
||
if FMaxSize <> Value then begin
|
||
FMaxSize := Value;
|
||
UpdatePositions;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXToolbar }
|
||
|
||
constructor TSpTBXToolbar.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
ControlStyle := ControlStyle - [csOpaque];
|
||
Color := clNone;
|
||
|
||
Items.RegisterNotification(DoItemNotification);
|
||
FAnchoredControlItems := TSpTBXItemCacheCollection.Create(TSpTBXItemCache);
|
||
FChevronVertical := True;
|
||
FCustomizable := True;
|
||
FDefaultToolbarBorderSize := CDefaultToolbarBorderSize;
|
||
FDisplayMode := tbdmSelectiveCaption;
|
||
SkinManager.AddSkinNotification(Self);
|
||
end;
|
||
|
||
destructor TSpTBXToolbar.Destroy;
|
||
begin
|
||
SkinManager.RemoveSkinNotification(Self);
|
||
Items.UnRegisterNotification(DoItemNotification);
|
||
FAnchoredControlItems.Free;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.CreateWindowHandle(const Params: TCreateParams);
|
||
begin
|
||
{$IFNDEF UNICODE}
|
||
CreateUnicodeHandle(Self, Params, '');
|
||
{$ELSE}
|
||
inherited;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.DefineProperties(Filer: TFiler);
|
||
begin
|
||
inherited;
|
||
// Don't let the streaming system store the WideStrings,
|
||
// we need to store them manually
|
||
SpPersistent_AfterInherited_DefineProperties(Filer, Self);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.DoDrawBackground(ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawBackground) then FOnDrawBackground(Self, ACanvas, ARect,
|
||
PaintStage, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.DoItemClick(Item: TTBCustomItem; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
begin
|
||
// Force OnClick event, by default tbisClicksTransparent Items doesn't get executed
|
||
if (Button = mbLeft) and Item.Enabled then
|
||
if (tbisClicksTransparent in TTBCustomItemAccess(Item).ItemStyle) then
|
||
if Assigned(Item.OnClick) then Item.OnClick(Item);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.DoItemNotification(Ancestor: TTBCustomItem;
|
||
Relayed: Boolean; Action: TTBItemChangedAction; Index: Integer;
|
||
Item: TTBCustomItem);
|
||
var
|
||
I: Integer;
|
||
begin
|
||
if (csDestroying in ComponentState) or (csReading in ComponentState) then Exit;
|
||
|
||
if not (tstResizing in FState) and not IsItemMoving then begin
|
||
if Assigned(FOnItemNotification) then FOnItemNotification(Self, Ancestor, Relayed, Action, Index, Item);
|
||
|
||
case Action of
|
||
tbicInserted:
|
||
begin
|
||
RightAlignItems;
|
||
AnchorItems(True);
|
||
end;
|
||
tbicDeleting:
|
||
begin
|
||
I := FAnchoredControlItems.IndexOf(Item);
|
||
if I > -1 then
|
||
FAnchoredControlItems.Delete(I);
|
||
RightAlignItems;
|
||
AnchorItems(True);
|
||
end;
|
||
tbicInvalidateAndResize:
|
||
begin
|
||
RightAlignItems;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.Resize;
|
||
begin
|
||
FState := FState + [tstResizing];
|
||
try
|
||
RightAlignItems;
|
||
AnchorItems;
|
||
finally
|
||
FState := FState - [tstResizing];
|
||
end;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.AnchorItems(UpdateControlItems: Boolean);
|
||
var
|
||
I, J, UpdatedDelta: Integer;
|
||
SpIV: TSpTBXItemViewer;
|
||
Size: TPoint;
|
||
CI: TTBControlItem;
|
||
IV: TTBItemViewer;
|
||
IsRotated: Boolean;
|
||
begin
|
||
if (csDestroying in ComponentState) or
|
||
(tstAnchoring in FState) or not Assigned(CurrentDock) or
|
||
(CurrentDock.Width = 0) or (CurrentDock.Height = 0) or
|
||
not Stretch or (ShrinkMode <> tbsmNone) or IsUpdating then
|
||
Exit;
|
||
|
||
FState := FState + [tstAnchoring];
|
||
View.BeginUpdate;
|
||
try
|
||
View.ValidatePositions;
|
||
IsRotated := IsVertical;
|
||
// Adjust the delta, only used when inserting/deleting an item on the toolbar
|
||
UpdatedDelta := 0;
|
||
if (FLastSelectableWidth > 0) and UpdateControlItems then begin
|
||
IV := View.NextSelectable(nil, False);
|
||
if Assigned(IV) then
|
||
if IsRotated then
|
||
UpdatedDelta := FLastSelectableWidth - IV.BoundsRect.Bottom
|
||
else
|
||
UpdatedDelta := FLastSelectableWidth - IV.BoundsRect.Right;
|
||
end;
|
||
|
||
// Calculate the Toolbar size
|
||
Size := Point(CurrentDock.Width, CurrentDock.Height);
|
||
|
||
// Resize the anchored items
|
||
for I := 0 to View.ViewerCount - 1 do
|
||
if View.Viewers[I] is TSpTBXItemViewer then begin
|
||
SpIV := View.Viewers[I] as TSpTBXItemViewer;
|
||
if SpIV.Item.Anchored then begin
|
||
// Revalidate FAnchorSize and set FAnchorDelta
|
||
if (SpIV.FAnchorSize.X = 0) and (SpIV.FAnchorSize.Y = 0) then
|
||
SpIV.FAnchorSize := Size;
|
||
|
||
// Adjust the delta, only used when inserting/deleting an item on
|
||
// the toolbar and resize
|
||
if IsRotated then begin
|
||
SpIV.FAnchorSize.Y := SpIV.FAnchorSize.Y - UpdatedDelta;
|
||
SpIV.FAnchorDelta := Size.Y - SpIV.FAnchorSize.Y;
|
||
end
|
||
else begin
|
||
SpIV.FAnchorSize.X := SpIV.FAnchorSize.X - UpdatedDelta;
|
||
SpIV.FAnchorDelta := Size.X - SpIV.FAnchorSize.X;
|
||
end;
|
||
end;
|
||
end
|
||
else begin
|
||
// Client align TTBControlItem items if the associated Control is client
|
||
// aligned or has akRight in its Anchors property.
|
||
CI := IsAnchoredControlItem(View.Viewers[I].Item);
|
||
J := FAnchoredControlItems.IndexOf(View.Viewers[I].Item);
|
||
if Assigned(CI) then begin
|
||
// Add the TTBControlItem item to the list if its not there
|
||
if J = -1 then begin
|
||
J := FAnchoredControlItems.Add(CI);
|
||
FAnchoredControlItems[J].Width := CI.Control.Width;
|
||
FAnchoredControlItems[J].Height := CI.Control.Height;
|
||
FAnchoredControlItems[J].ParentWidth := Size.X;
|
||
FAnchoredControlItems[J].ParentHeight := Size.Y;
|
||
FAnchoredControlItems[J].Dock := CurrentDock;
|
||
end;
|
||
// Resize
|
||
if FAnchoredControlItems[J].Dock = CurrentDock then begin
|
||
FAnchoredControlItems[J].Width := FAnchoredControlItems[J].Width + UpdatedDelta;
|
||
CI.Control.Width := FAnchoredControlItems[J].Width + (Size.X - FAnchoredControlItems[J].ParentWidth);
|
||
end;
|
||
end
|
||
else
|
||
// If ControlItem is not valid delete it from the list
|
||
if J > -1 then
|
||
FAnchoredControlItems.Delete(J);
|
||
end;
|
||
View.UpdatePositions;
|
||
finally
|
||
View.EndUpdate;
|
||
FState := FState - [tstAnchoring];
|
||
end;
|
||
|
||
// We can't calculate the delta based on the IV.BoundsRect because
|
||
// the IV is nil on tbicDeleting notification.
|
||
// We have to keep track of the sum of the selectable items width
|
||
IV := View.NextSelectable(nil, False);
|
||
if Assigned(IV) then begin
|
||
if IsRotated then
|
||
FLastSelectableWidth := IV.BoundsRect.Bottom
|
||
else
|
||
FLastSelectableWidth := IV.BoundsRect.Right;
|
||
end
|
||
else
|
||
FLastSelectableWidth := 0;
|
||
end;
|
||
|
||
function TSpTBXToolbar.IsAnchoredControlItem(Item: TTBCustomItem): TTBControlItem;
|
||
var
|
||
CI: TTBControlItem;
|
||
begin
|
||
Result := nil;
|
||
if Assigned(CurrentDock) and (Item is TTBControlItem) then begin
|
||
CI := Item as TTBControlItem;
|
||
if Assigned(CI.Control) and
|
||
((CI.Control.Align = alClient) or (akRight in CI.Control.Anchors)) then
|
||
begin
|
||
Result := CI;
|
||
end
|
||
else
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.RightAlignItems;
|
||
var
|
||
I, VisibleWidth, RightAlignedWidth: Integer;
|
||
Spacer: TSpTBXItemViewer;
|
||
IsRotated: Boolean;
|
||
begin
|
||
if (csDestroying in ComponentState) or (tstRightAligning in FState) or
|
||
not Assigned(CurrentDock) or (Items.Count <= 0) or
|
||
not Stretch or (ShrinkMode <> tbsmNone) or
|
||
((CurrentDock.Width <= 0) and (CurrentDock.Height <= 0)) or IsUpdating then
|
||
Exit;
|
||
|
||
FState := FState + [tstRightAligning];
|
||
View.ValidatePositions;
|
||
View.BeginUpdate;
|
||
try
|
||
// Find the spacer and the right aligned items
|
||
IsRotated := IsVertical;
|
||
Spacer := SpGetRightAlignedItems(View, nil, IsRotated, VisibleWidth, RightAlignedWidth);
|
||
if Assigned(Spacer) then begin
|
||
// Resize the spacer
|
||
if IsRotated then
|
||
I := CurrentDock.Height - GetRightAlignMargin - (VisibleWidth - (Spacer.BoundsRect.Bottom - Spacer.BoundsRect.Top))
|
||
else
|
||
I := CurrentDock.Width - GetRightAlignMargin - (VisibleWidth - (Spacer.BoundsRect.Right - Spacer.BoundsRect.Left));
|
||
|
||
if I < 0 then I := 0;
|
||
Spacer.Item.CustomWidth := I;
|
||
end;
|
||
View.UpdatePositions;
|
||
finally
|
||
View.EndUpdate;
|
||
FState := FState - [tstRightAligning];
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetChevronItemClass: TTBChevronItemClass;
|
||
begin
|
||
Result := TSpTBXChevronItem;
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetFloatingBorderSize: TPoint;
|
||
begin
|
||
if SkinManager.GetSkinType = sknSkin then
|
||
Result := Point(CurrentSkin.FloatingWindowBorderSize, CurrentSkin.FloatingWindowBorderSize)
|
||
else
|
||
Result := inherited GetFloatingBorderSize;
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetFloatingWindowParentClass: TTBFloatingWindowParentClass;
|
||
begin
|
||
Result := TSpTBXFloatingWindowParent;
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetRightAlignMargin: Integer;
|
||
begin
|
||
if IsVertical then
|
||
Result := NonClientHeight
|
||
else
|
||
Result := NonClientWidth;
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetViewClass: TTBToolbarViewClass;
|
||
begin
|
||
Result := TSpTBXToolbarView;
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetItemsTextColor(State: TSpTBXSkinStatesType): TColor;
|
||
begin
|
||
if vsMenuBar in View.Style then
|
||
Result := CurrentSkin.GetTextColor(skncMenuBarItem, State)
|
||
else
|
||
Result := CurrentSkin.GetTextColor(skncToolbarItem, State);
|
||
end;
|
||
|
||
function TSpTBXToolbar.IsVertical: Boolean;
|
||
begin
|
||
Result := SpIsVerticalToolbar(Self);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.InternalDrawBackground(ACanvas: TCanvas; ARect: TRect;
|
||
PaintOnNCArea: Boolean; PaintBorders: Boolean = True);
|
||
begin
|
||
SpDrawXPToolbar(Self, ACanvas, ARect, PaintOnNCArea, PaintBorders and (BorderStyle <> bsNone));
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.DrawNCArea(const DrawToDC: Boolean; const ADC: HDC;
|
||
const Clip: HRGN);
|
||
var
|
||
DC: HDC;
|
||
R, ExcludeR: TRect;
|
||
GripSize: Integer;
|
||
ACanvas: TCanvas;
|
||
begin
|
||
if (csDestroying in ComponentState) or not Docked or not HandleAllocated then Exit;
|
||
|
||
if not DrawToDC then DC := GetWindowDC(Handle)
|
||
else DC := ADC;
|
||
try
|
||
GetWindowRect(Handle, R);
|
||
OffsetRect(R, -R.Left, -R.Top);
|
||
GripSize := SpGetDragHandleSize(Self);
|
||
|
||
if not DrawToDC then begin
|
||
SelectNCUpdateRgn(Handle, DC, Clip);
|
||
ExcludeR := R;
|
||
InflateRect(ExcludeR, -DefaultToolbarBorderSize, -DefaultToolbarBorderSize);
|
||
if IsVertical then
|
||
Inc(ExcludeR.Top, GripSize)
|
||
else
|
||
Inc(ExcludeR.Left, GripSize);
|
||
ExcludeClipRect(DC, ExcludeR.Left, ExcludeR.Top, ExcludeR.Right, ExcludeR.Bottom);
|
||
end;
|
||
|
||
ACanvas := TCanvas.Create;
|
||
try
|
||
ACanvas.Handle := DC;
|
||
|
||
// Paint the background and borders
|
||
InternalDrawBackground(ACanvas, R, True);
|
||
|
||
// Paint the grip and close button
|
||
SpDrawXPToolbarGrip(Self, ACanvas, R);
|
||
finally
|
||
ACanvas.Handle := 0;
|
||
ACanvas.Free;
|
||
end;
|
||
finally
|
||
if not DrawToDC then ReleaseDC(Handle, DC);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.CMHintShow(var Message: TCMHintShow);
|
||
// Dispatch the message to the Item Viewer.
|
||
// TSpTBXItemViewer will handle CM_HINTSHOW message to show unicode hints using
|
||
// a custom THintWindow.
|
||
begin
|
||
with Message.HintInfo^ do begin
|
||
HintStr := '';
|
||
if Assigned(View.Selected) then begin
|
||
CursorRect := View.Selected.BoundsRect;
|
||
HintStr := View.Selected.GetHintText;
|
||
View.Selected.Dispatch(Message);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.CMControlChange(var Message: TCMControlChange);
|
||
begin
|
||
// When a control is dropped on the toolbar a TTBControlItem is created by
|
||
// TTBCustomToolbar.CreateWrapper, unfortunately it is created with the
|
||
// Self.Owner instead of the Form (Owner.Owner for CompoundToolbars like
|
||
// the TabToolbar or StatusToolbar).
|
||
|
||
if CompoundToolbar and Message.Inserting and not(csLoading in ComponentState) and
|
||
not (csUpdating in ComponentState) then
|
||
begin
|
||
CreateWrapper(Items.Count, Message.Control);
|
||
end
|
||
else
|
||
inherited;
|
||
end;
|
||
|
||
function TSpTBXToolbar.CreateWrapper(Index: Integer; Ctl: TControl): TTBControlItem;
|
||
// CreateWrapper is used only when CompoundToolbar is true, otherwise the
|
||
// wrapper is created by TB2K
|
||
var
|
||
I: Integer;
|
||
S: String;
|
||
C: TComponent;
|
||
ItemsInterface: ITBItems;
|
||
begin
|
||
Result := nil;
|
||
if SpFindControlItem(Items, Ctl) <> nil then Exit;
|
||
|
||
C := Owner.Owner; // The Form
|
||
Result := TTBControlItem.Create(C);
|
||
Result.Control := Ctl;
|
||
if (csDesigning in ComponentState) and Assigned(C) then begin
|
||
{ Needs a name for compatibility with form inheritance }
|
||
I := 1;
|
||
while True do begin
|
||
S := Format('TBControlItem%d', [I]);
|
||
if C.FindComponent(S) = nil then
|
||
Break;
|
||
Inc(I);
|
||
end;
|
||
Result.Name := S;
|
||
end;
|
||
|
||
if CompoundToolbar then begin
|
||
if Assigned(Owner) and Owner.GetInterface(ITBItems, ItemsInterface) then begin
|
||
if Index > ItemsInterface.GetItems.Count then
|
||
Index := 0;
|
||
ItemsInterface.GetItems.Insert(Index, Result)
|
||
end;
|
||
end
|
||
else
|
||
Items.Insert(Index, Result);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.CMDialogChar(var Message: TCMDialogChar);
|
||
var
|
||
I: Integer;
|
||
begin
|
||
if Enabled and Visible then
|
||
for I := 0 to Items.Count - 1 do
|
||
if Items[I] is TSpTBXCustomItem then
|
||
if TSpTBXCustomItem(Items[I]).DialogChar(Message.CharCode) then begin
|
||
Message.Result := 1;
|
||
Exit;
|
||
end;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.CMMouseleave(var Message: TMessage);
|
||
begin
|
||
inherited;
|
||
if IsCustomizing and FCustomizable then begin
|
||
// Clear the last DropMark
|
||
InvalidateRect(Handle, @FLastDropMark, True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.CMTextChanged(var Message: TMessage);
|
||
begin
|
||
inherited;
|
||
if HandleAllocated then begin
|
||
if Floating then RedrawWindow(TSpTBXFloatingWindowParent(Parent).Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE)
|
||
else RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE)
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.WMSpSkinChange(var Message: TMessage);
|
||
begin
|
||
if HandleAllocated and not Floating then
|
||
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN or RDW_FRAME);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.WMEraseBkgnd(var Message: TWMEraseBkgnd);
|
||
// Same as TSpTBXToolWindow.WMEraseBkgnd
|
||
var
|
||
ACanvas: TCanvas;
|
||
R: TRect;
|
||
begin
|
||
if (csDestroying in ComponentState) then Exit;
|
||
|
||
Message.Result := 1;
|
||
ACanvas := TCanvas.Create;
|
||
ACanvas.Handle := Message.DC;
|
||
try
|
||
R := ClientRect;
|
||
if Docked then begin
|
||
InflateRect(R, DefaultToolbarBorderSize, DefaultToolbarBorderSize);
|
||
if IsVertical then
|
||
Dec(R.Top, SpGetDragHandleSize(Self))
|
||
else
|
||
Dec(R.Left, SpGetDragHandleSize(Self));
|
||
end;
|
||
|
||
InternalDrawBackground(ACanvas, R, False);
|
||
finally
|
||
ACanvas.Handle := 0;
|
||
ACanvas.Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.WMSize(var Message: TWMSize);
|
||
var
|
||
I: Integer;
|
||
V: TTBItemViewer;
|
||
R: TRect;
|
||
begin
|
||
inherited;
|
||
|
||
if Docked and ((CurrentDock is TSpTBXDock) and not TSpTBXDock(CurrentDock).FResizing) then begin
|
||
for I := 0 to View.ViewerCount - 1 do begin
|
||
V := View.Viewers[I];
|
||
if V.Show and not IsRectEmpty(V.BoundsRect) and not (V.Item is TTBControlItem) then
|
||
View.Invalidate(V);
|
||
end;
|
||
Self.Update;
|
||
InvalidateRect(Handle, nil, True);
|
||
for I := 0 to View.ViewerCount - 1 do begin
|
||
V := View.Viewers[I];
|
||
if V.Show and not IsRectEmpty(V.BoundsRect) and not (V.Item is TTBControlItem) then begin
|
||
R := V.BoundsRect;
|
||
ValidateRect(Handle, @R);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{$IFNDEF UNICODE}
|
||
function TSpTBXToolbar.IsCaptionStored: Boolean;
|
||
begin
|
||
Result := TntControl_IsCaptionStored(Self);
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetCaption: TWideCaption;
|
||
begin
|
||
Result := TntControl_GetText(Self);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.SetCaption(const Value: TWideCaption);
|
||
begin
|
||
TntControl_SetText(Self, Value);
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetHint: WideString;
|
||
begin
|
||
Result := TntControl_GetHint(Self);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.SetHint(const Value: WideString);
|
||
begin
|
||
TntControl_SetHint(Self, Value);
|
||
end;
|
||
{$ENDIF}
|
||
|
||
procedure TSpTBXToolbar.SetCustomizable(const Value: Boolean);
|
||
begin
|
||
if FCustomizable <> Value then begin
|
||
if FMenuBar then
|
||
FCustomizable := False
|
||
else
|
||
FCustomizable := Value;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.SetDisplayMode(const Value: TSpTBXToolbarDisplayMode);
|
||
begin
|
||
if FDisplayMode <> Value then begin
|
||
FDisplayMode := Value;
|
||
if Value = tbdmImageAboveCaption then
|
||
Options := Options + [tboImageAboveCaption, tboSameWidth]
|
||
else
|
||
Options := Options - [tboImageAboveCaption, tboSameWidth];
|
||
View.UpdatePositions;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXToolbar.GetMaxSize: Integer;
|
||
begin
|
||
if Assigned(View) then
|
||
Result := TSpTBXToolbarView(View).MaxSize
|
||
else
|
||
Result := -1;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.SetMaxSize(const Value: Integer);
|
||
begin
|
||
if Assigned(View) then
|
||
TSpTBXToolbarView(View).MaxSize := Value;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.SetMenuBar(const Value: Boolean);
|
||
begin
|
||
inherited MenuBar := Value;
|
||
FMenuBar := inherited MenuBar;
|
||
FCustomizable := not FMenuBar;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.BeginUpdate;
|
||
begin
|
||
TSpTBXToolbarView(View).BeginUpdate;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.EndUpdate;
|
||
begin
|
||
TSpTBXToolbarView(View).EndUpdate;
|
||
end;
|
||
|
||
function TSpTBXToolbar.IsUpdating: Boolean;
|
||
begin
|
||
Result := TSpTBXToolbarView(View).IsUpdating;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.BeginItemMove;
|
||
begin
|
||
Inc(FItemMovingCount);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.EndItemMove;
|
||
begin
|
||
Dec(FItemMovingCount);
|
||
if FItemMovingCount < 0 then FItemMovingCount := 0;
|
||
end;
|
||
|
||
function TSpTBXToolbar.IsItemMoving: Boolean;
|
||
begin
|
||
Result := FItemMovingCount > 0;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.BeginCustomize;
|
||
begin
|
||
Inc(FCustomizingCount);
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.EndCustomize;
|
||
begin
|
||
Dec(FCustomizingCount);
|
||
if FCustomizingCount < 0 then FCustomizingCount := 0;
|
||
end;
|
||
|
||
function TSpTBXToolbar.IsCustomizing: Boolean;
|
||
begin
|
||
Result := FCustomizingCount > 0;
|
||
end;
|
||
|
||
function TSpTBXToolbar.CanDragCustomize(Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean;
|
||
var
|
||
IV: TTBItemViewer;
|
||
begin
|
||
Result := False;
|
||
FBeginDragIV := nil;
|
||
|
||
if not (csDesigning in ComponentState) and IsCustomizing then begin
|
||
Result := True;
|
||
if FCustomizable then begin
|
||
IV := SpGetItemViewerFromPoint(Items, View, Point(X, Y));
|
||
if Assigned(IV) and Assigned(IV.Item) and not (IV.Item is TTBChevronItem) then begin
|
||
FBeginDragIV := IV;
|
||
BeginDrag(True);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXToolbar.CanItemClick(Item: TTBCustomItem; Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer): Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.MouseMove(Shift: TShiftState; X, Y: Integer);
|
||
var
|
||
Item: TTBCustomItem;
|
||
begin
|
||
inherited;
|
||
|
||
// Handle the Toolbar items hints
|
||
// Set the Toolbar.Hint to change the Application.Hint when the
|
||
// mouse is over the Item.
|
||
// From TB2Toolbar.MouseMove
|
||
if not (csDesigning in ComponentState) then begin
|
||
if Assigned(View.Selected) then begin
|
||
Item := View.Selected.Item;
|
||
if not (tboLongHintInMenuOnly in Item.EffectiveOptions) then
|
||
if Item is TSpTBXCustomItem then
|
||
Hint := TSpTBXCustomItem(Item).Hint
|
||
else
|
||
Hint := Item.Hint;
|
||
// Send MouseMove to the selected viewer (with TB2K MouseMove is only
|
||
// called when the modal handler is active, we need this on the toolbar
|
||
// for the tab close button)
|
||
if View.Selected is TSpTBXItemViewer then
|
||
TSpTBXItemViewer(View.Selected).InternalMouseMove(Shift, X, Y);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
||
X, Y: Integer);
|
||
var
|
||
OldParent: TWinControl;
|
||
CurrentPos, OldPos: TPoint;
|
||
Item: TTBCustomItem;
|
||
begin
|
||
if not (csDesigning in ComponentState) and not CanDragCustomize(Button, Shift, X, Y) then begin
|
||
OldParent := Parent;
|
||
OldPos := ClientToScreen(Point(Left, Top));
|
||
if Assigned(View.Selected) then
|
||
Item := View.Selected.Item
|
||
else
|
||
Item := nil;
|
||
|
||
if CanItemClick(Item, Button, Shift, X, Y) then
|
||
inherited;
|
||
|
||
// Check if the Parent was changed due to the toolbar moving between docks
|
||
if (Parent = OldParent) and Assigned(View.Selected) then begin
|
||
// Check if the toolbar was moved across the screen
|
||
CurrentPos := ClientToScreen(Point(Left, Top));
|
||
if (CurrentPos.X = OldPos.X) and (CurrentPos.Y = OldPos.Y) then
|
||
DoItemClick(View.Selected.Item, Button, Shift, X, Y); // Extra click processing
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.DoStartDrag(var DragObject: TDragObject);
|
||
begin
|
||
if IsCustomizing and FCustomizable and Assigned(FBeginDragIV) and Assigned(FBeginDragIV.Item) then begin
|
||
// TSpTBXItemDragObject will be automatically destroyed since it's
|
||
// a descendant of TDragObjectEx.
|
||
// It's destroyed on Controls.DragDone
|
||
DragObject := TSpTBXItemDragObject.Create(Self, FBeginDragIV.Item);
|
||
inherited DoStartDrag(DragObject);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.DragOver(Source: TObject; X, Y: Integer;
|
||
State: TDragState; var Accept: Boolean);
|
||
var
|
||
DestIV: TTBItemViewer;
|
||
DestPos: Integer;
|
||
DropMark: TRect;
|
||
begin
|
||
inherited DragOver(Source, X, Y, State, Accept);
|
||
|
||
if IsCustomizing and FCustomizable then begin
|
||
Accept := True;
|
||
SpGetDropPosItemViewer(Items, View, Point(X, Y), DestIV, DestPos, DropMark);
|
||
if not EqualRect(DropMark, FLastDropMark) then begin
|
||
// Clear the last DropMark
|
||
InvalidateRect(Handle, @FLastDropMark, True);
|
||
// Draw the new DropMark
|
||
SpDrawDropMark(Canvas, DropMark);
|
||
FLastDropMark := DropMark;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.DragDrop(Source: TObject; X, Y: Integer);
|
||
var
|
||
D: TSpTBXItemDragObject;
|
||
DestIV: TTBItemViewer;
|
||
OrigItem: TTBCustomItem;
|
||
OrigPos, DestPos: Integer;
|
||
DropMark: TRect;
|
||
begin
|
||
if Assigned(Source) and (Source is TSpTBXItemDragObject) then begin
|
||
D := Source as TSpTBXItemDragObject;
|
||
OrigItem := D.SouceItem;
|
||
OrigPos := OrigItem.Parent.IndexOf(OrigItem);
|
||
|
||
// Get the destination item position
|
||
if X < 0 then X := 0;
|
||
if Y < 0 then Y := 0;
|
||
SpGetDropPosItemViewer(Items, View, Point(X, Y), DestIV, DestPos, DropMark);
|
||
if OrigItem.Parent = Items then begin
|
||
if DestPos > OrigPos then
|
||
dec(DestPos);
|
||
if (OrigPos = DestPos) then begin
|
||
// Clear the last DropMark
|
||
InvalidateRect(Handle, @FLastDropMark, True);
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
if Assigned(DestIV) and (DestPos < 0) then Exit;
|
||
|
||
// Insert the dragging item to the destination toolbar
|
||
OrigItem.Parent.Remove(OrigItem);
|
||
try
|
||
if Assigned(DestIV) then
|
||
Items.Insert(DestPos, OrigItem)
|
||
else
|
||
Items.Add(OrigItem);
|
||
|
||
if OrigItem is TTBControlItem then
|
||
if D.SourceControl <> Self then
|
||
TTBControlItem(OrigItem).Control.Parent := Self;
|
||
|
||
OrigItem.Visible := True;
|
||
FLastDropMark := Rect(0, 0, 0, 0);
|
||
except
|
||
OrigItem.Parent.Insert(OrigPos, OrigItem);
|
||
end;
|
||
end;
|
||
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.ReadPositionData(const Data: TTBReadPositionData);
|
||
begin
|
||
inherited;
|
||
with Data do
|
||
DisplayMode := TSpTBXToolbarDisplayMode(ReadIntProc(Name, rvSpTBXDisplayMode, 0, ExtraData));
|
||
end;
|
||
|
||
procedure TSpTBXToolbar.WritePositionData(const Data: TTBWritePositionData);
|
||
begin
|
||
inherited;
|
||
with Data do
|
||
WriteIntProc(Name, rvSpTBXDisplayMode, Integer(DisplayMode), ExtraData);
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomToolWindow }
|
||
|
||
constructor TSpTBXCustomToolWindow.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
FDefaultToolbarBorderSize := CDefaultToolbarBorderSize;
|
||
FMinClientWidth := 32;
|
||
FMinClientHeight := 32;
|
||
SetBounds(Left, Top, FMinClientWidth, FMinClientHeight);
|
||
|
||
Color := clNone;
|
||
SkinManager.AddSkinNotification(Self);
|
||
end;
|
||
|
||
destructor TSpTBXCustomToolWindow.Destroy;
|
||
begin
|
||
SkinManager.RemoveSkinNotification(Self);
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.CreateWindowHandle(const Params: TCreateParams);
|
||
begin
|
||
{$IFNDEF UNICODE}
|
||
CreateUnicodeHandle(Self, Params, '');
|
||
{$ELSE}
|
||
inherited;
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.DefineProperties(Filer: TFiler);
|
||
begin
|
||
inherited;
|
||
// Don't let the streaming system store the WideStrings,
|
||
// we need to store them manually
|
||
SpPersistent_AfterInherited_DefineProperties(Filer, Self);
|
||
end;
|
||
|
||
function TSpTBXCustomToolWindow.CalcSize(ADock: TTBDock): TPoint;
|
||
begin
|
||
Result.X := FBarSize.cx;
|
||
Result.Y := FBarSize.cy;
|
||
if Assigned(ADock) and (FullSize or Stretch) then begin
|
||
// If docked and stretching, return the minimum size so that the
|
||
// toolbar can shrink below FBarSize
|
||
if SpIsVerticalToolbar(Self) then
|
||
Result.Y := FMinClientHeight
|
||
else
|
||
Result.X := FMinClientWidth;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXCustomToolWindow.DoArrange(CanMoveControls: Boolean;
|
||
PreviousDockType: TTBDockType; NewFloating: Boolean; NewDock: TTBDock): TPoint;
|
||
begin
|
||
Result := CalcSize(NewDock);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.GetBaseSize(var ASize: TPoint);
|
||
begin
|
||
ASize := CalcSize(CurrentDock);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.GetMinMaxSize(var AMinClientWidth, AMinClientHeight,
|
||
AMaxClientWidth, AMaxClientHeight: Integer);
|
||
begin
|
||
// GetMinMaxSize is used only when the window is floating
|
||
AMinClientWidth := FMinClientWidth;
|
||
AMinClientHeight := FMinClientHeight;
|
||
AMaxClientWidth := FMaxClientWidth;
|
||
AMaxClientHeight := FMaxClientHeight;
|
||
end;
|
||
|
||
function TSpTBXCustomToolWindow.IsVertical: Boolean;
|
||
begin
|
||
Result := SpIsVerticalToolbar(Self);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.SizeChanging(const AWidth, AHeight: Integer);
|
||
begin
|
||
FBarSize.cx := AWidth;
|
||
FBarSize.cy := AHeight;
|
||
if Assigned(Parent) then begin
|
||
Dec(FBarSize.cx, Width - ClientWidth);
|
||
Dec(FBarSize.cy, Height - ClientHeight);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.SetClientAreaSize(AWidth, AHeight: Integer);
|
||
var
|
||
R: TRect;
|
||
begin
|
||
if Assigned(Parent) then begin
|
||
Windows.GetClientRect(Handle, R);
|
||
SetBounds(Left, Top, Width - R.Right + AWidth, Height - R.Bottom + AHeight);
|
||
end
|
||
else
|
||
SetBounds(Left, Top, AWidth, AHeight);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.Paint;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
// Dotted border in design mode
|
||
if csDesigning in ComponentState then begin
|
||
R := ClientRect;
|
||
Canvas.Pen.Style := psDot;
|
||
Canvas.Pen.Color := clBtnShadow;
|
||
Canvas.Brush.Style := bsClear;
|
||
Canvas.Rectangle(R.Left, R.Top, R.Right, R.Bottom);
|
||
Canvas.Pen.Style := psSolid;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.InternalDrawBackground(ACanvas: TCanvas;
|
||
ARect: TRect; PaintOnNCArea, PaintBorders: Boolean);
|
||
begin
|
||
SpDrawXPToolbar(Self, ACanvas, ARect, PaintOnNCArea, PaintBorders and (BorderStyle <> bsNone));
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.InvalidateBackground(InvalidateChildren: Boolean);
|
||
begin
|
||
// Force background repaint
|
||
if not (csDestroying in ComponentState) and HandleAllocated then
|
||
if InvalidateChildren then
|
||
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN)
|
||
else
|
||
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.DrawNCArea(const DrawToDC: Boolean;
|
||
const ADC: HDC; const Clip: HRGN);
|
||
var
|
||
DC: HDC;
|
||
R, ExcludeR: TRect;
|
||
GripSize: Integer;
|
||
ACanvas: TCanvas;
|
||
begin
|
||
if (csDestroying in ComponentState) or not Docked or not HandleAllocated then Exit;
|
||
|
||
if not DrawToDC then DC := GetWindowDC(Handle)
|
||
else DC := ADC;
|
||
try
|
||
GetWindowRect(Handle, R);
|
||
OffsetRect(R, -R.Left, -R.Top);
|
||
GripSize := SpGetDragHandleSize(Self);
|
||
|
||
if not DrawToDC then begin
|
||
SelectNCUpdateRgn(Handle, DC, Clip);
|
||
ExcludeR := R;
|
||
InflateRect(ExcludeR, -DefaultToolbarBorderSize, -DefaultToolbarBorderSize);
|
||
if IsVertical then
|
||
Inc(ExcludeR.Top, GripSize)
|
||
else
|
||
Inc(ExcludeR.Left, GripSize);
|
||
ExcludeClipRect(DC, ExcludeR.Left, ExcludeR.Top, ExcludeR.Right, ExcludeR.Bottom);
|
||
end;
|
||
|
||
ACanvas := TCanvas.Create;
|
||
try
|
||
ACanvas.Handle := DC;
|
||
|
||
// Paint the background and borders
|
||
InternalDrawBackground(ACanvas, R, True);
|
||
|
||
// Paint the grip and close button
|
||
SpDrawXPToolbarGrip(Self, ACanvas, R);
|
||
finally
|
||
ACanvas.Handle := 0;
|
||
ACanvas.Free;
|
||
end;
|
||
finally
|
||
if not DrawToDC then ReleaseDC(Handle, DC);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.DoDrawBackground(ACanvas: TCanvas;
|
||
ARect: TRect; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawBackground) then FOnDrawBackground(Self, ACanvas, ARect, PaintStage, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.ReadPositionData(const Data: TTBReadPositionData);
|
||
var
|
||
W, H: Integer;
|
||
begin
|
||
inherited;
|
||
// Load ClientAreaWidth/ClientAreaHeight
|
||
if Resizable then
|
||
with Data do begin
|
||
W := ReadIntProc(Name, rvClientWidth, FBarSize.cx, ExtraData);
|
||
H := ReadIntProc(Name, rvClientHeight, FBarSize.cy, ExtraData);
|
||
SetClientAreaSize(W, H);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.WritePositionData(const Data: TTBWritePositionData);
|
||
begin
|
||
inherited;
|
||
// Save ClientAreaWidth/ClientAreaHeight
|
||
with Data do begin
|
||
WriteIntProc(Name, rvClientWidth, ClientAreaWidth, ExtraData);
|
||
WriteIntProc(Name, rvClientHeight, ClientAreaHeight, ExtraData);
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXCustomToolWindow.GetFloatingBorderSize: TPoint;
|
||
begin
|
||
if SkinManager.GetSkinType = sknSkin then
|
||
Result := Point(CurrentSkin.FloatingWindowBorderSize, CurrentSkin.FloatingWindowBorderSize)
|
||
else
|
||
Result := inherited GetFloatingBorderSize;
|
||
end;
|
||
|
||
function TSpTBXCustomToolWindow.GetFloatingWindowParentClass: TTBFloatingWindowParentClass;
|
||
begin
|
||
Result := TSpTBXFloatingWindowParent;
|
||
end;
|
||
|
||
{$IFNDEF UNICODE}
|
||
function TSpTBXCustomToolWindow.IsCaptionStored: Boolean;
|
||
begin
|
||
Result := TntControl_IsCaptionStored(Self);
|
||
end;
|
||
|
||
function TSpTBXCustomToolWindow.GetCaption: TWideCaption;
|
||
begin
|
||
Result := TntControl_GetText(Self);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.SetCaption(const Value: TWideCaption);
|
||
begin
|
||
TntControl_SetText(Self, Value);
|
||
end;
|
||
{$ENDIF}
|
||
|
||
function TSpTBXCustomToolWindow.GetClientAreaWidth: Integer;
|
||
begin
|
||
if Assigned(Parent) then Result := ClientWidth
|
||
else Result := Width;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.SetClientAreaWidth(Value: Integer);
|
||
begin
|
||
SetClientAreaSize(Value, ClientAreaHeight);
|
||
end;
|
||
|
||
function TSpTBXCustomToolWindow.GetClientAreaHeight: Integer;
|
||
begin
|
||
if Assigned(Parent) then Result := ClientHeight
|
||
else Result := Height;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.SetClientAreaHeight(Value: Integer);
|
||
begin
|
||
SetClientAreaSize(ClientAreaWidth, Value);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.CMTextChanged(var Message: TMessage);
|
||
begin
|
||
inherited;
|
||
if HandleAllocated then begin
|
||
if Floating then RedrawWindow(TSpTBXFloatingWindowParent(Parent).Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE)
|
||
else RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE)
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.WMEraseBkgnd(var Message: TWMEraseBkgnd);
|
||
// Same as TSpTBXToolbar.WMEraseBkgnd
|
||
var
|
||
ACanvas: TCanvas;
|
||
R: TRect;
|
||
begin
|
||
if (csDestroying in ComponentState) then Exit;
|
||
|
||
Message.Result := 1;
|
||
ACanvas := TCanvas.Create;
|
||
ACanvas.Handle := Message.DC;
|
||
try
|
||
R := ClientRect;
|
||
if Docked then begin
|
||
InflateRect(R, DefaultToolbarBorderSize, DefaultToolbarBorderSize);
|
||
if IsVertical then
|
||
Dec(R.Top, SpGetDragHandleSize(Self))
|
||
else
|
||
Dec(R.Left, SpGetDragHandleSize(Self));
|
||
end;
|
||
|
||
InternalDrawBackground(ACanvas, R, False);
|
||
finally
|
||
ACanvas.Handle := 0;
|
||
ACanvas.Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.WMSpSkinChange(var Message: TMessage);
|
||
begin
|
||
if HandleAllocated and not Floating then
|
||
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN or RDW_FRAME);
|
||
end;
|
||
|
||
procedure TSpTBXCustomToolWindow.WMWindowPosChanged(var Message: TWMWindowPosChanged);
|
||
begin
|
||
inherited;
|
||
InvalidateBackground;
|
||
if (Message.WindowPos.flags and SWP_NOSIZE) = 0 then begin
|
||
Realign;
|
||
Update;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXFloatingWindowParent }
|
||
|
||
constructor TSpTBXFloatingWindowParent.CreateNew(AOwner: TComponent;
|
||
Dummy: Integer);
|
||
begin
|
||
inherited;
|
||
ScreenSnap := True;
|
||
SkinManager.AddSkinNotification(Self);
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.CreateWnd;
|
||
begin
|
||
inherited;
|
||
UpdateDwmNCSize;
|
||
end;
|
||
|
||
destructor TSpTBXFloatingWindowParent.Destroy;
|
||
begin
|
||
SkinManager.RemoveSkinNotification(Self);
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.DrawNCArea(const DrawToDC: Boolean;
|
||
const ADC: HDC; const Clip: HRGN; RedrawWhat: TTBToolWindowNCRedrawWhat);
|
||
const
|
||
Pattern: array [0..15] of Byte = ($C6, 0, $EE, 0, $7C, 0, $38, 0, $7C, 0, $EE, 0, $C6, 0, 0, 0);
|
||
var
|
||
DC: HDC;
|
||
R, CaptionR, CloseR: TRect;
|
||
ACanvas: TCanvas;
|
||
DockWindow: TTBCustomDockableWindowAccess;
|
||
FloatingBorderSize: TPoint;
|
||
WideCaption: WideString;
|
||
IsActive: Boolean;
|
||
Flags: Integer;
|
||
CloseButtonWidth: Integer;
|
||
SkinState: TSpTBXSkinStatesType;
|
||
PatternColor: TColor;
|
||
begin
|
||
if not HandleAllocated then Exit;
|
||
if not DrawToDC then DC := GetWindowDC(Handle)
|
||
else DC := ADC;
|
||
try
|
||
if not DrawToDC then SelectNCUpdateRgn(Handle, DC, Clip);
|
||
GetWindowRect(Handle, R);
|
||
OffsetRect(R, -R.Left, -R.Top);
|
||
with R do IntersectClipRect(DC, Left, Top, Right, Bottom);
|
||
ACanvas := TCanvas.Create;
|
||
try
|
||
ACanvas.Handle := DC;
|
||
ACanvas.Brush.Color := Color; // SpDrawXPTitleBarBody needs it to paint the background
|
||
GetWindowRect(Handle, R);
|
||
OffsetRect(R, -R.Left, -R.Top);
|
||
DockWindow := TTBCustomDockableWindowAccess(DockableWindow);
|
||
FloatingBorderSize := DockWindow.GetFloatingBorderSize;
|
||
IsActive := not DockWindow.InactiveCaption;
|
||
|
||
// Borders
|
||
if twrdBorder in RedrawWhat then
|
||
SpDrawXPTitleBarBody(ACanvas, R, IsActive, FloatingBorderSize, False);
|
||
|
||
// Caption
|
||
if DockWindow.ShowCaption then begin
|
||
R.Bottom := R.Top + FloatingBorderSize.Y + GetSystemMetrics(SM_CYSMCAPTION);
|
||
if SkinManager.GetSkinType = sknWindows then begin
|
||
if twrdBorder in RedrawWhat then
|
||
SpDrawXPTitleBar(ACanvas, R, IsActive, False);
|
||
InflateRect(R, -FloatingBorderSize.X, 0);
|
||
R.Top := R.Top + FloatingBorderSize.Y;
|
||
end
|
||
else begin
|
||
InflateRect(R, -FloatingBorderSize.X, 0);
|
||
R.Top := R.Top + FloatingBorderSize.Y;
|
||
if twrdBorder in RedrawWhat then
|
||
SpDrawXPTitleBar(ACanvas, R, IsActive, False);
|
||
end;
|
||
|
||
// Text
|
||
if twrdCaption in RedrawWhat then begin
|
||
CaptionR := R;
|
||
OffsetRect(CaptionR, 2, 0);
|
||
if DockWindow.CloseButton then
|
||
Dec(CaptionR.Right, GetSystemMetrics(SM_CYSMCAPTION) + 2);
|
||
ACanvas.Brush.Style := bsClear;
|
||
try
|
||
ACanvas.Font.Assign(SmCaptionFont);
|
||
if IsActive then
|
||
ACanvas.Font.Color := CurrentSkin.GetTextColor(skncWindowTitleBar, sknsNormal)
|
||
else
|
||
ACanvas.Font.Color := CurrentSkin.GetTextColor(skncWindowTitleBar, sknsDisabled);
|
||
|
||
if DockableWindow is TSpTBXToolbar then
|
||
WideCaption := TSpTBXToolbar(DockWindow).Caption
|
||
else
|
||
if DockableWindow is TSpTBXCustomToolWindow then
|
||
WideCaption := TSpTBXCustomToolWindow(DockWindow).Caption
|
||
else
|
||
WideCaption := '';
|
||
SpDrawXPText(ACanvas, WideCaption, CaptionR, DT_SINGLELINE or DT_VCENTER or DT_END_ELLIPSIS or DT_HIDEPREFIX);
|
||
finally
|
||
ACanvas.Brush.Style := bsSolid;
|
||
end;
|
||
end;
|
||
|
||
// Close button
|
||
if (twrdCloseButton in RedrawWhat) and DockWindow.CloseButton then begin
|
||
CloseR := R;
|
||
Dec(CloseR.Bottom);
|
||
CloseButtonWidth := (CloseR.Bottom - CloseR.Top) - 2 - 2;
|
||
CloseR.Left := CloseR.Right - CloseButtonWidth - 2; // TB2Dock.GetCloseButtonRect
|
||
CloseR.Right := CloseR.Left + CloseButtonWidth;
|
||
CloseR.Top := CloseR.Top + 2;
|
||
CloseR.Bottom := CloseR.Top + CloseButtonWidth;
|
||
|
||
case SkinManager.GetSkinType of
|
||
sknNone:
|
||
begin
|
||
if CloseButtonDown then
|
||
DrawFrameControl(ACanvas.Handle, CloseR, DFC_CAPTION, DFCS_CAPTIONCLOSE or DFCS_PUSHED)
|
||
else
|
||
DrawFrameControl(ACanvas.Handle, CloseR, DFC_CAPTION, DFCS_CAPTIONCLOSE);
|
||
end;
|
||
sknWindows:
|
||
begin
|
||
if CloseButtonDown then Flags := CBS_PUSHED
|
||
else if FCloseButtonHover then Flags := CBS_HOT
|
||
else Flags := CBS_NORMAL;
|
||
DrawThemeBackground(ThemeServices.Theme[teWindow], ACanvas.Handle, WP_SMALLCLOSEBUTTON, Flags, CloseR, nil);
|
||
end;
|
||
sknSkin:
|
||
begin
|
||
SkinState := CurrentSkin.GetState(True, CloseButtonDown, FCloseButtonHover, False);
|
||
PatternColor := CurrentSkin.GetTextColor(skncWindowTitleBar, SkinState);
|
||
if PatternColor = clNone then
|
||
PatternColor := CurrentSkin.GetTextColor(skncToolbarItem, SkinState);
|
||
CurrentSkin.PaintBackground(ACanvas, CloseR, skncToolbarItem, SkinState, True, True);
|
||
SpDrawGlyphPattern(ACanvas, CloseR, 0, PatternColor);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
finally
|
||
ACanvas.Handle := 0;
|
||
ACanvas.Free;
|
||
end;
|
||
finally
|
||
if not DrawToDC then ReleaseDC(Handle, DC);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.RedrawCloseButton;
|
||
begin
|
||
if HandleAllocated and IsWindowVisible(Handle) then
|
||
if SkinManager.GetSkinType <> sknNone then
|
||
DrawNCArea(False, 0, 0, [twrdBorder, twrdCaption, twrdCloseButton]);
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.UpdateDwmNCSize;
|
||
var
|
||
Style: Integer;
|
||
begin
|
||
if HandleAllocated then begin
|
||
// Make sure WS_THICKFRAME is setted only when Windows themes are used with
|
||
// DwmComposition, otherwise borders are incorrectly painted on Vista
|
||
Style := GetWindowLong(Handle, GWL_STYLE);
|
||
if SpIsDwmCompositionEnabled and (SkinManager.GetSkinType = sknWindows) then
|
||
Style := Style or WS_THICKFRAME
|
||
else
|
||
Style := Style and not WS_THICKFRAME;
|
||
SetWindowLong(Handle, GWL_STYLE, Style);
|
||
|
||
// Update the NC area size, CurrentSkin.FloatingWindowBorderSize could have changed
|
||
// Make sure to resize the toolbar
|
||
SpRecalcNCArea(Self);
|
||
if Assigned(DockableWindow) then
|
||
TTBCustomDockableWindowAccess(DockableWindow).Arrange;
|
||
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN or RDW_FRAME);
|
||
SpActivateDwmNC(Self, SkinManager.GetSkinType <> sknSkin);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.CancelNCHover;
|
||
begin
|
||
if FCloseButtonHover then begin
|
||
FCloseButtonHover := False;
|
||
RedrawCloseButton;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.VisibleChanging;
|
||
begin
|
||
inherited;
|
||
Caption := '';
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.CMMouseLeave(var Message: TMessage);
|
||
begin
|
||
inherited;
|
||
CancelNCHover;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.WMActivateApp(var Message: TWMActivateApp);
|
||
var
|
||
DockWindow: TTBCustomDockableWindowAccess;
|
||
begin
|
||
inherited;
|
||
|
||
// The floating window is not repainted correctly if HideWhenInactive is
|
||
// false and the application is deactivated/activated.
|
||
if HandleAllocated then begin
|
||
DockWindow := TTBCustomDockableWindowAccess(DockableWindow);
|
||
if not DockWindow.HideWhenInactive then
|
||
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.WMClose(var Message: TWMClose);
|
||
begin
|
||
if FCloseOnAltF4 then begin
|
||
if Assigned(DockableWindow) then
|
||
TTBCustomDockableWindowAccess(DockableWindow).Close;
|
||
end
|
||
else
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.WMEraseBkgnd(var Message: TMessage);
|
||
begin
|
||
Message.Result := 1;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.WMNCMouseLeave(var Message: TMessage);
|
||
begin
|
||
if not MouseCapture then CancelNCHover;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.WMNCMouseMove(var Message: TWMNCMouseMove);
|
||
var
|
||
InArea: Boolean;
|
||
begin
|
||
inherited;
|
||
{ Note: TME_NONCLIENT was introduced in Windows 98 and 2000 }
|
||
if (Win32MajorVersion >= 5) or
|
||
(Win32MajorVersion = 4) and (Win32MinorVersion >= 10) then
|
||
CallTrackMouseEvent(Handle, TME_LEAVE or $10 {TME_NONCLIENT});
|
||
InArea := Message.HitTest = 2001; {HT_TB2k_Close}
|
||
if FCloseButtonHover <> InArea then begin
|
||
FCloseButtonHover := InArea;
|
||
RedrawCloseButton;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXFloatingWindowParent.WMSpSkinChange(var Message: TMessage);
|
||
begin
|
||
UpdateDwmNCSize;
|
||
inherited;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXPopupWindow }
|
||
|
||
constructor TSpTBXPopupWindow.CreatePopupWindow(AOwner: TComponent;
|
||
const AParentView: TTBView; const AItem: TTBCustomItem;
|
||
const ACustomizing: Boolean);
|
||
begin
|
||
inherited;
|
||
if AItem is TSpTBXCustomItem then
|
||
if Assigned(View) and (View is TSpTBXPopupWindowView) then begin
|
||
if TSpTBXCustomItem(AItem).ToolbarStylePopup then
|
||
TSpTBXPopupWindowView(View).SetIsToolbar(True);
|
||
end;
|
||
|
||
FMaximumImageSize := SpGetMenuMaximumImageSize(View);
|
||
end;
|
||
|
||
destructor TSpTBXPopupWindow.Destroy;
|
||
begin
|
||
DoPopupShowingChanged(False);
|
||
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXPopupWindow.DoPopupShowingChanged(IsVisible: Boolean);
|
||
begin
|
||
if View.ParentItem is TSpTBXCustomItem then
|
||
TSpTBXCustomItem(View.ParentItem).DoPopupShowingChanged(Self, IsVisible)
|
||
else
|
||
if View.ParentItem is TSpTBXRootItem then
|
||
TSpTBXRootItem(View.ParentItem).DoPopupShowingChanged(Self, IsVisible);
|
||
end;
|
||
|
||
function TSpTBXPopupWindow.GetViewClass: TTBViewClass;
|
||
begin
|
||
Result := TSpTBXPopupWindowView;
|
||
end;
|
||
|
||
function TSpTBXPopupWindow.CanDrawGutter: Boolean;
|
||
begin
|
||
if View.IsToolbar then
|
||
Result := False
|
||
else begin
|
||
Result := True;
|
||
// Is it a toolbox?
|
||
if Assigned(View) and Assigned(View.ParentItem) then begin
|
||
if View.ParentItem is TSpTBXCustomItem then
|
||
Result := not TSpTBXCustomItem(View.ParentItem).ToolBoxPopup
|
||
else
|
||
if View.ParentItem is TSpTBXRootItem then
|
||
Result := not TSpTBXRootItem(View.ParentItem).ToolBoxPopup;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure PopupWindowNCPaintProc(Wnd: HWND; DC: HDC; AppData: TObject);
|
||
// Paints the NC area and the client background, used by WMEraseBkgnd, WMNCPaint, WMPrint
|
||
var
|
||
ACanvas: TCanvas;
|
||
R: TRect;
|
||
PopupWindow: TSpTBXPopupWindow;
|
||
begin
|
||
ACanvas := TCanvas.Create;
|
||
try
|
||
ACanvas.Handle := DC;
|
||
GetWindowRect(Wnd, R);
|
||
OffsetRect(R, -R.Left, -R.Top);
|
||
|
||
PopupWindow := TSpTBXPopupWindow(AppData);
|
||
// If it's used by WM_ERASEBKGND offset the rect
|
||
if PopupWindow.FPaintingClientArea then begin
|
||
PopupWindow.FPaintingClientArea := False;
|
||
OffsetRect(R, -3, -3);
|
||
end;
|
||
|
||
PopupWindow.PaintBackground(ACanvas, R);
|
||
finally
|
||
ACanvas.Handle := 0;
|
||
ACanvas.Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXPopupWindow.PaintBackground(ACanvas: TCanvas; ARect: TRect);
|
||
// Paints the NC area and the client background, used by WMEraseBkgnd, WMNCPaint, WMPrint
|
||
var
|
||
DrawGutter: Boolean;
|
||
OpenIVRect: TRect;
|
||
OpenIV: TTBItemViewer;
|
||
OpenIVSize: Integer;
|
||
begin
|
||
OpenIVRect := Rect(0, 0, 0, 0);
|
||
DrawGutter := False;
|
||
|
||
if Assigned(View) then begin
|
||
ACanvas.Font.Assign(ToolbarFont);
|
||
DrawGutter := CanDrawGutter;
|
||
|
||
if Assigned(View.ParentView) and CurrentSkin.OfficePopup then begin
|
||
OpenIV := TTBViewAccess(View.ParentView).OpenViewer;
|
||
if Assigned(OpenIV) and OpenIV.IsToolbarStyle and
|
||
((OpenIV is TSpTBXItemViewer) or (OpenIV is TSpTBXChevronItemViewer)) then
|
||
begin
|
||
// Get the OpenIVRect in window coordinates
|
||
OpenIVRect := OpenIV.BoundsRect;
|
||
OpenIVRect.TopLeft := View.ParentView.Window.ClientToScreen(OpenIVRect.TopLeft);
|
||
OpenIVRect.BottomRight := View.ParentView.Window.ClientToScreen(OpenIVRect.BottomRight);
|
||
OpenIVRect.TopLeft := ScreenToClient(OpenIVRect.TopLeft);
|
||
OpenIVRect.BottomRight := ScreenToClient(OpenIVRect.BottomRight);
|
||
OffsetRect(OpenIVRect, 3, 3); // Offset to get it on window coordinates
|
||
OpenIVSize := OpenIVRect.Right - OpenIVRect.Left;
|
||
|
||
// Get the Clip rect based on OpenIVRect
|
||
OpenIVRect.Left := OpenIVRect.Left + ARect.Left; // ARect.Left is -3 when called by WMEraseBkgnd and is 0 when called by WMNCPaint and WMPrint
|
||
OpenIVRect.Right := OpenIVRect.Left + OpenIVSize;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
SpDrawXPMenuPopupWindow(ACanvas, ARect, OpenIVRect, DrawGutter, MaximumImageSize.cx, sknSkin);
|
||
end;
|
||
|
||
procedure TSpTBXPopupWindow.CMHintShow(var Message: TCMHintShow);
|
||
// Dispatch the message to the Item Viewer.
|
||
// TSpTBXItemViewer will handle CM_HINTSHOW message to show unicode hints using
|
||
// a custom THintWindow.
|
||
begin
|
||
with Message.HintInfo^ do begin
|
||
HintStr := '';
|
||
if Assigned(View.Selected) then begin
|
||
CursorRect := View.Selected.BoundsRect;
|
||
HintStr := View.Selected.GetHintText;
|
||
View.Selected.Dispatch(Message);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXPopupWindow.CMShowingchanged(var Message: TMessage);
|
||
const
|
||
ShowFlags: array[Boolean] of UINT = (
|
||
SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_HIDEWINDOW,
|
||
SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_SHOWWINDOW);
|
||
var
|
||
HideEmptyPopup: Boolean;
|
||
begin
|
||
if View.ParentItem is TSpTBXSubmenuItem then
|
||
HideEmptyPopup := TSpTBXSubmenuItem(View.ParentItem).HideEmptyPopup
|
||
else
|
||
HideEmptyPopup := False;
|
||
|
||
// When the View is empty the size is set to 0 on TSpTBXPopupWindowView.AutoSize
|
||
// We should disable the animation because it can't animate an empty window
|
||
if HideEmptyPopup and Showing and (View.ViewerCount = 0) then begin
|
||
SetWindowPos(WindowHandle, 0, 0, 0, 0, 0, ShowFlags[Showing]);
|
||
end
|
||
else
|
||
inherited;
|
||
|
||
if Visible then
|
||
DoPopupShowingChanged(True);
|
||
end;
|
||
|
||
procedure TSpTBXPopupWindow.WMEraseBkgnd(var Message: TWMEraseBkgnd);
|
||
begin
|
||
case SkinManager.GetSkinType of
|
||
sknNone:
|
||
inherited;
|
||
sknWindows:
|
||
// If it's Windows theme and we're not on Vista do default painting
|
||
if not SpIsWinVistaOrUp then
|
||
inherited
|
||
else begin
|
||
Message.Result := 1;
|
||
FPaintingClientArea := True;
|
||
TBEndAnimation(WindowHandle);
|
||
PopupWindowNCPaintProc(Handle, Message.DC, Self);
|
||
end;
|
||
sknSkin:
|
||
begin
|
||
Message.Result := 1;
|
||
FPaintingClientArea := True;
|
||
TBEndAnimation(WindowHandle);
|
||
PopupWindowNCPaintProc(Handle, Message.DC, Self);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXPopupWindow.WMNCPaint(var Message: TMessage);
|
||
var
|
||
DC: HDC;
|
||
begin
|
||
DC := GetWindowDC(Handle);
|
||
try
|
||
FPaintingClientArea := False;
|
||
SelectNCUpdateRgn(Handle, DC, HRGN(Message.WParam));
|
||
PopupWindowNCPaintProc(Handle, DC, Self);
|
||
finally
|
||
ReleaseDC(Handle, DC);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXPopupWindow.WMPrint(var Message: TMessage);
|
||
begin
|
||
FPaintingClientArea := False;
|
||
HandleWMPrint(Handle, Message, PopupWindowNCPaintProc, Self);
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXPopupWindowView }
|
||
|
||
procedure TSpTBXPopupWindowView.AutoSize(AWidth, AHeight: Integer);
|
||
begin
|
||
// When the View is empty the size should be 0
|
||
if (ViewerCount = 0) and (ParentItem is TSpTBXSubmenuItem) then
|
||
if TSpTBXSubmenuItem(ParentItem).HideEmptyPopup then begin
|
||
AWidth := -(PopupMenuWindowNCSize * 2);
|
||
AHeight := -(PopupMenuWindowNCSize * 2);
|
||
end;
|
||
|
||
inherited AutoSize(AWidth, AHeight);
|
||
end;
|
||
|
||
procedure TSpTBXPopupWindowView.SetIsToolbar(const Value: Boolean);
|
||
begin
|
||
// Change the readonly IsToolbar property using RTTI, the property must
|
||
// be published.
|
||
// Tip from: http://hallvards.blogspot.com/2004/05/hack-1-write-access-to-read-only.html
|
||
PBoolean(Integer(Self) + (Integer(GetPropInfo(TSpTBXPopupWindowView, 'IsToolbar').GetProc) and $00FFFFFF))^ := Value;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXChevronItem }
|
||
|
||
function TSpTBXChevronItem.GetItemViewerClass(AView: TTBView): TTBItemViewerClass;
|
||
begin
|
||
Result := TSpTBXChevronItemViewer;
|
||
end;
|
||
|
||
function TSpTBXChevronItem.GetPopupWindowClass: TTBPopupWindowClass;
|
||
begin
|
||
Result := TSpTBXChevronPopupWindow;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXChevronItemViewer }
|
||
|
||
function TSpTBXChevronItemViewer.GetTextColor(State: TSpTBXSkinStatesType): TColor;
|
||
begin
|
||
Result := clNone;
|
||
if IsToolbarStyle then begin
|
||
if View.Window is TSpTBXToolbar then
|
||
Result := TSpTBXToolbar(View.Window).GetItemsTextColor(State);
|
||
if Result = clNone then
|
||
Result := CurrentSkin.GetTextColor(skncToolbarItem, State);
|
||
end
|
||
else
|
||
Result := CurrentSkin.GetTextColor(skncMenuItem, State);
|
||
end;
|
||
|
||
procedure TSpTBXChevronItemViewer.Paint(const Canvas: TCanvas;
|
||
const ClientAreaRect: TRect; IsSelected, IsPushed,
|
||
UseDisabledShadow: Boolean);
|
||
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
|
||
ItemInfo: TSpTBXMenuItemInfo;
|
||
R2: TRect;
|
||
P: PByte;
|
||
W, H: Integer;
|
||
DC: HDC;
|
||
PatternColor: TColor;
|
||
begin
|
||
DC := Canvas.Handle;
|
||
SpFillItemInfo(Canvas, Self, ItemInfo);
|
||
SpDrawXPMenuItem(Canvas, ClientAreaRect, ItemInfo);
|
||
|
||
// Chevron glyph
|
||
R2 := ClientAreaRect;
|
||
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);
|
||
|
||
if SkinManager.GetSkinType = sknSkin then
|
||
PatternColor := GetTextColor(ItemInfo.State)
|
||
else
|
||
PatternColor := clBtnText;
|
||
P := @Pattern[ItemInfo.IsVertical][0];
|
||
if ItemInfo.Enabled then
|
||
SpDrawGlyphPattern(DC, R2, W, H, P^, PatternColor)
|
||
else begin
|
||
OffsetRect(R2, 1, 1);
|
||
SpDrawGlyphPattern(DC, R2, W, H, P^, clBtnHighlight);
|
||
OffsetRect(R2, -1, -1);
|
||
SpDrawGlyphPattern(DC, R2, W, H, P^, clBtnShadow);
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXChevronPopupWindow }
|
||
|
||
procedure TSpTBXChevronPopupWindow.CMColorChanged(var Message: TMessage);
|
||
var
|
||
V: TSpTBXPopupWindowView;
|
||
PV: TTBView;
|
||
begin
|
||
// The private FIsToolbar field of the ChevronItem is setted to True
|
||
// in TTBCustomItem.CreatePopup, we need to reset it to False before
|
||
// the Popup is showed.
|
||
// TTBCustomItem.CreatePopup changes the PopupWindow color to clBtnFace
|
||
// after it changes the FIsToolbar value (and before it is visible),
|
||
// that's why we are trapping CM_COLORCHANGED to reset the field.
|
||
|
||
inherited;
|
||
if Assigned(View) and (View is TSpTBXPopupWindowView) then begin
|
||
V := TSpTBXPopupWindowView(View);
|
||
PV := V.ParentView;
|
||
// Do we really need to change it?
|
||
if (Color = clBtnFace) and V.IsToolbar and Assigned(PV) and
|
||
Assigned(PV.Owner) and (PV.Owner is TSpTBXToolbar) and
|
||
(TSpTBXToolbar(PV.Owner).ChevronVertical) then
|
||
begin
|
||
V.SetIsToolbar(False);
|
||
Color := clMenu;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXPopupMenu }
|
||
|
||
function TSpTBXPopupMenu.GetOnClosePopup: TNotifyEvent;
|
||
begin
|
||
Result := TSpTBXRootItem(Items).OnClosePopup;
|
||
end;
|
||
|
||
function TSpTBXPopupMenu.GetOnInitPopup: TSpTBXPopupEvent;
|
||
begin
|
||
Result := TSpTBXRootItem(Items).OnInitPopup;
|
||
end;
|
||
|
||
function TSpTBXPopupMenu.GetRootItemClass: TTBRootItemClass;
|
||
begin
|
||
Result := TSpTBXRootItem;
|
||
end;
|
||
|
||
function TSpTBXPopupMenu.InternalPopup(X, Y: Integer; ForceFocus: Boolean;
|
||
PopupControl: TControl = nil): Boolean;
|
||
var
|
||
P: TPoint;
|
||
PopupControlRect: TRect;
|
||
WinPopupControl: TWinControl;
|
||
Msg: TMessage;
|
||
begin
|
||
Result := True;
|
||
FClickedItem := nil;
|
||
P := Point(X, Y);
|
||
|
||
{$IFDEF JR_D9}
|
||
SetPopupPoint(P);
|
||
{$ELSE}
|
||
PPoint(@PopupPoint)^ := P;
|
||
{$ENDIF}
|
||
|
||
WinPopupControl := nil;
|
||
if Assigned(PopupControl) and Assigned(PopupControl.Parent) then begin
|
||
PopupControlRect := PopupControl.BoundsRect;
|
||
PopupControlRect.TopLeft := PopupControl.Parent.ClientToScreen(PopupControlRect.TopLeft);
|
||
PopupControlRect.BottomRight := PopupControl.Parent.ClientToScreen(PopupControlRect.BottomRight);
|
||
if PopupControl is TWinControl then
|
||
WinPopupControl := PopupControl as TWinControl;
|
||
end
|
||
else
|
||
PopupControlRect := Rect(X, Y, X, Y);
|
||
|
||
P.X := PopupControlRect.Left;
|
||
P.Y := PopupControlRect.Bottom;
|
||
TSpTBXRootItem(Items).ToolBoxPopup := ToolBoxPopup;
|
||
FClickedItem := Items.Popup(P.X, P.Y, TrackButton = tbRightButton,
|
||
TTBPopupAlignment(Alignment), FReturnClickedItemOnly);
|
||
|
||
if Assigned(WinPopupControl) then begin
|
||
// Send a message to the PopupControl and it's children controls
|
||
// to inform that the Popup is closed.
|
||
Msg.Msg := CM_SPPOPUPCLOSE;
|
||
Msg.WParam := Integer(Self);
|
||
Msg.LParam := 0;
|
||
Msg.Result := 0;
|
||
PostMessage(WinPopupControl.Handle, Msg.Msg, Msg.WParam, Msg.LParam);
|
||
WinPopupControl.Broadcast(Msg);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXPopupMenu.Popup(X, Y: Integer);
|
||
begin
|
||
PopupEx(X, Y);
|
||
end;
|
||
|
||
function TSpTBXPopupMenu.PopupEx(X, Y: Integer; PopupControl: TControl = nil;
|
||
ReturnClickedItemOnly: Boolean = False): TTBCustomItem;
|
||
begin
|
||
FReturnClickedItemOnly := ReturnClickedItemOnly;
|
||
try
|
||
InternalPopup(X, Y, False, PopupControl);
|
||
Result := FClickedItem;
|
||
finally
|
||
FReturnClickedItemOnly := False;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXPopupMenu.SetOnClosePopup(const Value: TNotifyEvent);
|
||
begin
|
||
TSpTBXRootItem(Items).OnClosePopup := Value;
|
||
end;
|
||
|
||
procedure TSpTBXPopupMenu.SetOnInitPopup(const Value: TSpTBXPopupEvent);
|
||
begin
|
||
TSpTBXRootItem(Items).OnInitPopup := Value;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCompoundItemsControl }
|
||
|
||
constructor TSpTBXCompoundItemsControl.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
|
||
FDock := GetDockClass.Create(Self);
|
||
FDock.Parent := Self;
|
||
FDock.OnRequestDock := DockRequestDock;
|
||
|
||
FToolbar := GetToolbarClass.Create(Self);
|
||
FToolbar.CompoundToolbar := True;
|
||
FToolbar.Parent := FDock;
|
||
FToolbar.CurrentDock := FDock;
|
||
FToolbar.Name := Name + 'Toolbar';
|
||
FToolbar.Customizable := False;
|
||
FToolbar.BorderStyle := bsNone;
|
||
FToolbar.DockMode := dmCannotFloatOrChangeDocks;
|
||
FToolbar.DragHandleStyle := dhNone;
|
||
FToolbar.Stretch := True;
|
||
FToolbar.ShrinkMode := tbsmNone;
|
||
FToolbar.ShowCaption := False;
|
||
|
||
FSkinType := sknSkin;
|
||
SkinManager.AddSkinNotification(Self);
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.CreateParams(var Params: TCreateParams);
|
||
begin
|
||
// Disable complete redraws when size changes. CS_HREDRAW and CS_VREDRAW
|
||
// cause flicker and are not necessary for this control at run time
|
||
// Invalidate in WMWindowPosChanged message instead.
|
||
inherited CreateParams(Params);
|
||
if not (csDesigning in ComponentState) then begin
|
||
with Params do
|
||
Style := Style or WS_CLIPCHILDREN;
|
||
with Params do
|
||
WindowClass.Style := WindowClass.Style and not (CS_HREDRAW or CS_VREDRAW);
|
||
end;
|
||
end;
|
||
|
||
destructor TSpTBXCompoundItemsControl.Destroy;
|
||
begin
|
||
SkinManager.RemoveSkinNotification(Self);
|
||
FToolbar.Free;
|
||
FDock.Free;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.Loaded;
|
||
var
|
||
I: Integer;
|
||
C: TControl;
|
||
DesignerRootItem: TTBCustomItem;
|
||
begin
|
||
inherited;
|
||
|
||
// The parent of TTBControlItem.Control should be the toolbar, not Self
|
||
// (as setted in GetChildren for dfm streaming).
|
||
DesignerRootItem := GetItems;
|
||
for I := 0 to DesignerRootItem.Count - 1 do
|
||
if DesignerRootItem[I] is TTBControlItem then begin
|
||
C := TTBControlItem(DesignerRootItem[I]).Control;
|
||
if Assigned(C) and (C.Parent <> FToolbar) then
|
||
C.Parent := FToolbar;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.DockRequestDock(Sender: TObject;
|
||
Bar: TTBCustomDockableWindow; var Accept: Boolean);
|
||
begin
|
||
if Assigned(FToolbar) then Accept := Bar = FToolbar;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.GetChildren(Proc: TGetChildProc;
|
||
Root: TComponent);
|
||
var
|
||
I: Integer;
|
||
C: TControl;
|
||
DesignerRootItem: TTBCustomItem;
|
||
begin
|
||
// Needed to fake the DFM streaming system because the owner of the items
|
||
// is the Form and not the Toolbar nor Self.
|
||
// But the parent must be the Toolbar.
|
||
// GetChildren is used to pass the children components of Self to the DFM
|
||
// streaming system.
|
||
// We also need to do the same with the controls of TTBControlItems.
|
||
// More info on the Delphi help or Classes.TWriter.WriteData
|
||
// Same as TSpTBXCompoundItemsControl and TSpTBXCustomDockablePanel
|
||
|
||
DesignerRootItem := GetItems;
|
||
TTBCustomItemAccess(DesignerRootItem).GetChildren(Proc, Root);
|
||
for I := 0 to DesignerRootItem.Count - 1 do
|
||
if (DesignerRootItem[I] is TTBControlItem) then begin
|
||
C := TTBControlItem(DesignerRootItem[I]).Control;
|
||
if Assigned(C) then
|
||
if SpFindControl(Self, C) = -1 then Proc(C);
|
||
end;
|
||
inherited;
|
||
end;
|
||
|
||
function TSpTBXCompoundItemsControl.GetItems: TTBCustomItem;
|
||
begin
|
||
Result := FToolbar.Items;
|
||
end;
|
||
|
||
function TSpTBXCompoundItemsControl.GetRootItems: TTBRootItem;
|
||
begin
|
||
Result := FToolbar.Items;
|
||
end;
|
||
|
||
function TSpTBXCompoundItemsControl.GetDockClass: TSpTBXDockClass;
|
||
begin
|
||
Result := TSpTBXDock;
|
||
end;
|
||
|
||
function TSpTBXCompoundItemsControl.GetToolbarClass: TSpTBXToolbarClass;
|
||
begin
|
||
Result := TSpTBXToolbar;
|
||
end;
|
||
|
||
function TSpTBXCompoundItemsControl.GetView: TSpTBXToolbarView;
|
||
begin
|
||
Result := FToolbar.View as TSpTBXToolbarView;
|
||
end;
|
||
|
||
function TSpTBXCompoundItemsControl.GetImages: TCustomImageList;
|
||
begin
|
||
if Assigned(FToolbar) then
|
||
Result := FToolbar.Images
|
||
else
|
||
Result := nil;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.InvalidateBackground(InvalidateChildren: Boolean);
|
||
begin
|
||
// Invalidate will not fire WM_ERASEBKGND, because csOpaque is setted
|
||
if not (csDestroying in ComponentState) and HandleAllocated then
|
||
if InvalidateChildren then
|
||
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN)
|
||
else
|
||
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE);
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.SetImages(const Value: TCustomImageList);
|
||
begin
|
||
if Assigned(FToolbar) then FToolbar.Images := Value;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.SetName(const Value: TComponentName);
|
||
begin
|
||
inherited;
|
||
if Name = Value then
|
||
if Assigned(FToolbar) then
|
||
FToolbar.Name := Name + 'Toolbar';
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.SetSkinType(const Value: TSpTBXSkinType);
|
||
begin
|
||
if FSkinType <> Value then begin
|
||
FSkinType := Value;
|
||
InvalidateBackground;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundItemsControl.WMSpSkinChange(var Message: TMessage);
|
||
begin
|
||
InvalidateBackground;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCompoundBar }
|
||
|
||
constructor TSpTBXCompoundBar.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
Height := FDock.Height;
|
||
FDock.OnDrawBackground := DrawDockBackground;
|
||
FDock.OnResize := DockResize;
|
||
FToolbar.OnDrawBackground := DrawToolbarBackground;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundBar.DockResize(Sender: TObject);
|
||
begin
|
||
if Assigned(FDock) then
|
||
if Height <> FDock.Height then
|
||
Height := FDock.Height;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundBar.DoDrawDockBackground(ACanvas: TCanvas;
|
||
ARect: TRect; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawDockBackground) then FOnDrawDockBackground(Self, ACanvas, ARect, PaintStage, PaintDefault);
|
||
end;
|
||
|
||
procedure TSpTBXCompoundBar.DrawDockBackground(Sender: TObject;
|
||
ACanvas: TCanvas; ARect: TRect; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean);
|
||
var
|
||
InternalPaintDefault: Boolean;
|
||
begin
|
||
if PaintStage = pstPrePaint then begin
|
||
// OnDrawBackground is triggered by the Dock and by the docked Toolbar.
|
||
// The Toolbar triggers it only if Dock.ThemedBackground is true, which depends
|
||
// on CurrentTheme.PaintDockBackground, this is done in
|
||
// TTBXToolbar.WMEraseBkgnd.
|
||
ACanvas.Brush.Color := clBtnFace;
|
||
InternalPaintDefault := True;
|
||
DoDrawDockBackground(ACanvas, ARect, pstPrePaint, InternalPaintDefault);
|
||
PaintDefault := InternalPaintDefault;
|
||
InternalPaintDefault := True;
|
||
DoDrawDockBackground(ACanvas, ARect, pstPostPaint, InternalPaintDefault);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCompoundBar.DrawToolbarBackground(Sender: TObject;
|
||
ACanvas: TCanvas; ARect: TRect; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean);
|
||
begin
|
||
// Let the background be painted by the Dock
|
||
if PaintStage = pstPrePaint then
|
||
PaintDefault := False;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXButtonOptions }
|
||
|
||
constructor TSpTBXButtonOptions.Create(AParent: TWinControl);
|
||
begin
|
||
inherited Create;
|
||
|
||
FToolbar := nil;
|
||
if AParent is TSpTBXCompoundItemsControl then
|
||
FToolbar := TSpTBXCompoundItemsControl(AParent).FToolbar;
|
||
FParentControl := AParent;
|
||
|
||
FCaption := True;
|
||
FClose := True;
|
||
FMinimize := True;
|
||
FMaximize := True;
|
||
FCaptionImageIndex := -1;
|
||
FCloseImageIndex := -1;
|
||
FMinimizeImageIndex := -1;
|
||
FMaximizeImageIndex := -1;
|
||
FRestoreImageIndex := -1;
|
||
FTitleBarMaxSize := 21;
|
||
FButtonBorders := True;
|
||
CreateButtons;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.CreateButtons;
|
||
begin
|
||
FRightAlignSpacer := TSpTBXRightAlignSpacerItem.Create(nil);
|
||
FRightAlignSpacer.FontSettings.Style := FRightAlignSpacer.FontSettings.Style + [fsBold];
|
||
FRightAlignSpacer.Wrapping := twEndEllipsis;
|
||
FToolbar.Items.Add(FRightAlignSpacer);
|
||
|
||
FEditableItems := TTBGroupItem.Create(nil);
|
||
FToolbar.Items.Add(FEditableItems);
|
||
|
||
FMinimizeButton := TSpTBXItem.Create(nil);
|
||
SetupButton(FMinimizeButton);
|
||
FMinimizeButton.Visible := FMinimize;
|
||
|
||
FMaximizeButton := TSpTBXItem.Create(nil);
|
||
SetupButton(FMaximizeButton);
|
||
FMaximizeButton.Visible := FMaximize;
|
||
|
||
FCloseButton := TSpTBXItem.Create(nil);
|
||
SetupButton(FCloseButton);
|
||
FCloseButton.Visible := FClose;
|
||
|
||
SetTitleBarMaxSize(FTitleBarMaxSize);
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.MoveItemToTheLeft(B: TTBCustomItem);
|
||
var
|
||
I: Integer;
|
||
begin
|
||
I := EditableItems.IndexOf(B);
|
||
if I > -1 then begin
|
||
EditableItems.Delete(I);
|
||
I := FToolbar.Items.IndexOf(RightAlignSpacer);
|
||
FToolbar.Items.Insert(I, B);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetupButton(B: TSpTBXCustomItem);
|
||
begin
|
||
B.CustomWidth := 17;
|
||
B.CustomHeight := FTitleBarMaxSize;
|
||
B.DisplayMode := nbdmImageAndText;
|
||
B.OnDrawImage := ButtonsDrawImage;
|
||
B.OnDrawItem := ButtonsDrawItem;
|
||
B.OnClick := ButtonsClick;
|
||
FToolbar.Items.Add(B);
|
||
B.Visible := False;
|
||
SetupButtonIcon(B);
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetupButtonIcon(B: TSpTBXCustomItem);
|
||
var
|
||
Index, GlyphIndex: Integer;
|
||
begin
|
||
if Assigned(B) then begin
|
||
Index := -1;
|
||
GlyphIndex := -1;
|
||
|
||
if B = FRightAlignSpacer then begin
|
||
Index := FCaptionImageIndex;
|
||
end else
|
||
if B = FCloseButton then begin
|
||
Index := FCloseImageIndex;
|
||
GlyphIndex := 0;
|
||
end else
|
||
if B = FMaximizeButton then begin
|
||
if Restoring(B) then begin
|
||
Index := FRestoreImageIndex;
|
||
GlyphIndex := 3;
|
||
end
|
||
else begin
|
||
Index := FMaximizeImageIndex;
|
||
GlyphIndex := 1;
|
||
end;
|
||
end else
|
||
if B = FMinimizeButton then begin
|
||
if Restoring(B) then begin
|
||
Index := FRestoreImageIndex;
|
||
GlyphIndex := 3;
|
||
end
|
||
else begin
|
||
Index := FMinimizeImageIndex;
|
||
GlyphIndex := 2;
|
||
end;
|
||
end;
|
||
|
||
if Index = -1 then begin
|
||
B.Images := MDIButtonsImgList;
|
||
B.ImageIndex := GlyphIndex;
|
||
end
|
||
else begin
|
||
B.Images := nil;
|
||
B.ImageIndex := Index;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.UpdateButtonsVisibility;
|
||
begin
|
||
FRightAlignSpacer.Visible := FCaption or FClose or FMaximize or FMinimize;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.ButtonsDrawImage(Sender: TObject;
|
||
ACanvas: TCanvas; State: TSpTBXSkinStatesType;
|
||
const PaintStage: TSpTBXPaintStage; var AImageList: TCustomImageList;
|
||
var AImageIndex: Integer; var ARect: TRect; var PaintDefault: Boolean);
|
||
begin
|
||
// Empty, useful for descendants
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.ButtonsDrawItem(Sender: TObject; ACanvas: TCanvas;
|
||
ARect: TRect; ItemInfo: TSpTBXMenuItemInfo; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean);
|
||
begin
|
||
// [Theme-Change]
|
||
// Don't draw the items background if ButtonBorders is False
|
||
if (PaintStage = pstPrePaint) and not ButtonBorders then
|
||
PaintDefault := False;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetCaptionLabel(const Value: WideString);
|
||
begin
|
||
if FCaptionLabel <> Value then begin
|
||
FCaptionLabel := Value;
|
||
if Assigned(FRightAlignSpacer) then
|
||
FRightAlignSpacer.Caption := Value;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetCaption(const Value: Boolean);
|
||
begin
|
||
FCaption := Value;
|
||
if Assigned(FRightAlignSpacer) then begin
|
||
if Value then
|
||
FRightAlignSpacer.Caption := CaptionLabel
|
||
else
|
||
FRightAlignSpacer.Caption := '';
|
||
UpdateButtonsVisibility;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetClose(const Value: Boolean);
|
||
begin
|
||
FClose := Value;
|
||
if Assigned(FCloseButton) then begin
|
||
FCloseButton.Visible := Value;
|
||
UpdateButtonsVisibility;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetMaximize(const Value: Boolean);
|
||
begin
|
||
FMaximize := Value;
|
||
if Assigned(FMaximizeButton) then begin
|
||
FMaximizeButton.Visible := Value;
|
||
UpdateButtonsVisibility;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetMinimize(const Value: Boolean);
|
||
begin
|
||
FMinimize := Value;
|
||
if Assigned(FMinimizeButton) then begin
|
||
FMinimizeButton.Visible := Value;
|
||
UpdateButtonsVisibility;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetCaptionImageIndex(Value: Integer);
|
||
begin
|
||
if Value < 0 then Value := -1;
|
||
FCaptionImageIndex := Value;
|
||
if Assigned(FRightAlignSpacer) then SetupButtonIcon(FRightAlignSpacer);
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetCloseImageIndex(Value: Integer);
|
||
begin
|
||
if Value < 0 then Value := -1;
|
||
FCloseImageIndex := Value;
|
||
if Assigned(FCloseButton) then SetupButtonIcon(FCloseButton);
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetMinimizeImageIndex(Value: Integer);
|
||
begin
|
||
if Value < 0 then Value := -1;
|
||
FMinimizeImageIndex := Value;
|
||
if Assigned(FMinimizeButton) then SetupButtonIcon(FMinimizeButton);
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetMaximizeImageIndex(Value: Integer);
|
||
begin
|
||
if Value < 0 then Value := -1;
|
||
FMaximizeImageIndex := Value;
|
||
if Assigned(FMaximizeButton) then SetupButtonIcon(FMaximizeButton);
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetRestoreImageIndex(Value: Integer);
|
||
begin
|
||
if Value < 0 then Value := -1;
|
||
FRestoreImageIndex := Value;
|
||
SetupButtonIcon(FMinimizeButton);
|
||
SetupButtonIcon(FMaximizeButton);
|
||
end;
|
||
|
||
procedure TSpTBXButtonOptions.SetTitleBarMaxSize(const Value: Integer);
|
||
begin
|
||
FTitleBarMaxSize := Value;
|
||
TSpTBXToolbarView(FToolbar.View).MaxSize := Value;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXStatusToolbar }
|
||
|
||
constructor TSpTBXStatusToolbar.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
FSkinType := sknSkin;
|
||
FSizeGrip := True;
|
||
end;
|
||
|
||
destructor TSpTBXStatusToolbar.Destroy;
|
||
begin
|
||
FParentForm := nil;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXStatusToolbar.DoItemNotification(Ancestor: TTBCustomItem;
|
||
Relayed: Boolean; Action: TTBItemChangedAction; Index: Integer;
|
||
Item: TTBCustomItem);
|
||
begin
|
||
inherited;
|
||
|
||
if not (csDestroying in ComponentState) and not (csReading in ComponentState) and
|
||
not (tstResizing in FState) and not IsItemMoving then
|
||
begin
|
||
if (Action = tbicInvalidateAndResize) and Assigned(Owner) and (Owner is TSpTBXCustomStatusBar) then
|
||
if NeedsSeparatorRepaint then
|
||
TSpTBXCustomStatusBar(Owner).InvalidateBackground;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXStatusToolbar.GetParentFormWindowState: TWindowState;
|
||
// This method is more accurate than FParentForm.WindowState
|
||
var
|
||
R: TRect;
|
||
begin
|
||
if not Assigned(FParentForm) then
|
||
FParentForm := GetParentForm(Self);
|
||
Result := SpGetFormWindowState(FParentForm, R);
|
||
end;
|
||
|
||
function TSpTBXStatusToolbar.IsPointInGrip(P: TPoint): Boolean;
|
||
var
|
||
GR: TRect;
|
||
begin
|
||
Result := False;
|
||
GR := GetGripRect;
|
||
if not IsRectEmpty(GR) and PtInRect(GR, P) then
|
||
Result := True;
|
||
end;
|
||
|
||
function TSpTBXStatusToolbar.GetGripRect: TRect;
|
||
var
|
||
C: TWinControl;
|
||
FS: TWindowState;
|
||
HasGrip: Boolean;
|
||
begin
|
||
Result := Rect(0, 0, 0, 0);
|
||
if not (csDestroying in ComponentState) and FSizeGrip and Assigned(CurrentDock) then begin
|
||
FS := GetParentFormWindowState; // initializes FParentForm
|
||
if Assigned(FParentForm) and FParentForm.HandleAllocated then begin
|
||
C := SpFindParent(Self, TSpTBXTitleBar);
|
||
if Assigned(C) and TSpTBXTitleBar(C).Active and not TSpTBXTitleBar(C).FixedSize then
|
||
HasGrip := (FS = wsNormal) or not TSpTBXTitleBar(C).MouseActive
|
||
else
|
||
HasGrip := (FS = wsNormal) and (GetWindowLong(FParentForm.Handle, GWL_STYLE) and WS_THICKFRAME <> 0);
|
||
if HasGrip then begin
|
||
Result := CurrentDock.ClientRect;
|
||
Result.Left := Result.Right - GetSystemMetrics(SM_CXVSCROLL);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXStatusToolbar.GetItemsTextColor(State: TSpTBXSkinStatesType): TColor;
|
||
begin
|
||
if Assigned(Owner) and (Owner is TSpTBXCustomStatusBar) then
|
||
Result := CurrentSkin.GetTextColor(skncStatusBar, State, TSpTBXCustomStatusBar(Owner).SkinType)
|
||
else
|
||
Result := clNone;
|
||
end;
|
||
|
||
function TSpTBXStatusToolbar.GetRightAlignMargin: Integer;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
R := GetGripRect;
|
||
Result := R.Right - R.Left;
|
||
if Result = 0 then
|
||
Result := 4;
|
||
end;
|
||
|
||
function TSpTBXStatusToolbar.NeedsSeparatorRepaint: Boolean;
|
||
var
|
||
T: TSpTBXSkinType;
|
||
begin
|
||
// [Theme-Change]
|
||
// Office themes have rectangle panels, the separator needs
|
||
// to be painted by the Toolbar.
|
||
if Assigned(Owner) and (Owner is TSpTBXCustomStatusBar) then begin
|
||
T := TSpTBXCustomStatusBar(Owner).SkinType;
|
||
Result := (CurrentSkin.OfficeStatusBar and (T = sknSkin)) or (T = sknNone);
|
||
end
|
||
else
|
||
Result := False;
|
||
end;
|
||
|
||
procedure TSpTBXStatusToolbar.SetSizeGrip(const Value: Boolean);
|
||
begin
|
||
if FSizeGrip <> Value then begin
|
||
FSizeGrip := Value;
|
||
if Assigned(Owner) and (Owner is TSpTBXStatusBar) then
|
||
TSpTBXStatusBar(Owner).InvalidateBackground;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXStatusToolbar.MouseDown(Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
var
|
||
P: TPoint;
|
||
begin
|
||
// Resize the StatusBar if the parent is TSpTBXTitleBar
|
||
if not (csDesigning in ComponentState) and (Button = mbLeft) and Assigned(FParentForm) then begin
|
||
P := Point(X, Y);
|
||
if IsPointInGrip(P) then begin
|
||
ReleaseCapture;
|
||
SendMessage(FParentForm.Handle, WM_SYSCOMMAND, $F008, 0);
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXStatusToolbar.WMNCLButtonDown(var Message: TWMNCLButtonDown);
|
||
var
|
||
P: TPoint;
|
||
begin
|
||
if not (csDesigning in ComponentState) and Assigned(FParentForm) then begin
|
||
P := ScreenToClient(SmallPointToPoint(TSmallPoint(GetMessagePos())));
|
||
if IsPointInGrip(P) then begin
|
||
ReleaseCapture;
|
||
SendMessage(FParentForm.Handle, WM_SYSCOMMAND, $F008, 0);
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXStatusToolbar.WMSetCursor(var Message: TWMSetCursor);
|
||
var
|
||
P: TPoint;
|
||
begin
|
||
if not (csDesigning in ComponentState) and (Message.CursorWnd = Handle) and
|
||
(Screen.Cursor = crDefault) and Assigned(FParentForm) then
|
||
begin
|
||
GetCursorPos(P);
|
||
P := ScreenToClient(P);
|
||
if IsPointInGrip(P) then begin
|
||
Windows.SetCursor(Screen.Cursors[-8]);
|
||
Message.Result := 1;
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
inherited;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomStatusBar }
|
||
|
||
constructor TSpTBXCustomStatusBar.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
Align := alBottom;
|
||
end;
|
||
|
||
function TSpTBXCustomStatusBar.CanResize(var NewWidth, NewHeight: Integer): Boolean;
|
||
begin
|
||
if Assigned(FDock) and (NewHeight <> FDock.Height) then
|
||
Result := False
|
||
else
|
||
Result := inherited CanResize(NewWidth, NewHeight);
|
||
end;
|
||
|
||
procedure TSpTBXCustomStatusBar.DoDrawDockBackground(ACanvas: TCanvas;
|
||
ARect: TRect; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean);
|
||
var
|
||
G: TRect;
|
||
OfficeSeparators: Boolean;
|
||
begin
|
||
inherited DoDrawDockBackground(ACanvas, ARect, PaintStage, PaintDefault);
|
||
if (PaintStage = pstPrePaint) and PaintDefault then begin
|
||
PaintDefault := False;
|
||
G := Toolbar.GetGripRect;
|
||
if not IsRectEmpty(G) then begin
|
||
// When it's called by the Toolbar the Gripper position should be corrected
|
||
if (ARect.Left = -2) and (ARect.Top = -2) then
|
||
OffsetRect(G, -2, -2);
|
||
end;
|
||
|
||
OfficeSeparators := Toolbar.NeedsSeparatorRepaint;
|
||
SpDrawXPStatusBar(ACanvas, ARect, G, SkinType);
|
||
if OfficeSeparators then
|
||
DrawSeparators(ACanvas, ARect);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomStatusBar.DrawSeparators(ACanvas: TCanvas; ARect: TRect);
|
||
// Draws Office separators when the skin has OfficeStatusBar set to true
|
||
var
|
||
I: Integer;
|
||
IV: TTBItemViewer;
|
||
R: TRect;
|
||
SaveIndex: Integer;
|
||
begin
|
||
SaveIndex := SaveDC(ACanvas.Handle);
|
||
try
|
||
for I := 0 to FToolbar.View.ViewerCount - 1 do begin
|
||
IV := FToolbar.View.Viewers[I];
|
||
if (IV is TSpTBXSeparatorItemViewer) and (not TSpTBXSeparatorItem(IV.Item).Blank) then begin
|
||
R := IV.BoundsRect;
|
||
if IsRectEmpty(R) then
|
||
Continue;
|
||
|
||
OffsetRect(R, ARect.Left + 2, ARect.Top + 2);
|
||
R.Top := ARect.Top;
|
||
R.Bottom := ARect.Bottom;
|
||
R.Left := ((R.Right + R.Left) div 2) - 2;
|
||
R.Right := R.Left + 3;
|
||
|
||
if SpTBXSkinType(FSkinType) = sknNone then begin
|
||
ACanvas.Brush.Color := clBtnFace;
|
||
ACanvas.FillRect(R);
|
||
SpDrawLine(ACanvas, R.Left, R.Top, R.Left, R.Bottom, clWindow);
|
||
SpDrawLine(ACanvas, R.Right, R.Top, R.Right, R.Bottom, clBtnShadow);
|
||
end
|
||
else begin
|
||
// For Office XP, when called by the Dock inc Top by 1
|
||
if ARect.Top = 0 then Inc(R.Top);
|
||
SpDrawLine(ACanvas, R.Left, R.Top, R.Left, R.Bottom, clWindow);
|
||
SpDrawLine(ACanvas, R.Right, R.Top, R.Right, R.Bottom, clWindow);
|
||
ExcludeClipRect(ACanvas.Handle, R.Left, R.Top, R.Right, R.Bottom);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
if SpTBXSkinType(FSkinType) = sknSkin then begin
|
||
Inc(ARect.Top);
|
||
ACanvas.Brush.Color := clWindow;
|
||
ACanvas.FrameRect(ARect);
|
||
end;
|
||
finally
|
||
RestoreDC(ACanvas.Handle, SaveIndex);
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXCustomStatusBar.GetStatusToolbar: TSpTBXStatusToolbar;
|
||
begin
|
||
Result := FToolbar as TSpTBXStatusToolbar;
|
||
end;
|
||
|
||
function TSpTBXCustomStatusBar.GetToolbarClass: TSpTBXToolbarClass;
|
||
begin
|
||
Result := TSpTBXStatusToolbar;
|
||
end;
|
||
|
||
function TSpTBXCustomStatusBar.GetSizeGrip: Boolean;
|
||
begin
|
||
Result := Toolbar.SizeGrip;
|
||
end;
|
||
|
||
procedure TSpTBXCustomStatusBar.SetSizeGrip(const Value: Boolean);
|
||
begin
|
||
Toolbar.SizeGrip := Value;
|
||
end;
|
||
|
||
procedure TSpTBXCustomStatusBar.WMEraseBkgnd(var Message: TWMEraseBkgnd);
|
||
begin
|
||
Message.Result := 1;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXTitleToolbar }
|
||
|
||
function TSpTBXTitleToolbar.GetItemsTextColor(State: TSpTBXSkinStatesType): TColor;
|
||
begin
|
||
Result := CurrentSkin.GetTextColor(skncWindowTitleBar, State);
|
||
end;
|
||
|
||
function TSpTBXTitleToolbar.GetRightAlignMargin: Integer;
|
||
var
|
||
TitleBar: TSpTBXCustomTitleBar;
|
||
begin
|
||
Result := inherited GetRightAlignMargin;
|
||
|
||
TitleBar := GetTitleBar;
|
||
if Assigned(TitleBar) and (TitleBar.WindowState = wsMaximized) then
|
||
Result := 0;
|
||
end;
|
||
|
||
function TSpTBXTitleToolbar.GetTitleBar: TSpTBXCustomTitleBar;
|
||
begin
|
||
Result := CurrentDock.Parent as TSpTBXCustomTitleBar;
|
||
end;
|
||
|
||
procedure TSpTBXTitleToolbar.MouseDown(Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
var
|
||
TransparentClick: Boolean;
|
||
F: TCustomForm;
|
||
TitleBar: TSpTBXCustomTitleBar;
|
||
P: TPoint;
|
||
IV: TTBItemViewer;
|
||
begin
|
||
// Move the Parent Form if the toolbar client area or an item with
|
||
// tbisClicksTransparent itemstyle is clicked (like a TBXLabelItem)
|
||
if not (csDesigning in ComponentState) then begin
|
||
TitleBar := GetTitleBar;
|
||
F := TitleBar.FParentForm;
|
||
if not Assigned(F) or not Assigned(TitleBar) then Exit;
|
||
if not TitleBar.IsActive then Exit;
|
||
|
||
if Assigned(View.Selected) then
|
||
TransparentClick := tbisClicksTransparent in TTBCustomItemAccess(View.Selected.Item).ItemStyle
|
||
else
|
||
TransparentClick := True;
|
||
|
||
case Button of
|
||
mbLeft:
|
||
if TransparentClick then begin
|
||
if ssDouble in Shift then begin
|
||
// Maximize or restore when double clicking the toolbar
|
||
if TitleBar.Options.Maximize and not TitleBar.FixedSize then
|
||
TitleBar.Options.MaximizeButton.Click;
|
||
end
|
||
else
|
||
if F.WindowState <> wsMaximized then begin
|
||
// Drag the form when dragging the toolbar
|
||
ReleaseCapture;
|
||
SendMessage(F.Handle, WM_SYSCOMMAND, $F012, 0);
|
||
end;
|
||
Exit; // Do not process transparent clicks
|
||
end
|
||
else
|
||
if (ssDouble in Shift) and TitleBar.Options.SystemMenu then begin
|
||
// Close the form when the system menu button is double clicked
|
||
IV := View.ViewerFromPoint(Point(X, Y));
|
||
if Assigned(IV) and (IV.Item = TitleBar.Options.SystemButton) then begin
|
||
F.Close;
|
||
Exit; // Do not process transparent clicks
|
||
end;
|
||
end;
|
||
mbRight:
|
||
if TransparentClick and TitleBar.Options.SystemMenu then begin
|
||
P := ClientToScreen(Point(X, Y));
|
||
TitleBar.Options.SystemButton.Popup(P.X, P.Y, True);
|
||
Exit; // Do not process transparent clicks
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXTitleToolbar.WMNCCalcSize(var Message: TWMNCCalcSize);
|
||
var
|
||
TitleBar: TSpTBXCustomTitleBar;
|
||
begin
|
||
inherited;
|
||
|
||
FDefaultToolbarBorderSize := CDefaultToolbarBorderSize;
|
||
if Docked then begin
|
||
TitleBar := GetTitleBar;
|
||
if Assigned(TitleBar) and (TitleBar.WindowState = wsMaximized) then begin
|
||
InflateRect(Message.CalcSize_Params.rgrc[0], 2, 2);
|
||
FDefaultToolbarBorderSize := 0;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXTitleBarButtonOptions }
|
||
|
||
constructor TSpTBXTitleBarButtonOptions.Create(AParent: TWinControl);
|
||
begin
|
||
FSystemMenu := True;
|
||
FTitleBar := AParent as TSpTBXCustomTitleBar;
|
||
inherited Create(AParent);
|
||
end;
|
||
|
||
procedure TSpTBXTitleBarButtonOptions.CreateButtons;
|
||
begin
|
||
FSystemButton := TSpTBXSystemMenuItem.Create(nil);
|
||
SetupButton(FSystemButton);
|
||
FSystemButton.Visible := FSystemMenu;
|
||
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXTitleBarButtonOptions.SetSystemMenu(const Value: Boolean);
|
||
begin
|
||
FSystemMenu := Value;
|
||
if Assigned(FSystemButton) then
|
||
FSystemButton.Visible := Value;
|
||
end;
|
||
|
||
procedure TSpTBXTitleBarButtonOptions.ButtonsDrawItem(Sender: TObject; ACanvas: TCanvas;
|
||
ARect: TRect; ItemInfo: TSpTBXMenuItemInfo; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean);
|
||
begin
|
||
inherited;
|
||
|
||
// [Theme-Change]
|
||
// Don't draw the items background if ButtonBorders is False or Default theme is used
|
||
if (PaintStage = pstPrePaint) and (not ButtonBorders or SkinManager.IsDefaultSkin) then
|
||
PaintDefault := False;
|
||
end;
|
||
|
||
procedure TSpTBXTitleBarButtonOptions.ButtonsClick(Sender: TObject);
|
||
begin
|
||
if not Assigned(FTitleBar.FParentForm) or not FTitleBar.IsActive then Exit;
|
||
|
||
if Sender = FSystemButton then
|
||
FSystemButton.ShowSize := not FTitleBar.FixedSize
|
||
else
|
||
if Sender = FMinimizeButton then
|
||
FTitleBar.WindowState := wsMinimized
|
||
else
|
||
if Sender = FCloseButton then
|
||
FTitleBar.FParentForm.Close
|
||
else
|
||
if Sender = FMaximizeButton then begin
|
||
if FTitleBar.WindowState = wsNormal then
|
||
FTitleBar.WindowState := wsMaximized
|
||
else
|
||
FTitleBar.WindowState := wsNormal;
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXTitleBarButtonOptions.Restoring(B: TSpTBXCustomItem): Boolean;
|
||
begin
|
||
Result := False;
|
||
if (B = MaximizeButton) and (FTitleBar.WindowState = wsMaximized) then Result := True;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TSpTBXCustomTitleBar }
|
||
|
||
constructor TSpTBXCustomTitleBar.Create(AOwner: TComponent);
|
||
begin
|
||
inherited;
|
||
|
||
FActive := True;
|
||
FMouseActive := True;
|
||
ControlStyle := ControlStyle + [csAcceptsControls];
|
||
|
||
Align := alClient;
|
||
FDock.OnResize := nil;
|
||
|
||
FParentForm := GetParentForm(Self);
|
||
FOptions := TSpTBXTitleBarButtonOptions.Create(Self);
|
||
FOptions.CaptionLabel := Caption;
|
||
end;
|
||
|
||
destructor TSpTBXCustomTitleBar.Destroy;
|
||
begin
|
||
ChangeTitleBarState(False);
|
||
FOptions.Free;
|
||
|
||
if Assigned(FParentForm) and Assigned(FOldParentFormWndProc) then begin
|
||
FParentForm.WindowProc := FOldParentFormWndProc;
|
||
FOldParentFormWndProc := nil;
|
||
end;
|
||
|
||
if Assigned(Application) and Assigned(FNewAppWndProc) then begin
|
||
SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(FOldAppWndProc));
|
||
Classes.FreeObjectInstance(FNewAppWndProc);
|
||
FNewAppWndProc := nil;
|
||
end;
|
||
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.Loaded;
|
||
begin
|
||
inherited;
|
||
|
||
// Subclass the ParentForm and Application for the System menu handling
|
||
if not (csDesigning in ComponentState) then begin
|
||
FParentForm := GetParentForm(Self);
|
||
// Hook the ParentForm
|
||
if Assigned(FParentForm) then begin
|
||
FOldParentFormWndProc := FParentForm.WindowProc;
|
||
FParentForm.WindowProc := NewParentFormWndProc;
|
||
end;
|
||
|
||
// Hook the Application to trap the $0313 message, more info on AppWndProc
|
||
if not (csDesigning in ComponentState) and (Application.Handle <> 0) and
|
||
(Application.MainForm = nil) and (FOldAppWndProc = nil) then
|
||
begin
|
||
// When Application.MainForm asume FParentForm as the MainForm
|
||
FOldAppWndProc := Pointer(GetWindowLong(Application.Handle, GWL_WNDPROC));
|
||
FNewAppWndProc := Classes.MakeObjectInstance(AppWndProc);
|
||
SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(FNewAppWndProc));
|
||
end;
|
||
|
||
ChangeTitleBarState(Active);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.UpdateSkinMetrics;
|
||
begin
|
||
if HandleAllocated then begin
|
||
// Update the NC area size, CurrentSkin.FloatingWindowBorderSize could have changed
|
||
// Make sure to realign the toolbars
|
||
SpRecalcNCArea(Self);
|
||
Realign;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.AppWndProc(var Msg: TMessage);
|
||
var
|
||
SystemButtonP: TPoint;
|
||
begin
|
||
// Handle undocumented $0313 message, this is sent when the
|
||
// taskbar button of the application is right clicked.
|
||
// When Application.MainFormOnTaskbar = True (Delphi 2007 and above)
|
||
// the message is sent to the Main Form, otherwise it is sent
|
||
// to the Application.
|
||
// More info:
|
||
// http://delphi.about.com/od/vclwriteenhance/a/ttaskbarmenu.htm
|
||
if (Msg.Msg = $0313) and Assigned(FParentForm) and Assigned(Options) then begin
|
||
GetCursorPos(SystemButtonP);
|
||
FOptions.SystemButton.Popup(SystemButtonP.X, SystemButtonP.Y, True);
|
||
end
|
||
else
|
||
if Assigned(FOldAppWndProc) then
|
||
Msg.Result := CallWindowProc(FOldAppWndProc, Application.Handle, Msg.Msg, Msg.wParam, Msg.lParam);
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.NewParentFormWndProc(var Message: TMessage);
|
||
var
|
||
M: TWMSysCommand;
|
||
I: Integer;
|
||
HandleSpaceKey: Boolean;
|
||
|
||
MMI: ^TMinMaxInfo;
|
||
MonitorBounds, WorkArea, TaskBarBounds: TRect;
|
||
TaskBarState, TaskBarEdge: Cardinal;
|
||
SystemButtonIV: TTBItemViewer;
|
||
SystemButtonP: TPoint;
|
||
begin
|
||
if not Assigned(FParentForm) then Exit;
|
||
|
||
case Message.Msg of
|
||
$0313:
|
||
begin
|
||
// Handle undocumented $0313 message, this is sent when the
|
||
// taskbar button of the application is right clicked.
|
||
// When Application.MainFormOnTaskbar = True (Delphi 2007 and above)
|
||
// the message is sent to the Main Form, otherwise it is sent
|
||
// to the Application.
|
||
// More info:
|
||
// http://delphi.about.com/od/vclwriteenhance/a/ttaskbarmenu.htm
|
||
GetCursorPos(SystemButtonP);
|
||
FOptions.SystemButton.Popup(SystemButtonP.X, SystemButtonP.Y, True);
|
||
Exit;
|
||
end;
|
||
WM_GETMINMAXINFO:
|
||
if IsActive and not FFullScreenMaximize then begin
|
||
MMI := Pointer(Message.lParam);
|
||
WorkArea := GetRectOfMonitorContainingWindow(Handle, True);
|
||
MonitorBounds := GetRectOfMonitorContainingWindow(Handle, False);
|
||
|
||
// Calculate the Max position and size
|
||
// http://news.jrsoftware.org/news/toolbar2000.thirdparty/msg13127.html
|
||
MMI^.ptMaxPosition.X := WorkArea.Left - MonitorBounds.Left;
|
||
MMI^.ptMaxPosition.Y := WorkArea.Top - MonitorBounds.Top;
|
||
MMI^.ptMaxSize.X := WorkArea.Right - WorkArea.Left;
|
||
MMI^.ptMaxSize.Y := WorkArea.Bottom - WorkArea.Top;
|
||
|
||
// Reduce the Max Size if the TaskBar is AutoHidden
|
||
if SpGetTaskBar(TaskBarState, TaskBarEdge, TaskBarBounds) then begin
|
||
if (TaskBarState and ABS_AUTOHIDE) = ABS_AUTOHIDE then
|
||
case TaskBarEdge of
|
||
ABE_LEFT, ABE_RIGHT: MMI^.ptMaxSize.X := MMI^.ptMaxSize.X - 2;
|
||
ABE_TOP, ABE_BOTTOM: MMI^.ptMaxSize.Y := MMI^.ptMaxSize.Y - 2;
|
||
end;
|
||
end;
|
||
|
||
// Max size during window resize, change the ParentForm constraints
|
||
// to make it work
|
||
if WindowState = wsMaximized then begin
|
||
MMI^.ptMaxTrackSize.X := MMI^.ptMaxSize.X;
|
||
MMI^.ptMaxTrackSize.Y := MMI^.ptMaxSize.Y;
|
||
FParentForm.Constraints.MaxWidth := MMI^.ptMaxSize.X;
|
||
FParentForm.Constraints.MaxHeight := MMI^.ptMaxSize.Y;
|
||
end
|
||
else begin
|
||
FParentForm.Constraints.MaxWidth := 0;
|
||
FParentForm.Constraints.MaxHeight := 0;
|
||
end;
|
||
|
||
Message.Result := 0;
|
||
end;
|
||
WM_SYSCOMMAND:
|
||
if IsActive and Options.SystemMenu then begin
|
||
M := TWMSysCommand(Message);
|
||
if M.CmdType and $FFF0 = SC_KEYMENU then
|
||
case M.Key of
|
||
VK_SPACE:
|
||
begin
|
||
// Show the custom SysMenu
|
||
SystemButtonIV := FToolbar.View.Find(FOptions.SystemButton);
|
||
if Assigned(SystemButtonIV) then begin
|
||
SystemButtonP.X := SystemButtonIV.BoundsRect.Left;
|
||
SystemButtonP.Y := SystemButtonIV.BoundsRect.Bottom;
|
||
SystemButtonP := FToolbar.ClientToScreen(SystemButtonP);
|
||
FOptions.SystemButton.Popup(SystemButtonP.X, SystemButtonP.Y, True);
|
||
Message.Result := 1;
|
||
Exit;
|
||
end;
|
||
end;
|
||
0:
|
||
if GetCapture = 0 then begin
|
||
// When only the Alt key is pressed and a few seconds latter the Space
|
||
// key is pressed the default SysMenu is showed, this only happens
|
||
// when there are no menubars on the form.
|
||
// In this case the WM_SYSCOMMAND is sent when the Alt key is
|
||
// pressed (Key = 0), but not when the space key is pressed.
|
||
// Apparently there's no way to override this, the only solution is to
|
||
// handle the Alt key press (Key = 0).
|
||
//
|
||
// Message log when Alt [...] Space is pressed:
|
||
// WM_SYSKEYDOWN: VK_MENU
|
||
// WM_SYSKEYUP: VK_MENU
|
||
// WM_SYSCOMMAND: Key = 0
|
||
// WM_ENTERMENULOOP
|
||
// WM_INITMENU
|
||
// WM_KEYDOWN: VK_SPACE
|
||
// WM_CHAR: VK_SPACE
|
||
// WM_INITMENUPOPUP: system hmenu
|
||
|
||
// If the form has a main menu VK_SPACE will be correctly handled
|
||
HandleSpaceKey := True;
|
||
if Assigned(FParentForm.Menu) then
|
||
HandleSpaceKey := False
|
||
else
|
||
if Toolbar.MenuBar then
|
||
HandleSpaceKey := False
|
||
else
|
||
for I := 0 to FParentForm.ComponentCount - 1 do
|
||
if FParentForm.Components[I] is TTBCustomToolbar then
|
||
if TTBCustomToolbar(FParentForm.Components[I]).MenuBar then begin
|
||
HandleSpaceKey := False;
|
||
Break;
|
||
end;
|
||
if HandleSpaceKey then begin
|
||
Message.Result := 1;
|
||
Exit;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
// Default processing
|
||
if Assigned(FOldParentFormWndProc) then
|
||
FOldParentFormWndProc(Message);
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.ChangeTitleBarState(Activate: Boolean);
|
||
var
|
||
FloatingBorderSize: TPoint;
|
||
Style: Integer;
|
||
RestoreR: TRect;
|
||
WState: TWindowState;
|
||
OnParentFormShow: TNotifyEvent;
|
||
begin
|
||
FParentForm := GetParentForm(Self);
|
||
if Assigned(FParentForm) and (FParentForm.HandleAllocated) and ([csDesigning, csDestroying] * FParentForm.ComponentState = []) then begin
|
||
|
||
if FMouseActive then begin
|
||
FloatingBorderSize := GetFloatingBorderSize;
|
||
|
||
// Changing the BorderStyle of the form will recreate it,
|
||
// causing it to call Form.OnShow everytime Active is changed
|
||
// We need to disable the OnShow calling.
|
||
OnParentFormShow := TCustomFormAccess(FParentForm).OnShow;
|
||
TCustomFormAccess(FParentForm).OnShow := nil;
|
||
try
|
||
WState := SpGetFormWindowState(FParentForm, RestoreR);
|
||
|
||
if Activate then begin
|
||
// Remove the border and titlebar from the form, and add the sysmenu
|
||
FParentForm.BorderStyle := bsNone;
|
||
Style := GetWindowLong(FParentForm.Handle, GWL_STYLE);
|
||
Style := Style or WS_SYSMENU;
|
||
SetWindowLong(FParentForm.Handle, GWL_STYLE, Style);
|
||
|
||
// Resize the form to retain the same size before it was activated.
|
||
// This is needed to keep the designtime size
|
||
if (WState <> wsMaximized) and (TCustomFormAccess(FParentForm).FormStyle <> fsMDIChild) then begin
|
||
FParentForm.Height := FParentForm.Height - GetSystemMetrics(SM_CYCAPTION) - (FloatingBorderSize.Y * 2);
|
||
FParentForm.Width := FParentForm.Width - (FloatingBorderSize.X * 2);
|
||
end;
|
||
end
|
||
else begin
|
||
FParentForm.BorderStyle := bsSizeable;
|
||
|
||
// Resize the form to retain the same size before it was deactivated.
|
||
// This is needed to keep the designtime size
|
||
if (WState <> wsMaximized) and (TCustomFormAccess(FParentForm).FormStyle <> fsMDIChild) then begin
|
||
FParentForm.Height := FParentForm.Height + GetSystemMetrics(SM_CYCAPTION) + (FloatingBorderSize.Y * 2);
|
||
FParentForm.Width := FParentForm.Width + (FloatingBorderSize.X * 2);
|
||
end;
|
||
end;
|
||
|
||
// When Active is changed the Form is recreated, we have to
|
||
// reset the Restore size if the form is currently Maximized.
|
||
if WState = wsMaximized then
|
||
SpSetFormWindowState(FParentForm, WState, RestoreR);
|
||
|
||
InvalidateBackground;
|
||
finally
|
||
TCustomFormAccess(FParentForm).OnShow := OnParentFormShow;
|
||
end;
|
||
end;
|
||
|
||
FDock.Visible := FActive;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.AdjustClientRect(var Rect: TRect);
|
||
begin
|
||
inherited AdjustClientRect(Rect);
|
||
Rect := GetClientAreaRect;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.DoDrawDockBackground(ACanvas: TCanvas;
|
||
ARect: TRect; const PaintStage: TSpTBXPaintStage;
|
||
var PaintDefault: Boolean);
|
||
var
|
||
FloatingBorderSize: TPoint;
|
||
begin
|
||
inherited DoDrawDockBackground(ACanvas, ARect, PaintStage, PaintDefault);
|
||
if (PaintStage = pstPrePaint) and PaintDefault then begin
|
||
PaintDefault := False;
|
||
|
||
// [Theme-Change]
|
||
// On WindowsXP make sure we paint the titlebar on the NC area
|
||
// TSpTBXCustomTitleBar.WMEraseBkgnd and TSpTBXCustomTitleBar.DoDrawDockBackground handles this issue
|
||
if SkinManager.GetSkinType = sknWindows then begin
|
||
FloatingBorderSize := GetFloatingBorderSize;
|
||
InflateRect(ARect, FloatingBorderSize.X, FloatingBorderSize.Y);
|
||
end;
|
||
|
||
SpDrawXPTitleBar(ACanvas, ARect, True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.DoDrawBackground(ACanvas: TCanvas; ARect: TRect;
|
||
const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean);
|
||
begin
|
||
if Assigned(FOnDrawBackground) then FOnDrawBackground(Self, ACanvas, ARect, PaintStage, PaintDefault);
|
||
end;
|
||
|
||
function TSpTBXCustomTitleBar.GetClientAreaRect: TRect;
|
||
var
|
||
FloatingBorderSize: TPoint;
|
||
begin
|
||
Result := ClientRect;
|
||
if Active then begin
|
||
FloatingBorderSize := GetFloatingBorderSize;
|
||
if Assigned(FParentForm) then begin
|
||
if not FMouseActive or (FParentForm.WindowState <> wsMaximized) then
|
||
InflateRect(Result, -FloatingBorderSize.X, -FloatingBorderSize.Y);
|
||
end
|
||
else
|
||
InflateRect(Result, -FloatingBorderSize.X, -FloatingBorderSize.Y);
|
||
end;
|
||
end;
|
||
|
||
function TSpTBXCustomTitleBar.GetFloatingBorderSize: TPoint;
|
||
begin
|
||
if SkinManager.GetSkinType = sknSkin then
|
||
Result := Point(CurrentSkin.FloatingWindowBorderSize, CurrentSkin.FloatingWindowBorderSize)
|
||
else begin
|
||
Result.X := GetSystemMetrics(SM_CXFRAME);
|
||
Result.Y := GetSystemMetrics(SM_CYFRAME);
|
||
end
|
||
end;
|
||
|
||
function TSpTBXCustomTitleBar.GetItems: TTBCustomItem;
|
||
begin
|
||
// The ToolbarEditor designer will open the editable items and
|
||
// not the Toolbar.Items
|
||
Result := Options.EditableItems;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.GetSizeCursor(MousePos: TPoint; var SizeCursor,
|
||
SizeCode: Integer);
|
||
var
|
||
R: TRect;
|
||
Pt, FloatingBorderSize: TPoint;
|
||
const
|
||
SC_SizeLeft = $F001;
|
||
SC_SizeRight = $F002;
|
||
SC_SizeUp = $F003;
|
||
SC_SizeUpLeft = $F004;
|
||
SC_SizeUpRight = $F005;
|
||
SC_SizeDown = $F006;
|
||
SC_SizeDownLeft = $F007;
|
||
SC_SizeDownRight = $F008;
|
||
begin
|
||
SizeCursor := 0;
|
||
SizeCode := 0;
|
||
|
||
if not IsActive or (Assigned(FParentForm) and (FParentForm.WindowState = wsMaximized)) then Exit;
|
||
|
||
R := ClientRect;
|
||
FloatingBorderSize := GetFloatingBorderSize;
|
||
InflateRect(R, -FloatingBorderSize.X, -FloatingBorderSize.Y);
|
||
Pt := MousePos;
|
||
if not PtInRect(R, Pt) then begin
|
||
if (Pt.X < 10) and (Pt.Y < 10) then SizeCode := SC_SizeUpLeft
|
||
else if (Pt.X > Width - 10) and (Pt.Y < 10) then SizeCode := SC_SizeUpRight
|
||
else if (Pt.X < 10) and (Pt.Y > Height - 10) then SizeCode := SC_SizeDownLeft
|
||
else if (Pt.X > Width - 10) and (Pt.Y > Height - 10) then SizeCode := SC_SizeDownRight
|
||
else if (Pt.X > 10) and (Pt.X < Width - 10) and (Pt.Y < 10) then SizeCode := SC_SizeUp
|
||
else if (Pt.X > 10) and (Pt.X < Width - 10) and (Pt.Y > Height - 10) then SizeCode := SC_SizeDown
|
||
else if (Pt.Y > 10) and (Pt.Y < Height - 10) and (Pt.X < 10) then SizeCode := SC_SizeLeft
|
||
else if (Pt.Y > 10) and (Pt.Y < Height - 10) and (Pt.X > Width - 10) then SizeCode := SC_SizeRight;
|
||
|
||
case SizeCode of
|
||
SC_SizeLeft, SC_SizeRight: SizeCursor := -9;
|
||
SC_SizeUp, SC_SizeDown: SizeCursor := -7;
|
||
SC_SizeUpLeft, SC_SizeDownRight: SizeCursor := -8;
|
||
SC_SizeDownLeft, SC_SizeUpRight: SizeCursor := -6;
|
||
end;
|
||
end
|
||
end;
|
||
|
||
function TSpTBXCustomTitleBar.GetToolbarClass: TSpTBXToolbarClass;
|
||
begin
|
||
Result := TSpTBXTitleToolbar;
|
||
end;
|
||
|
||
function TSpTBXCustomTitleBar.GetWindowState: TWindowState;
|
||
begin
|
||
if Assigned(FParentForm) then
|
||
Result := FParentForm.WindowState
|
||
else
|
||
Result := wsNormal;
|
||
end;
|
||
|
||
function TSpTBXCustomTitleBar.IsActive: Boolean;
|
||
begin
|
||
Result := FActive and FMouseActive;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.MouseDown(Button: TMouseButton;
|
||
Shift: TShiftState; X, Y: Integer);
|
||
var
|
||
Pt: TPoint;
|
||
SizeCursor, SizeCode: Integer;
|
||
begin
|
||
inherited;
|
||
if not FixedSize and (Button = mbLeft) then begin
|
||
Pt := Point(X, Y);
|
||
GetSizeCursor(Pt, SizeCursor, SizeCode);
|
||
if (SizeCode > 0) and Assigned(FParentForm) then begin
|
||
ReleaseCapture;
|
||
FParentForm.Perform(WM_SYSCOMMAND, SizeCode, 0);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.SetActive(const Value: Boolean);
|
||
begin
|
||
if FActive <> Value then begin
|
||
FActive := Value;
|
||
ChangeTitleBarState(Value);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.SetFullScreenMaximize(const Value: Boolean);
|
||
begin
|
||
if FFullScreenMaximize <> Value then begin
|
||
FFullScreenMaximize := Value;
|
||
if IsActive and Assigned(FParentForm) and FParentForm.HandleAllocated then begin
|
||
FParentForm.Constraints.MaxWidth := 0;
|
||
FParentForm.Constraints.MaxHeight := 0;
|
||
if (WindowState = wsMaximized) and not (csDesigning in ComponentState) then
|
||
TCustomFormAccess(FParentForm).RecreateWnd;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.SetMouseActive(const Value: Boolean);
|
||
begin
|
||
if FMouseActive <> Value then begin
|
||
FMouseActive := Value;
|
||
ChangeTitleBarState(Value);
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.SetWindowState(const Value: TWindowState);
|
||
begin
|
||
if Assigned(FParentForm) then begin
|
||
case Value of
|
||
wsMinimized:
|
||
begin
|
||
// WindowState := wsMinimized will not minimize the app correctly
|
||
SendMessage(FParentForm.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
|
||
end;
|
||
wsMaximized, wsNormal:
|
||
FParentForm.WindowState := Value;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.WMSpSkinChange(var Message: TMessage);
|
||
begin
|
||
UpdateSkinMetrics;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.CMTextChanged(var Message: TMessage);
|
||
begin
|
||
inherited;
|
||
if Assigned(FOptions) then
|
||
FOptions.CaptionLabel := Caption;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.WMEraseBkgnd(var Message: TMessage);
|
||
var
|
||
ARect, DockAreaR: TRect;
|
||
FloatingBorderSize: TPoint;
|
||
Maximized, PaintDefault: Boolean;
|
||
B: TBitmap;
|
||
begin
|
||
Message.Result := 1;
|
||
if not DoubleBuffered or (Message.wParam = Message.lParam) then begin
|
||
B := TBitmap.Create;
|
||
try
|
||
ARect := GetClientRect;
|
||
B.Width := ARect.Right;
|
||
B.Height := ARect.Bottom;
|
||
B.Canvas.Brush.Color := Color; // SpDrawXPTitleBarBody needs it to paint the background
|
||
B.Canvas.FillRect(ARect);
|
||
|
||
PaintDefault := True;
|
||
DoDrawBackground(B.Canvas, ARect, pstPrePaint, PaintDefault);
|
||
if PaintDefault then begin
|
||
Maximized := (WindowState = wsMaximized) and FMouseActive;
|
||
if Maximized then
|
||
InflateRect(ARect, 4, 4);
|
||
if Active then begin
|
||
FloatingBorderSize := GetFloatingBorderSize;
|
||
SpDrawXPTitleBarBody(B.Canvas, ARect, True, FloatingBorderSize);
|
||
|
||
// [Theme-Change]
|
||
// On WindowsXP make sure we paint the titlebar on the NC area
|
||
// TSpTBXCustomTitleBar.WMEraseBkgnd and TSpTBXCustomTitleBar.DoDrawDockBackground handles this issue
|
||
if Assigned(FDock) and not Maximized and (SkinManager.GetSkinType = sknWindows) then begin
|
||
DockAreaR := ARect;
|
||
DockAreaR.Bottom := FDock.Height + FloatingBorderSize.Y; // don't multiply by 2
|
||
SpDrawXPTitleBar(B.Canvas, DockAreaR, True);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
PaintDefault := True;
|
||
DoDrawBackground(B.Canvas, ARect, pstPostPaint, PaintDefault);
|
||
|
||
BitBlt(TWMEraseBkgnd(Message).DC, 0, 0, B.Width, B.Height, B.Canvas.Handle, 0, 0, SRCCOPY);
|
||
finally
|
||
B.Free;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.WMSetCursor(var Message: TWMSetCursor);
|
||
var
|
||
P: TPoint;
|
||
SizeCursor, SizeCode: Integer;
|
||
begin
|
||
if not FixedSize and not (csDesigning in ComponentState) and
|
||
(Message.CursorWnd = Handle) and (Screen.Cursor = crDefault) then
|
||
begin
|
||
GetCursorPos(P);
|
||
P := ScreenToClient(P);
|
||
GetSizeCursor(P, SizeCursor, SizeCode);
|
||
if SizeCursor <> 0 then begin
|
||
Windows.SetCursor(Screen.Cursors[SizeCursor]);
|
||
Message.Result := 1;
|
||
end
|
||
else
|
||
inherited;
|
||
end
|
||
else
|
||
inherited;
|
||
end;
|
||
|
||
procedure TSpTBXCustomTitleBar.WMWindowPosChanged(var Message: TWMWindowPosChanged);
|
||
begin
|
||
inherited;
|
||
InvalidateBackground(False);
|
||
if [csDesigning, csDestroying] * ComponentState = [] then begin
|
||
if FOptions.Maximize then
|
||
FOptions.SetupButtonIcon(FOptions.MaximizeButton);
|
||
// Hide the Toolbar if the Form is a MDI child and it's maximized
|
||
if Assigned(FParentForm) and (FParentForm.HandleAllocated) then begin
|
||
if (TCustomFormAccess(FParentForm).FormStyle = fsMDIChild) then
|
||
FDock.Visible := FParentForm.WindowState <> wsMaximized;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ TBitmapHint }
|
||
|
||
procedure TBitmapHint.ActivateHint(Rect: TRect; const AHint: string);
|
||
var
|
||
SaveActivating: Boolean;
|
||
// Detect Delphi 7
|
||
{$IF CompilerVersion < 17}
|
||
MonitorR: TRect;
|
||
Delta: TPoint;
|
||
{$IFEND}
|
||
begin
|
||
// [Bugfix] Delphi 7 bug, D7 hints doesn't support multi-monitors
|
||
{$IF CompilerVersion < 17}
|
||
MonitorR := GetRectOfMonitorContainingPoint(Point(Rect.Left, Rect.Top), True);
|
||
Delta := Point(0, 0);
|
||
if (Rect.Left < MonitorR.Right) and (Rect.Right > MonitorR.Right) then
|
||
Delta.X := - (Rect.Right - MonitorR.Right);
|
||
if (Rect.Top < MonitorR.Bottom) and (Rect.Bottom > MonitorR.Bottom) then
|
||
Delta.Y := - (Rect.Bottom - MonitorR.Bottom);
|
||
OffsetRect(Rect, Delta.X, Delta.Y);
|
||
{$IFEND}
|
||
|
||
SaveActivating := FActivating;
|
||
try
|
||
FActivating := True;
|
||
inherited ActivateHint(Rect, AHint);
|
||
finally
|
||
FActivating := SaveActivating;
|
||
end;
|
||
end;
|
||
|
||
procedure TBitmapHint.ActivateHintData(Rect: TRect; const AHint: string; AData: Pointer);
|
||
begin
|
||
//The AData parameter is a bitmap
|
||
FHintBitmap := TBitmap(AData);
|
||
Rect.Right := Rect.Left + FHintBitmap.Width - 2;
|
||
Rect.Bottom := Rect.Top + FHintBitmap.Height - 2;
|
||
inherited ActivateHintData(Rect, AHint, AData);
|
||
end;
|
||
|
||
procedure TBitmapHint.CMTextChanged(var Message: TMessage);
|
||
begin
|
||
Message.Result := 1;
|
||
end;
|
||
|
||
procedure TBitmapHint.Paint;
|
||
begin
|
||
if Assigned(FHintBitmap) then
|
||
Canvas.Draw(0, 0, FHintBitmap);
|
||
end;
|
||
|
||
//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM
|
||
{ Stock Objects }
|
||
|
||
procedure InitializeStock;
|
||
var
|
||
NonClientMetrics: TNonClientMetrics;
|
||
begin
|
||
// Small caption font
|
||
SmCaptionFont := TFont.Create;
|
||
NonClientMetrics.cbSize := SizeOf(NonClientMetrics);
|
||
if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then
|
||
SmCaptionFont.Handle := CreateFontIndirect(NonClientMetrics.lfSmCaptionFont);
|
||
|
||
SpStockHintBitmap := TBitmap.Create;
|
||
|
||
Screen.Cursors[crSpTBXNewHandPoint] := LoadCursor(0, IDC_HAND);
|
||
Screen.Cursors[crSpTBXCustomization] := LoadCursor(HInstance, 'CZMOVE');
|
||
Screen.Cursors[crSpTBXCustomizationCancel] := LoadCursor(HInstance, 'CZCANCEL');
|
||
|
||
// Dummy ImageList, used by TSpTBXItemViewer and TSpTBXButtonOptions
|
||
MDIButtonsImgList := TImageList.Create(nil);
|
||
end;
|
||
|
||
procedure FinalizeStock;
|
||
begin
|
||
FreeAndNil(SmCaptionFont);
|
||
FreeAndNil(SpStockHintBitmap);
|
||
FreeAndNil(MDIButtonsImgList);
|
||
end;
|
||
|
||
initialization
|
||
InitializeStock;
|
||
|
||
finalization
|
||
FinalizeStock;
|
||
|
||
end.
|