diff --git a/Demos/Customizer/Unit1.dfm b/Demos/Customizer/Unit1.dfm index 2c87c70..0a49b4f 100644 --- a/Demos/Customizer/Unit1.dfm +++ b/Demos/Customizer/Unit1.dfm @@ -21,6 +21,7 @@ object Form1: TForm1 Top = 77 Height = 343 Cursor = crSizeWE + ParentColor = False end object SpTBXSplitter2: TSpTBXSplitter Left = 614 @@ -28,6 +29,7 @@ object Form1: TForm1 Height = 343 Cursor = crSizeWE Align = alRight + ParentColor = False end object SpTBXTabControl1: TSpTBXTabControl Left = 147 @@ -495,11 +497,11 @@ object Form1: TForm1 Height = 343 object dpLog: TSpTBXDockablePanel Left = 0 - Top = 156 + Top = 0 Width = 142 Height = 187 Caption = 'Commands Log' - DockPos = 156 + DockPos = 0 TabOrder = 0 object Memo1: TMemo Left = 0 @@ -515,11 +517,11 @@ object Form1: TForm1 end object dpOptions: TSpTBXDockablePanel Left = 0 - Top = 0 + Top = 187 Width = 142 Height = 156 Caption = 'Customizer Options' - DockPos = 0 + DockPos = 187 TabOrder = 1 end end @@ -604,7 +606,7 @@ object Form1: TForm1 Left = 192 Top = 352 Bitmap = { - 494C01011A001D00080010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C01011A001D00040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000007000000001002000000000000070 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/Demos/Customizer/Unit1.pas b/Demos/Customizer/Unit1.pas index ae29edf..aaa2ffb 100644 --- a/Demos/Customizer/Unit1.pas +++ b/Demos/Customizer/Unit1.pas @@ -355,7 +355,7 @@ procedure TForm1.FormCreate(Sender: TObject); FillLayoutList('LastLayout'); // Enable high DPI on the image list - SpDPIScaleImageList(ImageList1); + // Use TVirtualImageList! SpDPIScaleImageList(ImageList1); end; end. diff --git a/Demos/Customizer/gnugettext.pas b/Demos/Customizer/gnugettext.pas index f815536..52df9bd 100644 --- a/Demos/Customizer/gnugettext.pas +++ b/Demos/Customizer/gnugettext.pas @@ -2219,7 +2219,7 @@ function TGnuGettextInstance.LoadResString( const ResStringTableLen = 16; type - ResStringTable = array [0..ResStringTableLen-1] of LongWord; + ResStringTable = array [0..ResStringTableLen-1] of FixedUInt; var Handle: TResourceHandle; Tab: ^ResStringTable; diff --git a/Demos/Overview/Unit1.dfm b/Demos/Overview/Unit1.dfm index 9cae50a..47b1fea 100644 --- a/Demos/Overview/Unit1.dfm +++ b/Demos/Overview/Unit1.dfm @@ -1,9 +1,9 @@ object Form1: TForm1 Left = 279 Top = 147 - Caption = 'SpTBXLib Demo' - ClientHeight = 555 - ClientWidth = 716 + Caption = 'SpTBXLib Demo - Per Monitor V2 High DPI Enabled' + ClientHeight = 561 + ClientWidth = 723 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -18,31 +18,31 @@ object Form1: TForm1 TextHeight = 13 object SpTBXSplitter1: TSpTBXSplitter Left = 273 - Top = 76 - Height = 452 + Top = 75 + Height = 463 Cursor = crSizeWE ParentColor = False end object SpTBXSplitter2: TSpTBXSplitter - Left = 575 - Top = 76 - Height = 452 + Left = 582 + Top = 75 + Height = 463 Cursor = crSizeWE Align = alRight ParentColor = False end object SpTBXMultiDock1: TSpTBXMultiDock Left = 0 - Top = 76 + Top = 75 Width = 273 - Height = 452 + Height = 463 object SpTBXDockablePanel1: TSpTBXDockablePanel Left = 0 - Top = 154 + Top = 0 Width = 273 Height = 298 Caption = 'Options Panel' - DockPos = 154 + DockPos = 0 TabOrder = 0 object SpTBXSubmenuItem1: TSpTBXSubmenuItem Options = [tboDropdownArrow] @@ -68,6 +68,57 @@ object Form1: TForm1 object SpTBXTabItem3: TSpTBXTabItem Caption = 'Misc' end + object SpTBXTabSheet3: TSpTBXTabSheet + Left = 0 + Top = 25 + Width = 269 + Height = 250 + Caption = 'Misc' + ImageIndex = -1 + DesignSize = ( + 269 + 250) + TabItem = 'SpTBXTabItem3' + object SpTBXGroupBox5: TSpTBXGroupBox + Left = 8 + Top = 8 + Width = 252 + Height = 133 + Caption = 'Links' + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + object SpTBXLabel2: TSpTBXLabel + Left = 8 + Top = 24 + Width = 151 + Height = 19 + Caption = 'Go to Silverpoint Development' + LinkText = 'http://www.silverpointdevelopment.com' + end + object SpTBXLabel3: TSpTBXLabel + Left = 8 + Top = 48 + Width = 156 + Height = 19 + Caption = 'Go to Toolbar2000 newsgroups' + LinkText = 'news://news.jrsoftware.org' + end + object SpTBXLabel4: TSpTBXLabel + Left = 8 + Top = 72 + Width = 119 + Height = 19 + Caption = 'Open Documents folder' + end + object SpTBXLabel5: TSpTBXLabel + Left = 8 + Top = 96 + Width = 184 + Height = 19 + Caption = 'Open Documents folder with the tree' + end + end + end object SpTBXTabSheet6: TSpTBXTabSheet Left = 0 Top = 25 @@ -83,7 +134,7 @@ object Form1: TForm1 Left = 8 Top = 112 Width = 252 - Height = 49 + Height = 102 Anchors = [akLeft, akTop, akRight, akBottom] TabOrder = 4 HotTrack = True @@ -91,7 +142,7 @@ object Form1: TForm1 Left = 2 Top = 22 Width = 248 - Height = 25 + Height = 78 Align = alClient BorderStyle = bsNone Lines.Strings = ( @@ -197,79 +248,12 @@ object Form1: TForm1 Width = 121 Height = 21 ItemHeight = 23 - ItemIndex = 6 + ItemIndex = 3 TabOrder = 6 Text = 'Arial' SelectedFont = 'Arial' end end - object SpTBXTabSheet3: TSpTBXTabSheet - Left = 0 - Top = 25 - Width = 269 - Height = 250 - Caption = 'Misc' - ImageIndex = -1 - DesignSize = ( - 269 - 250) - TabItem = 'SpTBXTabItem3' - object SpTBXGroupBox5: TSpTBXGroupBox - Left = 8 - Top = 8 - Width = 252 - Height = 177 - Caption = 'Links' - Anchors = [akLeft, akTop, akRight] - TabOrder = 0 - object SpTBXLabel2: TSpTBXLabel - Left = 8 - Top = 24 - Width = 151 - Height = 19 - Caption = 'Go to Silverpoint Development' - LinkText = 'http://www.silverpointdevelopment.com' - end - object SpTBXLabel3: TSpTBXLabel - Left = 8 - Top = 48 - Width = 156 - Height = 19 - Caption = 'Go to Toolbar2000 newsgroups' - LinkText = 'news://news.jrsoftware.org' - end - object SpTBXLabel4: TSpTBXLabel - Left = 8 - Top = 72 - Width = 128 - Height = 19 - Caption = 'Open the Windows folder' - end - object SpTBXLabel7: TSpTBXLabel - Left = 8 - Top = 144 - Width = 105 - Height = 19 - Cursor = crHandPoint - Caption = 'View the sourcecode' - LinkText = 'notepad.exe' - end - object SpTBXLabel5: TSpTBXLabel - Left = 8 - Top = 96 - Width = 106 - Height = 19 - Caption = 'Open it with the tree' - end - object SpTBXLabel6: TSpTBXLabel - Left = 8 - Top = 120 - Width = 74 - Height = 19 - Caption = 'Open WinAmp' - end - end - end object SpTBXTabSheet1: TSpTBXTabSheet Left = 0 Top = 25 @@ -351,8 +335,8 @@ object Form1: TForm1 object progressFiles: TSpTBXCheckBox Left = 160 Top = 102 - Width = 85 - Height = 21 + Width = 89 + Height = 25 Caption = 'File progress' TabOrder = 6 OnClick = progressFilesClick @@ -402,28 +386,28 @@ object Form1: TForm1 end object SpTBXDockablePanel2: TSpTBXDockablePanel Left = 0 - Top = 0 + Top = 298 Width = 273 - Height = 154 + Height = 165 Caption = 'Skins Options' - DockPos = 0 + DockPos = 298 TabOrder = 1 DesignSize = ( 269 - 150) + 161) object SpTBXGroupBox3: TSpTBXGroupBox Left = 13 Top = 26 Width = 241 - Height = 113 + Height = 124 Caption = 'Skin Type' Anchors = [akLeft, akTop, akRight, akBottom] TabOrder = 2 object radiobuttonSkin1: TSpTBXRadioButton Left = 16 Top = 24 - Width = 67 - Height = 21 + Width = 71 + Height = 25 Caption = 'Windows' TabOrder = 0 TabStop = True @@ -434,8 +418,8 @@ object Form1: TForm1 object radiobuttonSkin2: TSpTBXRadioButton Left = 16 Top = 51 - Width = 74 - Height = 21 + Width = 78 + Height = 25 Caption = 'VCL Styles' TabOrder = 1 OnClick = rgSkinTypeClick @@ -444,8 +428,8 @@ object Form1: TForm1 object radiobuttonSkin3: TSpTBXRadioButton Left = 16 Top = 78 - Width = 48 - Height = 21 + Width = 52 + Height = 25 Caption = 'Skins' TabOrder = 2 OnClick = rgSkinTypeClick @@ -465,11 +449,12 @@ object Form1: TForm1 object SpTBXDock1: TSpTBXDock Left = 0 Top = 0 - Width = 716 - Height = 76 + Width = 723 + Height = 75 object SpTBXToolbar1: TSpTBXToolbar Left = 0 Top = 0 + DockPos = 2 ShrinkMode = tbsmNone Stretch = True TabOrder = 0 @@ -520,8 +505,8 @@ object Form1: TForm1 TabOrder = 1 Caption = 'SpTBXToolbar3' DesignSize = ( - 708 - 22) + 713 + 21) object SpTBXLabelItem3: TSpTBXLabelItem Caption = '&Address:' Control = SpTBXComboBox1 @@ -535,13 +520,12 @@ object Form1: TForm1 object SpTBXItem1: TSpTBXItem Caption = 'Go' DisplayMode = nbdmImageAndText - ImageIndex = 1 - Images = ImageList1 + ImageIndex = 5 end object SpTBXComboBox1: TSpTBXComboBox Left = 55 Top = 0 - Width = 605 + Width = 600 Height = 21 Anchors = [akLeft, akTop, akRight] ItemHeight = 13 @@ -553,7 +537,7 @@ object Form1: TForm1 end object SpTBXToolbar2: TSpTBXToolbar Left = 0 - Top = 51 + Top = 50 DockPos = 8 DockRow = 2 ShrinkMode = tbsmNone @@ -569,25 +553,24 @@ object Form1: TForm1 object SpTBXItem4: TSpTBXItem Caption = 'Anchored Item' Anchored = True - CustomWidth = 497 + CustomWidth = 500 end end end object SpTBXMultiDock3: TSpTBXMultiDock - Left = 580 - Top = 76 + Left = 587 + Top = 75 Width = 136 - Height = 452 + Height = 463 Position = dpxRight object DP1: TSpTBXDockablePanel Left = 0 Top = 286 Width = 136 - Height = 166 + Height = 177 Caption = 'Panel1' DockPos = 286 TabOrder = 0 - Images = ImageList1 Options.Close = False Options.Minimize = True Options.Maximize = True @@ -631,13 +614,12 @@ object Form1: TForm1 Caption = 'Panel2' DockPos = 164 TabOrder = 1 - Images = ImageList1 Options.ButtonBorders = False Options.Close = False Options.Minimize = True - Options.MinimizeImageIndex = 5 + Options.MinimizeImageIndex = 1 Options.MaximizeImageIndex = 8 - Options.RestoreImageIndex = 6 + Options.RestoreImageIndex = 0 object SpTBXLabel11: TSpTBXLabel Left = 8 Top = 32 @@ -671,13 +653,11 @@ object Form1: TForm1 Caption = 'Panel3' DockPos = 0 TabOrder = 2 - Images = ImageList1 Options.ButtonBorders = False Options.Close = False Options.Minimize = True - Options.MinimizeImageIndex = 5 - Options.MaximizeImageIndex = 8 - Options.RestoreImageIndex = 6 + Options.MinimizeImageIndex = 1 + Options.RestoreImageIndex = 0 object SpTBXLabel15: TSpTBXLabel Left = 8 Top = 32 @@ -706,9 +686,9 @@ object Form1: TForm1 end object Panel1: TPanel Left = 278 - Top = 76 - Width = 297 - Height = 452 + Top = 75 + Width = 304 + Height = 463 Align = alClient BevelOuter = bvNone TabOrder = 2 @@ -1402,14 +1382,13 @@ object Form1: TForm1 object SpTBXTabControl1: TSpTBXTabControl Left = 0 Top = 0 - Width = 297 - Height = 452 + Width = 304 + Height = 463 Align = alClient ActiveTabIndex = -1 - Images = ImageList1 HiddenItems = <> object SpTBXRightAlignSpacerItem1: TSpTBXRightAlignSpacerItem - CustomWidth = 210 + CustomWidth = 268 end object SpTBXSubmenuItem2: TSpTBXSubmenuItem Options = [tboDropdownArrow] @@ -1431,12 +1410,12 @@ object Form1: TForm1 end object SpTBXStatusBar1: TSpTBXStatusBar Left = 0 - Top = 528 - Width = 716 - Height = 27 + Top = 538 + Width = 723 + Height = 23 ParentShowHint = False ShowHint = True - ExplicitTop = 530 + ExplicitTop = 536 object TBControlItem2: TTBControlItem Control = SpTBXProgressBar2 end @@ -1448,13 +1427,6 @@ object Form1: TForm1 end object SpTBXSeparatorItem4: TSpTBXSeparatorItem end - object SpTBXLabelItem6: TSpTBXLabelItem - Caption = 'C:\Mozilla' - ImageIndex = 0 - Images = ImageList1 - end - object SpTBXSeparatorItem3: TSpTBXSeparatorItem - end object subLang2: TSpTBXSubmenuItem Caption = 'Languages' Options = [tboDropdownArrow] @@ -1466,7 +1438,7 @@ object Form1: TForm1 end object SpTBXProgressBar2: TSpTBXProgressBar Left = 0 - Top = 2 + Top = 0 Width = 140 Height = 19 Caption = '30%' @@ -1499,7 +1471,7 @@ object Form1: TForm1 end object ActionList1: TActionList OnUpdate = ActionList1Update - Left = 376 + Left = 408 Top = 352 object Action1: TAction OnExecute = Action1Execute @@ -1508,413 +1480,6 @@ object Form1: TForm1 OnExecute = Action2Execute end end - object ImageList1: TImageList - Left = 408 - Top = 352 - Bitmap = { - 494C01010A000E00340010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 - 0000000000003600000028000000400000003000000001002000000000000030 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 0000B7CEC400C5DED600C3DAD100C5DBD200C4DAD100C2DAD200C7E2DA000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000B7CEC400BCD1C500C6D8CE00CBDBD300CBDBD300C6D8CE00BDD2C700B8D0 - C500000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF0084B58400107310001873 - 18001873180018731800187B1800187B1800107B1000107B1000087B0800087B - 0800007B0000007300007BB57B00FFFFFF00000000000000000000000000BFD5 - CA00C8D9CF00DDE7E100E7EEEA00EEF3F000EBF1EE00E0E9E400CCDBD300B7CD - C00000000000000000000000000000000000000000000000000000000000B8CE - C100D4E2DB00E9F1EE00F0F6F400F0F6F500EFF5F300EDF3F100E4EDE900D0DF - D700BACFC3000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF0010841000218C21002994 - 2900319431003194310029942900299C2900219C210018A5180018A5180010A5 - 100008A5080000940000006B0000FFFFFF000000000000000000BBD0C400DBE6 - E000F7F9F800FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FDFEFD00E7EE - EA00C2D4CA000000000000000000000000000000000000000000BACFC300E0EA - E500F7FAFA00F6F9F800F7FAFA00F7FAFA00F6F9F800F4F8F700F1F6F500EEF4 - F200D8E5DF00BBD0C50000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF00188C180029942900399C - 3900399C3900399C3900FFFFFF00A5D6A5004AA54A004AA54A004AA54A0029A5 - 290018A51800009C0000007B0000FFFFFF0000000000BCD1C600DDE7E100FDFE - FD00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00F1F5F300C3D5CB00000000000000000000000000B8CDC100E3ECE700FBFC - FC00FBFCFC00FBFCFC00FDFEFE001C674B00FDFEFE00FBFCFC00F8FBFA00F3F8 - F700EFF5F300D8E4DE00B9CFC300000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF0021942100399C390042A5 - 420042A5420042A54200FFFFFF00FFFFFF00A5D6A5004AA54A004AA54A0039A5 - 390021A5210008A50800087B0800FFFFFF00C2DAD200D1DFD800FBFCFC00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00ECF2EF00B9CEC20000000000BED5CB00D3E1D900FDFEFD00FEFF - FE00FEFFFE00FFFFFF001C674B001C674B001C674B00FFFFFF00FDFEFE00FAFC - FC00F4F8F700EDF3F100C9DAD100BBD6CC000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF0029942900429C42004AA5 - 4A0052A552004AA54A00FFFFFF00FFFFFF00FFFFFF00A5D6A5004AA54A0039A5 - 390021A5210010A5100008840800FFFFFF00BFD5C900EBF1EE00FFFFFF00FFFF - FF001C674B001C674B00FFFFFF00FFFFFF00FFFFFF001C674B001C674B00FFFF - FF00FEFFFE00FDFEFE00D1DFD700BED8CE00BCD1C600EEF3F000FFFFFF00FFFF - FF00FFFFFF001C674B001C674B00FFFFFF001C674B001C674B00FFFFFF00FDFE - FE00F9FBFB00F3F8F700DDE8E300BAD2C9000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF00319C31004AA54A0052A5 - 52004AA54A004AA54A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5D6A50039A5 - 390021A5210018A5180010841000FFFFFF00C7D8CE00F9FBFA00FFFFFF00FFFF - FF00FFFFFF001C674B001C674B00FFFFFF001C674B001C674B00FFFFFF00FFFF - FF00FEFFFE00FBFCFC00E4EDE900BBD3CA00C4D6CC00FBFCFC00FFFFFF00FFFF - FF001C674B001C674B00FFFFFF00FFFFFF00FFFFFF001C674B001C674B00FEFF - FE00FBFCFC00F6F9F800E7EFEC00BCD3C8000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF00429C420052A552004AA5 - 4A004AA54A004AA54A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5D6 - A500219C2100219C210018841800FFFFFF00CDDCD300FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF001C674B001C674B001C674B00FFFFFF00FFFFFF00FFFF - FF00FDFEFE00FAFCFC00EAF1EE00BCD2C900CCDBD300FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF001C674B00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FCFDFD00F9FBFB00EBF1EF00BED5CA000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF0042A5420052A5520052A5 - 52004AA54A004AA54A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5D6 - A500219C2100219C2100217B2100FFFFFF00CCDBD300FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF001C674B00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FCFDFD00F9FBFB00EBF1EF00BED5CA00CDDCD300FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF001C674B001C674B001C674B00FFFFFF00FFFFFF00FFFF - FF00FDFEFE00FAFCFC00EAF1EE00BCD2C9000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF0052A552005AAD5A005AAD - 5A0052A552004AA54A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5D6A5003194 - 31002994290029942900217B2100FFFFFF00C4D6CC00FBFCFC00FFFFFF00FFFF - FF001C674B001C674B00FFFFFF00FFFFFF00FFFFFF001C674B001C674B00FEFF - FE00FBFCFC00F6F9F800E7EFEC00BCD3C800C7D8CE00F9FBFA00FFFFFF00FFFF - FF00FFFFFF001C674B001C674B00FFFFFF001C674B001C674B00FFFFFF00FFFF - FF00FEFFFE00FBFCFC00E4EDE900BBD3CA000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF0052A552006BB56B006BB5 - 6B005AAD5A0052AD5200FFFFFF00FFFFFF00FFFFFF00A5D6A500399C39003194 - 31002994290029942900217B2100FFFFFF00BCD1C600EEF3F000FFFFFF00FFFF - FF00FFFFFF001C674B001C674B00FFFFFF001C674B001C674B00FFFFFF00FDFE - FE00F9FBFB00F3F8F700DDE8E300BAD2C900BFD5C900EBF1EE00FFFFFF00FFFF - FF001C674B001C674B00FFFFFF00FFFFFF00FFFFFF001C674B001C674B00FFFF - FF00FEFFFE00FDFEFE00D1DFD700BED8CE000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF005AAD5A007BBD7B0073BD - 730063AD63005AAD5A00FFFFFF00FFFFFF00A5D6A500429C4200429C4200399C - 39003194310031943100217B2100FFFFFF00BED5CB00D3E1D900FDFEFD00FEFF - FE00FEFFFE00FFFFFF001C674B001C674B001C674B00FFFFFF00FDFEFE00FAFC - FC00F4F8F700EDF3F100C9DAD100BBD6CC00C2DAD200D1DFD800FBFCFC00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00ECF2EF00B9CEC200000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF006BB56B008CC68C007BBD - 7B006BB56B0063B56300FFFFFF00A5D6A5005AAD5A0052A552004AA54A0042A5 - 4200399C390031943100217B2100FFFFFF0000000000B8CDC100E3ECE700FBFC - FC00FBFCFC00FBFCFC00FDFEFE001C674B00FDFEFE00FBFCFC00F8FBFA00F3F8 - F700EFF5F300D8E4DE00B9CFC3000000000000000000BCD1C600DDE7E100FDFE - FD00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00F1F5F300C3D5CB0000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF0073BD73009CCE9C008CC6 - 8C007BBD7B0073BD73006BB56B0063B5630063AD63005AAD5A0052AD52004AA5 - 4A0042A542003194310018731800FFFFFF000000000000000000BACFC300E0EA - E500F7FAFA00F6F9F800F7FAFA00F7FAFA00F6F9F800F4F8F700F1F6F500EEF4 - F200D8E5DF00BBD0C50000000000000000000000000000000000BBD0C400DBE6 - E000F7F9F800FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FDFEFD00E7EE - EA00C2D4CA000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000FFFFFF00B5DEB50073BD730063B5 - 63005AAD5A0052A5520052A552004AA54A004AA54A0042A54200429C4200399C - 390031943100218C21008CBD8C00FFFFFF00000000000000000000000000B8CE - C100D4E2DB00E9F1EE00F0F6F400F0F6F500EFF5F300EDF3F100E4EDE900D0DF - D700BACFC300000000000000000000000000000000000000000000000000BFD5 - CA00C8D9CF00DDE7E100E7EEEA00EEF3F000EBF1EE00E0E9E400CCDBD300B7CD - C000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 0000B7CEC400BCD1C500C6D8CE00CBDBD300CBDBD300C6D8CE00BDD2C700B8D0 - C500000000000000000000000000000000000000000000000000000000000000 - 0000B7CEC400C5DED600C3DAD100C5DBD200C4DAD100C2DAD200C7E2DA000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000 - 0000B8BDBD000000870000007600110000006565650000000000000000000000 - 000000000000000000000000000000000000FFFFFF0084B58400107310001873 - 18001873180018731800187B1800187B1800107B1000107B1000087B0800087B - 0800007B0000007300007BB57B00FFFFFF00FFFFFF0052ADFF0018529400185A - 9C00185A9C00185A9C00185AA500185AA500185A9C00185A9C00185294001852 - 940018528C00184A84004AADFF00FFFFFF00FFFFFF0084B58400107310001873 - 18001873180018731800187B1800187B1800107B1000107B1000087B0800087B - 0800007B0000007300007BB57B00FFFFFF000000000000000000B8BDBD003232 - 32000000A9000000FF000000DD00000043005454540000000000000000000000 - 000000000000000000000000000000000000FFFFFF0010841000218C21002994 - 2900319431003194310029942900299C2900219C210018A5180018A5180010A5 - 100008A5080000940000006B0000FFFFFF00FFFFFF00185AA500186BBD001873 - CE001873CE001873CE001873CE001873CE001873CE001873CE001873CE00186B - C600186BBD00185AA500104A7B00FFFFFF00FFFFFF0010841000218C21002994 - 2900319431003194310029942900299C2900219C210018A5180018A5180010A5 - 100008A5080000940000006B0000FFFFFF000000000000000000767676000000 - 43000000FF000000FF0000008700003298002121210000000000000000000000 - 000000000000000000000000000000000000FFFFFF00188C180029942900399C - 3900399C3900399C390039A53900A5D6A500FFFFFF0021AD210018AD180010B5 - 100008AD0800009C0000007B0000FFFFFF00FFFFFF001863AD001873CE00187B - DE00187BDE00187BE7001884E700188CF700188CF700188CF700188CF700187B - DE00186BC6001863AD0018528C00FFFFFF00FFFFFF00188C180029942900399C - 3900399C3900399C390039A539004AA54A00A5D6A500FFFFFF004AA54A0031A5 - 310018A51800009C0000007B0000FFFFFF000000000088898900B8BDBE000000 - 4300000087000000EE000000FF000000CC000000320076767600000000000000 - 000000000000000000000000000000000000FFFFFF0021942100399C390042A5 - 42004AA54A0042A5420042A54200FFFFFF00FFFFFF00FFFFFF0021B5210018B5 - 180010AD100008A50800087B0800FFFFFF00FFFFFF00186BC600187BDE001884 - EF00FFFFFF0084C6FF00188CF700188CF700188CF700188CF70084C6FF00FFFF - FF001873CE00186BBD0018529400FFFFFF00FFFFFF0021942100399C390042A5 - 420042A5420042A542004AA54A00A5D6A500FFFFFF00FFFFFF004AA54A0039A5 - 390021A5210008A50800087B0800FFFFFF000000000000000000001100000000 - A9000000FF000000FF000000FF000000DD001111110000002100545454007676 - 76003200980000323200A0A2A20000000000FFFFFF0029942900429C42004AA5 - 4A0052A552004AA54A0042A5420042AD4200FFFFFF00FFFFFF00FFFFFF0018B5 - 180010AD100010A5100008840800FFFFFF00FFFFFF001873CE001884E700188C - F700188CFF00FFFFFF0084C6FF00188CF700188CF70084C6FF00FFFFFF001884 - E7001873D600186BC600185A9C00FFFFFF00FFFFFF0029942900429C42004AA5 - 4A0052A552004AA54A00A5D6A500FFFFFF00FFFFFF00FFFFFF004AA54A0039A5 - 390021A5210010A5100008840800FFFFFF0000000000B9BEBF00110000000000 - 87000000FF000000CC000000EE0000008700000087000000FF000000BA000000 - 870000006500767676000021000065656500FFFFFF00319C31004AA54A0052A5 - 520052A552004AA54A004AA54A0042A5420039AD3900FFFFFF00FFFFFF00FFFF - FF0018AD180018A5180010841000FFFFFF00FFFFFF00187BDE00188CF700188C - FF00188CF700188CF700FFFFFF0084C6FF0084C6FF00FFFFFF00188CF7001884 - E7001873D6001873CE00185AA500FFFFFF00FFFFFF00319C31004AA54A0052A5 - 52004AA54A00A5D6A500FFFFFF00FFFFFF00FFFFFF00FFFFFF004AA54A0039A5 - 390021A5210018A5180010841000FFFFFF000000000021212100000021000000 - A9000000FF0000004300000087000000FF000000FF0000007600000043000000 - 430076767600323265000000A90000006500FFFFFF00429C420052A55200FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00219C210018841800FFFFFF00FFFFFF001884E700188CFF00188C - F700188CF700188CF700188CF700FFFFFF0084C6FF00188CF7001884EF00187B - DE001873CE001873CE001863AD00FFFFFF00FFFFFF00429C420052A552004AA5 - 4A00A5D6A500FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0042A5420031A5 - 3100219C2100219C210018841800FFFFFF000000000088888800000098000000 - FF000000EE00000076000000EE000000FF000000EE0000003200110000005454 - 54000000EE000000FF000000DD0032326500FFFFFF0042A542005AAD5A00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00219C2100217B2100FFFFFF00FFFFFF001884EF00188CFF00188C - FF00188CF700188CF70084C6FF00FFFFFF00FFFFFF0084C6FF001884E7001873 - D6001873CE001873CE001863AD00FFFFFF00FFFFFF0042A5420052A5520052A5 - 5200A5D6A500FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00399C3900299C - 2900219C2100219C2100217B2100FFFFFF000000000011000000000043000032 - CC000000FF00000098000000FF000000FF000000EE00000076000000A9000000 - CC000000FF000000FF000000A90021212100FFFFFF0052A5520063AD630063AD - 63005AAD5A0052A552004AA54A00429C4200399C3900FFFFFF00FFFFFF00FFFF - FF00299C290029942900217B2100FFFFFF00FFFFFF00188CFF002194FF002194 - FF00188CFF0084C6FF00FFFFFF001884F7001884EF00FFFFFF0084C6FF001873 - CE001873CE001873CE001863AD00FFFFFF00FFFFFF0052A552005AAD5A005AAD - 5A0052A55200A5D6A500FFFFFF00FFFFFF00FFFFFF00FFFFFF00399C39003194 - 31002994290029942900217B2100FFFFFF000000000088898900000000000000 - A9000000FF000000EE0000007600000054000032CC000000A9000000EE000000 - EE000000BA0000006500BABEBE0000000000FFFFFF0052A552006BB56B006BB5 - 6B005AAD5A0052A552004AA54A00429C4200FFFFFF00FFFFFF00FFFFFF002994 - 29002994290029942900217B2100FFFFFF00FFFFFF00188CFF0039A5FF0039A5 - FF0084C6FF00FFFFFF00188CFF00188CFF001884EF001884E700FFFFFF0084C6 - FF001873CE001873CE001863AD00FFFFFF00FFFFFF0052A552006BB56B006BB5 - 6B005AAD5A0052AD5200A5D6A500FFFFFF00FFFFFF00FFFFFF00399C39003194 - 31002994290029942900217B2100FFFFFF000000000000000000000000000000 - 54000000FF000000BA000032CC000000A900000076003200CC00545454002121 - 21000000A900000000000000000000000000FFFFFF005AAD5A007BBD7B0073BD - 730063AD63005AAD5A0052A55200FFFFFF00FFFFFF00FFFFFF00319C3100319C - 31003194310031943100217B2100FFFFFF00FFFFFF002194FF0052ADFF004AAD - FF00FFFFFF002194FF002194FF001894FF00188CF7001884EF001884E700FFFF - FF001873CE001873CE001863AD00FFFFFF00FFFFFF005AAD5A007BBD7B0073BD - 730063AD63005AAD5A005AAD5A00A5D6A500FFFFFF00FFFFFF00429C4200399C - 39003194310031943100217B2100FFFFFF0000000000A0A2A200000000000000 - 54000000A90000005400000076000032FF000000760000005400212121000000 - 110000000000000000000000000000000000FFFFFF006BB56B008CC68C007BBD - 7B006BB56B0063B5630063AD6300B5DEB500FFFFFF004AA54A004AA54A0042A5 - 4200399C390031943100217B2100FFFFFF00FFFFFF0039A5FF006BBDFF0052AD - FF0039A5FF00319CFF00299CFF00299CFF002194FF00188CFF001884F7001884 - EF00187BDE001873CE001863AD00FFFFFF00FFFFFF006BB56B008CC68C007BBD - 7B006BB56B0063B5630063AD630063AD6300A5D6A500FFFFFF004AA54A0042A5 - 4200399C390031943100217B2100FFFFFF000000000000000000000000003232 - 3200000043000000CC000000A9000000DD00000065000000430000004300BBBF - BF0000000000000000000000000000000000FFFFFF0073BD73009CCE9C008CC6 - 8C007BBD7B0073BD73006BB56B0063B5630063AD63005AAD5A0052AD52004AA5 - 4A0042A542003194310018731800FFFFFF00FFFFFF004AADFF0084C6FF006BBD - FF0052ADFF004AADFF0039A5FF00319CFF00299CFF002194FF001894FF00188C - F7001884EF001873CE00185A9C00FFFFFF00FFFFFF0073BD73009CCE9C008CC6 - 8C007BBD7B0073BD73006BB56B0063B5630063AD63005AAD5A0052AD52004AA5 - 4A0042A542003194310018731800FFFFFF000000000000000000000000000000 - 00008888880021212100000043003232320089898900BDC0C100000000000000 - 000000000000000000000000000000000000FFFFFF00B5DEB50073BD730063B5 - 63005AAD5A0052A5520052A552004AA54A004AA54A0042A54200429C4200399C - 390031943100218C21008CBD8C00FFFFFF00FFFFFF00ADDEFF004AADFF00319C - FF002194FF00188CFF00188CFF00188CF700188CF7001884EF001884E700187B - DE001873CE00186BBD0063B5FF00FFFFFF00FFFFFF00B5DEB50073BD730063B5 - 63005AAD5A0052A5520052A552004AA54A004AA54A0042A54200429C4200399C - 390031943100218C21008CBD8C00FFFFFF000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF0000000000424D3E000000000000003E000000 - 2800000040000000300000000100010000000000800100000000000000000000 - 000000000000000000000000FFFFFF00FFFFFFFF00000000FFFFFFFF00000000 - FFFFFFFF00000000F00FF03F00000000F7EFF7BF00000000F7EFF7BF00000000 - F7EFF78F00000000F7EFF02F00000000F7EFF02F00000000F00FFDEF00000000 - F00FFC0F00000000FFFFFC0F00000000FFFFFFFF00000000FFFFFFFF00000000 - FFFFFFFF00000000FFFFFFFF000000008001F01FF00FFFFF0000E00FE007FFFF - 0000C007C003FFFF000080038001FFFF000000010000F81F000000000000F81F - 000000000000FFFF000000000000FFFF000000000000FFFF000000000000FFFF - 000000000000FFFF000000000001FFFF000080018003FFFF0000C003C007FFFF - 0000E007E00FFFFF8001F00FF01FFFFFFFFF800180018001F07F000000000000 - C07F000000000000C07F000000000000003F0000000000008001000000000000 - 0000000000000000800000000000000000000000000000008000000000000000 - 00010000000000008007000000000000800F000000000000E00F000000000000 - F03F000000000000FFFF80018001800100000000000000000000000000000000 - 000000000000} - end object Timer1: TTimer Enabled = False Interval = 50 diff --git a/Demos/Overview/Unit1.pas b/Demos/Overview/Unit1.pas index 21812c7..242a587 100644 --- a/Demos/Overview/Unit1.pas +++ b/Demos/Overview/Unit1.pas @@ -9,7 +9,13 @@ interface TB2Item, TB2Toolbar, TB2Dock, TB2ExtItems, // SpTBXLib SpTBXSkins, SpTBXItem, SpTBXDkPanels, SpTBXTabs, SpTBXEditors, SpTBXControls, - SpTBXExtEditors; + SpTBXExtEditors, + {$IF CompilerVersion >= 33} // for Delphi Rio and up + // TImageCollection and TVirtualImagelist introduced on Rio + Vcl.VirtualImageList, Vcl.BaseImageCollection, Vcl.ImageCollection, + {$IFEND} + System.ImageList; + type TForm1 = class(TForm) @@ -45,9 +51,6 @@ TForm1 = class(TForm) SpTBXStatusBar1: TSpTBXStatusBar; SpTBXSeparatorItem2: TSpTBXSeparatorItem; hintLabel: TSpTBXLabelItem; - SpTBXSeparatorItem3: TSpTBXSeparatorItem; - ImageList1: TImageList; - SpTBXLabelItem6: TSpTBXLabelItem; SpTBXSeparatorItem4: TSpTBXSeparatorItem; subLang2: TSpTBXSubmenuItem; Image1: TImage; @@ -59,7 +62,6 @@ TForm1 = class(TForm) SpTBXLabel2: TSpTBXLabel; SpTBXLabel3: TSpTBXLabel; SpTBXLabel4: TSpTBXLabel; - SpTBXLabel7: TSpTBXLabel; SpTBXLabel5: TSpTBXLabel; SpTBXToolbar2: TSpTBXToolbar; SpTBXItem1: TSpTBXItem; @@ -67,7 +69,6 @@ TForm1 = class(TForm) SpTBXItem3: TSpTBXItem; SpTBXItem4: TSpTBXItem; SpTBXSeparatorItem7: TSpTBXSeparatorItem; - SpTBXLabel6: TSpTBXLabel; DP1: TSpTBXDockablePanel; DP2: TSpTBXDockablePanel; DP3: TSpTBXDockablePanel; @@ -151,11 +152,16 @@ TForm1 = class(TForm) procedure FormDestroy(Sender: TObject); private { Private declarations } - FLastSkin: WideString; + FLastSkin: string; procedure LangClick(Sender: TObject); procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE; public - AppPath: String; + AppPath: string; + {$IF CompilerVersion >= 33} // for Delphi Rio and up + // TImageCollection and TVirtualImagelist introduced on Rio + IC: TImageCollection; + {$IFEND} + IL: TCustomImageList; end; var @@ -164,52 +170,21 @@ TForm1 = class(TForm) implementation uses - Themes, Registry, ShlObj; + Themes, Registry, IOUtils; {$R *.dfm} //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Utility functions } -function SpGetWindowsDir: String; -var - Z: Cardinal; -begin - Z := GetWindowsDirectory(nil, 0); - if Z > 0 then begin - SetLength(Result, Z); - GetWindowsDirectory(PChar(Result), Z); - Result := IncludeTrailingPathDelimiter(Result); - end - else - Result := ''; -end; - -function SpGetCommonDocumentsFolder: string; -// Gets All Users\Documents folder. -// Gets Public\Documents folder on Vista -var - TargetPIDL: PItemIDList; - S: string; -begin - Result := ''; - if Succeeded(SHGetSpecialFolderLocation(Application.Handle, CSIDL_COMMON_DOCUMENTS, TargetPIDL)) then - begin - SetLength(S, MAX_PATH); - FillChar(PChar(S)^, MAX_PATH, #0); - if SHGetPathFromIDList(TargetPIDL, PChar(S)) then begin - SetLength(S, StrLen(PChar(S))); - Result := IncludeTrailingPathDelimiter(S); - end; - end; -end; - function SpIDEBDSCommonDir(RADStudioIDENumber: Integer): string; var S: string; begin Result := ''; - S := SpGetCommonDocumentsFolder + 'RAD Studio\' + IntToStr(RADStudioIDENumber) + '.0\Styles'; // RAD Studio\5.0 + // C:\Users\Public\Documents\Embarcadero\Studio\21.0 + S := IncludeTrailingPathDelimiter(TPath.GetSharedDocumentsPath) + + 'Embarcadero\Studio\' + IntToStr(RADStudioIDENumber) + '.0'; if DirectoryExists(S) then Result := S; end; @@ -221,8 +196,8 @@ function SpGetDelphiStylesFolder: string; begin Result := ''; // XE2 = 9 - for I := 20 downto 9 do begin - S := SpIDEBDSCommonDir(I); + for I := 30 downto 9 do begin + S := SpIDEBDSCommonDir(I) + '\Styles'; // C:\Users\Public\Documents\Embarcadero\Studio\21.0\Styles if DirectoryExists(S) then begin Result := S; Exit; @@ -230,23 +205,6 @@ function SpGetDelphiStylesFolder: string; end; end; -function SpGetWinAmpDir: String; -var - Registry: TRegistry; -begin - Registry := TRegistry.Create; - try - Registry.RootKey := HKEY_CURRENT_USER; - // False because we do not want to create it if it doesn't exist - Registry.OpenKey('\Software\Winamp', False); - Result := Registry.ReadString(''); - if Length(Result) > 0 then - Result := IncludeTrailingPathDelimiter(Result); - finally - Registry.Free; - end; -end; - //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Form } @@ -254,17 +212,32 @@ procedure TForm1.FormCreate(Sender: TObject); begin FLastSkin := 'Aluminum'; SkinManager.AddSkinNotification(Self); + + {$IF CompilerVersion >= 33} // for Delphi Rio and up + // TImageCollection and TVirtualImagelist introduced on Rio + IC := TImageCollection.Create(Self); + IL := TVirtualImageList.Create(Self); + TVirtualImageList(IL).ImageCollection := IC; + {$ELSE} + IL := TImageList.Create(Self); + {$IFEND} end; procedure TForm1.FormDestroy(Sender: TObject); begin SkinManager.RemoveSkinNotification(Self); + + {$IF CompilerVersion >= 33} // for Delphi Rio and up + // TImageCollection and TVirtualImagelist introduced on Rio + IC.Free; + {$IFEND} + IL.Free; end; procedure TForm1.FormShow(Sender: TObject); var A: TSpTBXItem; - D: String; + S: string; I: Integer; begin // Add the Languages to the Languages menu item and TabControl @@ -293,18 +266,23 @@ procedure TForm1.FormShow(Sender: TObject); // Load default button Skin AppPath := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)); + // Load PNGs + // Use ImageCollection/TVirtualImagelist on Rio and up + SpLoadGlyphs(IL, AppPath + 'Glyphs'); + + SpTBXTabControl1.Images := IL; + SpTBXToolbar3.Images := IL; + SpTBXStatusBar1.Images := IL; + DP2.Images := IL; + DP3.Images := IL; + // Initialize the link labels - D := SpGetWindowsDir; - if Length(D) > 0 then begin - SpTBXLabel4.LinkText := D; + S := TPath.GetDocumentsPath; + if Length(S) > 0 then begin + SpTBXLabel4.LinkText := S; SpTBXLabel5.LinkText := 'explorer.exe'; - SpTBXLabel5.LinkTextParams := '/e, ' + D; + SpTBXLabel5.LinkTextParams := '/e, ' + S; end; - D := SpGetWinAmpDir; - if Length(D) > 0 then - SpTBXLabel6.LinkText := D + 'winamp.exe'; - if FileExists(AppPath + 'unit1.pas') then - SpTBXLabel7.LinkTextParams := '"' + AppPath + 'unit1.pas' + '"'; // Init Skin Type radiobuttonSkin2.Enabled := CompilerVersion >= 23; // Delphi XE2 or up @@ -372,9 +350,6 @@ procedure TForm1.rgSkinTypeClick(Sender: TObject); FLastSkin := SkinManager.CurrentSkinName; SkinManager.SetSkin('Default'); end; - {$IF CompilerVersion >= 23} //for Delphi XE2 and up - TStyleManager.SetStyle(TStyleManager.SystemStyle); - {$IFEND} end; sknSkin: SkinManager.SetSkin(FLastSkin); @@ -387,6 +362,8 @@ procedure TForm1.rgSkinTypeClick(Sender: TObject); SkinManager.SetToDefaultSkin; {$IF CompilerVersion >= 23} //for Delphi XE2 and up TStyleManager.SetStyle(TStyleManager.LoadFromFile(OpenDialog1.FileName)); + // Recreate the SkinGroupItem and add the selected style + SpTBXSkinGroupItem1.Recreate; {$IFEND} end; end; @@ -410,7 +387,7 @@ procedure TForm1.skinButtonClick(Sender: TObject); // Set the new skin FLastSkin := S; SkinManager.SetSkin(FLastSkin); - // Recreate the SkinGroupItem + // Recreate the SkinGroupItem and add the selected skin SpTBXSkinGroupItem1.Recreate; radiobuttonSkin3.Checked := True; end; @@ -432,7 +409,7 @@ procedure TForm1.SpTBXSpeedButton1Draw(Sender: TObject; ACanvas: TCanvas; if PaintStage = pstPrePaint then begin PaintDefault := False; SB := TSpTBXSpeedButton(Sender); - SpDrawXPHeader(ACanvas, ARect, SB.MouseInControl, SB.Pushed); + SpDrawXPHeader(ACanvas, ARect, SB.MouseInControl, SB.Pushed, CurrentPPI); end; end; @@ -442,33 +419,33 @@ procedure TForm1.SpTBXSpeedButton1Draw(Sender: TObject; ACanvas: TCanvas; procedure TForm1.hintLabelDrawHint(Sender: TObject; AHintBitmap: TBitmap; var AHint: string; var PaintDefault: Boolean); var - R, GR, TR: TRect; - WS: WideString; + R, CaptionR, GlyphR: TRect; + S: string; + GSize: TSize; + Margin: Integer; begin PaintDefault := False; - AHintBitmap.Width := Image1.Picture.Bitmap.Width + 115; - AHintBitmap.Height := Image1.Picture.Bitmap.Height + 30; - with AHintBitmap.Canvas do begin - Brush.Color := clInfoBk; - Font.Color := clInfoText; - R := Rect(0, 0, AHintBitmap.Width, AHintBitmap.Height); - FillRect(R); - - GR := Bounds(5, 5, Image1.Picture.Bitmap.Width, Image1.Picture.Bitmap.Height); - Draw(GR.Left, GR.Top, Image1.Picture.Bitmap); - - WS := 'Language: ' + subLang.Caption + #13#10 + - 'Skin: ' + SkinManager.CurrentSkinName + #13#10 + - 'Time: ' + TimeToStr(Now); - TR := Rect(GR.Right + 5, 10, R.Right, R.Bottom); - SpDrawXPText(AHintBitmap.Canvas, WS, TR, DT_WORDBREAK); - - Font.Color := clBlue; - Font.Style := [fsUnderline]; - TR := Rect(GR.Left, GR.Bottom + 5, R.Right, R.Bottom); - WS := 'http://www.silverpointdevelopment.com'; - SpDrawXPText(AHintBitmap.Canvas, WS, TR, DT_WORDBREAK); - end; + + Margin := SpPPIScale(5, CurrentPPI); + AHintBitmap.Canvas.Brush.Color := clInfoBk; + AHintBitmap.Canvas.Font.Color := clInfoText; + S := 'Selected Language: ' + subLang.Caption + #13#10 + + 'Selected Skin: ' + SkinManager.CurrentSkinName + #13#10 + + 'http://www.silverpointdevelopment.com'; + GSize := SpGetTextSize(AHintBitmap.Canvas.Handle, 'http://www.silverpointdevelopment.com', True); + + AHintBitmap.Width := Image1.Picture.Bitmap.Width + GSize.cx + Margin * 4; + AHintBitmap.Height := Image1.Picture.Bitmap.Height + Margin * 2; + R := Rect(0, 0, AHintBitmap.Width, AHintBitmap.Height); + AHintBitmap.Canvas.FillRect(R); + + R := Rect(Margin, Margin, AHintBitmap.Width - Margin, AHintBitmap.Height - Margin); + GSize.cx := Image1.Picture.Bitmap.Width; + GSize.cy := Image1.Picture.Bitmap.Height; + SpCalcXPText(AHintBitmap.Canvas, R, S, taLeftJustify, DT_WORDBREAK, GSize, + ghlGlyphLeft, False, CurrentPPI, CaptionR, GlyphR); + SpDrawXPText(AHintBitmap.Canvas, S, CaptionR, DT_WORDBREAK); + AHintBitmap.Canvas.Draw(GlyphR.Left, GlyphR.Top, Image1.Picture.Bitmap); end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -505,15 +482,15 @@ procedure TForm1.SpTBXProgressBar1ProgressChange(Sender: TObject; NewPosition: Integer); var I: Integer; - WS: WideString; + S: string; begin if progressFiles.Checked then begin I := (NewPosition div 10) - 1; if I < 0 then I := 0; if I > LangListBox.Items.Count - 1 then I := LangListBox.Items.Count - 1; - WS := 'C:\Lang\' + LangListBox.Items[I] + '.txt'; - SpTBXProgressBar1.Caption := WS; - SpTBXProgressBar2.Caption := WS; + S := 'C:\Lang\' + LangListBox.Items[I] + '.txt'; + SpTBXProgressBar1.Caption := S; + SpTBXProgressBar2.Caption := S; end; end; diff --git a/Packages/RAD Studio/SpTBXLib.dpk b/Packages/RAD Studio/SpTBXLib.dpk index 409ea17..1c896c8 100644 --- a/Packages/RAD Studio/SpTBXLib.dpk +++ b/Packages/RAD Studio/SpTBXLib.dpk @@ -1,10 +1,11 @@ package SpTBXLib; {$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} {$ALIGN 8} {$ASSERTIONS ON} {$BOOLEVAL OFF} -{$DEBUGINFO ON} +{$DEBUGINFO OFF} {$EXTENDEDSYNTAX ON} {$IMPORTEDDATA ON} {$IOCHECKS ON} @@ -14,7 +15,7 @@ package SpTBXLib; {$OPTIMIZATION ON} {$OVERFLOWCHECKS OFF} {$RANGECHECKS OFF} -{$REFERENCEINFO ON} +{$DEFINITIONINFO ON} {$SAFEDIVIDE OFF} {$STACKFRAMES OFF} {$TYPEDADDRESS OFF} @@ -22,15 +23,18 @@ package SpTBXLib; {$WRITEABLECONST OFF} {$MINENUMSIZE 1} {$IMAGEBASE $4FC00000} +{$DEFINE DEBUG} +{$ENDIF IMPLICITBUILDING} {$DESCRIPTION 'Toolbar2000 -- SpTBXLib'} {$RUNONLY} {$IMPLICITBUILD ON} requires vcl, - tb2k_d12, + tb2k_d16, rtl, - vclx; + vclx, + vclimg; contains SpTBXItem in '..\..\Source\SpTBXItem.pas', @@ -48,4 +52,4 @@ contains SpTBXSkins in '..\..\Source\SpTBXSkins.pas', SpTBXDefaultSkins in '..\..\Source\SpTBXDefaultSkins.pas'; -end. \ No newline at end of file +end. diff --git a/Packages/RAD Studio/SpTBXLib.dproj b/Packages/RAD Studio/SpTBXLib.dproj index ed3c194..dcd2e78 100644 --- a/Packages/RAD Studio/SpTBXLib.dproj +++ b/Packages/RAD Studio/SpTBXLib.dproj @@ -1,15 +1,15 @@  - {1EB74E79-E290-4976-B63E-8E6B50611D5F} - SpTBXLib.dpk + True + Package Debug DCC32 - 18.4 VCL - True + SpTBXLib.dpk Win32 + {1EB74E79-E290-4976-B63E-8E6B50611D5F} + 18.4 3 - Package true @@ -35,45 +35,35 @@ true - true - All + SpTBXLib $(BDSCOMMONDIR)\DCP + All SpTBXLib.bpl + Toolbar2000 -- SpTBXLib 4FC00000 - 1 + true + Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;System.Win;$(DCC_Namespace) x86 - Toolbar2000 -- SpTBXLib - true - false + 1 true - false true - false - false - SpTBXLib - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;System.Win;$(DCC_Namespace) - 1033 + true CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true + 1033 - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - 1033 + Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - false + 0 RELEASE;$(DCC_Define) + false 0 - 0 DEBUG;$(DCC_Define) @@ -83,7 +73,7 @@ MainSource - + @@ -100,10 +90,6 @@ - - Cfg_2 - Base - Base @@ -111,6 +97,10 @@ Cfg_1 Base + + Cfg_2 + Base + @@ -121,11 +111,6 @@ SpTBXLib.dpk - - False - True - False - False False @@ -153,11 +138,13 @@ 1.0.0.0 + + False + True + False + - False - False - False True True @@ -166,3 +153,10 @@ + diff --git a/Packages/RAD Studio/SpTBXLibDsgn.dproj b/Packages/RAD Studio/SpTBXLibDsgn.dproj index 65c5906..b0b97a1 100644 --- a/Packages/RAD Studio/SpTBXLibDsgn.dproj +++ b/Packages/RAD Studio/SpTBXLibDsgn.dproj @@ -1,116 +1,145 @@ - - - {0CD140C3-3ADC-4BF2-8A9C-6B5FAA587036} - SpTBXLibDsgn.dpk - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - true - All - 4F800000 - 1 - WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias) - x86 - Toolbar2000 -- SpTBXLib Design Package - true - false - true - false - true - false - false - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - - - - - - - - - - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - - - - - Delphi.Personality.12 - Package - - - - SpTBXLibDsgn.dpk - - - False - True - False - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - - + + + True + Package + Debug + DCC32 + VCL + SpTBXLibDsgn.dpk + Win32 + {0CD140C3-3ADC-4BF2-8A9C-6B5FAA587036} + 15.4 + 1 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + SpTBXLibDsgn + All + Toolbar2000 -- SpTBXLib Design Package + 4F800000 + Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) + x86 + 1 + true + true + true + true + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + 1033 + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + vcl;tb2k_d16;SpTBXLib;$(DCC_UsePackage) + true + 1033 + + + 0 + RELEASE;$(DCC_Define) + false + 0 + + + DEBUG;$(DCC_Define) + + + + MainSource + + + + + + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + + Delphi.Personality.12 + Package + + + + SpTBXLibDsgn.dpk + + + True + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1033 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + False + True + False + + + + False + True + False + False + False + + + 12 + + + + diff --git a/Source/SpTBXColorPickerForm.dfm b/Source/SpTBXColorPickerForm.dfm index fdef349..914022f 100644 --- a/Source/SpTBXColorPickerForm.dfm +++ b/Source/SpTBXColorPickerForm.dfm @@ -2742,14 +2742,14 @@ object SpTBXColorPickerForm: TSpTBXColorPickerForm Enabled = False Interval = 25 OnTimer = Timer1Timer - Left = 112 - Top = 152 + Left = 40 + Top = 136 end object ImageList1: TImageList - Left = 72 - Top = 152 + Left = 40 + Top = 72 Bitmap = { - 494C010105000A00540010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C010105000800040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000002000000001002000000000000020 00000000000000000000000000000000000000000000A1A1A100000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -3022,7 +3022,1687 @@ object SpTBXColorPickerForm: TSpTBXColorPickerForm end object ColorDialog1: TColorDialog Options = [cdFullOpen] - Left = 144 - Top = 152 + Left = 104 + Top = 136 + end + object ImageList2: TImageList + ColorDepth = cd32Bit + DrawingStyle = dsTransparent + Height = 24 + Width = 24 + Left = 104 + Top = 68 + Bitmap = { + 494C010105000800040018001800FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000600000003000000001002000000000000048 + 00000000000000000000000000000000000000000000545454828F8F8FEE1414 + 1416000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000005D5D5D948E8E8DCEC5C3C1F75E5E + 5E94555556844D4D4D7300000001000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000909191EEC3C0BDF5F3EFEBFFC0BF + BDFFBDBBBAFF9F9F9DF23030303C0D0D0D0E0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001A1A1A1E59595989BFBEBDFEE8E1 + DAFFF5EADFFFDFD4CAFD9E9C9BE64A4A4B6E0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000004F4F5079C5C4C4FFF9F3 + EDFFFDF6EBFEF5E8DBFFE4DCD4FF8D8A88CB4D4E4E7300000001000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000004949496A9E9E9EE2E6E3 + E1FDFAF3EDFFF5EAE0FEF8E9DCFEE6DED6FFA5A4A4F23030303C0D0D0D0E0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000C0C0C0D2C2C2C36A4A3 + A3EEECE8E7FFFDF6F1FEF4EAE0FEF4E8DCFFE1D7CDFDA5A3A3E64B4B4C6E0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000004949 + 4969888686C1EFECEAFFFAF3EDFFFAEEE5FEF5E9DCFFE9E1D8FF908D8DCB4F4F + 4F73000000010000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000045464662A4A4A3E2E9E6E4FDFBF4EEFFF4E9DFFEF6E9DBFEECE4DCFFAEAC + ACF23030303C1B1B1B1F1B1B1B1F1B1B1B1F0D0D0D0E00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000B0B0B0C2C2C2C36ABABACEEF1EFECFFFCF5F0FEF3E9DFFEF7EDE2FFE4D8 + CFFD9C8C85E6845F53E27F4634E2854C35E24A43416E00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000049494A698B8B8AC1F4F2F0FFFDF8F3FFF4E8DFFEDEC3 + B6FFAF7B6AFFAA6548FFB7683FFFBE6A3EFF805644CB4D4543750F0F0F100000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000046464662ABABAAE2E8E3DFFAE2CBC2FEBD8E + 7DFEA05A40FEB06A43FEC98859FEC9824DFEBF6B3FFF894833EE1919191D0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000B0B0B0C2B2A2A349E8F8AE2B58575FEA15D + 40FEC48A68FECF986FFECD9262FEC7854CFEBD6E3FFF85513BE2101010120000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000C0C0C0D876356DCB67C62FEBD84 + 66FED5A57EFED7A479FECF9463FEC8864DFEC17942FEA3633DF05F5048932F2E + 2E3C000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001918181C87503AE1CA8C67FFE0BA + 99FEDDB590FED8A97FFED29869FECB8852FEC98246FEC87A40FFC06C3FFF6251 + 489B1818181B0000000100000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000001919191D955B40EBD4956DFFE2BB + 99FEE5C2A6FEE2BC9DFEDBAA82FED08F5CFECC854BFECB8247FECC8145FFB16D + 45F27A5748C70E0E0E0F00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000C0C0C0D4A45426B826655C1D89A + 73FFDDA98CFFE3B89BFFE0B998FED9A279FED3925DFED0884CFED0884CFED287 + 4DFFB97346FE63544B95302F2E3C000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000045413F629461 + 4BDE976D5ADEB9917BEFE3BB9EFFE3B594FFDBA376FED5915AFED28D53FED28C + 51FED28B4FFFCF824FFF64554C9B1B1B1B1F0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000B0B0B0C1919 + 181C1919191C6057528FDEA585FFE4B99AFFE1B590FEDBA67AFED5935EFED38E + 55FED38E55FED68F55FFB17853F2956651E20000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000292928325F56518ACF9F82FCEDBE9BFFE2B891FEDCA678FED89A + 65FED7935BFED8965BFED38E5CFFCB845DFF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000909090A836C5EC0CAA187EFEAC3A1FFE6BB94FFDFAB + 7DFEDB9E6AFEDD9D63FFB4815AF0956B54DE0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000015151518635C578FEEC1A0FFEBC4A4FFE6BF + 9AFEE5B68BFFE2A273FF665951981919181C0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000002929293261595588BC9479EDDEA9 + 83FEBC9170EF6057508A2D2C2C37000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000D0D0D0E986F57DCD58F + 66FE9B7157DF0F0F0F1100000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000534C4D72E88393FED25170FEC7315FFEC223 + 5EFEC1246DFEC43682FECF5AA4FEE890D0FE5952577C00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00002C2B2B36605050845D4142848A454BBEE25C73FEDE5574FEDB517BFEDB4F + 83FED94F8FFED64F9BFED553A9FED95BBBFE884880C35A4459845F545F843030 + 303C000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000001818 + 181B6A555491FE7572FFE9292CFFE32937FFE34B65FEED617EFEF26E93FEF473 + A4FEF372B0FEED68B7FEE358B8FED540B5FED127BFFFD62FD0FFEC86F2FF6C5C + 709B1818181B0000000100000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000202 + 02FF020202FF020202FF020202FF020202FF020202FF020202FF020202FF0202 + 02FF020202FF020202FF020202FF020202FF020202FF020202FF020202FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF00000000000000000000000000000000000000000B0B0B0C965E + 51C4DD604AF1EC5345FFF3706DFFF8878CFFF98B98FEFA768FFEFB6890FEFB5F + 9BFEFB5FAEFEFA68C2FEF878D5FEF587E2FEF07AE8FFDF5CE2FFC038D0FFB254 + C9F2856192C70E0E0E0F00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000202 + 02FF020202FF020202FF020202FF020202FF020202FF020202FF020202FF0202 + 02FF020202FF020202FF020202FF020202FF020202FF020202FF020202FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFF000000FF000000000000000000000000000000003331313F6E5C5393E86F + 44FCFD7755FFF07B6CFEF9837CFEFD7E7EFEFD707BFEFD667FFEFD5E89FEFD59 + 9AFEFD58B0FEFD5EC6FEFD67DCFEFD6DEFFEF878F7FEE778F2FEC75BDCFEBD50 + E1FFA651D1FE655B6C9535353644000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000001414 + 14FF141414FF141414FF202020FF141414FF141414FF141414FF202020FF2020 + 20FF141414FF141414FF141414FF141414FF141414FF141414FF141414FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFF000000FF000000000000000000000000000000005D524B7FFFA665FFF683 + 49FFF3906CFEFBA38EFEFC7F6FFEFC605AFEFC4D56FEFC5770FEFC5D87FEFC60 + 9FFEFC5DB5FEFC5ACAFEFC54DDFEFC47F2FEF55BFBFEE879FDFEDA89F5FEB25C + DEFE993BD4FFBF84F8FF5B54628A00000000000000000000000000000000B078 + 56FFB07856FFB07856FFB07856FF0000000000000000DD9BD9FFDD9BD9FFDD9B + D9FFDD9BD9FF0000000000000000B175FFFFB175FFFFB175FFFFB175FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 31FF003131FF003131FF003131FF003131FF003131FF313100FF313100FF3131 + 00FF313100FF310000FF310000FF310031FF310031FF310031FF310031FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FF000000FF0000000000000000000000000000000055493F73FF8B21FFF9AA + 76FEF9A77FFEFC906BFEFC795BFEFC6B5BFEFC6868FEFC6D7EFEFC7294FEFC75 + ACFEFC74C1FEFC6FD7FEFB68EAFEF75EF9FEE854FCFED757FCFED27AFBFEC17A + F1FEA45EE3FE7C2EE2FF4B41587E00000000000000000000000000000000B078 + 56FFB07856FFB07856FFB07856FF0000000000000000DD9BD9FFDD9BD9FFDD9B + D9FFDD9BD9FF0000000000000000B175FFFFB175FFFFB175FFFFB175FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 31FF003131FF003131FF003131FF003131FF003131FF313100FF313100FF3131 + 00FF313100FF310000FF310000FF310031FF310031FF310031FF310031FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FF000000FF000000000000000000000000635A4D84977547BEFBA03BFEFBC3 + 90FEFCB382FEFC9459FEFC8A5FFEFC856AFEFC8279FEFC828AFEFC87A0FEFC8B + B9FEFC8BCEFEFC86E3FEFA7EF4FEEF71FBFEDE60FCFEC956FCFEBA5DFDFEBD7A + FAFEB07EF0FE702DDBFE60488DC356535F84000000000000000000000000B078 + 56FFB07856FFB07856FFB07856FF0000000000000000DD9BD9FFDD9BD9FFDD9B + D9FFDD9BD9FF0000000000000000B175FFFFB175FFFFB175FFFFB175FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 64FF003164FF003164FF006464FF006431FF006431FF316400FF646400FF6464 + 00FF643100FF640000FF640000FF640031FF640064FF640064FF310064FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFF000000FF000000000000000000000000FFD35EFFFFCB5EFFFAC36CFEFBCF + 91FEFCBB7AFEFCA459FEFCA66EFEFCA27CFEFC9D89FEFC9997FEFC9DABFEFCA1 + C4FEFCA2DAFEFC9DEDFEF791FAFEE681FBFED373FCFEBD62FCFEA34BFCFEAE70 + FDFEB08AF8FE794BDFFE855DE5FFA489F2FF000000000000000000000000B078 + 56FFB07856FFB07856FFB07856FF0000000000000000DD9BD9FFDD9BD9FFDD9B + D9FFDD9BD9FF0000000000000000B175FFFFB175FFFFB175FFFFB175FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000031 + 99FF006499FF006499FF009999FF009964FF009964FF649900FF999900FF9999 + 00FF993100FF990000FF990000FF990064FF990099FF990099FF310099FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFF000000FF000000000000000000000000F9C833FFFBD157FFFBD57DFEFBCF + 72FEFCC569FEFCBE68FEFCBE7BFEFCBC8BFEFCBA9AFEFCB4A7FEFCB5BAFEFCB7 + CFFEFCB7E6FEF9B2F5FEEFA5FCFEDB93FCFEC682FCFEB070FCFE985AFCFE9869 + FCFE9978FAFE8263EAFE7455E3FF6C50DFFF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000031 + 99FF006499FF006499FF009999FF009964FF009964FF649900FF999900FF9999 + 00FF993100FF990000FF990000FF990064FF990099FF990099FF310099FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FF000000FF000000000000000000000000F0CD1BFEF6DB54FEFCE689FEFCDB + 67FEFCD764FEFCD573FEFCD585FEFCD498FEFCD3A9FEFCD0B8FEFCCFCAFEFCD0 + DDFEFCCEF1FEF3C4FAFEE3B5FCFECEA1FCFEB98DFCFEA278FCFE8A63FCFE8262 + FCFE826BFBFE8673F1FE6955E3FE4832D7FE0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000031 + CCFF0064CCFF0064CCFF00CCCCFF00CC64FF00CC64FF64CC00FFCCCC00FFCCCC + 00FFCC6400FFCC0000FFCC0000FFCC0064FFCC00CCFFCC00CCFF6400CCFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FF000000FF000000000000000000000000EDDA10FEF5E753FEFCF18FFEFCEB + 66FEFCEA64FEFCE979FEFCE98BFEFCE8A0FEFCE8B3FEFCE9C4FEFCE8D7FEFBE6 + E8FEF9E2F8FEEBD4FDFED6C1FCFEC1AAFCFEAB94FCFE947EFCFE7D69FCFE705F + FCFE7365FBFE877CF6FE6155E6FE3125D6FE000000000000000000000000B2EB + D0FFB2EBD0FFB2EBD0FFB2EBD0FF00000000000000006BCC4EFF6BCC4EFF6BCC + 4EFF6BCC4EFF0000000000000000EBB05EFFEBB05EFFEBB05EFFEBB05EFF0000 + 0000000000000000000000000000000000000000000000000000000000000031 + FFFF0064FFFF0064FFFF00FFFFFF00FF64FF00FF64FF99FF00FFFFFF00FFFFFF + 00FFFF6400FFFF0000FFFF0000FFFF0099FFCC00FFFFCC00FFFF6400FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFF000000FF000000000000000000000000E9E70DFEF0EF53FEF8F891FEF9F7 + 66FEF9F867FEF8F87DFEF8F88FFEF8F7A2FEF9F8B6FEF9F8CAFEF9F9DEFEF8F8 + EFFEF2F1FBFEE1E0FCFECACAFCFEB3B2FCFE9E9DFCFE8786FCFE706FFCFE6463 + FCFE6968FBFE8280FAFE5959E8FE2525D8FE000000000000000000000000B2EB + D0FFB2EBD0FFB2EBD0FFB2EBD0FF00000000000000006BCC4EFF6BCC4EFF6BCC + 4EFF6BCC4EFF0000000000000000EBB05EFFEBB05EFFEBB05EFFEBB05EFF0000 + 0000000000000000000000000000000000000000000000000000000000000031 + FFFF0064FFFF0064FFFF00FFFFFF00FF64FF00FF64FF99FF00FFFFFF00FFFFFF + 00FFFF6400FFFF0000FFFF0000FFFF0099FFCC00FFFFCC00FFFF6400FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFF000000FF000000000000000000000000DBEA19FEE3F054FEEDF78AFEECFB + 69FEEBFC6AFEEAFD7DFEEAFD8FFEEAFCA1FEEAFDB4FEE9FDC6FEE9FDD8FEE8FD + E9FEE4F9F7FED6EBFCFEC2D7FCFEADC1FCFE97ABFCFE8194FCFE6B7EFCFE6576 + FCFE6C79FBFE7B84FAFE5963EBFE303CDDFE000000000000000000000000B2EB + D0FFB2EBD0FFB2EBD0FFB2EBD0FF00000000000000006BCC4EFF6BCC4EFF6BCC + 4EFF6BCC4EFF0000000000000000EBB05EFFEBB05EFFEBB05EFFEBB05EFF0000 + 0000000000000000000000000000000000000000000000000000000000000031 + FFFF3199FFFF3199FFFF31FFFFFF31FF99FF31FF99FF99FF31FFFFFF31FFFFFF + 31FFFF9931FFFF3131FFFF3131FFFF3199FFFF31FFFFFF31FFFF6431FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FF000000FF000000000000000000000000D2EE30FFD8F056FFDEF27EFEE0FA + 75FEDCFC72FED7FC79FED7FC8CFED7FC9DFED6FCADFED3FCBCFED3FCCCFED3FC + DEFED2FDF1FECAF4FAFEBBE4FCFEA7D0FCFE92BBFCFE7EA5FCFE678FFCFE6F8E + FCFE7C91FBFE7186F9FE5C72F1FF4B60E8FF000000000000000000000000B2EB + D0FFB2EBD0FFB2EBD0FFB2EBD0FF00000000000000006BCC4EFF6BCC4EFF6BCC + 4EFF6BCC4EFF0000000000000000EBB05EFFEBB05EFFEBB05EFFEBB05EFF0000 + 0000000000000000000000000000000000000000000000000000000000003164 + FFFF6499FFFF6499FFFF64FFFFFF64FF99FF64FF99FFCCFF64FFFFFF64FFFFFF + 64FFFF9964FFFF6464FFFF6464FFFF64CCFFFF64FFFFFF64FFFF9964FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FF000000FF000000000000000000000000D6FA53FFCFF25CFFCAEB71FEDAFA + 90FED3FC82FEC4FC6FFEC5FC85FEC2FC96FEBFFCA3FEBBFCAFFEBCFCBFFEBFFC + D3FEBFFCE8FEB9F9F7FEAEF0FCFE9DDCFCFE8CCAFCFE78B6FCFE609EFCFE7CA9 + FCFE94AFFBFE6386F6FE6487F8FF7693F9FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000003164 + FFFF6499FFFF6499FFFF64FFFFFF64FF99FF64FF99FFCCFF64FFFFFF64FFFFFF + 64FFFF9964FFFF6464FFFF6464FFFF64CCFFFF64FFFFFF64FFFF9964FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFF000000FF000000000000000000000000494C447A657146B9B6EA55FED1F7 + 95FEC7FB86FEB1FC67FEB0FC7BFEADFC8AFEA9FC97FEA6FCA3FEA9FCB5FEADFC + CAFEADFCDFFEA7FCEFFE9EF7FAFE90E8FCFE7FD6FCFE6FC3FCFE67B3FCFE86BD + FCFE91BAFAFE3D7FF9FE42547BBE46474C7A0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000807A + FFFF99CCFFFF99CCFFFF99FFFFFF99FFCCFF99FFCCFFCCFF99FFFFFF99FFFFFF + 99FFFFCC99FFFF9999FFFF9999FFFF99CCFFFF99FFFFFF99FFFF9999FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFF000000FF0000000000000000000000000000000045484173ACF144FFC1F2 + 86FFBAF683FEA9FC6FFE9EFC72FE96FC7CFE92FC88FE92FC98FE98FCADFE9DFC + C3FE9BFCD5FE95FCE7FE8CFBF5FE80F1FBFE73E1FCFE6CD0FCFE79C9FCFE88C8 + FAFE7DBAFBFE318DFFFF40464E7E00000000000000000000000000000000696D + FEFF696DFEFF696DFEFF696DFEFF000000000000000071AAFFFF71AAFFFF71AA + FFFF71AAFFFF000000000000000065D5F0FF65D5F0FF65D5F0FF65D5F0FF0000 + 0000000000000000000000000000000000000000000000000000000000009999 + FFFF99CCFFFF99CCFFFF99FFFFFF99FFCCFF99FFCCFFCCFF99FFFFFF99FFFFFF + 99FFFFCCCCFFFFCCCCFFFFCCCCFFFF99CCFFFF99FFFFFF99FFFFCC99FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FF000000FF00000000000000000000000000000000494D447FB0FC58FF9DE6 + 58FFAAEB7DFEB6F996FE8FFC71FE7EFC69FE78FC77FE80FC8EFE87FCA5FE8AFC + B9FE89FCCBFE84FCDDFE7BFBEEFE6CF8FAFE69EDFCFE76E0FBFE96DDFAFE7BC8 + F8FE57B9FEFF70C5FFFF484E548900000000000000000000000000000000696D + FEFF696DFEFF696DFEFF696DFEFF000000000000000071AAFFFF71AAFFFF71AA + FFFF71AAFFFF000000000000000065D5F0FF65D5F0FF65D5F0FF65D5F0FF0000 + 0000000000000000000000000000000000000000000000000000000000009999 + FFFF99CCFFFF99CCFFFF99FFFFFF99FFCCFF99FFCCFFCCFF99FFFFFF99FFFFFF + 99FFFFCCCCFFFFCCCCFFFFCCCCFFFF99CCFFFF99FFFFFF99FFFFCC99FFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FF000000FF000000000000000000000000000000002E2F2D3A58654D8A7AD8 + 3FFC8FF25FFF96EA7EFE98F785FE93FC89FE87FD8EFE7CFD94FE77FD9FFE76FC + B0FE75FCC2FE75FCD5FE7BFCE8FE87FCF8FE8DF6FCFE8AEAFAFE7ADCF5FE63DA + FFFF4EBFF9FE5360698C3132333F00000000000000000000000000000000696D + FEFF696DFEFF696DFEFF696DFEFF000000000000000071AAFFFF71AAFFFF71AA + FFFF71AAFFFF000000000000000065D5F0FF65D5F0FF65D5F0FF65D5F0FF0000 + 000000000000000000000000000000000000000000000000000000000000CCCC + FFFFCCCCFFFFCCCCFFFFCCFFFFFFCCFFCCFFCCFFCCFFCCFFCCFFFFFFCCFFFFFF + CCFFFFCCCCFFFFCCCCFFFFCCCCFFFFCCCCFFFFCCFFFFFFCCFFFFCCCCFFFF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF00000000000000000000000000000000000000000909090A5A8D + 45C06ACE46EF71E55AFF90F087FF9BF79CFF94F9A1FE7EFB9DFE75FBA3FE72FC + B1FE72FCC1FE75FCD2FE7FFBE2FE9AFAF1FE9BFAF9FF83F2FAFF59E1F8FF52C6 + E1F051899EC30C0C0C0D0000000000000000000000000000000000000000696D + FEFF696DFEFF696DFEFF696DFEFF000000000000000071AAFFFF71AAFFFF71AA + FFFF71AAFFFF000000000000000065D5F0FF65D5F0FF65D5F0FF65D5F0FF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000001515 + 151850664D8F6AF559FF48E747FF55E55EFF74E786FE84F1A3FE8FF6B7FE96F9 + C6FE96FBCFFE90F8D7FE84F4DBFE75EEDFFE47F2EAFF2EF5F8FF69FDFFFF546D + 7198151515180000000100000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000282928324A59487A4456457A4E8653B95FE57AFE5EE285FE5BE391FE5AE3 + 9FFE5BE5ABFE5DE6B8FE5FE8C6FE65EED9FE4B908BBE4158587A4A5A5B7A2C2D + 2D37000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000004752497156E776FE37D86AFE22D36BFE17D0 + 77FE1AD286FE25D59AFE3BDEB4FE63F2D8FE4C5A577C00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000060000000300000000100010000000000400200000000000000000000 + 000000000000000000000000FFFFFF008FFFFF00000000000000000001FFFF00 + 000000000000000000FFFF00000000000000000000FFFF000000000000000000 + 803FFF000000000000000000801FFF000000000000000000801FFF0000000000 + 00000000E007FF000000000000000000F0007F000000000000000000F0007F00 + 0000000000000000FC001F000000000000000000FE001F000000000000000000 + FE001F000000000000000000FF000F000000000000000000FF00030000000000 + 00000000FF0003000000000000000000FF0001000000000000000000FFC00000 + 0000000000000000FFC000000000000000000000FFF800000000000000000000 + FFFC00000000000000000000FFFE00000000000000000000FFFF010000000000 + 00000000FFFF83000000000000000000FFFFFFFFFFFFFE007FFFFFFFFFFFFFFF + FFFFF0000FFFFFFFFFFFFFFFFFFFE00003FFFFFFE0001FE00007C00003FFFFFF + E0001FE00007800001FFFFFFE0001FE00007800001E1861FE0001FE000078000 + 01E1861FE0001FE00007000000E1861FE0001FE00007000000E1861FE0001FE0 + 0007000000FFFFFFE0001FE00007000000FFFFFFE0001FE00007000000E1861F + E0001FE00007000000E1861FE0001FE00007000000E1861FE0001FE000070000 + 00E1861FE0001FE00007000000FFFFFFE0001FE00007000000FFFFFFE0001FE0 + 0007800001E1861FE0001FE00007800001E1861FE0001FE00007800001E1861F + E0001FE00007C00003E1861FFFFFFFFFFFFFE00003FFFFFFFFFFFFFFFFFFF000 + 0FFFFFFFFFFFFFFFFFFFFE007FFFFFFF00000000000000000000000000000000 + 000000000000} + end + object ImageList3: TImageList + ColorDepth = cd32Bit + DrawingStyle = dsTransparent + Height = 32 + Width = 32 + Left = 168 + Top = 68 + Bitmap = { + 494C010105000800040020002000FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000800000004000000001002000000000000080 + 000000000000000000000000000000000000000000002323232A7F7F7FDA7F7F + 80DA2323232A0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000002525252D484848659A9997E49595 + 95E345454560292A2A332A2A2A33212121270404040500000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000696969B0A2A2A2E4E0DCD9FBD7D3 + CFF78B8B8BD6767678CB7E7E7ECB6060619E1717171A00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000696969B0A2A0A0E3DBD8D5F6EDE9 + E5FFCCC9C7FFBFBDBBFFC9C6C3FF969594E34444445F21212127040404050000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000002525252D454545608E8E8ED6CFCC + C9FFE2DCD6FFEDE4DAFFEEE3D8FFCEC6BEF8929191D66060629E1717171A0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000020202025787879CBC6C4 + C3FFF0E9E3FFFDF6EBFEFCEFE1FEF0E5D9FFD9D4CFFF959595E34444445F2121 + 2127040404050000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000028282831838383D7D3D2 + D1FFF6F1EDFFFDF9F2FEF8EDE3FEF3E8DCFFF0E4D9FFD1C7BFF8959492D66262 + 629E1717171A0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000022222228656565A19898 + 98D6D9D6D4F8F9F3EFFFF8F0E9FFF6ECE2FEF9EBDEFEF2E6DBFFDDD8D2FF9A98 + 96E34545455F2121212704040405000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000909090A222222284545 + 455F9C9C9CE3E4E2E0FFF8F3EFFFFDF5EFFEF7ECE2FEF3E8DCFFF1E5D9FFD2C9 + C1F8979695D66363649E1717171A000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000001717 + 171A6262639E999998D6D9D8D6F8FAF5F1FFF8F1E9FFF6EBE1FEF7EADDFEF2E6 + DBFFE1DBD6FF9C9C9BE34545455F212121270404040500000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000404 + 0405212121274545455FA1A1A1E3E8E6E5FFF9F4F0FFFDF5EEFEF5EBE1FEF4E8 + DCFFF1E6DAFFD4CBC3F89A9999D66565679E1717171A00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000001717171A6565659E9D9C9CD6DAD9D8F8FAF6F1FFF7F0E9FFF6EB + E1FEF7E9DDFEF3E8DCFFE6E1DDFFA09E9DE34544445F2A292933292929332929 + 29332A2929332121212704040405000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000004040405212121274545455FA4A4A4E3ECEAE9FFF9F5F1FFFCF4 + EDFEF5EBE1FEF5EADEFFF6EDE4FFD4C9C1F8928783D67B675FCB725047CB7249 + 3ACB764C3DCB5E4B459E1717171A000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000001717171A6566669E9D9D9DD6DCDAD9F8FCF6 + F3FFF8F2ECFFF5EBE1FEF4E6DAFEE3CEC1FFBF9D91FFAB7664FFA85E42FFAB56 + 32FFB35B35FF89523AE3433F3D5F222121280909090A00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000004040405212121274545455FA7A7A6E3F0EF + EEFFFDFBF9FFF8EFE9FEE5D0C6FECBA696FFA66A56FFA0573CFFB66D47FFC277 + 4AFFC47647FFB0673EF8875540D65F4C45A12221212800000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000001717171A6767679EA0A0 + A0D5D8D2D0F3E8D8D1FECBA89BFEB6806DFEA46147FEA8603EFEC17E54FECC8B + 5AFECA8450FEC47644FFB65E38FF794B3BD72828273100000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000004040405212121274443 + 435C968C89D5C5A499FEA9705BFEA66447FEBC7F5EFEC99069FECE9367FECE90 + 5EFECA864FFEC27742FFB36139FF754F41CB201F1F2500000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000001F1F + 1F247C6963C6B48371FEA6684EFEAF6F4EFECD9873FED9A87EFED49D70FECF93 + 60FEC98850FEC17B44FEB66B3DFE845842D5423F3D5C21212127040404050000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000002525 + 252D785749C9B47556FEC59073FED0A381FED7AA84FED8A97EFED49C6EFECE92 + 5FFECA8851FEC68046FEC27A41FEAD6B3FF38C5C44D5614F479E1717171A0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000002A29 + 29337A503ECFBD734EFFD8A886FFE2BE9CFEDFB895FEDBB08AFED7A479FED198 + 68FECC8B56FECA844AFECA8145FECA7B42FFC77241FF915B41E344403E5F2121 + 2127040404050000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000002C2B + 2B36855742D8CB8259FFDDAB86FFE4BF9DFEE5C3A5FEE3BFA1FEDEB390FED7A4 + 7BFECF915EFECC864DFECC8448FECD8345FFCC8045FFB97242F8916148D66251 + 499E1717171A0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000002222 + 212865534AA1956B55D6C59470F8E0B08DFFE2B99CFFE4BDA1FFE3BC9DFFDDB0 + 8BFED59C6EFED18F5BFECF894FFECE874AFECE864AFECF8449FFCC7A49FF9561 + 46E345413F5F2121212704040405000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000909 + 090A2222212845413F5F97674FE3D18A64FFD29574FFD9A689FFE1B99CFFE2BA + 9BFEDDAC87FED89F72FED4905AFED08A4EFED0894EFED18A4DFFD0874CFFBC7A + 4BF895694CD665544B9E1717171A000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000001717171A6251499E865F4ECB866656CB957565D6CBA289F8E6BC + 9DFFE4B897FFDEAD85FED89C6BFED4935CFED28E55FED18C51FED18C51FED48D + 50FFD58851FF9C684BE345413F5F222221280000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000004040405212121272A2929332A2929334542415FA48069E3E6B0 + 8FFFE6B99BFFE2B795FEDDAC83FED9A072FED4935FFED38D54FED38E54FED690 + 53FFD69054FFC18153F8966D55D667574FA10000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000001717171A685A539EA17F + 6BD6D2A68BF8E7BC9BFFE4B995FFDEAE85FED99F6FFED69660FED6935BFED692 + 58FED69359FED8935AFFD68D60FF916651DD0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000004040405212121274643 + 415FA8846DE3EAB593FFE9BE9CFFE4BB96FEE0B185FEDCA575FED99A65FED896 + 5DFED9985EFEDB975EFFD99163FF936853DD0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000001717 + 171A6A5D569EA38470D6D8B194F8EDC5A2FFE8BF98FFE2B389FEDEA777FEDFA2 + 6BFFE0A067FFC98F5EF899735AD6695951A10000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000404 + 0405212121274644425FB1927CE3F5C7A6FFEDC6A5FFE6C09CFEE5BA90FEE7B3 + 86FFE8A876FFA77B5DE34542405F222222280000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000001717171A6D625C9EA98E7CD6D7AF92F8E9BD99FFE9BA93FFD3A3 + 7FF8A38065D66A5B539E1717171A000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000004040405212121274643425FA78065E3E6A579FFE6A477FFA47C + 61E34643405F2121212704040405000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000001717171A6859509E926F59CB926F5ACB6859 + 509E1717171A0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000001717171A715D609EA06A + 74CB965463CB8F445ACB8D3D56CB8A3858CB8A395DCB8B3F66CB8D4972CB955B + 82CBA07294CB71606D9E1717171A000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000004040405212121272A2929332A282933463E3F5FB6656FE3FB79 + 91FFEC5C7DFFE24873FFDF3D72FFDD3877FFDC3983FFDC4092FFDF4CA4FFE763 + BBFFF683D8FFB26BA4E3463F455F2A292A332A292A3321212127040404050000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000001717171A735C5C9EA35F5FCB97383ACB9F2A31D6D1394CF8E94F + 6BFFEB5878FFEC5E86FFED6291FFED649BFFEB64A3FFE860ABFFE459AFFFE051 + B4FFDC48BAFFC238ACF8942D8BD690408DCB9E6C9FCB7162729E1717171A0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000404 + 0405212121274741405FBC6C67E3FF6D69FFF1373AFFE82933FFE64053FFE653 + 6DFEEE617EFEF36A8DFEF5709AFEF673A6FEF472B0FEF16EB7FEEB65BAFEE358 + BBFEDA49BAFED739C0FFD628CAFFDD3DDAFFED78F3FFAF75B5E34642475F2121 + 2127040404050000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000020202FF020202FF020202FF020202FF020202FF020202FF020202FF0202 + 02FF020202FF020202FF020202FF020202FF020202FF020202FF020202FF0202 + 02FF020202FF020202FF020202FF020202FF020202FF020202FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000000000000000000000000000000000000000000000000000001717 + 171A73554F9EB66152D6DE5845F8F1584DFFF36562FFF57277FFF7848DFFF682 + 92FEF8768DFEFA6D8FFEFB6694FEFB639FFEFA62ADFEF966BBFEF86EC8FEF576 + D4FEF27FDCFEEF79E3FFE965E3FFDC53E0FFC942D8FFB648C7F89961A8D66857 + 6F9E1717171A0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000020202FF020202FF020202FF020202FF020202FF020202FF020202FF0202 + 02FF020202FF020202FF020202FF020202FF020202FF020202FF020202FF0202 + 02FF020202FF020202FF020202FF020202FF020202FF020202FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF00000000000000000000000000000000000000000909090A222222284842 + 405FBF674EE3FF7350FFF26048FFEB6556FEF57E78FEFB8C8BFEFD8D91FEFD84 + 90FEFD748AFEFD678BFEFD5E91FEFD5A9CFEFD59ADFEFD5FBDFEFD6ACFFEFD77 + DFFEFD83EDFEF986F3FEF17FF2FEDE69E7FEC043D4FEBB40D6FFC860ECFF975F + B0E34542475F222222280909090A000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000141414FF141414FF141414FF141414FF202020FF202020FF141414FF1414 + 14FF141414FF141414FF202020FF202020FF141414FF141414FF141414FF1414 + 14FF141414FF141414FF141414FF141414FF141414FF141414FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF000000000000000000000000000000000000000022222228796459A1B780 + 61D6E57445F8F6764BFFF68E73FFF69081FEFA847AFEFC7671FEFD6266FEFD5A + 67FEFD5B74FEFD5B80FEFD5A8EFEFD599EFEFD58AEFEFD58BFFEFD5ACEFEFD59 + DEFEFD56EDFEFA5FF6FEF375FAFEE87DF5FED677EBFEC263E2FFA841D9FF9D49 + CAF89574AFD66C6375A122222228000000000000000000000000000000000000 + 0000B07856FFB07856FFB07856FFB07856FFB07856FFB07856FF000000000000 + 0000DD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FF000000000000 + 0000B175FFFFB175FFFFB175FFFFB175FFFFB175FFFFB175FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000141414FF141414FF141414FF141414FF202020FF202020FF141414FF1414 + 14FF141414FF141414FF202020FF202020FF141414FF141414FF141414FF1414 + 14FF141414FF141414FF141414FF141414FF141414FF141414FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF000000000000000000000000000000000000000029282831B47B55D7FFA5 + 5FFFFB8A4FFFF0875CFEF8A083FEFC9F89FEFC8371FEFD6C60FEFC5554FEFC4F + 59FEFC576EFEFC5D80FEFC6092FEFC61A4FEFC60B3FEFC5EC4FEFC59D3FEFC52 + E2FEFB48F1FEF84FF9FEEE67FDFEE67AFDFEDD88F8FEC678EBFEA145D6FE9E44 + DCFFBB77F8FF876CA8D728282931000000000000000000000000000000000000 + 0000B07856FFB07856FFB07856FFB07856FFB07856FFB07856FF000000000000 + 0000DD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FF000000000000 + 0000B175FFFFB175FFFFB175FFFFB175FFFFB175FFFFB175FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000031FF000031FF003131FF003131FF003131FF003131FF003131FF0031 + 31FF313100FF313100FF313100FF313100FF313100FF313100FF310000FF3100 + 00FF310031FF310031FF310031FF310031FF310031FF310031FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF0000000000000000000000000000000000000000201F1F25A66731CBFF95 + 32FFFEA669FFF7A77FFEFA9E78FEFC8F6DFEFC7C5FFEFC6E5AFEFC655DFEFC64 + 68FEFC6979FEFC6D89FEFC709CFEFC72ADFEFC71BDFEFC6ECDFEFC68DDFEFC63 + EBFEF95BF7FEF156FBFEE254FDFED960FCFED57AFBFEC97EF5FEB36CE7FEA054 + E4FF8C3CE9FF613D92CB1F1F2025000000000000000000000000000000000000 + 0000B07856FFB07856FFB07856FFB07856FFB07856FFB07856FF000000000000 + 0000DD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FF000000000000 + 0000B175FFFFB175FFFFB175FFFFB175FFFFB175FFFFB175FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000031FF000031FF003131FF003131FF003131FF003131FF003131FF0031 + 31FF313100FF313100FF313100FF313100FF313100FF313100FF310000FF3100 + 00FF310031FF310031FF310031FF310031FF310031FF310031FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF000000000000000000000000000000002222222846423D5CB3712BD5FC98 + 31FEFDB97EFEFBBB92FEFCA070FEFC8D5CFEFC815AFEFC7B5EFEFC7869FEFC78 + 75FEFC7A82FEFC7D92FEFC80A5FEFC82B7FEFC82C7FEFC7FD7FEFC79E7FEFA73 + F3FEF56BFBFEEA60FDFED853FCFECC55FCFEC767FDFEC277FAFEBD81F3FEA469 + EAFE762BDFFE582E9AD5403D455C2A292A330000000000000000000000000000 + 0000B07856FFB07856FFB07856FFB07856FFB07856FFB07856FF000000000000 + 0000DD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FF000000000000 + 0000B175FFFFB175FFFFB175FFFFB175FFFFB175FFFFB175FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000064FF000064FF003164FF003164FF006464FF006464FF006431FF0064 + 31FF316400FF316400FF646400FF646400FF643100FF643100FF640000FF6400 + 00FF640031FF640031FF640064FF640064FF310064FF310064FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF000000000000000000000000000000007B6D54A1B7995BD5E5A84AF3FBB3 + 5BFEFCC78FFEFCC293FEFCA768FEFC9758FEFC9562FEFC926CFEFC8D76FEFC8B + 80FEFC8A8CFEFC8D9BFEFC91AEFEFC94C0FEFC95D1FEFC91E0FEFD8BF0FEF882 + F8FEEE79FBFEE26EFCFED162FCFEC159FCFEB252FCFEB062FCFEBE89FAFEAC7E + F1FE7A40DEFE6A3BC6F37863A7D57E719DCB0000000000000000000000000000 + 0000B07856FFB07856FFB07856FFB07856FFB07856FFB07856FF000000000000 + 0000DD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FF000000000000 + 0000B175FFFFB175FFFFB175FFFFB175FFFFB175FFFFB175FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000064FF000064FF003164FF003164FF006464FF006464FF006431FF0064 + 31FF316400FF316400FF646400FF646400FF643100FF643100FF640000FF6400 + 00FF640031FF640031FF640064FF640064FF310064FF310064FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF00000000000000000000000000000000B99A54D8FFE164FFFFCE66FFFAC6 + 74FEFBCF8CFEFDC787FEFCB165FEFCA65BFEFCA86CFEFCA779FEFCA383FEFCA0 + 8DFEFC9D97FEFC9EA5FEFCA2B7FEFCA4C8FEFCA6DAFEFCA1E8FEFB9BF6FEF492 + FBFEE785FCFED97AFCFEC96FFCFEB760FCFEA34DFCFEA259FDFEB585FDFEA984 + F5FE7E53E2FE774DE1FF9473EFFFA287F4FF0000000000000000000000000000 + 0000B07856FFB07856FFB07856FFB07856FFB07856FFB07856FF000000000000 + 0000DD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FFDD9BD9FF000000000000 + 0000B175FFFFB175FFFFB175FFFFB175FFFFB175FFFFB175FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000003199FF003199FF006499FF006499FF009999FF009999FF009964FF0099 + 64FF649900FF649900FF999900FF999900FF993100FF993100FF990000FF9900 + 00FF990064FF990064FF990099FF990099FF310099FF310099FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF00000000000000000000000000000000AB9043CFFFDC4DFFFFD96DFFFBD3 + 7CFEFBCF77FEFCC870FEFCBE66FEFCBA68FEFCBA76FEFCBA83FEFCB890FEFCB5 + 9AFEFCB1A4FEFCB0B0FEFCB3C0FEFCB4D1FEFCB5E2FEFBB1F0FEF8AAF8FEEEA0 + FCFEDF93FCFED086FCFEC07AFCFEAE6AFCFE9B5AFCFE975EFCFEA077FDFE9979 + F7FE8363E9FE7757E5FF7658E4FF7559E2FF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000003199FF003199FF006499FF006499FF009999FF009999FF009964FF0099 + 64FF649900FF649900FF999900FF999900FF993100FF993100FF990000FF9900 + 00FF990064FF990064FF990099FF990099FF310099FF310099FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF00000000000000000000000000000000A38E38CAFCDE3EFEFCE174FEFCDF + 82FEFCD66BFEFCD063FEFCCD67FEFCCC71FEFCCC7EFEFCCC8DFEFCCC9AFEFCC9 + A6FEFCC6B0FEFCC4BCFEFCC5CBFEFCC5DAFEFCC6EAFEF9C1F6FEF2B8FAFEE6AD + FCFED69EFCFEC690FCFEB681FCFEA471FCFE9262FCFE8A5FFCFE8D6BFCFE8B70 + F9FE866EF0FE7960E7FE6047DCFE553CD7FE0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000031CCFF0031CCFF0064CCFF0064CCFF00CCCCFF00CCCCFF00CC64FF00CC + 64FF64CC00FF64CC00FFCCCC00FFCCCC00FFCC6400FFCC6400FFCC0000FFCC00 + 00FFCC0064FFCC0064FFCC00CCFFCC00CCFF6400CCFF6400CCFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF00000000000000000000000000000000A19433CAFCE836FEFDEC79FEFCEA + 89FEFCE36AFEFDDE60FEFDDE6BFEFDDD78FEFDDD86FEFDDC94FEFDDDA2FEFDDB + B0FEFDDABCFEFDD9C8FEFDD9D7FEFDD9E4FEFCD7F2FEF6D0FBFEE9C4FCFEDBB7 + FCFECBA7FCFEBB97FCFEAC86FCFE9977FCFE8667FCFE7D5FFCFE7B62FCFE7E6A + FAFE8776F4FE7967EBFE503FDDFE3E2BD6FE0000000000000000000000000000 + 0000B2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FF000000000000 + 00006BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF000000000000 + 0000EBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000031CCFF0031CCFF0064CCFF0064CCFF00CCCCFF00CCCCFF00CC64FF00CC + 64FF64CC00FF64CC00FFCCCC00FFCCCC00FFCC6400FFCC6400FFCC0000FFCC00 + 00FFCC0064FFCC0064FFCC00CCFFCC00CCFF6400CCFF6400CCFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF00000000000000000000000000000000A0982FCAFDF231FEFCF37BFEFCF2 + 8DFEFCED6AFEFCEB60FEFCEC6EFEFCEB7CFEFCEB8AFEFCEA99FEFCEBA7FEFCEA + B6FEFCEBC4FEFCEAD1FEFCEADFFEFBE9ECFEFAE5F7FEF1DCFDFEE1CEFDFED1BF + FCFEC1AFFCFEB19DFCFEA18CFCFE8F7CFCFE7D6BFCFE7261FCFE6D5FFCFE7468 + FBFE857CF8FE776CEEFE453BDEFE2D23D6FE0000000000000000000000000000 + 0000B2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FF000000000000 + 00006BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF000000000000 + 0000EBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000031FFFF0031FFFF0064FFFF0064FFFF00FFFFFF00FFFFFF00FF64FF00FF + 64FF99FF00FF99FF00FFFFFF00FFFFFF00FFFF6400FFFF6400FFFF0000FFFF00 + 00FFFF0099FFFF0099FFCC00FFFFCC00FFFF6400FFFF6400FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF00000000000000000000000000000000A09D2ECAFDFA30FEFBF87CFEFAF7 + 8EFEFAF66BFEFAF661FEFAF770FEF9F67EFEF9F68DFEF9F59CFEF9F6AAFEFAF6 + B9FEFBF6C8FEFBF7D7FEFBF7E5FEF9F5F1FEF4F0F9FEE9E5FDFED9D6FCFEC8C5 + FCFEB8B4FCFEA7A3FCFE9692FCFE8580FCFE746FFCFE6964FCFE6561FCFE6D6A + FBFE817EF9FE726FF0FE3D3BDFFE2423D7FE0000000000000000000000000000 + 0000B2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FF000000000000 + 00006BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF000000000000 + 0000EBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000031FFFF0031FFFF0064FFFF0064FFFF00FFFFFF00FFFFFF00FF64FF00FF + 64FF99FF00FF99FF00FFFFFF00FFFFFF00FFFF6400FFFF6400FFFF0000FFFF00 + 00FFFF0099FFFF0099FFCC00FFFFCC00FFFF6400FFFF6400FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF000000000000000000000000000000009B9F31CAF7FD34FEF4F97AFEF3F8 + 8BFEF3FB6DFEF3FC64FEF2FC72FEF1FC7EFEF1FC8DFEF1FC9CFEF1FCAAFEF2FC + B9FEF2FCC7FEF1FDD6FEF2FDE3FEF0FCEFFEEBF7F8FEE1EDFCFED2DFFCFEC1CE + FCFEB1BDFCFEA1ACFCFE8F9BFCFE7F8AFCFE6E79FCFE656EFCFE646CFCFE6D73 + FBFE7E82FAFE6E73F2FE3E44E2FE272FDAFE0000000000000000000000000000 + 0000B2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FF000000000000 + 00006BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF000000000000 + 0000EBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000031FFFF0031FFFF3199FFFF3199FFFF31FFFFFF31FFFFFF31FF99FF31FF + 99FF99FF31FF99FF31FFFFFF31FFFFFF31FFFF9931FFFF9931FFFF3131FFFF31 + 31FFFF3199FFFF3199FFFF31FFFFFF31FFFF6431FFFF6431FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF00000000000000000000000000000000949F38CAE9FD3DFEE9F774FEE8F6 + 84FEE7FA6FFEE6FC68FEE5FC72FEE3FC7EFEE3FC8CFEE3FC9AFEE4FCA7FEE3FC + B5FEE2FCC1FEE1FDCEFEE2FDDBFEE0FCE7FEDFFBF4FED7F4FBFECCE8FCFEBED9 + FCFEAEC9FCFE9EB9FCFE8DA8FCFE7E97FCFE6D86FCFE677EFCFE6C7FFCFE7382 + FBFE7886FAFE6A78F3FE4756E5FE3747DFFE0000000000000000000000000000 + 0000B2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FF000000000000 + 00006BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF000000000000 + 0000EBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000031FFFF0031FFFF3199FFFF3199FFFF31FFFFFF31FFFFFF31FF99FF31FF + 99FF99FF31FF99FF31FFFFFF31FFFFFF31FFFF9931FFFF9931FFFF3131FFFF31 + 31FFFF3199FFFF3199FFFF31FFFFFF31FFFF6431FFFF6431FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF0000000000000000000000000000000094A541CFE5FF4AFFDFF76DFFDCF2 + 7EFEDFFA79FEDEFC76FED8FC73FED5FC79FED5FC88FED5FD96FED5FDA3FED3FC + AFFED1FCB9FED0FCC6FED1FCD2FED1FDDFFED1FDEEFECCF9F8FEC3F0FBFEB7E3 + FCFEA8D4FCFE9AC5FCFE89B4FCFE7AA4FCFE6893FCFE698EFCFE7A96FCFE7E94 + FBFE7288F9FE647CF6FF566DEFFF5066EBFF0000000000000000000000000000 + 0000B2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FFB2EBD0FF000000000000 + 00006BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF6BCC4EFF000000000000 + 0000EBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFFEBB05EFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00003164FFFF3164FFFF6499FFFF6499FFFF64FFFFFF64FFFFFF64FF99FF64FF + 99FFCCFF64FFCCFF64FFFFFF64FFFFFF64FFFF9964FFFF9964FFFF6464FFFF64 + 64FFFF64CCFFFF64CCFFFF64FFFFFF64FFFF9964FFFF9964FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF000000000000000000000000000000009CB14ED8E6FF5DFFD4F467FFCEEC + 76FED9F88BFED9FD8BFECDFC75FEC7FC72FEC7FC83FEC6FC91FEC4FC9DFEC2FC + A7FEBFFCAFFEBEFCBBFEC1FCC8FEC1FCD7FEC3FCE8FEBEFBF3FEB7F6FAFEAEEB + FDFEA0DEFCFE93CFFCFE84C1FCFE75B0FCFE629DFCFE6A9DFCFE8DAFFCFE8DA8 + FAFE6A8BF8FE6083F8FF6E8DFCFF7491FCFF0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00003164FFFF3164FFFF6499FFFF6499FFFF64FFFFFF64FFFFFF64FF99FF64FF + 99FFCCFF64FFCCFF64FFFFFF64FFFFFF64FFFF9964FFFF9964FFFF6464FFFF64 + 64FFFF64CCFFFF64CCFFFF64FFFFFF64FFFF9964FFFF9964FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF000000000000000000000000000000006E7651A19DB558D5B1D755F3C1EC + 69FED3F691FED3FB96FEC1FC74FEB9FC6CFEB8FC7DFEB6FC8AFEB4FC95FEB1FC + 9EFEAEFCA6FEAEFCB2FEB2FCC1FEB4FCD0FEB4FCE1FEB1FCEDFEABFAF8FEA3F2 + FCFE98E6FCFE8BD9FCFE7ECBFCFE70BBFCFE63ABFCFE70ACFCFE97BFFCFE8EB3 + FBFE5889F8FE4A74DFF36076AED56875A0CB0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000807AFFFF807AFFFF99CCFFFF99CCFFFF99FFFFFF99FFFFFF99FFCCFF99FF + CCFFCCFF99FFCCFF99FFFFFF99FFFFFF99FFFFCC99FFFFCC99FFFF9999FFFF99 + 99FFFF99CCFFFF99CCFFFF99FFFFFF99FFFF9999FFFF9999FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF000000000000000000000000000000002222222843463E5C83A642D5B6F0 + 54FECCF58CFECBF996FEB6FB71FEABFD67FEA9FC75FEA6FC80FEA4FC8AFEA0FC + 94FE9FFC9DFEA0FCAAFEA6FCBBFEA7FCCBFEA7FCD9FEA4FCE6FE9EFCF3FE96F7 + FAFE8DEEFCFE80E1FCFE73D2FCFE6CC6FCFE6BBCFDFE7ABCFCFE97C6FBFE81B4 + FCFE3985FBFE3260AFD53D40465C292A2A330000000000000000000000000000 + 0000696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF000000000000 + 000071AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF000000000000 + 000065D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000807AFFFF807AFFFF99CCFFFF99CCFFFF99FFFFFF99FFFFFF99FFCCFF99FF + CCFFCCFF99FFCCFF99FFFFFF99FFFFFF99FFFFCC99FFFFCC99FFFF9999FFFF99 + 99FFFF99CCFFFF99CCFFFF99FFFFFF99FFFF9999FFFF9999FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0 + C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFF000000FF0000 + 00FF00000000000000000000000000000000000000001F201F25769941CBB3F8 + 4EFFBDF37AFFBCF289FEB2F87AFEA9FC73FE9DFC71FE95FC76FE91FC7EFE8EFC + 88FE8FFC95FE92FCA4FE98FCB5FE9AFCC5FE99FCD2FE96FCDEFE90FDEDFE89FA + F6FE7FF4FBFE76E9FCFE6DDBFCFE6ED1FCFE7BCCFCFE83C8FBFE87C6FAFE71B8 + FFFF3F9AFFFF3966A4CB1F1F2025000000000000000000000000000000000000 + 0000696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF000000000000 + 000071AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF000000000000 + 000065D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00009999FFFF9999FFFF99CCFFFF99CCFFFF99FFFFFF99FFFFFF99FFCCFF99FF + CCFFCCFF99FFCCFF99FFFFFF99FFFFFF99FFFFCCCCFFFFCCCCFFFFCCCCFFFFCC + CCFFFF99CCFFFF99CCFFFF99FFFFFF99FFFFCC99FFFFCC99FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF00000000000000000000000000000000000000002829283182A94DD7B3FF + 59FFA4EC5DFFA5E670FEB7F38EFEB2FB8FFE95FD74FE82FD69FE7CFC6FFE7BFC + 7BFE81FC8CFE86FC9DFE8BFCAEFE8DFCBDFE8CFCCAFE89FCD7FE83FCE6FE7BFB + F1FE6FF9F9FE69F1FDFE6BE5FDFE79DDFCFE92DBFBFE8DD0F9FE6ABFF8FE5EBB + FFFF6AC3FFFF5B87B7D728282931000000000000000000000000000000000000 + 0000696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF000000000000 + 000071AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF000000000000 + 000065D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00009999FFFF9999FFFF99CCFFFF99CCFFFF99FFFFFF99FFFFFF99FFCCFF99FF + CCFFCCFF99FFCCFF99FFFFFF99FFFFFF99FFFFCCCCFFFFCCCCFFFFCCCCFFFFCC + CCFFFF99CCFFFF99CCFFFF99FFFFFF99FFFFCC99FFFFCC99FFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFF + FFFFC0C0C0FFC0C0C0FFFFFFFFFFFFFFFFFFC0C0C0FFC0C0C0FF000000FF0000 + 00FF000000000000000000000000000000000000000022222228637451A183B0 + 54D686D848F893E95AFFA8EF86FFA7F38FFE94F97CFE86FC75FE7EFC79FE7BFD + 80FE7CFD8EFE7DFD9BFE7EFCA9FE7EFCB7FE7EFCC4FE7DFCD1FE7AFCDFFE78FC + ECFE76FCF7FE77F7FCFE7CEDFCFE82E5FAFE8DE0F8FE82D7FBFF59C9FFFF53B6 + F0F86799B7D65B6B7AA122222228000000000000000000000000000000000000 + 0000696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF000000000000 + 000071AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF000000000000 + 000065D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000CCCCFFFFCCCCFFFFCCCCFFFFCCCCFFFFCCFFFFFFCCFFFFFFCCFFCCFFCCFF + CCFFCCFFCCFFCCFFCCFFFFFFCCFFFFFFCCFFFFCCCCFFFFCCCCFFFFCCCCFFFFCC + CCFFFFCCCCFFFFCCCCFFFFCCFFFFFFCCFFFFCCCCFFFFCCCCFFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF00000000000000000000000000000000000000000909090A222222284247 + 3F5F69B441E382F74AFF81E95AFF88E670FE9AF28AFEA0FA98FE9BFD9BFE8FFD + 9AFE7EFD98FE75FD9BFE70FDA4FE6EFDB0FE6EFDBEFE70FDCBFE74FDDBFE7FFD + E9FE93FDF5FE9DFAFBFE9CF4FBFE8BE9F8FE6CDBF3FE5AD9FEFF59E2FFFF51A4 + CAE34046485F222222280909090A000000000000000000000000000000000000 + 0000696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF000000000000 + 000071AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF000000000000 + 000065D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000CCCCFFFFCCCCFFFFCCCCFFFFCCCCFFFFCCFFFFFFCCFFFFFFCCFFCCFFCCFF + CCFFCCFFCCFFCCFFCCFFFFFFCCFFFFFFCCFFFFCCCCFFFFCCCCFFFFCCCCFFFFCC + CCFFFFCCCCFFFFCCCCFFFFCCFFFFFFCCFFFFCCCCFFFFCCCCFFFF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000000000000000000000000000000000000000000000000000001717 + 171A546F479E64AD47D666D649F873EA5EFF87F07CFF92F592FF96F79CFF8FF8 + 9FFE81FA9EFE7AFBA3FE77FBABFE75FCB5FE75FCC1FE77FCCDFE7AFBD9FE83FB + E4FE95F9EDFE99FAF6FF8AF9F9FF75F2FBFF5EE8FCFF51D0EBF853A5B7D64E6C + 779E1717171A0000000000000000000000000000000000000000000000000000 + 0000696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF696DFEFF000000000000 + 000071AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF71AAFFFF000000000000 + 000065D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF65D5F0FF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000404 + 04052121212740473F5F61B652E36BFA5AFF54EF50FF54EB5AFF6AE976FF7BEB + 8EFE84F2A1FE8BF6B0FE90F8BCFE94FAC6FE94FCCFFE91FBD4FE8BF9DAFE83F5 + DEFE7CF1E0FE63F2E9FF3EF7F4FF3FFBFFFF65FFFFFF61B8C4E34047485F2121 + 2127040404050000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000001717171A5470509E58A051CB449644CB429F47D555CD63F369E5 + 81FE73E994FE79EBA3FE7DEDAEFE7FEEB8FE80F0C0FE7EF0C6FE7AEFCCFE73EE + D3FE6BEED9FE4FD5CBF332A8A4D5399FA0CB58A6A8CB5872759E1717171A0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000404040521212127292A2933292A29333D453E5C55A363D55AE9 + 7BFE4CDF79FE41DA7BFE3ADA82FE37DA8BFE39DB97FE3DDDA2FE43DFB0FE51E6 + C2FE64F2D8FE59AAA0D53D45455C292A2A33292A2A3321212127040404050000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000001F1F1F24559560C653EA + 77FE3ADB6CFE28D268FE1BD16EFE16D077FE18D183FE1FD492FE2BD7A3FE41E2 + BAFE61F3D8FE5C988FC61F1F1F24000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000080000000400000000100010000000000000400000000000000000000 + 000000000000000000000000FFFFFF0087FFFFFF000000000000000000000000 + 007FFFFF000000000000000000000000007FFFFF000000000000000000000000 + 001FFFFF000000000000000000000000001FFFFF000000000000000000000000 + 8007FFFF0000000000000000000000008007FFFF000000000000000000000000 + 8001FFFF0000000000000000000000008001FFFF000000000000000000000000 + E0007FFF000000000000000000000000E0007FFF000000000000000000000000 + F80001FF000000000000000000000000F80001FF000000000000000000000000 + FE00007F000000000000000000000000FE00007F000000000000000000000000 + FF80007F000000000000000000000000FF80007F000000000000000000000000 + FFE0001F000000000000000000000000FFE0001F000000000000000000000000 + FFE00007000000000000000000000000FFE00007000000000000000000000000 + FFE00001000000000000000000000000FFE00001000000000000000000000000 + FFF80000000000000000000000000000FFF80000000000000000000000000000 + FFFF8000000000000000000000000000FFFF8000000000000000000000000000 + FFFFE000000000000000000000000000FFFFE000000000000000000000000000 + FFFFF801000000000000000000000000FFFFF801000000000000000000000000 + FFFFFE07000000000000000000000000FFFFFFFFFFFFFFFFFF8001FFFFFFFFFF + FFFFFFFFFFFFFFFFF800001FFFFFFFFFFFFFFFFFFFFFFFFFF800001FFFFFFFFF + FFFFFFFFFFFFFFFFE0000007FFFFFFFFF000003FF000000FE0000007FFFFFFFF + F000003FF000000F80000001FFFFFFFFF000003FF000000F80000001F030303F + F000003FF000000F80000001F030303FF000003FF000000F80000001F030303F + F000003FF000000F00000000F030303FF000003FF000000F00000000F030303F + F000003FF000000F00000000F030303FF000003FF000000F00000000FFFFFFFF + F000003FF000000F00000000FFFFFFFFF000003FF000000F00000000F030303F + F000003FF000000F00000000F030303FF000003FF000000F00000000F030303F + F000003FF000000F00000000F030303FF000003FF000000F00000000F030303F + F000003FF000000F00000000F030303FF000003FF000000F00000000FFFFFFFF + F000003FF000000F00000000FFFFFFFFF000003FF000000F00000000F030303F + F000003FF000000F80000001F030303FF000003FF000000F80000001F030303F + F000003FF000000F80000001F030303FF000003FF000000F80000001F030303F + F000003FF000000FE0000007F030303FFFFFFFFFFFFFFFFFE0000007FFFFFFFF + FFFFFFFFFFFFFFFFF800001FFFFFFFFFFFFFFFFFFFFFFFFFF800001FFFFFFFFF + FFFFFFFFFFFFFFFFFF8001FFFFFFFFFF00000000000000000000000000000000 + 000000000000} end end diff --git a/Source/SpTBXColorPickerForm.pas b/Source/SpTBXColorPickerForm.pas index 856c993..31bf9b4 100644 --- a/Source/SpTBXColorPickerForm.pas +++ b/Source/SpTBXColorPickerForm.pas @@ -40,13 +40,13 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses Windows, Messages, Classes, SysUtils, Controls, Graphics, Forms, - Menus, StdCtrls, ExtCtrls, ActnList, Dialogs, ImgList, - TB2Dock, TB2Toolbar, TB2Item, TB2ExtItems, + Menus, StdCtrls, ExtCtrls, Dialogs, ImgList, + TB2Common, TB2Dock, TB2Toolbar, TB2Item, TB2ExtItems, SpTBXSkins, SpTBXItem, SpTBXControls, SpTBXEditors, SpTBXFormPopupMenu, SpTBXExtEditors, SpTBXTabs; // Delphi XE8 and up will automatically add System.ImageList, make sure to delete it @@ -91,6 +91,8 @@ TSpTBXColorPickerForm = class(TForm) btnColorDialog: TSpTBXSpeedButton; btnColor: TSpTBXSpeedButton; btnLabel: TSpTBXLabel; + ImageList2: TImageList; + ImageList3: TImageList; procedure Timer1Timer(Sender: TObject); procedure imgPaletteMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); @@ -141,7 +143,6 @@ procedure SpScreenShotMagnify(DestCanvas: TCanvas; DestR: TRect; DrawCrosshair: crSpTBXEyeDropper = 103; // Cursor ID used for Eye Dropper cursor resourcestring - SSpTBXTransparentColor = 'Transparent Color'; SSpTBXColorPicker = 'Color Picker'; SSpTBXClickAndDrag = 'Drag && Drop'; @@ -247,8 +248,6 @@ procedure TSpTBXColorPickerForm.FormCreate(Sender: TObject); begin btnColorPicker.Caption := SSpTBXClickAndDrag; imgPalette.Cursor := crSpTBXEyeDropper; - - SpDPIScaleImageList(ImageList1); end; procedure TSpTBXColorPickerForm.FormDestroy(Sender: TObject); @@ -264,15 +263,28 @@ procedure TSpTBXColorPickerForm.FormResize(Sender: TObject); procedure TSpTBXColorPickerForm.FormShow(Sender: TObject); Var Bitmap : TBitmap; + I: Integer; + IL: TCustomImageList; begin + // Scale imgPalette Bitmap := TBitmap.Create; try Bitmap.Assign(imgPalette.Picture.Bitmap); - SpDPIResizeBitmap(Bitmap, SpDPIScale(ImgPalette.Width), SpDPIScale(ImgPalette.Height)); + SpDPIResizeBitmap(Bitmap, PPIScale(ImgPalette.Width), PPIScale(ImgPalette.Height), CurrentPPI); imgPalette.Picture.Assign(Bitmap); finally Bitmap.Free; end; + + // Scale ImageList + I := PPIScale(16); + if I >= 32 then IL := ImageList3 + else if I >= 24 then IL := ImageList2 + else IL := ImageList1; + SpTBXTabControl1.Images := IL; + btnColorNone.Images := IL; + btnColorDialog.Images := IL; + UpdateColorLabel(GetSelectedColor); CenterImages; end; @@ -297,7 +309,7 @@ procedure TSpTBXColorPickerForm.btnColorDraw(Sender: TObject; begin if PaintStage = pstPrePaint then begin PaintDefault := False; - InflateRect(ARect, -SpDPIScale(3), -SpDPIScale(3)); + InflateRect(ARect, -PPIScale(3), -PPIScale(3)); if btnColor.CaptionGlowColor = clNone then SpDrawCheckeredBackground(ACanvas, ARect) else begin @@ -450,7 +462,7 @@ procedure TSpTBXColorPickerForm.SpTBXPanel1DrawBackground(Sender: TObject; begin if PaintStage = pstPrePaint then begin PaintDefault := False; - SpDrawXPDock(ACanvas, ARect); + SpDrawXPDock(ACanvas, ARect, False, CurrentPPI); SpDrawXPToolbar(ACanvas, ARect, True, False, False, True, False); end; end; @@ -514,10 +526,11 @@ procedure TSpTBXColorPickerForm.SetSelectedColor(AColor: TColor); procedure TSpTBXColorPickerForm.UpdateColorLabel(AColor: TColor; AButtonType: Integer = -1); begin btnColor.CaptionGlowColor := AColor; - if AColor = clNone then - btnLabel.Caption := SSpTBXTransparentColor + if AColor = clNone then btnLabel.Caption := SSpTBXColorNone else - btnLabel.Caption := SpColorToHTML(AColor); + if AColor = clDefault then btnLabel.Caption := SSpTBXColorDefault + else + btnLabel.Caption := SpColorToHTML(AColor); end; end. diff --git a/Source/SpTBXControls.pas b/Source/SpTBXControls.pas index 9a25b8e..342369c 100644 --- a/Source/SpTBXControls.pas +++ b/Source/SpTBXControls.pas @@ -1,7 +1,7 @@ unit SpTBXControls; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -41,7 +41,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -92,16 +92,13 @@ TSpTBXTextObject = class; TSpTBXCustomPanel = class(TSpTBXCustomContainer) private - FBorders: Boolean; FBorderType: TSpTBXPanelBorder; FTBXStyleBackground: Boolean; - procedure SetBorders(const Value: Boolean); procedure SetBorderType(const Value: TSpTBXPanelBorder); procedure SetTBXStyleBackground(const Value: Boolean); protected procedure AdjustClientRect(var Rect: TRect); override; procedure DrawBackground(ACanvas: TCanvas; ARect: TRect); override; - property Borders: Boolean read FBorders write SetBorders default True; property BorderType: TSpTBXPanelBorder read FBorderType write SetBorderType default pbrEtched; property TBXStyleBackground: Boolean read FTBXStyleBackground write SetTBXStyleBackground default False; public @@ -175,6 +172,8 @@ TSpTBXPanel = class(TSpTBXCustomPanel) property OnMouseDown; property OnMouseMove; property OnMouseUp; + property OnMouseEnter; + property OnMouseLeave; property OnResize; property OnStartDock; property OnStartDrag; @@ -264,6 +263,9 @@ TSpTBXTextObjectActionLink = class(TControlActionLink) procedure AssignClient(AClient: TObject); override; function IsCheckedLinked: Boolean; override; function IsImageIndexLinked: Boolean; override; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + function IsImageNameLinked: Boolean; override; + {$IFEND} procedure SetChecked(Value: Boolean); override; procedure SetImageIndex(Value: Integer); override; end; @@ -283,6 +285,9 @@ TSpTBXTextObject = class(TSpTBXCustomControl) FImages: TCustomImageList; FImageChangeLink: TChangeLink; FImageIndex: TImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + FImageName: TImageName; + {$IFEND} FLinkText: string; FLinkTextParams: string; FMouseInControl: Boolean; @@ -298,6 +303,11 @@ TSpTBXTextObject = class(TSpTBXCustomControl) FOnMouseEnter: TNotifyEvent; FOnMouseLeave: TNotifyEvent; procedure ImageListChange(Sender: TObject); + function IsImageIndexStored: Boolean; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + function IsImageNameStored: Boolean; + procedure SetImageName(const Value: TImageName); + {$IFEND} procedure UpdateTracking(ForceMouseLeave: Boolean = False); procedure SetAlignment(const Value: TAlignment); procedure SetCaptionGlow(const Value: TSpGlowDirection); @@ -369,7 +379,10 @@ TSpTBXTextObject = class(TSpTBXCustomControl) property DisabledIconCorrection: Boolean read FDisabledIconCorrection write FDisabledIconCorrection default True; property GlyphLayout: TSpGlyphLayout read FGlyphLayout write SetGlyphLayout default ghlGlyphLeft; property Images: TCustomImageList read FImages write SetImages; - property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1; + property ImageIndex: TImageIndex read FImageIndex write SetImageIndex stored IsImageIndexStored default -1; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName: TImageName read FImageName write SetImageName stored IsImageNameStored; + {$IFEND} property LinkText: string read FLinkText write FLinkText; property LinkTextParams: string read FLinkTextParams write FLinkTextParams; property ShowAccelChar: Boolean read FShowAccelChar write SetShowAccelChar default True; @@ -470,6 +483,9 @@ TSpTBXLabel = class(TSpTBXCustomLabel) property GlyphLayout; property Images; property ImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName; + {$IFEND} property LinkText; property LinkTextParams; property Underline; @@ -532,6 +548,7 @@ TSpTBXCustomCheckBox = class(TSpTBXCustomCheckButton) property State: TCheckBoxState read FState write SetState default cbUnchecked; public constructor Create(AOwner: TComponent); override; + function GetGlyphSize: TSize; override; procedure Click; override; end; @@ -594,13 +611,14 @@ TSpTBXCustomRadioButton = class(TSpTBXCustomCheckButton) procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED; protected procedure AdjustFont(AFont: TFont); override; - function CanUpdateExclusive: Boolean; override; + function CanUpdateExclusive: Boolean; override; procedure DoInternalGlyphDraw(ACanvas: TCanvas; AGlyphRect: TRect); override; procedure SetChecked(Value: Boolean); override; procedure Toggle; override; property TabStop default False; public constructor Create(AOwner: TComponent); override; + function GetGlyphSize: TSize; override; procedure Click; override; end; @@ -866,6 +884,9 @@ TSpTBXButton = class(TSpTBXCustomButton) property GroupIndex; property Images; property ImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName; + {$IFEND} property LinkText; property LinkTextParams; property ModalResult; @@ -943,6 +964,9 @@ TSpTBXSpeedButton = class(TSpTBXCustomSpeedButton) property GroupIndex; property Images; property ImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName; + {$IFEND} property LinkText; property LinkTextParams; property Repeating; @@ -1052,6 +1076,10 @@ TSpTBXTrackBar = class(TTrackBar) procedure SetTickMarks(const Value: TSpTBXTickMark); procedure CMSpTBXControlsInvalidate(var Message: TMessage); message CM_SPTBXCONTROLSINVALIDATE; procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY; + procedure CNHScroll(var Message: TWMHScroll); message CN_HSCROLL; + procedure CNVScroll(var Message: TWMVScroll); message CN_VSCROLL; + procedure WMLButtonUp(var Message: TWMMouse); message WM_LBUTTONUP; + procedure WMLButtonDown(var Message: TWMMouse); message WM_LBUTTONDOWN; procedure WMEraseBkGnd(var Message: TMessage); message WM_ERASEBKGND; procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE; protected @@ -1077,33 +1105,32 @@ TSpTBXTrackBar = class(TTrackBar) end; { Painting helpers } -procedure SpDrawXPPanel(ACanvas: TCanvas; ARect: TRect; Enabled, TBXStyleBackground: Boolean; Border: TSpTBXPanelBorder); +procedure SpDrawXPPanel(ACanvas: TCanvas; ARect: TRect; Enabled, TBXStyleBackground: Boolean; Border: TSpTBXPanelBorder; DPI: Integer); procedure SpDrawXPPanelBorder(ACanvas: TCanvas; ARect: TRect; Border: TSpTBXPanelBorder); -procedure SpDrawXPGroupBox(ACanvas: TCanvas; ARect: TRect; ACaption: string; TextFlags: Cardinal; Enabled, TBXStyleBackground: Boolean); -procedure SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; Min, Max, Position: Integer; Back, Fore: TBitmap); overload; -function SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; Vertical, Smooth, DrawProgress: Boolean; Min, Max, Position: Integer): Integer; overload; -procedure SpDrawXPTrackBar(ACanvas: TCanvas; ARect: TRect; Part: Cardinal; Vertical, ChannelSelection: Boolean; ThumbState: TSpTBXSkinStatesType; TickMark: TSpTBXTickMark; Min, Max, SelStart, SelEnd: Integer); +procedure SpDrawXPGroupBox(ACanvas: TCanvas; ARect: TRect; ACaption: string; TextFlags: Cardinal; Enabled, TBXStyleBackground: Boolean; DPI: Integer); +procedure SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; Min, Max, Position: Integer; Back, Fore: TBitmap; DPI: Integer); overload; +function SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; Vertical, Smooth, DrawProgress: Boolean; Min, Max, Position, DPI: Integer): Integer; overload; +procedure SpDrawXPTrackBar(ACanvas: TCanvas; ARect: TRect; Part: Cardinal; Vertical, ChannelSelection: Boolean; ThumbState: TSpTBXSkinStatesType; TickMark: TSpTBXTickMark; Min, Max, SelStart, SelEnd, DPI: Integer); implementation uses Types, Themes, UxTheme, - CommCtrl, ShellAPI; + CommCtrl, ShellAPI, TB2Common; type TWinControlAccess = class(TWinControl); //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Helpers } -procedure SpDrawXPPanel(ACanvas: TCanvas; ARect: TRect; Enabled, TBXStyleBackground: Boolean; - Border: TSpTBXPanelBorder); +procedure SpDrawXPPanel(ACanvas: TCanvas; ARect: TRect; Enabled, TBXStyleBackground: Boolean; Border: TSpTBXPanelBorder; DPI: Integer); begin case SkinManager.GetSkinType of sknNone: SpDrawXPPanelBorder(ACanvas, ARect, Border); sknWindows, sknDelphiStyle: CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncPanel, - Enabled, False, False, False, False, False, False); + Enabled, False, False, False, False, False, False, DPI); sknSkin: CurrentSkin.PaintBackground(ACanvas, ARect, skncPanel, sknsNormal, TBXStyleBackground, True); end; @@ -1122,8 +1149,7 @@ procedure SpDrawXPPanelBorder(ACanvas: TCanvas; ARect: TRect; Border: TSpTBXPane DrawEdge(ACanvas.Handle, ARect, Edge[Border], BF_RECT); end; -procedure SpDrawXPGroupBox(ACanvas: TCanvas; ARect: TRect; ACaption: string; - TextFlags: Cardinal; Enabled, TBXStyleBackground: Boolean); +procedure SpDrawXPGroupBox(ACanvas: TCanvas; ARect: TRect; ACaption: string; TextFlags: Cardinal; Enabled, TBXStyleBackground: Boolean; DPI: Integer); var Width, SaveIndex: Integer; R: TRect; @@ -1152,7 +1178,7 @@ procedure SpDrawXPGroupBox(ACanvas: TCanvas; ARect: TRect; ACaption: string; with CaptionRect do ExcludeClipRect(ACanvas.Handle, Left, Top, Right, Bottom); try - SpDrawXPPanel(ACanvas, R, Enabled, TBXStyleBackground, pbrEtched); + SpDrawXPPanel(ACanvas, R, Enabled, TBXStyleBackground, pbrEtched, DPI); finally RestoreDC(ACanvas.Handle, SaveIndex); end; @@ -1185,7 +1211,7 @@ procedure SpDrawXPGroupBox(ACanvas: TCanvas; ARect: TRect; ACaption: string; end; procedure SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; - Min, Max, Position: Integer; Back, Fore: TBitmap); + Min, Max, Position: Integer; Back, Fore: TBitmap; DPI: Integer); var Percent, Delta: Integer; DeltaR, R: TRect; @@ -1218,7 +1244,7 @@ procedure SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; end; function SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; - Vertical, Smooth, DrawProgress: Boolean; Min, Max, Position: Integer): Integer; + Vertical, Smooth, DrawProgress: Boolean; Min, Max, Position, DPI: Integer): Integer; var ChunkPaint: Boolean; I: Integer; @@ -1262,7 +1288,7 @@ function SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; begin if Vertical then Details := SpTBXThemeServices.GetElementDetails(tpBarVert) else Details := SpTBXThemeServices.GetElementDetails(tpBar); - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); if DrawProgress and not IsRectEmpty(DeltaR) then begin if SpIsWinVistaOrUp then begin Details.Element := teProgress; @@ -1277,7 +1303,7 @@ function SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; InflateRect(DeltaR, 0, -1); end; {$IFEND} - CurrentSkin.PaintThemedElementBackground(ACanvas, DeltaR, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, DeltaR, Details, DPI); end else begin // [Theme-Change] @@ -1293,7 +1319,7 @@ function SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; end; if Vertical then Details := SpTBXThemeServices.GetElementDetails(tpChunkVert) else Details := SpTBXThemeServices.GetElementDetails(tpChunk); - CurrentSkin.PaintThemedElementBackground(B.Canvas, R, Details); + CurrentSkin.PaintThemedElementBackground(B.Canvas, R, Details, DPI); ChunkPaint := True; end; end; @@ -1368,7 +1394,7 @@ function SpDrawXPProgressBar(ACanvas: TCanvas; ARect: TRect; procedure SpDrawXPTrackBar(ACanvas: TCanvas; ARect: TRect; Part: Cardinal; Vertical, ChannelSelection: Boolean; ThumbState: TSpTBXSkinStatesType; - TickMark: TSpTBXTickMark; Min, Max, SelStart, SelEnd: Integer); + TickMark: TSpTBXTickMark; Min, Max, SelStart, SelEnd, DPI: Integer); procedure DrawChannelSelection(ChannelR: TRect); var @@ -1452,13 +1478,13 @@ procedure SpDrawXPTrackBar(ACanvas: TCanvas; ARect: TRect; Part: Cardinal; end; end; Details := SpTBXThemeServices.GetElementDetails(T); - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); end else if Part = TBCD_CHANNEL then begin if Vertical then T := ttbTrackVert else T := ttbTrack; Details := SpTBXThemeServices.GetElementDetails(T); - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); DrawChannelSelection(ARect); end; sknSkin: @@ -1505,7 +1531,6 @@ constructor TSpTBXCustomPanel.Create(AOwner: TComponent); // TSpTBXCustomContainer.WMEraseBkgnd if SkinManager.GetSkinType <> sknNone then ControlStyle := ControlStyle + [csParentBackground] - [csOpaque]; - FBorders := True; FBorderType := pbrEtched; end; @@ -1513,16 +1538,7 @@ procedure TSpTBXCustomPanel.AdjustClientRect(var Rect: TRect); begin inherited AdjustClientRect(Rect); if Borders then - InflateRect(Rect, -SpDPIScale(2), -SpDPIScale(2)); -end; - -procedure TSpTBXCustomPanel.SetBorders(const Value: Boolean); -begin - if FBorders <> Value then begin - FBorders := Value; - Realign; - InvalidateBackground; - end; + InflateRect(Rect, -SpDefaultBorderSize, -SpDefaultBorderSize); // Do not scale end; procedure TSpTBXCustomPanel.SetBorderType(const Value: TSpTBXPanelBorder); @@ -1544,8 +1560,8 @@ procedure TSpTBXCustomPanel.SetTBXStyleBackground(const Value: Boolean); procedure TSpTBXCustomPanel.DrawBackground(ACanvas: TCanvas; ARect: TRect); begin if not Borders then - InflateRect(ARect, SpDPIScale(3), SpDPIScale(3)); - SpDrawXPPanel(ACanvas, ARect, True, FTBXStyleBackground, FBorderType); + InflateRect(ARect, SpDefaultBorderSize + 1, SpDefaultBorderSize + 1); // Do not scale + SpDrawXPPanel(ACanvas, ARect, True, FTBXStyleBackground, FBorderType, CurrentPPI); end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -1569,13 +1585,13 @@ procedure TSpTBXPanel.DrawBackground(ACanvas: TCanvas; ARect: TRect); {$IFEND} begin if not Borders then - InflateRect(ARect, SpDPIScale(3), SpDPIScale(3)); + InflateRect(ARect, PPIScale(3), PPIScale(3)); if not TBXStyleBackground and FHotTrack then begin if SkinManager.GetSkinType = sknNone then SpDrawXPPanelBorder(ACanvas, ARect, pbrDoubleSunken) else - SpDrawXPEditFrame(ACanvas, ARect, Enabled, FHotTracking, True, True); + SpDrawXPEditFrame(ACanvas, ARect, Enabled, FHotTracking, True, True, CurrentPPI); end else inherited; @@ -1595,8 +1611,12 @@ procedure TSpTBXPanel.DrawBackground(ACanvas: TCanvas; ARect: TRect); // [Theme-Change] {$IF CompilerVersion >= 23} // for Delphi XE2 and up // tpPanelBackground is defined on XE2 and up - Details := SpTBXThemeServices.GetElementDetails(tpPanelBackground); - SpTBXThemeServices.DrawText(ACanvas.Handle, Details, Caption, ARect, TTextFormatFlags(TextFlags)); + if (ACanvas.Font.Color = clWindowText) or (ACanvas.Font.Color = clNone) then begin + Details := SpTBXThemeServices.GetElementDetails(tpPanelBackground); + SpTBXThemeServices.DrawText(ACanvas.Handle, Details, Caption, ARect, TTextFormatFlags(TextFlags)); + end + else + SpDrawXPText(ACanvas, Caption, ARect, TextFlags); {$ELSE} SpDrawXPText(ACanvas, Caption, ARect, TextFlags); {$IFEND} @@ -1708,12 +1728,12 @@ procedure TSpTBXCustomGroupBox.DrawBackground(ACanvas: TCanvas; ARect: TRect); Flags: Cardinal; begin if not Borders then - InflateRect(ARect, SpDPIScale(3), SpDPIScale(3)); + InflateRect(ARect, PPIScale(3), PPIScale(3)); Flags := DT_SINGLELINE; if UseRightToLeftAlignment then Flags := Flags or DT_RTLREADING; - SpDrawXPGroupBox(ACanvas, ARect, Caption, Flags, True, TBXStyleBackground); + SpDrawXPGroupBox(ACanvas, ARect, Caption, Flags, True, TBXStyleBackground, CurrentPPI); end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -1737,6 +1757,14 @@ function TSpTBXTextObjectActionLink.IsImageIndexLinked: Boolean; (FClient.ImageIndex = (Action as TCustomAction).ImageIndex); end; +{$IF CompilerVersion >= 34} // for Delphi Sydney and up +function TSpTBXTextObjectActionLink.IsImageNameLinked: Boolean; +begin + Result := inherited IsImageNameLinked and + (FClient.ImageName = (Action as TCustomAction).ImageName); +end; +{$IFEND} + procedure TSpTBXTextObjectActionLink.SetChecked(Value: Boolean); begin if IsCheckedLinked then FClient.Checked := Value; @@ -1899,8 +1927,7 @@ function TSpTBXTextObject.DoDrawText(ACanvas: TCanvas; var ARect: TRect; Flags: Longint): Integer; var PaintDefault: Boolean; - GlyphSize, DummyRightGlyphSize: TSize; - DummyRightGlyphRect: TRect; + GlyphSize: TSize; R, R1, R2: TRect; WS: string; TextFlags: Cardinal; @@ -1920,10 +1947,9 @@ function TSpTBXTextObject.DoDrawText(ACanvas: TCanvas; var ARect: TRect; if PaintDefault then begin // Calc the rects GlyphSize := GetGlyphSize; - DummyRightGlyphSize.cx := 0; - DummyRightGlyphSize.cy := 0; - DummyRightGlyphRect := Rect(0, 0, 0, 0); - SpCalcXPText(ACanvas, ARect, WS, GetRealAlignment(Self), TextFlags, GlyphSize, DummyRightGlyphSize, FGlyphLayout, DrawPushedCaption and Pushed, R1, R2, DummyRightGlyphRect, FCaptionRoatationAngle); + SpCalcXPText(ACanvas, ARect, WS, GetRealAlignment(Self), TextFlags, + GlyphSize, FGlyphLayout, DrawPushedCaption and Pushed, + CurrentPPI, R1, R2, FCaptionRoatationAngle); // Paint the text if IsGlassPainting then @@ -1931,10 +1957,10 @@ function TSpTBXTextObject.DoDrawText(ACanvas: TCanvas; var ARect: TRect; else begin if not Enabled then if SkinManager.GetSkinType = sknNone then begin - OffsetRect(R1, SpDPIScale(1), SpDPIScale(1)); + OffsetRect(R1, PPIScale(1), PPIScale(1)); ACanvas.Font.Color := clBtnHighlight; SpDrawXPText(ACanvas, WS, R1, TextFlags, FCaptionGlow, FCaptionGlowColor, FCaptionRoatationAngle); - OffsetRect(R1, -SpDPIScale(1), -SpDPIScale(1)); + OffsetRect(R1, -PPIScale(1), -PPIScale(1)); ACanvas.Font.Color := clGrayText; end; SpDrawXPText(ACanvas, WS, R1, TextFlags, FCaptionGlow, FCaptionGlowColor, FCaptionRoatationAngle); @@ -1971,14 +1997,13 @@ procedure TSpTBXTextObject.DoInternalGlyphDraw(ACanvas: TCanvas; IL := FImages; I := FImageIndex; DoGetImageIndex(IL, I); - if Assigned(IL) and (I > -1) and (I < IL.Count) then - SpDrawImageList(ACanvas, AGlyphRect, IL, I, Enabled, FDisabledIconCorrection) + SpDrawVirtualImageList(ACanvas, AGlyphRect, IL, I, Enabled); end; procedure TSpTBXTextObject.DoMouseEnter; begin Invalidate; - if Assigned(FOnMouseEnter) then FOnMouseEnter(Self); + if Assigned(FOnMouseEnter) then FOnMouseEnter(Self); end; procedure TSpTBXTextObject.DoMouseLeave; @@ -2038,7 +2063,7 @@ function TSpTBXTextObject.GetFocusRect(R, TextR, GlyphR: TRect): TRect; if Caption = '' then Result := Rect(0, 0, 0, 0) else begin - InflateRect(TextR, SpDPIScale(1), SpDPIScale(1)); + InflateRect(TextR, PPIScale(1), PPIScale(1)); Result := TextR; end; end; @@ -2051,10 +2076,8 @@ function TSpTBXTextObject.GetGlyphSize: TSize; IL := FImages; I := FImageIndex; DoGetImageIndex(IL, I); - if Assigned(IL) and (I > -1) and (I < IL.Count) then begin - Result.cx := IL.Width; - Result.cy := IL.Height; - end + if Assigned(IL) and (I > -1) and (I < IL.Count) then + Result := SpGetScaledVirtualImageListSize(Self, IL) else begin Result.cx := 0; Result.cy := 0; @@ -2074,21 +2097,17 @@ function TSpTBXTextObject.GetPushed: Boolean; procedure TSpTBXTextObject.GetSize(out TotalR, TextR, GlyphR: TRect); // Size of Text + Glyph + TextMargin + Margins var - GlyphSize, DummyRightGlyphSize: TSize; - DummyRightGlyphRect: TRect; + GlyphSize: TSize; R: TRect; begin GlyphSize := GetGlyphSize; - DummyRightGlyphSize.cx := 0; - DummyRightGlyphSize.cy := 0; - DummyRightGlyphRect := Rect(0, 0, 0, 0); R := ClientRect; ApplyMargins(R, GetTextMargins); Canvas.Font.Assign(Font); AdjustFont(Canvas.Font); - SpCalcXPText(Canvas, R, Caption, GetRealAlignment(Self), GetTextFlags, GlyphSize, DummyRightGlyphSize, - FGlyphLayout, DrawPushedCaption and Pushed, TextR, GlyphR, DummyRightGlyphRect); + SpCalcXPText(Canvas, R, Caption, GetRealAlignment(Self), GetTextFlags, GlyphSize, + FGlyphLayout, DrawPushedCaption and Pushed, CurrentPPI, TextR, GlyphR); UnionRect(TotalR, TextR, GlyphR); @@ -2244,9 +2263,18 @@ function TSpTBXTextObject.IsImageIndexValid: Boolean; Result := Assigned(IL) and (I > -1) and (I < IL.Count); end; +function TSpTBXTextObject.IsImageIndexStored: Boolean; +begin + Result := (ActionLink = nil) or not TSpTBXTextObjectActionLink(ActionLink).IsImageIndexLinked; +end; + procedure TSpTBXTextObject.ImageListChange(Sender: TObject); begin if Sender = Images then begin + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + if Assigned(Images) and Images.IsImageNameAvailable then + Images.CheckIndexAndName(FImageIndex, FImageName); + {$IFEND} Invalidate; AdjustBounds; end; @@ -2256,11 +2284,34 @@ procedure TSpTBXTextObject.SetImageIndex(const Value: TImageIndex); begin if FImageIndex <> Value then begin FImageIndex := Value; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + if Assigned(Images) and Images.IsImageNameAvailable then begin + FImageName := Images.GetNameByIndex(Value); + Invalidate; + end; + {$ELSE} if Assigned(Images) then Invalidate; + {$IFEND} AdjustBounds; end; end; +{$IF CompilerVersion >= 34} // for Delphi Sydney and up +function TSpTBXTextObject.IsImageNameStored: Boolean; +begin + Result := (ActionLink = nil) or not TSpTBXTextObjectActionLink(ActionLink).IsImageNameLinked; +end; + +procedure TSpTBXTextObject.SetImageName(const Value: TImageName); +begin + if Value <> FImageName then begin + FImageName := Value; + if Assigned(Images) and Images.IsImageNameAvailable then + SetImageIndex(Images.GetIndexByName(Value)); // Update ImageIndex and invalidate + end; +end; +{$IFEND} + procedure TSpTBXTextObject.SetImages(const Value: TCustomImageList); begin if FImages <> nil then FImages.UnRegisterChanges(FImageChangeLink); @@ -2357,6 +2408,8 @@ procedure TSpTBXTextObject.CMHintShow(var Message: TCMHintShow); // Prepare the HintBitmap SpStockHintBitmap.Canvas.Font.Assign(Screen.HintFont); + SpStockHintBitmap.Canvas.Font.Height := + MulDiv(SpStockHintBitmap.Canvas.Font.Height, CurrentPPI, Screen.PixelsPerInch); SpStockHintBitmap.Canvas.Font.Color := clInfoText; {$IF CompilerVersion >= 23} //for Delphi XE2 and up if SkinManager.GetSkinType = sknDelphiStyle then begin @@ -2523,7 +2576,7 @@ procedure TSpTBXCustomLabel.GetSize(out TotalR, TextR, GlyphR: TRect); begin inherited GetSize(TotalR, TextR, GlyphR); if FUnderline then - Inc(TotalR.Bottom, SpDPIScale(1)); + Inc(TotalR.Bottom, PPIScale(1)); end; function TSpTBXCustomLabel.IsGlassPainting: Boolean; @@ -2582,7 +2635,7 @@ procedure TSpTBXCustomLabel.CMDialogChar(var Message: TCMDialogChar); constructor TSpTBXButtonControl.Create(AOwner: TComponent); begin inherited; - ControlStyle := ControlStyle - [csDoubleClicks]; + ControlStyle := ControlStyle - [csDoubleClicks]; FGroupIndex := 0; end; @@ -2680,8 +2733,8 @@ function TSpTBXCustomCheckButton.GetGlyphSize: TSize; begin Result := inherited GetGlyphSize; if (Result.cx = 0) or (Result.cy = 0) then begin - Result.cx := SpDPIScale(13); - Result.cy := SpDPIScale(13); + Result.cx := PPIScale(13); + Result.cy := PPIScale(13); end; end; @@ -2690,8 +2743,8 @@ procedure TSpTBXCustomCheckButton.GetSize(out TotalR, TextR, GlyphR: TRect); inherited GetSize(TotalR, TextR, GlyphR); // Inc TotalR for the FocusRect if Autosize then begin - Inc(TotalR.Right, SpDPIScale(1)); - Inc(TotalR.Bottom, SpDPIScale(2)); + Inc(TotalR.Right, PPIScale(1)); + Inc(TotalR.Bottom, PPIScale(2)); end; end; @@ -2722,7 +2775,7 @@ procedure TSpTBXCustomCheckBox.DoInternalGlyphDraw(ACanvas: TCanvas; if IsImageIndexValid then inherited else - SpDrawXPCheckBoxGlyph(ACanvas, AGlyphRect, Enabled, State, MouseInControl, Pushed); + SpDrawXPCheckBoxGlyph(ACanvas, AGlyphRect, Enabled, State, MouseInControl, Pushed, CurrentPPI); end; procedure TSpTBXCustomCheckBox.AdjustFont(AFont: TFont); @@ -2751,6 +2804,22 @@ function TSpTBXCustomCheckBox.GetChecked: Boolean; Result := FState = cbChecked; end; +function TSpTBXCustomCheckBox.GetGlyphSize: TSize; +var + Details: TThemedElementDetails; +begin + if not IsImageIndexValid and HandleAllocated and (SkinManager.GetSkinType = sknDelphiStyle) then begin + // 10.4 Styles bug: GetThemedElementSize returns incorrect value when Pushed = True + // When Pushed is true it returns (13, 13), when false it returns the correct value (16,16) + // Check Vcl.Styles.TCustomStyle.DoGetElementSize, the problem might be in the vsf file itself + CurrentSkin.GetThemedElementDetails(skncCheckBox, Enabled, False, MouseInControl, State = cbChecked, False, False, State = cbGrayed, Details); + // CurrentPPI introduced on 10.3 Rio, but we are using TB2Common.TControlHelper + Result := CurrentSkin.GetThemedElementSize(Canvas, Details, CurrentPPI); // returns a scaled value + if not ((Result.cx = 0) and (Result.cy = 0)) then Exit; + end; + Result := inherited GetGlyphSize; +end; + procedure TSpTBXCustomCheckBox.SetChecked(Value: Boolean); begin if (Checked <> Value) or (FState = cbGrayed) then begin @@ -2800,7 +2869,24 @@ procedure TSpTBXCustomRadioButton.DoInternalGlyphDraw(ACanvas: TCanvas; if IsImageIndexValid then inherited else - SpDrawXPRadioButtonGlyph(ACanvas, AGlyphRect, Enabled, Checked, MouseInControl, Pushed); + SpDrawXPRadioButtonGlyph(ACanvas, AGlyphRect, Enabled, Checked, MouseInControl, Pushed, CurrentPPI); +end; + +function TSpTBXCustomRadioButton.GetGlyphSize: TSize; +var + Details: TThemedElementDetails; +begin + if not IsImageIndexValid and HandleAllocated and (SkinManager.GetSkinType = sknDelphiStyle) then begin + // 10.4 Styles bug: GetThemedElementSize returns incorrect value when Pushed = True + // When Pushed is true it returns (13, 13), when false it returns the correct value (16,16) + // Check Vcl.Styles.TCustomStyle.DoGetElementSize, the problem might be in the vsf file itself + CurrentSkin.GetThemedElementDetails(skncRadioButton, Enabled, False, MouseInControl, Checked, False, False, False, Details); + // CurrentPPI introduced on 10.3 Rio, but we are using TB2Common.TControlHelper + // GetThemedElementSize returns a scaled value + Result := CurrentSkin.GetThemedElementSize(Canvas, Details, CurrentPPI); + if not ((Result.cx = 0) and (Result.cy = 0)) then Exit; + end; + Result := inherited GetGlyphSize; end; procedure TSpTBXCustomRadioButton.AdjustFont(AFont: TFont); @@ -3250,9 +3336,9 @@ function TSpTBXCustomButton.DoDrawDropDownArrow(ACanvas: TCanvas; R := ARect; R.Left := R.Right - GetTextMargins.Right; - P.X := (R.Left + R.Right) div 2 - SpDPIScale(1); - P.Y := (R.Top + R.Bottom) div 2 - SpDPIScale(1); - SpDrawArrow(ACanvas, P.X, P.Y, ACanvas.Font.Color, True, False, SpDPIScale(2)); + P.X := (R.Left + R.Right) div 2 - PPIScale(1); + P.Y := (R.Top + R.Bottom) div 2 - PPIScale(1); + SpDrawArrow(ACanvas, P.X, P.Y, ACanvas.Font.Color, True, False, PPIScale(2)); end; end; @@ -3284,14 +3370,14 @@ function TSpTBXCustomButton.DoDrawItem(ACanvas: TCanvas; ARect: TRect; else begin if Flat and FToolbarStyle then begin State := CurrentSkin.GetState(Enabled, Pushed, MouseInControl, Checked); - SpDrawXPToolbarButton(ACanvas, ARect, State); + SpDrawXPToolbarButton(ACanvas, ARect, State, cpNone, CurrentPPI); end else begin if SkinManager.GetSkinType = sknSkin then Defaulted := False else Defaulted := FActive; - SpDrawXPButton(ACanvas, ARect, Enabled, Pushed, MouseInControl, Checked, False, Defaulted); + SpDrawXPButton(ACanvas, ARect, Enabled, Pushed, MouseInControl, Checked, False, Defaulted, CurrentPPI); end; end; end; @@ -3329,9 +3415,9 @@ function TSpTBXCustomButton.GetTextMargins: TRect; const ArrowWidth = 5; begin - Result := Rect(SpDPIScale(8), SpDPIScale(2), SpDPIScale(8), SpDPIScale(2)); + Result := Rect(PPIScale(8), PPIScale(2), PPIScale(8), PPIScale(2)); if FDropDownArrow and Assigned(FDropdownMenu) then - Inc(Result.Right, SpDPIScale(ArrowWidth+4)); + Inc(Result.Right, PPIScale(ArrowWidth+4)); end; function TSpTBXCustomButton.IsDroppedDown: Boolean; @@ -3570,7 +3656,7 @@ function TSpTBXCustomProgressBar.DoDrawItem(ACanvas: TCanvas; ARect: TRect; begin Result := inherited DoDrawItem(ACanvas, ARect, PaintStage); if Result and (PaintStage = pstPrePaint) then begin - I := SpDrawXPProgressBar(ACanvas, ARect, FVertical, FSmooth, FProgressVisible, FMin, FMax, FPosition); + I := SpDrawXPProgressBar(ACanvas, ARect, FVertical, FSmooth, FProgressVisible, FMin, FMax, FPosition, CurrentPPI); case FCaptionType of pctNone: Caption := ''; pctPercentage: Caption := IntToStr(I) + '%'; @@ -3586,7 +3672,7 @@ procedure TSpTBXCustomProgressBar.DoProgressChange; function TSpTBXCustomProgressBar.GetTextMargins: TRect; begin - Result := Rect(SpDPIScale(8), SpDPIScale(2), SpDPIScale(8), SpDPIScale(2)); + Result := Rect(PPIScale(8), PPIScale(2), PPIScale(8), PPIScale(2)); end; procedure TSpTBXCustomProgressBar.SetCaptionType(const Value: TSpTBXProgressCaption); @@ -3753,7 +3839,11 @@ procedure TSpTBXTrackBar.DrawTicks(ACanvas: TCanvas); sknNone: ACanvas.Pen.Color := clBlack; sknWindows, sknDelphiStyle: + {$IF CompilerVersion >= 23} // for Delphi XE2 and up + ACanvas.Pen.Color := SpTBXThemeServices.GetSystemColor(clBtnText); + {$ELSE} ACanvas.Pen.Color := clBtnShadow; + {$IFEND} sknSkin: if CurrentSkin.Options(skncTrackBar, sknsNormal).TextColor <> clNone then ACanvas.Pen.Color := CurrentSkin.Options(skncTrackBar, sknsNormal).TextColor @@ -3763,8 +3853,8 @@ procedure TSpTBXTrackBar.DrawTicks(ACanvas: TCanvas); SendMessage(Self.Handle, TBM_GETTHUMBRECT, 0, LPARAM(@ThumbR)); ChannelR := ChannelRect; - FirstTickSize := SpDPIScale(4); - TickSize := SpDPIScale(3); + FirstTickSize := PPIScale(4); + TickSize := PPIScale(3); Y := 0; if Orientation = trHorizontal then begin @@ -3774,27 +3864,27 @@ procedure TSpTBXTrackBar.DrawTicks(ACanvas: TCanvas); case TickMarks of tmxBottomRight: begin - Y := ThumbR.Bottom + SpDPIScale(1); - FirstTickSize := SpDPIScale(4); - TickSize := SpDPIScale(3); + Y := ThumbR.Bottom + PPIScale(1); + FirstTickSize := PPIScale(4); + TickSize := PPIScale(3); end; tmxTopLeft: begin - Y := ThumbR.Top - SpDPIScale(2); - FirstTickSize := -SpDPIScale(4); - TickSize := -SpDPIScale(3); + Y := ThumbR.Top - PPIScale(2); + FirstTickSize := -PPIScale(4); + TickSize := -PPIScale(3); end; tmxBoth: begin - Y := ThumbR.Top - SpDPIScale(2); - FirstTickSize := -SpDPIScale(4); - TickSize := -SpDPIScale(3); + Y := ThumbR.Top - PPIScale(2); + FirstTickSize := -PPIScale(4); + TickSize := -PPIScale(3); end; tmxCenter: begin Y := ChannelR.Top + (ChannelR.Bottom - ChannelR.Top) div 2; - FirstTickSize := SpDPIScale(2); - TickSize := SpDPIScale(2); + FirstTickSize := PPIScale(2); + TickSize := PPIScale(2); end; end; for I := 0 to Count - 1 do @@ -3822,27 +3912,27 @@ procedure TSpTBXTrackBar.DrawTicks(ACanvas: TCanvas); case TickMarks of tmxBottomRight: begin - Y := ThumbR.Right + SpDPIScale(1); - FirstTickSize := SpDPIScale(4); - TickSize := SpDPIScale(3); + Y := ThumbR.Right + PPIScale(1); + FirstTickSize := PPIScale(4); + TickSize := PPIScale(3); end; tmxTopLeft: begin - Y := ThumbR.Left - SpDPIScale(2); - FirstTickSize := -SpDPIScale(4); - TickSize := -SpDPIScale(3); + Y := ThumbR.Left - PPIScale(2); + FirstTickSize := -PPIScale(4); + TickSize := -PPIScale(3); end; tmxBoth: begin - Y := ThumbR.Left - SpDPIScale(2); - FirstTickSize := -SpDPIScale(4); - TickSize := -SpDPIScale(3); + Y := ThumbR.Left - PPIScale(2); + FirstTickSize := -PPIScale(4); + TickSize := -PPIScale(3); end; tmxCenter: begin Y := ChannelR.Left + (ChannelR.Right - ChannelR.Left) div 2; - FirstTickSize := SpDPIScale(2); - TickSize := SpDPIScale(2); + FirstTickSize := PPIScale(2); + TickSize := PPIScale(2); end; end; for I := 0 to Count - 1 do @@ -3956,22 +4046,11 @@ procedure TSpTBXTrackBar.CNNotify(var Message: TWMNotify); TBCD_THUMB: begin if SliderVisible then begin - // VCL Styles doesn't stretch draw the trackbar thumb, sometimes it's - // bigger than the rect we get from TBM_GETTHUMBRECT (it has a custom - // size depending on the style), which causes painting issues. - // We need to clip the painting region. SendMessage(Handle, TBM_GETTHUMBRECT, 0, LPARAM(@R)); - Rgn := CreateRectRgn(R.Left, R.Top, R.Right, R.Bottom); - SelectClipRgn(ACanvas.Handle, Rgn); - try - if DoDrawThumb(ACanvas, R, pstPrePaint) then - SpDrawXPTrackBar(ACanvas, R, TBCD_THUMB, Orientation = trVertical, False, GetThumbState, FTickMarks, Min, Max, SelStart, SelEnd); - DoDrawThumb(ACanvas, R, pstPostPaint); - Message.Result := CDRF_SKIPDEFAULT; - finally - DeleteObject(Rgn); - SelectClipRgn(ACanvas.Handle, 0); - end; + if DoDrawThumb(ACanvas, R, pstPrePaint) then + SpDrawXPTrackBar(ACanvas, R, TBCD_THUMB, Orientation = trVertical, False, GetThumbState, FTickMarks, Min, Max, SelStart, SelEnd, CurrentPPI); + DoDrawThumb(ACanvas, R, pstPostPaint); + Message.Result := CDRF_SKIPDEFAULT; end; end; TBCD_CHANNEL: @@ -3979,7 +4058,7 @@ procedure TSpTBXTrackBar.CNNotify(var Message: TWMNotify); SendMessage(Handle, TBM_GETTHUMBRECT, 0, LPARAM(@R)); Offset := 0; if Focused then - Offset := SpDPIScale(1); + Offset := PPIScale(1); if Orientation = trHorizontal then begin R.Left := ClientRect.Left + Offset; R.Right := ClientRect.Right - Offset; @@ -3995,7 +4074,7 @@ procedure TSpTBXTrackBar.CNNotify(var Message: TWMNotify); SpDrawParentBackground(Self, ACanvas.Handle, ClientRect); R := ChannelRect; if DoDrawChannel(ACanvas, R, pstPrePaint) then - SpDrawXPTrackBar(ACanvas, R, TBCD_CHANNEL, Orientation = trVertical, FCanDrawChannelSelection, sknsNormal, FTickMarks, Min, Max, SelStart, SelEnd); + SpDrawXPTrackBar(ACanvas, R, TBCD_CHANNEL, Orientation = trVertical, FCanDrawChannelSelection, sknsNormal, FTickMarks, Min, Max, SelStart, SelEnd, CurrentPPI); DoDrawChannel(ACanvas, R, pstPostPaint); // Draw channel tics @@ -4018,6 +4097,38 @@ procedure TSpTBXTrackBar.CNNotify(var Message: TWMNotify); end; end; +procedure TSpTBXTrackBar.CNHScroll(var Message: TWMHScroll); +begin + inherited; + InvalidateBackground; +end; + +procedure TSpTBXTrackBar.CNVScroll(var Message: TWMVScroll); +begin + inherited; + InvalidateBackground; +end; + +procedure TSpTBXTrackBar.WMLButtonDown(var Message: TWMMouse); +var + R: TRect; +begin + inherited; + if GetWindowLong(Handle, GWL_STYLE) and TBS_NOTHUMB = 0 then + begin + SendMessage(Handle, TBM_GETTHUMBRECT, 0, LPARAM(@R)); + if PtInRect(R, Point(Message.XPos, Message.YPos)) then + InvalidateBackground; + end; +end; + +procedure TSpTBXTrackBar.WMLButtonUp(var Message: TWMMouse); +begin + inherited; + if GetWindowLong(Handle, GWL_STYLE) and TBS_NOTHUMB = 0 then + InvalidateBackground; +end; + procedure TSpTBXTrackBar.WMEraseBkGnd(var Message: TMessage); begin if SkinManager.GetSkinType <> sknNone then diff --git a/Source/SpTBXCustomizer.pas b/Source/SpTBXCustomizer.pas index d84c465..d2a10da 100644 --- a/Source/SpTBXCustomizer.pas +++ b/Source/SpTBXCustomizer.pas @@ -1,7 +1,7 @@ unit SpTBXCustomizer; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -38,7 +38,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -216,7 +216,7 @@ function SpCreateUniqueSeparator(Blank: Boolean): TSpTBXSeparatorItem; implementation uses - TypInfo, Registry, Menus, ActnList, Themes, TB2ExtItems, + TypInfo, Registry, Menus, ActnList, Themes, TB2ExtItems, TB2Common, SpTBXTabs, SpTBXDkPanels, SpTBXCustomizerForm; type @@ -555,16 +555,31 @@ procedure SpLoadFormState(Form: TCustomForm; OptionsList: TStrings); var WState: TWindowState; R: TRect; + DPI: Integer; begin if Assigned(Form) then begin WState := TWindowState(GetEnumValue(TypeInfo(TWindowState), OptionsList.Values[rvMainFormWindowState])); if (WState < Low(WState)) or (WState > High(WState)) then WState := Form.WindowState; // Failed reading from string, leave the default value - if SpStringToRect(OptionsList.Values[rvMainFormBounds], R) then - Form.SetBounds(R.Left, R.Top, R.Right, R.Bottom); + // Read the saved DPI and scale + DPI := StrToIntDef(OptionsList.Values[rvDPI], 96); + if SpStringToRect(OptionsList.Values[rvMainFormBounds], R) then begin + Form.SetBounds( + MulDiv(R.Left, Form.CurrentPPI, DPI), + MulDiv(R.Top, Form.CurrentPPI, DPI), + MulDiv(R.Right, Form.CurrentPPI, DPI), + MulDiv(R.Bottom, Form.CurrentPPI, DPI)); + end; - if not SpStringToRect(OptionsList.Values[rvMainFormRestoreBounds], R) then + if SpStringToRect(OptionsList.Values[rvMainFormRestoreBounds], R) then begin + R := Rect( + MulDiv(R.Left, Form.CurrentPPI, DPI), + MulDiv(R.Top, Form.CurrentPPI, DPI), + MulDiv(R.Right, Form.CurrentPPI, DPI), + MulDiv(R.Bottom, Form.CurrentPPI, DPI)); + end + else R := Rect(Form.Left, Form.Top, Form.Width, Form.Height); // Failed reading from string, leave the default value SpSetFormWindowState(Form, WState, R); @@ -1028,7 +1043,7 @@ procedure TSpTBXCustomizer.Save(IniFile: TCustomIniFile; SaveLastLayout: Boolean if TStyleManager.IsCustomStyleActive then ExtraL.Values[rvVCLStyle] := TStyleManager.ActiveStyle.Name; {$IFEND} - + ExtraL.Values[rvDPI] := IntToStr(Application.MainForm.CurrentPPI); if FSaveFormState then SpSaveFormState(Application.MainForm, ExtraL); DoSave(ExtraL); diff --git a/Source/SpTBXCustomizerForm.pas b/Source/SpTBXCustomizerForm.pas index 9fb8180..342805d 100644 --- a/Source/SpTBXCustomizerForm.pas +++ b/Source/SpTBXCustomizerForm.pas @@ -39,7 +39,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -117,7 +117,7 @@ TSpTBXCustomizeForm = class(TSpTBXCustomCustomizeForm) implementation uses - ActnList, Themes; + ActnList, Themes, TB2Common; {$R *.dfm} @@ -139,7 +139,7 @@ procedure SpDrawListboxItem(L: TSpTBXListBox; Index: Integer; ARect: TRect; ACanvas := L.Canvas; // Draw the icon image - Inc(ARect.Left, SpDPIScale(2)); // Apply margins + Inc(ARect.Left, L.PPIScale(2)); // Apply margins if Item.ImageIndex > -1 then begin IL := Item.Images; if not Assigned(IL) then @@ -149,11 +149,11 @@ procedure SpDrawListboxItem(L: TSpTBXListBox; Index: Integer; ARect: TRect; ILRect := Bounds(ARect.Left, ARect.Top + Y, IL.Width, IL.Height); // Draw icon shadow if odSelected in State then begin - OffsetRect(ILRect, SpDPIScale(1), SpDPIScale(1)); - SpDrawImageList(ACanvas, ILRect, IL, Item.ImageIndex, False, True); - OffsetRect(ILRect, SpDPIScale(-2), SpDPIScale(-2)); + OffsetRect(ILRect, L.PPIScale(1), L.PPIScale(1)); + SpDrawVirtualImageList(ACanvas, ILRect, IL, Item.ImageIndex, False); + OffsetRect(ILRect, L.PPIScale(-2), L.PPIScale(-2)); end; - SpDrawImageList(ACanvas, ILRect, IL, Item.ImageIndex, True, True); + SpDrawVirtualImageList(ACanvas, ILRect, IL, Item.ImageIndex, True); end; end; @@ -184,7 +184,7 @@ procedure TSpTBXCustomizeForm.FormCreate(Sender: TObject); // Setup the listboxes if Assigned(Customizer.Images) then begin - lbCommands.ItemHeight := Customizer.Images.Height + SpDPIScale(4); + lbCommands.ItemHeight := Customizer.Images.Height + PPIScale(4); lbShortcuts.ItemHeight := lbCommands.ItemHeight; end; // Hide the Icon Options combobox if necessary diff --git a/Source/SpTBXDefaultSkins.pas b/Source/SpTBXDefaultSkins.pas index 6fa1e6b..6bc572d 100644 --- a/Source/SpTBXDefaultSkins.pas +++ b/Source/SpTBXDefaultSkins.pas @@ -1,7 +1,7 @@ unit SpTBXDefaultSkins; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -38,7 +38,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -50,11 +50,8 @@ interface TSpTBXAluminumColors = array[0..3] of TColor; TSpTBXAluminumSkin = class(TSpTBXSkinOptions) - private - procedure SetDefaultColorScheme(const Value: TSpTBXLunaScheme); protected FColors: TSpTBXAluminumColors; - FDefaultColorScheme: TSpTBXLunaScheme; FLightMetalColor: TColor; FDarkMetalColor: TColor; FRoughness: Integer; @@ -67,7 +64,6 @@ TSpTBXAluminumSkin = class(TSpTBXSkinOptions) procedure PaintBackground(ACanvas: TCanvas; ARect: TRect; Component: TSpTBXSkinComponentsType; State: TSpTBXSkinStatesType; Background, Borders: Boolean; Vertical: Boolean = False; ForceRectBorders: TAnchors = []); override; property LightMetalColor: TColor read FLightMetalColor write FLightMetalColor; property DarkMetalColor: TColor read FDarkMetalColor write FDarkMetalColor; - property DefaultColorScheme: TSpTBXLunaScheme read FDefaultColorScheme write SetDefaultColorScheme default lusUnknown; end; TSpTBXAthenSkin = class(TSpTBXSkinOptions) @@ -112,16 +108,11 @@ TSpTBXOfficeXPSkin = class(TSpTBXSkinOptions) TSpTBXOffice2003Colors = array[0..22] of TColor; TSpTBXOffice2003Skin = class(TSpTBXSkinOptions) - private - procedure SetDefaultColorScheme(const Value: TSpTBXLunaScheme); protected FColors: TSpTBXOffice2003Colors; - FDefaultColorScheme: TSpTBXLunaScheme; procedure FillColors; virtual; public - constructor Create; override; procedure FillOptions; override; - property DefaultColorScheme: TSpTBXLunaScheme read FDefaultColorScheme write SetDefaultColorScheme default lusUnknown; end; TSpTBXOffice2007Colors = array[0..17] of TColor; @@ -413,7 +404,6 @@ procedure BrushedFill(DC: HDC; Origin: PPoint; ARect: TRect; Color: TColor; Roug constructor TSpTBXAluminumSkin.Create; begin FRoughness := 12; - FDefaultColorScheme := lusUnknown; inherited; end; @@ -424,34 +414,11 @@ destructor TSpTBXAluminumSkin.Destroy; end; procedure TSpTBXAluminumSkin.FillColors; -const - AluminumColors: array[lusBlue..lusGreen] of TSpTBXAluminumColors = ( - ($C56A31, // 0: Item borders - $E0D7D1, // 1: Item Checked - $E2B598, // 2: Item Pushed - $EED2C1), // 3: Item HotTrack - - ($BFB4B2, // 0: Item borders - $DDDCDC, // 1: Item Checked - $DFDAD9, // 2: Item Pushed - $ECE9E8), // 3: Item HotTrack - - ($70A093, // 0: Item borders - $D8DCDB, // 1: Item Checked - $B8D0C9, // 2: Item Pushed - $D4E3DF) // 3: Item HotTrack - ); -var - Luna: TSpTBXLunaScheme; begin - if FDefaultColorScheme <> lusUnknown then - Luna := FDefaultColorScheme - else begin - Luna := SpGetLunaScheme; - if Luna = lusUnknown then Luna := lusMetallic; - end; - - FColors := AluminumColors[Luna]; + FColors[0] := $BFB4B2; // 0: Item borders + FColors[1] := $DDDCDC; // 1: Item Checked + FColors[2] := $DFDAD9; // 2: Item Pushed + FColors[3] := $ECE9E8; // 3: Item HotTrack FRoughness := 12; FLightMetalColor := $C7C7C7; FDarkMetalColor := $DFDFDF; @@ -630,15 +597,6 @@ procedure TSpTBXAluminumSkin.PaintBackground(ACanvas: TCanvas; ARect: TRect; end; end; -procedure TSpTBXAluminumSkin.SetDefaultColorScheme(const Value: TSpTBXLunaScheme); -begin - if FDefaultColorScheme <> Value then begin - FDefaultColorScheme := Value; - Reset; - FillOptions; - end; -end; - //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { TSpTBXAthenSkin } @@ -1657,119 +1615,50 @@ procedure TSpTBXOfficeXPSkin.FillOptions; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { TSpTBXOffice2003Skin } -constructor TSpTBXOffice2003Skin.Create; -begin - FDefaultColorScheme := lusUnknown; - inherited; -end; - procedure TSpTBXOffice2003Skin.FillColors; -const - Office2003Colors: array[lusBlue..lusGreen] of TSpTBXOffice2003Colors = ( - ($F5BE9E, $F9D9C3, // 0, 1: Dock - $FEECDD, $E2A981, // 2, 3: Toolbar - $CB8C6A, $F5BE9E, // 4, 5: Toolbar borders - $F6F6F6, // 6: Popup - $962D00, // 7: Popup borders - $800000, // 8: Item borders - $C9662A, // 9: Window borders - $8CD5FF, $55ADFF, // 10, 11: Item Checked - $4E91FE, $8ED3FF, // 12, 13: Item Pushed - $CCF4FF, $91D0FF, // 14, 15: Item HotTrack - $FFEFE3, $E7B593, // 16, 17: OpenToolbarItem - $91420D, // 18: Button external border - $FBD0B3, $CB8C6A, // 19, 20: Button internal borders - $FEECDD, // 21: Grip/Separator soft color - $E2A981), // 22: Panel/CheckBox/Tabs/ProgressBar/TrackBar borders - - ($E5D7D7, $F7F3F3, // 0, 1: Dock - $FAF4F3, $B59799, // 2, 3: Toolbar - $8F6D6E, $E5D7D7, // 4, 5: Toolbar borders - $FFFAFD, // 6: Popup - $947C7C, // 7: Popup borders - $6F4B4B, // 8: Item borders - $99797A, // 9: Window borders - $8CD5FF, $55ADFF, // 10, 11: Item Checked - $4E91FE, $8ED3FF, // 12, 13: Item Pushed - $CCF4FF, $91D0FF, // 14, 15: Item HotTrack - $F1E9E8, $CDB9BA, // 16, 17: OpenToolbarItem - $988B8A, // 18: Button external border - clWhite, $B0A7A6, // 19, 20: Button internal borders - $FFFFFF, // 21: Grip/Separator soft color - $B59799), // 22: Panel/CheckBox/Tabs/ProgressBar/TrackBar borders - - ($A7D9D9, $E4F2F0, // 0, 1: Dock - $DEF7F4, $91C6B7, // 2, 3: Toolbar - $588060, $A7D9D9, // 4, 5: Toolbar borders - $EEF4F4, // 6: Popup - $5E8D75, // 7: Popup borders - $385D3F, // 8: Item borders - $5E8674, // 9: Window borders - $8CD5FF, $55ADFF, // 10, 11: Item Checked - $4E91FE, $8ED3FF, // 12, 13: Item Pushed - $CCF4FF, $91D0FF, // 14, 15: Item HotTrack - $D5F0EC, $9FCEC2, // 16, 17: OpenToolbarItem - $5B8479, // 18: Button external border - $E3FFFA, $86ADAA, // 19, 20: Button internal borders - $DEF7F4, // 21: Grip/Separator soft color - $91C6B7) // 22: Panel/CheckBox/Tabs/ProgressBar/TrackBar borders - ); -var - Luna: TSpTBXLunaScheme; begin - if FDefaultColorScheme <> lusUnknown then - Luna := FDefaultColorScheme - else - Luna := SpGetLunaScheme; - - if Luna <> lusUnknown then - FColors := Office2003Colors[Luna] - else begin - // Use adapted colors - // 0, 1: Dock - FColors[0] := clBtnFace; - FColors[1] := SpBlendColors(clBtnFace, clWindow, 35); - // 2, 3: Toolbar - FColors[2] := SpBlendColors(clBtnFace, clWindow, 20); - FColors[3] := SpBlendColors(clBtnFace, clWindow, 95); - // 4, 5: Toolbar borders - FColors[4] := SpBlendColors(clBtnShadow, clWindow, 70); - FColors[5] := SpBlendColors(clBtnFace, clWindow, 62); - // 6: Popup - FColors[6] := SpBlendColors(clBtnFace, clWindow, 15); - // 7: Popup borders - FColors[7] := SpBlendColors(clBtnFace, clBtnShadow, 20); - // 8: Item borders - FColors[8] := clHighlight; - // 9: Window borders - FColors[9] := SpBlendColors(clBtnText, clBtnShadow, 15); - // 10, 11: Item Checked - FColors[10] := SpBlendColors(clHighlight, SpBlendColors(clBtnFace, clWindow, 50), 10); - FColors[11] := FColors[10]; - // 12, 13: Item Pushed - FColors[12] := SpBlendColors(clHighlight, clWindow, 50); - FColors[13] := FColors[12]; - // 14, 15: Item HotTrack - FColors[14] := SpBlendColors(clHighlight, clWindow, 30); - FColors[15] := FColors[14]; - // 16, 17: OpenToolbarItem - FColors[16] := SpBlendColors(clBtnFace, clWindow, 16); - FColors[17] := SpBlendColors(clBtnFace, clWindow, 42); - // 18: Button external border - FColors[18] := FColors[4]; - // 19, 20: Button internal borders - FColors[19] := FColors[5]; - FColors[20] := SpBlendColors(clBtnShadow, clWindow, 40); - // 21: Grip/Separator soft color - FColors[21] := clWhite; - // 22: Panel/CheckBox/Tabs/ProgressBar/TrackBar borders - FColors[22] := SpBlendColors(clBtnShadow, clWindow, 70); - end; + // Use adapted colors + // 0, 1: Dock + FColors[0] := clBtnFace; + FColors[1] := SpBlendColors(clBtnFace, clWindow, 35); + // 2, 3: Toolbar + FColors[2] := SpBlendColors(clBtnFace, clWindow, 20); + FColors[3] := SpBlendColors(clBtnFace, clWindow, 95); + // 4, 5: Toolbar borders + FColors[4] := SpBlendColors(clBtnShadow, clWindow, 70); + FColors[5] := SpBlendColors(clBtnFace, clWindow, 62); + // 6: Popup + FColors[6] := SpBlendColors(clBtnFace, clWindow, 15); + // 7: Popup borders + FColors[7] := SpBlendColors(clBtnFace, clBtnShadow, 20); + // 8: Item borders + FColors[8] := clHighlight; + // 9: Window borders + FColors[9] := SpBlendColors(clBtnText, clBtnShadow, 15); + // 10, 11: Item Checked + FColors[10] := SpBlendColors(clHighlight, SpBlendColors(clBtnFace, clWindow, 50), 10); + FColors[11] := FColors[10]; + // 12, 13: Item Pushed + FColors[12] := SpBlendColors(clHighlight, clWindow, 50); + FColors[13] := FColors[12]; + // 14, 15: Item HotTrack + FColors[14] := SpBlendColors(clHighlight, clWindow, 30); + FColors[15] := FColors[14]; + // 16, 17: OpenToolbarItem + FColors[16] := SpBlendColors(clBtnFace, clWindow, 16); + FColors[17] := SpBlendColors(clBtnFace, clWindow, 42); + // 18: Button external border + FColors[18] := FColors[4]; + // 19, 20: Button internal borders + FColors[19] := FColors[5]; + FColors[20] := SpBlendColors(clBtnShadow, clWindow, 40); + // 21: Grip/Separator soft color + FColors[21] := clWhite; + // 22: Panel/CheckBox/Tabs/ProgressBar/TrackBar borders + FColors[22] := SpBlendColors(clBtnShadow, clWindow, 70); end; procedure TSpTBXOffice2003Skin.FillOptions; -var - IsUnknownLuna: Boolean; begin //---- Skin Properties ----// @@ -1779,7 +1668,6 @@ procedure TSpTBXOffice2003Skin.FillOptions; //---- Colors ----// FillColors; - IsUnknownLuna := FColors[0] = clBtnFace; //---- Single State ----// Options(skncDock, sknsNormal).Body.Fill(2, FColors[0], FColors[1], clNone, clNone); @@ -1807,8 +1695,7 @@ procedure TSpTBXOffice2003Skin.FillOptions; Options(skncWindow, sknsNormal).Borders.Fill(0, FColors[9], FColors[9], FColors[9], FColors[9]); Options(skncWindowTitleBar, sknsNormal).Body.Fill(0, FColors[9], clNone, clNone, clNone); - if IsUnknownLuna then - Options(skncWindowTitleBar, sknsNormal).TextColor := clBtnHighlight; + Options(skncWindowTitleBar, sknsNormal).TextColor := clBtnHighlight; //---- Elements ----// Options(skncGutter, sknsNormal).Body.Fill(2, FColors[2], FColors[3], clNone, clNone); @@ -1912,15 +1799,6 @@ procedure TSpTBXOffice2003Skin.FillOptions; Options(skncHeader, sknsHotTrack).Borders.Fill(0, FColors[19], FColors[20], clNone, clNone); end; -procedure TSpTBXOffice2003Skin.SetDefaultColorScheme(const Value: TSpTBXLunaScheme); -begin - if FDefaultColorScheme <> Value then begin - FDefaultColorScheme := Value; - Reset; - FillOptions; - end; -end; - //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { TSpTBXOffice2007Skin } diff --git a/Source/SpTBXDkPanels.pas b/Source/SpTBXDkPanels.pas index 3e32f53..a5585f2 100644 --- a/Source/SpTBXDkPanels.pas +++ b/Source/SpTBXDkPanels.pas @@ -1,7 +1,7 @@ unit SpTBXDkPanels; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -50,7 +50,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -59,6 +59,9 @@ interface TB2Item, TB2Dock, TB2Toolbar, SpTBXSkins, SpTBXItem, SpTBXControls; +const + CM_SPCHANGESCALE = CM_BASE + 2244; // Message sent to the controls to update its scaling + type TSpTBXCustomDockablePanel = class; TSpTBXCustomSplitter = class; @@ -100,8 +103,13 @@ TSpTBXCustomMultiDock = class(TTBDock) procedure UpdateDPLateralSize(AWidth, AHeight: Integer); procedure SetPosition(const Value: TSpTBXDockPosition); procedure SetLimitToOneRow(const Value: Boolean); + procedure CMSPChangeScale(var Message: TMessage); message CM_SPCHANGESCALE; protected procedure AlignControls(AControl: TControl; var Rect: TRect); override; + {$IF CompilerVersion >= 27} // for Delphi XE6 and up + function DefaultScalingFlags: TScalingFlags; override; + {$IFEND} + procedure ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); override; procedure DoInsertRemoveBar(Sender: TObject; Inserting: Boolean; Bar: TTBCustomDockableWindow); virtual; // OnInsertRemoveBar is republished procedure DoRequestDock(Sender: TObject; Bar: TTBCustomDockableWindow; var Accept: Boolean); virtual; // OnRequestDock is republished procedure Loaded; override; @@ -217,7 +225,7 @@ TSpTBXCustomDockablePanel = class(TSpTBXCustomToolWindow, ITBItems) FDockForms: TList; // Component - procedure ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); override; + procedure ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); override; procedure CreateParams(var Params: TCreateParams); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Loaded; override; @@ -378,7 +386,7 @@ TSpTBXCustomSplitter = class(TCustomControl) procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND; protected FRestorePos: Integer; - procedure ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); override; + procedure ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); override; procedure DoDrawBackground(ACanvas: TCanvas; ARect: TRect; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual; procedure DoMoved; virtual; function DoMoving(var NewSize: Integer): Boolean; virtual; @@ -441,7 +449,7 @@ TSpTBXSplitter = class(TSpTBXCustomSplitter) end; { Painting helpers } -procedure SpDrawXPDockablePanelTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive, Vertical: Boolean); +procedure SpDrawXPDockablePanelTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive, Vertical: Boolean; DPI: Integer); procedure SpDrawXPDockablePanelBody(ACanvas: TCanvas; ARect: TRect; IsActive, IsFloating: Boolean); { Toolbar Load/Save Position helpers } @@ -456,7 +464,7 @@ implementation uses Types, - {$IF CompilerVersion >= 25} // for Delphi XE4 and up + {$IF CompilerVersion >= 24} // for Delphi XE3 and up System.UITypes, {$IFEND} Themes, ComCtrls, Registry, TB2Consts, TB2Common; @@ -884,10 +892,9 @@ function SpDPResize(DP: TSpTBXCustomDockablePanel; NewSize: Integer; ResizeType: Exit; if MultiDock.IsVertical then - MinSize := DPSibling.MinClientHeight + (CDefaultToolbarBorderSize * 2) + MinSize := DPSibling.MinClientHeight + (DP.DockedBorderSize * 2) else - MinSize := DPSibling.MinClientWidth + (CDefaultToolbarBorderSize * 2); - + MinSize := DPSibling.MinClientWidth + (DP.DockedBorderSize * 2); // If DP can't be resized find another sibling if not (csDesigning in MultiDock.ComponentState) and DP.FixedDockedSize then begin if MultiDock.IsVertical then @@ -903,16 +910,16 @@ function SpDPResize(DP: TSpTBXCustomDockablePanel; NewSize: Integer; ResizeType: if MultiDock.IsVertical then begin NewSize := DP.Height - Delta; - if (DPSibling.Height + Delta < DPSibling.MinClientHeight + (CDefaultToolbarBorderSize * 2)) or - (NewSize < DP.MinClientHeight + (CDefaultToolbarBorderSize * 2)) then + if (DPSibling.Height + Delta < DPSibling.MinClientHeight + (DP.DockedBorderSize * 2)) or + (NewSize < DP.MinClientHeight + (DP.DockedBorderSize * 2)) then begin Exit; end; end else begin NewSize := DP.Width - Delta; - if (DPSibling.Width + Delta < DPSibling.MinClientWidth + (CDefaultToolbarBorderSize * 2)) or - (NewSize < DP.MinClientWidth + (CDefaultToolbarBorderSize * 2)) then + if (DPSibling.Width + Delta < DPSibling.MinClientWidth + (DP.DockedBorderSize * 2)) or + (NewSize < DP.MinClientWidth + (DP.DockedBorderSize * 2)) then begin Exit; end; @@ -1043,7 +1050,7 @@ function SpPtInDP(P: TPoint; MultiDock: TSpTBXCustomMultiDock; OnlyOnTitleBar: B //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Painting helpers } -procedure SpDrawXPDockablePanelTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive, Vertical: Boolean); +procedure SpDrawXPDockablePanelTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive, Vertical: Boolean; DPI: Integer); var Details: TThemedElementDetails; begin @@ -1057,7 +1064,7 @@ procedure SpDrawXPDockablePanelTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive end; sknDelphiStyle: if CurrentSkin.GetThemedElementDetails(skncDockablePanelTitleBar, sknsNormal, Details) then - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); sknSkin: CurrentSkin.PaintBackground(ACanvas, ARect, skncDockablePanelTitleBar, sknsNormal, True, True, Vertical); end; @@ -1079,7 +1086,7 @@ procedure SpDrawXPDockablePanelBody(ACanvas: TCanvas; ARect: TRect; IsActive, Is if not IsFloating then begin ACanvas.Brush.Color := clBtnFace; ACanvas.FrameRect(ARect); - InflateRect(ARect, -SpDPIScale(1), -SpDPIScale(1)); + InflateRect(ARect, -1, -1); // do not scale ACanvas.Brush.Color := clWhite; ACanvas.FrameRect(ARect); end; @@ -1105,7 +1112,7 @@ procedure SpDrawXPDockablePanelBody(ACanvas: TCanvas; ARect: TRect; IsActive, Is //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Toolbar Load/Save Position helpers } -procedure SpTBUpdateMultiDocksAfterLoad(const M: TSpTBXMultiDock); +procedure SpTBUpdateMultiDocksAfterLoad(const M: TSpTBXCustomMultiDock); // TBCustomLoadPositions doesn't correctly position the DPs after they are loaded. // To reproduce: // 1) Drop a top aligned MultiDock with 3 DPs (DP1, DP2, DP3), and drop a left @@ -1327,7 +1334,7 @@ procedure SpTBIniLoadPositions(const OwnerComponent: TComponent; try SpTBUpdateBeforeLoadIni(OwnerComponent, IniFile, SectionNamePrefix, LockedDocks); TBIniLoadPositions(OwnerComponent, IniFile, SectionNamePrefix); - SpTBUpdateAfterLoadIni(OwnerComponent, IniFile, SectionNamePrefix, LockedDocks); + SpTBUpdateAfterLoadIni(OwnerComponent, IniFile, SectionNamePrefix, LockedDocks); finally LockedDocks.Free; end; @@ -1444,6 +1451,66 @@ procedure TSpTBXCustomMultiDock.AlignControls(AControl: TControl; UpdateDPLateralSize(Width, Height); end; +{$IF CompilerVersion >= 27} // for Delphi XE6 and up +function TSpTBXCustomMultiDock.DefaultScalingFlags: TScalingFlags; +begin + // Make sure Width and Height are not scaled + Result := inherited; + Result := Result - [sfWidth, sfHeight]; +end; +{$IFEND} + +procedure TSpTBXCustomMultiDock.ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); +begin + inherited; + // The parent Form doesn't scale itself before scaling child controls, so + // we can't scale the DPs here because the MultiDock size is not correct. + // See TCustomForm.ScaleForPPIRect, we need to post a message to handle it + // asynchronously to make sure the parent Form and the MultiDock are scaled + // first. + PostMessage(Self.Handle, CM_SPCHANGESCALE, M, D); +end; + +procedure TSpTBXCustomMultiDock.CMSPChangeScale(var Message: TMessage); +var + L: TList; + I, TotalSize: Integer; + DP: TSpTBXCustomDockablePanel; +begin + // Use BeginUpdate to disable arrangement, manually arrange the docked + // DPs, set the DockPos and scale the Height/Width + TotalSize := 0; + L := TList.Create; + BeginUpdate; + try + GetDockablePanelList(L); + for I := 0 to L.Count - 1 do begin + DP := TSpTBXCustomDockablePanel(L[I]); + DP.DockPos := TotalSize; + if (I = L.Count - 1) then begin + // The last one should fill the remaining space + if IsVertical then + DP.Height := ClientHeight - TotalSize + else + DP.Width := ClientWidth - TotalSize; + end + else begin + if IsVertical then begin + DP.Height := MulDiv(DP.Height, Message.WParam, Message.LParam); + Inc(TotalSize, DP.Height); + end + else begin + DP.Width := MulDiv(DP.Width, Message.WParam, Message.LParam); + Inc(TotalSize, DP.Width); + end; + end; + end; + finally + EndUpdate; + L.Free; + end; +end; + function CompareEffectiveDockPos(Item1, Item2: Pointer): Integer; begin Result := TSpTBXCustomDockablePanel(Item1).EffectiveDockPos - TSpTBXCustomDockablePanel(Item2).EffectiveDockPos; @@ -1544,7 +1611,8 @@ procedure TSpTBXCustomMultiDock.Notification(AComponent: TComponent; procedure TSpTBXCustomMultiDock.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); begin inherited; - UpdateDPLateralSize(AWidth, AHeight); + if not (csLoading in ComponentState) then + UpdateDPLateralSize(AWidth, AHeight); end; procedure TSpTBXCustomMultiDock.SetLimitToOneRow(const Value: Boolean); @@ -1667,8 +1735,7 @@ constructor TSpTBXDockablePanelButtonOptions.Create(AParent: TWinControl); inherited; Maximize := False; Minimize := False; - // Do not use SpDPIScale, scaled on TSpTBXCustomDockablePanel.ChangeScale - TitleBarMaxSize := 19; + TitleBarMaxSize := 19; // Do not scale, scaled in TSpTBXToolbar.ChangeScale end; procedure TSpTBXDockablePanelButtonOptions.CreateButtons; @@ -1698,8 +1765,7 @@ function TSpTBXDockablePanelButtonOptions.Restoring(B: TSpTBXCustomItem): Boolea procedure TSpTBXDockablePanelButtonOptions.SetupButton(B: TSpTBXCustomItem); begin inherited; - // Do not use SpDPIScale, scaled on TSpTBXCustomDockablePanel.ChangeScale - TSpTBXCustomItemAccess(B).CustomWidth := 15; + TSpTBXCustomItemAccess(B).CustomWidth := 15; // Do not scale, scaled in TSpTBXToolbar.ChangeScale end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -1733,7 +1799,7 @@ function TSpTBXDockablePanelToolbar.GetParentDockablePanel: TSpTBXCustomDockable function TSpTBXDockablePanelToolbar.GetRightAlignMargin: Integer; begin - Result := SpDPIScale(4); + Result := PPIScale(4); end; function TSpTBXDockablePanelToolbar.CanItemClick(Item: TTBCustomItem; @@ -1836,17 +1902,23 @@ destructor TSpTBXCustomDockablePanel.Destroy; FreeAndNil(FDockForms); // After inherited, Notification accesses FDockForms end; -procedure TSpTBXCustomDockablePanel.ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); -begin - inherited; - FOptions.TitleBarMaxSize := MulDiv(FOptions.TitleBarMaxSize, M, D); - if Assigned(Options.MinimizeButton) then - Options.MinimizeButton.CustomWidth := MulDiv(Options.MinimizeButton.CustomWidth, M, D); - if Assigned(Options.MaximizeButton) then - Options.MaximizeButton.CustomWidth := MulDiv(Options.MaximizeButton.CustomWidth, M, D); - if Assigned(Options.CloseButton) then - Options.CloseButton.CustomWidth := MulDiv(Options.CloseButton.CustomWidth, M, D); -end; +procedure TSpTBXCustomDockablePanel.ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); +begin + // Scaling is done by the MultiDock and by the floating Form when undocked + BeginUpdate; + try + inherited; + // View.UpdatePositions; not needed + finally + EndUpdate; + end; + DockResize(nil); // Update MinClientWidth/Height with the scaled FPanel + + // The following shouldn't be necessary, FFloatingClientHeight/Width is + // scaled by the floating form + //FFloatingClientHeight := MulDiv(FFloatingClientHeight, M, D); + //FFloatingClientWidth := MulDiv(FFloatingClientWidth, M, D); +end; procedure TSpTBXCustomDockablePanel.Loaded; var @@ -1992,7 +2064,7 @@ procedure TSpTBXCustomDockablePanel.Resize; // Make sure to calculate the floating form constraints taking into // account the borders and the close button. TotalBorderSize := GetFloatingBorderSize.Y * 2; - Parent.Constraints.MinWidth := SpDPIScale(20) + TotalBorderSize; + Parent.Constraints.MinWidth := PPIScale(20) + TotalBorderSize; Parent.Constraints.MinHeight := MinClientHeight + TotalBorderSize; if (FState.DockedState = wsMinimized) and (Parent.ClientHeight > MinClientHeight) then begin FState.DockedState := wsNormal; @@ -2437,19 +2509,19 @@ procedure TSpTBXCustomDockablePanel.DockDrawBackground(Sender: TObject; // DTTTTTTTTTTTTTTTTTTTTTTTTTD // DDDDDDDDDDDDDDDDDDDDDDDDDDD if IsVerticalTitleBar then begin - InflateRect(ARect, 0, CDefaultToolbarBorderSize); - ARect.Left := ARect.Left - CDefaultToolbarBorderSize; + InflateRect(ARect, 0, DockedBorderSize); + ARect.Left := ARect.Left - DockedBorderSize; end else begin - InflateRect(ARect, CDefaultToolbarBorderSize, 0); - ARect.Top := ARect.Top - CDefaultToolbarBorderSize; + InflateRect(ARect, DockedBorderSize, 0); + ARect.Top := ARect.Top - DockedBorderSize; end; end; DefaultPainting := True; DoDrawCaptionPanel(ACanvas, ARect, pstPrePaint, DefaultPainting); if DefaultPainting then - SpDrawXPDockablePanelTitleBar(ACanvas, ARect, True, IsVerticalTitleBar); + SpDrawXPDockablePanelTitleBar(ACanvas, ARect, True, IsVerticalTitleBar, CurrentPPI); DefaultPainting := True; DoDrawCaptionPanel(ACanvas, ARect, pstPostPaint, DefaultPainting); end; @@ -2494,7 +2566,7 @@ procedure TSpTBXCustomDockablePanel.DockResize(Sender: TObject); FPanel.Height := FToolbarDock.Height; if Floating and Assigned(Parent) then begin Parent.Constraints.MinWidth := 0; - Parent.Constraints.MinHeight := FPanel.Height + GetFloatingBorderSize.Y * SpDPIScale(2); + Parent.Constraints.MinHeight := FPanel.Height + GetFloatingBorderSize.Y * 2; end; end; MinClientWidth := 0; @@ -2620,14 +2692,14 @@ procedure TSpTBXCustomDockablePanel.InternalDrawBackground(ACanvas: TCanvas; // Draw the CaptionBar borders on the NC Area of the embedded Dock // See DockDrawBackground. if IsVerticalTitleBar then - ARect.Right := ARect.Left + CaptionPanelSize.X + CDefaultToolbarBorderSize + ARect.Right := ARect.Left + CaptionPanelSize.X + DockedBorderSize else - ARect.Bottom := ARect.Top + CaptionPanelSize.Y + CDefaultToolbarBorderSize; + ARect.Bottom := ARect.Top + CaptionPanelSize.Y + DockedBorderSize; DefaultPainting := True; DoDrawCaptionPanel(ACanvas, ARect, pstPrePaint, DefaultPainting); if DefaultPainting then - SpDrawXPDockablePanelTitleBar(ACanvas, ARect, True, IsVerticalTitleBar); + SpDrawXPDockablePanelTitleBar(ACanvas, ARect, True, IsVerticalTitleBar, CurrentPPI); DefaultPainting := True; DoDrawCaptionPanel(ACanvas, ARect, pstPostPaint, DefaultPainting); end; @@ -2735,7 +2807,11 @@ procedure TSpTBXCustomDockablePanel.DoneReadingPositionData(const Data: TTBReadP end; procedure TSpTBXCustomDockablePanel.ReadPositionData(const Data: TTBReadPositionData); +var + DPI: Integer; begin + // The ancestor class TSpTBXCustomToolWindow scales the DockPos, + // FloatLeft, FloatTop, ClientAreaWidth, ClientAreaHeight inherited; // Load FLoadedBarSize and FLoadedDockPos @@ -2745,9 +2821,11 @@ procedure TSpTBXCustomDockablePanel.ReadPositionData(const Data: TTBReadPosition // Load FloatingClientWidth/FloatingClientHeight, RestoreSize, State with Data do begin - FFloatingClientWidth := ReadIntProc(Name, rvFloatingClientWidth, 0, ExtraData); - FFloatingClientHeight := ReadIntProc(Name, rvFloatingClientHeight, 0, ExtraData); - FState.RestoreSize := ReadIntProc(Name, rvRestoreSize, 0, ExtraData); + // Read the saved DPI and scale + DPI := ReadIntProc(Name, 'DPI', 96, ExtraData); + FFloatingClientWidth := MulDiv(ReadIntProc(Name, rvFloatingClientWidth, 0, ExtraData), CurrentPPI, DPI); + FFloatingClientHeight := MulDiv(ReadIntProc(Name, rvFloatingClientHeight, 0, ExtraData), CurrentPPI, DPI); + FState.RestoreSize := MulDiv(ReadIntProc(Name, rvRestoreSize, 0, ExtraData), CurrentPPI, DPI); FState.DockedState := TWindowState(ReadIntProc(Name, rvState, 0, ExtraData)); FLoadedState := FState.DockedState; end; @@ -2852,7 +2930,7 @@ procedure TSpTBXCustomDockablePanel.SetParent(AParent: TWinControl); end else begin if not Docked then // If it's not docked compute the borders - EffectiveWidth := D.ClientWidth - (CDefaultToolbarBorderSize * 2) + EffectiveWidth := D.ClientWidth - (DockedBorderSize * 2) else EffectiveWidth := D.ClientWidth; // Append the DP to the bottom if it's being docked by code @@ -2868,7 +2946,7 @@ procedure TSpTBXCustomDockablePanel.SetParent(AParent: TWinControl); end else begin if not Docked then // If it's not docked compute the borders - EffectiveHeight := D.ClientHeight - (CDefaultToolbarBorderSize * 2) + EffectiveHeight := D.ClientHeight - (DockedBorderSize * 2) else EffectiveHeight := D.ClientHeight; // Append the DP to the bottom if it's being docked by code @@ -2979,7 +3057,7 @@ function TSpTBXCustomDockablePanel.SizeToggle(ToMaximize: Boolean): Boolean; procedure TSpTBXCustomDockablePanel.UpdateTitleBarRotation; begin if not HandleAllocated then Exit; - + if FShowVerticalCaption and not (Floating or IsVertical) then begin if not IsVerticalTitleBar then begin // TTBDock doesn't allow us to change the position when there are @@ -3031,7 +3109,7 @@ procedure TSpTBXCustomDockablePanel.WMNCCalcSize(var Message: TWMNCCalcSize); Message.Result := 0; if Docked then with Message.CalcSize_Params^ do - InflateRect(rgrc[0], -CDefaultToolbarBorderSize, -CDefaultToolbarBorderSize); + InflateRect(rgrc[0], -DockedBorderSize, -DockedBorderSize); end; procedure TSpTBXCustomDockablePanel.WMNCHitTest(var Message: TWMNCHitTest); @@ -3046,14 +3124,14 @@ procedure TSpTBXCustomDockablePanel.WMNCHitTest(var Message: TWMNCHitTest); GetWindowRect(Handle, R); if IsVertical then begin - if (P.Y >= R.Bottom - CDefaultToolbarBorderSize) and CanSplitResize(dpBottom) then + if (P.Y >= R.Bottom - DockedBorderSize) and CanSplitResize(dpBottom) then Message.Result := HT_DP_SPLITRESIZEBOTTOM - else if (P.Y <= R.Top + CDefaultToolbarBorderSize) and CanSplitResize(dpTop) then + else if (P.Y <= R.Top + DockedBorderSize) and CanSplitResize(dpTop) then Message.Result := HT_DP_SPLITRESIZETOP; end else begin - if (P.X >= R.Right - CDefaultToolbarBorderSize) and CanSplitResize(dpRight) then Message.Result := HT_DP_SPLITRESIZERIGHT - else if (P.X <= R.Left + CDefaultToolbarBorderSize) and CanSplitResize(dpLeft) then Message.Result := HT_DP_SPLITRESIZELEFT; + if (P.X >= R.Right - DockedBorderSize) and CanSplitResize(dpRight) then Message.Result := HT_DP_SPLITRESIZERIGHT + else if (P.X <= R.Left + DockedBorderSize) and CanSplitResize(dpLeft) then Message.Result := HT_DP_SPLITRESIZELEFT; end; end; end; @@ -3252,13 +3330,13 @@ procedure TSpTBXCustomSplitter.WMSpSkinChange(var Message: TMessage); Invalidate; end; -procedure TSpTBXCustomSplitter.ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); -begin - inherited; - FGripSize := MulDiv(FGripSize, M, D); - FRestorePos := MulDiv(FRestorePos, M, D); -end; - +procedure TSpTBXCustomSplitter.ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); +begin + inherited; + FGripSize := MulDiv(FGripSize, M, D); + FRestorePos := MulDiv(FRestorePos, M, D); +end; + procedure TSpTBXCustomSplitter.MouseAllocateLineDC; begin FMouseLineDC := GetDCEx(Parent.Handle, 0, DCX_CACHE or DCX_CLIPSIBLINGS or DCX_LOCKWINDOWUPDATE); @@ -3491,21 +3569,21 @@ procedure TSpTBXCustomSplitter.Paint; R := GripRect; DragHandleR := R; if IsVertical then - InflateRect(DragHandleR, -SpDPIScale(1), -SpDPIScale(10)) + InflateRect(DragHandleR, -PPIScale(1), -PPIScale(10)) else - InflateRect(DragHandleR, -SpDPIScale(10), -SpDPIScale(1)); + InflateRect(DragHandleR, -PPIScale(10), -PPIScale(1)); if SkinManager.GetSkinType = sknSkin then begin if FMouseOverGrip then CurrentSkin.PaintBackground(Canvas, R, skncButton, sknsNormal, True, True, False, [akLeft, akTop, akRight, akBottom]); C1 := SkinManager.CurrentSkin.Options(skncToolbarGrip).Body.Color1; C2 := SkinManager.CurrentSkin.Options(skncToolbarGrip).Body.Color2; - SpDrawXPGrip(Canvas, DragHandleR, C1, C2); + SpDrawXPGrip(Canvas, DragHandleR, C1, C2, CurrentPPI); end else begin C1 := CurrentSkin.GetThemedSystemColor(clBtnShadow); C2 := CurrentSkin.GetThemedSystemColor(clWindow); - SpDrawXPGrip(Canvas, DragHandleR, C1, C2); + SpDrawXPGrip(Canvas, DragHandleR, C1, C2, CurrentPPI); end; end; diff --git a/Source/SpTBXEditors.pas b/Source/SpTBXEditors.pas index 8fdc81a..0b36c64 100644 --- a/Source/SpTBXEditors.pas +++ b/Source/SpTBXEditors.pas @@ -1,7 +1,7 @@ unit SpTBXEditors; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -45,7 +45,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -54,7 +54,7 @@ interface {$IF CompilerVersion >= 24} // for Delphi XE3 and up System.UITypes, {$IFEND} - TB2Toolbar, TB2Item, TB2ExtItems, + TB2Toolbar, TB2Item, TB2ExtItems, Clipbrd, SpTBXSkins, SpTBXItem, SpTBXControls; const @@ -82,6 +82,8 @@ TSpTBXSpinEditViewer = class; TSpTBXEditMessageEvent = procedure(Sender: TObject; Viewer: TSpTBXEditItemViewer; var Message: TMessage; var Handled: Boolean) of object; TSpTBXDrawListItemEvent = procedure(Sender: TObject; ACanvas: TCanvas; var ARect: TRect; Index: Integer; const State: TOwnerDrawState; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean) of object; + TSpCustomTextValidateEvent = procedure(Sender: TObject; Key: Char; + var AText: string; const Pos: Integer; var IsValid: Boolean) of object; { TSpTBXEditButton } @@ -145,6 +147,7 @@ TSpTBXEdit = class(TSpTBXUnicodeEdit) FBorderStyle: TBorderStyle; FHotTrack: Boolean; FMouseInControl: Boolean; + FOnCustomValidate: TSpCustomTextValidateEvent; procedure SetBorderStyle(const Value: TBorderStyle); procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED; procedure CMEnter(var Message: TCMEnter); message CM_ENTER; @@ -153,14 +156,26 @@ TSpTBXEdit = class(TSpTBXUnicodeEdit) procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT; procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE; + function GetAsInteger: Longint; + procedure SetAsInteger(const Value: Longint); + function GetAsHex: Longint; + procedure SetAsHex(const Value: Longint); + protected + procedure WMPaste(var Msg:TMessage); message WM_PASTE; + procedure KeyPress(var Key: Char); override; + function IsValidChar(var S: string; var Key: Char; Posn: Integer): Boolean; virtual; + function DoValidate(const Key: Char; var AText: string; const Posn: Integer): Boolean; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure InvalidateFrame; property MouseInControl: Boolean read FMouseInControl; + property AsInteger: Longint read GetAsInteger write SetAsInteger default 0; + property AsHex: Longint read GetAsHex write SetAsHex default 0; published property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle; // Hides the inherited BorderStyle property HotTrack: Boolean read FHotTrack write FHotTrack default True; + property OnCustomValidate: TSpCustomTextValidateEvent read FOnCustomValidate write FOnCustomValidate; end; { TSpTBXButtonEdit } @@ -249,6 +264,8 @@ TSpTBXSpinEdit = class(TSpTBXEdit) procedure SetValue(const Value: Extended); procedure SetValueChanged(const ValueChangedEvent: TNotifyEvent); procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS; + function GetAsInteger: Longint; + procedure SetAsInteger(const Value: Longint); protected procedure Change; override; procedure KeyDown(var Key: Word; Shift: TShiftState); override; @@ -263,6 +280,7 @@ TSpTBXSpinEdit = class(TSpTBXEdit) destructor Destroy; override; property OnMouseWheelDown; property OnMouseWheelUp; + property AsInteger: Longint read GetAsInteger write SetAsInteger default 0; published property Alignment default taRightJustify; property ExtendedAccept: Boolean read FExtendedAccept write FExtendedAccept default False; @@ -288,6 +306,7 @@ TSpTBXComboBox = class(TComboBox) FOnDrawBackground: TSpTBXDrawEvent; FOnDrawItem: TSpTBXDrawListItemEvent; FOnDrawItemBackground: TSpTBXDrawListItemEvent; + FOnCustomValidate: TSpCustomTextValidateEvent; procedure MouseTimerHandler(Sender: TObject); procedure UpdateDropDownButton; procedure CMEnter(var Message: TCMEnter); message CM_ENTER; @@ -297,10 +316,13 @@ TSpTBXComboBox = class(TComboBox) procedure CMSPFontChanged(var Message: TMessage); message CM_SPFONTCHANGED; procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM; procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE; - procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE; procedure WMPaint(var Message: TWMPaint); message WM_PAINT; procedure WMSetFont(var Message: TWMSetFont); message WM_SETFONT; procedure WMSpSkinChange(var Message: TMessage); message WM_SPSKINCHANGE; + function GetAsInteger: Longint; + procedure SetAsInteger(const Value: Longint); + function GetAsHex: Longint; + procedure SetAsHex(const Value: Longint); protected FAutoDropDownWidthRightMargin: Integer; procedure CreateParams(var Params: TCreateParams); override; @@ -320,6 +342,11 @@ TSpTBXComboBox = class(TComboBox) function IsItemHeightStored: Boolean; override; {$IFEND} procedure SetItemHeight(Value: Integer); override; + procedure KeyPress(var Key: Char); override; + function IsValidChar(var S: string; var Key: Char; Posn: Integer): Boolean; virtual; + function DoValidate(const Key: Char; var AText: string; const Posn: Integer): Boolean; + procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd; + ComboProc: TWindowProcPtr); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -327,6 +354,8 @@ TSpTBXComboBox = class(TComboBox) function GetMouseInDropDownButton: Boolean; procedure InvalidateFrame; property MouseInControl: Boolean read FMouseInControl; + property AsInteger: Longint read GetAsInteger write SetAsInteger default 0; + property AsHex: Longint read GetAsHex write SetAsHex default 0; published property AutoDropDownWidth: Boolean read FAutoDropDownWidth write FAutoDropDownWidth default False; property AutoItemHeight: Boolean read FAutoItemHeight write FAutoItemHeight default True; @@ -335,6 +364,7 @@ TSpTBXComboBox = class(TComboBox) property OnDrawItem: TSpTBXDrawListItemEvent read FOnDrawItem write FOnDrawItem; // Hides the inherited OnDrawItem property OnDrawItemBackground: TSpTBXDrawListItemEvent read FOnDrawItemBackground write FOnDrawItemBackground; property OnMouseMove; + property OnCustomValidate: TSpCustomTextValidateEvent read FOnCustomValidate write FOnCustomValidate; end; { TSpTBXListBox } @@ -436,7 +466,7 @@ TSpTBXEditItem = class(TSpTBXCustomItem) procedure SetMaxLength(Value: Integer); procedure SetPasswordChar(Value: Char); procedure SetShowImage(const Value: Boolean); - procedure SetText(Value: string); + procedure SetText(const Value: string); protected function DoAcceptText(var NewText: string): Boolean; virtual; function DoAutoComplete(var AText: string): Boolean; virtual; @@ -464,6 +494,9 @@ TSpTBXEditItem = class(TSpTBXCustomItem) property HelpContext; property Hint; property ImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName; + {$IFEND} property Images; property ShortCut; property Visible; @@ -545,11 +578,14 @@ TSpTBXSpinEditItem = class(TSpTBXEditItem) function GetValueChanged: TNotifyEvent; procedure SetValue(const Value: Extended); procedure SetValueChanged(const ValueChangedEvent: TNotifyEvent); + function GetAsInteger: Longint; + procedure SetAsInteger(const Value: Longint); protected function GetItemViewerClass(AView: TTBView): TTBItemViewerClass; override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; + property AsInteger: Longint read GetAsInteger write SetAsInteger default 0; published property Alignment default taRightJustify; property Text stored False; @@ -589,8 +625,8 @@ function SpFocusEditItem(Item: TTBCustomItem; View: TTBView): Boolean; { Painting helpers } function SpCanEditFrameBeHotTracked(BorderStyle: TBorderStyle): Boolean; procedure SpDrawXPEditButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTrack, HotTrack, Pushed, RightAligned: Boolean); -procedure SpDrawXPComboButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTrack, HotTrack, DroppedDown, RightAligned: Boolean); -procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTrack, UpHotTrack, DownHotTrack, UpPushed, DownPushed, RightAligned: Boolean); +procedure SpDrawXPComboButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTrack, HotTrack, DroppedDown, RightAligned: Boolean; DPI: Integer); +procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTrack, UpHotTrack, DownHotTrack, UpPushed, DownPushed, RightAligned: Boolean; DPI: Integer); implementation @@ -605,10 +641,8 @@ TCustomEditAccess = class(TCustomEdit); //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Constants } -function CDefaultSpinButtonSize: Integer; -begin - Result := SpDPIScale(14); -end; +Const + CDefaultSpinButtonSize = 14; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Helpers } @@ -626,11 +660,11 @@ procedure SpCalcMaxDropDownWidth(Combo: TSpTBXComboBox; RightMargin: Integer = 8 C.Control := Combo; C.Font.Assign(Combo.Font); for I := 0 to Combo.Items.Count - 1 do begin - Sz := SpGetTextSize(C.Handle, Combo.Items[I], False); + Sz := C.TextExtent(Combo.Items[I]); // Using SpGetTextSize returns zero on 64bit, doesn't happen on 32bit, don't know why if Sz.cx > MaxWidth then MaxWidth := Sz.cx; end; - MaxWidth := MaxWidth + GetSystemMetrics(SM_CXVSCROLL) + RightMargin; + MaxWidth := MaxWidth + {$IF CompilerVersion>= 33}Combo.{$IFEND}GetSystemMetrics(SM_CXVSCROLL) + RightMargin; if Combo.Width < MaxWidth then SendMessage(Combo.Handle, CB_SETDROPPEDWIDTH, MaxWidth, 0); finally @@ -646,7 +680,13 @@ function SpFocusEditItem(Item: TTBCustomItem; View: TTBView): Boolean; IV := View.Find(Item); if Assigned(IV) then begin View.Select(IV, False); - View.ExecuteSelected(False); + if vsModal in View.State then + View.ExecuteSelected(False) + else begin + // Call View.EnterToolbarLoop to reset FDoneActionData.DoneAction to + // tbdaNone and execute the selected edit item viewer. + View.EnterToolbarLoop([tbetExecuteSelected]); + end; Result := True; end; end; @@ -686,7 +726,7 @@ procedure SpDrawXPEditButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTr end; procedure SpDrawXPComboButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTrack, - HotTrack, DroppedDown, RightAligned: Boolean); + HotTrack, DroppedDown, RightAligned: Boolean; DPI: Integer); var State: TSpTBXSkinStatesType; C: TColor; @@ -706,7 +746,7 @@ procedure SpDrawXPComboButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotT C := CurrentSkin.GetTextColor(skncEditButton, State); X := (ARect.Left + ARect.Right) div 2; Y := (ARect.Top + ARect.Bottom) div 2 - 1; - SpDrawArrow(ACanvas, X, Y, C, True, False, SpDPIScale(3)); + SpDrawArrow(ACanvas, X, Y, C, True, False, SpPPIScale(3, DPI)); end; sknWindows, sknDelphiStyle: begin @@ -735,7 +775,7 @@ procedure SpDrawXPComboButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotT else Details := SpTBXThemeServices.GetElementDetails(tcDropDownButtonNormal); {$IFEND} - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); end; sknSkin: begin @@ -745,13 +785,13 @@ procedure SpDrawXPComboButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotT C := CurrentSkin.GetTextColor(skncEditButton, State); X := (ARect.Left + ARect.Right) div 2; Y := (ARect.Top + ARect.Bottom) div 2 - 1; - SpDrawArrow(ACanvas, X, Y, C, True, False, SpDPIScale(3)); + SpDrawArrow(ACanvas, X, Y, C, True, False, SpPPIScale(3, DPI)); end; end; end; procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTrack, - UpHotTrack, DownHotTrack, UpPushed, DownPushed, RightAligned: Boolean); + UpHotTrack, DownHotTrack, UpPushed, DownPushed, RightAligned: Boolean; DPI: Integer); var ButtonR, BR: TRect; Details: TThemedElementDetails; @@ -788,7 +828,7 @@ procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTr else if UpPushed then Details := SpTBXThemeServices.GetElementDetails(tsUpPressed) else if UpHotTrack then Details := SpTBXThemeServices.GetElementDetails(tsUpHot) else Details := SpTBXThemeServices.GetElementDetails(tsUpNormal); - CurrentSkin.PaintThemedElementBackground(ACanvas, BR, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, BR, Details, DPI); // Down button BR := ButtonR; BR.Top := (ButtonR.Top + ButtonR.Bottom) div 2; @@ -796,7 +836,7 @@ procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTr else if DownPushed then Details := SpTBXThemeServices.GetElementDetails(tsDownPressed) else if DownHotTrack then Details := SpTBXThemeServices.GetElementDetails(tsDownHot) else Details := SpTBXThemeServices.GetElementDetails(tsDownNormal); - CurrentSkin.PaintThemedElementBackground(ACanvas, BR, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, BR, Details, DPI); end; sknDelphiStyle: begin @@ -810,7 +850,7 @@ procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTr else if UpPushed then Details := SpTBXThemeServices.GetElementDetails(tsArrowBtnUpPressed) else if UpHotTrack then Details := SpTBXThemeServices.GetElementDetails(tsArrowBtnUpHot) else Details := SpTBXThemeServices.GetElementDetails(tsArrowBtnUpNormal); - CurrentSkin.PaintThemedElementBackground(ACanvas, BR, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, BR, Details, DPI); // Down button BR := ButtonR; BR.Top := (ButtonR.Top + ButtonR.Bottom) div 2; @@ -818,7 +858,7 @@ procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTr else if DownPushed then Details := SpTBXThemeServices.GetElementDetails(tsArrowBtnDownPressed) else if DownHotTrack then Details := SpTBXThemeServices.GetElementDetails(tsArrowBtnDownHot) else Details := SpTBXThemeServices.GetElementDetails(tsArrowBtnDownNormal); - CurrentSkin.PaintThemedElementBackground(ACanvas, BR, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, BR, Details, DPI); end; sknSkin: begin @@ -831,7 +871,7 @@ procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTr BR.Bottom := BR.Bottom - 1; SpDrawXPEditButton(ACanvas, BR, Enabled, FrameHotTrack, UpHotTrack, UpPushed, RightAligned); C := CurrentSkin.GetTextColor(skncEditButton, State); - SpDrawArrow(ACanvas, X, Y, C, True, True, SpDPIScale(2)); + SpDrawArrow(ACanvas, X, Y, C, True, True, SpPPIScale(2, DPI)); if FrameHotTrack then BR.Bottom := BR.Bottom + 1; // Down button @@ -843,7 +883,7 @@ procedure SpDrawXPSpinButton(ACanvas: TCanvas; ARect: TRect; Enabled, FrameHotTr BR.Top := BR.Top + 1; SpDrawXPEditButton(ACanvas, BR, Enabled, FrameHotTrack, DownHotTrack, DownPushed, RightAligned); C := CurrentSkin.GetTextColor(skncEditButton, State); - SpDrawArrow(ACanvas, X, Y, C, True, False, SpDPIScale(2)); + SpDrawArrow(ACanvas, X, Y, C, True, False, SpPPIScale(2, DPI)); end; end; end; @@ -918,15 +958,15 @@ function TSpTBXEditButton.DoDrawItem(ACanvas: TCanvas; ARect: TRect; // Draw the ComboButton if the caption is not set if (Length(Caption) = 0) and not IsImageIndexValid then - SpDrawXPComboButton(ACanvas, ARect, Enabled, FrameHotTrack, MouseInControl, Pushed, RightAligned) + SpDrawXPComboButton(ACanvas, ARect, Enabled, FrameHotTrack, MouseInControl, Pushed, RightAligned, CurrentPPI) else begin case SkinManager.GetSkinType of sknNone: - SpDrawXPButton(ACanvas, ARect, Enabled, Pushed, MouseInControl, Checked, Focused, Default); + SpDrawXPButton(ACanvas, ARect, Enabled, Pushed, MouseInControl, Checked, Focused, Default, CurrentPPI); sknWindows, sknDelphiStyle: begin InflateRect(ARect, 1, 1); - SpDrawXPButton(ACanvas, ARect, Enabled, Pushed, MouseInControl, Checked, Focused, Default); + SpDrawXPButton(ACanvas, ARect, Enabled, Pushed, MouseInControl, Checked, Focused, Default, CurrentPPI); end; sknSkin: SpDrawXPEditButton(ACanvas, ARect, Enabled, FrameHotTrack, FrameHotTrack or MouseInControl, Pushed, RightAligned); @@ -989,7 +1029,7 @@ function TSpTBXSpinButton.DoDrawItem(ACanvas: TCanvas; ARect: TRect; if Result then begin IsHotTracking(UpHotTrack, DownHotTrack, EditFrameHotTrack); RightAligned := Align <> alLeft; - SpDrawXPSpinButton(ACanvas, ARect, Enabled, EditFrameHotTrack, UpHotTrack, DownHotTrack, FUpPushed, FDownPushed, RightAligned); + SpDrawXPSpinButton(ACanvas, ARect, Enabled, EditFrameHotTrack, UpHotTrack, DownHotTrack, FUpPushed, FDownPushed, RightAligned, CurrentPPI); end; end else @@ -1165,6 +1205,24 @@ destructor TSpTBXEdit.Destroy; inherited; end; +function TSpTBXEdit.DoValidate(const Key: Char; var AText: string; + const Posn: Integer): Boolean; +begin + Result := True; + if Assigned(FOnCustomValidate) then + FOnCustomValidate(Self, Key, AText, Posn, Result); +end; + +function TSpTBXEdit.GetAsHex: Longint; +begin + Result := StrToIntDef('$' + Text, 0); +end; + +function TSpTBXEdit.GetAsInteger: Longint; +begin + Result := StrToIntDef(Text, 0); +end; + procedure TSpTBXEdit.CMEnabledChanged(var Message: TMessage); begin inherited; @@ -1212,6 +1270,33 @@ procedure TSpTBXEdit.InvalidateFrame; RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN); end; +function TSpTBXEdit.IsValidChar(var S: string; var Key: Char; + Posn: Integer): Boolean; +begin + Result := DoValidate(Key, S, Posn); +end; + +procedure TSpTBXEdit.KeyPress(var Key: Char); +var + s: string; +begin + s:= Text; + if not IsValidChar(s, Key, SelStart + 1) and ((Key >= #32) or (Key = #8)) then + Key := #0; + Text := s; + inherited KeyPress(Key); +end; + +procedure TSpTBXEdit.SetAsHex(const Value: Longint); +begin + Text := IntToHex(Value, MaxLength); +end; + +procedure TSpTBXEdit.SetAsInteger(const Value: Longint); +begin + Text := IntToStr(Value); +end; + procedure TSpTBXEdit.SetBorderStyle(const Value: TBorderStyle); begin if FBorderStyle <> Value then begin @@ -1233,7 +1318,40 @@ procedure TSpTBXEdit.WMNCPaint(var Message: TWMNCPaint); inherited else if Ctl3D then - SpDrawXPEditFrame(Self, HotTrackFrame, False, FBorderStyle = bsNone); + SpDrawXPEditFrame(Self, HotTrackFrame, False, FBorderStyle = bsNone, CurrentPPI); +end; + +procedure TSpTBXEdit.WMPaste(var Msg: TMessage); +var + i: integer; + s, s1, s2: string; +begin + Clipboard.Open; + try + s := ClipBoard.AsText; + finally + Clipboard.Close; + end; + s2 := Text; //1602 + for i := 1 to Length(s) do + if IsValidChar(s2, s[i], SelStart) then + begin + s1 := s1 + s[i]; + s2 := s2 + s[i]; + end; + Clipboard.Open; + try + ClipBoard.AsText := s1; + finally + Clipboard.Close; + end; + inherited; + Clipboard.Open; + try + ClipBoard.AsText := s; + finally + Clipboard.Close; + end; end; procedure TSpTBXEdit.WMSpSkinChange(var Message: TMessage); @@ -1548,11 +1666,21 @@ procedure TSpTBXSpinEdit.Change; inherited; end; +function TSpTBXSpinEdit.GetAsInteger: Longint; +begin + Result := Trunc(GetValue); +end; + function TSpTBXSpinEdit.GetValue: Extended; begin Result := SpinOptions.Value; end; +procedure TSpTBXSpinEdit.SetAsInteger(const Value: Longint); +begin + SetValue(Value); +end; + procedure TSpTBXSpinEdit.SetValue(const Value: Extended); begin SpinOptions.Value := Value; @@ -1703,7 +1831,7 @@ procedure TSpTBXComboBox.CNDrawItem(var Message: TWMDrawItem); DrawItem(itemID, rcItem, State); end else - Canvas.FillRect(rcItem); + SpDrawXPListItemBackground(Canvas, rcItem, False, False, odFocused in State) finally Canvas.Unlock; Canvas.Handle := 0; @@ -1735,7 +1863,7 @@ procedure TSpTBXComboBox.MouseTimerHandler(Sender: TObject); procedure TSpTBXComboBox.DoCalcMaxDropDownWidth; begin if FAutoDropDownWidth then - SpCalcMaxDropDownWidth(Self, FAutoDropDownWidthRightMargin); + SpCalcMaxDropDownWidth(Self, PPIScale(FAutoDropDownWidthRightMargin)); end; procedure TSpTBXComboBox.DoDrawBackground(ACanvas: TCanvas; ARect: TRect; @@ -1759,6 +1887,14 @@ procedure TSpTBXComboBox.DoDrawItemBackground(ACanvas: TCanvas; if Assigned(FOnDrawItemBackground) then FOnDrawItemBackground(Self, ACanvas, ARect, Index, State, PaintStage, PaintDefault); end; +function TSpTBXComboBox.DoValidate(const Key: Char; var AText: string; + const Posn: Integer): Boolean; +begin + Result := True; + if Assigned(FOnCustomValidate) then + FOnCustomValidate(Self, Key, AText, Posn, Result); +end; + procedure TSpTBXComboBox.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); var @@ -1816,6 +1952,16 @@ procedure TSpTBXComboBox.EditWndProc(var Message: TMessage); inherited; end; +function TSpTBXComboBox.GetAsHex: Longint; +begin + Result := StrToIntDef('$' + Text, 0); +end; + +function TSpTBXComboBox.GetAsInteger: Longint; +begin + Result := StrToIntDef(Text, 0); +end; + function TSpTBXComboBox.GetDropDownButtonRect: TRect; var ButtonWidth: Integer; @@ -1877,6 +2023,23 @@ procedure TSpTBXComboBox.InvalidateFrame; Invalidate; end; +function TSpTBXComboBox.IsValidChar(var S: string; var Key: Char; + Posn: Integer): Boolean; +begin + Result := DoValidate(Key, S, Posn); +end; + +procedure TSpTBXComboBox.KeyPress(var Key: Char); +var + s: string; +begin + s:= Text; + if not IsValidChar(s, Key, SelStart + 1) and (Key >= #32) then + Key := #0; + Text := s; + inherited KeyPress(Key); +end; + procedure TSpTBXComboBox.UpdateDropDownButton; var ButtonState: Boolean; @@ -1916,6 +2079,16 @@ function TSpTBXComboBox.IsItemHeightStored: Boolean; end; {$IFEND} +procedure TSpTBXComboBox.SetAsHex(const Value: Integer); +begin + Text := IntToHex(Value, MaxLength); +end; + +procedure TSpTBXComboBox.SetAsInteger(const Value: Integer); +begin + Text := IntToStr(Value); +end; + procedure TSpTBXComboBox.SetItemHeight(Value: Integer); begin if Value > 0 then @@ -1929,12 +2102,6 @@ procedure TSpTBXComboBox.WMMouseMove(var Message: TWMMouseMove); UpdateDropDownButton; end; -procedure TSpTBXComboBox.WMNCCalcSize(var Message: TWMNCCalcSize); -begin - // [Bugfix] Delphi 2006 bug: - // Do nothing, fix Delphi 2005/2006 bug: http://qc.borland.com/wc/qcmain.aspx?d=13852 -end; - procedure TSpTBXComboBox.WMPaint(var Message: TWMPaint); var ACanvas: TControlCanvas; @@ -1977,9 +2144,9 @@ procedure TSpTBXComboBox.WMPaint(var Message: TWMPaint); ButtonR := GetDropDownButtonRect; if SkinManager.GetSkinType = sknSkin then SpDrawParentBackground(Self, ACanvas.Handle, R); - SpDrawXPEditFrame(ACanvas, R, Enabled, HotTrackFrame); + SpDrawXPEditFrame(ACanvas, R, Enabled, HotTrackFrame, False, False, CurrentPPI); if Style <> csSimple then - SpDrawXPComboButton(ACanvas, ButtonR, Enabled, HotTrackFrame, GetMouseInDropDownButton, DroppedDown, True); + SpDrawXPComboButton(ACanvas, ButtonR, Enabled, HotTrackFrame, GetMouseInDropDownButton, DroppedDown, True, CurrentPPI); end; PaintDefault := True; @@ -2014,6 +2181,26 @@ procedure TSpTBXComboBox.CNMeasureItem(var Message: TWMMeasureItem); end; end; +procedure TSpTBXComboBox.ComboWndProc(var Message: TMessage; ComboWnd: HWnd; + ComboProc: TWindowProcPtr); +var + i: integer; + s, s1: string; +begin + if Message.Msg = WM_PASTE then + begin + s := ClipBoard.AsText; + for i := 1 to Length(s) do + if IsValidChar(s1, s[i], Length(s1)) then + s1 := s1 + s[i]; + ClipBoard.AsText := s1; + inherited; + ClipBoard.AsText := s; + end + else + inherited; +end; + procedure TSpTBXComboBox.CMSPFontChanged(var Message: TMessage); // Automatically update the Height/ItemHeight when Style is csDropDown, // csDropDownList or csSimple @@ -2215,7 +2402,7 @@ procedure TSpTBXListBox.WMNCPaint(var Message: TWMNCPaint); inherited; if (BorderStyle <> bsNone) and (SkinManager.GetSkinType <> sknNone) then if Ctl3D then - SpDrawXPEditFrame(Self, FHotTracking, True); + SpDrawXPEditFrame(Self, FHotTracking, True, False, CurrentPPI); end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -2317,9 +2504,9 @@ procedure TSpTBXCheckListBox.DrawItem(Index: Integer; Rect: TRect; // Add a margin to the rect R := Rect; if not UseRightToLeftAlignment then - Inc(R.Left, SpDPIScale(3)) + Inc(R.Left, PPIScale(3)) else - Dec(R.Right, SpDPIScale(3)); + Dec(R.Right, PPIScale(3)); SpDrawXPText(Canvas, Items[Index], R, Flags); end; @@ -2354,7 +2541,7 @@ procedure TSpTBXCheckListBox.DrawItemBackground(Index: Integer; ARect: TRect; if SkinManager.GetSkinType = sknSkin then Canvas.FillRect(R); - SpDrawXPCheckBoxGlyph(Canvas, R, ItemEnabled[Index], Self.State[Index], False, False); + SpDrawXPCheckBoxGlyph(Canvas, R, ItemEnabled[Index], Self.State[Index], False, False, CurrentPPI); // Draw the background and focus SpDrawXPListItemBackground(Canvas, ARect, odSelected in State, False, odFocused in State); @@ -2412,7 +2599,7 @@ procedure TSpTBXCheckListBox.WMNCPaint(var Message: TWMNCPaint); inherited; if (BorderStyle <> bsNone) and (SkinManager.GetSkinType <> sknNone) then if Ctl3D then - SpDrawXPEditFrame(Self, FHotTracking, True); + SpDrawXPEditFrame(Self, FHotTracking, True, False, CurrentPPI); end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -2546,7 +2733,7 @@ procedure TSpTBXEditItem.SetMaxLength(Value: Integer); end; end; -procedure TSpTBXEditItem.SetText(Value: string); +procedure TSpTBXEditItem.SetText(const Value: string); begin SetTextEx(Value, tcrSetProperty); end; @@ -2640,7 +2827,7 @@ procedure TSpTBXEditItemViewer.GetEditRect(var R: TRect); R := BoundsRect; if not IsToolbarStyle then begin TextSize := MeasureEditCaption; - CurrentSkin.GetMenuItemMargins(StockBitmap.Canvas, 0, MarginsInfo); + CurrentSkin.GetMenuItemMargins(StockBitmap.Canvas, 0, MarginsInfo, View.Window.CurrentPPI); Inc(R.Left, MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace); if Length(Item.EditCaption) > 0 then Inc(R.Left, MarginsInfo.LeftCaptionMargin + TextSize.cx + MarginsInfo.RightCaptionMargin + 1); @@ -2705,11 +2892,11 @@ procedure TSpTBXEditItemViewer.CalcSize(const Canvas: TCanvas; EditBoxHeight: Integer; begin if Item.CustomWidth > -1 then - AWidth := Item.CustomWidth; + AWidth := PPIScale(Item.CustomWidth); if not IsToolbarStyle then begin TextSize := MeasureEditCaption; - CurrentSkin.GetMenuItemMargins(StockBitmap.Canvas, 0, MarginsInfo); + CurrentSkin.GetMenuItemMargins(StockBitmap.Canvas, 0, MarginsInfo, View.Window.CurrentPPI); Inc(AWidth, MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace); if Length(Item.EditCaption) > 0 then Inc(AWidth, MarginsInfo.LeftCaptionMargin + TextSize.cx + MarginsInfo.RightCaptionMargin + 2); @@ -2728,7 +2915,7 @@ procedure TSpTBXEditItemViewer.CalcSize(const Canvas: TCanvas; AHeight := AHeight or $01; if (Item.CustomHeight > -1) and IsToolbarStyle then - AHeight := Item.CustomHeight; + AHeight := PPIScale(Item.CustomHeight); end; function TSpTBXEditItemViewer.CaptionShown: Boolean; @@ -2747,8 +2934,8 @@ procedure TSpTBXEditItemViewer.InternalDrawFrame(ACanvas: TCanvas; if not (ItemInfo.HotTrack or ItemInfo.Pushed) and (SkinManager.CurrentSkinName = 'Default') and not SpIsWinVistaOrUp then SpFillRect(ACanvas, ARect, clWindow, clBtnFace) else begin - SpDrawXPEditFrame(ACanvas, ARect, ItemInfo.Enabled, ItemInfo.HotTrack); - InflateRect(ARect, -2, -2); // Do not use SpDPIScale, border size is always 2 + SpDrawXPEditFrame(ACanvas, ARect, ItemInfo.Enabled, ItemInfo.HotTrack, False, False, View.Window.CurrentPPI); + InflateRect(ARect, -2, -2); // Do not DPI scale, border size is always 2 SpFillRect(ACanvas, ARect, CurrentSkin.GetThemedSystemColor(clWindow)); end; end; @@ -2782,18 +2969,19 @@ procedure TSpTBXEditItemViewer.Paint(const Canvas: TCanvas; SpFillItemInfo(Canvas, Self, ItemInfo); Canvas.Font.Assign(View.GetFont); + Canvas.Font.Height := MulDiv(Canvas.Font.Height, View.Window.CurrentPPI, View.GetFont.PixelsPerInch); Item.FontSettings.Apply(Canvas.Font); { Item Caption, only on MenuItems } if not IsToolbarStyle then begin S := Item.EditCaption; - CurrentSkin.GetMenuItemMargins(Canvas, 0, MarginsInfo); + CurrentSkin.GetMenuItemMargins(Canvas, 0, MarginsInfo, View.Window.CurrentPPI); TextSize := SpGetTextSize(DC, S, True); if Length(S) > 0 then R.Right := MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace + TextSize.cx + MarginsInfo.LeftCaptionMargin + MarginsInfo.RightCaptionMargin else - R.Right := MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace - SpDpiScale(1); + R.Right := MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace - PPIScale(1); SpDrawXPMenuItem(Canvas, R, ItemInfo); R.Right := ClientAreaRect.Right; @@ -2820,18 +3008,18 @@ procedure TSpTBXEditItemViewer.Paint(const Canvas: TCanvas; { Edit Frame } InternalDrawFrame(Canvas, R, ItemInfo); - InflateRect(R, SpDPIScale(1), 0); + InflateRect(R, PPIScale(1), 0); { Editor Image } if ShowImage then begin ImgList := GetImageList; if Assigned(ImgList) and (Item.ImageIndex >= 0) and (Item.ImageIndex <= ImgList.Count - 1) then begin - ImageRect.Left := R.Left + SpDPIScale(4); + ImageRect.Left := R.Left + PPIScale(4); ImageRect.Right := R.Left + ImgList.Width; ImageRect.Top := (R.Top + R.Bottom + 1 - ImgList.Height) div 2; ImageRect.Bottom := ImageRect.Top + ImgList.Height; - SpDrawImageList(Canvas, ImageRect, ImgList, Item.ImageIndex, Item.Enabled, True); + SpDrawVirtualImageList(Canvas, ImageRect, ImgList, Item.ImageIndex, Item.Enabled); end; end; @@ -2843,21 +3031,22 @@ procedure TSpTBXEditItemViewer.Paint(const Canvas: TCanvas; S := Item.Text; Canvas.Font.Assign(View.GetFont); + Canvas.Font.Height := MulDiv(Canvas.Font.Height, View.Window.CurrentPPI, View.GetFont.PixelsPerInch); Item.EditorFontSettings.Apply(Canvas.Font); if Canvas.Font.Color = clNone then if Item.Enabled then Canvas.Font.Color := CurrentSkin.GetThemedSystemColor(clWindowText) else Canvas.Font.Color := CurrentSkin.GetThemedSystemColor(clGrayText); - InflateRect(R, -SpDPIScale(2), -SpDPIScale(1)); + InflateRect(R, -PPIScale(2), -PPIScale(1)); if not IsToolbarStyle then - Inc(R.Left, GetIndentBefore + SpDPIScale(1)) + Inc(R.Left, GetIndentBefore + PPIScale(1)) else - Inc(R.Left, GetIndentBefore + SpDPIScale(2)); - Dec(R.Right, GetIndentAfter + SpDPIScale(1)); - Dec(R.Top, SpDPIScale(1)); + Inc(R.Left, GetIndentBefore + PPIScale(2)); + Dec(R.Right, GetIndentAfter + PPIScale(1)); + Dec(R.Top, PPIScale(1)); if IsToolbarStyle then - Inc(R.Left, -SpDPIScale(1)); + Inc(R.Left, -PPIScale(1)); SpDrawXPText(Canvas, S, R, DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX or Alignments[Item.Alignment]); end; end; @@ -3015,6 +3204,8 @@ function TSpTBXEditItemViewer.EditLoop(const CapHandle: HWND): Boolean; TCustomEditAccess(FEditControl).BorderStyle := bsNone; TCustomEditAccess(FEditControl).AutoSize := False; TCustomEditAccess(FEditControl).Font.Assign(View.GetFont); + TCustomEditAccess(FEditControl).Font.Height := + MulDiv(TCustomEditAccess(FEditControl).Font.Height, View.Window.CurrentPPI, View.GetFont.PixelsPerInch); Item.EditorFontSettings.Apply(TCustomEditAccess(FEditControl).Font); if FEditControl is TSpTBXUnicodeEdit then begin TSpTBXUnicodeEdit(FEditControl).Alignment := Item.Alignment; @@ -3098,6 +3289,8 @@ function TSpTBXEditItemViewer.DoExecute: Boolean; function TSpTBXEditItemViewer.MeasureEditCaption: TSize; begin StockBitmap.Canvas.Font.Assign(View.GetFont); + StockBitmap.Canvas.Font.Height := + MulDiv(StockBitmap.Canvas.Font.Height, View.Window.CurrentPPI, View.GetFont.PixelsPerInch); Item.FontSettings.Apply(StockBitmap.Canvas.Font); Result := SpGetTextSize(StockBitmap.Canvas.Handle, Item.EditCaption, True); end; @@ -3107,6 +3300,8 @@ function TSpTBXEditItemViewer.MeasureTextHeight: Integer; I: Integer; begin StockBitmap.Canvas.Font.Assign(View.GetFont); + StockBitmap.Canvas.Font.Height := + MulDiv(StockBitmap.Canvas.Font.Height, View.Window.CurrentPPI, View.GetFont.PixelsPerInch); Item.EditorFontSettings.Apply(StockBitmap.Canvas.Font); GetEditHeight(StockBitmap.Canvas.Handle, Result, I); Inc(Result, I); @@ -3177,6 +3372,11 @@ destructor TSpTBXSpinEditItem.Destroy; inherited; end; +function TSpTBXSpinEditItem.GetAsInteger: Longint; +begin + Result := Trunc(GetValue); +end; + function TSpTBXSpinEditItem.GetItemViewerClass(AView: TTBView): TTBItemViewerClass; begin if not FAllowVerticalEditor and (AView.Orientation = tbvoVertical) then @@ -3190,6 +3390,11 @@ function TSpTBXSpinEditItem.GetValue: Extended; Result := SpinOptions.Value; end; +procedure TSpTBXSpinEditItem.SetAsInteger(const Value: Longint); +begin + SetValue(Value); +end; + procedure TSpTBXSpinEditItem.SetValue(const Value: Extended); begin SpinOptions.Value := Value; @@ -3238,9 +3443,9 @@ function TSpTBXSpinEditViewer.GetAccRole: Integer; function TSpTBXSpinEditViewer.GetIndentAfter: Integer; begin if IsToolbarStyle then - Result := CDefaultSpinButtonSize + SpDPIScale(1) + Result := PPIScale(CDefaultSpinButtonSize + 1) else - Result := GetSystemMetrics(SM_CXMENUCHECK) + SpDPIScale(1); + Result := {$IF CompilerVersion>= 33}View.Window.{$IFEND}GetSystemMetrics(SM_CXMENUCHECK) + PPIScale(1); end; function TSpTBXSpinEditViewer.GetItem: TSpTBXSpinEditItem; @@ -3300,11 +3505,11 @@ procedure TSpTBXSpinEditViewer.InternalDrawFrame(ACanvas: TCanvas; ARect: TRect; begin inherited; R := ARect; - InflateRect(R, -SpDPIScale(2), -SpDPIScale(2)); + InflateRect(R, -PPIScale(2), -PPIScale(2)); R.Left := ARect.Right - GetIndentAfter; IsHotTrack := ItemInfo.HotTrack; - SpDrawXPSpinButton(ACanvas, R, ItemInfo.Enabled, IsHotTrack, IsHotTrack, IsHotTrack, FUpPushed, FDownPushed, True); + SpDrawXPSpinButton(ACanvas, R, ItemInfo.Enabled, IsHotTrack, IsHotTrack, IsHotTrack, FUpPushed, FDownPushed, True, View.Window.CurrentPPI); end; procedure TSpTBXSpinEditViewer.InternalEditControlChange(Sender: TObject); diff --git a/Source/SpTBXExtEditors.pas b/Source/SpTBXExtEditors.pas index 4d076a5..ed64e8f 100644 --- a/Source/SpTBXExtEditors.pas +++ b/Source/SpTBXExtEditors.pas @@ -1,7 +1,7 @@ unit SpTBXExtEditors; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -38,7 +38,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -101,15 +101,20 @@ TSpTBXColorEdit = class(TSpTBXEdit) { TSpTBXFontComboBox } + TSpTBXFontPitch = (ffScalable, ffMonospaced); + TSpTBXFontPitchSet = set of TSpTBXFontPitch; + TSpTBXFontType = (ffRaster, ffTrueType, ffOpenType); + TSpTBXFontTypeSet = set of TSpTBXFontType; + TSpTBXFontComboBoxPreview = class(TCustomControl) private - FPreviewPanel: TPanel; protected procedure CreateParams(var Params: TCreateParams); override; + procedure Paint; override; public constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - property PreviewPanel: TPanel read FPreviewPanel; + property Caption; + property Font; end; TSpTBXFontComboBox = class(TSpTBXComboBox) @@ -118,14 +123,19 @@ TSpTBXFontComboBox = class(TSpTBXComboBox) FFontNamePreview: Boolean; FMaxMRUItems: Integer; FMRUCount: Integer; + FFilterFontPitch: TSpTBXFontPitchSet; + FFilterFontType: TSpTBXFontTypeSet; FPreviewWindow: TSpTBXFontComboBoxPreview; FSelectedFont: TFontName; FOnFontPreview: TSpTBXEditGetTextEvent; + FScaledFontGlyphImgList : TImageList; procedure UpdateSelectedFont(AddMRU: Boolean); procedure SetFontNamePreview(const Value: Boolean); procedure SetSelectedFont(const Value: TFontName); procedure SetMaxMRUItems(Value: Integer); procedure SetFontPreview(const Value: Boolean); + procedure SetFilterFontPitch(const Value: TSpTBXFontPitchSet); + procedure SetFilterFontType(const Value: TSpTBXFontTypeSet); protected procedure Click; override; procedure CloseUp; override; @@ -133,11 +143,12 @@ TSpTBXFontComboBox = class(TSpTBXComboBox) procedure DoDrawItem(ACanvas: TCanvas; var ARect: TRect; Index: Integer; const State: TOwnerDrawState; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); override; procedure DropDown; override; + procedure ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; - procedure MRUAdd(AFontName: TFontName); - function MRUDelete(AFontName: TFontName): Boolean; + procedure MRUAdd(const AFontName: TFontName); + function MRUDelete(const AFontName: TFontName): Boolean; property MRUCount: Integer read FMRUCount; published property Items stored False; @@ -147,6 +158,8 @@ TSpTBXFontComboBox = class(TSpTBXComboBox) property FontNamePreview: Boolean read FFontNamePreview write SetFontNamePreview default True; property MaxMRUItems: Integer read FMaxMRUItems write SetMaxMRUItems default 5; property SelectedFont: TFontName read FSelectedFont write SetSelectedFont; + property FilterFontPitch: TSpTBXFontPitchSet read FFilterFontPitch write SetFilterFontPitch default [ffScalable, ffMonospaced]; + property FilterFontType: TSpTBXFontTypeSet read FFilterFontType write SetFilterFontType default [ffRaster, ffTrueType, ffOpenType]; property OnFontPreview: TSpTBXEditGetTextEvent read FOnFontPreview write FOnFontPreview; end; @@ -175,7 +188,7 @@ TSpTBXColorListBox = class(TSpTBXListBox) procedure PopulateList; public constructor Create(AOwner: TComponent); override; - procedure AddColor(AColor: TColor; AColorName: string); + procedure AddColor(AColor: TColor; const AColorName: string); function ColorCount: Integer; property Colors[Index: Integer]: TColor read GetColor; property ColorNames[Index: Integer]: string read GetColorName; @@ -186,20 +199,17 @@ TSpTBXColorListBox = class(TSpTBXListBox) end; { Helpers } -procedure SpFillFontNames(ADest: TStrings); +procedure SpFillFontNames(ADest: TStrings; FilterFontPitch: TSpTBXFontPitchSet; FilterFontType: TSpTBXFontTypeSet); { Painting helpers } procedure SpDrawCheckeredBackground(ACanvas: TCanvas; ARect: TRect); -procedure SpDrawColorDropDownButton(ACanvas: TCanvas; ARect: TRect; Pushed: Boolean; AColor: TColor; CheckeredBkgndWhenTransparent: Boolean = True); - -var - FontGlyphImgList: TImageList = nil; +procedure SpDrawColorDropDownButton(ACanvas: TCanvas; ARect: TRect; Pushed: Boolean; AColor: TColor; PPIScale: TPPIScale; CheckeredBkgndWhenTransparent: Boolean = True); implementation uses Dialogs, TB2Common, - {$IF CompilerVersion >= 25} // for Delphi XE4 and up + {$IF CompilerVersion >= 24} // for Delphi XE3 and up System.Types, System.UITypes, {$IFEND} SpTBXFormPopupMenu, SpTBXColorPickerForm; @@ -209,6 +219,13 @@ implementation //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Helpers } +type + TFontEnumRecord = record + Strings: TStringList; + FilterFontPitch: TSpTBXFontPitchSet; + FilterFontType: TSpTBXFontTypeSet; + end; + PFontEnumRecord = ^TFontEnumRecord; function EnumFontsProc(EnumLogFontExDV: PEnumLogFontExDV; EnumTextMetric: PEnumTextMetric; FontType: DWORD; LParam: LPARAM): Integer; stdcall; @@ -216,42 +233,68 @@ function EnumFontsProc(EnumLogFontExDV: PEnumLogFontExDV; EnumTextMetric: PEnumT S: string; GlyphIndex: Integer; L: TStringList; + P: TSpTBXFontPitch; + T: TSpTBXFontType; + FilterFontPitch: TSpTBXFontPitchSet; + FilterFontType: TSpTBXFontTypeSet; const NTM_PS_OPENTYPE = $00020000; NTM_TT_OPENTYPE = $00040000; begin - L := TStringList(LParam); + Result := 1; + + L := PFontEnumRecord(LParam).Strings; + FilterFontPitch := PFontEnumRecord(LParam).FilterFontPitch; + FilterFontType := PFontEnumRecord(LParam).FilterFontType; + GlyphIndex := 0; if ((EnumTextMetric.etmNewTextMetricEx.ntmTm.ntmFlags and NTM_TT_OPENTYPE) = NTM_TT_OPENTYPE) or ((EnumTextMetric.etmNewTextMetricEx.ntmTm.ntmFlags and NTM_PS_OPENTYPE) = NTM_PS_OPENTYPE) then - GlyphIndex := 2 - else - if FontType = TRUETYPE_FONTTYPE then - GlyphIndex := 1; + begin + GlyphIndex := 2; + P := ffScalable; + T := ffOpenType; + end + else begin + P := ffScalable; + if FontType = RASTER_FONTTYPE then + T := ffRaster + else + T := ffTrueType; + end; - S := EnumLogFontExDV.elfEnumLogfontEx.elfLogFont.lfFaceName; + if (EnumLogFontExDV.elfEnumLogfontEx.elfLogFont.lfPitchAndFamily and FIXED_PITCH) = FIXED_PITCH then + P := ffMonospaced; + if not (P in FilterFontPitch) or not (T in FilterFontType) then + exit; + + S := EnumLogFontExDV.elfEnumLogfontEx.elfLogFont.lfFaceName; if (S[1] <> '@') then if (L.Count = 0) or not SameText(S, L[L.Count - 1]) then L.AddObject(S, Pointer(GlyphIndex)); - - Result := 1; end; -procedure SpFillFontNames(ADest: TStrings); +procedure SpFillFontNames(ADest: TStrings; FilterFontPitch: TSpTBXFontPitchSet; + FilterFontType: TSpTBXFontTypeSet); // This will only work on Windows 2000 and above, more info on: -// http://www.delphipraxis.net/post712587.html&sid=945c12fa9fb826d76e51c80b42109a21#712587 +// https://www.delphipraxis.net/616082-post.html#712587 var DC: HDC; LFont: TLogFont; L: TStringList; + FontEnumRecord: TFontEnumRecord; begin L := TStringList.Create; + FontEnumRecord.Strings := L; + FontEnumRecord.FilterFontPitch := FilterFontPitch; + FontEnumRecord.FilterFontType := FilterFontType; + DC := GetDC(0); try FillChar(LFont, SizeOf(LFont), 0); LFont.lfCharset := DEFAULT_CHARSET; - EnumFontFamiliesEx(DC, LFont, @EnumFontsProc, LPARAM(L), 0); + EnumFontFamiliesEx(DC, LFont, @EnumFontsProc, LPARAM(@FontEnumRecord), 0); L.Sort; ADest.Assign(L); finally @@ -289,7 +332,8 @@ procedure SpDrawCheckeredBackground(ACanvas: TCanvas; ARect: TRect); end; procedure SpDrawColorDropDownButton(ACanvas: TCanvas; ARect: TRect; - Pushed: Boolean; AColor: TColor; CheckeredBkgndWhenTransparent: Boolean); + Pushed: Boolean; AColor: TColor; PPIScale: TPPIScale; + CheckeredBkgndWhenTransparent: Boolean); // Draws a button used for color editboxes var R: TRect; @@ -301,7 +345,7 @@ procedure SpDrawColorDropDownButton(ACanvas: TCanvas; ARect: TRect; if not Pushed then SpDrawRectangle(ACanvas, R, 0, clBtnHighlight, clBtnShadow); - InflateRect(R, -SpDPIScale(2), -SpDPIScale(2)); + InflateRect(R, -PPIScale(2), -PPIScale(2)); if (AColor = clNone) and CheckeredBkgndWhenTransparent then begin // Draw a checkered background when clNone is used SpDrawCheckeredBackground(ACanvas, R); @@ -313,18 +357,18 @@ procedure SpDrawColorDropDownButton(ACanvas: TCanvas; ARect: TRect; SpDrawRectangle(ACanvas, R, 0, clBtnShadow, clBtnHighlight); R := ARect; - R.Left := R.Right - SpDPIScale(9); - R.Top := R.Bottom - SpDPIScale(7); + R.Left := R.Right - PPIScale(9); + R.Top := R.Bottom - PPIScale(7); ACanvas.Brush.Color := clBtnFace; ACanvas.FillRect(R); if Pushed then SpDrawRectangle(ACanvas, R, 0, clBtnHighlight, clBtnFace) else SpDrawRectangle(ACanvas, R, 0, clBtnHighlight, clBtnShadow); - SpDrawArrow(ACanvas, R.Left + (R.Right - R.Left) div 2, R.Top + (R.Bottom - R.Top) div 2 - SpDPIScale(1), clBlack, True, False, SpDPIScale(2)); + SpDrawArrow(ACanvas, R.Left + (R.Right - R.Left) div 2, R.Top + (R.Bottom - R.Top) div 2 - PPIScale(1), clBlack, True, False, PPIScale(2)); R := ARect; - InflateRect(R, -SpDPIScale(1), -SpDPIScale(1)); + InflateRect(R, -PPIScale(1), -PPIScale(1)); SpDrawRectangle(ACanvas, R, 0, clBtnFace, clBtnFace); end; @@ -338,7 +382,7 @@ function TSpTBXColorEditButton.DoDrawItem(ACanvas: TCanvas; ARect: TRect; Result := True; if Assigned(OnDraw) then OnDraw(Self, ACanvas, ARect, PaintStage, Result); if Result then - SpDrawColorDropDownButton(ACanvas, ARect, Pushed, FSelectedColor); + SpDrawColorDropDownButton(ACanvas, ARect, Pushed, FSelectedColor, PPIScale); end else Result := inherited DoDrawItem(ACanvas, ARect, PaintStage); @@ -433,10 +477,7 @@ procedure TSpTBXColorEdit.SetSelectedFormat(const Value: TSpTBXColorTextType); procedure TSpTBXColorEdit.UpdateTextFromValue; begin - if (SelectedColor = clNone) or (SelectedColor = clDefault) then - Text := ColorToString(SelectedColor) - else - Text := SpColorToString(SelectedColor, FSelectedFormat); + Text := SpColorToString(SelectedColor, FSelectedFormat); SelStart := Length(Text); end; @@ -473,12 +514,7 @@ constructor TSpTBXFontComboBoxPreview.Create(AOwner: TComponent); Visible := False; SetBounds(0, 0, 0, 0); Color := CurrentSkin.GetThemedSystemColor(clWindow); - FPreviewPanel := TPanel.Create(Self); - FPreviewPanel.Parent := Self; - FPreviewPanel.Color := CurrentSkin.GetThemedSystemColor(clWindow); - FPreviewPanel.Font.Color := CurrentSkin.GetThemedSystemColor(clWindowText); - FPreviewPanel.BevelOuter := bvNone; - FPreviewPanel.Align := alClient; + Font.Color := CurrentSkin.GetThemedSystemColor(clWindowText); end; procedure TSpTBXFontComboBoxPreview.CreateParams(var Params: TCreateParams); @@ -495,11 +531,14 @@ procedure TSpTBXFontComboBoxPreview.CreateParams(var Params: TCreateParams); end; end; -destructor TSpTBXFontComboBoxPreview.Destroy; +procedure TSpTBXFontComboBoxPreview.Paint; +var + R: TRect; begin - FreeAndNil(FPreviewPanel); - inherited; + R := ClientRect; + Canvas.Font.Assign(Font); + SpDrawXPText(Canvas, Caption, R, DT_SINGLELINE or DT_CENTER or DT_VCENTER); end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -508,22 +547,59 @@ destructor TSpTBXFontComboBoxPreview.Destroy; constructor TSpTBXFontComboBox.Create(AOwner: TComponent); begin inherited Create(AOwner); - FAutoDropDownWidthRightMargin := SpDPIScale(60); + FAutoDropDownWidthRightMargin := 60; // scaled on DoCalcMaxDropDownWidth FFontNamePreview := True; FFontPreview := True; FMaxMRUItems := 5; FMRUCount := 0; AutoItemHeight := False; AutoDropDownWidth := True; + FScaledFontGlyphImgList := TImageList.CreateSize(12, 12); + FScaledFontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXTRUETYPE', clFuchsia); + FScaledFontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXOPENTYPE', clFuchsia); + FFilterFontPitch := [ffScalable, ffMonospaced]; + FFilterFontType := [ffRaster, ffTrueType, ffOpenType]; ItemHeight := 23; end; destructor TSpTBXFontComboBox.Destroy; begin + FreeAndNil(FScaledFontGlyphImgList); FreeAndNil(FPreviewWindow); inherited; end; +procedure TSpTBXFontComboBox.ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); +var + I: Integer; +begin + inherited; + + // Load scaled glyphs + I := MulDiv(12, M, D); // Original size of the glyph is 12 (scaled to 18 and 24) + if I >= 24 then I := 24 + else if I >= 18 then I := 18 + else I := 12; + if I <> FScaledFontGlyphImgList.Width then begin + FScaledFontGlyphImgList.Clear; + FScaledFontGlyphImgList.SetSize(I, I); + case I of + 12: begin // 96 PPI, 1x + FScaledFontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXTRUETYPE', clFuchsia); + FScaledFontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXOPENTYPE', clFuchsia); + end; + 18: begin // 144 PPI, 1.5x + FScaledFontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXTRUETYPE15x', clFuchsia); + FScaledFontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXOPENTYPE15x', clFuchsia); + end; + 24: begin // 192 PPI, 2x + FScaledFontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXTRUETYPE20x', clFuchsia); + FScaledFontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXOPENTYPE20x', clFuchsia); + end; + end; + end; +end; + procedure TSpTBXFontComboBox.Click; begin UpdateSelectedFont(False); @@ -550,14 +626,14 @@ procedure TSpTBXFontComboBox.DropDown; S := 'AaBbYyZz'; FPreviewWindow := TSpTBXFontComboBoxPreview.Create(Self); FPreviewWindow.ParentWindow := Application.Handle; - FPreviewWindow.PreviewPanel.Font.Size := 14; + FPreviewWindow.Font.Size := 14; if Assigned(FOnFontPreview) then FOnFontPreview(Self, S); - FPreviewWindow.PreviewPanel.Caption := S; - Sz := SpGetControlTextSize(FPreviewWindow.PreviewPanel, FPreviewWindow.PreviewPanel.Font, S); - Inc(Sz.cx, SpDPIScale(100)); - Inc(Sz.cy, SpDPIScale(20)); + FPreviewWindow.Caption := S; + Sz := SpGetControlTextSize(FPreviewWindow, FPreviewWindow.Font, S); + Inc(Sz.cx, PPIScale(100)); + Inc(Sz.cy, PPIScale(20)); W := SendMessage(Handle, CB_GETDROPPEDWIDTH, 0, 0); P := Parent.ClientToScreen(Point(Left, Top)); @@ -578,10 +654,8 @@ procedure TSpTBXFontComboBox.DropDown; procedure TSpTBXFontComboBox.DoCalcMaxDropDownWidth; begin - if Items.Count <= 0 then begin - SpFillFontNames(Items); - end; - + if Items.Count <= 0 then + SpFillFontNames(Items, FilterFontPitch, FFilterFontType); inherited; end; @@ -600,14 +674,14 @@ procedure TSpTBXFontComboBox.DoDrawItem(ACanvas: TCanvas; var ARect: TRect; // Draw the item glyph if the font is TrueType/OpenType R := ARect; R.Left := Spacing; - R.Top := R.Top + ((R.Bottom - R.Top) - FontGlyphImgList.Height) div 2; + R.Top := R.Top + ((R.Bottom - R.Top) - FScaledFontGlyphImgList.Height) div 2; ImageIndex := Integer(Items.Objects[Index]) - 1; if ImageIndex > -1 then - FontGlyphImgList.Draw(ACanvas, R.Left, R.Top, ImageIndex); + FScaledFontGlyphImgList.Draw(ACanvas, R.Left, R.Top, ImageIndex); // Draw the item text R := ARect; - R.Left := Spacing + FontGlyphImgList.Width + Spacing; + R.Left := Spacing + FScaledFontGlyphImgList.Width + Spacing; if FFontNamePreview then ACanvas.Font.Name := Items[Index]; Flags := DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX); @@ -622,12 +696,14 @@ procedure TSpTBXFontComboBox.DoDrawItem(ACanvas: TCanvas; var ARect: TRect; end; // Update the Font of the PreviewWindow - if Assigned(FPreviewWindow) and (odSelected in State) then - FPreviewWindow.PreviewPanel.Font.Name := Items[Index]; + if Assigned(FPreviewWindow) and (odSelected in State) then begin + FPreviewWindow.Font.Name := Items[Index]; + FPreviewWindow.Invalidate; + end; end; end; -procedure TSpTBXFontComboBox.MRUAdd(AFontName: TFontName); +procedure TSpTBXFontComboBox.MRUAdd(const AFontName: TFontName); var I, AFontNameIndex: Integer; begin @@ -646,7 +722,7 @@ procedure TSpTBXFontComboBox.MRUAdd(AFontName: TFontName); end; end; -function TSpTBXFontComboBox.MRUDelete(AFontName: TFontName): Boolean; +function TSpTBXFontComboBox.MRUDelete(const AFontName: TFontName): Boolean; var I: Integer; begin @@ -671,6 +747,24 @@ procedure TSpTBXFontComboBox.SetMaxMRUItems(Value: Integer); end; end; +procedure TSpTBXFontComboBox.SetFilterFontPitch(const Value: TSpTBXFontPitchSet); +begin + if FFilterFontPitch <> Value then begin + FFilterFontPitch := Value; + Items.Clear; + DoCalcMaxDropDownWidth; + end; +end; + +procedure TSpTBXFontComboBox.SetFilterFontType(const Value: TSpTBXFontTypeSet); +begin + if FFilterFontType <> Value then begin + FFilterFontType := Value; + Items.Clear; + DoCalcMaxDropDownWidth; + end; +end; + procedure TSpTBXFontComboBox.SetFontNamePreview(const Value: Boolean); begin if FFontNamePreview <> Value then begin @@ -748,7 +842,7 @@ procedure TSpTBXColorListBox.Loaded; PopulateList; end; -procedure TSpTBXColorListBox.AddColor(AColor: TColor; AColorName: string); +procedure TSpTBXColorListBox.AddColor(AColor: TColor; const AColorName: string); begin (inherited Items).AddObject(AColorName, TObject(AColor)); end; @@ -807,13 +901,13 @@ procedure TSpTBXColorListBox.DoDrawItem(ACanvas: TCanvas; var ARect: TRect; if PaintStage = pstPrePaint then begin // Paint the color glyphs R := ARect; - R.Right := R.Left + SpDPIScale(16 + 5); - ARect.Left := R.Right + SpDPIScale(1); + R.Right := R.Left + PPIScale(16 + 5); + ARect.Left := R.Right + PPIScale(1); inherited DoDrawItem(ACanvas, ARect, Index, State, PaintStage, PaintDefault); if PaintDefault then begin SavedBrushColor := ACanvas.Brush.Color; try - InflateRect(R, -SpDPIScale(1), -SpDPIScale(1)); + InflateRect(R, -PPIScale(1), -PPIScale(1)); ACanvas.Brush.Color := Colors[Index]; if (ACanvas.Brush.Color = clNone) and (clbsNoneAsTransparent in Style) then @@ -992,17 +1086,11 @@ procedure TSpTBXColorListBox.SetStyle(const Value: TSpTBXColorListBoxStyles); procedure InitializeStock; begin Screen.Cursors[crSpTBXEyeDropper] := LoadCursor(HInstance, 'CZEYEDROPPER'); - - FontGlyphImgList := TImageList.CreateSize(SpDPIScale(12), SpDPIScale(12)); - FontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXTRUETYPE', clFuchsia); - FontGlyphImgList.ResInstLoad(HInstance, rtBitmap, 'SPTBXOPENTYPE', clFuchsia); - DefaultColorPickerDropDownMenu := TSpTBXColorEditPopupMenu.Create(nil); end; procedure FinalizeStock; begin - FreeAndNil(FontGlyphImgList); FreeAndNil(DefaultColorPickerDropDownMenu); end; diff --git a/Source/SpTBXFormPopupMenu.pas b/Source/SpTBXFormPopupMenu.pas index 026b91e..6547e69 100644 --- a/Source/SpTBXFormPopupMenu.pas +++ b/Source/SpTBXFormPopupMenu.pas @@ -1,7 +1,7 @@ unit SpTBXFormPopupMenu; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -38,7 +38,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -223,9 +223,6 @@ implementation uses Themes, UxTheme, Types, TB2Common, TB2Acc; -const - DefaultBorderSize = 2; - type TCustomFormAccess = class(TCustomForm); @@ -238,7 +235,7 @@ constructor TSpTBXPopupSizeGrip.Create(AOwner: TComponent); if Assigned(AOwner) and (AOwner is TSpTBXCustomWrapperPopupForm) then FPopupForm := AOwner as TSpTBXCustomWrapperPopupForm; Align := alBottom; - Height := SpDPIScale(10); + Height := 10; end; procedure TSpTBXPopupSizeGrip.DoDrawBackground(ACanvas: TCanvas; ARect: TRect; @@ -275,13 +272,13 @@ function TSpTBXPopupSizeGrip.GetGripSizerRect: TRect; pbsSizeableBottom: begin Result := ClientRect; - Result.Left := (Result.Right + Result.Left - SpDPIScale(20)) div 2; - Result.Right := Result.Left + SpDPIScale(20); + Result.Left := (Result.Right + Result.Left - PPIScale(20)) div 2; + Result.Right := Result.Left + PPIScale(20); end; pbsSizeableRightBottom: begin Result := ClientRect; - Result.Left := Result.Right - SpDPIScale(14); + Result.Left := Result.Right - PPIScale(14); end; end; end; @@ -344,7 +341,7 @@ procedure TSpTBXPopupSizeGrip.WMEraseBkgnd(var Message: TWMEraseBkgnd); DoDrawBackground(ACanvas, R, pstPrePaint, PaintDefault); if PaintDefault then begin GR := Rect(0, 0, 0, 0); - SpDrawXPStatusBar(ACanvas, R, GR); + SpDrawXPStatusBar(ACanvas, R, GR, CurrentPPI); end; // Draw the grip @@ -361,21 +358,21 @@ procedure TSpTBXPopupSizeGrip.WMEraseBkgnd(var Message: TWMEraseBkgnd); case FPopupForm.BorderStyle of pbsSizeableBottom: begin - CellR.Top := (CellR.Top + CellR.Bottom - SpDPIScale(4)) div 2 + SpDPIScale(1); - CellR.Bottom := CellR.Top + SpDPIScale(3); - SpDrawXPGrip(ACanvas, CellR, C1, C2); + CellR.Top := (CellR.Top + CellR.Bottom - PPIScale(4)) div 2 + PPIScale(1); + CellR.Bottom := CellR.Top + PPIScale(3); + SpDrawXPGrip(ACanvas, CellR, C1, C2, CurrentPPI); end; pbsSizeableRightBottom: begin // Draw 2 cells at the bottom - CellR.Left := GR.Right - SpDPIScale(4) * 2; - CellR.Top := CellR.Bottom - SpDPIScale(4); - SpDrawXPGrip(ACanvas, CellR, C1, C2); + CellR.Left := GR.Right - PPIScale(4) * 2; + CellR.Top := CellR.Bottom - PPIScale(4); + SpDrawXPGrip(ACanvas, CellR, C1, C2, CurrentPPI); // Draw 1 cell at the top CellR.Bottom := CellR.Top; - CellR.Top := CellR.Bottom - SpDPIScale(4); - CellR.Left := CellR.Left + SpDPIScale(4); - SpDrawXPGrip(ACanvas, CellR, C1, C2); + CellR.Top := CellR.Bottom - PPIScale(4); + CellR.Left := CellR.Left + PPIScale(4); + SpDrawXPGrip(ACanvas, CellR, C1, C2, CurrentPPI); end; end; end; @@ -699,7 +696,7 @@ procedure TSpTBXCustomWrapperPopupForm.WMActivate(var Message: TWMActivate); procedure TSpTBXCustomWrapperPopupForm.WMNCCalcSize(var Message: TWMNCCalcSize); begin Message.Result := 0; - InflateRect(Message.CalcSize_Params^.rgrc[0], -DefaultBorderSize, -DefaultBorderSize); + InflateRect(Message.CalcSize_Params^.rgrc[0], -SpDefaultBorderSize, -SpDefaultBorderSize); end; procedure TSpTBXCustomWrapperPopupForm.WMNCHitTest(var Message: TWMNCHitTest); @@ -755,7 +752,7 @@ procedure PopupWindowNCPaintProc(Wnd: HWND; DC: HDC; AppData: TObject); PopupWindow := TSpTBXCustomWrapperPopupForm(AppData); if PopupWindow.FPaintingClientArea then begin PopupWindow.FPaintingClientArea := False; - OffsetRect(R, -DefaultBorderSize, -DefaultBorderSize); + OffsetRect(R, -SpDefaultBorderSize, -SpDefaultBorderSize); end; PopupWindow.PaintBackground(ACanvas, R); @@ -785,7 +782,7 @@ procedure TSpTBXCustomWrapperPopupForm.WMNCPaint(var Message: TMessage); // Make sure we clip the client area Windows.GetWindowRect(Handle, R); OffsetRect(R, -R.Left, -R.Top); - InflateRect(R, -DefaultBorderSize, -DefaultBorderSize); + InflateRect(R, -SpDefaultBorderSize, -SpDefaultBorderSize); ExcludeClipRect(DC, R.Left, R.Top, R.Right, R.Bottom); PopupWindowNCPaintProc(Handle, DC, Self); @@ -862,7 +859,7 @@ procedure TSpTBXWrapperPopupForm.CMShowingChanged(var Message: TMessage); procedure TSpTBXWrapperPopupForm.PaintBackground(ACanvas: TCanvas; ARect: TRect); begin - SpDrawXPMenuPopupWindow(ACanvas, ARect, Rect(0, 0, 0, 0), False, 0); + SpDrawXPMenuPopupWindow(ACanvas, ARect, Rect(0, 0, 0, 0), False, 0, CurrentPPI); end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -972,6 +969,9 @@ function TSpTBXFormPopupMenu.InternalPopup(X, Y: Integer; ForceFocus: Boolean; var ClientR: TRect; FC: TCustomFormClass; + {$IF CompilerVersion > 32} + PPI: Integer; + {$IFEND} begin Result := False; SetPopupPoint(Point(X, Y)); @@ -986,6 +986,16 @@ function TSpTBXFormPopupMenu.InternalPopup(X, Y: Integer; ForceFocus: Boolean; // Use the WrapperForm to show the PopupForm if Assigned(FPopupForm) then begin + {$IF CompilerVersion > 32} + // Normally, setting the Parent scales the Form but here it doesn't because + // FPopupForm has a FreeNotification (see TControl.SetParent) + if Assigned(PopupControl) then + PPI := PopupControl.CurrentPPI + else + PPI := Screen.MonitorFromPoint(Point(X, Y)).PixelsPerInch; + TCustomFormAccess(FPopupForm).ScaleForPPI(PPI); + FWrapperForm.ScaleForPPI(PPI); + {$IFEND} FPopupFormState.PopupForm := FPopupForm; FPopupFormState.BorderStyle := FPopupForm.BorderStyle; FPopupFormState.BoundsRect := FPopupForm.BoundsRect; @@ -995,7 +1005,6 @@ function TSpTBXFormPopupMenu.InternalPopup(X, Y: Integer; ForceFocus: Boolean; ClientR.Right := FPopupFormPrevSize.cx; ClientR.Bottom := FPopupFormPrevSize.cy; end; - FPopupForm.Parent := FWrapperForm; FPopupForm.Align := alClient; FPopupForm.BorderStyle := bsNone; @@ -1004,9 +1013,9 @@ function TSpTBXFormPopupMenu.InternalPopup(X, Y: Integer; ForceFocus: Boolean; if Assigned(FOnBeforePopup) then FOnBeforePopup(Self, ClientR.Right, ClientR.Bottom); if Assigned(PopupControl) then - FWrapperForm.RollDown(PopupControl, ClientR.Right + DefaultBorderSize * 2, ClientR.Bottom + DefaultBorderSize * 2, False, ForceFocus) + FWrapperForm.RollDown(PopupControl, ClientR.Right + SpDefaultBorderSize * 2, ClientR.Bottom + SpDefaultBorderSize * 2, False, ForceFocus) else - FWrapperForm.RollDown(X, Y, ClientR.Right + DefaultBorderSize * 2, ClientR.Bottom + DefaultBorderSize * 2, ForceFocus); + FWrapperForm.RollDown(X, Y, ClientR.Right + SpDefaultBorderSize * 2, ClientR.Bottom + SpDefaultBorderSize * 2, ForceFocus); if Assigned(OnPopup) then OnPopup(Self); Result := True; diff --git a/Source/SpTBXItem.pas b/Source/SpTBXItem.pas index c370282..6a2a352 100644 --- a/Source/SpTBXItem.pas +++ b/Source/SpTBXItem.pas @@ -1,7 +1,7 @@ unit SpTBXItem; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -66,18 +66,19 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses Windows, Messages, Classes, SysUtils, Forms, Controls, Graphics, ImgList, - Menus, StdCtrls, ActnList, + Menus, StdCtrls, ActnList, StrUtils, TB2Item, TB2Dock, TB2Toolbar, TB2ToolWindow, SpTBXSkins; 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 + rvDPI = 'DPI'; // Constant used to save the Toolbar CurrentPPI with the Customizer. Do not localize! rvSpTBXDisplayMode = 'DisplayMode'; // Constant used to save the Toolbar DisplayMode with the Customizer. Do not localize! CPDefaultCols = 8; // ColorPalette constant CPDefaultRows = 5; // ColorPalette constant @@ -295,9 +296,9 @@ TSpTBXCustomItem = class(TTBCustomItem) 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 Margins: Integer read FMargins write SetMargins default 0; // Unscaled + property MinHeight: Integer read FMinHeight write SetMinHeight default 0; // Unscaled + property MinWidth: Integer read FMinWidth write SetMinWidth default 0; // Unscaled 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 @@ -325,9 +326,6 @@ TSpTBXItemViewer = class(TTBItemViewer) 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 @@ -346,7 +344,6 @@ TSpTBXItemViewer = class(TTBItemViewer) // 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; @@ -372,6 +369,9 @@ TSpTBXItem = class(TSpTBXCustomItem) property GroupIndex; property HelpContext; property ImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName; + {$IFEND} property Images; property InheritOptions; property MaskOptions; @@ -517,6 +517,9 @@ TSpTBXLabelItem = class(TSpTBXCustomLabelItem) published property Enabled; property ImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName; + {$IFEND} property Images; property InheritOptions; property MaskOptions; @@ -560,6 +563,9 @@ TSpTBXSeparatorItemViewer = class(TTBSeparatorItemViewer) TSpTBXRightAlignSpacerItem = class(TSpTBXCustomLabelItem) published property ImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName; + {$IFEND} property Images; property MaskOptions; property Options; @@ -812,18 +818,17 @@ TSpTBXItemCacheCollection = class(TCollection) TSpTBXDock = class(TTBDock) private - FMoving: Boolean; FResizing: Boolean; - FPrevWidth: Integer; - FPrevHeight: Integer; + FScaling: Boolean; 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; + FPrevSize: TSize; + procedure ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); override; procedure DrawBackground(DC: HDC; const DrawRect: TRect); override; + procedure DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; const Clip: HRGN); override; procedure DoDrawBackground(ACanvas: TCanvas; ARect: TRect; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual; procedure Resize; override; function UsingBackground: Boolean; override; @@ -831,8 +836,6 @@ TSpTBXDock = class(TTBDock) 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; @@ -870,7 +873,6 @@ TSpTBXToolbar = class(TTBCustomToolbar) FItemMovingCount: Integer; FDisplayMode: TSpTBXToolbarDisplayMode; FLastDropMark: TRect; - FLastSelectableWidth: Integer; FMenuBar: Boolean; FOnDrawBackground: TSpTBXDrawEvent; FOnItemNotification: TSpTBXItemNotificationEvent; @@ -891,12 +893,11 @@ TSpTBXToolbar = class(TTBCustomToolbar) procedure SetCustomizable(const Value: Boolean); protected FBeginDragIV: TTBItemViewer; - FAnchoredControlItems: TSpTBXItemCacheCollection; FState: TSpTBXToolbarStates; // Component procedure Resize; override; - procedure AnchorItems(UpdateControlItems: Boolean = True); virtual; + procedure AnchorItems(Delta: Integer); virtual; procedure RightAlignItems; virtual; // Painting @@ -924,6 +925,7 @@ TSpTBXToolbar = class(TTBCustomToolbar) 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; + procedure ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); override; property CompoundToolbar: Boolean read FCompoundToolbar write FCompoundToolbar; public @@ -997,6 +999,8 @@ TSpTBXToolbar = class(TTBCustomToolbar) property OnMouseMove; property OnMouseUp; property OnMove; + property OnMouseEnter; + property OnMouseLeave; property OnRecreated; property OnRecreating; property OnDockChanged; @@ -1036,6 +1040,7 @@ TSpTBXCustomToolWindow = class(TTBCustomDockableWindow) function GetFloatingWindowParentClass: TTBFloatingWindowParentClass; override; // Sizing + procedure ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); override; function CalcSize(ADock: TTBDock): TPoint; virtual; function DoArrange(CanMoveControls: Boolean; PreviousDockType: TTBDockType; NewFloating: Boolean; NewDock: TTBDock): TPoint; override; procedure GetBaseSize(var ASize: TPoint); override; @@ -1114,6 +1119,8 @@ TSpTBXToolWindow = class(TSpTBXCustomToolWindow) property OnMouseDown; property OnMouseMove; property OnMouseUp; + property OnMouseWheelDown; + property OnMouseWheelUp; property OnMove; property OnRecreated; property OnRecreating; @@ -1145,7 +1152,6 @@ TSpTBXFloatingWindowParent = class(TTBFloatingWindowParent) 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; @@ -1231,6 +1237,7 @@ TSpTBXPopupMenu = class(TTBPopupMenu, ISpTBXPopupMenu) function GetRootItemClass: TTBRootItemClass; override; public procedure Popup(X: Integer; Y: Integer); override; + procedure PopupAtMousePos; function PopupEx(X, Y: Integer; PopupControl: TControl = nil; ReturnClickedItemOnly: Boolean = False): TTBCustomItem; virtual; published property ToolBoxPopup: Boolean read FToolBoxPopup write FToolBoxPopup default False; @@ -1242,7 +1249,9 @@ TSpTBXPopupMenu = class(TTBPopupMenu, ISpTBXPopupMenu) TSpTBXCustomContainer = class(TSpTBXCustomControl) private + FBorders: Boolean; FOnDrawBackground: TSpTBXDrawEvent; + procedure SetBorders(const Value: Boolean); procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED; procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED; procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED; @@ -1254,6 +1263,7 @@ TSpTBXCustomContainer = class(TSpTBXCustomControl) procedure CreateParams(var Params: TCreateParams); override; procedure DoDrawBackground(ACanvas: TCanvas; ARect: TRect; const PaintStage: TSpTBXPaintStage; var PaintDefault: Boolean); virtual; procedure DrawBackground(ACanvas: TCanvas; ARect: TRect); virtual; + property Borders: Boolean read FBorders write SetBorders default True; property ParentColor default False; property OnDrawBackground: TSpTBXDrawEvent read FOnDrawBackground write FOnDrawBackground; public @@ -1330,7 +1340,6 @@ TSpTBXButtonOptions = class(TPersistent) FMinimize: Boolean; FMaximize: Boolean; FButtonBorders: Boolean; - FTitleBarMaxSize: Integer; procedure SetCaptionImageIndex(Value: Integer); procedure SetCloseImageIndex(Value: Integer); procedure SetCaptionLabel(const Value: string); @@ -1341,6 +1350,7 @@ TSpTBXButtonOptions = class(TPersistent) procedure SetClose(const Value: Boolean); procedure SetMaximize(const Value: Boolean); procedure SetMinimize(const Value: Boolean); + function GetTitleBarMaxSize: Integer; procedure SetTitleBarMaxSize(const Value: Integer); protected FParentControl: TWinControl; @@ -1378,7 +1388,7 @@ TSpTBXButtonOptions = class(TPersistent) 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; + property TitleBarMaxSize: Integer read GetTitleBarMaxSize write SetTitleBarMaxSize default 21; end; { TSpTBXStatusBar } @@ -1626,9 +1636,6 @@ TBitmapHint = class(THintWindow) procedure ActivateHintData(Rect: TRect; const AHint: string; AData: Pointer); override; end; -{ Constants } -function CDefaultToolbarBorderSize: Integer; - { Item helpers } procedure SpFillItemInfo(ACanvas: TCanvas; IV: TTBItemViewer; out ItemInfo: TSpTBXMenuItemInfo); function SpGetBoundsRect(IV: TTBItemViewer; Root: TTBRootItem): TRect; @@ -1643,21 +1650,20 @@ 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; ComboPart: TSpTBXComboPart = cpNone); +procedure SpDrawXPToolbarButton(ACanvas: TCanvas; ARect: TRect; State: TSpTBXSkinStatesType; ComboPart: TSpTBXComboPart; DPI: Integer); procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo); -procedure SpDrawXPMenuSeparator(ACanvas: TCanvas; ARect: TRect; MenuItemStyle, Vertical: Boolean); +procedure SpDrawXPMenuSeparator(ACanvas: TCanvas; ARect: TRect; MenuItemStyle, Vertical: Boolean; DPI: Integer); procedure SpDrawXPMenuItemImage(ACanvas: TCanvas; ARect: TRect; const ItemInfo: TSpTBXMenuItemInfo; ImageList: TCustomImageList; ImageIndex: Integer); -procedure SpDrawXPMenuGutter(ACanvas: TCanvas; ARect: TRect); -procedure SpDrawXPMenuPopupWindow(ACanvas: TCanvas; ARect, OpenIVRect: TRect; DrawGutter: Boolean; ImageSize: Integer); -procedure SpDrawXPStatusBar(ACanvas: TCanvas; ARect, AGripRect: TRect); -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; Vertical: Boolean = False); +procedure SpDrawXPMenuGutter(ACanvas: TCanvas; ARect: TRect; DPI: Integer); +procedure SpDrawXPMenuPopupWindow(ACanvas: TCanvas; ARect, OpenIVRect: TRect; DrawGutter: Boolean; ImageSize: Integer; DPI: Integer); +procedure SpDrawXPStatusBar(ACanvas: TCanvas; ARect, AGripRect: TRect; DPI: Integer); +procedure SpDrawXPTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive, DrawBorders: Boolean; DPI: Integer); +procedure SpDrawXPTitleBarBody(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean; BorderSize: TPoint; DrawBody: Boolean; DPI: Integer); +procedure SpDrawXPDock(ACanvas: TCanvas; ARect: TRect; Vertical: Boolean; DPI: Integer); procedure SpDrawXPToolbar(ACanvas: TCanvas; ARect: TRect; 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); @@ -1696,6 +1702,7 @@ procedure SpEndUpdateAllToolbars(AParentComponent: TComponent); SpStockHintBitmap: TBitmap; MDIButtonsImgList: TImageList = nil; SpTBXHintWindowClass: THintWindowClass = TBitmapHint; + StatLogFileName: string; const crSpTBXNewHandPoint = 100; // Cursor ID to replace crHandPoint for IDC_HAND @@ -1709,7 +1716,7 @@ implementation uses Themes, UxTheme, TypInfo, Types, - {$IF CompilerVersion >= 25} // for Delphi XE4 and up + {$IF CompilerVersion >= 24} // for Delphi XE3 and up System.UITypes, {$IFEND} ComCtrls, CommCtrl, ShellApi, DwmApi, @@ -1779,17 +1786,6 @@ TWinControlAccess = class(TWinControl); TCustomFormAccess = class(TCustomForm); TActionLinkAccess = class(TActionLink); -//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM -{ Constants } - -function CDefaultToolbarBorderSize: Integer; -begin - // Default size of Docked and Floating Toolbar borders - // Constant defined on implementation section of TB2Dock - // as DockedBorderSize - Result := SpDPIScale(2); -end; - //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Item Helpers } @@ -1832,6 +1828,7 @@ procedure SpFillItemInfo(ACanvas: TCanvas; IV: TTBItemViewer; out ItemInfo: TSpT end; FillChar(ItemInfo, SizeOf(ItemInfo), 0); + ItemInfo.CurrentPPI := View.Window.CurrentPPI; ItemInfo.Enabled := Item.Enabled or View.Customizing; ItemInfo.Pushed := IsPushed; ItemInfo.Checked := Item.Checked; @@ -1864,9 +1861,9 @@ procedure SpFillItemInfo(ACanvas: TCanvas; IV: TTBItemViewer; out ItemInfo: TSpT else begin // Only for menu items if View.Window is TSpTBXPopupWindow then - CurrentSkin.GetMenuItemMargins(ACanvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, ItemInfo.MenuMargins) + CurrentSkin.GetMenuItemMargins(ACanvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, ItemInfo.MenuMargins, ItemInfo.CurrentPPI) else - CurrentSkin.GetMenuItemMargins(ACanvas, ImgSize.cx, ItemInfo.MenuMargins); + CurrentSkin.GetMenuItemMargins(ACanvas, ImgSize.cx, ItemInfo.MenuMargins, ItemInfo.CurrentPPI); end; if tbisClicksTransparent in Item.ItemStyle then @@ -2232,20 +2229,6 @@ procedure SpGetDropPosItemViewer(Root: TTBRootItem; View: TTBView; P: TPoint; 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 := SpDPIScale(DragHandleSizes[T.CloseButtonWhenDocked, Ord(T.DragHandleStyle)]); - end; -end; - function SpIsVerticalToolbar(Toolbar: TTBCustomDockableWindow): Boolean; begin if Assigned(Toolbar.CurrentDock) then @@ -2266,7 +2249,7 @@ function SpIsDockUsingBitmap(Dock: TTBDock): Boolean; { Painting helpers } procedure SpDrawXPToolbarButton(ACanvas: TCanvas; ARect: TRect; State: TSpTBXSkinStatesType; - ComboPart: TSpTBXComboPart = cpNone); + ComboPart: TSpTBXComboPart; DPI: Integer); // Paints a toolbar button depending on the State and SkinType var ForceRectBorders: TAnchors; @@ -2327,7 +2310,7 @@ procedure SpDrawXPToolbarButton(ACanvas: TCanvas; ARect: TRect; State: TSpTBXSki Details := SpTBXThemeServices.GetElementDetails(ttbSplitButtonDropDownNormal); end; end; - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); end; sknSkin: begin @@ -2365,7 +2348,7 @@ procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuI Windows.DrawEdge(ACanvas.Handle, ARect, BDR_RAISEDINNER, BF_RECT); end else - SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.ComboPart); + SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.ComboPart, ItemInfo.CurrentPPI); end; sknWindows, sknDelphiStyle: if ItemInfo.IsDesigning then @@ -2374,14 +2357,14 @@ procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuI if ItemInfo.IsOnMenuBar then begin if SpIsWinVistaOrUp or (ItemInfo.SkinType = sknDelphiStyle) then begin if ItemInfo.State <> sknsNormal then - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncMenuBarItem, ItemInfo.State); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncMenuBarItem, ItemInfo.State, ItemInfo.CurrentPPI); end else if ItemInfo.State in [sknsHotTrack, sknsPushed, sknsChecked, sknsCheckedAndHotTrack] then SpFillRect(ACanvas, ARect, clHighlight); end else - SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.ComboPart); + SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.ComboPart, ItemInfo.CurrentPPI); sknSkin: if ItemInfo.IsOpen and CurrentSkin.OfficePopup then begin // Paints skncOpenToolbarItem skin, hide the bottom border @@ -2395,7 +2378,7 @@ procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuI if ItemInfo.IsOnMenuBar then CurrentSkin.PaintBackground(ACanvas, ARect, skncMenuBarItem, ItemInfo.State, True, True, False, ForceRectBorders) else - SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.ComboPart); + SpDrawXPToolbarButton(ACanvas, ARect, ItemInfo.State, ItemInfo.ComboPart, ItemInfo.CurrentPPI); end; end; @@ -2406,7 +2389,7 @@ procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuI SpFillRect(ACanvas, ARect, clHighlight); sknWindows, sknDelphiStyle: if SpIsWinVistaOrUp or (ItemInfo.SkinType = sknDelphiStyle) then - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncMenuItem, ItemInfo.Enabled, False, ItemInfo.HotTrack, False, False, False, False) + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncMenuItem, ItemInfo.Enabled, False, ItemInfo.HotTrack, False, False, False, False, ItemInfo.CurrentPPI) else SpFillRect(ACanvas, ARect, clHighlight); sknSkin: @@ -2505,7 +2488,7 @@ procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuI else if ItemInfo.ImageShown then Details.State := MCB_BITMAP else Details.State := MCB_NORMAL; {$IFEND} - CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details, ItemInfo.CurrentPPI); end else ToolbarItemDraw(R); @@ -2521,13 +2504,13 @@ procedure SpDrawXPMenuItem(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuI else C := CurrentSkin.GetThemedSystemColor(clBtnShadow); R := ARect; - R.Left := ARect.Right - 10 - 4; + R.Left := ARect.Right - SpPPIScale(14, ItemInfo.CurrentPPI); 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); +procedure SpDrawXPMenuSeparator(ACanvas: TCanvas; ARect: TRect; MenuItemStyle, Vertical: Boolean; DPI: Integer); const ToolbarPartFlags: array [Boolean] of Integer = (TP_SEPARATORVERT, TP_SEPARATOR); var @@ -2560,9 +2543,9 @@ procedure SpDrawXPMenuSeparator(ACanvas: TCanvas; ARect: TRect; MenuItemStyle, V Details.Part := MENU_POPUPSEPARATOR; Details.State := 0; {$IFEND} - VistaSeparatorSize := CurrentSkin.GetThemedElementSize(ACanvas, Details); + VistaSeparatorSize := CurrentSkin.GetThemedElementSize(ACanvas, Details, DPI); // Returns a scaled value R := SpCenterRectVert(R, VistaSeparatorSize.cy); - CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details, DPI); end else if Vertical then begin @@ -2576,7 +2559,7 @@ procedure SpDrawXPMenuSeparator(ACanvas: TCanvas; ARect: TRect; MenuItemStyle, V end else begin CurrentSkin.GetThemedElementDetails(skncSeparator, Vertical, False, False, False, False, False, False, Details); - CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details, DPI); end; sknSkin: if not Vertical then begin @@ -2614,22 +2597,20 @@ procedure SpDrawXPMenuItemImage(ACanvas: TCanvas; ARect: TRect; end; if ItemInfo.Enabled and SkinManager.CurrentSkin.OfficeIcons then begin - // Draw icon shadow + // Draw icon shadow for Office style icons 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; + else + if ItemInfo.IsSunkenCaption then OffsetRect(ARect, 1, 1); + + SpDrawVirtualImageList(ACanvas, ARect, ImageList, ImageIndex, ItemInfo.Enabled); end; -procedure SpDrawXPMenuGutter(ACanvas: TCanvas; ARect: TRect); +procedure SpDrawXPMenuGutter(ACanvas: TCanvas; ARect: TRect; DPI: Integer); var Op: TSpTBXSkinOptionCategory; C: TColor; @@ -2645,7 +2626,7 @@ procedure SpDrawXPMenuGutter(ACanvas: TCanvas; ARect: TRect); sknNone:; // No gutter on Windows 9x, 2000 and XP sknWindows, sknDelphiStyle: // Only Windows Vista painting if CurrentSkin.GetThemedElementDetails(skncGutter, sknsNormal, Details) then - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); sknSkin: begin Op := CurrentSkin.Options(skncGutter, sknsNormal); @@ -2667,7 +2648,7 @@ procedure SpDrawXPMenuGutter(ACanvas: TCanvas; ARect: TRect); end; procedure SpDrawXPMenuPopupWindow(ACanvas: TCanvas; ARect, OpenIVRect: TRect; - DrawGutter: Boolean; ImageSize: Integer); + DrawGutter: Boolean; ImageSize: Integer; DPI: Integer); var GutterR: TRect; MarginsInfo: TSpTBXMenuItemMarginsInfo; @@ -2692,7 +2673,7 @@ procedure SpDrawXPMenuPopupWindow(ACanvas: TCanvas; ARect, OpenIVRect: TRect; begin SaveIndex := SaveDC(ACanvas.Handle); try - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncPopup, sknsNormal); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncPopup, sknsNormal, DPI); // Now paint the borders, clip the background ExcludeClipRect(ACanvas.Handle, ARect.Left + 2, ARect.Top + 2, ARect.Right - 2, ARect.Bottom - 2); // [Old-Themes] @@ -2703,7 +2684,7 @@ procedure SpDrawXPMenuPopupWindow(ACanvas: TCanvas; ARect, OpenIVRect: TRect; Details.Part := MENU_POPUPBORDERS; Details.State := 0; {$IFEND} - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); finally RestoreDC(ACanvas.Handle, SaveIndex); end; @@ -2735,20 +2716,21 @@ procedure SpDrawXPMenuPopupWindow(ACanvas: TCanvas; ARect, OpenIVRect: TRect; // 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); + CurrentSkin.GetMenuItemMargins(ACanvas, ImageSize, MarginsInfo, DPI); 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); + SpDrawXPMenuGutter(ACanvas, GutterR, DPI); end; end; end; end; -procedure SpDrawXPStatusBar(ACanvas: TCanvas; ARect, AGripRect: TRect); +procedure SpDrawXPStatusBar(ACanvas: TCanvas; ARect, AGripRect: TRect; DPI: Integer); var R: TRect; C1, C2: TColor; + I: Integer; begin case SkinManager.GetSkinType of sknNone: @@ -2765,9 +2747,9 @@ procedure SpDrawXPStatusBar(ACanvas: TCanvas; ARect, AGripRect: TRect); sknWindows, sknDelphiStyle: begin if not IsRectEmpty(ARect) then - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncStatusBar, True, False, False, False, False, False, False); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncStatusBar, True, False, False, False, False, False, False, DPI); if not IsRectEmpty(AGripRect) then - CurrentSkin.PaintThemedElementBackground(ACanvas, AGripRect, skncStatusBarGrip, True, False, False, False, False, False, False); + CurrentSkin.PaintThemedElementBackground(ACanvas, AGripRect, skncStatusBarGrip, True, False, False, False, False, False, False, DPI); end; sknSkin: begin @@ -2778,26 +2760,27 @@ procedure SpDrawXPStatusBar(ACanvas: TCanvas; ARect, AGripRect: TRect); R := AGripRect; C1 := SkinManager.CurrentSkin.Options(skncStatusBarGrip).Body.Color1; C2 := SkinManager.CurrentSkin.Options(skncStatusBarGrip).Body.Color2; + I := SpPPIScale(4, DPI); // Draw 3 cells at the bottom - R.Left := R.Right - SpDPIScale(4) * 3; - R.Top := R.Bottom - SpDPIScale(4); - SpDrawXPGrip(ACanvas, R, C1, C2); + R.Left := R.Right - I * 3; + R.Top := R.Bottom - I; + SpDrawXPGrip(ACanvas, R, C1, C2, DPI); // Draw 2 cells at the top R.Bottom := R.Top; - R.Top := R.Bottom - SpDPIScale(4); - R.Left := R.Left + SpDPIScale(4); - SpDrawXPGrip(ACanvas, R, C1, C2); + R.Top := R.Bottom - I; + R.Left := R.Left + I; + SpDrawXPGrip(ACanvas, R, C1, C2, DPI); // Draw 1 cell at the top R.Bottom := R.Top; - R.Top := R.Bottom - SpDPIScale(4); - R.Left := R.Left + SpDPIScale(4); - SpDrawXPGrip(ACanvas, R, C1, C2); + R.Top := R.Bottom - I; + R.Left := R.Left + I; + SpDrawXPGrip(ACanvas, R, C1, C2, DPI); end; end; end; end; -procedure SpDrawXPTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean; DrawBorders: Boolean = True); +procedure SpDrawXPTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive, DrawBorders: Boolean; DPI: Integer); const W9xFlags: array [Boolean] of Integer = (0, DC_ACTIVE); W9xGradientFlag: array [Boolean] of Integer = (0, DC_GRADIENT); @@ -2821,23 +2804,23 @@ procedure SpDrawXPTitleBar(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean; Dr B := TBitmap.Create; try CurrentSkin.GetThemedElementDetails(skncWindowTitleBar, IsActive, False, False, False, False, False, False, Details); - ElementSize := CurrentSkin.GetThemedElementSize(ACanvas, Details); + ElementSize := CurrentSkin.GetThemedElementSize(ACanvas, Details, DPI); // Returns a scaled value B.SetSize(ARect.Right - ARect.Left, ElementSize.cy); - CurrentSkin.PaintThemedElementBackground(B.Canvas, Rect(0, 0, B.Width, B.Height), Details); + CurrentSkin.PaintThemedElementBackground(B.Canvas, Rect(0, 0, B.Width, B.Height), Details, DPI); ACanvas.StretchDraw(ARect, B); finally B.Free; end; end else - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncWindowTitleBar, IsActive, False, False, False, False, False, False); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncWindowTitleBar, IsActive, False, False, False, False, False, False, DPI); sknSkin: CurrentSkin.PaintBackground(ACanvas, ARect, skncWindowTitleBar, sknsNormal, True, DrawBorders); end; end; procedure SpDrawXPTitleBarBody(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean; - BorderSize: TPoint; DrawBody: Boolean = True); + BorderSize: TPoint; DrawBody: Boolean; DPI: Integer); var R, MirrorR: TRect; SaveIndex: Integer; @@ -2882,22 +2865,25 @@ procedure SpDrawXPTitleBarBody(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean RightBorder := TThemedWindow(Ord(RightBorder) + 1); end; + // Do not scale borders, set DPI to 96 + DPI := 96; + R := ARect; Details := SpTBXThemeServices.GetElementDetails(LeftBorder); R.Top := ARect.Top + BorderSize.Y; R.Bottom := ARect.Bottom - BorderSize.Y; R.Right := R.Left + BorderSize.X; - CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details, DPI); Details := SpTBXThemeServices.GetElementDetails(RightBorder); R.Right := ARect.Right; R.Left := R.Right - BorderSize.X; - CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details, DPI); Details := SpTBXThemeServices.GetElementDetails(BottomBorder); R := ARect; R.Top := R.Bottom - BorderSize.Y; - CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, R, Details, DPI); // Don't know how to paint a captionless window frame // We have to mirror the bottom frame and paint it on the top @@ -2906,7 +2892,7 @@ procedure SpDrawXPTitleBarBody(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean R := ARect; R.Bottom := R.Top + BorderSize.Y; B.SetSize(R.Right - R.Left, R.Bottom - R.Top); - CurrentSkin.PaintThemedElementBackground(B.Canvas, Rect(0, 0, B.Width, B.Height), Details); + CurrentSkin.PaintThemedElementBackground(B.Canvas, Rect(0, 0, B.Width, B.Height), Details, DPI); // Mirror MirrorR := Rect(0, B.Height - 1, B.Width, -1); ACanvas.CopyRect(R, B.Canvas, MirrorR); @@ -2919,7 +2905,7 @@ procedure SpDrawXPTitleBarBody(ACanvas: TCanvas; ARect: TRect; IsActive: Boolean end; end; -procedure SpDrawXPDock(ACanvas: TCanvas; ARect: TRect; Vertical: Boolean = False); +procedure SpDrawXPDock(ACanvas: TCanvas; ARect: TRect; Vertical: Boolean; DPI: Integer); begin case SkinManager.GetSkinType of sknNone: @@ -2932,7 +2918,7 @@ procedure SpDrawXPDock(ACanvas: TCanvas; ARect: TRect; Vertical: Boolean = False if Vertical then Inc(ARect.Bottom, 1); // Fix WindowsXP bug ACanvas.Brush.Color := CurrentSkin.GetThemedSystemColor(clBtnFace); ACanvas.FillRect(ARect); - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncDock, Vertical, False, False, False, False, False, False); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncDock, Vertical, False, False, False, False, False, False, DPI); end; sknSkin: CurrentSkin.PaintBackground(ACanvas, ARect, skncDock, sknsNormal, True, True, Vertical); @@ -2991,7 +2977,7 @@ procedure SpDrawXPToolbar(W: TTBCustomDockableWindow; ACanvas: TCanvas; if not PaintOnNCArea then begin // Called by WMEraseBkgnd, map R from toolbar Canvas to dock Canvas // We need to offset the border size - OffsetRect(R, -CDefaultToolbarBorderSize, -CDefaultToolbarBorderSize) + OffsetRect(R, -Toolbar.CurrentDock.DockedBorderSize, -Toolbar.CurrentDock.DockedBorderSize) end; if Toolbar.CurrentDock is TSpTBXDock then TSpTBXDock(Toolbar.CurrentDock).DrawBackground(ACanvas.Handle, R); @@ -3045,7 +3031,7 @@ procedure SpDrawXPToolbar(W: TTBCustomDockableWindow; ACanvas: TCanvas; procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARect: TRect); var GripR, CloseR: TRect; - GripSize: Integer; + GripSize, PP1, PP2, PP3, PP4: Integer; Vertical: Boolean; C1, C2: TColor; Toolbar: TTBCustomDockableWindowAccess; @@ -3055,7 +3041,7 @@ procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARec begin Toolbar := TTBCustomDockableWindowAccess(W); - GripSize := SpGetDragHandleSize(Toolbar); + GripSize := Toolbar.DragHandleSize; if GripSize <= 0 then Exit; Vertical := SpIsVerticalToolbar(Toolbar); @@ -3070,47 +3056,53 @@ procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARec InflateRect(GripR, 0, -2); end; + W.PPIScale(1); + PP1 := SpPPIScale(1, W.CurrentPPI); + PP2 := SpPPIScale(2, W.CurrentPPI); + PP3 := SpPPIScale(3, W.CurrentPPI); + PP4 := SpPPIScale(4, W.CurrentPPI); + 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 - SpDpiScale(2); - CloseR.Top := ARect.Top + SpDpiScale(2); - CloseR.Bottom := CloseR.Top + GripSize - SpDpiScale(2); - Dec(GripR.Right, GripSize - SpDpiScale(1)); + CloseR.Right := CloseR.Left + GripSize - PP2; + CloseR.Top := ARect.Top + PP2; + CloseR.Bottom := CloseR.Top + GripSize - PP2; + Dec(GripR.Right, GripSize - PP1); end else begin - CloseR.Left := ARect.Left + SpDpiScale(2); - CloseR.Right := CloseR.Left + GripSize - SpDpiScale(2); - CloseR.Top := ARect.Top + SpDpiScale(2); - CloseR.Bottom := CloseR.Top + GripSize - SpDpiScale(2); - Inc(GripR.Top, GripSize - SpDpiScale(1)); + CloseR.Left := ARect.Left + PP2; + CloseR.Right := CloseR.Left + GripSize - PP2; + CloseR.Top := ARect.Top + PP2; + CloseR.Bottom := CloseR.Top + GripSize - PP2; + Inc(GripR.Top, GripSize - PP1); end; end; case SkinManager.GetSkinType of sknNone: begin - OffsetRect(CloseR, -SpDpiScale(1), -SpDpiScale(1)); + OffsetRect(CloseR, -PP1, -PP1); if Vertical then begin if Toolbar.CloseButtonWhenDocked then - if Toolbar.DragHandleStyle = dhDouble then Inc(GripR.Top, SpDpiScale(1)) - else Inc(GripR.Top, SpDpiScale(3)); - Inc(GripR.Top, SpDpiScale(3)); - GripR.Bottom := GripR.Top + SpDpiScale(3); + if Toolbar.DragHandleStyle = dhDouble then Inc(GripR.Top, PP1) + else Inc(GripR.Top, PP3); + Inc(GripR.Top, PP3); + GripR.Bottom := GripR.Top + PP3; end else begin if Toolbar.CloseButtonWhenDocked then - if Toolbar.DragHandleStyle = dhDouble then Inc(GripR.Left, SpDpiScale(1)) - else Inc(GripR.Left, SpDpiScale(3)); - Inc(GripR.Left, SpDpiScale(3)); - GripR.Right := GripR.Left + SpDpiScale(3); + if Toolbar.DragHandleStyle = dhDouble then Inc(GripR.Left, PP1) + else Inc(GripR.Left, PP3); + Inc(GripR.Left, PP3); + GripR.Right := GripR.Left + PP3; 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, SpDpiScale(3)) - else OffsetRect(GripR, SpDpiScale(3), 0); + if Vertical then OffsetRect(GripR, 0, PP3) + else OffsetRect(GripR, PP3, 0); Windows.DrawEdge(ACanvas.Handle, GripR, BDR_RAISEDINNER, BF_RECT); ACanvas.Pixels[GripR.Left, GripR.Bottom - 1] := clBtnHighlight; end; @@ -3122,8 +3114,8 @@ procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARec else if Toolbar. CloseButtonHover then Windows.DrawEdge(ACanvas.Handle, CloseR, BDR_RAISEDINNER, BF_RECT); - if Toolbar.CloseButtonDown then OffsetRect(CloseR, SpDpiScale(1), SpDpiScale(1)); - SpDrawGlyphPattern(ACanvas, CloseR, gptToolbarClose, clBtnText); + if Toolbar.CloseButtonDown then OffsetRect(CloseR, PP1, PP1); + SpDrawGlyphPattern(ACanvas, CloseR, gptToolbarClose, clBtnText, W.CurrentPPI); end; end; sknWindows, sknDelphiStyle: @@ -3131,13 +3123,13 @@ procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARec if SkinManager.GetSkinType = sknDelphiStyle then begin if Vertical then begin Details := SpTBXThemeServices.GetElementDetails(trGripperVert); - Inc(GripR.Left, SpDpiScale(2)); - OffsetRect(GripR, 0, SpDPIScale(2)); + Inc(GripR.Left, PP2); + OffsetRect(GripR, 0, PP2); end else begin Details := SpTBXThemeServices.GetElementDetails(trGripper); - Inc(GripR.Top, SpDpiScale(2)); - OffsetRect(GripR, SpDPIScale(2), 0); + Inc(GripR.Top, PP2); + OffsetRect(GripR, PP2, 0); end; end else begin @@ -3145,22 +3137,22 @@ procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARec // WindowsXP themes where the gripper pattern repeats itself every 4 pixels if Vertical then begin Details := SpTBXThemeServices.GetElementDetails(trGripperVert); - GripR := SpCenterRectVert(GripR, 6); // Do not use SpDPIScale, Windows paints the grip with 4 pixels + GripR := SpCenterRectVert(GripR, 6); // Do not scale, Windows paints the grip with 4 pixels GripR.Right := GripR.Left + ((GripR.Right - GripR.Left) div 4) * 4; - OffsetRect(GripR, 0, SpDPIScale(1)); + OffsetRect(GripR, 0, PP1); end else begin Details := SpTBXThemeServices.GetElementDetails(trGripper); - GripR := SpCenterRectHoriz(GripR, 6); // Do not use SpDPIScale, Windows paints the grip with 4 pixels + GripR := SpCenterRectHoriz(GripR, 6); // Do not scale, Windows paints the grip with 4 pixels GripR.Bottom := GripR.Top + ((GripR.Bottom - GripR.Top) div 4) * 4; - OffsetRect(GripR, SpDPIScale(1), 0); + OffsetRect(GripR, PP1, 0); end; end; // Weird Delphi styles painting bug, we need to clip the bottom SaveIndex := SaveDC(ACanvas.Handle); try - ExcludeClipRect(ACanvas.Handle, ARect.Left, ARect.Bottom - SpDPIScale(3), ARect.Right, ARect.Bottom); + ExcludeClipRect(ACanvas.Handle, ARect.Left, ARect.Bottom - PP3, ARect.Right, ARect.Bottom); SpTBXThemeServices.DrawElement(ACanvas.Handle, Details, GripR); finally RestoreDC(ACanvas.Handle, SaveIndex); @@ -3168,25 +3160,25 @@ procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARec // Close button if Toolbar.CloseButtonWhenDocked then begin - CurrentSkin.PaintThemedElementBackground(ACanvas, CloseR, skncToolbarItem, True, Toolbar.CloseButtonDown, Toolbar.CloseButtonHover, False, False, False, False); - SpDrawGlyphPattern(ACanvas, CloseR, gptToolbarClose, CurrentSkin.GetThemedSystemColor(clBtnText)); + CurrentSkin.PaintThemedElementBackground(ACanvas, CloseR, skncToolbarItem, True, Toolbar.CloseButtonDown, Toolbar.CloseButtonHover, False, False, False, False, W.CurrentPPI); + SpDrawGlyphPattern(ACanvas, CloseR, gptToolbarClose, CurrentSkin.GetThemedSystemColor(clBtnText), W.CurrentPPI); end; end; sknSkin: begin if Vertical then begin - InflateRect(GripR, SpDpiScale(-3), 0); - OffsetRect(GripR, 0, SpDpiScale(2)); - GripR := SpCenterRectVert(GripR, SpDpiScale(4)); + InflateRect(GripR, -PP3, 0); + OffsetRect(GripR, 0, PP2); + GripR := SpCenterRectVert(GripR, PP4); end else begin - InflateRect(GripR, 0, SpDpiScale(-3)); - OffsetRect(GripR, SpDpiScale(2), 0); - GripR := SpCenterRectHoriz(GripR, SpDpiScale(4)); + InflateRect(GripR, 0, -PP3); + OffsetRect(GripR, PP2, 0); + GripR := SpCenterRectHoriz(GripR, PP4); end; C1 := SkinManager.CurrentSkin.Options(skncToolbarGrip).Body.Color1; C2 := SkinManager.CurrentSkin.Options(skncToolbarGrip).Body.Color2; - SpDrawXPGrip(ACanvas, GripR, C1, C2); + SpDrawXPGrip(ACanvas, GripR, C1, C2, W.CurrentPPI); // Close button if Toolbar.CloseButtonWhenDocked then begin @@ -3194,8 +3186,8 @@ procedure SpDrawXPToolbarGrip(W: TTBCustomDockableWindow; ACanvas: TCanvas; ARec 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, SpDpiScale(1), SpDpiScale(1)); - SpDrawGlyphPattern(ACanvas, CloseR, gptToolbarClose, CurrentSkin.GetTextColor(skncToolbarItem, State)); + if Toolbar.CloseButtonDown then OffsetRect(CloseR, PP1, PP1); + SpDrawGlyphPattern(ACanvas, CloseR, gptToolbarClose, CurrentSkin.GetTextColor(skncToolbarItem, State), W.CurrentPPI); end; end; end; @@ -3262,7 +3254,7 @@ procedure SpInvalidateSpTBXControl(AControl: TWinControl; InvalidateChildren: Bo RedrawWindow(ChildW.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN) else if not (ChildW is TSpTBXDock) and not (ChildW is TSpTBXToolbar) then - RedrawWindow(ChildW.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE); + RedrawWindow(ChildW.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE); end; end; end @@ -3977,8 +3969,39 @@ function TSpTBXCustomItem.GetPopupWindowClass: TTBPopupWindowClass; Result := TSpTBXPopupWindow; end; +function IsTextOpen(var f: TextFile): boolean; +begin + with TTextRec(f) do + Result := (Handle <> 0) and (Mode <> fmClosed); +end; + procedure TSpTBXCustomItem.Click; +var + s, s1: string; + t: TextFile; begin + if (Parent is TSpTBXSubmenuItem) and (tboSetSubmenuItem in Options) then + if (Action is TAction) and (TAction(Action)).Enabled then + TSpTBXSubmenuItem(Parent).Action := Action; + if (StatLogFileName <> '') and (Name <> '') then + begin + try + AssignFile(t, StatLogFileName); + if FileExists(StatLogFileName) then + Append(t) + else + Rewrite(t); + except + if IsTextOpen(t) then + CloseFile(t); + Exit; + end; + s := IfThen(Owner.Name <> '', Owner.Name + ' '); + if Assigned(Parent) then + s1 := IfThen(Parent.Name <> '', Parent.Name + ' '); + Writeln(t, s + s1 + Name + ' ' + DateTimeToStr(Now)); + CloseFile(t); + end; if Assigned(FControl) then ToggleControl; inherited; end; @@ -4038,7 +4061,7 @@ procedure TSpTBXCustomItem.SetControl(const Value: TControl); procedure TSpTBXCustomItem.SetCustomWidth(Value: Integer); begin - if Value < -1 then Value := -1; + if Value < 0 then Value := -1; if FCustomWidth <> Value then begin FCustomWidth := Value; Change(True); @@ -4047,7 +4070,7 @@ procedure TSpTBXCustomItem.SetCustomWidth(Value: Integer); procedure TSpTBXCustomItem.SetCustomHeight(Value: Integer); begin - if Value < -1 then Value := -1; + if Value < 0 then Value := -1; if FCustomHeight <> Value then begin FCustomHeight := Value; Change(True); @@ -4151,21 +4174,6 @@ function TSpTBXItemViewer.GetImageShown: Boolean; 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; @@ -4203,6 +4211,7 @@ procedure TSpTBXItemViewer.DoDrawImage(ACanvas: TCanvas; procedure TSpTBXItemViewer.DoDrawAdjustFont(AFont: TFont; State: TSpTBXSkinStatesType); begin Item.FontSettings.Apply(AFont); + AFont.Height := MulDiv(AFont.Height, View.Window.CurrentPPI, AFont.PixelsPerInch); if tboDefault in Item.EffectiveOptions then AFont.Style := AFont.Style + [fsBold]; @@ -4230,7 +4239,7 @@ procedure TSpTBXItemViewer.DrawItemImage(ACanvas: TCanvas; ARect: TRect; PatternColor := clMenuText else PatternColor := GetTextColor(ItemInfo.State); - SpDrawGlyphPattern(ACanvas, ARect, TSpTBXGlyphPattern(ImgIndex), PatternColor); + SpDrawGlyphPattern(ACanvas, ARect, TSpTBXGlyphPattern(ImgIndex), PatternColor, View.Window.CurrentPPI); end else if (ImgIndex >= 0) and (ImgIndex < ImgList.Count) then @@ -4249,7 +4258,7 @@ procedure TSpTBXItemViewer.InternalCalcSize(const Canvas: TCanvas; CalcStretch: Boolean; var AWidth, AHeight: Integer); var I, W, H: Integer; - DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize: Integer; + SplitBtnArrowSize: Integer; ImgSize, RightImgSize: TSize; GlyphTop, ToolbarStyle: Boolean; WS: string; @@ -4260,7 +4269,10 @@ procedure TSpTBXItemViewer.InternalCalcSize(const Canvas: TCanvas; TextInfo: TSpTBXTextInfo; TB: TSpTBXToolbar; begin - CurrentSkin.GetDropDownArrowSize(DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize); + if SkinManager.GetSkinType in [sknWindows, sknDelphiStyle] then + SplitBtnArrowSize := Self.tbDropdownComboArrowWidth + PPIScale(2) // 13 + else + SplitBtnArrowSize := Self.tbDropdownComboArrowWidth + PPIScale(1); // 12 ToolbarStyle := IsToolbarStyle; @@ -4288,14 +4300,14 @@ procedure TSpTBXItemViewer.InternalCalcSize(const Canvas: TCanvas; // Measure size if ToolbarStyle then begin - AWidth := SpDpiScale(6); - AHeight := SpDpiScale(6); + AWidth := PPIScale(6); + AHeight := PPIScale(6); if CaptionShown then begin Inc(AWidth, TextInfo.TextSize.CX); Inc(AHeight, TextInfo.TextSize.CY); - if not TextInfo.IsTextRotated then Inc(AWidth, SpDpiScale(4)) - else Inc(AHeight, SpDpiScale(4)); + if not TextInfo.IsTextRotated then Inc(AWidth, PPIScale(4)) + else Inc(AHeight, PPIScale(4)); end; if GetImageShown and (ImgSize.CX > 0) and (ImgSize.CY > 0) then begin @@ -4303,25 +4315,25 @@ procedure TSpTBXItemViewer.InternalCalcSize(const Canvas: TCanvas; if not TextInfo.IsTextRotated then begin Inc(AWidth, ImgSize.CX); Inc(AWidth); - if AHeight < ImgSize.CY + SpDpiScale(6) then AHeight := ImgSize.CY + SpDpiScale(6); + if AHeight < ImgSize.CY + PPIScale(6) then AHeight := ImgSize.CY + PPIScale(6); end else begin Inc(AHeight, ImgSize.CY); Inc(AHeight); - if AWidth < ImgSize.CX + SpDpiScale(6) then AWidth := ImgSize.CX + SpDpiScale(6); + if AWidth < ImgSize.CX + PPIScale(6) then AWidth := ImgSize.CX + PPIScale(6); end; end else begin Inc(AHeight, ImgSize.CY); - if AWidth < ImgSize.CX + SpDpiScale(7) then AWidth := ImgSize.CX + SpDpiScale(7); + if AWidth < ImgSize.CX + PPIScale(7) then AWidth := ImgSize.CX + PPIScale(7); end; end; if (RightImgSize.cx > 0) and (RightImgSize.cy > 0) then begin if View.Orientation = tbvoVertical then - Inc(AHeight, SpDpiScale(4) + RightImgSize.cy) + Inc(AHeight, PPIScale(4) + RightImgSize.cy) else - Inc(AWidth, SpDpiScale(4) + RightImgSize.cx); + Inc(AWidth, PPIScale(4) + RightImgSize.cx); end; if (tbisSubmenu in Item.ItemStyle) and (tbisCombo in Item.ItemStyle) then @@ -4329,23 +4341,23 @@ procedure TSpTBXItemViewer.InternalCalcSize(const Canvas: TCanvas; 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); + if View.Orientation = tbvoVertical then Inc(AHeight, Self.tbDropdownArrowWidth) + else Inc(AWidth, Self.tbDropdownArrowWidth); end else if GlyphTop and (TextInfo.IsTextRotated xor (View.Orientation <> tbvoVertical)) then begin - W := ImgSize.CX + DropDownArrowSize + SpDpiScale(2); - if W > AWidth - SpDpiScale(7) then AWidth := W + SpDpiScale(7); + W := ImgSize.CX + Self.tbDropdownArrowWidth + PPIScale(2); + if W > AWidth - PPIScale(7) then AWidth := W + PPIScale(7); end else begin - H := ImgSize.CY + DropDownArrowSize + SpDpiScale(2); - if H > AHeight - SpDpiScale(7) then AHeight := H + SpDpiScale(7); + H := ImgSize.CY + Self.tbDropdownArrowWidth + PPIScale(2); + if H > AHeight - PPIScale(7) then AHeight := H + PPIScale(7); end; end; // Widen MenuBar SubMenuItems if (tbisSubmenu in Item.ItemStyle) and (vsMenuBar in View.Style) then - Inc(AWidth, SpDpiScale(6)); + Inc(AWidth, PPIScale(6)); // Toolbar.Stretch property doesn't work correctly, I don't know how to fix // it without changing the TB2K source. @@ -4365,13 +4377,13 @@ procedure TSpTBXItemViewer.InternalCalcSize(const Canvas: TCanvas; AWidth := TextInfo.TextSize.cx; AHeight := TextInfo.TextSize.cy; - if ImgSize.cy = 0 then ImgSize.cy := SpDpiScale(16); + if ImgSize.cy = 0 then ImgSize.cy := PPIScale(16); if AHeight < ImgSize.cy then AHeight := ImgSize.cy; if View.Window is TSpTBXPopupWindow then - CurrentSkin.GetMenuItemMargins(Canvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, MenuMargins) + CurrentSkin.GetMenuItemMargins(Canvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, MenuMargins, View.Window.CurrentPPI) else - CurrentSkin.GetMenuItemMargins(Canvas, ImgSize.cx, MenuMargins); + CurrentSkin.GetMenuItemMargins(Canvas, ImgSize.cx, MenuMargins, View.Window.CurrentPPI); Inc(AWidth, MenuMargins.Margins.Left + MenuMargins.Margins.Right); Inc(AHeight, MenuMargins.Margins.Top + MenuMargins.Margins.Bottom); @@ -4379,36 +4391,45 @@ procedure TSpTBXItemViewer.InternalCalcSize(const Canvas: TCanvas; Inc(AWidth, MenuMargins.GutterSize + MenuMargins.ImageTextSpace + MenuMargins.LeftCaptionMargin + MenuMargins.RightCaptionMargin); WS := Item.GetShortCutText; if Length(WS) > 0 then - Inc(AWidth, (AHeight - SpDpiScale(6)) + SpGetTextSize(Canvas.Handle, WS, True).cx); + Inc(AWidth, (AHeight - PPIScale(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; + if AWidth < PPIScale(Item.MinWidth) then AWidth := PPIScale(Item.MinWidth); + if AHeight < PPIScale(Item.MinHeight) then AHeight := PPIScale(Item.MinHeight); - // Handle Custom size and anchors if IsRotated then begin - // Reverse - H := AWidth + Item.Margins; + H := AWidth + PPIScale(Item.Margins); W := AHeight; end else begin - W := AWidth + Item.Margins; + W := AWidth + PPIScale(Item.Margins); H := AHeight; end; - if Item.CustomWidth > -1 then - W := Item.CustomWidth; - if Item.CustomHeight > -1 then - H := Item.CustomHeight; + // Handle Spacer, anchored and custom sized items + // Do not scale CustomWidth/CustomHeight, it's scaled in TSpTBXToolbar.ChangeScale + // No min size for Anchored items + // 0 is the min size for SpacerItem + if IsRotated then begin + if Item.CustomWidth > -1 then + W := Item.CustomWidth; + if (Item is TSpTBXRightAlignSpacerItem) or (Item.Anchored) or (Item.CustomHeight > -1) then + H := Item.CustomHeight; + end + else begin + if (Item is TSpTBXRightAlignSpacerItem) or (Item.Anchored) or (Item.CustomWidth > -1) then + W := Item.CustomWidth; + if Item.CustomHeight > -1 then + H := Item.CustomHeight; + end; - 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; + if W < PPIScale(Item.MinWidth) then W := PPIScale(Item.MinWidth); + if H < PPIScale(Item.MinHeight) then H := PPIScale(Item.MinHeight); // Apply View.MaxSize to the height of the item if View.Window is TSpTBXToolbar then begin TB := View.Window as TSpTBXToolbar; + // Do not scale MaxSize, it's scaled in TSpTBXToolbar.ChangeScale I := TB.MaxSize - TB.NonClientHeight; if (I > -1) and (H > I) then H := I; @@ -4502,13 +4523,13 @@ procedure TSpTBXItemViewer.GetTextInfo(ACanvas: TCanvas; State: TSpTBXSkinStates 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, SpDPIScale(80)); + R := Rect(0, 0, CaptionRect.Right - CaptionRect.Left, PPIScale(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; + Result.cx := R.Right; + Result.cy := R.Bottom; end; begin @@ -4566,7 +4587,7 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR R, CaptionRect, ImageRect, RightImageRect: TRect; P: TPoint; - DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize, ImgAndArrowWidth: Integer; + SplitBtnArrowSize, ImgAndArrowWidth: Integer; WS: string; TextC, DropDownC: TColor; @@ -4579,7 +4600,11 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR CaptionRect := Rect(0, 0, 0, 0); ImageRect := Rect(0, 0, 0, 0); RightImageRect := Rect(0, 0, 0, 0); - CurrentSkin.GetDropDownArrowSize(DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize); + + if SkinManager.GetSkinType in [sknWindows, sknDelphiStyle] then + SplitBtnArrowSize := Self.tbDropdownComboArrowWidth + PPIScale(2) // 13 + else + SplitBtnArrowSize := Self.tbDropdownComboArrowWidth + PPIScale(1); // 12 View := TTBViewAccess(Self.View); SpFillItemInfo(Canvas, Self, ItemInfo); @@ -4610,19 +4635,19 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR else if not IsSpecialDropDown then begin if View.Orientation <> tbvoVertical then - ItemInfo.ComboRect := Rect(R.Right - DropDownArrowSize - DropDownArrowMargin, 0, - R.Right - DropDownArrowMargin, R.Bottom) + ItemInfo.ComboRect := Rect(R.Right - Self.tbDropdownArrowWidth - Self.tbDropdownArrowMargin, 0, + R.Right - Self.tbDropdownArrowMargin, R.Bottom) else - ItemInfo.ComboRect := Rect(0, R.Bottom - DropDownArrowSize - DropDownArrowMargin, - R.Right, R.Bottom - DropDownArrowMargin); + ItemInfo.ComboRect := Rect(0, R.Bottom - Self.tbDropdownArrowWidth - Self.tbDropdownArrowMargin, + R.Right, R.Bottom - Self.tbDropdownArrowMargin); 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 + SpDPIScale(2); - ItemInfo.ComboRect.Right := (R.Left + R.Right + ImgAndArrowWidth + SpDPIScale(2)) div 2; - ItemInfo.ComboRect.Left := ItemInfo.ComboRect.Right - DropDownArrowSize; - ItemInfo.ComboRect.Top := (R.Top + R.Bottom - ItemInfo.ImageSize.cy - SpDPIScale(2) - TextInfo.TextSize.CY) div 2; + ImgAndArrowWidth := ItemInfo.ImageSize.cx + Self.tbDropdownArrowWidth + PPIScale(2); + ItemInfo.ComboRect.Right := (R.Left + R.Right + ImgAndArrowWidth + PPIScale(2)) div 2; + ItemInfo.ComboRect.Left := ItemInfo.ComboRect.Right - Self.tbDropdownArrowWidth; + ItemInfo.ComboRect.Top := (R.Top + R.Bottom - ItemInfo.ImageSize.cy - PPIScale(2) - TextInfo.TextSize.CY) div 2; ItemInfo.ComboRect.Bottom := ItemInfo.ComboRect.Top + ItemInfo.ImageSize.cy; end; end; @@ -4636,8 +4661,8 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR // Draw dropdown arrow if PaintDefault and ItemInfo.HasArrow then begin - P.X := (ItemInfo.ComboRect.Left + ItemInfo.ComboRect.Right) div 2 - SpDPIScale(1); - P.Y := (ItemInfo.ComboRect.Top + ItemInfo.ComboRect.Bottom) div 2 - SpDPIScale(1); + P.X := (ItemInfo.ComboRect.Left + ItemInfo.ComboRect.Right - 1) div 2; + P.Y := (ItemInfo.ComboRect.Top + ItemInfo.ComboRect.Bottom - 1) div 2; // Don't draw the arrow if is a split button in Windows, it's // painted by the Windows theme. if not (ItemInfo.IsSplit and (ItemInfo.SkinType in [sknWindows, sknDelphiStyle])) then begin @@ -4645,16 +4670,16 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR if ItemInfo.IsSplit and ItemInfo.Enabled then DropDownC := GetTextColor(ItemInfo.ComboState); if ItemInfo.IsSunkenCaption then - P := Point(P.X + SpDPIScale(1), P.Y + SpDPIScale(1)); - SpDrawArrow(Canvas, P.X, P.Y, DropDownC, not ItemInfo.IsVertical, False, SpDPIScale(2)); + P := Point(P.X + PPIScale(1), P.Y + PPIScale(1)); + SpDrawArrow(Canvas, P.X, P.Y, DropDownC, not ItemInfo.IsVertical, False, PPIScale(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); + if View.Orientation <> tbvoVertical then Dec(R.Right, Self.tbDropdownArrowWidth) + else Dec(R.Bottom, Self.tbDropdownArrowWidth); end; end; - InflateRect(R, -SpDPIScale(4), -SpDPIScale(4)); // Adjust + InflateRect(R, -PPIScale(4), -PPIScale(4)); // Adjust end else begin // Menu items PaintDefault := True; @@ -4666,7 +4691,7 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR // Draw the submenu arrows if PaintDefault and (tbisSubmenu in Item.ItemStyle) then - SpDrawArrow(Canvas, R.Right - SpDPIScale(10), R.Bottom div 2, TextC, False, False, SpDPIScale(3)); + SpDrawArrow(Canvas, R.Right - PPIScale(10), R.Bottom div 2, TextC, False, False, PPIScale(3)); // Don't apply the margins if the menu item has // tbisClicksTransparent itemstyle (like a SpTBXLabelItem) @@ -4695,10 +4720,12 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR 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); + SpCalcXPText(Canvas, R, WS, TextAlignment, TextInfo.TextFlags, ItemInfo.ImageSize, + ItemInfo.RightImageSize, GlyphLayout, False, ItemInfo.CurrentPPI, CaptionRect, ImageRect, + RightImageRect, TextInfo.TextAngle); if ItemInfo.IsSunkenCaption then - OffsetRect(CaptionRect, SpDPIScale(1), SpDPIScale(1)); + OffsetRect(CaptionRect, PPIScale(1), PPIScale(1)); end else begin if tbisClicksTransparent in Item.ItemStyle then begin @@ -4726,10 +4753,10 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR if (not IsSelected or ItemInfo.ToolbarStyle) and (ItemInfo.State = sknsDisabled) and (ItemInfo.SkinType = sknNone) then begin - OffsetRect(CaptionRect, SpDPIScale(1), SpDPIScale(1)); + OffsetRect(CaptionRect, PPIScale(1), PPIScale(1)); Canvas.Font.Color := clBtnHighlight; SpDrawXPText(Canvas, WS, CaptionRect, TextInfo.TextFlags, Item.CaptionGlow, Item.CaptionGlowColor, TextInfo.TextAngle); - OffsetRect(CaptionRect, -SpDPIScale(1), -SpDPIScale(1)); + OffsetRect(CaptionRect, -PPIScale(1), -PPIScale(1)); Canvas.Font.Color := clGrayText; end; @@ -4768,7 +4795,7 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR if ItemInfo.ToolBarStyle then begin if IsRectEmpty(ImageRect) then ImageRect := R; - if IsSpecialDropDown then OffsetRect(ImageRect, (-DropDownArrowSize + SpDPIScale(1)) div 2, 0); + if IsSpecialDropDown then OffsetRect(ImageRect, (-Self.tbDropdownArrowWidth + PPIScale(1)) div 2, 0); end else begin ImageRect := R; @@ -4782,9 +4809,9 @@ procedure TSpTBXItemViewer.Paint(const Canvas: TCanvas; const ClientAreaRect: TR else begin if not ItemInfo.ToolbarStyle and Item.Checked then begin if Item.RadioItem then - CurrentSkin.PaintMenuRadioMark(Canvas, ImageRect, True, ItemInfo.State) + CurrentSkin.PaintMenuRadioMark(Canvas, ImageRect, True, ItemInfo.State, View.Window.CurrentPPI) else - CurrentSkin.PaintMenuCheckMark(Canvas, ImageRect, True, False, ItemInfo.State); + CurrentSkin.PaintMenuCheckMark(Canvas, ImageRect, True, False, ItemInfo.State, View.Window.CurrentPPI); end; end; end; @@ -4839,6 +4866,8 @@ procedure TSpTBXItemViewer.CMHintShow(var Message: TMessage); // Prepare the HintBitmap SpStockHintBitmap.Canvas.Font.Assign(Screen.HintFont); SpStockHintBitmap.Canvas.Font.Color := clInfoText; + SpStockHintBitmap.Canvas.Font.Height := + MulDiv(SpStockHintBitmap.Canvas.Font.Height, PPIScale(96), Screen.PixelsPerInch); {$IF CompilerVersion >= 23} //for Delphi XE2 and up if SkinManager.GetSkinType = sknDelphiStyle then begin Details := SpTBXThemeServices.GetElementDetails(thHintNormal); @@ -4995,12 +5024,12 @@ function TSpTBXColorItemViewer.GetImageShown: Boolean; function TSpTBXColorItemViewer.GetImageSize: TSize; begin if IsToolbarStyle then begin - Result.cx := SpDpiScale(12); - Result.cy := SpDPIScale(12); + Result.cx := PPIScale(12); + Result.cy := PPIScale(12); end else begin - Result.cx := SpDpiScale(16); - Result.cy := SpDpiScale(16); + Result.cx := PPIScale(16); + Result.cy := PPIScale(16); end; end; @@ -5093,13 +5122,13 @@ procedure TSpTBXSeparatorItemViewer.CalcSize(const Canvas: TCanvas; var AWidth, begin if not IsToolbarStyle then begin if CurrentSkin.OfficeMenu then - AHeight := SpDpiScale(4) // For Office XP, 2003, 2007 + AHeight := PPIScale(4) // For Office XP, 2003, 2007 else - AHeight := SpDpiScale(10); + AHeight := PPIScale(10); end else begin - AWidth := SpDpiScale(6); - AHeight := SpDpiScale(6); + AWidth := PPIScale(6); + AHeight := PPIScale(6); end; end; @@ -5139,9 +5168,9 @@ procedure TSpTBXSeparatorItemViewer.Paint(const Canvas: TCanvas; const ClientAre 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) + CurrentSkin.GetMenuItemMargins(Canvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, MarginsInfo, View.Window.CurrentPPI) else - CurrentSkin.GetMenuItemMargins(Canvas, 0, MarginsInfo); + CurrentSkin.GetMenuItemMargins(Canvas, 0, MarginsInfo, View.Window.CurrentPPI); if SpIsWinVistaOrUp then R.Left := MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace else @@ -5152,7 +5181,7 @@ procedure TSpTBXSeparatorItemViewer.Paint(const Canvas: TCanvas; const ClientAre else Vertical := View.Orientation <> tbvoVertical; - SpDrawXPMenuSeparator(Canvas, R, MenuItemStyle, Vertical); + SpDrawXPMenuSeparator(Canvas, R, MenuItemStyle, Vertical, View.Window.CurrentPPI); end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -5284,8 +5313,17 @@ procedure TSpTBXSkinGroupItem.DoSkinChange; procedure TSpTBXSkinGroupItem.DoFillStrings; begin SkinManager.GetSkinsAndDelphiStyles(FStrings); + inherited; + + {$IF CompilerVersion >= 23} // for Delphi XE2 and up + if TStyleManager.IsCustomStyleActive then + FDefaultIndex := FStrings.IndexOf(TStyleManager.ActiveStyle.Name) + else + FDefaultIndex := FStrings.IndexOf(SkinManager.CurrentSkinName); + {$ELSE} FDefaultIndex := FStrings.IndexOf(SkinManager.CurrentSkinName); + {$IFEND} end; procedure TSpTBXSkinGroupItem.WMSpSkinChange(var Message: TMessage); @@ -5359,8 +5397,8 @@ procedure TSpTBXSystemMenuItem.CommandClick(Sender: TObject); procedure TSpTBXSystemMenuItemViewer.CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); begin - AWidth := GetSystemMetrics(SM_CXSMICON) + SpDpiScale(2); - AHeight := GetSystemMetrics(SM_CYSMICON) + SpDpiScale(2); + AWidth := {$IF CompilerVersion>= 33}View.Window.{$IFEND}GetSystemMetrics(SM_CXSMICON) + PPIScale(2); + AHeight := {$IF CompilerVersion>= 33}View.Window.{$IFEND}GetSystemMetrics(SM_CYSMICON) + PPIScale(2); end; procedure TSpTBXSystemMenuItemViewer.Paint(const Canvas: TCanvas; @@ -5483,8 +5521,8 @@ procedure TSpTBXToolViewer.CalcCellSize(ACanvas: TCanvas; var AWidth, AHeight: I ImageSize: TSize; begin ImageSize := GetImageSize; - AWidth := ImageSize.cx + SpDpiScale(6); - AHeight := ImageSize.cy + SpDpiScale(6); + AWidth := ImageSize.cx + PPIScale(6); + AHeight := ImageSize.cy + PPIScale(6); end; procedure TSpTBXToolViewer.CalcSize(const Canvas: TCanvas; var AWidth, AHeight: Integer); @@ -5496,9 +5534,9 @@ procedure TSpTBXToolViewer.CalcSize(const Canvas: TCanvas; var AWidth, AHeight: FIndent := 0 else begin if View.Window is TSpTBXPopupWindow then - CurrentSkin.GetMenuItemMargins(Canvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, MarginsInfo) + CurrentSkin.GetMenuItemMargins(Canvas, TSpTBXPopupWindow(View.Window).MaximumImageSize.cx, MarginsInfo, View.Window.CurrentPPI) else - CurrentSkin.GetMenuItemMargins(Canvas, 0, MarginsInfo); + CurrentSkin.GetMenuItemMargins(Canvas, 0, MarginsInfo, View.Window.CurrentPPI); FIndent := MarginsInfo.GutterSize + MarginsInfo.ImageTextSpace + MarginsInfo.LeftCaptionMargin - 3; end; @@ -5509,8 +5547,8 @@ procedure TSpTBXToolViewer.CalcSize(const Canvas: TCanvas; var AWidth, AHeight: if not IsToolbarStyle then Inc(AWidth, MarginsInfo.RightCaptionMargin); AHeight := H * FRowCount; - if AWidth < SpDpiScale(8) then AWidth := SpDpiScale(8); - if AHeight < SpDpiScale(8) then AHeight := SpDpiScale(8); + if AWidth < PPIScale(8) then AWidth := PPIScale(8); + if AHeight < PPIScale(8) then AHeight := PPIScale(8); end; procedure TSpTBXToolViewer.DoDrawHint(AHintBitmap: TBitmap; CursorPos: TPoint; @@ -5531,12 +5569,10 @@ 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); + SpDrawVirtualImageList(ACanvas, ARect, Item.Images, I, ItemInfo.Enabled); end; Item.DoDrawCellImage(ACanvas, ARect, Col, Row, ItemInfo); end; @@ -5599,14 +5635,12 @@ function TSpTBXToolViewer.GetImageSize: TSize; IL := nil else IL := Item.Images; - - if Assigned(IL) then begin - Result.cx := IL.Width; - Result.cy := IL.Height; - end + + if Assigned(IL) then + Result := SpGetScaledVirtualImageListSize(View.Window, IL) else begin - Result.cx := SpDpiScale(12); - Result.cy := SpDpiScale(12); + Result.cx := PPIScale(12); + Result.cy := PPIScale(12); end; end; @@ -5971,11 +6005,23 @@ procedure TSpTBXItemCacheCollection.SetItem(Index: Integer; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { TSpTBXDock } +procedure TSpTBXDock.ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); +begin + FScaling := True; + // Reset anchor prev size + FPrevSize.cx := 0; + FPrevSize.cy := 0; + inherited; + FScaling := False; +end; + constructor TSpTBXDock.Create(AOwner: TComponent); begin inherited; Color := clNone; SkinManager.AddSkinNotification(Self); + FPrevSize.cx := 0; + FPrevSize.cy := 0; end; destructor TSpTBXDock.Destroy; @@ -5984,13 +6030,6 @@ destructor TSpTBXDock.Destroy; 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 @@ -6021,7 +6060,7 @@ procedure TSpTBXDock.DrawBackground(DC: HDC; const DrawRect: TRect); inherited else if Color = clNone then - SpDrawXPDock(ACanvas, DrawRect, Position in [dpLeft, dpRight]) + SpDrawXPDock(ACanvas, DrawRect, Position in [dpLeft, dpRight], CurrentPPI) else begin ACanvas.Brush.Color := Color; ACanvas.FillRect(DrawRect); @@ -6037,24 +6076,89 @@ procedure TSpTBXDock.DrawBackground(DC: HDC; const DrawRect: TRect); end; end; +procedure TSpTBXDock.DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; + const Clip: HRGN); +var + DC: HDC; + R: TRect; + ACanvas: TCanvas; + HighlightC, ShadowC: TColor; +begin + // Handle BoundLines painting when using Delphi styles + if (BoundLines <> []) and ((csDesigning in ComponentState) or HasVisibleToolbars) and + not (csDestroying in ComponentState) and HandleAllocated then + begin + if not DrawToDC then DC := GetWindowDC(Handle) + else DC := ADC; + try + GetWindowRect(Handle, R); + OffsetRect(R, -R.Left, -R.Top); + if not DrawToDC then + SelectNCUpdateRgn(Handle, DC, Clip); + + ACanvas := TCanvas.Create; + try + ACanvas.Handle := DC; + // Paint BoundLines + HighlightC := CurrentSkin.GetThemedSystemColor(clBtnHighlight); + ShadowC := CurrentSkin.GetThemedSystemColor(clBtnShadow); + if blTop in BoundLines then begin + SpDrawLine(ACanvas, R.Left, R.Top, R.Right, R.Top, ShadowC); + end; + if blLeft in BoundLines then begin + SpDrawLine(ACanvas, R.Left, R.Top, R.Left, R.Bottom, ShadowC); + end; + if blBottom in BoundLines then begin + SpDrawLine(ACanvas, R.Left, R.Bottom-1, R.Right, R.Bottom-1, HighlightC); + end; + if blRight in BoundLines then begin + SpDrawLine(ACanvas, R.Right-1, R.Top, R.Right-1, R.Bottom, HighlightC); + end; + // Don't fill the background, it's handled by DrawBackground + finally + ACanvas.Handle := 0; + ACanvas.Free; + end; + finally + if not DrawToDC then ReleaseDC(Handle, DC); + end; + end + else + inherited; +end; + procedure TSpTBXDock.Resize; var I, J: Integer; - ResizeToolbars: Boolean; V: TTBItemViewer; R: TRect; begin - inherited Resize; + inherited; + + if FScaling then + Exit; // 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; + for I := 0 to ToolbarCount - 1 do + if Toolbars[I] is TSpTBXToolbar then begin + + TSpTBXToolbar(Toolbars[I]).RightAlignItems; + + if (ComponentState * [csReading, csLoading, csDestroying] = []) and + (FPrevSize.cx > 0) and (FPrevSize.cy > 0) then + begin + if TSpTBXToolbar(Toolbars[I]).IsVertical then + TSpTBXToolbar(Toolbars[I]).AnchorItems(ClientHeight - FPrevSize.cy) + else + TSpTBXToolbar(Toolbars[I]).AnchorItems(ClientWidth - FPrevSize.cx); + end; + end; + if (ComponentState * [csReading, csLoading, csDestroying] = []) then begin + // Set anchor prev size + FPrevSize.cx := ClientWidth; + FPrevSize.cy := ClientHeight; + end; + // Invalidate the dock and the toolbars for J := 0 to ToolbarCount - 1 do begin @@ -6108,13 +6212,6 @@ procedure TSpTBXDock.WMEraseBkgnd(var Message: TWMEraseBkgnd); 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; @@ -6187,10 +6284,8 @@ procedure TSpTBXToolbarView.EndUpdate; Dec(FUpdating); inherited EndUpdate; if FUpdating = 0 then - if Assigned(Owner) and (Owner is TSpTBXToolbar) then begin + if Assigned(Owner) and (Owner is TSpTBXToolbar) then TSpTBXToolbar(Owner).RightAlignItems; - TSpTBXToolbar(Owner).AnchorItems; - end; end; function TSpTBXToolbarView.IsUpdating: Boolean; @@ -6215,7 +6310,6 @@ constructor TSpTBXToolbar.Create(AOwner: TComponent); Color := clNone; Items.RegisterNotification(DoItemNotification); - FAnchoredControlItems := TSpTBXItemCacheCollection.Create(TSpTBXItemCache); FChevronVertical := True; FCustomizable := True; FDisplayMode := tbdmSelectiveCaption; @@ -6226,7 +6320,6 @@ destructor TSpTBXToolbar.Destroy; begin SkinManager.RemoveSkinNotification(Self); Items.UnRegisterNotification(DoItemNotification); - FAnchoredControlItems.Free; inherited; end; @@ -6249,147 +6342,66 @@ procedure TSpTBXToolbar.DoItemClick(Item: TTBCustomItem; Button: TMouseButton; 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; + if not (tstResizing in FState) and not (tstRightAligning in FState) and + not IsItemMoving then + begin + if Assigned(FOnItemNotification) then + FOnItemNotification(Self, Ancestor, Relayed, Action, Index, Item); + if Action in [tbicInserted, tbicDeleting, tbicInvalidateAndResize] then + RightAlignItems; end; end; procedure TSpTBXToolbar.Resize; begin FState := FState + [tstResizing]; - try - RightAlignItems; - AnchorItems; - finally - FState := FState - [tstResizing]; - end; inherited; + RightAlignItems; + FState := FState - [tstResizing]; end; -procedure TSpTBXToolbar.AnchorItems(UpdateControlItems: Boolean); +procedure TSpTBXToolbar.AnchorItems(Delta: Integer); var - I, J, UpdatedDelta: Integer; + I: 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 + if (Delta = 0) 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.ValidatePositions; 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 + // Resize anchored items, do not scale 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; + if SpIV.Item.Anchored then + if IsVertical then + SpIV.Item.CustomHeight := SpIV.Item.CustomHeight + Delta + else + SpIV.Item.CustomWidth := SpIV.Item.CustomWidth + Delta; 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); + if CI.Control.Tag = 0 then + CI.Control.Tag := CI.Control.Width; // Use Tag as the control prev size + CI.Control.Tag := CI.Control.Tag + Delta; + CI.Control.Width := CI.Control.Tag; + end; 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; @@ -6413,7 +6425,6 @@ 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 @@ -6426,19 +6437,21 @@ procedure TSpTBXToolbar.RightAlignItems; View.BeginUpdate; try // Find the spacer and the right aligned items - IsRotated := IsVertical; - Spacer := SpGetRightAlignedItems(View, nil, IsRotated, VisibleWidth, RightAlignedWidth); + Spacer := SpGetRightAlignedItems(View, nil, IsVertical, 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 + if IsVertical then begin + I := CurrentDock.Height - GetRightAlignMargin - (VisibleWidth - (Spacer.BoundsRect.Bottom - Spacer.BoundsRect.Top)); + if I < 0 then I := 0; + Spacer.Item.CustomHeight := I; + end + else begin I := CurrentDock.Width - GetRightAlignMargin - (VisibleWidth - (Spacer.BoundsRect.Right - Spacer.BoundsRect.Left)); - - if I < 0 then I := 0; - Spacer.Item.CustomWidth := I; + if I < 0 then I := 0; + Spacer.Item.CustomWidth := I; + end; end; - View.UpdatePositions; +// View.UpdatePositions; // not needed finally View.EndUpdate; FState := FState - [tstRightAligning]; @@ -6451,6 +6464,7 @@ function TSpTBXToolbar.GetChevronItemClass: TTBChevronItemClass; end; function TSpTBXToolbar.GetFloatingBorderSize: TPoint; +// TSpTBXToolbar and TSpTBXCustomToolWindow var Details: TThemedElementDetails; ElementSize: TSize; @@ -6459,17 +6473,22 @@ function TSpTBXToolbar.GetFloatingBorderSize: TPoint; case SkinManager.GetSkinType of sknSkin: - Result := Point(CurrentSkin.FloatingWindowBorderSize, CurrentSkin.FloatingWindowBorderSize); + Result := Point(PPIScale(CurrentSkin.FloatingWindowBorderSize), PPIScale(CurrentSkin.FloatingWindowBorderSize)); sknDelphiStyle: begin + // GetThemedElementSize returns a scaled value Details := SpTBXThemeServices.GetElementDetails(twSmallFrameBottomActive); - ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details); - Result.Y := ElementSize.cy; + ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details, CurrentPPI); + Result.Y := ElementSize.cy + 2; // Do not scale, not sure why +2 is needed Details := SpTBXThemeServices.GetElementDetails(twSmallFrameLeftActive); - ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details); - Result.X := ElementSize.cx; + ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details, CurrentPPI); + Result.X := ElementSize.cx + 2; // Do not scale, not sure why +2 is needed end; + else begin + Result.X := GetSystemMetrics(SM_CXDLGFRAME); + Result.Y := GetSystemMetrics(SM_CYDLGFRAME); + end; end; end; @@ -6510,8 +6529,8 @@ procedure TSpTBXToolbar.InternalDrawBackground(ACanvas: TCanvas; ARect: TRect; SpDrawXPToolbar(Self, ACanvas, ARect, PaintOnNCArea, PaintBorders and (BorderStyle <> bsNone)); end; -procedure TSpTBXToolbar.DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; - const Clip: HRGN); +procedure TSpTBXToolbar.DrawNCArea(const DrawToDC: Boolean; + const ADC: HDC; const Clip: HRGN); // Same as TSpTBXCustomToolWindow.DrawNCArea var DC: HDC; @@ -6526,12 +6545,12 @@ procedure TSpTBXToolbar.DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; try GetWindowRect(Handle, R); OffsetRect(R, -R.Left, -R.Top); - GripSize := SpGetDragHandleSize(Self); + GripSize := DragHandleSize; if not DrawToDC then begin SelectNCUpdateRgn(Handle, DC, Clip); ExcludeR := R; - InflateRect(ExcludeR, -CDefaultToolbarBorderSize, -CDefaultToolbarBorderSize); + InflateRect(ExcludeR, -CurrentDock.DockedBorderSize, -CurrentDock.DockedBorderSize); if IsVertical then Inc(ExcludeR.Top, GripSize) else @@ -6694,17 +6713,19 @@ procedure TSpTBXToolbar.WMEraseBkgnd(var Message: TMessage); ACanvas := TCanvas.Create; ACanvas.Handle := TWMEraseBkgnd(Message).DC; try + ACanvas.Lock; R := ClientRect; if Docked then begin - InflateRect(R, CDefaultToolbarBorderSize, CDefaultToolbarBorderSize); + InflateRect(R, DockedBorderSize, DockedBorderSize); if IsVertical then - Dec(R.Top, SpGetDragHandleSize(Self)) + Dec(R.Top, DragHandleSize) else - Dec(R.Left, SpGetDragHandleSize(Self)); + Dec(R.Left, DragHandleSize); end; InternalDrawBackground(ACanvas, R, False); finally + ACanvas.Unlock; ACanvas.Handle := 0; ACanvas.Free; end; @@ -6717,8 +6738,10 @@ procedure TSpTBXToolbar.WMSize(var Message: TWMSize); R: TRect; begin inherited; - - if Docked and ((CurrentDock is TSpTBXDock) and not TSpTBXDock(CurrentDock).FResizing) then begin + // Ported from TBX, assume we are using a background and invalidate when resizing + if not (csLoading in ComponentState) and 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 @@ -6851,6 +6874,69 @@ function TSpTBXToolbar.CanItemClick(Item: TTBCustomItem; Button: TMouseButton; Result := True; end; +procedure TSpTBXToolbar.ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); +var + I, W, H: Integer; + T: TSpTBXCustomItem; + CI: TTBControlItem; +begin + BeginUpdate; + try + inherited; + finally + EndUpdate; + end; + + // Scale DockPos, if changing to a lower DPI reposition counting the toolbars + // that are on the left side + if D > M then begin + if Assigned(CurrentDock) then begin + for I := 0 to CurrentDock.ToolbarCount - 1 do + if CurrentDock.Toolbars[I] = Self then + Break; + DockPos := MulDiv(DockPos, M, D) - MulDiv(I * 14, M, D) + end; + end + else + DockPos := MulDiv(DockPos, M, D); + + // Scale MaxSize + if MaxSize > -1 then begin + HandleNeeded; // not sure why this is needed when starting on a high DPI monitor + MaxSize := MulDiv(MaxSize, M, D); + end; + + // Scale CustomWidth/CustomHeight + for I := 0 to Items.Count - 1 do + if Items[I] is TSpTBXCustomItem then begin + T := TSpTBXCustomItem(Items[I]); + W := MulDiv(T.CustomWidth, M, D); + H := MulDiv(T.CustomHeight, M, D); + if IsVertical then begin + if (T is TSpTBXRightAlignSpacerItem) and (H < 0) then + H := 0; + if (T is TSpTBXRightAlignSpacerItem) or (T.Anchored) or (T.CustomHeight > -1) then + T.CustomHeight := H; + T.CustomWidth := W; + end + else begin + if (T is TSpTBXRightAlignSpacerItem) and (W < 0) then + W := 0; + if (T is TSpTBXRightAlignSpacerItem) or (T.Anchored) or (T.CustomWidth > -1) then + T.CustomWidth := W; + T.CustomHeight := H; + end; + end + else begin + CI := IsAnchoredControlItem(Items[I]); + if Assigned(CI) and (CI.Control.Tag <> 0) then + CI.Control.Tag := MulDiv(CI.Control.Tag, M, D); // Scale prev size of the anchored ControlItem + end; + + // Needed for vertical stretched items + View.InvalidatePositions; +end; + procedure TSpTBXToolbar.MouseMove(Shift: TShiftState; X, Y: Integer); var Item: TTBCustomItem; @@ -6991,17 +7077,36 @@ procedure TSpTBXToolbar.DragDrop(Source: TObject; X, Y: Integer); end; procedure TSpTBXToolbar.ReadPositionData(const Data: TTBReadPositionData); +var + DPI: Integer; + P: TPoint; begin inherited; - with Data do + with Data do begin + // Read DisplayMode DisplayMode := TSpTBXToolbarDisplayMode(ReadIntProc(Name, rvSpTBXDisplayMode, 0, ExtraData)); + // Read the saved DPI and scale the position + DPI := ReadIntProc(Name, 'DPI', 96, ExtraData); + DockPos := MulDiv(ReadIntProc(Name, 'DockPos', DockPos, ExtraData), CurrentPPI, DPI); + // FloatingPosition is reset after ReadPositionData is called, this is a + // TB2K bug, I've changed TB2K sources for this to work, see + // TB2Dock.TBCustomLoadPositions + P.X := MulDiv(ReadIntProc(Name, 'FloatLeft', 0, ExtraData), CurrentPPI, DPI); + P.Y := MulDiv(ReadIntProc(Name, 'FloatTop', 0, ExtraData), CurrentPPI, DPI); + FloatingPosition := P; + FloatingWidth := MulDiv(ReadIntProc(Name, 'FloatRightX', 0, ExtraData), CurrentPPI, DPI); + end; end; procedure TSpTBXToolbar.WritePositionData(const Data: TTBWritePositionData); begin inherited; - with Data do + with Data do begin + // Save DisplayMode WriteIntProc(Name, rvSpTBXDisplayMode, Integer(DisplayMode), ExtraData); + // Save the current dpi + WriteIntProc(Name, rvDPI, CurrentPPI, ExtraData); + end; end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -7010,9 +7115,12 @@ procedure TSpTBXToolbar.WritePositionData(const Data: TTBWritePositionData); constructor TSpTBXCustomToolWindow.Create(AOwner: TComponent); begin inherited; - FMinClientWidth := SpDpiScale(32); - FMinClientHeight := SpDpiScale(32); - SetBounds(Left, Top, FMinClientWidth, FMinClientHeight); + FMinClientWidth := 32; + FMinClientHeight := 32; + // Make sure Width/Height are included in ScalingFlags on + // TControl.ChangeScale when csLoading + Width := FMinClientWidth; + Height := FMinClientHeight; Color := clNone; SkinManager.AddSkinNotification(Self); @@ -7024,6 +7132,16 @@ destructor TSpTBXCustomToolWindow.Destroy; inherited; end; +procedure TSpTBXCustomToolWindow.ChangeScale(M, D: Integer{$IF CompilerVersion >= 31}; isDpiChange: Boolean{$IFEND}); +begin + inherited; + // Do not scale FBarSize, it's updated with scaled Width/Height values in SizeChanging + FMaxClientHeight := MulDiv(FMaxClientHeight, M, D); + FMaxClientWidth := MulDiv(FMaxClientWidth, M, D); + FMinClientHeight := MulDiv(FMinClientHeight, M, D); + FMinClientWidth := MulDiv(FMinClientWidth, M, D); +end; + function TSpTBXCustomToolWindow.CalcSize(ADock: TTBDock): TPoint; begin Result.X := FBarSize.cx; @@ -7034,7 +7152,7 @@ function TSpTBXCustomToolWindow.CalcSize(ADock: TTBDock): TPoint; if SpIsVerticalToolbar(Self) then Result.Y := FMinClientHeight else - Result.X := FMinClientWidth; + Result.X := FMinClientWidth; end; end; @@ -7119,6 +7237,7 @@ procedure TSpTBXCustomToolWindow.InvalidateBackground(InvalidateChildren: Boolea procedure TSpTBXCustomToolWindow.DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; const Clip: HRGN); +// Same as TSpTBXToolbar.DrawNCArea var DC: HDC; R, ExcludeR: TRect; @@ -7132,12 +7251,12 @@ procedure TSpTBXCustomToolWindow.DrawNCArea(const DrawToDC: Boolean; try GetWindowRect(Handle, R); OffsetRect(R, -R.Left, -R.Top); - GripSize := SpGetDragHandleSize(Self); + GripSize := DragHandleSize; if not DrawToDC then begin SelectNCUpdateRgn(Handle, DC, Clip); ExcludeR := R; - InflateRect(ExcludeR, -CDefaultToolbarBorderSize, -CDefaultToolbarBorderSize); + InflateRect(ExcludeR, -DockedBorderSize, -DockedBorderSize); if IsVertical then Inc(ExcludeR.Top, GripSize) else @@ -7171,48 +7290,65 @@ procedure TSpTBXCustomToolWindow.DoDrawBackground(ACanvas: TCanvas; procedure TSpTBXCustomToolWindow.ReadPositionData(const Data: TTBReadPositionData); var - W, H: Integer; + DPI, W, H: Integer; + P: TPoint; 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); + with Data do begin + // Read the saved DPI and scale the position + DPI := ReadIntProc(Name, 'DPI', 96, ExtraData); + DockPos := MulDiv(ReadIntProc(Name, 'DockPos', DockPos, ExtraData), CurrentPPI, DPI); + // FloatingPosition is reset after ReadPositionData is called, this is a + // TB2K bug, I've changed TB2K sources for this to work, see + // TB2Dock.TBCustomLoadPositions + P.X := MulDiv(ReadIntProc(Name, 'FloatLeft', 0, ExtraData), CurrentPPI, DPI); + P.Y := MulDiv(ReadIntProc(Name, 'FloatTop', 0, ExtraData), CurrentPPI, DPI); + FloatingPosition := P; + // Load ClientAreaWidth/ClientAreaHeight + if Resizable then begin + W := MulDiv(ReadIntProc(Name, rvClientWidth, FBarSize.cx, ExtraData), CurrentPPI, DPI); + H := MulDiv(ReadIntProc(Name, rvClientHeight, FBarSize.cy, ExtraData), CurrentPPI, DPI); SetClientAreaSize(W, H); end; + end; end; procedure TSpTBXCustomToolWindow.WritePositionData(const Data: TTBWritePositionData); begin inherited; - // Save ClientAreaWidth/ClientAreaHeight with Data do begin + // Save ClientAreaWidth/ClientAreaHeight WriteIntProc(Name, rvClientWidth, ClientAreaWidth, ExtraData); WriteIntProc(Name, rvClientHeight, ClientAreaHeight, ExtraData); + // Save the current dpi + WriteIntProc(Name, rvDPI, CurrentPPI, ExtraData); end; end; function TSpTBXCustomToolWindow.GetFloatingBorderSize: TPoint; +// TSpTBXToolbar and TSpTBXCustomToolWindow var Details: TThemedElementDetails; ElementSize: TSize; begin - Result := inherited GetFloatingBorderSize; - case SkinManager.GetSkinType of sknSkin: - Result := Point(CurrentSkin.FloatingWindowBorderSize, CurrentSkin.FloatingWindowBorderSize); + Result := Point(PPIScale(CurrentSkin.FloatingWindowBorderSize), PPIScale(CurrentSkin.FloatingWindowBorderSize)); sknDelphiStyle: begin + // GetThemedElementSize returns a scaled value Details := SpTBXThemeServices.GetElementDetails(twSmallFrameBottomActive); - ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details); - Result.Y := ElementSize.cy; + ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details, CurrentPPI); + Result.Y := ElementSize.cy + 2; // Do not scale, not sure why +2 is needed Details := SpTBXThemeServices.GetElementDetails(twSmallFrameLeftActive); - ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details); - Result.X := ElementSize.cx; + ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details, CurrentPPI); + Result.X := ElementSize.cx + 2; // Do not scale, not sure why +2 is needed end; + else begin + Result.X := GetSystemMetrics(SM_CXDLGFRAME); + Result.Y := GetSystemMetrics(SM_CYDLGFRAME); + end; end; end; @@ -7284,11 +7420,11 @@ procedure TSpTBXCustomToolWindow.WMEraseBkgnd(var Message: TMessage); try R := ClientRect; if Docked then begin - InflateRect(R, CDefaultToolbarBorderSize, CDefaultToolbarBorderSize); + InflateRect(R, DockedBorderSize, DockedBorderSize); if IsVertical then - Dec(R.Top, SpGetDragHandleSize(Self)) + Dec(R.Top, DragHandleSize) else - Dec(R.Left, SpGetDragHandleSize(Self)); + Dec(R.Left, DragHandleSize); end; InternalDrawBackground(ACanvas, R, False); @@ -7325,12 +7461,6 @@ constructor TSpTBXFloatingWindowParent.CreateNew(AOwner: TComponent; SkinManager.AddSkinNotification(Self); end; -procedure TSpTBXFloatingWindowParent.CreateWnd; -begin - inherited; - UpdateDwmNCSize; -end; - destructor TSpTBXFloatingWindowParent.Destroy; begin SkinManager.RemoveSkinNotification(Self); @@ -7372,14 +7502,14 @@ procedure TSpTBXFloatingWindowParent.DrawNCArea(const DrawToDC: Boolean; // Borders if twrdBorder in RedrawWhat then - SpDrawXPTitleBarBody(ACanvas, R, IsActive, FloatingBorderSize, False); + SpDrawXPTitleBarBody(ACanvas, R, IsActive, FloatingBorderSize, False, CurrentPPI); // Caption if DockWindow.ShowCaption then begin R.Bottom := R.Top + FloatingBorderSize.Y + GetSystemMetrics(SM_CYSMCAPTION); if SkinManager.GetSkinType in [sknWindows, sknDelphiStyle] then begin if twrdBorder in RedrawWhat then - SpDrawXPTitleBar(ACanvas, R, IsActive, False); + SpDrawXPTitleBar(ACanvas, R, IsActive, False, CurrentPPI); InflateRect(R, -FloatingBorderSize.X, 0); R.Top := R.Top + FloatingBorderSize.Y; end @@ -7387,7 +7517,7 @@ procedure TSpTBXFloatingWindowParent.DrawNCArea(const DrawToDC: Boolean; InflateRect(R, -FloatingBorderSize.X, 0); R.Top := R.Top + FloatingBorderSize.Y; if twrdBorder in RedrawWhat then - SpDrawXPTitleBar(ACanvas, R, IsActive, False); + SpDrawXPTitleBar(ACanvas, R, IsActive, False, CurrentPPI); end; // Text @@ -7399,6 +7529,7 @@ procedure TSpTBXFloatingWindowParent.DrawNCArea(const DrawToDC: Boolean; ACanvas.Brush.Style := bsClear; try ACanvas.Font.Assign(SmCaptionFont); + ACanvas.Font.Height := MulDiv(ACanvas.Font.Height, CurrentPPI, SmCaptionFont.PixelsPerInch); if IsActive then ACanvas.Font.Color := CurrentSkin.GetTextColor(skncWindowTitleBar, sknsNormal) else @@ -7420,10 +7551,10 @@ procedure TSpTBXFloatingWindowParent.DrawNCArea(const DrawToDC: Boolean; if (twrdCloseButton in RedrawWhat) and DockWindow.CloseButton then begin CloseR := R; Dec(CloseR.Bottom); - CloseButtonWidth := (CloseR.Bottom - CloseR.Top) - SpDpiScale(2) - SpDpiScale(2); - CloseR.Left := CloseR.Right - CloseButtonWidth - SpDpiScale(2); // TB2Dock.GetCloseButtonRect + CloseButtonWidth := (CloseR.Bottom - CloseR.Top) - PPIScale(2) - PPIScale(2); + CloseR.Left := CloseR.Right - CloseButtonWidth - PPIScale(2); // TB2Dock.GetCloseButtonRect CloseR.Right := CloseR.Left + CloseButtonWidth; - CloseR.Top := CloseR.Top + SpDpiScale(2); + CloseR.Top := CloseR.Top + PPIScale(2); CloseR.Bottom := CloseR.Top + CloseButtonWidth; case SkinManager.GetSkinType of @@ -7439,7 +7570,7 @@ procedure TSpTBXFloatingWindowParent.DrawNCArea(const DrawToDC: Boolean; if CloseButtonDown then Details := SpTBXThemeServices.GetElementDetails(twSmallCloseButtonPushed) else if FCloseButtonHover then Details := SpTBXThemeServices.GetElementDetails(twSmallCloseButtonHot) else Details := SpTBXThemeServices.GetElementDetails(twSmallCloseButtonNormal); - CurrentSkin.PaintThemedElementBackground(ACanvas, CloseR, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, CloseR, Details, CurrentPPI); end; sknSkin: begin @@ -7448,7 +7579,7 @@ procedure TSpTBXFloatingWindowParent.DrawNCArea(const DrawToDC: Boolean; if PatternColor = clNone then PatternColor := CurrentSkin.GetTextColor(skncToolbarItem, SkinState); CurrentSkin.PaintBackground(ACanvas, CloseR, skncToolbarItem, SkinState, True, True); - SpDrawGlyphPattern(ACanvas, CloseR, gptClose, PatternColor); + SpDrawGlyphPattern(ACanvas, CloseR, gptClose, PatternColor, CurrentPPI); end; end; end; @@ -7474,14 +7605,18 @@ procedure TSpTBXFloatingWindowParent.UpdateDwmNCSize; Style: {$IF CompilerVersion >= 23} NativeInt {$ELSE} Integer {$IFEND}; 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 TTBCustomDockableWindowAccess(DockableWindow).Resizable and (SkinManager.GetSkinType = sknWindows) and SpIsDwmCompositionEnabled then - Style := Style or WS_THICKFRAME - else - Style := Style and not WS_THICKFRAME; - SetWindowLong(Handle, GWL_STYLE, Style); + // newpy: on Windows 10 avoid using WS_THICKFRAME altogether. + // See TTBFloatingWindowParent.CreateParams and TTBCustomDockableWindow.GetFloatingBorderSize + if not SpIsWin10OrUp 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 TTBCustomDockableWindowAccess(DockableWindow).Resizable and (SkinManager.GetSkinType = sknWindows) and SpIsDwmCompositionEnabled then + Style := Style or WS_THICKFRAME + else + Style := Style and not WS_THICKFRAME; + SetWindowLong(Handle, GWL_STYLE, Style); + end; // Update the NC area size, CurrentSkin.FloatingWindowBorderSize could have changed // Make sure to resize the toolbar @@ -7489,7 +7624,11 @@ procedure TSpTBXFloatingWindowParent.UpdateDwmNCSize; 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 = sknWindows); + + if not SpIsWin10OrUp then begin + // Activate DwmComposition + SpActivateDwmNC(Self, SkinManager.GetSkinType = sknWindows); + end; end; end; @@ -7647,7 +7786,7 @@ procedure PopupWindowNCPaintProc(Wnd: HWND; DC: HDC; AppData: TObject); // If it's used by WM_ERASEBKGND offset the rect if PopupWindow.FPaintingClientArea then begin PopupWindow.FPaintingClientArea := False; - OffsetRect(R, -TB2Common.PopupMenuWindowNCSize, -TB2Common.PopupMenuWindowNCSize); + OffsetRect(R, -PopupMenuWindowNCSize, -PopupMenuWindowNCSize); end; PopupWindow.PaintBackground(ACanvas, R); @@ -7670,6 +7809,7 @@ procedure TSpTBXPopupWindow.PaintBackground(ACanvas: TCanvas; ARect: TRect); if Assigned(View) then begin ACanvas.Font.Assign(ToolbarFont); + ACanvas.Font.Height := MulDiv(ACanvas.Font.Height, CurrentPPI, ToolbarFont.PixelsPerInch); DrawGutter := CanDrawGutter; if Assigned(View.ParentView) and CurrentSkin.OfficePopup then begin @@ -7683,7 +7823,7 @@ procedure TSpTBXPopupWindow.PaintBackground(ACanvas: TCanvas; ARect: TRect); OpenIVRect.BottomRight := View.ParentView.Window.ClientToScreen(OpenIVRect.BottomRight); OpenIVRect.TopLeft := ScreenToClient(OpenIVRect.TopLeft); OpenIVRect.BottomRight := ScreenToClient(OpenIVRect.BottomRight); - OffsetRect(OpenIVRect, TB2Common.PopupMenuWindowNCSize, TB2Common.PopupMenuWindowNCSize); // Offset to get it on window coordinates + OffsetRect(OpenIVRect, PopupMenuWindowNCSize, PopupMenuWindowNCSize); // Offset to get it on window coordinates OpenIVSize := OpenIVRect.Right - OpenIVRect.Left; // Get the Clip rect based on OpenIVRect @@ -7693,7 +7833,7 @@ procedure TSpTBXPopupWindow.PaintBackground(ACanvas: TCanvas; ARect: TRect); end; end; - SpDrawXPMenuPopupWindow(ACanvas, ARect, OpenIVRect, DrawGutter, MaximumImageSize.cx); + SpDrawXPMenuPopupWindow(ACanvas, ARect, OpenIVRect, DrawGutter, MaximumImageSize.cx, CurrentPPI); end; procedure TSpTBXPopupWindow.CMHintShow(var Message: TCMHintShow); @@ -7801,7 +7941,7 @@ procedure TSpTBXPopupWindowView.SetIsToolbar(const Value: Boolean); // 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; + PBoolean(@(Self.IsToolbar))^ := Value; end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -7847,14 +7987,14 @@ procedure TSpTBXChevronItemViewer.Paint(const Canvas: TCanvas; // Chevron glyph R2 := ClientAreaRect; if not ItemInfo.IsVertical then begin - Inc(R2.Top, SpDPIScale(4)); - R2.Bottom := R2.Top + SpDPIScale(5); + Inc(R2.Top, PPIScale(4)); + R2.Bottom := R2.Top + PPIScale(5); end else begin - R2.Left := R2.Right - SpDPIScale(9); - R2.Right := R2.Left + SpDPIScale(5); + R2.Left := R2.Right - PPIScale(9); + R2.Right := R2.Left + PPIScale(5); end; - if ItemInfo.Pushed then OffsetRect(R2, SpDPIScale(1), SpDPIScale(1)); + if ItemInfo.Pushed then OffsetRect(R2, PPIScale(1), PPIScale(1)); if ItemInfo.Enabled then begin if SkinManager.GetSkinType = sknSkin then @@ -7862,30 +8002,30 @@ procedure TSpTBXChevronItemViewer.Paint(const Canvas: TCanvas; else PatternColor := CurrentSkin.GetThemedSystemColor(clBtnText); if not ItemInfo.IsVertical then - SpDrawGlyphPattern(Canvas, R2, gptChevron, PatternColor) + SpDrawGlyphPattern(Canvas, R2, gptChevron, PatternColor, View.Window.CurrentPPI) else - SpDrawGlyphPattern(Canvas, R2, gptVerticalChevron, PatternColor); + SpDrawGlyphPattern(Canvas, R2, gptVerticalChevron, PatternColor, View.Window.CurrentPPI); end else begin if SkinManager.GetSkinType = sknSkin then PatternColor := GetTextColor(ItemInfo.State) else PatternColor := CurrentSkin.GetThemedSystemColor(clBtnHighlight); - OffsetRect(R2, SpDPIScale(1), SpDPIScale(1)); + OffsetRect(R2, PPIScale(1), PPIScale(1)); if not ItemInfo.IsVertical then - SpDrawGlyphPattern(Canvas, R2, gptChevron, PatternColor) + SpDrawGlyphPattern(Canvas, R2, gptChevron, PatternColor, View.Window.CurrentPPI) else - SpDrawGlyphPattern(Canvas, R2, gptVerticalChevron, PatternColor); + SpDrawGlyphPattern(Canvas, R2, gptVerticalChevron, PatternColor, View.Window.CurrentPPI); if SkinManager.GetSkinType = sknSkin then PatternColor := GetTextColor(ItemInfo.State) else PatternColor := CurrentSkin.GetThemedSystemColor(clBtnShadow); - OffsetRect(R2, -SpDPIScale(1), -SpDPIScale(1)); + OffsetRect(R2, -PPIScale(1), -PPIScale(1)); if not ItemInfo.IsVertical then - SpDrawGlyphPattern(Canvas, R2, gptChevron, PatternColor) + SpDrawGlyphPattern(Canvas, R2, gptChevron, PatternColor, View.Window.CurrentPPI) else - SpDrawGlyphPattern(Canvas, R2, gptVerticalChevron, PatternColor); + SpDrawGlyphPattern(Canvas, R2, gptVerticalChevron, PatternColor, View.Window.CurrentPPI); end; end; @@ -7983,6 +8123,14 @@ procedure TSpTBXPopupMenu.Popup(X, Y: Integer); PopupEx(X, Y); end; +procedure TSpTBXPopupMenu.PopupAtMousePos; +var + Point: TPoint; +begin + GetCursorPos(Point); + Popup(Point.X, Point.Y); +end; + function TSpTBXPopupMenu.PopupEx(X, Y: Integer; PopupControl: TControl = nil; ReturnClickedItemOnly: Boolean = False): TTBCustomItem; begin @@ -8015,6 +8163,7 @@ constructor TSpTBXCustomContainer.Create(AOwner: TComponent); Color := clNone; ParentColor := False; SkinManager.AddSkinNotification(Self); + FBorders := True; DoubleBuffered := True; end; @@ -8038,7 +8187,9 @@ procedure TSpTBXCustomContainer.CreateParams(var Params: TCreateParams); - Drop a TMemo inside a TSpTBXPanel - Change Memo.ScrollBars to ssVertical - Run and try to resize using a VCL Style. - The problem seems to be that TScrollingStyleHook.WndProc gets called non stop, even when the window is not visible. TScrollingStyleHook.WndProc calls TScrollingStyleHook.PaintNC which + The problem seems to be that TScrollingStyleHook.WndProc gets called + non stop, even when the window is not visible. + TScrollingStyleHook.WndProc calls TScrollingStyleHook.PaintNC which constantly shows and repaints the scrollbars. Seems to be a VCL bug. @@ -8089,6 +8240,15 @@ procedure TSpTBXCustomContainer.DrawBackground(ACanvas: TCanvas; ARect: TRect); // end; +procedure TSpTBXCustomContainer.SetBorders(const Value: Boolean); +begin + if FBorders <> Value then begin + FBorders := Value; + Realign; + InvalidateBackground; + end; +end; + procedure TSpTBXCustomContainer.InvalidateBackground(InvalidateChildren: Boolean); begin // Force background repaint, calling invalidate doesn't repaint children controls @@ -8098,9 +8258,9 @@ procedure TSpTBXCustomContainer.InvalidateBackground(InvalidateChildren: Boolean else if not (csDestroying in ComponentState) and HandleAllocated then if InvalidateChildren then - RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN) + RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ALLCHILDREN or RDW_FRAME) else - RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE); + RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME); end; procedure TSpTBXCustomContainer.WMEraseBkgnd(var Message: TMessage); @@ -8501,7 +8661,7 @@ constructor TSpTBXButtonOptions.Create(AParent: TWinControl); FMinimizeImageIndex := -1; FMaximizeImageIndex := -1; FRestoreImageIndex := -1; - FTitleBarMaxSize := SpDpiScale(21); + TitleBarMaxSize := 21; FButtonBorders := True; CreateButtons; end; @@ -8527,8 +8687,6 @@ procedure TSpTBXButtonOptions.CreateButtons; FCloseButton := TSpTBXItem.Create(nil); SetupButton(FCloseButton); FCloseButton.Visible := FClose; - - SetTitleBarMaxSize(FTitleBarMaxSize); end; procedure TSpTBXButtonOptions.MoveItemToTheLeft(B: TTBCustomItem); @@ -8545,8 +8703,8 @@ procedure TSpTBXButtonOptions.MoveItemToTheLeft(B: TTBCustomItem); procedure TSpTBXButtonOptions.SetupButton(B: TSpTBXCustomItem); begin - B.CustomWidth := SpDPIScale(17); - B.CustomHeight := FTitleBarMaxSize; + B.CustomWidth := 17; + B.CustomHeight := TitleBarMaxSize; B.DisplayMode := nbdmImageAndText; B.OnDrawImage := ButtonsDrawImage; B.OnDrawItem := ButtonsDrawItem; @@ -8710,10 +8868,18 @@ procedure TSpTBXButtonOptions.SetRestoreImageIndex(Value: Integer); SetupButtonIcon(FMaximizeButton); end; +function TSpTBXButtonOptions.GetTitleBarMaxSize: Integer; +begin + if Assigned(FToolbar) then + Result := FToolbar.MaxSize + else + Result := -1; +end; + procedure TSpTBXButtonOptions.SetTitleBarMaxSize(const Value: Integer); begin - FTitleBarMaxSize := Value; - TSpTBXToolbarView(FToolbar.View).MaxSize := Value; + if Assigned(FToolbar) then + FToolbar.MaxSize := Value; end; //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM @@ -8784,6 +8950,7 @@ function TSpTBXStatusToolbar.GetGripRect: TRect; if HasGrip then begin Result := CurrentDock.ClientRect; Result.Left := Result.Right - GetSystemMetrics(SM_CXVSCROLL); + Result.Top := Result.Bottom - GetSystemMetrics(SM_CXVSCROLL); end; end; end; @@ -8804,7 +8971,7 @@ function TSpTBXStatusToolbar.GetRightAlignMargin: Integer; R := GetGripRect; Result := R.Right - R.Left; if Result = 0 then - Result := SpDPIScale(4); + Result := PPIScale(4); end; function TSpTBXStatusToolbar.NeedsSeparatorRepaint: Boolean; @@ -8914,11 +9081,15 @@ procedure TSpTBXCustomStatusBar.DoDrawDockBackground(ACanvas: TCanvas; 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 = SpDPIScale(-2)) and (ARect.Top = SpDPIScale(-2)) then - OffsetRect(G, SpDPIScale(-2), SpDPIScale(-2)); + if (ARect.Left = PPIScale(-2)) and (ARect.Top = PPIScale(-2)) then + OffsetRect(G, PPIScale(-2), PPIScale(-2)); end; + + // newpy Hack!! not sure why is needed + //if SkinManager.GetSkinType = sknDelphiStyle then + // OffsetRect(G, PPIScale(4), PPIScale(2)); - SpDrawXPStatusBar(ACanvas, ARect, G); + SpDrawXPStatusBar(ACanvas, ARect, G, CurrentPPI); if Toolbar.NeedsSeparatorRepaint then DrawSeparators(ACanvas, ARect); end; @@ -8941,10 +9112,10 @@ procedure TSpTBXCustomStatusBar.DrawSeparators(ACanvas: TCanvas; ARect: TRect); if IsRectEmpty(R) then Continue; - OffsetRect(R, ARect.Left + SpDpiScale(2), ARect.Top + SpDpiScale(2)); + OffsetRect(R, ARect.Left + PPIScale(2), ARect.Top + PPIScale(2)); R.Top := ARect.Top; R.Bottom := ARect.Bottom; - R.Left := ((R.Right + R.Left) div 2) - SpDpiScale(2); + R.Left := ((R.Right + R.Left) div 2) - PPIScale(2); R.Right := R.Left + 3; if SkinManager.GetSkinType = sknNone then begin @@ -9093,7 +9264,7 @@ procedure TSpTBXTitleToolbar.WMNCCalcSize(var Message: TWMNCCalcSize); if Docked then begin TitleBar := GetTitleBar; if Assigned(TitleBar) and (TitleBar.WindowState = wsMaximized) then begin - InflateRect(Message.CalcSize_Params.rgrc[0], CDefaultToolbarBorderSize, CDefaultToolbarBorderSize); + InflateRect(Message.CalcSize_Params.rgrc[0], DockedBorderSize, DockedBorderSize); end; end; end; @@ -9353,8 +9524,8 @@ procedure TSpTBXCustomTitleBar.NewParentFormWndProc(var Message: TMessage); 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 - SpDpiScale(2); - ABE_TOP, ABE_BOTTOM: MMI^.ptMaxSize.Y := MMI^.ptMaxSize.Y - SpDpiScale(2); + ABE_LEFT, ABE_RIGHT: MMI^.ptMaxSize.X := MMI^.ptMaxSize.X - PPIScale(2); + ABE_TOP, ABE_BOTTOM: MMI^.ptMaxSize.Y := MMI^.ptMaxSize.Y - PPIScale(2); end; end; @@ -9524,7 +9695,7 @@ procedure TSpTBXCustomTitleBar.DoDrawDockBackground(ACanvas: TCanvas; InflateRect(ARect, FloatingBorderSize.X, FloatingBorderSize.Y); end; - SpDrawXPTitleBar(ACanvas, ARect, True); + SpDrawXPTitleBar(ACanvas, ARect, True, True, CurrentPPI); end; end; @@ -9539,10 +9710,10 @@ procedure TSpTBXCustomTitleBar.DrawBackground(ACanvas: TCanvas; ARect: TRect); Maximized := (WindowState = wsMaximized) and FMouseActive; if Maximized then - InflateRect(ARect, SpDpiScale(4), SpDpiScale(4)); + InflateRect(ARect, PPIScale(4), PPIScale(4)); if Active then begin FloatingBorderSize := GetFloatingBorderSize; - SpDrawXPTitleBarBody(ACanvas, ARect, True, FloatingBorderSize); + SpDrawXPTitleBarBody(ACanvas, ARect, True, FloatingBorderSize, True, CurrentPPI); // [Theme-Change] // On WindowsXP make sure we paint the titlebar on the NC area @@ -9550,7 +9721,7 @@ procedure TSpTBXCustomTitleBar.DrawBackground(ACanvas: TCanvas; ARect: TRect); if Assigned(FDock) and not Maximized and (SkinManager.GetSkinType in [sknWindows, sknDelphiStyle]) then begin DockAreaR := ARect; DockAreaR.Bottom := FDock.Height + FloatingBorderSize.Y; // don't multiply by 2 - SpDrawXPTitleBar(ACanvas, DockAreaR, True); + SpDrawXPTitleBar(ACanvas, DockAreaR, True, True, CurrentPPI); end; end; end; @@ -9576,22 +9747,24 @@ function TSpTBXCustomTitleBar.GetFloatingBorderSize: TPoint; Details: TThemedElementDetails; ElementSize: TSize; begin - Result.X := GetSystemMetrics(SM_CXFRAME); - Result.Y := GetSystemMetrics(SM_CYFRAME); - case SkinManager.GetSkinType of sknSkin: - Result := Point(CurrentSkin.FloatingWindowBorderSize, CurrentSkin.FloatingWindowBorderSize); + Result := Point(PPIScale(CurrentSkin.FloatingWindowBorderSize), PPIScale(CurrentSkin.FloatingWindowBorderSize)); sknDelphiStyle: begin + // GetThemedElementSize returns a scaled value Details := SpTBXThemeServices.GetElementDetails(twFrameBottomActive); - ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details); + ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details, CurrentPPI); Result.Y := ElementSize.cy; Details := SpTBXThemeServices.GetElementDetails(twFrameLeftActive); - ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details); + ElementSize := CurrentSkin.GetThemedElementSize(Canvas, Details, CurrentPPI); Result.X := ElementSize.cx; end; + else begin + Result.X := GetSystemMetrics(SM_CXFRAME); + Result.Y := GetSystemMetrics(SM_CYFRAME); + end; end; end; @@ -9627,14 +9800,14 @@ procedure TSpTBXCustomTitleBar.GetSizeCursor(MousePos: TPoint; var SizeCursor, InflateRect(R, -FloatingBorderSize.X, -FloatingBorderSize.Y); Pt := MousePos; if not PtInRect(R, Pt) then begin - if (Pt.X < SpDpiScale(10)) and (Pt.Y < SpDpiScale(10)) then SizeCode := SC_SizeUpLeft - else if (Pt.X > Width - SpDpiScale(10)) and (Pt.Y < SpDpiScale(10)) then SizeCode := SC_SizeUpRight - else if (Pt.X < SpDpiScale(10)) and (Pt.Y > Height - SpDpiScale(10)) then SizeCode := SC_SizeDownLeft - else if (Pt.X > Width - SpDpiScale(10)) and (Pt.Y > Height - SpDpiScale(10)) then SizeCode := SC_SizeDownRight - else if (Pt.X > SpDpiScale(10)) and (Pt.X < Width - SpDpiScale(10)) and (Pt.Y < SpDpiScale(10)) then SizeCode := SC_SizeUp - else if (Pt.X > SpDpiScale(10)) and (Pt.X < Width - SpDpiScale(10)) and (Pt.Y > Height - SpDpiScale(10)) then SizeCode := SC_SizeDown - else if (Pt.Y > SpDpiScale(10)) and (Pt.Y < Height - SpDpiScale(10)) and (Pt.X < SpDpiScale(10)) then SizeCode := SC_SizeLeft - else if (Pt.Y > SpDpiScale(10)) and (Pt.Y < Height - SpDpiScale(10)) and (Pt.X > Width - SpDpiScale(10)) then SizeCode := SC_SizeRight; + if (Pt.X < PPIScale(10)) and (Pt.Y < PPIScale(10)) then SizeCode := SC_SizeUpLeft + else if (Pt.X > Width - PPIScale(10)) and (Pt.Y < PPIScale(10)) then SizeCode := SC_SizeUpRight + else if (Pt.X < PPIScale(10)) and (Pt.Y > Height - PPIScale(10)) then SizeCode := SC_SizeDownLeft + else if (Pt.X > Width - PPIScale(10)) and (Pt.Y > Height - PPIScale(10)) then SizeCode := SC_SizeDownRight + else if (Pt.X > PPIScale(10)) and (Pt.X < Width - PPIScale(10)) and (Pt.Y < PPIScale(10)) then SizeCode := SC_SizeUp + else if (Pt.X > PPIScale(10)) and (Pt.X < Width - PPIScale(10)) and (Pt.Y > Height - PPIScale(10)) then SizeCode := SC_SizeDown + else if (Pt.Y > PPIScale(10)) and (Pt.Y < Height - PPIScale(10)) and (Pt.X < PPIScale(10)) then SizeCode := SC_SizeLeft + else if (Pt.Y > PPIScale(10)) and (Pt.Y < Height - PPIScale(10)) and (Pt.X > Width - PPIScale(10)) then SizeCode := SC_SizeRight; case SizeCode of SC_SizeLeft, SC_SizeRight: SizeCursor := -9; diff --git a/Source/SpTBXMDIMRU.pas b/Source/SpTBXMDIMRU.pas index ef7a3c2..469285a 100644 --- a/Source/SpTBXMDIMRU.pas +++ b/Source/SpTBXMDIMRU.pas @@ -1,7 +1,7 @@ unit SpTBXMDIMRU; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -41,7 +41,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -124,10 +124,10 @@ TSpTBXMRUListItem = class(TTBCustomItem) public constructor Create(AOwner: TComponent); override; procedure GetMRUFilenames(MRUFilenames: TStrings); - function IndexOfMRU(Filename: string): Integer; - function MRUAdd(Filename: string): Integer; - function MRUClick(Filename: string): Boolean; - procedure MRURemove(Filename: string); + function IndexOfMRU(const Filename: string): Integer; + function MRUAdd(const Filename: string): Integer; + function MRUClick(const Filename: string): Boolean; + procedure MRURemove(const Filename: string); procedure MRUUpdateCaptions; procedure LoadFromIni(Ini: TCustomIniFile; const Section: string); procedure SaveToIni(Ini: TCustomIniFile; const Section: string); @@ -333,7 +333,16 @@ procedure TSpTBXMDIButtonsItem.DrawItemImage(Sender: TObject; ACanvas: TCanvas; NoneFlags: array[TSpTBXSkinStatesType] of Integer = (0, DFCS_INACTIVE, 0, DFCS_PUSHED, DFCS_PUSHED, DFCS_PUSHED); XPPart: array [0..3] of Integer = (WP_MDICLOSEBUTTON, WP_MAXBUTTON, WP_MDIMINBUTTON, WP_MDIRESTOREBUTTON); XPFlags: array[TSpTBXSkinStatesType] of Integer = (CBS_NORMAL, CBS_DISABLED, CBS_HOT, CBS_PUSHED, CBS_PUSHED, CBS_PUSHED); +var + PPI : Integer; begin + {$IF CompilerVersion <= 30} + // Seattle and below, TMonitor.PixelsPerInch was introduced in Seattle + PPI := Screen.PixelsPerInch; + {$ELSE} + PPI := Screen.MonitorFromRect(ARect).PixelsPerInch; + {$IFEND} + if (PaintStage = pstPrePaint) and (AImageList = MDIButtonsImgList) and (AImageIndex >= 0) and (AImageIndex <= 3) then begin @@ -341,11 +350,13 @@ procedure TSpTBXMDIButtonsItem.DrawItemImage(Sender: TObject; ACanvas: TCanvas; sknNone: begin PaintDefault := False; + ARect := SpCenterRect(ARect, SpPPIScale(16, PPI), SpPPIScale(16, PPI)); DrawFrameControl(ACanvas.Handle, ARect, DFC_CAPTION, ButtonIndexFlags[AImageIndex] or NoneFlags[State]); end; sknWindows: begin PaintDefault := False; + ARect := SpCenterRect(ARect, SpPPIScale(16, PPI), SpPPIScale(16, PPI)); DrawThemeBackground(SpTBXThemeServices.Theme[teWindow], ACanvas.Handle, XPPart[AImageIndex], XPFlags[State], ARect, nil); end; end; @@ -584,7 +595,7 @@ procedure TSpTBXMRUListItem.GetMRUFilenames(MRUFilenames: TStrings); MRUFilenames.Add(TSpTBXMRUItem(Items[I]).MRUString); end; -function TSpTBXMRUListItem.IndexOfMRU(Filename: string): Integer; +function TSpTBXMRUListItem.IndexOfMRU(const Filename: string): Integer; var I: Integer; begin @@ -597,7 +608,7 @@ function TSpTBXMRUListItem.IndexOfMRU(Filename: string): Integer; end; end; -function TSpTBXMRUListItem.MRUAdd(Filename: string): Integer; +function TSpTBXMRUListItem.MRUAdd(const Filename: string): Integer; var A: TSpTBXMRUItem; I: Integer; @@ -623,7 +634,7 @@ function TSpTBXMRUListItem.MRUAdd(Filename: string): Integer; end; end; -function TSpTBXMRUListItem.MRUClick(Filename: string): Boolean; +function TSpTBXMRUListItem.MRUClick(const Filename: string): Boolean; var I: Integer; begin @@ -635,7 +646,7 @@ function TSpTBXMRUListItem.MRUClick(Filename: string): Boolean; end; end; -procedure TSpTBXMRUListItem.MRURemove(Filename: string); +procedure TSpTBXMRUListItem.MRURemove(const Filename: string); var I: Integer; begin diff --git a/Source/SpTBXPageScroller.pas b/Source/SpTBXPageScroller.pas index 4dd19b5..1f174c9 100644 --- a/Source/SpTBXPageScroller.pas +++ b/Source/SpTBXPageScroller.pas @@ -1,7 +1,7 @@ unit SpTBXPageScroller; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -42,7 +42,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -117,7 +117,6 @@ TSpTBXCustomPageScroller = class(TWinControl) procedure DrawNCArea(const DrawToDC: Boolean; const ADC: HDC; const Clip: HRGN); virtual; procedure HandleScrollTimer; virtual; procedure Loaded; override; - procedure RecalcNCArea; procedure Resizing; virtual; procedure UpdateButtons; property AutoRange: Boolean read FAutoRange write SetAutoRange default True; @@ -193,13 +192,13 @@ TSpTBXPageScroller = class(TSpTBXCustomPageScroller) end; { Painting helpers } -procedure SpTBXPaintPageScrollButton(ACanvas: TCanvas; const ARect: TRect; ButtonType: TSpTBXPageScrollerButtonType; Hot: Boolean); +procedure SpTBXPaintPageScrollButton(ACanvas: TCanvas; const ARect: TRect; ButtonType: TSpTBXPageScrollerButtonType; Hot: Boolean; DPI: Integer); implementation uses SysUtils, Types, TB2Common, - {$IF CompilerVersion >= 25} // for Delphi XE4 and up + {$IF CompilerVersion >= 24} // for Delphi XE3 and up System.UITypes, {$IFEND} UxTheme, Themes; @@ -228,7 +227,7 @@ function GetMinControlWidth(Control: TControl): Integer; end; procedure SpTBXPaintPageScrollButton(ACanvas: TCanvas; const ARect: TRect; - ButtonType: TSpTBXPageScrollerButtonType; Hot: Boolean); + ButtonType: TSpTBXPageScrollerButtonType; Hot: Boolean; DPI: Integer); var R: TRect; Flags: Integer; @@ -257,12 +256,12 @@ procedure SpTBXPaintPageScrollButton(ACanvas: TCanvas; const ARect: TRect; else Details := SpTBXThemeServices.GetElementDetails(tbPushButtonNormal); - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, Details, DPI); CurrentSkin.GetThemedElementTextColor(Details, C); end; sknSkin: begin - SpDrawXPButton(ACanvas, R, True, False, Hot, False, False, False); + SpDrawXPButton(ACanvas, R, True, False, Hot, False, False, False, DPI); if Hot then C := CurrentSkin.GetTextColor(skncButton, sknsHotTrack) else @@ -563,14 +562,14 @@ procedure TSpTBXCustomPageScroller.DrawNCArea(const DrawToDC: Boolean; BR := R; if Orientation = tpsoVertical then BR.Bottom := BR.Top + ButtonSize else BR.Right := BR.Left + ButtonSize; - SpTBXPaintPageScrollButton(ACanvas, BR, CBtns[Orientation, False], FScrollDirection < 0); + SpTBXPaintPageScrollButton(ACanvas, BR, CBtns[Orientation, False], FScrollDirection < 0, CurrentPPI); end; if tpsbNext in FVisibleButtons then begin BR := R; if Orientation = tpsoVertical then BR.Top := BR.Bottom - ButtonSize else BR.Left := BR.Right - ButtonSize; - SpTBXPaintPageScrollButton(ACanvas, BR, CBtns[Orientation, True], FScrollDirection > 0); + SpTBXPaintPageScrollButton(ACanvas, BR, CBtns[Orientation, True], FScrollDirection > 0, CurrentPPI); end; ACanvas.Brush.Color := clBlue; ACanvas.Pen.Color := clBlue; @@ -647,12 +646,6 @@ procedure TSpTBXCustomPageScroller.Loaded; UpdateButtons; end; -procedure TSpTBXCustomPageScroller.RecalcNCArea; -begin - SetWindowPos(Handle, 0, 0, 0, 0, 0, - SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOZORDER or SWP_NOMOVE or SWP_NOSIZE); -end; - procedure TSpTBXCustomPageScroller.Resizing; begin // do nothing by default @@ -788,7 +781,7 @@ procedure TSpTBXCustomPageScroller.UpdateButtons; end; if FVisibleButtons <> OldVisibleButtons then begin - RecalcNCArea; + SpRecalcNCArea(Self); RealignNeeded := True; end; finally diff --git a/Source/SpTBXReg.pas b/Source/SpTBXReg.pas index 067ad53..53d6003 100644 --- a/Source/SpTBXReg.pas +++ b/Source/SpTBXReg.pas @@ -64,6 +64,21 @@ TSpTBXImageIndexEditor = class(TIntegerProperty, ICustomPropertyListDrawing) procedure ListDrawValue(const Value: string; ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean); end; + { TSpTBXImageNameEditor } + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + TSpTBXImageNameEditor = class(TStringProperty, ICustomPropertyListDrawing) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + function GetImageListAt(Index: Integer): TCustomImageList; virtual; + + // ICustomPropertyListDrawing + procedure ListMeasureHeight(const Value: string; ACanvas: TCanvas; var AHeight: Integer); + procedure ListMeasureWidth(const Value: string; ACanvas: TCanvas; var AWidth: Integer); + procedure ListDrawValue(const Value: string; ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean); + end; + {$IFEND} + procedure Register; implementation @@ -206,6 +221,72 @@ procedure TSpTBXImageIndexEditor.ListMeasureWidth(const Value: string; Inc(AWidth, ImgList.Width); end; +//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM +{ TSpTBXImageNameEditor } + +{$IF CompilerVersion >= 34} // Robert: for Delphi Sydney and up + +function TSpTBXImageNameEditor.GetAttributes: TPropertyAttributes; +begin + Result := [paMultiSelect, paValueList, paRevertable]; +end; + +function TSpTBXImageNameEditor.GetImageListAt(Index: Integer): TCustomImageList; +begin + Result := TCustomImageList(TypInfo.GetObjectProp(GetComponent(Index), 'Images')); +end; + +procedure TSpTBXImageNameEditor.GetValues(Proc: TGetStrProc); +var + ImgList: TCustomImageList; + I: Integer; +begin + ImgList := GetImageListAt(0); + if Assigned(ImgList) and ImgList.IsImageNameAvailable then + for I := 0 to ImgList.Count-1 do + Proc(ImgList.GetNameByIndex(I)); +end; + +procedure TSpTBXImageNameEditor.ListDrawValue(const Value: string; + ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean); +var + ImgList: TCustomImageList; + X: Integer; +begin + ImgList := GetImageListAt(0); + ACanvas.FillRect(ARect); + X := ARect.Left + 2; + if Assigned(ImgList) then begin + ImgList.Draw(ACanvas, X, ARect.Top + 2, ImgList.GetIndexByName(Value)); + Inc(X, ImgList.Width); + end; + ACanvas.TextOut(X + 3, ARect.Top + 1, Value); +end; + +procedure TSpTBXImageNameEditor.ListMeasureHeight(const Value: string; + ACanvas: TCanvas; var AHeight: Integer); +var + ImgList: TCustomImageList; +begin + ImgList := GetImageListAt(0); + AHeight := ACanvas.TextHeight(Value) + 2; + if Assigned(ImgList) and (ImgList.Height + 4 > AHeight) then + AHeight := ImgList.Height + 4; +end; + +procedure TSpTBXImageNameEditor.ListMeasureWidth(const Value: string; + ACanvas: TCanvas; var AWidth: Integer); +var + ImgList: TCustomImageList; +begin + ImgList := GetImageListAt(0); + AWidth := ACanvas.TextWidth(Value) + 4; + if Assigned(ImgList) then + Inc(AWidth, ImgList.Width); +end; + +{$IFEND} + //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM procedure Register; @@ -287,9 +368,12 @@ procedure Register; RegisterComponentEditor(TSpTBXCustomizer, TSpTBXItemsEditor); RegisterComponentEditor(TSpTBXPopupMenu, TSpTBXItemsEditor); - // Register the ImageIndex property editor for TSpTBXTextObject descendants, this is - // needed to show the preview of images in the property editor combobox. + // Register ImageIndex and ImageName property editor for TSpTBXTextObject + // descendants, this is needed to show the preview of images in the Object Inspector. RegisterPropertyEditor(TypeInfo(TImageIndex), TSpTBXTextObject, '', TSpTBXImageIndexEditor); + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + RegisterPropertyEditor(TypeInfo(TImageName), TSpTBXTextObject, '', TSpTBXImageNameEditor); + {$IFEND} end; end. diff --git a/Source/SpTBXSkins.pas b/Source/SpTBXSkins.pas index ae3abe6..217a4db 100644 --- a/Source/SpTBXSkins.pas +++ b/Source/SpTBXSkins.pas @@ -1,7 +1,7 @@ unit SpTBXSkins; {============================================================================== -Version 2.5.4 +Version 2.5.8 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -58,19 +58,24 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses Windows, Messages, Classes, SysUtils, Graphics, Controls, StdCtrls, ImgList, IniFiles, Types, - {$IF CompilerVersion >= 25} // for Delphi XE4 and up - System.UITypes, + {$IF CompilerVersion >= 23} // for Delphi XE2 and up + System.UITypes, Styles, {$IFEND} Themes, Generics.Collections; +resourcestring + SSpTBXColorNone = 'None'; + SSpTBXColorDefault = 'Default'; + const WM_SPSKINCHANGE = WM_APP + 2007; // Skin change notification message + SpDefaultBorderSize = 2; // Do not scale type { Skins } @@ -82,13 +87,6 @@ interface sknDelphiStyle // Use Delphi Custom Styles ); - TSpTBXLunaScheme = ( - lusBlue, - lusMetallic, - lusGreen, - lusUnknown - ); - TSpTBXSkinComponentsType = ( skncDock, skncDockablePanel, @@ -137,6 +135,8 @@ TSpTBXSkinComponentsIdentEntry = record States: TSpTBXSkinStatesSet; end; + TPPIScale = function(Value: Integer): Integer of object; + const SpTBXSkinMultiStateComponents: set of TSpTBXSkinComponentsType = [skncMenuBarItem..High(TSpTBXSkinComponentsType)]; @@ -202,7 +202,8 @@ TSpTBXTextInfo = record TSpGlyphLayout = ( ghlGlyphLeft, // Glyph icon on the left of the caption - ghlGlyphTop // Glyph icon on the top of the caption + ghlGlyphTop, // Glyph icon on the top of the caption + ghlGlyphNone ); TSpGlowDirection = ( @@ -237,6 +238,7 @@ TSpTBXMenuItemMarginsInfo = record end; TSpTBXMenuItemInfo = record + CurrentPPI: Integer; Enabled: Boolean; HotTrack: Boolean; Pushed: Boolean; @@ -265,7 +267,7 @@ TSpTBXMenuItemInfo = record { Colors } TSpTBXColorTextType = ( - cttDefault, // Default format (clWhite, $FFFFFF) + cttDefault, // Use color idents (clWhite), if not possible use Delphi format ($FFFFFF) cttHTML, // HTML format (#FFFFFF) cttIdentAndHTML // Use color idents (clWhite), if not possible use HTML format ); @@ -281,7 +283,7 @@ TSpTBXSkinOptionEntry = class(TPersistent) public constructor Create; virtual; procedure Fill(ASkinType: Integer; AColor1, AColor2, AColor3, AColor4: TColor); - procedure ReadFromString(S: string); + procedure ReadFromString(const S: string); function WriteToString: string; function IsEmpty: Boolean; function IsEqual(AOptionEntry: TSpTBXSkinOptionEntry): Boolean; @@ -307,8 +309,9 @@ TSpTBXSkinOptionCategory = class(TPersistent) destructor Destroy; override; function IsEmpty: Boolean; procedure Reset; - procedure LoadFromIni(MemIni: TMemIniFile; Section, Ident: string); - procedure SaveToIni(MemIni: TMemIniFile; Section, Ident: string); + procedure LoadFromIni(MemIni: TMemIniFile; const Section: string; Ident: + string); + procedure SaveToIni(MemIni: TMemIniFile; const Section, Ident: string); published property Body: TSpTBXSkinOptionEntry read FBody write FBody; property Borders: TSpTBXSkinOptionEntry read FBorders write FBorders; @@ -341,39 +344,38 @@ TSpTBXSkinOptions = class(TPersistent) procedure FillOptions; virtual; function Options(Component: TSpTBXSkinComponentsType; State: TSpTBXSkinStatesType): TSpTBXSkinOptionCategory; overload; function Options(Component: TSpTBXSkinComponentsType): TSpTBXSkinOptionCategory; overload; - procedure LoadFromFile(Filename: string); + procedure LoadFromFile(const Filename: string); procedure LoadFromStrings(L: TStrings); virtual; - procedure SaveToFile(Filename: string); + procedure SaveToFile(const Filename: string); procedure SaveToStrings(L: TStrings); virtual; procedure SaveToMemIni(MemIni: TMemIniFile); virtual; procedure Reset(ForceResetSkinProperties: Boolean = False); // Metrics - procedure GetDropDownArrowSize(out DropDownArrowSize, DropDownArrowMargin, SplitBtnArrowSize: Integer); virtual; - procedure GetMenuItemMargins(ACanvas: TCanvas; ImgSize: Integer; out MarginsInfo: TSpTBXMenuItemMarginsInfo); virtual; + procedure GetMenuItemMargins(ACanvas: TCanvas; ImgSize: Integer; out MarginsInfo: TSpTBXMenuItemMarginsInfo; DPI: Integer); virtual; function GetState(Enabled, Pushed, HotTrack, Checked: Boolean): TSpTBXSkinStatesType; overload; procedure GetState(State: TSpTBXSkinStatesType; out Enabled, Pushed, HotTrack, Checked: Boolean); overload; function GetTextColor(Component: TSpTBXSkinComponentsType; State: TSpTBXSkinStatesType): TColor; virtual; function GetThemedElementDetails(Component: TSpTBXSkinComponentsType; Enabled, Pushed, HotTrack, Checked, Focused, Defaulted, Grayed: Boolean; out Details: TThemedElementDetails): Boolean; overload; function GetThemedElementDetails(Component: TSpTBXSkinComponentsType; State: TSpTBXSkinStatesType; out Details: TThemedElementDetails): Boolean; overload; - function GetThemedElementSize(ACanvas: TCanvas; Details: TThemedElementDetails): TSize; + function GetThemedElementSize(ACanvas: TCanvas; Details: TThemedElementDetails; DPI: Integer): TSize; procedure GetThemedElementTextColor(Details: TThemedElementDetails; out AColor: TColor); function GetThemedSystemColor(AColor: TColor): TColor; // Skin Paint procedure PaintBackground(ACanvas: TCanvas; ARect: TRect; Component: TSpTBXSkinComponentsType; State: TSpTBXSkinStatesType; Background, Borders: Boolean; Vertical: Boolean = False; ForceRectBorders: TAnchors = []); virtual; - procedure PaintThemedElementBackground(ACanvas: TCanvas; ARect: TRect; Details: TThemedElementDetails); overload; - procedure PaintThemedElementBackground(ACanvas: TCanvas; ARect: TRect; Component: TSpTBXSkinComponentsType; State: TSpTBXSkinStatesType); overload; - procedure PaintThemedElementBackground(ACanvas: TCanvas; ARect: TRect; Component: TSpTBXSkinComponentsType; Enabled, Pushed, HotTrack, Checked, Focused, Defaulted, Grayed: Boolean); overload; + procedure PaintThemedElementBackground(ACanvas: TCanvas; ARect: TRect; Details: TThemedElementDetails; DPI: Integer); overload; + procedure PaintThemedElementBackground(ACanvas: TCanvas; ARect: TRect; Component: TSpTBXSkinComponentsType; State: TSpTBXSkinStatesType; DPI: Integer); overload; + procedure PaintThemedElementBackground(ACanvas: TCanvas; ARect: TRect; Component: TSpTBXSkinComponentsType; Enabled, Pushed, HotTrack, Checked, Focused, Defaulted, Grayed: Boolean; DPI: Integer); overload; // Element Paint - procedure PaintMenuCheckMark(ACanvas: TCanvas; ARect: TRect; Checked, Grayed: Boolean; State: TSpTBXSkinStatesType); virtual; - procedure PaintMenuRadioMark(ACanvas: TCanvas; ARect: TRect; Checked: Boolean; State: TSpTBXSkinStatesType); virtual; + procedure PaintMenuCheckMark(ACanvas: TCanvas; ARect: TRect; Checked, Grayed: Boolean; State: TSpTBXSkinStatesType; DPI: Integer); virtual; + procedure PaintMenuRadioMark(ACanvas: TCanvas; ARect: TRect; Checked: Boolean; State: TSpTBXSkinStatesType; DPI: Integer); virtual; procedure PaintWindowFrame(ACanvas: TCanvas; ARect: TRect; IsActive, DrawBody: Boolean; BorderSize: Integer = 4); virtual; // Properties property ColorBtnFace: TColor read FColorBtnFace write FColorBtnFace; - property FloatingWindowBorderSize: Integer read GetFloatingWindowBorderSize write SetFloatingWindowBorderSize; + property FloatingWindowBorderSize: Integer read GetFloatingWindowBorderSize write SetFloatingWindowBorderSize; // Unscaled property OfficeIcons: Boolean read GetOfficeIcons write FOfficeIcons; property OfficeMenu: Boolean read GetOfficeMenu write FOfficeMenu; property OfficePopup: Boolean read GetOfficePopup; @@ -420,19 +422,19 @@ TSpTBXSkinManager = class procedure RemoveSkinNotification(AObject: TObject); procedure BroadcastSkinNotification; - procedure LoadFromFile(Filename: string); - procedure SaveToFile(Filename: string); + procedure LoadFromFile(const Filename: string); + procedure SaveToFile(const Filename: string); - procedure AddSkin(SkinName: string; SkinClass: TSpTBXSkinOptionsClass); overload; + procedure AddSkin(const SkinName: string; SkinClass: TSpTBXSkinOptionsClass); overload; procedure AddSkin(SkinOptions: TStrings); overload; - function AddSkinFromFile(Filename: string): string; + function AddSkinFromFile(const Filename: string): string; procedure SetToDefaultSkin; - procedure SetSkin(SkinName: string); + procedure SetSkin(const SkinName: string); // [Old-Themes] {$IF CompilerVersion >= 23} // for Delphi XE2 and up - procedure SetDelphiStyle(StyleName: string); - function IsValidDelphiStyle(StyleName: string): Boolean; + procedure SetDelphiStyle(const StyleName: string); + function IsValidDelphiStyle(const StyleName: string): Boolean; {$IFEND} property CurrentSkin: TSpTBXSkinOptions read FCurrentSkin; @@ -470,11 +472,16 @@ TSpTBXSkinSwitcher = class(TComponent) // http://msdn2.microsoft.com/en-us/library/ms535695.aspx TSpPrintWindow = function(Hnd: HWND; HdcBlt: HDC; nFlags: UINT): BOOL; stdcall; +{ Delphi Styles} +{$IF CompilerVersion >= 23} // for Delphi XE2 and up +function SpStyleGetElementObject(Style: TCustomStyleServices; const ControlName, ElementName: string): TObject; +function SpStyleDrawBitmapElement(const ControlName, ElementName: string; State: TSpTBXSkinStatesType; DC: HDC; const R: TRect; ClipRect: PRect; Stretch: Boolean; DPI: Integer): Boolean; +{$IFEND} + { Themes } function SpTBXThemeServices: TSpTBXThemeServices; function SkinManager: TSpTBXSkinManager; function CurrentSkin: TSpTBXSkinOptions; -function SpGetLunaScheme: TSpTBXLunaScheme; procedure SpFillGlassRect(ACanvas: TCanvas; ARect: TRect); function SpIsGlassPainting(AControl: TControl): Boolean; procedure SpDrawParentBackground(Control: TControl; DC: HDC; R: TRect); @@ -482,19 +489,18 @@ procedure SpDrawParentBackground(Control: TControl; DC: HDC; R: TRect); { WideString helpers } function SpCreateRotatedFont(DC: HDC; Orientation: Integer = 2700): HFONT; function SpDrawRotatedText(const DC: HDC; AText: string; var ARect: TRect; const AFormat: Cardinal; RotationAngle: TSpTextRotationAngle = tra270): Integer; -function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; CaptionAlignment: TAlignment; Flags: Cardinal; GlyphSize, RightGlyphSize: TSize; Layout: TSpGlyphLayout; PushedCaption: Boolean; out ACaptionRect, AGlyphRect, ARightGlyphRect: TRect; RotationAngle: TSpTextRotationAngle = tra0): Integer; +function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; CaptionAlignment: TAlignment; Flags: Cardinal; GlyphSize, RightGlyphSize: TSize; Layout: TSpGlyphLayout; PushedCaption: Boolean; DPI: Integer; out ACaptionRect, AGlyphRect, ARightGlyphRect: TRect; RotationAngle: TSpTextRotationAngle = tra0): Integer; overload; +function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; CaptionAlignment: TAlignment; Flags: Cardinal; GlyphSize: TSize; Layout: TSpGlyphLayout; PushedCaption: Boolean; DPI: Integer; out ACaptionRect, AGlyphRect: TRect; RotationAngle: TSpTextRotationAngle = tra0): Integer; overload; function SpDrawXPGlassText(ACanvas: TCanvas; Caption: string; var ARect: TRect; Flags: Cardinal; CaptionGlowSize: Integer): Integer; -function SpDrawXPText(ACanvas: TCanvas; Caption: string; var ARect: TRect; Flags: Cardinal; CaptionGlow: TSpGlowDirection = gldNone; CaptionGlowColor: TColor = clYellow; RotationAngle: TSpTextRotationAngle = tra0): Integer; overload; -function SpDrawXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; CaptionGlow: TSpGlowDirection; CaptionGlowColor: TColor; CaptionAlignment: TAlignment; Flags: Cardinal; GlyphSize: TSize; Layout: TSpGlyphLayout; PushedCaption: Boolean; out ACaptionRect, AGlyphRect: TRect; RotationAngle: TSpTextRotationAngle = tra0): Integer; overload; -function SpDrawXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; CaptionGlow: TSpGlowDirection; CaptionGlowColor: TColor; CaptionAlignment: TAlignment; Flags: Cardinal; IL: TCustomImageList; ImageIndex: Integer; Layout: TSpGlyphLayout; Enabled, PushedCaption, DisabledIconCorrection: Boolean; out ACaptionRect, AGlyphRect: TRect; RotationAngle: TSpTextRotationAngle = tra0): Integer; overload; +function SpDrawXPText(ACanvas: TCanvas; Caption: string; var ARect: TRect; Flags: Cardinal; CaptionGlow: TSpGlowDirection = gldNone; CaptionGlowColor: TColor = clYellow; RotationAngle: TSpTextRotationAngle = tra0): Integer; function SpGetTextSize(DC: HDC; S: string; NoPrefix: Boolean): TSize; function SpGetControlTextHeight(AControl: TControl; AFont: TFont): Integer; function SpGetControlTextSize(AControl: TControl; AFont: TFont; S: string): TSize; -function SpStripAccelChars(S: string): string; -function SpStripShortcut(S: string): string; -function SpStripTrailingPunctuation(S: string): string; +function SpStripAccelChars(const S: string): string; +function SpStripShortcut(const S: string): string; +function SpStripTrailingPunctuation(const S: string): string; function SpRectToString(R: TRect): string; -function SpStringToRect(S: string; out R: TRect): Boolean; +function SpStringToRect(const S: string; out R: TRect): Boolean; { Color helpers } function SpColorToHTML(const Color: TColor): string; @@ -518,10 +524,6 @@ procedure SpDrawRectangle(ACanvas: TCanvas; ARect: TRect; CornerSize: Integer; C procedure SpAlphaBlend(SrcDC, DstDC: HDC; SrcR, DstR: TRect; Alpha: Byte; SrcHasAlphaChannel: Boolean = False); procedure SpPaintTo(WinControl: TWinControl; ACanvas: TCanvas; X, Y: Integer); -{ ImageList painting } -procedure SpDrawIconShadow(ACanvas: TCanvas; const ARect: TRect; ImageList: TCustomImageList; ImageIndex: Integer); -procedure SpDrawImageList(ACanvas: TCanvas; const ARect: TRect; ImageList: TCustomImageList; ImageIndex: Integer; Enabled, DisabledIconCorrection: Boolean); - { Gradients } procedure SpGradient(ACanvas: TCanvas; const ARect: TRect; StartPos, EndPos, ChunkSize: Integer; C1, C2: TColor; const Vertical: Boolean); procedure SpGradientFill(ACanvas: TCanvas; const ARect: TRect; const C1, C2: TColor; const Vertical: Boolean); @@ -533,14 +535,14 @@ procedure SpGradientFillGlass(ACanvas: TCanvas; const ARect: TRect; const C1, C2 procedure SpDrawArrow(ACanvas: TCanvas; X, Y: Integer; AColor: TColor; Vertical, Reverse: Boolean; Size: Integer); procedure SpDrawDropMark(ACanvas: TCanvas; DropMark: TRect); procedure SpDrawFocusRect(ACanvas: TCanvas; const ARect: TRect); -procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; Pattern: TSpTBXGlyphPattern; PatternColor: TColor); -procedure SpDrawXPButton(ACanvas: TCanvas; ARect: TRect; Enabled, Pushed, HotTrack, Checked, Focused, Defaulted: Boolean); -procedure SpDrawXPCheckBoxGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Boolean; State: TCheckBoxState; HotTrack, Pushed: Boolean); -procedure SpDrawXPRadioButtonGlyph(ACanvas: TCanvas; ARect: TRect; Enabled, Checked, HotTrack, Pushed: Boolean); -procedure SpDrawXPEditFrame(ACanvas: TCanvas; ARect: TRect; Enabled, HotTrack: Boolean; ClipContent: Boolean = False; AutoAdjust: Boolean = False); overload; -procedure SpDrawXPEditFrame(AWinControl: TWinControl; HotTracking: Boolean; AutoAdjust: Boolean = False; HideFrame: Boolean = False); overload; -procedure SpDrawXPGrip(ACanvas: TCanvas; ARect: TRect; LoC, HiC: TColor); -procedure SpDrawXPHeader(ACanvas: TCanvas; ARect: TRect; HotTrack, Pushed: Boolean); +procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; Pattern: TSpTBXGlyphPattern; PatternColor: TColor; DPI: Integer); +procedure SpDrawXPButton(ACanvas: TCanvas; ARect: TRect; Enabled, Pushed, HotTrack, Checked, Focused, Defaulted: Boolean; DPI: Integer); +procedure SpDrawXPCheckBoxGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Boolean; State: TCheckBoxState; HotTrack, Pushed: Boolean; DPI: Integer); +procedure SpDrawXPRadioButtonGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Boolean; Checked, HotTrack, Pushed: Boolean; DPI: Integer); +procedure SpDrawXPEditFrame(ACanvas: TCanvas; ARect: TRect; Enabled, HotTrack, ClipContent, AutoAdjust: Boolean; DPI: Integer); overload; +procedure SpDrawXPEditFrame(AWinControl: TWinControl; HotTracking, AutoAdjust, HideFrame: Boolean; DPI: Integer); overload; +procedure SpDrawXPGrip(ACanvas: TCanvas; ARect: TRect; LoC, HiC: TColor; DPI: Integer); +procedure SpDrawXPHeader(ACanvas: TCanvas; ARect: TRect; HotTrack, Pushed: Boolean; DPI: Integer); procedure SpDrawXPListItemBackground(ACanvas: TCanvas; ARect: TRect; Selected, HotTrack, Focused: Boolean; ForceRectBorders: Boolean = False; Borders: Boolean = True); { Skins painting } @@ -549,10 +551,14 @@ procedure SpPaintSkinBorders(ACanvas: TCanvas; ARect: TRect; SkinOption: TSpTBXS { Misc } function SpIsWinVistaOrUp: Boolean; +function SpIsWin10OrUp: Boolean; function SpGetDirectories(Path: string; L: TStringList): Boolean; -function SpDPIScale(I: Integer): Integer; -procedure SpDPIResizeBitmap(Bitmap: TBitmap; const NewWidth, NewHeight: Integer); -procedure SpDPIScaleImageList(const ImageList: TCustomImageList); + +{ DPI } +function SpPPIScale(Value, DPI: Integer): Integer; +function SpPPIScaleToDPI(PPIScale: TPPIScale): Integer; +procedure SpDPIResizeBitmap(Bitmap: TBitmap; const NewWidth, NewHeight, DPI: Integer); +procedure SpDPIScaleImageList(const ImageList: TCustomImageList; M, D: Integer); { Stock Objects } var @@ -562,11 +568,8 @@ procedure SpDPIScaleImageList(const ImageList: TCustomImageList); implementation uses - UxTheme, Forms, Math, TypInfo, - SpTBXDefaultSkins, CommCtrl; - -const - ROP_DSPDxax = $00E20746; + UxTheme, Forms, TypInfo, CommCtrl, + SpTBXDefaultSkins, Rtti, TB2Common; type TControlAccess = class(TControl); @@ -574,6 +577,122 @@ TControlAccess = class(TControl); var FInternalSkinManager: TSpTBXSkinManager = nil; +//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM +{ Delphi Styles } + +{$IF CompilerVersion >= 23} // for Delphi XE2 and up + +function SpStyleGetElementObject(Style: TCustomStyleServices; const ControlName, ElementName: string): TObject; +// From Vcl.Styles.GetElementObject +// Returns a TObject that is a TSeStyleObject: +// TSeBitmapObject(TSeStyleObject) +// TSeButtonObject(TSeBitmapObject) +// TSeTextObject(TSeStyleObject) +// Use Bitmap Style Designer to browse the different controls and elements +// of a style, and the class types of such elements. +var + RttiC: TRttiContext; + CustomStyle: TCustomStyle; + SeStyle, SeStyleSource, SeStyleObject: TObject; +begin + Result := nil; + if Style is TCustomStyle then + CustomStyle := Style as TCustomStyle + else + Exit; + + // Use RTTI to access fields, properties and methods of structures on StyleAPI.inc + RttiC := TRttiContext.Create; + // Get Vcl.Styles.TCustomStyle.FSource which is a StyleAPI.inc.TSeStyle (actual Delphi style file) + SeStyle := RttiC.GetType(CustomStyle.ClassType).GetField('FSource').GetValue(CustomStyle).AsObject; + // Get StyleAPI.inc.TSeStyle.FStyleSource which is a StyleAPI.inc.TSeStyleSource (structure that contains all the style options and bitmaps) + SeStyleSource := RttiC.GetType(SeStyle.ClassType).GetField('FStyleSource').GetValue(SeStyle).AsObject; + + // Find the control (TSeStyleObject) + // Call StyleAPI.inc.TSeStyleSource.GetObjectByName method that returns a StyleAPI.inc.TSeStyleObject + SeStyleObject := RttiC.GetType(SeStyleSource.ClassType).GetMethod('GetObjectByName').Invoke(SeStyleSource, [ControlName]).AsObject; + + // Find the element of the control (TSeStyleObject/TSeBitmapObject/TSeButtonObject) + // Call StyleAPI.inc.TSeStyleObject.FindObjectByName method that returns a StyleAPI.inc.TSeStyleObject + if SeStyleObject <> nil then begin + SeStyleObject := RttiC.GetType(SeStyleObject.ClassType).GetMethod('FindObjectByName').Invoke(SeStyleObject, [ElementName]).AsObject; + if SeStyleObject <> nil then + Result := SeStyleObject; + end; +end; + +function SpStyleDrawBitmapElement(const ControlName, ElementName: string; + State: TSpTBXSkinStatesType; DC: HDC; const R: TRect; ClipRect: PRect; + Stretch: Boolean; DPI: Integer): Boolean; +// From Vcl.Styles.DrawBitmapElement +// Used to paint a style element. For example: +// SpStyleDrawBitmapElement('CheckBox', 'Checked', sknsPushed, ACanvas.Handle, Rect(0, 0, 100, 100), nil, True, CurrentPPI); +var + RttiC: TRttiContext; + Element: TObject; + V1, V2, V3: TValue; + SeState: TValue; // TSeState = (ssNormal, ssDesign, ssMaximized, ssMinimized, ssRollup, ssHot, ssPressed, ssFocused, ssDisabled) + scTileStyle: TValue; // TscTileStyle = (tsTile, tsStretch, tsCenter, tsVertCenterStretch, tsVertCenterTile, tsHorzCenterStretch, tsHorzCenterTile); + I: Int64; + IsBitmapObject: Boolean; +begin + Result := False; + Element := SpStyleGetElementObject(StyleServices, ControlName, ElementName); + if Element <> nil then begin + // Use RTTI to access fields, properties and methods of structures on StyleAPI.inc + // Before calling StyleAPI.inc.TSeStyleObject.Draw we need to set BoundsRect, State and TileStyle properties + RttiC := TRttiContext.Create; + // Set StyleAPI.inc.TSeStyleObject.BoundsRect + V1 := V1.From(R); + RttiC.GetType(Element.ClassType).GetProperty('BoundsRect').SetValue(Element, V1); + + // Set StyleAPI.inc.TSeStyleObject.State + SeState := RttiC.GetType(Element.ClassType).GetProperty('State').GetValue(Element); + case State of + sknsDisabled: I := 7; // ssDisabled + sknsHotTrack: I := 5; // ssHot + sknsPushed: I := 6; // ssPressed + else + I := 0; // ssNormal + end; + SeState := SeState.FromOrdinal(SeState.TypeInfo, I); + RttiC.GetType(Element.ClassType).GetProperty('State').SetValue(Element, SeState); + + // If Stretch then check if is a TSeBitmapObject and set StyleAPI.inc.TSeBitmapObject.TileStyle + // to tsStretch, and after painting reset to original value + IsBitmapObject := (Element.ClassName = 'TSeBitmapObject') or + (Element.ClassName = 'TSeButtonObject') or (Element.ClassName = 'TSeActiveBitmap'); + if Stretch and IsBitmapObject then begin + scTileStyle := RttiC.GetType(Element.ClassType).GetProperty('TileStyle').GetValue(Element); + V3 := V3.FromOrdinal(scTileStyle.TypeInfo, 1); // tsStretch = 1 + RttiC.GetType(Element.ClassType).GetProperty('TileStyle').SetValue(Element, V3); + end; + try + // Call StyleAPI.inc.TSeStyleObject.Draw + // From Vcl.Styles.DrawBitmapElement + with TGDIHandleRecall.Create(DC, OBJ_FONT) do + try + V1 := V1.From(Canvas); + if ClipRect <> nil then + V2 := V2.From(ClipRect^) + else + V2 := V2.From(Rect(-1, -1, -1, -1)); + RttiC.GetType(Element.ClassType).GetMethod('Draw').Invoke(Element, [V1, V2, DPI]); + finally + Free; + end; + finally + // Reset to original value + if Stretch and IsBitmapObject then + RttiC.GetType(Element.ClassType).GetProperty('TileStyle').SetValue(Element, scTileStyle); + end; + + Result := True; + end; +end; + +{$IFEND} + //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Themes } @@ -598,38 +717,6 @@ function CurrentSkin: TSpTBXSkinOptions; Result := SkinManager.CurrentSkin; end; -function SpGetLunaScheme: TSpTBXLunaScheme; -const - MaxChars = 1024; -var - pszThemeFileName, pszColorBuff, pszSizeBuf: PWideChar; - S: string; -begin - Result := lusUnknown; - - if SkinManager.IsXPThemesEnabled then begin - GetMem(pszThemeFileName, 2 * MaxChars); - GetMem(pszColorBuff, 2 * MaxChars); - GetMem(pszSizeBuf, 2 * MaxChars); - try - if not Failed(GetCurrentThemeName(pszThemeFileName, MaxChars, pszColorBuff, MaxChars, pszSizeBuf, MaxChars)) then - if UpperCase(ExtractFileName(pszThemeFileName)) = 'LUNA.MSSTYLES' then begin - S := UpperCase(pszColorBuff); - if S = 'NORMALCOLOR' then - Result := lusBlue - else if S = 'METALLIC' then - Result := lusMetallic - else if S = 'HOMESTEAD' then - Result := lusGreen; - end; - finally - FreeMem(pszSizeBuf); - FreeMem(pszColorBuff); - FreeMem(pszThemeFileName); - end; - end; -end; - procedure SpFillGlassRect(ACanvas: TCanvas; ARect: TRect); var MemDC: HDC; @@ -859,24 +946,34 @@ function SpDrawRotatedText(const DC: HDC; AText: string; var ARect: TRect; const function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; CaptionAlignment: TAlignment; Flags: Cardinal; GlyphSize, RightGlyphSize: TSize; - Layout: TSpGlyphLayout; PushedCaption: Boolean; out ACaptionRect, AGlyphRect, ARightGlyphRect: TRect; - RotationAngle: TSpTextRotationAngle = tra0): Integer; + Layout: TSpGlyphLayout; PushedCaption: Boolean; DPI: Integer; out ACaptionRect, + AGlyphRect, ARightGlyphRect: TRect; RotationAngle: TSpTextRotationAngle = tra0): Integer; +// RightGlyphSize and ARightGlyphRect mostly used by tab items var + CaptionInt: string; R: TRect; TextOffset, Spacing, RightSpacing: TPoint; CaptionSz: TSize; + PP1, PP2, PP4: Integer; begin Result := 0; + PP1 := SpPPIScale(1, DPI); + PP2 := SpPPIScale(2, DPI); + PP4 := SpPPIScale(4, DPI); ACaptionRect := Rect(0, 0, 0, 0); AGlyphRect := Rect(0, 0, 0, 0); ARightGlyphRect := Rect(0, 0, 0, 0); TextOffset := Point(0, 0); Spacing := Point(0, 0); RightSpacing := Point(0, 0); + if Layout = ghlGlyphNone then + CaptionInt := '' + else + CaptionInt := Caption; if (Caption <> '') and (GlyphSize.cx > 0) and (GlyphSize.cy > 0) then - Spacing := Point(SpDPIScale(4), SpDPIScale(1)); + Spacing := Point(PP4, PP1); if (Caption <> '') and (RightGlyphSize.cx > 0) and (RightGlyphSize.cy > 0) then - RightSpacing := Point(SpDPIScale(4), SpDPIScale(1)); + RightSpacing := Point(PP4, PP1); Flags := Flags and not DT_CENTER; Flags := Flags and not DT_VCENTER; @@ -891,13 +988,13 @@ function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; // Get the caption size if ((Flags and DT_WORDBREAK) <> 0) or ((Flags and DT_END_ELLIPSIS) <> 0) or ((Flags and DT_PATH_ELLIPSIS) <> 0) then begin - if Layout = ghlGlyphLeft then // Glyph on left or right side - R := Rect(0, 0, ARect.Right - ARect.Left - GlyphSize.cx - Spacing.X - RightGlyphSize.cx - RightSpacing.X + SpDPIScale(2), SpDPIScale(1)) + if (Layout in [ghlGlyphLeft, ghlGlyphNone]) then // Glyph on left or right side + R := Rect(0, 0, ARect.Right - ARect.Left - GlyphSize.cx - Spacing.X - RightGlyphSize.cx - RightSpacing.X + PP2, PP1) else // Glyph on top - R := Rect(0, 0, ARect.Right - ARect.Left + SpDPIScale(2), SpDPIScale(1)); + R := Rect(0, 0, ARect.Right - ARect.Left + PP2, PP1); end else - R := Rect(0, 0, SpDPIScale(1), SpDPIScale(1)); + R := Rect(0, 0, PP1, PP1); if (fsBold in ACanvas.Font.Style) and (RotationAngle = tra0) and (((Flags and DT_END_ELLIPSIS) <> 0) or ((Flags and DT_PATH_ELLIPSIS) <> 0)) then begin // [Bugfix] Windows bug: @@ -906,7 +1003,7 @@ function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; // The R.Right is reduced by 3 which cuts down the string and // adds the ellipsis. // We have to obtain the real size and check if it fits in the Rect. - CaptionSz := SpGetTextSize(ACanvas.Handle, Caption, True); + CaptionSz := SpGetTextSize(ACanvas.Handle, CaptionInt, True); if CaptionSz.cx <= R.Right then begin R := Rect(0, 0, CaptionSz.cx, CaptionSz.cy); Result := CaptionSz.cy; @@ -914,7 +1011,7 @@ function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; end; if Result <= 0 then begin - Result := SpDrawXPText(ACanvas, Caption, R, Flags or DT_CALCRECT, gldNone, clYellow); + Result := SpDrawXPText(ACanvas, CaptionInt, R, Flags or DT_CALCRECT, gldNone, clYellow); CaptionSz.cx := R.Right; CaptionSz.cy := R.Bottom; end; @@ -937,10 +1034,10 @@ function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; // try to fix it by padding the text 8 pixels to the right if (RotationAngle <> tra0) and (R.Right + 8 < ARect.Right) then if ((Flags and DT_END_ELLIPSIS) <> 0) or ((Flags and DT_PATH_ELLIPSIS) <> 0) then - R.Right := R.Right + SpDPIScale(8); + R.Right := R.Right + SpPPIScale(8, DPI); if PushedCaption then - OffsetRect(R, SpDPIScale(1), SpDPIScale(1)); + OffsetRect(R, PP1, PP1); ACaptionRect := R; end; @@ -957,7 +1054,7 @@ function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; taCenter: begin // Total width = Icon + Space + Text - if Layout = ghlGlyphLeft then begin + if (Layout in [ghlGlyphLeft, ghlGlyphNone]) then begin AGlyphRect.Left := R.Left + (R.Right - R.Left - (GlyphSize.cx + Spacing.X + CaptionSz.cx)) div 2; TextOffset.X := (GlyphSize.cx + Spacing.X) div 2; end @@ -976,7 +1073,7 @@ function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; end; end; - if Layout = ghlGlyphLeft then + if (Layout in [ghlGlyphLeft, ghlGlyphNone]) then AGlyphRect.Top := R.Top + (R.Bottom - R.Top - GlyphSize.cy) div 2 else begin AGlyphRect.Top := R.Top + (R.Bottom - R.Top - (GlyphSize.cy + Spacing.Y + CaptionSz.cy)) div 2; @@ -987,7 +1084,7 @@ function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; AGlyphRect.Bottom := AGlyphRect.Top + GlyphSize.cy; if PushedCaption then - OffsetRect(AGlyphRect, SpDPIScale(1), SpDPIScale(1)); + OffsetRect(AGlyphRect, PP1, PP1); end; // Move the text according to the icon position @@ -1014,6 +1111,22 @@ function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; end; end; +function SpCalcXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; + CaptionAlignment: TAlignment; Flags: Cardinal; GlyphSize: TSize; + Layout: TSpGlyphLayout; PushedCaption: Boolean; DPI: Integer; + out ACaptionRect, AGlyphRect: TRect; RotationAngle: TSpTextRotationAngle = tra0): Integer; +var + DummyRightGlyphSize: TSize; + DummyRightGlyphRect: TRect; +begin + DummyRightGlyphSize.cx := 0; + DummyRightGlyphSize.cy := 0; + DummyRightGlyphRect := Rect(0, 0, 0, 0); + Result := SpCalcXPText(ACanvas, ARect, Caption, CaptionAlignment, Flags, GlyphSize, + DummyRightGlyphSize, Layout, PushedCaption, DPI, ACaptionRect, AGlyphRect, + DummyRightGlyphRect, RotationAngle); +end; + function SpDrawXPGlassText(ACanvas: TCanvas; Caption: string; var ARect: TRect; Flags: Cardinal; CaptionGlowSize: Integer): Integer; @@ -1138,52 +1251,6 @@ function SpDrawXPText(ACanvas: TCanvas; Caption: string; var ARect: TRect; end; end; -function SpDrawXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; - CaptionGlow: TSpGlowDirection; CaptionGlowColor: TColor; CaptionAlignment: TAlignment; - Flags: Cardinal; GlyphSize: TSize; Layout: TSpGlyphLayout; PushedCaption: Boolean; - out ACaptionRect, AGlyphRect: TRect; - RotationAngle: TSpTextRotationAngle = tra0): Integer; overload; -var - DummyRightGlyphSize: TSize; - DummyRightGlyphRect: TRect; -begin - DummyRightGlyphSize.cx := 0; - DummyRightGlyphSize.cy := 0; - DummyRightGlyphRect := Rect(0, 0, 0, 0); - Result := SpCalcXPText(ACanvas, ARect, Caption, CaptionAlignment, Flags, GlyphSize, DummyRightGlyphSize, - Layout, PushedCaption, ACaptionRect, AGlyphRect, DummyRightGlyphRect, RotationAngle); - SpDrawXPText(ACanvas, Caption, ACaptionRect, Flags and not DT_CALCRECT, CaptionGlow, CaptionGlowColor, RotationAngle); -end; - -function SpDrawXPText(ACanvas: TCanvas; ARect: TRect; Caption: string; - CaptionGlow: TSpGlowDirection; CaptionGlowColor: TColor; CaptionAlignment: TAlignment; - Flags: Cardinal; IL: TCustomImageList; ImageIndex: Integer; Layout: TSpGlyphLayout; - Enabled, PushedCaption, DisabledIconCorrection: Boolean; out ACaptionRect, AGlyphRect: TRect; - RotationAngle: TSpTextRotationAngle = tra0): Integer; overload; -var - GlyphSize, DummyRightGlyphSize: TSize; - DummyRightGlyphRect: TRect; -begin - GlyphSize.cx := 0; - GlyphSize.cy := 0; - DummyRightGlyphSize.cx := 0; - DummyRightGlyphSize.cy := 0; - DummyRightGlyphRect := Rect(0, 0, 0, 0); - - if Assigned(IL) and (ImageIndex > -1) and (ImageIndex < IL.Count) then begin - GlyphSize.cx := IL.Width; - GlyphSize.cy := IL.Height; - end; - - Result := SpCalcXPText(ACanvas, ARect, Caption, CaptionAlignment, Flags, GlyphSize, DummyRightGlyphSize, - Layout, PushedCaption, ACaptionRect, AGlyphRect, DummyRightGlyphRect, RotationAngle); - - SpDrawXPText(ACanvas, Caption, ACaptionRect, Flags and not DT_CALCRECT, CaptionGlow, CaptionGlowColor, RotationAngle); - - if Assigned(IL) and (ImageIndex > -1) and (ImageIndex < IL.Count) then - SpDrawImageList(ACanvas, AGlyphRect, IL, ImageIndex, Enabled, DisabledIconCorrection); -end; - function SpGetTextSize(DC: HDC; S: string; NoPrefix: Boolean): TSize; // Returns the size of the string, if NoPrefix is True, it first removes "&" // characters as necessary. @@ -1214,13 +1281,14 @@ function SpGetControlTextSize(AControl: TControl; AFont: TFont; S: string): TSiz try ACanvas.Control := AControl; ACanvas.Font.Assign(AFont); + // newpy MulDiv(ACanvas.Font.Height, AControl.CurrentPPI, AFont.PixelsPerInch); Result := SpGetTextSize(ACanvas.Handle, S, False); finally ACanvas.Free; end; end; -function SpStripAccelChars(S: string): string; +function SpStripAccelChars(const S: string): string; var I: Integer; begin @@ -1233,7 +1301,7 @@ function SpStripAccelChars(S: string): string; end; end; -function SpStripShortcut(S: string): string; +function SpStripShortcut(const S: string): string; var P: Integer; begin @@ -1243,7 +1311,7 @@ function SpStripShortcut(S: string): string; SetLength(Result, P - 1); end; -function SpStripTrailingPunctuation(S: string): string; +function SpStripTrailingPunctuation(const S: string): string; // Removes any colon (':') or ellipsis ('...') from the end of S and returns // the resulting string var @@ -1263,7 +1331,7 @@ function SpRectToString(R: TRect): string; Result := Format('%d, %d, %d, %d', [R.Left, R.Top, R.Right, R.Bottom]); end; -function SpStringToRect(S: string; out R: TRect): Boolean; +function SpStringToRect(const S: string; out R: TRect): Boolean; var L: TStringList; begin @@ -1301,7 +1369,12 @@ function SpColorToString(const Color: TColor; TextType: TSpTBXColorTextType = ct cttDefault: Result := ColorToString(Color); cttHTML: - Result := SpColorToHTML(Color); + // Use resourcestring only when clNone or clDefault + if Color = clNone then Result := SSpTBXColorNone + else + if Color = clDefault then Result := SSpTBXColorDefault + else + Result := SpColorToHTML(Color); cttIdentAndHTML: begin Result := ColorToString(Color); @@ -1320,6 +1393,19 @@ function SpStringToColor(S: string; out Color: TColor): Boolean; L := Length(S); if L < 2 then Exit; + // Try to convert clNone and clDefault resourcestring + if S = SSpTBXColorNone then begin + Color := clNone; + Result := True; + Exit; + end + else + if S = SSpTBXColorDefault then begin + Color := clDefault; + Result := True; + Exit; + end; + if (S[1] = '#') and (L = 7) then begin // HTML format: #FFFFFF S[1] := '$'; if TryStrToInt(S, C) then begin @@ -1542,38 +1628,38 @@ procedure SpDrawRectangle(ACanvas: TCanvas; ARect: TRect; CornerSize: Integer; end; // External borders - InflateRect(ARect, 1, 1); - if ColorL <> clNone then begin - ACanvas.Pen.Color := ColorL; - ACanvas.PolyLine([ - Point(Left, Bottom - CornerSizeBL), - Point(Left, Top + CornerSizeTL) - ]); - end; - if ColorT <> clNone then begin - ACanvas.Pen.Color := ColorT; - ACanvas.PolyLine([ - Point(Left, Top + CornerSizeTL), - Point(Left + CornerSizeTL, Top), - Point(Right - CornerSizeTR, Top), - Point(Right, Top + CornerSizeTR) - ]); - end; - if ColorR <> clNone then begin - ACanvas.Pen.Color := ColorR; - ACanvas.PolyLine([ - Point(Right , Bottom - CornerSizeBR), - Point(Right, Top - 1 + CornerSizeTR) - ]); - end; - if ColorB <> clNone then begin - ACanvas.Pen.Color := ColorB; - ACanvas.PolyLine([ - Point(Left, Bottom - CornerSizeBL), - Point(Left + CornerSizeBL, Bottom), - Point(Right - CornerSizeBR, Bottom), - Point(Right, Bottom - CornerSizeBR) - ]); + InflateRect(ARect, 1, 1); + if ColorL <> clNone then begin + ACanvas.Pen.Color := ColorL; + ACanvas.PolyLine([ + Point(Left, Bottom - CornerSizeBL), + Point(Left, Top + CornerSizeTL) + ]); + end; + if ColorT <> clNone then begin + ACanvas.Pen.Color := ColorT; + ACanvas.PolyLine([ + Point(Left, Top + CornerSizeTL), + Point(Left + CornerSizeTL, Top), + Point(Right - CornerSizeTR, Top), + Point(Right, Top + CornerSizeTR) + ]); + end; + if ColorR <> clNone then begin + ACanvas.Pen.Color := ColorR; + ACanvas.PolyLine([ + Point(Right , Bottom - CornerSizeBR), + Point(Right, Top - 1 + CornerSizeTR) + ]); + end; + if ColorB <> clNone then begin + ACanvas.Pen.Color := ColorB; + ACanvas.PolyLine([ + Point(Left, Bottom - CornerSizeBL), + Point(Left + CornerSizeBL, Bottom), + Point(Right - CornerSizeBR, Bottom), + Point(Right, Bottom - CornerSizeBR) + ]); end; end; @@ -1656,75 +1742,6 @@ procedure SpPaintTo(WinControl: TWinControl; ACanvas: TCanvas; X, Y: Integer); end; end; -//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM -{ ImageList painting } - -procedure SpDrawIconShadow(ACanvas: TCanvas; const ARect: TRect; - ImageList: TCustomImageList; ImageIndex: Integer); -var - ImageWidth, ImageHeight: Integer; - I, J: Integer; - Src, Dst: ^Cardinal; - S, C, CBRB, CBG: Cardinal; - B1, B2: TBitmap; -begin - ImageWidth := ARect.Right - ARect.Left; - ImageHeight := ARect.Bottom - ARect.Top; - with ImageList do - begin - if Width < ImageWidth then ImageWidth := Width; - if Height < ImageHeight then ImageHeight := Height; - end; - - B1 := TBitmap.Create; - B2 := TBitmap.Create; - try - B1.PixelFormat := pf32bit; - B2.PixelFormat := pf32bit; - B1.SetSize(ImageWidth, ImageHeight); - B2.SetSize(ImageWidth, ImageHeight); - - BitBlt(B1.Canvas.Handle, 0, 0, ImageWidth, ImageHeight, ACanvas.Handle, ARect.Left, ARect.Top, SRCCOPY); - BitBlt(B2.Canvas.Handle, 0, 0, ImageWidth, ImageHeight, ACanvas.Handle, ARect.Left, ARect.Top, SRCCOPY); - ImageList.Draw(B2.Canvas, 0, 0, ImageIndex, True); - - for J := 0 to ImageHeight - 1 do - begin - Src := B2.ScanLine[J]; - Dst := B1.ScanLine[J]; - for I := 0 to ImageWidth - 1 do - begin - S := Src^; - if S <> Dst^ then - begin - CBRB := Dst^ and $00FF00FF; - CBG := Dst^ and $0000FF00; - C := ((S and $00FF0000) shr 16 * 29 + (S and $0000FF00) shr 8 * 150 + - (S and $000000FF) * 76) shr 8; - C := (C div 3) + (255 - 255 div 3); - Dst^ := ((CBRB * C and $FF00FF00) or (CBG * C and $00FF0000)) shr 8; - end; - Inc(Src); - Inc(Dst); - end; - end; - BitBlt(ACanvas.Handle, ARect.Left, ARect.Top, ImageWidth, ImageHeight, B1.Canvas.Handle, 0, 0, SRCCOPY); - finally - B1.Free; - B2.Free; - end; -end; - -procedure SpDrawImageList(ACanvas: TCanvas; const ARect: TRect; ImageList: TCustomImageList; - ImageIndex: Integer; Enabled, DisabledIconCorrection: Boolean); -begin - if Assigned(ImageList) and (ImageIndex > -1) and (ImageIndex < ImageList.Count) then - if not Enabled and DisabledIconCorrection then - SpDrawIconShadow(ACanvas, ARect, ImageList, ImageIndex) - else - ImageList.Draw(ACanvas, ARect.Left, ARect.Top, ImageIndex, Enabled); -end; - //WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM { Gradients } @@ -1942,7 +1959,8 @@ procedure SpDrawFocusRect(ACanvas: TCanvas; const ARect: TRect); end; end; -procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; Pattern: TSpTBXGlyphPattern; PatternColor: TColor); +procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; + Pattern: TSpTBXGlyphPattern; PatternColor: TColor; DPI: Integer); var Size: Integer; PenStyle: Cardinal; @@ -1981,35 +1999,37 @@ procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; Pattern: TSpTBXGlyp --x---- -xxx--- --xx-- ------- --x---- } - - ACanvas.Pen.Width := SpDPIScale(1); + ACanvas.Pen.Width := SpPPIScale(1, DPI); PenStyle := PS_GEOMETRIC or PS_ENDCAP_SQUARE or PS_SOLID or PS_JOIN_MITER; case Pattern of gptClose: begin - Size := SpDPIScale(7); + Size := SpPPIScale(7, DPI); // Round EndCap/Join PenStyle := PS_GEOMETRIC or PS_ENDCAP_ROUND or PS_SOLID or PS_JOIN_ROUND; end; - gptMaximize: Size := SpDPIScale(8); - gptMinimize: Size := SpDPIScale(8); - gptRestore: Size := SpDPIScale(9); + gptMaximize: Size := SpPPIScale(8, DPI); + gptMinimize: Size := SpPPIScale(8, DPI); + gptRestore: Size := SpPPIScale(9, DPI); gptToolbarClose: begin - Size := SpDPIScale(6); + Size := SpPPIScale(6, DPI); // Round EndCap/Join PenStyle := PS_GEOMETRIC or PS_ENDCAP_ROUND or PS_SOLID or PS_JOIN_ROUND; end; - gptChevron: Size := SpDPIScale(8); - gptVerticalChevron: Size := SpDPIScale(8); - gptMenuCheckmark: Size := SpDPIScale(7); - gptCheckmark: Size := SpDPIScale(7); + gptChevron: Size := SpPPIScale(8, DPI); + gptVerticalChevron: Size := SpPPIScale(8, DPI); + gptMenuCheckmark, gptCheckmark: begin + Size := SpPPIScale(7, DPI); + if DPI > 96 then + inc(Size); + end; gptMenuRadiomark: begin - Size := SpDPIScale(7); + Size := SpPPIScale(7, DPI); // Round EndCap/Join PenStyle := PS_GEOMETRIC or PS_ENDCAP_ROUND or PS_SOLID or PS_JOIN_ROUND; ACanvas.Pen.Width := 1; // always 1 pixel end; else - Size := SpDPIScale(8); + Size := SpPPIScale(8, DPI); end; // Create a pen with a Square endcap @@ -2057,8 +2077,8 @@ procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; Pattern: TSpTBXGlyp gptMaximize: begin ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(1)), - Point(R.Right, R.Top + SpDPIScale(1)) + Point(R.Left, R.Top + SpPPIScale(1, DPI)), + Point(R.Right, R.Top + SpPPIScale(1, DPI)) ]); ACanvas.Polyline([ Point(R.Left, R.Top), @@ -2071,36 +2091,36 @@ procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; Pattern: TSpTBXGlyp gptMinimize: begin ACanvas.Polyline([ - Point(R.Left + SpDPIScale(1), R.Bottom - SpDPIScale(2)), - Point(R.Right - SpDPIScale(1), R.Bottom - SpDPIScale(2)), - Point(R.Right - SpDPIScale(1), R.Bottom - SpDPIScale(1)), - Point(R.Left + SpDPIScale(1), R.Bottom - SpDPIScale(1)), - Point(R.Left + SpDPIScale(1), R.Bottom - SpDPIScale(2)) + Point(R.Left + SpPPIScale(1, DPI), R.Bottom - SpPPIScale(2, DPI)), + Point(R.Right - SpPPIScale(1, DPI), R.Bottom - SpPPIScale(2, DPI)), + Point(R.Right - SpPPIScale(1, DPI), R.Bottom - SpPPIScale(1, DPI)), + Point(R.Left + SpPPIScale(1, DPI), R.Bottom - SpPPIScale(1, DPI)), + Point(R.Left + SpPPIScale(1, DPI), R.Bottom - SpPPIScale(2, DPI)) ]); end; gptRestore: begin ACanvas.Polyline([ - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2)), - Point(R.Left + SpDPIScale(2), R.Top), - Point(R.Left + SpDPIScale(7), R.Top), - Point(R.Left + SpDPIScale(7), R.Top + SpDPIScale(5)), - Point(R.Left + SpDPIScale(6), R.Top + SpDPIScale(5)) + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI)), + Point(R.Left + SpPPIScale(2, DPI), R.Top), + Point(R.Left + SpPPIScale(7, DPI), R.Top), + Point(R.Left + SpPPIScale(7, DPI), R.Top + SpPPIScale(5, DPI)), + Point(R.Left + SpPPIScale(6, DPI), R.Top + SpPPIScale(5, DPI)) ]); ACanvas.Polyline([ - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(1)), - Point(R.Left + SpDPIScale(7), R.Top + SpDPIScale(1)) + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(1, DPI)), + Point(R.Left + SpPPIScale(7, DPI), R.Top + SpPPIScale(1, DPI)) ]); ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(3)), - Point(R.Left + SpDPIScale(5), R.Top + SpDPIScale(3)), - Point(R.Left + SpDPIScale(5), R.Bottom), + Point(R.Left, R.Top + SpPPIScale(3, DPI)), + Point(R.Left + SpPPIScale(5, DPI), R.Top + SpPPIScale(3, DPI)), + Point(R.Left + SpPPIScale(5, DPI), R.Bottom), Point(R.Left, R.Bottom), - Point(R.Left, R.Top + SpDPIScale(3)) + Point(R.Left, R.Top + SpPPIScale(3, DPI)) ]); ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(4)), - Point(R.Left + SpDPIScale(5), R.Top + SpDPIScale(4)) + Point(R.Left, R.Top + SpPPIScale(4, DPI)), + Point(R.Left + SpPPIScale(5, DPI), R.Top + SpPPIScale(4, DPI)) ]); end; gptToolbarClose: @@ -2126,78 +2146,78 @@ procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; Pattern: TSpTBXGlyp begin ACanvas.Polyline([ Point(R.Left, R.Top), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2)), - Point(R.Left, R.Top + SpDPIScale(2) * 2) + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI)), + Point(R.Left, R.Top + SpPPIScale(2, DPI) * 2) ]); ACanvas.Polyline([ Point(R.Left + 1, R.Top), - Point(R.Left + SpDPIScale(2) + 1, R.Top + SpDPIScale(2)), - Point(R.Left + 1, R.Top + SpDPIScale(2) * 2) + Point(R.Left + SpPPIScale(2, DPI) + 1, R.Top + SpPPIScale(2, DPI)), + Point(R.Left + 1, R.Top + SpPPIScale(2, DPI) * 2) ]); ACanvas.Polyline([ - Point(R.Left + SpDPIScale(4), R.Top), - Point(R.Left + SpDPIScale(6), R.Top + SpDPIScale(2)), - Point(R.Left + SpDPIScale(4), R.Top + SpDPIScale(2) * 2) + Point(R.Left + SpPPIScale(4, DPI), R.Top), + Point(R.Left + SpPPIScale(6, DPI), R.Top + SpPPIScale(2, DPI)), + Point(R.Left + SpPPIScale(4, DPI), R.Top + SpPPIScale(2, DPI) * 2) ]); ACanvas.Polyline([ - Point(R.Left + SpDPIScale(4) + 1, R.Top), - Point(R.Left + SpDPIScale(6) + 1, R.Top + SpDPIScale(2)), - Point(R.Left + SpDPIScale(4) + 1, R.Top + SpDPIScale(2) * 2) + Point(R.Left + SpPPIScale(4, DPI) + 1, R.Top), + Point(R.Left + SpPPIScale(6, DPI) + 1, R.Top + SpPPIScale(2, DPI)), + Point(R.Left + SpPPIScale(4, DPI) + 1, R.Top + SpPPIScale(2, DPI) * 2) ]); end; gptVerticalChevron: begin ACanvas.Polyline([ Point(R.Left, R.Top), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2)), - Point(R.Left + SpDPIScale(2) * 2, R.Top) + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI)), + Point(R.Left + SpPPIScale(2, DPI) * 2, R.Top) ]); ACanvas.Polyline([ Point(R.Left, R.Top + 1), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2) + 1), - Point(R.Left + SpDPIScale(2) * 2, R.Top + 1) + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI) + 1), + Point(R.Left + SpPPIScale(2, DPI) * 2, R.Top + 1) ]); ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(4)), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(6)), - Point(R.Left + SpDPIScale(2) * 2, R.Top + SpDPIScale(4)) + Point(R.Left, R.Top + SpPPIScale(4, DPI)), + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(6, DPI)), + Point(R.Left + SpPPIScale(2, DPI) * 2, R.Top + SpPPIScale(4, DPI)) ]); ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(4) + 1), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(6) + 1), - Point(R.Left + SpDPIScale(2) * 2, R.Top + SpDPIScale(4) + 1) + Point(R.Left, R.Top + SpPPIScale(4, DPI) + 1), + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(6, DPI) + 1), + Point(R.Left + SpPPIScale(2, DPI) * 2, R.Top + SpPPIScale(4, DPI) + 1) ]); end; gptMenuCheckmark: begin ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(2)), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2) * 2), - Point(R.Right, R.Top) - ]); + Point(R.Left, R.Top + SpPPIScale(2, DPI)), + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI) * 2), + Point(R.Right, R.Top) + ]); ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(2) + 1), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2) * 2 + 1), - Point(R.Right, R.Top + 1) - ]); + Point(R.Left, R.Top + SpPPIScale(2, DPI) + 1), + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI) * 2 + 1), + Point(R.Right, R.Top + 1) + ]); end; gptCheckmark: begin ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(2)), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2) * 2), - Point(R.Right, R.Top) - ]); + Point(R.Left, R.Top + SpPPIScale(2, DPI)), + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI) * 2), + Point(R.Right, R.Top) + ]); ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(2) + 1), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2) * 2 + 1), - Point(R.Right, R.Top + 1) - ]); + Point(R.Left, R.Top + SpPPIScale(2, DPI) + 1), + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI) * 2 + 1), + Point(R.Right, R.Top + 1) + ]); ACanvas.Polyline([ - Point(R.Left, R.Top + SpDPIScale(2) + 2), - Point(R.Left + SpDPIScale(2), R.Top + SpDPIScale(2) * 2 + 2), - Point(R.Right, R.Top + 2) + Point(R.Left, R.Top + SpPPIScale(2, DPI) + 2), + Point(R.Left + SpPPIScale(2, DPI), R.Top + SpPPIScale(2, DPI) * 2 + 2), + Point(R.Right, R.Top + 2) ]); end; gptMenuRadiomark: @@ -2213,7 +2233,7 @@ procedure SpDrawGlyphPattern(ACanvas: TCanvas; ARect: TRect; Pattern: TSpTBXGlyp end; procedure SpDrawXPButton(ACanvas: TCanvas; ARect: TRect; Enabled, Pushed, - HotTrack, Checked, Focused, Defaulted: Boolean); + HotTrack, Checked, Focused, Defaulted: Boolean; DPI: Integer); var C: TColor; State: TSpTBXSkinStatesType; @@ -2238,7 +2258,7 @@ procedure SpDrawXPButton(ACanvas: TCanvas; ARect: TRect; Enabled, Pushed, ACanvas.Brush.Color := C; end; sknWindows, sknDelphiStyle: - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncButton, Enabled, Pushed, HotTrack, Checked, Focused, Defaulted, False); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncButton, Enabled, Pushed, HotTrack, Checked, Focused, Defaulted, False, DPI); sknSkin: begin State := CurrentSkin.GetState(Enabled, Pushed, HotTrack, Checked); @@ -2253,7 +2273,7 @@ procedure SpDrawXPButton(ACanvas: TCanvas; ARect: TRect; Enabled, Pushed, end; procedure SpDrawXPCheckBoxGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Boolean; - State: TCheckBoxState; HotTrack, Pushed: Boolean); + State: TCheckBoxState; HotTrack, Pushed: Boolean; DPI: Integer); var Flags: Cardinal; SknState: TSpTBXSkinStatesType; @@ -2275,18 +2295,18 @@ procedure SpDrawXPCheckBoxGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Boolean DrawFrameControl(ACanvas.Handle, ARect, DFC_BUTTON, Flags); end; sknWindows, sknDelphiStyle: - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncCheckBox, Enabled, Pushed, HotTrack, State = cbChecked, False, False, State = cbGrayed); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncCheckBox, Enabled, Pushed, HotTrack, State = cbChecked, False, False, State = cbGrayed, DPI); sknSkin: begin SknState := CurrentSkin.GetState(Enabled, Pushed, HotTrack, State in [cbChecked, cbGrayed]); CurrentSkin.PaintBackground(ACanvas, ARect, skncCheckBox, SknState, True, True); if State = cbChecked then begin CheckColor := CurrentSkin.GetTextColor(skncCheckBox, SknState); - SpDrawGlyphPattern(ACanvas, ARect, gptCheckmark, CheckColor); + SpDrawGlyphPattern(ACanvas, ARect, gptCheckmark, CheckColor, DPI); end else if State = cbGrayed then begin - InflateRect(ARect, -SpDPIScale(3), -SpDPIScale(3)); + InflateRect(ARect, -SpPPIScale(3, DPI), -SpPPIScale(3, DPI)); CheckColor := CurrentSkin.Options(skncCheckBox, sknsChecked).Borders.Color1; SpFillRect(ACanvas, ARect, CheckColor); end; @@ -2295,7 +2315,7 @@ procedure SpDrawXPCheckBoxGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Boolean end; procedure SpDrawXPRadioButtonGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Boolean; - Checked, HotTrack, Pushed: Boolean); + Checked, HotTrack, Pushed: Boolean; DPI: Integer); var Size, Flags: Integer; SknState: TSpTBXSkinStatesType; @@ -2313,12 +2333,12 @@ procedure SpDrawXPRadioButtonGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Bool DrawFrameControl(ACanvas.Handle, ARect, DFC_BUTTON, Flags); end; sknWindows, sknDelphiStyle: - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncRadioButton, Enabled, Pushed, HotTrack, Checked, False, False, False); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncRadioButton, Enabled, Pushed, HotTrack, Checked, False, False, False, DPI); sknSkin: begin SknState := CurrentSkin.GetState(Enabled, Pushed, HotTrack, Checked); // Keep it simple make the radio 13x13 - ARect := SpCenterRect(ARect, SpDPIScale(13), SpDPIScale(13)); + ARect := SpCenterRect(ARect, SpPPIScale(13, DPI), SpPPIScale(13, DPI)); // Background BeginPath(ACanvas.Handle); @@ -2336,15 +2356,16 @@ procedure SpDrawXPRadioButtonGlyph(ACanvas: TCanvas; ARect: TRect; Enabled: Bool if Checked then begin ACanvas.Brush.Color := CurrentSkin.GetTextColor(skncRadioButton, SknState); ACanvas.Pen.Color := ACanvas.Brush.Color; - Size := SpDpiScale(5); + Size := SpPPIScale(5, DPI); ACanvas.Ellipse(SpCenterRect(ARect, Size, Size)); end; end; end; end; -procedure SpDrawXPEditFrame(ACanvas: TCanvas; ARect: TRect; Enabled, HotTrack: Boolean; - ClipContent: Boolean; AutoAdjust: Boolean); +procedure SpDrawXPEditFrame(ACanvas: TCanvas; ARect: TRect; Enabled, HotTrack, + ClipContent, AutoAdjust: Boolean; DPI: Integer); + // ClipContent: Boolean = False; AutoAdjust: Boolean = False; var BorderR: TRect; State: TSpTBXSkinStatesType; @@ -2367,7 +2388,7 @@ procedure SpDrawXPEditFrame(ACanvas: TCanvas; ARect: TRect; Enabled, HotTrack: B SpDrawRectangle(ACanvas, ARect, 0, clBtnFace, clBtnFace, clBtnFace, clBtnFace); sknWindows, sknDelphiStyle: begin - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncEditFrame, Enabled, False, HotTrack, False, False, False, False); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncEditFrame, Enabled, False, HotTrack, False, False, False, False, DPI); end; sknSkin: begin @@ -2395,8 +2416,9 @@ procedure SpDrawXPEditFrame(ACanvas: TCanvas; ARect: TRect; Enabled, HotTrack: B end; end; -procedure SpDrawXPEditFrame(AWinControl: TWinControl; HotTracking: Boolean; - AutoAdjust, HideFrame: Boolean); +procedure SpDrawXPEditFrame(AWinControl: TWinControl; HotTracking, + AutoAdjust, HideFrame: Boolean; DPI: Integer); + //AutoAdjust: Boolean = False; HideFrame: Boolean = False; var R: TRect; DC: HDC; @@ -2423,7 +2445,7 @@ procedure SpDrawXPEditFrame(AWinControl: TWinControl; HotTracking: Boolean; // PerformEraseBackground(AWinControl, ACanvas.Handle); SpDrawParentBackground(AWinControl, ACanvas.Handle, R); - SpDrawXPEditFrame(ACanvas, R, AWinControl.Enabled, HotTracking, False, AutoAdjust); + SpDrawXPEditFrame(ACanvas, R, AWinControl.Enabled, HotTracking, False, AutoAdjust, DPI); end; finally ACanvas.Handle := 0; @@ -2434,7 +2456,7 @@ procedure SpDrawXPEditFrame(AWinControl: TWinControl; HotTracking: Boolean; end; end; -procedure SpDrawXPGrip(ACanvas: TCanvas; ARect: TRect; LoC, HiC: TColor); +procedure SpDrawXPGrip(ACanvas: TCanvas; ARect: TRect; LoC, HiC: TColor; DPI: Integer); var I, J: Integer; XCellCount, YCellCount: Integer; @@ -2448,28 +2470,28 @@ procedure SpDrawXPGrip(ACanvas: TCanvas; ARect: TRect; LoC, HiC: TColor); // ---- C := ACanvas.Brush.Color; - XCellCount := (ARect.Right - ARect.Left) div SpDPIScale(4); - YCellCount := (ARect.Bottom - ARect.Top) div SpDPIScale(4); + XCellCount := (ARect.Right - ARect.Left) div SpPPIScale(4, DPI); + YCellCount := (ARect.Bottom - ARect.Top) div SpPPIScale(4, DPI); if XCellCount = 0 then XCellCount := 1; if YCellCount = 0 then YCellCount := 1; - + for J := 0 to YCellCount - 1 do for I := 0 to XCellCount - 1 do begin - R.Left := ARect.Left + (I * SpDPIScale(4)) + SpDPIScale(1); - R.Right := R.Left + SpDPIScale(2); - R.Top := ARect.Top + (J * SpDPIScale(4)) + SpDPIScale(1); - R.Bottom := R.Top + SpDPIScale(2); + R.Left := ARect.Left + (I * SpPPIScale(4, DPI)) + SpPPIScale(1, DPI); + R.Right := R.Left + SpPPIScale(2, DPI); + R.Top := ARect.Top + (J * SpPPIScale(4, DPI)) + SpPPIScale(1, DPI); + R.Bottom := R.Top + SpPPIScale(2, DPI); ACanvas.Brush.Color := HiC; ACanvas.FillRect(R); - OffsetRect(R, -SpDPIScale(1), -SpDPIScale(1)); + OffsetRect(R, -SpPPIScale(1, DPI), -SpPPIScale(1, DPI)); ACanvas.Brush.Color := LoC; ACanvas.FillRect(R); end; ACanvas.Brush.Color := C; end; -procedure SpDrawXPHeader(ACanvas: TCanvas; ARect: TRect; HotTrack, Pushed: Boolean); +procedure SpDrawXPHeader(ACanvas: TCanvas; ARect: TRect; HotTrack, Pushed: Boolean; DPI: Integer); var State: TSpTBXSkinStatesType; begin @@ -2480,7 +2502,7 @@ procedure SpDrawXPHeader(ACanvas: TCanvas; ARect: TRect; HotTrack, Pushed: Boole end; sknWindows, sknDelphiStyle: begin - CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncHeader, True, Pushed, HotTrack, False, False, False, False); + CurrentSkin.PaintThemedElementBackground(ACanvas, ARect, skncHeader, True, Pushed, HotTrack, False, False, False, False, DPI); end; sknSkin: begin @@ -2615,6 +2637,11 @@ function SpIsWinVistaOrUp: Boolean; Result := (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 6); end; +function SpIsWin10OrUp: Boolean; +begin + Result := (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 10); +end; + function SpGetDirectories(Path: string; L: TStringList): Boolean; var SearchRec: TSearchRec; @@ -2636,20 +2663,28 @@ function SpGetDirectories(Path: string; L: TStringList): Boolean; end; end; -function SpDPIScale(I: Integer): Integer; +//WMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWM +{ DPI } + +function SpPPIScale(Value, DPI: Integer): Integer; begin - Result := MulDiv(I, Screen.PixelsPerInch, 96); + if DPI <= 0 then DPI := 96; + Result := MulDiv(Value, DPI, 96); end; -procedure SpDPIResizeBitmap(Bitmap: TBitmap; const NewWidth, NewHeight: Integer); +function SpPPIScaleToDPI(PPIScale: TPPIScale): Integer; +begin + Result := PPIScale(96); +end; + +procedure SpDPIResizeBitmap(Bitmap: TBitmap; const NewWidth, NewHeight, DPI: Integer); var B: TBitmap; begin B := TBitmap.Create; try B.SetSize(NewWidth, NewHeight); - - if Screen.PixelsPerInch * 100 / 96 >= 150 then begin // Stretch if >= 150% + if DPI * 100 / 96 >= 150 then begin // Stretch if >= 150% SetStretchBltMode(B.Canvas.Handle, STRETCH_HALFTONE); B.Canvas.StretchDraw(Rect(0, 0, NewWidth, NewHeight), Bitmap); end @@ -2663,20 +2698,62 @@ procedure SpDPIResizeBitmap(Bitmap: TBitmap; const NewWidth, NewHeight: Integer) end; end; -procedure SpDPIScaleImageList(const ImageList: TCustomImageList); +// newpy check with newer version of SpDPIScaleImageList +{ +procedure SpDPIScaleImageList(const ImageList: TCustomImageList; M, D: Integer); +const + ANDbits: array[0..2*16-1] of Byte = ($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, + $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, + $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, + $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF); + XORbits: array[0..2*16-1] of Byte = ($00,$00,$00,$00,$00,$00,$00,$00, + $00,$00,$00,$00,$00,$00,$00,$00, + $00,$00,$00,$00,$00,$00,$00,$00, + $00,$00,$00,$00,$00,$00,$00,$00); +var + I: integer; + Icon: HIcon; + TempIL : TCustomImageList; +begin + if M = D then + Exit; + TempIL := TCustomImageList.CreateSize(MulDiv(ImageList.Width, M, D), MulDiv(ImageList.Height, M, D)); + try + TempIL.ColorDepth := cd32Bit; + TempIL.DrawingStyle := ImageList.DrawingStyle; + TempIL.BkColor := ImageList.BkColor; + TempIL.BlendColor := ImageList.BlendColor; + for I := 0 to ImageList.Count-1 do + begin + Icon := ImageList_GetIcon(ImageList.Handle, I, LR_DEFAULTCOLOR); + if Icon = 0 then + begin + Icon := CreateIcon(hInstance,16,16,1,1,@ANDbits,@XORbits); + end; + ImageList_AddIcon(TempIL.Handle, Icon); + DestroyIcon(Icon); + end; + ImageList.Assign(TempIL); + finally + TempIL.Free; + end; +end; + +} +procedure SpDPIScaleImageList(const ImageList: TCustomImageList; M, D: Integer); var I: integer; Bimage, Bmask: TBitmap; TempIL : TImageList; begin - if Screen.PixelsPerInch = 96 then Exit; + if M = D then Exit; TempIL := TImageList.Create(nil); try // Set size to match DPI (like 250% of 16px = 40px) TempIL.Assign(ImageList); ImageList.Clear; - ImageList.SetSize(MulDiv(ImageList.Width, Screen.PixelsPerInch, 96), MulDiv(ImageList.Height, Screen.PixelsPerInch, 96)); + ImageList.SetSize(MulDiv(ImageList.Width, M, D), MulDiv(ImageList.Height, M, D)); // Add images back to original ImageList for I := 0 to -1 + TempIL.Count do begin @@ -2687,13 +2764,13 @@ procedure SpDPIScaleImageList(const ImageList: TCustomImageList); Bimage.SetSize(TempIL.Width, TempIL.Height); Bimage.Canvas.FillRect(Bimage.Canvas.ClipRect); ImageList_DrawEx(TempIL.Handle, I, Bimage.Canvas.Handle, 0, 0, Bimage.Width, Bimage.Height, CLR_NONE, CLR_NONE, ILD_NORMAL); - SpDPIResizeBitmap(Bimage, ImageList.Width, ImageList.Height); // Resize + SpDPIResizeBitmap(Bimage, ImageList.Width, ImageList.Height, M); // Resize // Get the mask bitmap Bmask.SetSize(TempIL.Width, TempIL.Height); Bmask.Canvas.FillRect(Bmask.Canvas.ClipRect); ImageList_DrawEx(TempIL.Handle, I, Bmask.Canvas.Handle, 0, 0, Bmask.Width, Bmask.Height, CLR_NONE, CLR_NONE, ILD_MASK); - SpDPIResizeBitmap(Bmask, ImageList.Width, ImageList.Height); // Resize + SpDPIResizeBitmap(Bmask, ImageList.Width, ImageList.Height, M); // Resize // Add the bitmaps ImageList.Add(Bimage, Bmask); @@ -2768,7 +2845,7 @@ procedure TSpTBXSkinOptionEntry.Reset; FColor4 := clNone; end; -procedure TSpTBXSkinOptionEntry.ReadFromString(S: string); +procedure TSpTBXSkinOptionEntry.ReadFromString(const S: string); var L: TStringList; begin @@ -2838,14 +2915,16 @@ procedure TSpTBXSkinOptionCategory.Reset; FTextColor := clNone; end; -procedure TSpTBXSkinOptionCategory.SaveToIni(MemIni: TMemIniFile; Section, Ident: string); +procedure TSpTBXSkinOptionCategory.SaveToIni(MemIni: TMemIniFile; const + Section, Ident: string); begin MemIni.WriteString(Section, Ident + '.Body', Body.WriteToString); MemIni.WriteString(Section, Ident + '.Borders', Borders.WriteToString); MemIni.WriteString(Section, Ident + '.TextColor', SpColorToString(TextColor)); end; -procedure TSpTBXSkinOptionCategory.LoadFromIni(MemIni: TMemIniFile; Section, Ident: string); +procedure TSpTBXSkinOptionCategory.LoadFromIni(MemIni: TMemIniFile; const + Section: string; Ident: string); begin Reset; if Ident = '' then Ident := SSpTBXSkinStatesString[sknsNormal]; @@ -2959,7 +3038,7 @@ function TSpTBXSkinOptions.Options(Component: TSpTBXSkinComponentsType): TSpTBXS Result := FOptions[Component, sknsNormal]; end; -procedure TSpTBXSkinOptions.SaveToFile(Filename: string); +procedure TSpTBXSkinOptions.SaveToFile(const Filename: string); var MemIni: TMemIniFile; begin @@ -3007,7 +3086,7 @@ procedure TSpTBXSkinOptions.SaveToStrings(L: TStrings); end; end; -procedure TSpTBXSkinOptions.LoadFromFile(Filename: string); +procedure TSpTBXSkinOptions.LoadFromFile(const Filename: string); var L: TStringList; begin @@ -3087,61 +3166,42 @@ function TSpTBXSkinOptions.GetFloatingWindowBorderSize: Integer; if SkinManager.GetSkinType = sknSkin then Result := FFloatingWindowBorderSize else - Result := SpDPIScale(4); + Result := 4; end; procedure TSpTBXSkinOptions.SetFloatingWindowBorderSize(const Value: Integer); begin FFloatingWindowBorderSize := Value; if FFloatingWindowBorderSize < 0 then FFloatingWindowBorderSize := 0; - if FFloatingWindowBorderSize > SpDPIScale(4) then FFloatingWindowBorderSize := SpDPIScale(4); -end; - -procedure TSpTBXSkinOptions.GetDropDownArrowSize(out DropDownArrowSize, - DropDownArrowMargin, SplitBtnArrowSize: Integer); -begin - DropDownArrowSize := SpDPIScale(8); // TB2Item.tbDropdownArrowWidth - DropDownArrowMargin := SpDPIScale(3); // TB2Item.tbDropdownArrowMargin - - SplitBtnArrowSize := SpDPIScale(12); // TB2Item.tbDropdownComboArrowWidth + 1 - if SkinManager.GetSkinType in [sknWindows, sknDelphiStyle] then - SplitBtnArrowSize := SpDPIScale(12+1); + if FFloatingWindowBorderSize > 4 then FFloatingWindowBorderSize := 4; end; procedure TSpTBXSkinOptions.GetMenuItemMargins(ACanvas: TCanvas; ImgSize: Integer; - out MarginsInfo: TSpTBXMenuItemMarginsInfo); + out MarginsInfo: TSpTBXMenuItemMarginsInfo; DPI: Integer); var TextMetric: TTextMetric; H, M2: Integer; SkinType: TSpTBXSkinType; begin if ImgSize = 0 then - ImgSize := SpDPIScale(16); + ImgSize := SpPPIScale(16, DPI); FillChar(MarginsInfo, SizeOf(MarginsInfo), 0); SkinType := SkinManager.GetSkinType; - if ((SkinType = sknWindows) and SpIsWinVistaOrUp) or (SkinType = sknDelphiStyle) then begin - // Vista-like spacing - MarginsInfo.Margins := Rect(SpDPIScale(1), SpDPIScale(3), SpDPIScale(1), SpDPIScale(3)); // MID_MENUITEM - MarginsInfo.ImageTextSpace := SpDPIScale(5 + 1); // TMI_MENU_IMGTEXTSPACE - MarginsInfo.LeftCaptionMargin := SpDPIScale(3); // TMI_MENU_LCAPTIONMARGIN - MarginsInfo.RightCaptionMargin := SpDPIScale(3); // TMI_MENU_RCAPTIONMARGIN + if ((SkinType = sknWindows) and not SpIsWinVistaOrUp) or (SkinType = sknNone) then begin + MarginsInfo.Margins := Rect(0, SpPPIScale(2, DPI), 0, SpPPIScale(2, DPI)); // MID_MENUITEM + MarginsInfo.ImageTextSpace := SpPPIScale(1, DPI); // TMI_MENU_IMGTEXTSPACE + MarginsInfo.LeftCaptionMargin := SpPPIScale(2, DPI); // TMI_MENU_LCAPTIONMARGIN + MarginsInfo.RightCaptionMargin := SpPPIScale(2, DPI); // TMI_MENU_RCAPTIONMARGIN end - else - if (SkinType = sknSkin) then begin - // Office-like spacing - MarginsInfo.Margins := Rect(SpDPIScale(1), SpDPIScale(3), SpDPIScale(1), SpDPIScale(3)); // MID_MENUITEM - MarginsInfo.ImageTextSpace := SpDPIScale(5); // TMI_MENU_IMGTEXTSPACE - MarginsInfo.LeftCaptionMargin := SpDPIScale(3); // TMI_MENU_LCAPTIONMARGIN - MarginsInfo.RightCaptionMargin := SpDPIScale(3); // TMI_MENU_RCAPTIONMARGIN - end - else begin - MarginsInfo.Margins := Rect(0, SpDPIScale(2), 0, SpDPIScale(2)); // MID_MENUITEM - MarginsInfo.ImageTextSpace := SpDPIScale(1); // TMI_MENU_IMGTEXTSPACE - MarginsInfo.LeftCaptionMargin := SpDPIScale(2); // TMI_MENU_LCAPTIONMARGIN - MarginsInfo.RightCaptionMargin := SpDPIScale(2); // TMI_MENU_RCAPTIONMARGIN - end; + else begin + // Vista-like spacing + MarginsInfo.Margins := Rect(SpPPIScale(1, DPI), SpPPIScale(3, DPI), SpPPIScale(1, DPI), SpPPIScale(3, DPI)); // MID_MENUITEM + MarginsInfo.ImageTextSpace := SpPPIScale(5 + 1, DPI); // TMI_MENU_IMGTEXTSPACE + MarginsInfo.LeftCaptionMargin := SpPPIScale(3, DPI); // TMI_MENU_LCAPTIONMARGIN + MarginsInfo.RightCaptionMargin := SpPPIScale(3, DPI); // TMI_MENU_RCAPTIONMARGIN + end; GetTextMetrics(ACanvas.Handle, TextMetric); M2 := MarginsInfo.Margins.Top + MarginsInfo.Margins.Bottom; @@ -3601,10 +3661,10 @@ function TSpTBXSkinOptions.GetThemedElementDetails(Component: TSpTBXSkinComponen Result := GetThemedElementDetails(Component, Enabled, Pushed, HotTrack, Checked, False, False, False, Details); end; -function TSpTBXSkinOptions.GetThemedElementSize(ACanvas: TCanvas; Details: TThemedElementDetails): TSize; +function TSpTBXSkinOptions.GetThemedElementSize(ACanvas: TCanvas; Details: TThemedElementDetails; DPI: Integer): TSize; begin {$IF CompilerVersion >= 23} // for Delphi XE2 and up - SpTBXThemeServices.GetElementSize(ACanvas.Handle, Details, esActual, Result); + SpTBXThemeServices.GetElementSize(ACanvas.Handle, Details, esActual, Result{$IF CompilerVersion >= 33}, DPI{$IFEND}); // DPI param introduced on 10.3 Rio {$ELSE} GetThemePartSize(SpTBXThemeServices.Theme[Details.Element], ACanvas.Handle, Details.Part, Details.State, nil, TS_TRUE, Result); {$IFEND} @@ -3656,13 +3716,13 @@ procedure TSpTBXSkinOptions.PaintBackground(ACanvas: TCanvas; ARect: TRect; end; procedure TSpTBXSkinOptions.PaintThemedElementBackground(ACanvas: TCanvas; - ARect: TRect; Details: TThemedElementDetails); + ARect: TRect; Details: TThemedElementDetails; DPI: Integer); var SaveIndex: Integer; begin SaveIndex := SaveDC(ACanvas.Handle); // XE2 Styles changes the font try - SpTBXThemeServices.DrawElement(ACanvas.Handle, Details, ARect, nil); + SpTBXThemeServices.DrawElement(ACanvas.Handle, Details, ARect, nil{$IF CompilerVersion >= 33}, DPI{$IFEND}); // DPI param introduced on 10.3 Rio DPI); finally RestoreDC(ACanvas.Handle, SaveIndex); end; @@ -3670,26 +3730,26 @@ procedure TSpTBXSkinOptions.PaintThemedElementBackground(ACanvas: TCanvas; procedure TSpTBXSkinOptions.PaintThemedElementBackground(ACanvas: TCanvas; ARect: TRect; Component: TSpTBXSkinComponentsType; Enabled, Pushed, HotTrack, - Checked, Focused, Defaulted, Grayed: Boolean); + Checked, Focused, Defaulted, Grayed: Boolean; DPI: Integer); var Details: TThemedElementDetails; begin if GetThemedElementDetails(Component, Enabled, Pushed, HotTrack, Checked, Focused, Defaulted, Grayed, Details) then - PaintThemedElementBackground(ACanvas, ARect, Details); + PaintThemedElementBackground(ACanvas, ARect, Details, DPI); end; procedure TSpTBXSkinOptions.PaintThemedElementBackground(ACanvas: TCanvas; ARect: TRect; Component: TSpTBXSkinComponentsType; - State: TSpTBXSkinStatesType); + State: TSpTBXSkinStatesType; DPI: Integer); var Details: TThemedElementDetails; begin if GetThemedElementDetails(Component, State, Details) then - PaintThemedElementBackground(ACanvas, ARect, Details); + PaintThemedElementBackground(ACanvas, ARect, Details, DPI); end; procedure TSpTBXSkinOptions.PaintMenuCheckMark(ACanvas: TCanvas; ARect: TRect; - Checked, Grayed: Boolean; State: TSpTBXSkinStatesType); + Checked, Grayed: Boolean; State: TSpTBXSkinStatesType; DPI: Integer); var CheckColor: TColor; VistaCheckSize: TSize; @@ -3698,8 +3758,7 @@ procedure TSpTBXSkinOptions.PaintMenuCheckMark(ACanvas: TCanvas; ARect: TRect; begin SkinType := SkinManager.GetSkinType; // VCL Styles does not DPI scale menu checkmarks, Windows does - if ((SkinType = sknWindows) and SpIsWinVistaOrUp) or - ((SkinType = sknDelphiStyle) and (Screen.PixelsPerInch = 96)) then + if ((SkinType = sknWindows) and SpIsWinVistaOrUp) or (SkinType = sknDelphiStyle) then begin // [Old-Themes] {$IF CompilerVersion >= 23} //for Delphi XE2 and up @@ -3711,21 +3770,21 @@ procedure TSpTBXSkinOptions.PaintMenuCheckMark(ACanvas: TCanvas; ARect: TRect; if State = sknsDisabled then Details.State := MC_CHECKMARKDISABLED else Details.State := MC_CHECKMARKNORMAL; {$IFEND} - VistaCheckSize := GetThemedElementSize(ACanvas, Details); + VistaCheckSize := GetThemedElementSize(ACanvas, Details, DPI); // Returns a scaled value ARect := SpCenterRect(ARect, VistaCheckSize.cx, VistaCheckSize.cy); - PaintThemedElementBackground(ACanvas, ARect, Details); + PaintThemedElementBackground(ACanvas, ARect, Details, DPI); end else begin if SkinType = sknNone then CheckColor := clMenuText // On sknNone it's clMenuText even when disabled else CheckColor := GetTextColor(skncMenuItem, State); - SpDrawGlyphPattern(ACanvas, ARect, gptMenuCheckmark, CheckColor); + SpDrawGlyphPattern(ACanvas, ARect, gptMenuCheckmark, CheckColor, DPI); end; end; procedure TSpTBXSkinOptions.PaintMenuRadioMark(ACanvas: TCanvas; ARect: TRect; - Checked: Boolean; State: TSpTBXSkinStatesType); + Checked: Boolean; State: TSpTBXSkinStatesType; DPI: Integer); var CheckColor: TColor; VistaCheckSize: TSize; @@ -3747,16 +3806,16 @@ procedure TSpTBXSkinOptions.PaintMenuRadioMark(ACanvas: TCanvas; ARect: TRect; if State = sknsDisabled then Details.State := MC_BULLETDISABLED else Details.State := MC_BULLETNORMAL; {$IFEND} - VistaCheckSize := GetThemedElementSize(ACanvas, Details); + VistaCheckSize := GetThemedElementSize(ACanvas, Details, DPI); // Returns a scaled value ARect := SpCenterRect(ARect, VistaCheckSize.cx, VistaCheckSize.cy); - PaintThemedElementBackground(ACanvas, ARect, Details); + PaintThemedElementBackground(ACanvas, ARect, Details, DPI); end else begin if SkinType = sknNone then CheckColor := clMenuText // On sknNone it's clMenuText even when disabled else CheckColor := GetTextColor(skncMenuItem, State); - SpDrawGlyphPattern(ACanvas, ARect, gptMenuRadiomark, CheckColor); + SpDrawGlyphPattern(ACanvas, ARect, gptMenuRadiomark, CheckColor, DPI); end; end; @@ -3822,8 +3881,8 @@ destructor TSpTBXSkinManager.Destroy; inherited; end; -procedure TSpTBXSkinManager.AddSkin(SkinName: string; - SkinClass: TSpTBXSkinOptionsClass); +procedure TSpTBXSkinManager.AddSkin(const SkinName: string; SkinClass: + TSpTBXSkinOptionsClass); var K: TSpTBXSkinsListEntry; begin @@ -3861,7 +3920,7 @@ procedure TSpTBXSkinManager.AddSkin(SkinOptions: TStrings); end; end; -function TSpTBXSkinManager.AddSkinFromFile(Filename: string): string; +function TSpTBXSkinManager.AddSkinFromFile(const Filename: string): string; var L: TStringList; begin @@ -3919,12 +3978,12 @@ procedure TSpTBXSkinManager.BroadcastSkinNotification; Broadcast; end; -procedure TSpTBXSkinManager.LoadFromFile(Filename: string); +procedure TSpTBXSkinManager.LoadFromFile(const Filename: string); begin FCurrentSkin.LoadFromFile(Filename); end; -procedure TSpTBXSkinManager.SaveToFile(Filename: string); +procedure TSpTBXSkinManager.SaveToFile(const Filename: string); begin FCurrentSkin.SaveToFile(Filename); end; @@ -3998,7 +4057,7 @@ function TSpTBXSkinManager.IsXPThemesEnabled: Boolean; {$IFEND} end; -procedure TSpTBXSkinManager.SetSkin(SkinName: string); +procedure TSpTBXSkinManager.SetSkin(const SkinName: string); var K: TSpTBXSkinsListEntry; begin @@ -4026,7 +4085,7 @@ procedure TSpTBXSkinManager.SetSkin(SkinName: string); // [Old-Themes] {$IF CompilerVersion >= 23} // for Delphi XE2 and up -procedure TSpTBXSkinManager.SetDelphiStyle(StyleName: string); +procedure TSpTBXSkinManager.SetDelphiStyle(const StyleName: string); begin if not SameText(StyleName, TStyleManager.ActiveStyle.Name) then begin if not IsDefaultSkin then @@ -4036,7 +4095,7 @@ procedure TSpTBXSkinManager.SetDelphiStyle(StyleName: string); end; end; -function TSpTBXSkinManager.IsValidDelphiStyle(StyleName: string): Boolean; +function TSpTBXSkinManager.IsValidDelphiStyle(const StyleName: string): Boolean; var S: string; begin diff --git a/Source/SpTBXTabs.pas b/Source/SpTBXTabs.pas index bb1ad3e..e981b04 100644 --- a/Source/SpTBXTabs.pas +++ b/Source/SpTBXTabs.pas @@ -1,7 +1,7 @@ unit SpTBXTabs; {============================================================================== -Version 2.5.4 +Version 2.5.7 The contents of this file are subject to the SpTBXLib License; you may not use or distribute this file except in compliance with the @@ -47,7 +47,7 @@ interface {$BOOLEVAL OFF} // Unit depends on short-circuit boolean evaluation {$IF CompilerVersion >= 25} // for Delphi XE4 and up - {$LEGACYIFEND ON} // XE4 and up requires $IF to be terminated with $ENDIF instead of $IFEND + {$LEGACYIFEND ON} // requires $IF to be terminated with $ENDIF instead of $IFEND {$IFEND} uses @@ -60,12 +60,6 @@ interface WM_INVALIDATETABBACKGROUND = WM_USER + 7777; type - TSpTBXTabEdge = ( - tedNone, // No edge needed - tedLeft, // Left edge of the tab - tedRight // Right edge of the tab - ); - TSpTBXTabPosition = ( ttpTop, // Top aligned tabset ttpBottom // Bottom aligned tabset @@ -129,6 +123,9 @@ TSpTBXTabItem = class(TSpTBXCustomItem) // property GroupIndex; property HelpContext; property ImageIndex; + {$IF CompilerVersion >= 34} // for Delphi Sydney and up + property ImageName; + {$IFEND} property Images; property InheritOptions; property MaskOptions; @@ -182,7 +179,7 @@ TSpTBXTabItemViewer = class(TSpTBXItemViewer) procedure DrawBottomBorder(ACanvas: TCanvas; ARect: TRect); procedure DrawTab(ACanvas: TCanvas; ARect: TRect; AEnabled, AChecked, AHoverItem: Boolean; Position: TSpTBXTabPosition; - ASeparator: Boolean = False; AEdge: TSpTBXTabEdge = tedNone); virtual; + ASeparator: Boolean = False); virtual; procedure DrawItemRightImage(ACanvas: TCanvas; ARect: TRect; ItemInfo: TSpTBXMenuItemInfo); override; function GetRightImageSize: TSize; override; function GetRightImageRect: TRect; @@ -265,9 +262,9 @@ TSpTBXTabToolbar = class(TSpTBXToolbar) property TabCloseMiddleClick: Boolean read FTabCloseMiddleClick write FTabCloseMiddleClick default False; property TabBackgroundBorders: Boolean read FTabBackgroundBorders write SetTabBackgroundBorders; property TabAutofit: Boolean read FTabAutofit write SetTabAutofit default False; - property TabAutofitMaxSize: Integer read FTabAutofitMaxSize write SetTabAutofitMaxSize default 200; + property TabAutofitMaxSize: Integer read FTabAutofitMaxSize write SetTabAutofitMaxSize default 200; //UnScaled property TabColor: TColor read FTabColor write SetTabColor default clBtnFace; - property TabMaxSize: Integer read FTabMaxSize write SetTabMaxSize default -1; + property TabMaxSize: Integer read FTabMaxSize write SetTabMaxSize default -1; //UnScaled property TabPosition: TSpTBXTabPosition read FTabPosition write SetTabPosition default ttpTop; property TabDragReorder: Boolean read FTabDragReorder write FTabDragReorder default False; end; @@ -395,8 +392,8 @@ TSpTBXCustomTabSet = class(TSpTBXCompoundItemsControl) public constructor Create(AOwner: TComponent); override; destructor Destroy; override; - function Add(ACaption: string): TSpTBXTabItem; - function Insert(NewIndex: Integer; ACaption: string): TSpTBXTabItem; + function Add(const ACaption: string): TSpTBXTabItem; + function Insert(NewIndex: Integer; const ACaption: string): TSpTBXTabItem; function GetTabSetHeight: Integer; procedure MakeVisible(ATab: TSpTBXTabItem); procedure ScrollLeft; @@ -554,7 +551,7 @@ TSpTBXTabControl = class(TSpTBXCustomTabControl) end; function SpGetNextTabItemViewer(View: TTBView; IV: TTBItemViewer; GoForward: Boolean; SearchType: TSpTBXSearchItemViewerType): TTBItemViewer; -procedure SpDrawXPTab(ACanvas: TCanvas; ARect: TRect; Enabled, Checked, HotTrack, Focused: Boolean; Position: TSpTBXTabPosition; Edge: TSpTBXTabEdge = tedNone); +procedure SpDrawXPTab(ACanvas: TCanvas; ARect: TRect; Enabled, Checked, HotTrack, Focused: Boolean; Position: TSpTBXTabPosition; DPI: Integer); procedure SpDrawXPTabControlBackground(ACanvas: TCanvas; ARect: TRect; AColor: TColor; BottomTabs: Boolean); implementation @@ -564,7 +561,7 @@ implementation {$IF CompilerVersion >= 25} // for Delphi XE4 and up System.UITypes, {$IFEND} - Types; + TB2Common, Types; type TTBItemViewerAccess = class(TTBItemViewer); @@ -606,7 +603,7 @@ function SpGetNextTabItemViewer(View: TTBView; IV: TTBItemViewer; GoForward: Boo procedure SpDrawXPTab(ACanvas: TCanvas; ARect: TRect; Enabled, Checked, HotTrack, Focused: Boolean; Position: TSpTBXTabPosition; - Edge: TSpTBXTabEdge = tedNone); + DPI: Integer); var B: TBitmap; R, FlippedR: TRect; @@ -614,6 +611,7 @@ procedure SpDrawXPTab(ACanvas: TCanvas; ARect: TRect; DrawState: TThemedTab; Details: TThemedElementDetails; SkinType: TSpTBXSkinType; + NeedToFlip: Boolean; begin SkinType := SkinManager.GetSkinType; if (SkinType = sknNone) and not Checked then @@ -632,10 +630,10 @@ procedure SpDrawXPTab(ACanvas: TCanvas; ARect: TRect; end; B.Canvas.FillRect(R); + NeedToFlip := False; case SkinType of sknNone: if Checked then begin - Position := ttpTop; // Don't need to flip B.Canvas.Brush.Color := ACanvas.Brush.Color; B.Canvas.FillRect(R); ExtCtrls.Frame3D(B.Canvas, R, clWindow, clWindowFrame, 1); @@ -644,12 +642,12 @@ procedure SpDrawXPTab(ACanvas: TCanvas; ARect: TRect; end; sknWindows, sknDelphiStyle: begin - case Edge of - tedLeft: DrawState := ttTabItemLeftEdgeNormal; - tedRight: DrawState := ttTabItemRightEdgeNormal; + if SkinType = sknWindows then NeedToFlip := True; + + if Position = ttpBottom then + DrawState := ttTabItemBothEdgeNormal else DrawState := ttTabItemNormal; - end; if not Enabled then DrawState := TThemedTab(Ord(DrawState) + 3) else @@ -658,17 +656,18 @@ procedure SpDrawXPTab(ACanvas: TCanvas; ARect: TRect; if HotTrack then DrawState := TThemedTab(Ord(DrawState) + 1); Details := SpTBXThemeServices.GetElementDetails(DrawState); - CurrentSkin.PaintThemedElementBackground(B.Canvas, R, Details); + CurrentSkin.PaintThemedElementBackground(B.Canvas, R, Details, DPI); end; sknSkin: begin + NeedToFlip := True; State := CurrentSkin.GetState(Enabled, False, HotTrack, Checked); CurrentSkin.PaintBackground(B.Canvas, R, skncTab, State, True, True); end; end; // Flip top to bottom - if Position = ttpBottom then begin + if (Position = ttpBottom) and NeedToFlip then begin // Unclear why extra "-1" is needed here. FlippedR := R; FlippedR.Top := R.Bottom - 1; @@ -755,7 +754,7 @@ constructor TSpTBXTabItem.Create(AOwner: TComponent); DisplayMode := nbdmImageAndText; GroupIndex := C_SpTBXTabGroupIndex; Wrapping := twEndEllipsis; - Margins := SpDPIScale(4); + Margins := 4; end; procedure TSpTBXTabItem.Click; @@ -798,17 +797,12 @@ procedure TSpTBXTabItem.TabClose; NextTab := GetNextTab(False, sivtInmediateSkipNonVisible); end; - T.BeginUpdate; - try - Visible := False; - DoTabClose; - if CloseAndFree then - Free; // Removes the item from the parent, sends tbicDeleting notification and frees the item - if Assigned(NextTab) then - NextTab.Click; // Sends tbicInvalidate notification, which is handled by TSpTBXCustomTabSet.ItemNotification - finally - T.EndUpdate; - end; + Visible := False; + DoTabClose; + if CloseAndFree then + Free; // Removes the item from the parent, sends tbicDeleting notification and frees the item + if Assigned(NextTab) then + NextTab.Click; // Sends tbicInvalidate notification, which is handled by TSpTBXCustomTabSet.ItemNotification end; end; end; @@ -939,12 +933,12 @@ procedure TSpTBXTabItemViewer.CalcSize(const Canvas: TCanvas; var AWidth, TabMaxSize := TSpTBXTabToolbar(View.Window).TabMaxSize; if TabMaxSize > 0 then if IsRotated then begin - if AHeight > TabMaxSize then - AHeight := TabMaxSize; + if AHeight > PPIScale(TabMaxSize) then + AHeight := PPIScale(TabMaxSize); end else begin - if AWidth > TabMaxSize then - AWidth := TabMaxSize; + if AWidth > PPIScale(TabMaxSize) then + AWidth := PPIScale(TabMaxSize); end; end; end; @@ -955,8 +949,8 @@ function TSpTBXTabItemViewer.CorrectTabRect(ARect: TRect): TRect; Result := ARect; if not Item.Checked then case TabPosition of - ttpTop: OffsetRect(Result, 0, SpDPIScale(2)); - ttpBottom: OffsetRect(Result, 0, -SpDPIScale(2)); + ttpTop: OffsetRect(Result, 0, PPIScale(2)); + ttpBottom: OffsetRect(Result, 0, -PPIScale(2)); end; end; @@ -978,8 +972,8 @@ procedure TSpTBXTabItemViewer.DoDrawButton(ACanvas: TCanvas; ARect: TRect; // Match the bottom of the Tab with the bottom of the TabSet case Position of - ttpTop: ARect.Bottom := ARect.Bottom + SpDPIScale(1); - ttpBottom: ARect.Top := ARect.Top - SpDPIScale(1); + ttpTop: ARect.Bottom := ARect.Bottom + PPIScale(1); + ttpBottom: ARect.Top := ARect.Top - PPIScale(1); end; R := ARect; @@ -990,8 +984,8 @@ procedure TSpTBXTabItemViewer.DoDrawButton(ACanvas: TCanvas; ARect: TRect; not CurrentSkin.Options(skncTab, sknsNormal).Borders.IsEmpty then begin case Position of - ttpTop: Inc(R.Bottom, SpDPIScale(5)); - ttpBottom: Dec(R.Top, SpDPIScale(5)); + ttpTop: Inc(R.Bottom, PPIScale(5)); + ttpBottom: Dec(R.Top, PPIScale(5)); end; DrawTab(ACanvas, R, Item.Enabled, Item.Checked, IsHoverItem, Position); end @@ -1017,16 +1011,16 @@ procedure TSpTBXTabItemViewer.DoDrawButton(ACanvas: TCanvas; ARect: TRect; // The left border of the Tab will be painted by the Left tab if // its the first tab if Assigned(LeftT) or (Item.IsFirstVisible) then - R.Left := R.Left - SpDPIScale(2); + R.Left := R.Left - PPIScale(2); // The right border of the Tab will be painted by the Right tab if Assigned(RightT) then - R.Right := R.Right + SpDPIScale(2); + R.Right := R.Right + PPIScale(2); end else begin // Non checked tabs should be smaller case Position of - ttpTop: Inc(R.Top, SpDPIScale(2)); - ttpBottom: Dec(R.Bottom, SpDPIScale(2)); + ttpTop: Inc(R.Top, PPIScale(2)); + ttpBottom: Dec(R.Bottom, PPIScale(2)); end; end; @@ -1038,15 +1032,15 @@ procedure TSpTBXTabItemViewer.DoDrawButton(ACanvas: TCanvas; ARect: TRect; R := ARect; // Draw the left border if Assigned(LeftT) and LeftT.Item.Checked then begin - R.Right := R.Left + SpDPIScale(2); - R.Left := R.Right - SpDPIScale(10); + R.Right := R.Left + PPIScale(2); + R.Left := R.Right - PPIScale(10); DrawTab(ACanvas, R, LeftT.Item.Enabled, True, IsHoverItem, Position); end else // Draw the right border if Assigned(RightT) and RightT.Item.Checked then begin - R.Left := R.Right - SpDPIScale(2); - R.Right := R.Left + SpDPIScale(10); + R.Left := R.Right - PPIScale(2); + R.Right := R.Left + PPIScale(10); DrawTab(ACanvas, R, RightT.Item.Enabled, True, IsHoverItem, Position); end; end; @@ -1085,45 +1079,44 @@ procedure TSpTBXTabItemViewer.DoDrawTabCloseButton(ACanvas: TCanvas; procedure TSpTBXTabItemViewer.DrawBottomBorder(ACanvas: TCanvas; ARect: TRect); var CR, R: TRect; - Edge: TSpTBXTabEdge; Position: TSpTBXTabPosition; B: TBitmap; + DockedBorderSize: Integer; begin if not IsOnTabToolbar then Exit; + // safe cast given IsOnTabToolbar + DockedBorderSize := TSpTBXTabToolbar(View.Window).DockedBorderSize; Position := TabPosition; - Edge := tedNone; CR := ARect; case Position of ttpTop: - Inc(CR.Bottom, SpDPIScale(2)); + Inc(CR.Bottom, PPIScale(2)); ttpBottom: - Dec(CR.Top, SpDPIScale(2)); + Dec(CR.Top, PPIScale(2)); end; if SkinManager.GetSkinType in [sknWindows, sknDelphiStyle] then begin - if Item.IsFirstVisible then // Is first IV? - Edge := tedLeft; // Grow the left border if it's the first visible or there is a left tab if Item.IsFirstVisible or Assigned(SpGetNextTabItemViewer(View, Self, False, sivtInmediateSkipNonVisible)) then - CR.Left := CR.Left - CDefaultToolbarBorderSize; + CR.Left := CR.Left - DockedBorderSize; // Grow the right border if there is a right tab if Assigned(SpGetNextTabItemViewer(View, Self, True, sivtInmediateSkipNonVisible)) then - CR.Right := CR.Right + CDefaultToolbarBorderSize; + CR.Right := CR.Right + DockedBorderSize; end; B := TBitmap.Create; try - B.SetSize(CR.Right - CR.Left, CR.Bottom - CR.Top + SpDPIScale(4)); // Larger than CR + B.SetSize(CR.Right - CR.Left, CR.Bottom - CR.Top + PPIScale(4)); // Larger than CR R := Rect(0, 0, B.Width, B.Height); - DrawTab(B.Canvas, R, True, True, False, Position, False, Edge); + DrawTab(B.Canvas, R, True, True, False, Position, False); case Position of ttpTop: R := Bounds(0, 0, CR.Right - CR.Left, CR.Bottom - CR.Top); // Copy from Y = 0 ttpBottom: - R := Bounds(0, SpDPIScale(2), CR.Right - CR.Left, CR.Bottom - CR.Top + SpDPIScale(2)); // Copy from Y = 2 + R := Bounds(0, PPIScale(2), CR.Right - CR.Left, CR.Bottom - CR.Top + PPIScale(2)); // Copy from Y = 2 end; ACanvas.CopyRect(CR, B.Canvas, R); @@ -1166,7 +1159,7 @@ procedure TSpTBXTabItemViewer.DrawItemRightImage(ACanvas: TCanvas; ARect: TRect; PaintDefault := True; if ImgList = MDIButtonsImgList then begin PatternColor := GetTextColor(ItemInfo.State); - SpDrawGlyphPattern(ACanvas, ARect, TSpTBXGlyphPattern(ImgIndex), PatternColor); + SpDrawGlyphPattern(ACanvas, ARect, TSpTBXGlyphPattern(ImgIndex), PatternColor, View.Window.CurrentPPI); end else DoDrawTabCloseButton(ACanvas, ItemInfo.State, pstPostPaint, ImgList, ImgIndex, ARect, PaintDefault); @@ -1177,15 +1170,15 @@ procedure TSpTBXTabItemViewer.DrawItemRightImage(ACanvas: TCanvas; ARect: TRect; procedure TSpTBXTabItemViewer.DrawTab(ACanvas: TCanvas; ARect: TRect; AEnabled, AChecked, AHoverItem: Boolean; Position: TSpTBXTabPosition; - ASeparator: Boolean; AEdge: TSpTBXTabEdge); + ASeparator: Boolean); begin if ASeparator then begin - ARect.Left := ARect.Right - SpDPIScale(2); - SpDrawXPMenuSeparator(ACanvas, ARect, False, True) + ARect.Left := ARect.Right - PPIScale(2); + SpDrawXPMenuSeparator(ACanvas, ARect, False, True, View.Window.CurrentPPI); end else begin ACanvas.Brush.Color := Item.TabColor; - SpDrawXPTab(ACanvas, ARect, AEnabled, AChecked, AHoverItem, False, Position, AEdge); + SpDrawXPTab(ACanvas, ARect, AEnabled, AChecked, AHoverItem, False, Position, View.Window.CurrentPPI); end; end; @@ -1201,7 +1194,7 @@ function TSpTBXTabItemViewer.GetRightImageRect: TRect; begin RightGlyphSize := GetRightImageSize; R := BoundsRect; - InflateRect(R, -SpDPIScale(4), -SpDPIScale(4)); // Apply borders + InflateRect(R, -PPIScale(4), -PPIScale(4)); // Apply borders Result.Left := R.Right - RightGlyphSize.cx; Result.Right := Result.Left + RightGlyphSize.cx; @@ -1213,21 +1206,20 @@ function TSpTBXTabItemViewer.GetRightImageRect: TRect; function TSpTBXTabItemViewer.GetRightImageSize: TSize; var - ImgList: TCustomImageList; - ImgIndex: Integer; + IL: TCustomImageList; + I: Integer; begin Result.cx := 0; Result.cy := 0; - GetTabCloseButtonImgList(ImgList, ImgIndex); - if Assigned(ImgList) then - if ImgList = MDIButtonsImgList then begin - Result.cx := SpDPIScale(15); - Result.cy := SpDPIScale(15); + GetTabCloseButtonImgList(IL, I); + if Assigned(IL) then + if IL = MDIButtonsImgList then begin + Result.cx := PPIScale(15); + Result.cy := PPIScale(15); end - else if (ImgIndex >= 0) and (ImgIndex < ImgList.Count) then begin - Result.cx := ImgList.Width; - Result.cy := ImgList.Height; - end; + else + if (I >= 0) and (I < IL.Count) then + Result := SpGetScaledVirtualImageListSize(View.Window, GetImageList); end; procedure TSpTBXTabItemViewer.GetTabCloseButtonImgList(var AImageList: TCustomImageList; @@ -1401,8 +1393,8 @@ constructor TSpTBXTabToolbar.Create(AOwner: TComponent); FOwnerTabControl := nil; FActiveTabIndex := -1; FTabBackgroundBorders := False; - FTabAutofitMaxSize := SpDPIScale(200); - FTabCloseButtonImageIndex := -1; + FTabAutofitMaxSize := 200; + FTabCloseButtonImageIndex := -1; FTabColor := clBtnFace; FTabMaxSize := -1; FTabPosition := ttpTop; @@ -1465,7 +1457,7 @@ procedure TSpTBXTabToolbar.InternalDrawBackground(ACanvas: TCanvas; ARect: TRect FActiveTabRect := IV.BoundsRect; DestR := IV.BoundsRect; // Add the toolbar margins to DestR - OffsetRect(DestR, CDefaultToolbarBorderSize, CDefaultToolbarBorderSize); + OffsetRect(DestR, DockedBorderSize, DockedBorderSize); // Draw the bottom border (and the left border if it's the first active tab) TSpTBXTabItemViewer(IV).DrawBottomBorder(B.Canvas, DestR); end; @@ -1475,25 +1467,25 @@ procedure TSpTBXTabToolbar.InternalDrawBackground(ACanvas: TCanvas; ARect: TRect NextDelta := 1; if SkinManager.GetSkinType in [sknWindows, sknDelphiStyle] then begin // Grow the size of the clip rect when using Windows theme - PrevDelta := -SpDPIScale(PrevDelta); // -PrevDelta; - NextDelta := -SpDPIScale(NextDelta); // -NextDelta; + PrevDelta := -PPIScale(PrevDelta); // -PrevDelta; + NextDelta := -PPIScale(NextDelta); // -NextDelta; // Special case: the right side of the last tab is not bigger if not Assigned(Tab.GetNextTab(True, sivtInmediateSkipNonVisible)) then NextDelta := 1; end; if FTabPosition = ttpTop then - ExcludeClipRect(B.Canvas.Handle, DestR.Left + PrevDelta, R.Bottom - SpDPIScale(2), DestR.Right - NextDelta, R.Bottom + SpDPIScale(4)) + ExcludeClipRect(B.Canvas.Handle, DestR.Left + PrevDelta, R.Bottom - PPIScale(2), DestR.Right - NextDelta, R.Bottom + PPIScale(4)) else - ExcludeClipRect(B.Canvas.Handle, DestR.Left + PrevDelta, R.Top + SpDPIScale(2), DestR.Right - NextDelta, R.Top - SpDPIScale(4)); + ExcludeClipRect(B.Canvas.Handle, DestR.Left + PrevDelta, R.Top + PPIScale(2), DestR.Right - NextDelta, R.Top - PPIScale(4)); end; // Draw the bottom border of the tabs pane // We just need the top or bottom borders, instead of painting the whole // tabcontrol background just paint a 10 pixel height area, don't need to scale if FTabPosition = ttpTop then - DestR := Bounds(R.Left, R.Bottom - CDefaultToolbarBorderSize, R.Right - R.Left, 10) + DestR := Bounds(R.Left, R.Bottom - DockedBorderSize, R.Right - R.Left, 10) else - DestR := Bounds(R.Left, R.Top - (10 - CDefaultToolbarBorderSize), R.Right - R.Left, 10); + DestR := Bounds(R.Left, R.Top - (10 - DockedBorderSize), R.Right - R.Left, 10); SpDrawXPTabControlBackground(B.Canvas, DestR, Color, FTabPosition = ttpBottom); ACanvas.Draw(ARect.Left, ARect.Top, B); @@ -1595,7 +1587,7 @@ procedure TSpTBXTabToolbar.Autofit; Inc(TabsCount) else if IV.Item is TSpTBXRightAlignSpacerItem then - Inc(RightAlignWidth, SpDPIScale(20)) + Inc(RightAlignWidth, PPIScale(20)) else begin R := SpGetBoundsRect(IV, Items); Inc(NonTabsArea, R.Right - R.Left); @@ -1605,10 +1597,10 @@ procedure TSpTBXTabToolbar.Autofit; // Get TabsArea if TabsCount > 0 then begin - TabsArea := CurrentDock.ClientWidth - SpDPIScale(4) - NonTabsArea - RightAlignWidth; + TabsArea := CurrentDock.ClientWidth - PPIScale(4) - NonTabsArea - RightAlignWidth; TabsWidth := TabsArea div TabsCount; - if TabsWidth > FTabAutofitMaxSize then - TabsWidth := FTabAutofitMaxSize; + if TabsWidth > PPIScale(FTabAutofitMaxSize) then + TabsWidth := PPIScale(FTabAutofitMaxSize); end; // Get RightAlignWidth @@ -1661,20 +1653,20 @@ procedure TSpTBXTabToolbar.RightAlignItems; Spacer := SpGetRightAlignedItems(View, RightAlignedList, IsRotated, VisibleWidth, RightAlignedWidth); if Assigned(Spacer) then begin SpacerW := Spacer.BoundsRect.Right - Spacer.BoundsRect.Left; - RightAlignedBorder := CurrentDock.Width - SpDPIScale(2) - RightAlignedWidth + SpacerW; + RightAlignedBorder := CurrentDock.Width - PPIScale(2) - RightAlignedWidth + SpacerW; VisibleWidth := VisibleWidth - SpacerW; - SpacerW := CurrentDock.Width - VisibleWidth - SpDPIScale(4); + SpacerW := CurrentDock.Width - VisibleWidth - PPIScale(4); end else begin SpacerW := 0; - RightAlignedBorder := CurrentDock.Width - SpDPIScale(2); + RightAlignedBorder := CurrentDock.Width - PPIScale(2); end; // Show items VisibleTabsCount := GetTabsCount(True); IsFirstPartiallyVisible := False; if VisibleTabsCount = 1 then begin - if VisibleWidth > CurrentDock.Width - SpDPIScale(2) then + if VisibleWidth > CurrentDock.Width - PPIScale(2) then IsFirstPartiallyVisible := True; end; @@ -1699,7 +1691,7 @@ procedure TSpTBXTabToolbar.RightAlignItems; H := 0; TTBItemViewerAccess(IV).CalcSize(Canvas, W, H); VisibleWidth := VisibleWidth + W; - if (VisibleTabsCount = 0) or (VisibleWidth < CurrentDock.Width - SpDPIScale(2)) then begin + if (VisibleTabsCount = 0) or (VisibleWidth < CurrentDock.Width - PPIScale(2)) then begin SpacerW := SpacerW - W; FHiddenTabs.Delete(J); IV.Item.Visible := True; @@ -1721,7 +1713,7 @@ procedure TSpTBXTabToolbar.RightAlignItems; H := 0; TTBItemViewerAccess(IV).CalcSize(Canvas, W, H); VisibleWidth := VisibleWidth + W; - if (VisibleTabsCount = 0) or (VisibleWidth < CurrentDock.Width - SpDPIScale(2)) then begin + if (VisibleTabsCount = 0) or (VisibleWidth < CurrentDock.Width - PPIScale(2)) then begin SpacerW := SpacerW - W; FHiddenTabs.Delete(J); IV.Item.Visible := True; @@ -1825,7 +1817,7 @@ procedure TSpTBXTabToolbar.Scroll(ToRight: Boolean); H := 0; TTBItemViewerAccess(IV).CalcSize(Canvas, W, H); if ToRight then begin - while Assigned(FirstIV) and (VisibleWidth + W >= CurrentDock.ClientWidth - SpDPIScale(2)) do begin + while Assigned(FirstIV) and (VisibleWidth + W >= CurrentDock.ClientWidth - PPIScale(2)) do begin VisibleWidth := VisibleWidth - (FirstIV.BoundsRect.Right - FirstIV.BoundsRect.Left); FHiddenTabs.Add(FirstIV.Item); FirstIV.Item.Visible := False; @@ -1834,7 +1826,7 @@ procedure TSpTBXTabToolbar.Scroll(ToRight: Boolean); end; end else begin - while Assigned(LastIV) and (VisibleWidth + W >= CurrentDock.ClientWidth - SpDPIScale(2)) do begin + while Assigned(LastIV) and (VisibleWidth + W >= CurrentDock.ClientWidth - PPIScale(2)) do begin VisibleWidth := VisibleWidth - (LastIV.BoundsRect.Right - LastIV.BoundsRect.Left); FHiddenTabs.Add(LastIV.Item); LastIV.Item.Visible := False; @@ -1845,7 +1837,7 @@ procedure TSpTBXTabToolbar.Scroll(ToRight: Boolean); // Try to show all the necessary clipped tabs IVIndex := IV.Index; - while Assigned(IV) and (ClippedIndex > -1) and ((VisibleTabsCount = 0) or (VisibleWidth + W <= CurrentDock.ClientWidth - SpDPIScale(2))) do begin + while Assigned(IV) and (ClippedIndex > -1) and ((VisibleTabsCount = 0) or (VisibleWidth + W <= CurrentDock.ClientWidth - PPIScale(2))) do begin VisibleWidth := VisibleWidth + W; IV.Item.Visible := True; FHiddenTabs.Delete(ClippedIndex); @@ -2000,12 +1992,7 @@ procedure TSpTBXTabToolbar.SetActiveTabIndex(Value: Integer); MakeVisible(ATab); end; FOwnerTabControl.DoActiveTabChange(FActiveTabIndex); - // To avoid flicker don't call InvalidateNC, use the following instead - if not IsUpdating then begin - View.InvalidatePositions; - SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or SWP_NOSIZE or - SWP_NOMOVE or SWP_DRAWFRAME or SWP_SHOWWINDOW); - end; + InvalidateNC; end; end; @@ -2127,7 +2114,7 @@ function TSpTBXTabToolbar.CanDragCustomize(Button: TMouseButton; if FTabDragReorder and not IsCustomizing and IV.Item.Checked then begin Result := True; // Bypass the inherited mouse down FBeginDragIV := IV; - BeginDrag(False, SpDPIScale(2)); + BeginDrag(False, PPIScale(2)); end; end; end @@ -2169,7 +2156,7 @@ procedure TSpTBXTabToolbar.DragOver(Source: TObject; X, Y: Integer; if Assigned(RightAlignIV) then RightAlignPos := Items.IndexOf(RightAlignIV.Item) else - RightAlignPos := -SpDPIScale(1); + RightAlignPos := -PPIScale(1); if (OrigPos <> DestPos) and (DestPos > -1) and (DestPos < Items.Count) and (OrigItem <> DestIV.Item) and not ((RightAlignPos > -1) and (DestPos >= RightAlignPos)) then begin @@ -2269,8 +2256,8 @@ procedure TSpTBXTabSheet.DrawBackground(ACanvas: TCanvas; ARect: TRect); if Assigned(FTabControl) and Visible then begin if FTabControl.TabVisible then begin case FTabControl.TabPosition of - ttpTop: dec(ARect.Top, SpDPIScale(4)); - ttpBottom: inc(ARect.Bottom, SpDPIScale(4)); + ttpTop: dec(ARect.Top, PPIScale(4)); + ttpBottom: inc(ARect.Bottom, PPIScale(4)); end; end; FTabControl.DrawBackground(ACanvas, ARect); @@ -2409,7 +2396,7 @@ constructor TSpTBXCustomTabSet.Create(AOwner: TComponent); inherited; FTabVisible := True; Width := 289; - Height := FDock.Height + SpDPIScale(2); + Height := FDock.Height + SpDefaultBorderSize; // Do not scale FToolbar.Items.RegisterNotification(ItemNotification); end; @@ -2476,7 +2463,7 @@ function TSpTBXCustomTabSet.GetToolbarClass: TSpTBXToolbarClass; Result := TSpTBXTabToolbar; end; -function TSpTBXCustomTabSet.Add(ACaption: string): TSpTBXTabItem; +function TSpTBXCustomTabSet.Add(const ACaption: string): TSpTBXTabItem; var I: Integer; SpacerIV: TSpTBXItemViewer; @@ -2499,7 +2486,8 @@ function TSpTBXCustomTabSet.Add(ACaption: string): TSpTBXTabItem; end; end; -function TSpTBXCustomTabSet.Insert(NewIndex: Integer; ACaption: string): TSpTBXTabItem; +function TSpTBXCustomTabSet.Insert(NewIndex: Integer; const ACaption: string): + TSpTBXTabItem; begin Result := TSpTBXTabItem.Create(Self); try @@ -2967,7 +2955,6 @@ procedure TSpTBXCustomTabSet.WMInvalidateTabBackground(var Message: TMessage); constructor TSpTBXCustomTabControl.Create(AOwner: TComponent); begin inherited; -// ControlStyle := ControlStyle - [csAcceptsControls]; FPages := TList.Create; // FEmptyTabSheet is used to hide the rest of the TabSheets