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<EFBFBD>l H<EFBFBD>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<EFBFBD>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.
|