From e83d3dc3ab19e151ae5ddb7991230e5a41bcc4ef Mon Sep 17 00:00:00 2001 From: Npc <1@2.com> Date: Tue, 5 Sep 2023 21:31:28 -0700 Subject: [PATCH 01/28] Add check for MainColumn column when it need to be the FocusedColumn DoFocusNode will slways set FFocusedColumn to MainColumn when FFocusedColumn is not a valid column, even coAllowFocus is not active on MainColumn. --- Source/VirtualTrees.BaseTree.pas | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index d36c2afc..a208e657 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -10603,7 +10603,9 @@ procedure TBaseVirtualTree.DoFocusNode(Node: PVirtualNode; Ask: Boolean); if Assigned(FFocusedNode) then begin // Make sure a valid column is set if columns are used and no column has currently the focus. - if FHeader.UseColumns and (not FHeader.Columns.IsValidColumn(FFocusedColumn)) then + // We should also check if the maincolumn is allowfocus + if FHeader.UseColumns and (not FHeader.Columns.IsValidColumn(FFocusedColumn)) + and FHeader.AllowFocus(FHeader.MainColumn) then FFocusedColumn := FHeader.MainColumn; // Do automatic expansion of the newly focused node if enabled. if (toAutoExpand in FOptions.AutoOptions) and not (vsExpanded in FFocusedNode.States) then From a05006427ee681dac08ae11eda651e148ef2db4a Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Wed, 20 Sep 2023 22:21:46 +0200 Subject: [PATCH 02/28] Fixed issue #1199: Infinite loop in TBaseVirtualTree.Destroy() --- Source/VirtualTrees.BaseTree.pas | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index d36c2afc..b5057010 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -570,6 +570,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) FOperationCanceled: Boolean; // Used to indicate that a long-running operation should be canceled. FChangingTheme: Boolean; // Used to indicate that a theme change is goi ng on FNextNodeToSelect: PVirtualNode; // Next tree node that we would like to select if the current one gets deleted or looses selection for other reasons. + FPendingSyncProcs:Integer; // Counter that indicates whether we have queued anonymous calls to the min thread, see issue #1199 // export FOnBeforeNodeExport: TVTNodeExportEvent; // called before exporting a node @@ -2667,7 +2668,7 @@ destructor TBaseVirtualTree.Destroy(); if WasValidating then begin // Make sure we dequeue the two synchronized calls from ChangeTreeStatesAsync(), fixes mem leak and AV reported in issue #1001, but is more a workaround. - while CheckSynchronize() do + while CheckSynchronize() and (FPendingSyncProcs>0) do Sleep(1); end;// if FOptions.InternalSetMiscOptions(FOptions.MiscOptions - [toReadOnly]); //SetMiscOptions has side effects @@ -9044,14 +9045,19 @@ procedure TBaseVirtualTree.ChangeTreeStatesAsync(EnterStates, LeaveStates: TVirt begin //TODO: If this works reliable, move to TWorkerThread if not (csDestroying in ComponentState) then + begin + AtomicIncrement(FPendingSyncProcs); TThread.Synchronize(nil, procedure begin + //Decrement invoke refs + AtomicDecrement(FPendingSyncProcs); // Prevent invalid combination tsUseCache + tsValidationNeeded (#915) if not ((tsUseCache in EnterStates) and (tsValidationNeeded in FStates + LeaveStates)) then DoStateChange(EnterStates, LeaveStates); if (tsValidating in FStates) and (tsValidating in LeaveStates) then UpdateEditBounds(); end); + end; end; //---------------------------------------------------------------------------------------------------------------------- @@ -20625,13 +20631,18 @@ procedure TBaseVirtualTree.MeasureItemHeight(const Canvas: TCanvas; Node: PVirtu NewNodeHeight := Node.NodeHeight; // Anonymous methods help to make this thread safe easily. if (MainThreadId <> GetCurrentThreadId) then + begin + AtomicIncrement(FPendingSyncProcs); TThread.Synchronize(nil, procedure begin + //swish:Decrement invoke refs + AtomicDecrement(FPendingSyncProcs); DoMeasureItem(Canvas, Node, NewNodeHeight); SetNodeHeight(Node, NewNodeHeight); end ) + end else begin DoMeasureItem(Canvas, Node, NewNodeHeight); From 90a09f8b60746e9de6c8520c2333848e7eeaff0a Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Wed, 20 Sep 2023 22:40:40 +0200 Subject: [PATCH 03/28] Change for #832: Turn TVirtualNode.NodeHeight into a readonly property --- Source/VirtualTrees.BaseTree.pas | 12 ++++++------ Source/VirtualTrees.Types.pas | 9 ++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 4d679f1b..f53b4733 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -4330,7 +4330,7 @@ procedure TBaseVirtualTree.InitRootNode(OldSize: Cardinal = 0); States := [vsInitialized, vsExpanded, vsHasChildren, vsVisible]; TotalHeight := FDefaultNodeHeight; TotalCount := 1; - NodeHeight := FDefaultNodeHeight; + SetNodeHeight(FDefaultNodeHeight); Align := 50; end; end; @@ -4414,7 +4414,7 @@ function TBaseVirtualTree.MakeNewNode: PVirtualNode; begin TotalCount := 1; TotalHeight := FDefaultNodeHeight; - NodeHeight := FDefaultNodeHeight; + SetNodeHeight(FDefaultNodeHeight); States := [vsVisible]; Align := 50; end; @@ -5180,7 +5180,7 @@ procedure TBaseVirtualTree.SetDefaultNodeHeight(Value: TDimension); if FDefaultNodeHeight <> Value then begin Inc(FRoot.TotalHeight, Value - FDefaultNodeHeight); - Inc(FRoot.NodeHeight, Value - FDefaultNodeHeight); + FRoot.SetNodeHeight(FRoot.NodeHeight + Value - FDefaultNodeHeight); FDefaultNodeHeight := Value; InvalidateCache; if (FUpdateCount = 0) and HandleAllocated and not (csLoading in ComponentState) then @@ -5599,7 +5599,7 @@ procedure TBaseVirtualTree.SetNodeHeight(Node: PVirtualNode; Value: TDimension); if (Node.NodeHeight <> Value) then begin Difference := Value - Node.NodeHeight; - Node.NodeHeight := Value; + Node.SetNodeHeight(Value); // If the node is effectively filtered out, nothing else has to be done, as it is not visible anyway. if not IsEffectivelyFiltered[Node] then @@ -9027,7 +9027,7 @@ procedure TBaseVirtualTree.ScaleNodeHeights(M, D: Integer); SetNodeHeight(Run, MulDiv(Run.NodeHeight, M, D)) else // prevent initialization of non-initialzed nodes begin - Run.NodeHeight := MulDiv(Run.NodeHeight, M, D); + Run.SetNodeHeight(MulDiv(Run.NodeHeight, M, D)); // The next three lines fix issue #1000 lNewNodeTotalHeight := MulDiv(Run.TotalHeight, M, D); FRoot.TotalHeight := Cardinal(Int64(FRoot.TotalHeight) + Int64(lNewNodeTotalHeight) - Int64(Run.TotalHeight)); // Avoiding EIntOverflow exception. @@ -15122,7 +15122,7 @@ function TBaseVirtualTree.ReadChunk(Stream: TStream; Version: Integer; Node: PVi begin // Set states first, in case the node is invisible. States := ChunkBody.States; - NodeHeight := ChunkBody.NodeHeight; + SetNodeHeight(ChunkBody.NodeHeight); TotalHeight := NodeHeight; Align := ChunkBody.Align; CheckState := ChunkBody.CheckState; diff --git a/Source/VirtualTrees.Types.pas b/Source/VirtualTrees.Types.pas index 0cda991f..3c8c6a61 100644 --- a/Source/VirtualTrees.Types.pas +++ b/Source/VirtualTrees.Types.pas @@ -887,8 +887,8 @@ TScrollBarOptions = class(TPersistent) private fIndex: Cardinal; // index of node with regard to its parent fChildCount: Cardinal; // number of child nodes + fNodeHeight: TDimension; // height in pixels public - NodeHeight: TDimension; // height in pixels States: TVirtualNodeStates; // states describing various properties of the node (expanded, initialized etc.) Align: Byte; // line/button alignment CheckState: TCheckState; // indicates the current check state (e.g. checked, pressed etc.) @@ -917,12 +917,14 @@ TScrollBarOptions = class(TPersistent) procedure SetLastChild(const pLastChild: PVirtualNode); inline; //internal method, do not call directly procedure SetIndex(const pIndex: Cardinal); inline; //internal method, do not call directly. procedure SetChildCount(const pCount: Cardinal); inline; //internal method, do not call directly. + procedure SetNodeHeight(const pNodeHeight: TDimension); inline; //internal method, do not call directly. property Index: Cardinal read fIndex; property ChildCount: Cardinal read fChildCount; property Parent: PVirtualNode read fParent; property PrevSibling: PVirtualNode read fPrevSibling; property NextSibling: PVirtualNode read fNextSibling; property LastChild: PVirtualNode read fLastChild; + property NodeHeight: TDimension read fNodeHeight; private Data: record end; // this is a placeholder, each node gets extra data determined by NodeDataSize public @@ -1149,6 +1151,11 @@ function TVirtualNode.IsAssigned: Boolean; Exit(@Self <> nil); end; +procedure TVirtualNode.SetNodeHeight(const pNodeHeight: TDimension); +begin + fNodeHeight := pNodeHeight; +end; + //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualNode.SetData(pUserData: Pointer); From 015f36797e355ab677dcef95e71c1e29dd903b26 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Thu, 21 Sep 2023 17:03:51 +0200 Subject: [PATCH 04/28] Issue #1169: Drop support for RAD Studio XE3 - XE8 --- .../RAD Studio XE3/VirtualTreeView.groupproj | 48 -- Packages/RAD Studio XE3/VirtualTreesD.dpk | 42 -- Packages/RAD Studio XE3/VirtualTreesD.dproj | 145 ----- Packages/RAD Studio XE3/VirtualTreesD.res | Bin 96 -> 0 bytes Packages/RAD Studio XE3/VirtualTreesR.dpk | 58 -- Packages/RAD Studio XE3/VirtualTreesR.dproj | 180 ------- Packages/RAD Studio XE3/VirtualTreesR.res | Bin 61540 -> 0 bytes .../RAD Studio XE4/VirtualTreeView.groupproj | 48 -- Packages/RAD Studio XE4/VirtualTreesD.dpk | 42 -- Packages/RAD Studio XE4/VirtualTreesD.dproj | 146 ----- Packages/RAD Studio XE4/VirtualTreesD.res | Bin 96 -> 0 bytes Packages/RAD Studio XE4/VirtualTreesR.dpk | 57 -- Packages/RAD Studio XE4/VirtualTreesR.dproj | 182 ------- Packages/RAD Studio XE4/VirtualTreesR.res | Bin 297436 -> 0 bytes .../RAD Studio XE5/VirtualTreeView.groupproj | 48 -- Packages/RAD Studio XE5/VirtualTreesD.cpp | 17 - Packages/RAD Studio XE5/VirtualTreesD.dpk | 42 -- Packages/RAD Studio XE5/VirtualTreesD.dproj | 158 ------ Packages/RAD Studio XE5/VirtualTreesD.res | Bin 96 -> 0 bytes Packages/RAD Studio XE5/VirtualTreesR.cpp | 17 - Packages/RAD Studio XE5/VirtualTreesR.dpk | 57 -- Packages/RAD Studio XE5/VirtualTreesR.dproj | 194 ------- Packages/RAD Studio XE5/VirtualTreesR.res | Bin 61540 -> 0 bytes .../RAD Studio XE6/VirtualTreeView.groupproj | 48 -- Packages/RAD Studio XE6/VirtualTreesD.dpk | 42 -- Packages/RAD Studio XE6/VirtualTreesD.dproj | 138 ----- Packages/RAD Studio XE6/VirtualTreesR.dpk | 57 -- Packages/RAD Studio XE6/VirtualTreesR.dproj | 194 ------- .../RAD Studio XE7/VirtualTreeView.groupproj | 48 -- Packages/RAD Studio XE7/VirtualTreesD.dpk | 42 -- Packages/RAD Studio XE7/VirtualTreesD.dproj | 139 ----- Packages/RAD Studio XE7/VirtualTreesR.dpk | 57 -- Packages/RAD Studio XE7/VirtualTreesR.dproj | 498 ------------------ .../RAD Studio XE8/VirtualTreeView.groupproj | 48 -- Packages/RAD Studio XE8/VirtualTreesD.dpk | 42 -- Packages/RAD Studio XE8/VirtualTreesD.dproj | 139 ----- Packages/RAD Studio XE8/VirtualTreesR.dpk | 57 -- Packages/RAD Studio XE8/VirtualTreesR.dproj | 498 ------------------ 38 files changed, 3528 deletions(-) delete mode 100644 Packages/RAD Studio XE3/VirtualTreeView.groupproj delete mode 100644 Packages/RAD Studio XE3/VirtualTreesD.dpk delete mode 100644 Packages/RAD Studio XE3/VirtualTreesD.dproj delete mode 100644 Packages/RAD Studio XE3/VirtualTreesD.res delete mode 100644 Packages/RAD Studio XE3/VirtualTreesR.dpk delete mode 100644 Packages/RAD Studio XE3/VirtualTreesR.dproj delete mode 100644 Packages/RAD Studio XE3/VirtualTreesR.res delete mode 100644 Packages/RAD Studio XE4/VirtualTreeView.groupproj delete mode 100644 Packages/RAD Studio XE4/VirtualTreesD.dpk delete mode 100644 Packages/RAD Studio XE4/VirtualTreesD.dproj delete mode 100644 Packages/RAD Studio XE4/VirtualTreesD.res delete mode 100644 Packages/RAD Studio XE4/VirtualTreesR.dpk delete mode 100644 Packages/RAD Studio XE4/VirtualTreesR.dproj delete mode 100644 Packages/RAD Studio XE4/VirtualTreesR.res delete mode 100644 Packages/RAD Studio XE5/VirtualTreeView.groupproj delete mode 100644 Packages/RAD Studio XE5/VirtualTreesD.cpp delete mode 100644 Packages/RAD Studio XE5/VirtualTreesD.dpk delete mode 100644 Packages/RAD Studio XE5/VirtualTreesD.dproj delete mode 100644 Packages/RAD Studio XE5/VirtualTreesD.res delete mode 100644 Packages/RAD Studio XE5/VirtualTreesR.cpp delete mode 100644 Packages/RAD Studio XE5/VirtualTreesR.dpk delete mode 100644 Packages/RAD Studio XE5/VirtualTreesR.dproj delete mode 100644 Packages/RAD Studio XE5/VirtualTreesR.res delete mode 100644 Packages/RAD Studio XE6/VirtualTreeView.groupproj delete mode 100644 Packages/RAD Studio XE6/VirtualTreesD.dpk delete mode 100644 Packages/RAD Studio XE6/VirtualTreesD.dproj delete mode 100644 Packages/RAD Studio XE6/VirtualTreesR.dpk delete mode 100644 Packages/RAD Studio XE6/VirtualTreesR.dproj delete mode 100644 Packages/RAD Studio XE7/VirtualTreeView.groupproj delete mode 100644 Packages/RAD Studio XE7/VirtualTreesD.dpk delete mode 100644 Packages/RAD Studio XE7/VirtualTreesD.dproj delete mode 100644 Packages/RAD Studio XE7/VirtualTreesR.dpk delete mode 100644 Packages/RAD Studio XE7/VirtualTreesR.dproj delete mode 100644 Packages/RAD Studio XE8/VirtualTreeView.groupproj delete mode 100644 Packages/RAD Studio XE8/VirtualTreesD.dpk delete mode 100644 Packages/RAD Studio XE8/VirtualTreesD.dproj delete mode 100644 Packages/RAD Studio XE8/VirtualTreesR.dpk delete mode 100644 Packages/RAD Studio XE8/VirtualTreesR.dproj diff --git a/Packages/RAD Studio XE3/VirtualTreeView.groupproj b/Packages/RAD Studio XE3/VirtualTreeView.groupproj deleted file mode 100644 index 980342db..00000000 --- a/Packages/RAD Studio XE3/VirtualTreeView.groupproj +++ /dev/null @@ -1,48 +0,0 @@ - - - {CC6A9541-DD5C-4BCD-8914-016D8D2EAB3B} - - - - - - - VirtualTreesR.dproj - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Packages/RAD Studio XE3/VirtualTreesD.dpk b/Packages/RAD Studio XE3/VirtualTreesD.dpk deleted file mode 100644 index 63978fda..00000000 --- a/Packages/RAD Studio XE3/VirtualTreesD.dpk +++ /dev/null @@ -1,42 +0,0 @@ -package VirtualTreesD; - -{$R *.res} -{$R '..\..\Design\VirtualTrees.dcr'} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'VirtualTreeView Controls'} -{$LIBSUFFIX '17'} -{$DESIGNONLY} -{$IMPLICITBUILD OFF} - -requires - DesignIDE, - VirtualTreesR; - -contains - VirtualTreesReg in '..\..\Design\VirtualTreesReg.pas'; - -end. - diff --git a/Packages/RAD Studio XE3/VirtualTreesD.dproj b/Packages/RAD Studio XE3/VirtualTreesD.dproj deleted file mode 100644 index dd2d8787..00000000 --- a/Packages/RAD Studio XE3/VirtualTreesD.dproj +++ /dev/null @@ -1,145 +0,0 @@ - - - {A34BA07B-19B6-4C21-9DEE-65FCA52D00AB} - VirtualTreesD.dpk - True - Debug - Package - VCL - DCC32 - 14.3 - Win32 - 1 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - VirtualTreeView Controls - All - 17 - true - ..\..\source;$(BDSCOMMONDIR)\dcp;$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - vcl;$(DCC_UsePackage) - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - vcl;VirtualTreesD;VirtualTreesR;$(DCC_UsePackage) - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - false - true - - - - MainSource - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesD.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - False - True - - - 12 - - - - diff --git a/Packages/RAD Studio XE3/VirtualTreesD.res b/Packages/RAD Studio XE3/VirtualTreesD.res deleted file mode 100644 index 743599575b02e97248bade49ed2e3eabafe25a0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmZQzU|>)H;{X347|28cOhBFu5dZ(r#Sp;Y!{Epe!r;c>&k)4m3uHM0X?F%!AS)QE O%YcEC1!e#vkO2UW7YiT& diff --git a/Packages/RAD Studio XE3/VirtualTreesR.dpk b/Packages/RAD Studio XE3/VirtualTreesR.dpk deleted file mode 100644 index 8e292efc..00000000 --- a/Packages/RAD Studio XE3/VirtualTreesR.dpk +++ /dev/null @@ -1,58 +0,0 @@ -package VirtualTreesR; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$LIBSUFFIX '17'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -requires - vcl, - vclx; - -contains - VirtualTrees in '..\..\Source\VirtualTrees.pas', - VirtualTrees.HeaderPopup in '..\..\Source\VirtualTrees.HeaderPopup.pas', - VirtualTrees.AccessibilityFactory in '..\..\Source\VirtualTrees.AccessibilityFactory.pas', - VirtualTrees.Accessibility in '..\..\Source\VirtualTrees.Accessibility.pas', - VirtualTrees.StyleHooks in '..\..\Source\VirtualTrees.StyleHooks.pas', - VirtualTrees.Classes in '..\..\Source\VirtualTrees.Classes.pas', - VirtualTrees.WorkerThread in '..\..\Source\VirtualTrees.WorkerThread.pas', - VirtualTrees.ClipBoard in '..\..\Source\VirtualTrees.ClipBoard.pas', - VirtualTrees.Actions in '..\..\Source\VirtualTrees.Actions.pas', - VirtualTrees.Export in '..\..\Source\VirtualTrees.Export.pas', - VirtualTrees.Utils in '..\..\Source\VirtualTrees.Utils.pas', - VirtualTrees.Types in '..\..\Source\VirtualTrees.Types.pas', - VirtualTrees.Header in '..\..\Source\VirtualTrees.Header.pas', - VirtualTrees.DataObject in '..\..\Source\VirtualTrees.DataObject.pas', - VirtualTrees.DragnDrop in '..\..\Source\VirtualTrees.DragnDrop.pas', - VirtualTrees.DragImage in '..\..\Source\VirtualTrees.DragImage.pas', - VirtualTrees.EditLink in '..\..\Source\VirtualTrees.EditLink.pas', - VirtualTrees.Colors in '..\..\Source\VirtualTrees.Colors.pas', - VirtualTrees.DrawTree in '..\..\Source\VirtualTrees.DrawTree.pas'; - -end. - diff --git a/Packages/RAD Studio XE3/VirtualTreesR.dproj b/Packages/RAD Studio XE3/VirtualTreesR.dproj deleted file mode 100644 index e8390e77..00000000 --- a/Packages/RAD Studio XE3/VirtualTreesR.dproj +++ /dev/null @@ -1,180 +0,0 @@ - - - {B62F3689-96E1-47D5-9FB2-2A2718281FDB} - VirtualTreesR.dpk - True - Debug - Package - VCL - DCC32 - 14.3 - Win32 - 3 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - ..\..\Source - All - 17 - true - ..\..\source;$(BDSCOMMONDIR)\dcp;$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - $(BDSCOMMONDIR)\DCP\$(Platform) - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - true - 1033 - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - false - true - - - true - - - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesR.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - - - 12 - - - - diff --git a/Packages/RAD Studio XE3/VirtualTreesR.res b/Packages/RAD Studio XE3/VirtualTreesR.res deleted file mode 100644 index 0e9e906fe457be266d93d16c8090c2f0c53f7ce7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61540 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�uzSd2!V%dzk#U+zRp*8Qt> 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 E210a*O#lD@ diff --git a/Packages/RAD Studio XE4/VirtualTreeView.groupproj b/Packages/RAD Studio XE4/VirtualTreeView.groupproj deleted file mode 100644 index 980342db..00000000 --- a/Packages/RAD Studio XE4/VirtualTreeView.groupproj +++ /dev/null @@ -1,48 +0,0 @@ - - - {CC6A9541-DD5C-4BCD-8914-016D8D2EAB3B} - - - - - - - VirtualTreesR.dproj - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Packages/RAD Studio XE4/VirtualTreesD.dpk b/Packages/RAD Studio XE4/VirtualTreesD.dpk deleted file mode 100644 index cb599e9d..00000000 --- a/Packages/RAD Studio XE4/VirtualTreesD.dpk +++ /dev/null @@ -1,42 +0,0 @@ -package VirtualTreesD; - -{$R *.res} -{$R '..\..\Design\VirtualTrees.dcr'} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'VirtualTreeView Controls'} -{$LIBSUFFIX '18'} -{$DESIGNONLY} -{$IMPLICITBUILD OFF} - -requires - DesignIDE, - VirtualTreesR; - -contains - VirtualTreesReg in '..\..\Design\VirtualTreesReg.pas'; - -end. - diff --git a/Packages/RAD Studio XE4/VirtualTreesD.dproj b/Packages/RAD Studio XE4/VirtualTreesD.dproj deleted file mode 100644 index d78544bc..00000000 --- a/Packages/RAD Studio XE4/VirtualTreesD.dproj +++ /dev/null @@ -1,146 +0,0 @@ - - - {A34BA07B-19B6-4C21-9DEE-65FCA52D00AB} - VirtualTreesD.dpk - True - Debug - Package - VCL - DCC32 - 14.6 - Win32 - 1 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - .\$(Platform)\$(Config) - true - VirtualTreeView Controls - All - 18 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - vcl;VirtualTreesD;VirtualTreesR;$(DCC_UsePackage) - - - vcl;$(DCC_UsePackage) - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - false - true - - - - MainSource - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesD.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver - Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server - - - - False - False - True - False - - - 12 - - - - diff --git a/Packages/RAD Studio XE4/VirtualTreesD.res b/Packages/RAD Studio XE4/VirtualTreesD.res deleted file mode 100644 index 743599575b02e97248bade49ed2e3eabafe25a0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmZQzU|>)H;{X347|28cOhBFu5dZ(r#Sp;Y!{Epe!r;c>&k)4m3uHM0X?F%!AS)QE O%YcEC1!e#vkO2UW7YiT& diff --git a/Packages/RAD Studio XE4/VirtualTreesR.dpk b/Packages/RAD Studio XE4/VirtualTreesR.dpk deleted file mode 100644 index 5288017a..00000000 --- a/Packages/RAD Studio XE4/VirtualTreesR.dpk +++ /dev/null @@ -1,57 +0,0 @@ -package VirtualTreesR; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$LIBSUFFIX '18'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -requires - vcl, - vclx; - -contains - VirtualTrees in '..\..\Source\VirtualTrees.pas', - VirtualTrees.HeaderPopup in '..\..\Source\VirtualTrees.HeaderPopup.pas', - VirtualTrees.AccessibilityFactory in '..\..\Source\VirtualTrees.AccessibilityFactory.pas', - VirtualTrees.Accessibility in '..\..\Source\VirtualTrees.Accessibility.pas', - VirtualTrees.StyleHooks in '..\..\Source\VirtualTrees.StyleHooks.pas', - VirtualTrees.Classes in '..\..\Source\VirtualTrees.Classes.pas', - VirtualTrees.WorkerThread in '..\..\Source\VirtualTrees.WorkerThread.pas', - VirtualTrees.ClipBoard in '..\..\Source\VirtualTrees.ClipBoard.pas', - VirtualTrees.Actions in '..\..\Source\VirtualTrees.Actions.pas', - VirtualTrees.Export in '..\..\Source\VirtualTrees.Export.pas', - VirtualTrees.Utils in '..\..\Source\VirtualTrees.Utils.pas', - VirtualTrees.Types in '..\..\Source\VirtualTrees.Types.pas', - VirtualTrees.Header in '..\..\Source\VirtualTrees.Header.pas', - VirtualTrees.DataObject in '..\..\Source\VirtualTrees.DataObject.pas', - VirtualTrees.DragnDrop in '..\..\Source\VirtualTrees.DragnDrop.pas', - VirtualTrees.DragImage in '..\..\Source\VirtualTrees.DragImage.pas', - VirtualTrees.EditLink in '..\..\Source\VirtualTrees.EditLink.pas', - VirtualTrees.Colors in '..\..\Source\VirtualTrees.Colors.pas', - VirtualTrees.DrawTree in '..\..\Source\VirtualTrees.DrawTree.pas'; - -end. diff --git a/Packages/RAD Studio XE4/VirtualTreesR.dproj b/Packages/RAD Studio XE4/VirtualTreesR.dproj deleted file mode 100644 index edd1208f..00000000 --- a/Packages/RAD Studio XE4/VirtualTreesR.dproj +++ /dev/null @@ -1,182 +0,0 @@ - - - {B62F3689-96E1-47D5-9FB2-2A2718281FDB} - VirtualTreesR.dpk - True - Debug - Package - VCL - DCC32 - 14.6 - Win32 - 3 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - .\$(Platform)\$(Config) - ..\..\Source - true - 18 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - - - $(BDSCOMMONDIR)\DCP\$(Platform) - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - true - 1033 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - false - true - - - true - - - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesR.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver - Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server - - - - False - False - True - True - - - 12 - - - - diff --git a/Packages/RAD Studio XE4/VirtualTreesR.res b/Packages/RAD Studio XE4/VirtualTreesR.res deleted file mode 100644 index 7ba21a6f502839e5cee8c3b22874695f8740952d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 297436 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 - - {CC6A9541-DD5C-4BCD-8914-016D8D2EAB3B} - - - - - - - VirtualTreesR.dproj - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Packages/RAD Studio XE5/VirtualTreesD.cpp b/Packages/RAD Studio XE5/VirtualTreesD.cpp deleted file mode 100644 index 37aacb55..00000000 --- a/Packages/RAD Studio XE5/VirtualTreesD.cpp +++ /dev/null @@ -1,17 +0,0 @@ -//--------------------------------------------------------------------------- - -#include -#pragma hdrstop -#pragma package(smart_init) -//--------------------------------------------------------------------------- - -// Package source. -//--------------------------------------------------------------------------- - - -#pragma argsused -int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) -{ - return 1; -} -//--------------------------------------------------------------------------- diff --git a/Packages/RAD Studio XE5/VirtualTreesD.dpk b/Packages/RAD Studio XE5/VirtualTreesD.dpk deleted file mode 100644 index eef9d637..00000000 --- a/Packages/RAD Studio XE5/VirtualTreesD.dpk +++ /dev/null @@ -1,42 +0,0 @@ -package VirtualTreesD; - -{$R *.res} -{$R '..\..\Design\VirtualTrees.dcr'} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'VirtualTreeView Controls'} -{$LIBSUFFIX '19'} -{$DESIGNONLY} -{$IMPLICITBUILD OFF} - -requires - DesignIDE, - VirtualTreesR; - -contains - VirtualTreesReg in '..\..\Design\VirtualTreesReg.pas'; - -end. - diff --git a/Packages/RAD Studio XE5/VirtualTreesD.dproj b/Packages/RAD Studio XE5/VirtualTreesD.dproj deleted file mode 100644 index f655f446..00000000 --- a/Packages/RAD Studio XE5/VirtualTreesD.dproj +++ /dev/null @@ -1,158 +0,0 @@ - - - {A34BA07B-19B6-4C21-9DEE-65FCA52D00AB} - VirtualTreesD.dpk - True - Debug - Package - VCL - DCC32 - 15.0 - Win32 - 1 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - .\$(Platform)\$(Config) - true - VirtualTreeView Controls - All - 19 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Debug - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal; - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - vcl;VirtualTreesD;VirtualTreesR;$(DCC_UsePackage) - - - vcl;$(DCC_UsePackage) - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - false - true - - - - MainSource - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesD.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder-Package für Office 2000-Server - Embarcadero C++Builder-Package für Office XP-Server - Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver - Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server - - - - False - False - False - True - False - - - 12 - - - - diff --git a/Packages/RAD Studio XE5/VirtualTreesD.res b/Packages/RAD Studio XE5/VirtualTreesD.res deleted file mode 100644 index 743599575b02e97248bade49ed2e3eabafe25a0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmZQzU|>)H;{X347|28cOhBFu5dZ(r#Sp;Y!{Epe!r;c>&k)4m3uHM0X?F%!AS)QE O%YcEC1!e#vkO2UW7YiT& diff --git a/Packages/RAD Studio XE5/VirtualTreesR.cpp b/Packages/RAD Studio XE5/VirtualTreesR.cpp deleted file mode 100644 index 37aacb55..00000000 --- a/Packages/RAD Studio XE5/VirtualTreesR.cpp +++ /dev/null @@ -1,17 +0,0 @@ -//--------------------------------------------------------------------------- - -#include -#pragma hdrstop -#pragma package(smart_init) -//--------------------------------------------------------------------------- - -// Package source. -//--------------------------------------------------------------------------- - - -#pragma argsused -int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) -{ - return 1; -} -//--------------------------------------------------------------------------- diff --git a/Packages/RAD Studio XE5/VirtualTreesR.dpk b/Packages/RAD Studio XE5/VirtualTreesR.dpk deleted file mode 100644 index 1759b9a9..00000000 --- a/Packages/RAD Studio XE5/VirtualTreesR.dpk +++ /dev/null @@ -1,57 +0,0 @@ -package VirtualTreesR; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$LIBSUFFIX '19'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -requires - vcl, - vclx; - -contains - VirtualTrees in '..\..\Source\VirtualTrees.pas', - VirtualTrees.HeaderPopup in '..\..\Source\VirtualTrees.HeaderPopup.pas', - VirtualTrees.AccessibilityFactory in '..\..\Source\VirtualTrees.AccessibilityFactory.pas', - VirtualTrees.Accessibility in '..\..\Source\VirtualTrees.Accessibility.pas', - VirtualTrees.StyleHooks in '..\..\Source\VirtualTrees.StyleHooks.pas', - VirtualTrees.Classes in '..\..\Source\VirtualTrees.Classes.pas', - VirtualTrees.WorkerThread in '..\..\Source\VirtualTrees.WorkerThread.pas', - VirtualTrees.ClipBoard in '..\..\Source\VirtualTrees.ClipBoard.pas', - VirtualTrees.Actions in '..\..\Source\VirtualTrees.Actions.pas', - VirtualTrees.Export in '..\..\Source\VirtualTrees.Export.pas', - VirtualTrees.Utils in '..\..\Source\VirtualTrees.Utils.pas', - VirtualTrees.Types in '..\..\Source\VirtualTrees.Types.pas', - VirtualTrees.Header in '..\..\Source\VirtualTrees.Header.pas', - VirtualTrees.DataObject in '..\..\Source\VirtualTrees.DataObject.pas', - VirtualTrees.DragnDrop in '..\..\Source\VirtualTrees.DragnDrop.pas', - VirtualTrees.DragImage in '..\..\Source\VirtualTrees.DragImage.pas', - VirtualTrees.EditLink in '..\..\Source\VirtualTrees.EditLink.pas', - VirtualTrees.Colors in '..\..\Source\VirtualTrees.Colors.pas', - VirtualTrees.DrawTree in '..\..\Source\VirtualTrees.DrawTree.pas'; - -end. diff --git a/Packages/RAD Studio XE5/VirtualTreesR.dproj b/Packages/RAD Studio XE5/VirtualTreesR.dproj deleted file mode 100644 index 9727f69d..00000000 --- a/Packages/RAD Studio XE5/VirtualTreesR.dproj +++ /dev/null @@ -1,194 +0,0 @@ - - - {B62F3689-96E1-47D5-9FB2-2A2718281FDB} - VirtualTreesR.dpk - True - Debug - Package - VCL - DCC32 - 15.0 - Win32 - 3 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - .\$(Platform)\$(Config) - ..\..\Source - true - 19 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Debug - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal; - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - - - $(BDSCOMMONDIR)\DCP\$(Platform) - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - true - 1033 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - false - true - - - true - - - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesR.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder-Package für Office 2000-Server - Embarcadero C++Builder-Package für Office XP-Server - Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver - Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server - - - - False - False - False - True - True - - - 12 - - - - diff --git a/Packages/RAD Studio XE5/VirtualTreesR.res b/Packages/RAD Studio XE5/VirtualTreesR.res deleted file mode 100644 index 0e9e906fe457be266d93d16c8090c2f0c53f7ce7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61540 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�uzSd2!V%dzk#U+zRp*8Qt> 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 E210a*O#lD@ diff --git a/Packages/RAD Studio XE6/VirtualTreeView.groupproj b/Packages/RAD Studio XE6/VirtualTreeView.groupproj deleted file mode 100644 index 980342db..00000000 --- a/Packages/RAD Studio XE6/VirtualTreeView.groupproj +++ /dev/null @@ -1,48 +0,0 @@ - - - {CC6A9541-DD5C-4BCD-8914-016D8D2EAB3B} - - - - - - - VirtualTreesR.dproj - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Packages/RAD Studio XE6/VirtualTreesD.dpk b/Packages/RAD Studio XE6/VirtualTreesD.dpk deleted file mode 100644 index 410bd5fc..00000000 --- a/Packages/RAD Studio XE6/VirtualTreesD.dpk +++ /dev/null @@ -1,42 +0,0 @@ -package VirtualTreesD; - -{$R *.res} -{$R '..\..\Design\VirtualTrees.dcr'} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'VirtualTreeView Controls'} -{$LIBSUFFIX '20'} -{$DESIGNONLY} -{$IMPLICITBUILD OFF} - -requires - DesignIDE, - VirtualTreesR; - -contains - VirtualTreesReg in '..\..\Design\VirtualTreesReg.pas'; - -end. - diff --git a/Packages/RAD Studio XE6/VirtualTreesD.dproj b/Packages/RAD Studio XE6/VirtualTreesD.dproj deleted file mode 100644 index e019f8a6..00000000 --- a/Packages/RAD Studio XE6/VirtualTreesD.dproj +++ /dev/null @@ -1,138 +0,0 @@ - - - {A34BA07B-19B6-4C21-9DEE-65FCA52D00AB} - VirtualTreesD.dpk - True - Debug - Package - VCL - DCC32 - 15.4 - Win32 - 1 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - ..\..\Source - .\$(Platform)\$(Config) - true - VirtualTreeView Controls - All - 20 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - vcl;VirtualTreesR;$(DCC_UsePackage) - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - false - true - - - - MainSource - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesD.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder-Package für Office 2000-Server - Embarcadero C++Builder-Package für Office XP-Server - Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver - Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server - - - - True - - - 12 - - - - diff --git a/Packages/RAD Studio XE6/VirtualTreesR.dpk b/Packages/RAD Studio XE6/VirtualTreesR.dpk deleted file mode 100644 index f1ee64ae..00000000 --- a/Packages/RAD Studio XE6/VirtualTreesR.dpk +++ /dev/null @@ -1,57 +0,0 @@ -package VirtualTreesR; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$LIBSUFFIX '20'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -requires - vcl, - vclx; - -contains - VirtualTrees in '..\..\Source\VirtualTrees.pas', - VirtualTrees.HeaderPopup in '..\..\Source\VirtualTrees.HeaderPopup.pas', - VirtualTrees.AccessibilityFactory in '..\..\Source\VirtualTrees.AccessibilityFactory.pas', - VirtualTrees.Accessibility in '..\..\Source\VirtualTrees.Accessibility.pas', - VirtualTrees.StyleHooks in '..\..\Source\VirtualTrees.StyleHooks.pas', - VirtualTrees.Classes in '..\..\Source\VirtualTrees.Classes.pas', - VirtualTrees.WorkerThread in '..\..\Source\VirtualTrees.WorkerThread.pas', - VirtualTrees.ClipBoard in '..\..\Source\VirtualTrees.ClipBoard.pas', - VirtualTrees.Actions in '..\..\Source\VirtualTrees.Actions.pas', - VirtualTrees.Export in '..\..\Source\VirtualTrees.Export.pas', - VirtualTrees.Utils in '..\..\Source\VirtualTrees.Utils.pas', - VirtualTrees.Types in '..\..\Source\VirtualTrees.Types.pas', - VirtualTrees.Header in '..\..\Source\VirtualTrees.Header.pas', - VirtualTrees.DataObject in '..\..\Source\VirtualTrees.DataObject.pas', - VirtualTrees.DragnDrop in '..\..\Source\VirtualTrees.DragnDrop.pas', - VirtualTrees.DragImage in '..\..\Source\VirtualTrees.DragImage.pas', - VirtualTrees.EditLink in '..\..\Source\VirtualTrees.EditLink.pas', - VirtualTrees.Colors in '..\..\Source\VirtualTrees.Colors.pas', - VirtualTrees.DrawTree in '..\..\Source\VirtualTrees.DrawTree.pas'; - -end. diff --git a/Packages/RAD Studio XE6/VirtualTreesR.dproj b/Packages/RAD Studio XE6/VirtualTreesR.dproj deleted file mode 100644 index 458ac90d..00000000 --- a/Packages/RAD Studio XE6/VirtualTreesR.dproj +++ /dev/null @@ -1,194 +0,0 @@ - - - {B62F3689-96E1-47D5-9FB2-2A2718281FDB} - VirtualTreesR.dpk - True - Debug - Package - VCL - DCC32 - 15.4 - Win32 - 3 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - .\$(Platform)\$(Config) - ..\..\Source - true - 20 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Debug - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal; - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - - - $(BDSCOMMONDIR)\DCP\$(Platform) - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - true - 1033 - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - false - true - - - true - - - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesR.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder-Package für Office 2000-Server - Embarcadero C++Builder-Package für Office XP-Server - Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver - Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server - - - - False - False - False - True - True - - - 12 - - - - diff --git a/Packages/RAD Studio XE7/VirtualTreeView.groupproj b/Packages/RAD Studio XE7/VirtualTreeView.groupproj deleted file mode 100644 index 980342db..00000000 --- a/Packages/RAD Studio XE7/VirtualTreeView.groupproj +++ /dev/null @@ -1,48 +0,0 @@ - - - {CC6A9541-DD5C-4BCD-8914-016D8D2EAB3B} - - - - - - - VirtualTreesR.dproj - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Packages/RAD Studio XE7/VirtualTreesD.dpk b/Packages/RAD Studio XE7/VirtualTreesD.dpk deleted file mode 100644 index 96449665..00000000 --- a/Packages/RAD Studio XE7/VirtualTreesD.dpk +++ /dev/null @@ -1,42 +0,0 @@ -package VirtualTreesD; - -{$R *.res} -{$R '..\..\Design\VirtualTrees.dcr'} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS OFF} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO OFF} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE RELEASE} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'VirtualTreeView Controls'} -{$LIBSUFFIX '21'} -{$DESIGNONLY} -{$IMPLICITBUILD OFF} - -requires - DesignIDE, - VirtualTreesR; - -contains - VirtualTreesReg in '..\..\Design\VirtualTreesReg.pas'; - -end. - diff --git a/Packages/RAD Studio XE7/VirtualTreesD.dproj b/Packages/RAD Studio XE7/VirtualTreesD.dproj deleted file mode 100644 index 722f10d8..00000000 --- a/Packages/RAD Studio XE7/VirtualTreesD.dproj +++ /dev/null @@ -1,139 +0,0 @@ - - - {A34BA07B-19B6-4C21-9DEE-65FCA52D00AB} - VirtualTreesD.dpk - True - Release - Package - VCL - DCC32 - 17.2 - Win32 - 1 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - VirtualTreesD - ..\..\Source - .\$(Platform)\$(Config) - true - VirtualTreeView Controls - All - 21 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - vcl;VirtualTreesR;$(DCC_UsePackage) - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - false - true - - - - MainSource - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesD.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder-Package für Office 2000-Server - Embarcadero C++Builder-Package für Office XP-Server - Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver - Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server - - - - True - - - 12 - - - - diff --git a/Packages/RAD Studio XE7/VirtualTreesR.dpk b/Packages/RAD Studio XE7/VirtualTreesR.dpk deleted file mode 100644 index 59efbdac..00000000 --- a/Packages/RAD Studio XE7/VirtualTreesR.dpk +++ /dev/null @@ -1,57 +0,0 @@ -package VirtualTreesR; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS OFF} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO OFF} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE RELEASE} -{$ENDIF IMPLICITBUILDING} -{$LIBSUFFIX '21'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -requires - vcl, - vclx; - -contains - VirtualTrees in '..\..\Source\VirtualTrees.pas', - VirtualTrees.HeaderPopup in '..\..\Source\VirtualTrees.HeaderPopup.pas', - VirtualTrees.AccessibilityFactory in '..\..\Source\VirtualTrees.AccessibilityFactory.pas', - VirtualTrees.Accessibility in '..\..\Source\VirtualTrees.Accessibility.pas', - VirtualTrees.StyleHooks in '..\..\Source\VirtualTrees.StyleHooks.pas', - VirtualTrees.Classes in '..\..\Source\VirtualTrees.Classes.pas', - VirtualTrees.WorkerThread in '..\..\Source\VirtualTrees.WorkerThread.pas', - VirtualTrees.ClipBoard in '..\..\Source\VirtualTrees.ClipBoard.pas', - VirtualTrees.Actions in '..\..\Source\VirtualTrees.Actions.pas', - VirtualTrees.Export in '..\..\Source\VirtualTrees.Export.pas', - VirtualTrees.Utils in '..\..\Source\VirtualTrees.Utils.pas', - VirtualTrees.Types in '..\..\Source\VirtualTrees.Types.pas', - VirtualTrees.Header in '..\..\Source\VirtualTrees.Header.pas', - VirtualTrees.DataObject in '..\..\Source\VirtualTrees.DataObject.pas', - VirtualTrees.DragnDrop in '..\..\Source\VirtualTrees.DragnDrop.pas', - VirtualTrees.DragImage in '..\..\Source\VirtualTrees.DragImage.pas', - VirtualTrees.EditLink in '..\..\Source\VirtualTrees.EditLink.pas', - VirtualTrees.Colors in '..\..\Source\VirtualTrees.Colors.pas', - VirtualTrees.DrawTree in '..\..\Source\VirtualTrees.DrawTree.pas'; - -end. diff --git a/Packages/RAD Studio XE7/VirtualTreesR.dproj b/Packages/RAD Studio XE7/VirtualTreesR.dproj deleted file mode 100644 index 62a3894b..00000000 --- a/Packages/RAD Studio XE7/VirtualTreesR.dproj +++ /dev/null @@ -1,498 +0,0 @@ - - - {B62F3689-96E1-47D5-9FB2-2A2718281FDB} - VirtualTreesR.dpk - True - Release - Package - VCL - DCC32 - 17.2 - Win32 - 3 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - All - VirtualTreesR - .\$(Platform)\$(Config) - ..\..\Source - true - 21 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - false - true - - - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesR.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - - - - True - True - - - - - VirtualTreesR.bpl - true - - - - - 1 - .dylib - - - 0 - .bpl - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - - - 1 - - - 1 - - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - res\drawable-normal - 1 - - - - - library\lib\x86 - 1 - - - - - 1 - - - 1 - - - 1 - - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-xlarge - 1 - - - - - res\drawable-xhdpi - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - library\lib\mips - 1 - - - - - res\drawable - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 0 - - - - - res\drawable-small - 1 - - - - - - 1 - - - Contents\MacOS - 0 - - - - - classes - 1 - - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable - 1 - - - - - Contents\Resources - 1 - - - - - - 1 - - - 1 - - - 1 - - - - - library\lib\armeabi-v7a - 1 - - - 1 - - - 0 - - - 1 - - - 1 - - - 1 - - - - - library\lib\armeabi - 1 - - - - - res\drawable-large - 1 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-ldpi - 1 - - - - - res\values - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - - - 1 - - - - - - - - - - - - 12 - - - - - diff --git a/Packages/RAD Studio XE8/VirtualTreeView.groupproj b/Packages/RAD Studio XE8/VirtualTreeView.groupproj deleted file mode 100644 index 980342db..00000000 --- a/Packages/RAD Studio XE8/VirtualTreeView.groupproj +++ /dev/null @@ -1,48 +0,0 @@ - - - {CC6A9541-DD5C-4BCD-8914-016D8D2EAB3B} - - - - - - - VirtualTreesR.dproj - - - - Default.Personality.12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Packages/RAD Studio XE8/VirtualTreesD.dpk b/Packages/RAD Studio XE8/VirtualTreesD.dpk deleted file mode 100644 index e9e263d7..00000000 --- a/Packages/RAD Studio XE8/VirtualTreesD.dpk +++ /dev/null @@ -1,42 +0,0 @@ -package VirtualTreesD; - -{$R *.res} -{$R '..\..\Design\VirtualTrees.dcr'} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS OFF} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO OFF} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE RELEASE} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'VirtualTreeView Controls'} -{$LIBSUFFIX '22'} -{$DESIGNONLY} -{$IMPLICITBUILD OFF} - -requires - DesignIDE, - VirtualTreesR; - -contains - VirtualTreesReg in '..\..\Design\VirtualTreesReg.pas'; - -end. - diff --git a/Packages/RAD Studio XE8/VirtualTreesD.dproj b/Packages/RAD Studio XE8/VirtualTreesD.dproj deleted file mode 100644 index 7b6a313c..00000000 --- a/Packages/RAD Studio XE8/VirtualTreesD.dproj +++ /dev/null @@ -1,139 +0,0 @@ - - - {A34BA07B-19B6-4C21-9DEE-65FCA52D00AB} - VirtualTreesD.dpk - True - Release - Package - VCL - DCC32 - 17.2 - Win32 - 1 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - VirtualTreesD - ..\..\Source - .\$(Platform)\$(Config) - true - VirtualTreeView Controls - All - 22 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - vcl;VirtualTreesR;$(DCC_UsePackage) - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - false - true - - - - MainSource - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesD.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - - - 12 - - - - diff --git a/Packages/RAD Studio XE8/VirtualTreesR.dpk b/Packages/RAD Studio XE8/VirtualTreesR.dpk deleted file mode 100644 index bbacabb5..00000000 --- a/Packages/RAD Studio XE8/VirtualTreesR.dpk +++ /dev/null @@ -1,57 +0,0 @@ -package VirtualTreesR; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS OFF} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO OFF} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE RELEASE} -{$ENDIF IMPLICITBUILDING} -{$LIBSUFFIX '22'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -requires - vcl, - vclx; - -contains - VirtualTrees in '..\..\Source\VirtualTrees.pas', - VirtualTrees.HeaderPopup in '..\..\Source\VirtualTrees.HeaderPopup.pas', - VirtualTrees.AccessibilityFactory in '..\..\Source\VirtualTrees.AccessibilityFactory.pas', - VirtualTrees.Accessibility in '..\..\Source\VirtualTrees.Accessibility.pas', - VirtualTrees.StyleHooks in '..\..\Source\VirtualTrees.StyleHooks.pas', - VirtualTrees.Classes in '..\..\Source\VirtualTrees.Classes.pas', - VirtualTrees.WorkerThread in '..\..\Source\VirtualTrees.WorkerThread.pas', - VirtualTrees.ClipBoard in '..\..\Source\VirtualTrees.ClipBoard.pas', - VirtualTrees.Actions in '..\..\Source\VirtualTrees.Actions.pas', - VirtualTrees.Export in '..\..\Source\VirtualTrees.Export.pas', - VirtualTrees.Utils in '..\..\Source\VirtualTrees.Utils.pas', - VirtualTrees.Types in '..\..\Source\VirtualTrees.Types.pas', - VirtualTrees.Header in '..\..\Source\VirtualTrees.Header.pas', - VirtualTrees.DataObject in '..\..\Source\VirtualTrees.DataObject.pas', - VirtualTrees.DragnDrop in '..\..\Source\VirtualTrees.DragnDrop.pas', - VirtualTrees.DragImage in '..\..\Source\VirtualTrees.DragImage.pas', - VirtualTrees.EditLink in '..\..\Source\VirtualTrees.EditLink.pas', - VirtualTrees.Colors in '..\..\Source\VirtualTrees.Colors.pas', - VirtualTrees.DrawTree in '..\..\Source\VirtualTrees.DrawTree.pas'; - -end. diff --git a/Packages/RAD Studio XE8/VirtualTreesR.dproj b/Packages/RAD Studio XE8/VirtualTreesR.dproj deleted file mode 100644 index 0b4e783f..00000000 --- a/Packages/RAD Studio XE8/VirtualTreesR.dproj +++ /dev/null @@ -1,498 +0,0 @@ - - - {B62F3689-96E1-47D5-9FB2-2A2718281FDB} - VirtualTreesR.dpk - True - Release - Package - VCL - DCC32 - 17.2 - Win32 - 3 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - All - VirtualTreesR - .\$(Platform)\$(Config) - ..\..\Source - true - 22 - true - ..\..\source;.\$(Platform)\$(Config);$(DCC_UnitSearchPath) - System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) - 1053 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - true - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - false - true - - - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - VirtualTreesR.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1053 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - - - - - VirtualTreesR.bpl - true - - - - - 1 - .dylib - - - 0 - .bpl - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - - - 1 - - - 1 - - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - res\drawable-normal - 1 - - - - - library\lib\x86 - 1 - - - - - 1 - - - 1 - - - 1 - - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-xlarge - 1 - - - - - res\drawable-xhdpi - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - library\lib\mips - 1 - - - - - res\drawable - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 0 - - - - - res\drawable-small - 1 - - - - - - 1 - - - Contents\MacOS - 0 - - - - - classes - 1 - - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable - 1 - - - - - Contents\Resources - 1 - - - - - - 1 - - - 1 - - - 1 - - - - - library\lib\armeabi-v7a - 1 - - - 1 - - - 0 - - - 1 - - - 1 - - - 1 - - - - - library\lib\armeabi - 1 - - - - - res\drawable-large - 1 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-ldpi - 1 - - - - - res\values - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - - - 1 - - - - - - - - - - - - 12 - - - - - From d8f63bdd71478bca597fedee3bcd4f9904d779a6 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Thu, 21 Sep 2023 18:12:58 +0200 Subject: [PATCH 05/28] Add alias for reducing breaking changes --- Source/VirtualTrees.pas | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/VirtualTrees.pas b/Source/VirtualTrees.pas index 30614e14..545ea7fe 100644 --- a/Source/VirtualTrees.pas +++ b/Source/VirtualTrees.pas @@ -129,6 +129,7 @@ interface THitPosition = VirtualTrees.Types.THitPosition; TVTPaintOption = VirtualTrees.Types.TVTPaintOption; TVTSelectionOption = VirtualTrees.Types.TVTSelectionOption; + TVstTextType = VirtualTrees.Types.TVstTextType; TBaseVirtualTree = VirtualTrees.BaseTree.TBaseVirtualTree; IVTEditLink = VirtualTrees.BaseTree.IVTEditLink; TVTHeaderNotifyEvent = VirtualTrees.BaseTree.TVTHeaderNotifyEvent; From 5cab5648785512ce8d6efb4efd8bf22b0089f7ef Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Thu, 21 Sep 2023 18:14:19 +0200 Subject: [PATCH 06/28] Issue #1088: Better visualize Fixed columns --- Source/VirtualTrees.BaseTree.pas | 15 +++++++++++++-- Source/VirtualTrees.Types.pas | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index f53b4733..77dd7a73 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -21171,6 +21171,7 @@ procedure TBaseVirtualTree.PaintTree(TargetCanvas: TCanvas; Window: TRect; Targe if UseColumns then begin + ColumnIsFixed := coFixed in FHeader.Columns[Column].Options; // Paint vertical grid line. if (poGridLines in PaintOptions) and (toShowVertGridLines in FOptions.PaintOptions) then begin @@ -21178,7 +21179,6 @@ procedure TBaseVirtualTree.PaintTree(TargetCanvas: TCanvas; Window: TRect; Targe // easier to understand. CellIsTouchingClientRight := PaintInfo.CellRect.Right = ClientRect.Right; CellIsInLastColumn := Position = TColumnPosition(Count - 1); - ColumnIsFixed := coFixed in FHeader.Columns[Column].Options; // Don't draw if this is the last column and the header is in autosize mode. if not ((hoAutoResize in FHeader.Options) and CellIsInLastColumn) then @@ -21202,7 +21202,18 @@ procedure TBaseVirtualTree.PaintTree(TargetCanvas: TCanvas; Window: TRect; Targe // Reduce the content rect size nonetheless to retain correct alignment // relative to header content (especially if "PaintInfo.Alignment = alRightJustify"). Dec(ContentRect.Right); - end; + end// if poGridLines + else + begin + if ColumnIsFixed then + begin + if (BidiMode = bdLeftToRight) or not ColumnIsEmpty(Node, Column) then + begin + DrawGridVLine(PaintInfo, CellRect.Top, CellRect.Bottom, CellRect.Right - 1, ColumnIsFixed and (NextColumn >= 0)); + end; + Dec(CellRect.Right); + end; + end//else end; // Prepare background and focus rect for the current cell. diff --git a/Source/VirtualTrees.Types.pas b/Source/VirtualTrees.Types.pas index 3c8c6a61..be66ae08 100644 --- a/Source/VirtualTrees.Types.pas +++ b/Source/VirtualTrees.Types.pas @@ -772,7 +772,7 @@ TChunkHeader = record end; const - DefaultPaintOptions = [toShowButtons, toShowDropmark, toShowTreeLines, toShowRoot, toThemeAware, toUseBlendedImages]; + DefaultPaintOptions = [toShowButtons, toShowDropmark, toShowTreeLines, toShowRoot, toThemeAware, toUseBlendedImages, toFullVertGridLines]; DefaultAnimationOptions = []; DefaultAutoOptions = [toAutoDropExpand, toAutoTristateTracking, toAutoScrollOnExpand, toAutoDeleteMovedNodes, toAutoChangeScale, toAutoSort, toAutoHideButtons]; DefaultSelectionOptions = [toSelectNextNodeOnRemoval]; From cbad967c10702ad2f1f719de22d01506e3368cd3 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Fri, 22 Sep 2023 09:45:47 +0200 Subject: [PATCH 07/28] Added aliases for increased compatibility with V7 --- Source/VirtualTrees.pas | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/VirtualTrees.pas b/Source/VirtualTrees.pas index 545ea7fe..51e662da 100644 --- a/Source/VirtualTrees.pas +++ b/Source/VirtualTrees.pas @@ -130,9 +130,11 @@ interface TVTPaintOption = VirtualTrees.Types.TVTPaintOption; TVTSelectionOption = VirtualTrees.Types.TVTSelectionOption; TVstTextType = VirtualTrees.Types.TVstTextType; + TVTHintMode = VirtualTrees.Types.TVTHintMode; TBaseVirtualTree = VirtualTrees.BaseTree.TBaseVirtualTree; IVTEditLink = VirtualTrees.BaseTree.IVTEditLink; TVTHeaderNotifyEvent = VirtualTrees.BaseTree.TVTHeaderNotifyEvent; + TVTCompareEvent = VirtualTrees.BaseTree.TVTCompareEvent; TVirtualTreeColumn = VirtualTrees.Header.TVirtualTreeColumn; TVirtualTreeColumns = VirtualTrees.Header.TVirtualTreeColumns; TVTHeader = VirtualTrees.Header.TVTHeader; @@ -165,6 +167,8 @@ interface csCheckedDisabled = VirtualTrees.Types.TCheckState.csCheckedDisabled; csMixedDisable = VirtualTrees.Types.TCheckState.csMixedDisabled; + coVisible = VirtualTrees.Types.TVTColumnOption.coVisible; + type TCustomVirtualStringTree = class; From d1bcddb2087b04fc31d855a0c72cf6687c1454de Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sat, 23 Sep 2023 22:51:34 +0200 Subject: [PATCH 08/28] Create Class inheritance.txt --- Doc/Class inheritance.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Doc/Class inheritance.txt diff --git a/Doc/Class inheritance.txt b/Doc/Class inheritance.txt new file mode 100644 index 00000000..6f080d85 --- /dev/null +++ b/Doc/Class inheritance.txt @@ -0,0 +1,13 @@ +TCustomControl TRectangle Base class of framework + | | +TVTBaseAncestorVcl TVTBaseAncestorFMX + | | +TVTBaseAncestor TVTBaseAncestor + | | +TBaseVirtualTree TBaseVirtualTree + | | +TVTAncestorVcl TVTAncestorFMX + | | +TVTAncestor TVTAncestor alias dependant on platform + | | +TCustomVirtualStringTree TCustomVirtualStringTree final control that is used From 36948a97c8a6b46920dc5d72c3acbc9f275e3fa6 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sun, 24 Sep 2023 11:32:07 +0200 Subject: [PATCH 09/28] Added aliases for increased compatibility with V7 --- Source/VirtualTrees.pas | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/VirtualTrees.pas b/Source/VirtualTrees.pas index 51e662da..01b034e1 100644 --- a/Source/VirtualTrees.pas +++ b/Source/VirtualTrees.pas @@ -128,6 +128,8 @@ interface THitInfo = VirtualTrees.Types.THitInfo; THitPosition = VirtualTrees.Types.THitPosition; TVTPaintOption = VirtualTrees.Types.TVTPaintOption; + TVTAutoOption = VirtualTrees.Types.TVTAutoOption; + TVTAutoOptions = VirtualTrees.Types.TVTAutoOptions; TVTSelectionOption = VirtualTrees.Types.TVTSelectionOption; TVstTextType = VirtualTrees.Types.TVstTextType; TVTHintMode = VirtualTrees.Types.TVTHintMode; @@ -150,7 +152,8 @@ interface InvalidColumn = VirtualTrees.Types.InvalidColumn; sdAscending = VirtualTrees.Types.TSortDirection.sdAscending; sdDescending = VirtualTrees.Types.TSortDirection.sdDescending; - + toAutoSort = VirtualTrees.Types.TVTAutoOption.toAutoSort; + toCheckSupport = VirtualTrees.Types.TVTMiscOption.toCheckSupport; ctNone = VirtualTrees.Types.TCheckType.ctNone; ctTriStateCheckBox = VirtualTrees.Types.TCheckType.ctTriStateCheckBox; ctCheckBox = VirtualTrees.Types.TCheckType.ctCheckBox; @@ -169,6 +172,7 @@ interface coVisible = VirtualTrees.Types.TVTColumnOption.coVisible; + type TCustomVirtualStringTree = class; From 4b3532fbc9a909da47ecbfe0a182e431746188e7 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sun, 24 Sep 2023 12:01:06 +0200 Subject: [PATCH 10/28] Added aliases for increased compatibility with V7 --- Source/VirtualTrees.pas | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/VirtualTrees.pas b/Source/VirtualTrees.pas index 01b034e1..8249dee5 100644 --- a/Source/VirtualTrees.pas +++ b/Source/VirtualTrees.pas @@ -146,14 +146,17 @@ interface TVTFixedAreaConstraints = VirtualTrees.Header.TVTFixedAreaConstraints; TColumnsArray = VirtualTrees.Header.TColumnsArray; TCanvas = Vcl.Graphics.TCanvas; + const - //Aliases + // Aliases for increased compatibility with V7, feel free to extend by pull requests NoColumn = VirtualTrees.Types.NoColumn; InvalidColumn = VirtualTrees.Types.InvalidColumn; sdAscending = VirtualTrees.Types.TSortDirection.sdAscending; sdDescending = VirtualTrees.Types.TSortDirection.sdDescending; toAutoSort = VirtualTrees.Types.TVTAutoOption.toAutoSort; toCheckSupport = VirtualTrees.Types.TVTMiscOption.toCheckSupport; + toEditable = VirtualTrees.Types.TVTMiscOption.toEditable; + toShowRoot = VirtualTrees.Types.TVTPaintOption.toShowRoot; ctNone = VirtualTrees.Types.TCheckType.ctNone; ctTriStateCheckBox = VirtualTrees.Types.TCheckType.ctTriStateCheckBox; ctCheckBox = VirtualTrees.Types.TCheckType.ctCheckBox; @@ -171,7 +174,13 @@ interface csMixedDisable = VirtualTrees.Types.TCheckState.csMixedDisabled; coVisible = VirtualTrees.Types.TVTColumnOption.coVisible; - + vsDisabled = VirtualTrees.Types.TVirtualNodeState.vsDisabled; + etHTML = VirtualTrees.Types.TVTExportType.etHTML; + hiOnItemButton = VirtualTrees.Types.THitPosition.hiOnItemButton; + dmOnNode = VirtualTrees.Types.TDropMode.dmOnNode; + hlbForceMultiLine = VirtualTrees.Types.TVTTooltipLineBreakStyle.hlbForceMultiLine; + hmHintAndDefault = VirtualTrees.Types.TVTHintMode.hmHintAndDefault; + hmTooltip = VirtualTrees.Types.TVTHintMode.hmTooltip; type TCustomVirtualStringTree = class; From c4349b39c6f387af8127dc9d8c48f9f9a045d2a2 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sun, 24 Sep 2023 12:17:03 +0200 Subject: [PATCH 11/28] Moved Accessible stuff from class TVTAncestorVcl to base class TVTBaseAncestorVcl --- Source/VirtualTrees.AccessibilityFactory.pas | 24 +++-- Source/VirtualTrees.AncestorFMX.pas | 15 ++- Source/VirtualTrees.AncestorVcl.pas | 103 ------------------- Source/VirtualTrees.BaseAncestorFMX.pas | 4 +- Source/VirtualTrees.BaseAncestorVcl.pas | 54 +++++++++- Source/VirtualTrees.BaseTree.pas | 15 ++- 6 files changed, 93 insertions(+), 122 deletions(-) diff --git a/Source/VirtualTrees.AccessibilityFactory.pas b/Source/VirtualTrees.AccessibilityFactory.pas index 524ea1f1..d478fdaa 100644 --- a/Source/VirtualTrees.AccessibilityFactory.pas +++ b/Source/VirtualTrees.AccessibilityFactory.pas @@ -39,6 +39,7 @@ interface uses Winapi.oleacc, System.Classes, + Vcl.Controls, VirtualTrees.BaseTree; type @@ -57,13 +58,13 @@ TVTAccessibilityFactory = class(TObject) public constructor Create; destructor Destroy; override; - function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible; + function CreateIAccessible(ATree: TCustomControl): IAccessible; class function GetAccessibilityFactory: TVTAccessibilityFactory; static; procedure RegisterAccessibleProvider(const AProvider: IVTAccessibleProvider); procedure UnRegisterAccessibleProvider(const AProvider: IVTAccessibleProvider); end; - + implementation { TVTAccessibilityFactory } @@ -75,11 +76,11 @@ constructor TVTAccessibilityFactory.Create; FAccessibleProviders.Clear; end; -function TVTAccessibilityFactory.CreateIAccessible( - ATree: TBaseVirtualTree): IAccessible; +function TVTAccessibilityFactory.CreateIAccessible(ATree: TCustomControl): IAccessible; var I: Integer; TmpIAccessible: IAccessible; + lTree: TBaseVirtualTree; // returns an IAccessible. // 1. If the Accessible property of the passed-in tree is nil, // the first registered element will be returned. @@ -91,23 +92,24 @@ function TVTAccessibilityFactory.CreateIAccessible( // The index for these should all be greater than 0, e g the IAccessible for the tree itself should always be registered first, then any IAccessible items. begin Result := nil; - if ATree <> nil then + lTree := (ATree as TBaseVirtualTree); + if lTree <> nil then begin - if ATree.Accessible = nil then + if lTree.Accessible = nil then begin if FAccessibleProviders.Count > 0 then begin - Result := IVTAccessibleProvider(FAccessibleProviders.Items[0]).CreateIAccessible(ATree); + Result := IVTAccessibleProvider(FAccessibleProviders.Items[0]).CreateIAccessible(lTree); Exit; end; end; - if ATree.AccessibleItem = nil then + if lTree.AccessibleItem = nil then begin if FAccessibleProviders.Count > 0 then begin for I := FAccessibleProviders.Count - 1 downto 1 do begin - TmpIAccessible := IVTAccessibleProvider(FAccessibleProviders.Items[I]).CreateIAccessible(ATree); + TmpIAccessible := IVTAccessibleProvider(FAccessibleProviders.Items[I]).CreateIAccessible(lTree); if TmpIAccessible <> nil then begin Result := TmpIAccessible; @@ -116,12 +118,12 @@ function TVTAccessibilityFactory.CreateIAccessible( end; if TmpIAccessible = nil then begin - Result := IVTAccessibleProvider(FAccessibleProviders.Items[0]).CreateIAccessible(ATree); + Result := IVTAccessibleProvider(FAccessibleProviders.Items[0]).CreateIAccessible(lTree); end; end; end else - Result := ATree.AccessibleItem; + Result := lTree.AccessibleItem; end; end; diff --git a/Source/VirtualTrees.AncestorFMX.pas b/Source/VirtualTrees.AncestorFMX.pas index fc5c0fce..2f5f593a 100644 --- a/Source/VirtualTrees.AncestorFMX.pas +++ b/Source/VirtualTrees.AncestorFMX.pas @@ -11,7 +11,12 @@ {****************************************************************************************************************} interface -uses VirtualTrees.BaseTree; + +uses + VirtualTrees.BaseTree; + +const + EVENT_OBJECT_STATECHANGE = $800A; type TVTAncestorFMX = class abstract(TBaseVirtualTree) @@ -24,8 +29,9 @@ TVTAncestorFMX = class abstract(TBaseVirtualTree) function GetClientHeight: Single; override; function GetClientWidth: Single; override; - function GetClientRect: TRect; override; + function GetClientRect: TRect; override; + procedure NotifyAccessibleEvent(pEvent: Uint32 = EVENT_OBJECT_STATECHANGE); virtual; //TODO: CopyCutPaste - need to be implemented { function PasteFromClipboard(): Boolean; override; @@ -120,6 +126,11 @@ procedure TVTAncestorFMX.MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled:= M.Result<>0; end; +procedure TVTAncestorFMX.NotifyAccessibleEvent(pEvent: Uint32); +begin + // Currently empty by intention as highly platfrom depedant +end; + //---------------------------------------------------------------------------------------------------------------------- function TVTAncestorFMX.PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; diff --git a/Source/VirtualTrees.AncestorVcl.pas b/Source/VirtualTrees.AncestorVcl.pas index bb1f9fd8..1bf47be8 100644 --- a/Source/VirtualTrees.AncestorVcl.pas +++ b/Source/VirtualTrees.AncestorVcl.pas @@ -16,7 +16,6 @@ interface Winapi.Windows, Winapi.oleacc, Winapi.ActiveX, - Winapi.Messages, VirtualTrees.Types, VirtualTrees.BaseTree; @@ -28,19 +27,12 @@ TVTAncestorVcl = class abstract(TBaseVirtualTree) private FOnRenderOLEData: TVTRenderOLEDataEvent; // application/descendant defined clipboard formats - procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT; protected function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; override; function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; override; - procedure DoChecked(Node: PVirtualNode); override; - procedure DoExpanded(Node: PVirtualNode); override; - procedure DoFocusChange(Node: PVirtualNode; Column: TColumnIndex); override; - procedure MainColumnChanged; override; - procedure NotifyAccessibilityCollapsed(); override; property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData; public //methods - destructor Destroy; override; function PasteFromClipboard(): Boolean; override; procedure CopyToClipboard(); override; procedure CutToClipboard(); override; @@ -51,7 +43,6 @@ implementation System.Classes, Vcl.AxCtrls, VirtualTrees.ClipBoard, - VirtualTrees.AccessibilityFactory, VirtualTrees.DataObject; resourcestring @@ -156,60 +147,6 @@ function TVTAncestorVcl.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: //---------------------------------------------------------------------------------------------------------------------- -destructor TVTAncestorVcl.Destroy; -begin - // Disconnect all remote MSAA connections - if Assigned(AccessibleItem) then begin - CoDisconnectObject(AccessibleItem, 0); - AccessibleItem := nil; - end; - if Assigned(Accessible) then begin - CoDisconnectObject(Accessible, 0); - Accessible := nil; - end; - - inherited; -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTAncestorVcl.DoChecked(Node: PVirtualNode); -begin - inherited; - - if Assigned(AccessibleItem) and (Self.UpdateCount = 0) then // See issue #1174 - NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTAncestorVcl.DoExpanded(Node: PVirtualNode); -begin - inherited; - - if Assigned(AccessibleItem) and (Self.UpdateCount = 0) then // See issue #1174 - NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTAncestorVcl.DoFocusChange(Node: PVirtualNode; Column: TColumnIndex); -begin - inherited; - - if Assigned(AccessibleItem) then - begin - NotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); - NotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); - NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); - NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); - NotifyWinEvent(EVENT_OBJECT_SELECTION, Handle, OBJID_CLIENT, CHILDID_SELF); - NotifyWinEvent(EVENT_OBJECT_FOCUS, Handle, OBJID_CLIENT, CHILDID_SELF); - end; -end; - -//---------------------------------------------------------------------------------------------------------------------- - function TVTAncestorVcl.DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; begin @@ -220,46 +157,6 @@ function TVTAncestorVcl.DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Mediu //---------------------------------------------------------------------------------------------------------------------- -procedure TVTAncestorVcl.MainColumnChanged; -begin - inherited; - - if Assigned(AccessibleItem) then - NotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTAncestorVcl.NotifyAccessibilityCollapsed; -begin - inherited; - - if Assigned(AccessibleItem) then // See issue #1174 then - NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF); -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTAncestorVcl.WMGetObject(var Message: TMessage); - -begin - if TVTAccessibilityFactory.GetAccessibilityFactory <> nil then - begin - // Create the IAccessibles for the tree view and tree view items, if necessary. - if Accessible = nil then - Accessible := TVTAccessibilityFactory.GetAccessibilityFactory.CreateIAccessible(Self); - if AccessibleItem = nil then - AccessibleItem := TVTAccessibilityFactory.GetAccessibilityFactory.CreateIAccessible(Self); - if Cardinal(Message.LParam) = OBJID_CLIENT then - if Assigned(Accessible) then - Message.Result := LresultFromObject(IID_IAccessible, Message.WParam, Accessible) - else - Message.Result := 0; - end; -end; - -//---------------------------------------------------------------------------------------------------------------------- - function TVTAncestorVcl.PasteFromClipboard(): Boolean; // Reads what is currently on the clipboard into the tree (if the format is supported). diff --git a/Source/VirtualTrees.BaseAncestorFMX.pas b/Source/VirtualTrees.BaseAncestorFMX.pas index cc3e5299..eb40fefc 100644 --- a/Source/VirtualTrees.BaseAncestorFMX.pas +++ b/Source/VirtualTrees.BaseAncestorFMX.pas @@ -369,7 +369,7 @@ procedure TVTBaseAncestorFMX.Invalidate(); //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorVcl.InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL; +function TVTBaseAncestorFMX.InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL; begin Repaint; Result:= true; @@ -377,7 +377,7 @@ function TVTBaseAncestorVcl.InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL; //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorVcl.UpdateWindow(): BOOL; +function TVTBaseAncestorFMX.UpdateWindow(): BOOL; begin Repaint; Result:= true; diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index a00b930e..8ba163ab 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -15,6 +15,7 @@ interface Winapi.Windows, Winapi.oleacc, Winapi.ActiveX, + Winapi.Messages, Vcl.Controls, Vcl.Graphics, Vcl.StdCtrls, @@ -30,15 +31,17 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) FDottedBrushTreeLines: TBrush; // used to paint dotted lines without special pens function GetDottedBrushGridLines: TBrush; + procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT; protected // methods function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; virtual; abstract; function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; virtual; abstract; - procedure NotifyAccessibilityCollapsed(); virtual; abstract; + procedure NotifyAccessibleEvent(pEvent: DWord = EVENT_OBJECT_STATECHANGE); function PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; virtual; protected //properties property DottedBrushTreeLines: TBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; property DottedBrushGridLines: TBrush read GetDottedBrushGridLines; public // methods + destructor Destroy; override; procedure CopyToClipboard; virtual; abstract; procedure CutToClipboard; virtual; abstract; function PasteFromClipboard: Boolean; virtual; abstract; @@ -92,9 +95,29 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) end; implementation -uses Winapi.Messages; + +uses + VirtualTrees.AccessibilityFactory; //---------------------------------------------------------------------------------------------------------------------- + +destructor TVTBaseAncestorVcl.Destroy; +begin + // Disconnect all remote MSAA connections + if Assigned(AccessibleItem) then begin + CoDisconnectObject(AccessibleItem, 0); + AccessibleItem := nil; + end; + if Assigned(Accessible) then begin + CoDisconnectObject(Accessible, 0); + Accessible := nil; + end; + + inherited; +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TVTBaseAncestorVcl.PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; begin if Assigned(CurrentDottedBrush) then @@ -130,6 +153,12 @@ function TVTBaseAncestorVcl.InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL; Result:= WinApi.Windows.InvalidateRect(Handle, lpRect, bErase); end; +procedure TVTBaseAncestorVcl.NotifyAccessibleEvent(pEvent: DWord = EVENT_OBJECT_STATECHANGE); +begin + if Assigned(AccessibleItem) then + NotifyWinEvent(pEvent, Handle, OBJID_CLIENT, CHILDID_SELF); +end; + //---------------------------------------------------------------------------------------------------------------------- function TVTBaseAncestorVcl.UpdateWindow(): BOOL; @@ -137,6 +166,27 @@ function TVTBaseAncestorVcl.UpdateWindow(): BOOL; Result:= WinApi.Windows.UpdateWindow(Handle); end; +//---------------------------------------------------------------------------------------------------------------------- + +procedure TVTBaseAncestorVcl.WMGetObject(var Message: TMessage); + +begin + if TVTAccessibilityFactory.GetAccessibilityFactory <> nil then + begin + // Create the IAccessibles for the tree view and tree view items, if necessary. + if Accessible = nil then + Accessible := TVTAccessibilityFactory.GetAccessibilityFactory.CreateIAccessible(Self); + if AccessibleItem = nil then + AccessibleItem := TVTAccessibilityFactory.GetAccessibilityFactory.CreateIAccessible(Self); + if Cardinal(Message.LParam) = OBJID_CLIENT then + if Assigned(Accessible) then + Message.Result := LresultFromObject(IID_IAccessible, Message.WParam, Accessible) + else + Message.Result := 0; + end; +end; + + //---------------------------------------------------------------------------------------------------------------------- procedure TVTBaseAncestorVcl.ShowScrollBar(Bar: Integer; AShow: Boolean); diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 77dd7a73..2e977cca 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -10149,6 +10149,8 @@ procedure TBaseVirtualTree.DoChecked(Node: PVirtualNode); begin if Assigned(FOnChecked) then FOnChecked(Self, Node); + if (Self.UpdateCount = 0) then // See issue #1174 + NotifyAccessibleEvent(); end; //---------------------------------------------------------------------------------------------------------------------- @@ -10179,7 +10181,7 @@ procedure TBaseVirtualTree.DoCollapsed(Node: PVirtualNode); FOnCollapsed(Self, Node); if (Self.UpdateCount = 0) then // See issue #1174 - NotifyAccessibilityCollapsed(); + NotifyAccessibleEvent(); if (toAlwaysSelectNode in TreeOptions.SelectionOptions) then begin @@ -10550,6 +10552,8 @@ procedure TBaseVirtualTree.DoExpanded(Node: PVirtualNode); begin if Assigned(FOnExpanded) then FOnExpanded(Self, Node); + if (Self.UpdateCount = 0) then // See issue #1174 + NotifyAccessibleEvent(); end; //---------------------------------------------------------------------------------------------------------------------- @@ -10569,6 +10573,12 @@ procedure TBaseVirtualTree.DoFocusChange(Node: PVirtualNode; Column: TColumnInde begin if Assigned(FOnFocusChanged) then FOnFocusChanged(Self, Node, Column); + NotifyAccessibleEvent(EVENT_OBJECT_LOCATIONCHANGE); + NotifyAccessibleEvent(EVENT_OBJECT_NAMECHANGE); + NotifyAccessibleEvent(EVENT_OBJECT_VALUECHANGE); + NotifyAccessibleEvent(EVENT_OBJECT_STATECHANGE); + NotifyAccessibleEvent(EVENT_OBJECT_SELECTION); + NotifyAccessibleEvent(EVENT_OBJECT_FOCUS); end; //---------------------------------------------------------------------------------------------------------------------- @@ -14116,6 +14126,7 @@ procedure TBaseVirtualTree.MainColumnChanged; begin DoCancelEdit; + NotifyAccessibleEvent(); end; //---------------------------------------------------------------------------------------------------------------------- @@ -17210,7 +17221,7 @@ procedure TBaseVirtualTree.EndUpdate; Invalidate; UpdateDesigner; end; - NotifyAccessibilityCollapsed(); // See issue #1174 + NotifyAccessibleEvent(); // See issue #1174 DoUpdating(usEnd); EnsureNodeSelected(False); From 5812346492ba26e7e9c05077d380cb692f1f9636 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sun, 24 Sep 2023 17:34:46 +0200 Subject: [PATCH 12/28] =?UTF-8?q?Moved=20implementation=20of=20methods=20C?= =?UTF-8?q?opyToClipboard()=20and=20CutToClipboard()=20from=20class=20TVTA?= =?UTF-8?q?ncestorVcl=20to=20base=20class=20TVTBaseAn=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/VirtualTrees.AncestorVcl.pas | 42 +------------------------ Source/VirtualTrees.BaseAncestorFMX.pas | 2 ++ Source/VirtualTrees.BaseAncestorVcl.pas | 42 +++++++++++++++++++++++-- Source/VirtualTrees.BaseTree.pas | 20 ++++++++++-- 4 files changed, 60 insertions(+), 46 deletions(-) diff --git a/Source/VirtualTrees.AncestorVcl.pas b/Source/VirtualTrees.AncestorVcl.pas index 1bf47be8..92438a17 100644 --- a/Source/VirtualTrees.AncestorVcl.pas +++ b/Source/VirtualTrees.AncestorVcl.pas @@ -34,9 +34,7 @@ TVTAncestorVcl = class abstract(TBaseVirtualTree) property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData; public //methods function PasteFromClipboard(): Boolean; override; - procedure CopyToClipboard(); override; - procedure CutToClipboard(); override; - end; + end; implementation uses @@ -190,42 +188,4 @@ function TVTAncestorVcl.PasteFromClipboard(): Boolean; end; end; -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTAncestorVcl.CopyToClipboard(); - -var - lDataObject: IDataObject; - -begin - if SelectedCount > 0 then - begin - lDataObject := TVTDataObject.Create(Self, True); - if OleSetClipboard(lDataObject) = S_OK then - begin - MarkCutCopyNodes; - DoStateChange([tsCopyPending]); - Invalidate; - end; - end; -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTAncestorVcl.CutToClipboard(); -var - lDataObject: IDataObject; -begin - if (SelectedCount > 0) and not (toReadOnly in TreeOptions.MiscOptions) then - begin - lDataObject := TVTDataObject.Create(Self, True); - if OleSetClipboard(lDataObject) = S_OK then - begin - MarkCutCopyNodes; - DoStateChange([tsCutPending], [tsCopyPending]); - Invalidate; - end; - end; -end; - end. diff --git a/Source/VirtualTrees.BaseAncestorFMX.pas b/Source/VirtualTrees.BaseAncestorFMX.pas index eb40fefc..f5af1b41 100644 --- a/Source/VirtualTrees.BaseAncestorFMX.pas +++ b/Source/VirtualTrees.BaseAncestorFMX.pas @@ -63,6 +63,8 @@ TVTBaseAncestorFMX = class abstract(TRectangle) procedure ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); virtual; abstract; function GetControlsAlignment: TAlignment; virtual; abstract; function PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; virtual; abstract; + function GetSelectedCount(): Integer; virtual; abstract; + procedure MarkCutCopyNodes; virtual; abstract; protected //properties property DottedBrushTreeLines: TStrokeBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; property DottedBrushGridLines: TStrokeBrush read FDottedBrushGridLines write FDottedBrushGridLines; diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index 8ba163ab..c7f70520 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -37,13 +37,16 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; virtual; abstract; procedure NotifyAccessibleEvent(pEvent: DWord = EVENT_OBJECT_STATECHANGE); function PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; virtual; + function GetSelectedCount(): Integer; virtual; abstract; + procedure MarkCutCopyNodes; virtual; abstract; + procedure DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []); virtual; abstract; protected //properties property DottedBrushTreeLines: TBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; property DottedBrushGridLines: TBrush read GetDottedBrushGridLines; public // methods destructor Destroy; override; - procedure CopyToClipboard; virtual; abstract; - procedure CutToClipboard; virtual; abstract; + procedure CopyToClipboard; virtual; + procedure CutToClipboard(); virtual; function PasteFromClipboard: Boolean; virtual; abstract; ///

@@ -97,10 +100,45 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) implementation uses + VirtualTrees.DataObject, VirtualTrees.AccessibilityFactory; //---------------------------------------------------------------------------------------------------------------------- +procedure TVTBaseAncestorVcl.CopyToClipboard; + +var + lDataObject: IDataObject; + +begin + if GetSelectedCount > 0 then + begin + lDataObject := TVTDataObject.Create(Self, True); + if OleSetClipboard(lDataObject) = S_OK then + begin + MarkCutCopyNodes; + DoStateChange([tsCopyPending]); + Invalidate; + end; + end; +end; + +procedure TVTBaseAncestorVcl.CutToClipboard; +var + lDataObject: IDataObject; +begin + if (GetSelectedCount > 0) then + begin + lDataObject := TVTDataObject.Create(Self, True); + if OleSetClipboard(lDataObject) = S_OK then + begin + MarkCutCopyNodes; + DoStateChange([tsCutPending], [tsCopyPending]); + Invalidate; + end; + end; +end; + destructor TVTBaseAncestorVcl.Destroy; begin // Disconnect all remote MSAA connections diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 2e977cca..482ecd8b 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -463,7 +463,6 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) FVisibleCount: Cardinal; // number of currently visible nodes FStartIndex: Cardinal; // index to start validating cache from FSelection: TNodeArray; // list of currently selected nodes - FSelectionCount: Integer; // number of currently selected nodes (size of FSelection might differ) FSelectionLocked: Boolean; // prevents the tree from changing the selection FRangeAnchor: PVirtualNode; // anchor node for selection with the keyboard, determines start of a // selection range @@ -737,6 +736,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) FOnEndOperation: TVTOperationEvent; // Called when an operation ends FVclStyleEnabled: Boolean; + FSelectionCount: Integer; procedure CMStyleChanged(var Message: TMessage); message CM_STYLECHANGED; procedure CMParentDoubleBufferedChange(var Message: TMessage); message CM_PARENTDOUBLEBUFFEREDCHANGED; @@ -1068,7 +1068,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) procedure DoShowScrollBar(Bar: Integer; Show: Boolean); virtual; procedure DoStartDrag(var DragObject: TDragObject); override; procedure DoStartOperation(OperationKind: TVTOperationKind); virtual; - procedure DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []); virtual; + procedure DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []); override; procedure DoStructureChange(Node: PVirtualNode; Reason: TChangeReason); virtual; procedure DoTimerScroll; virtual; procedure DoUpdating(State: TVTUpdateState); virtual; @@ -1106,6 +1106,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) procedure GetNativeClipboardFormats(var Formats: TFormatEtcArray); virtual; function GetOperationCanceled: Boolean; function GetOptionsClass: TTreeOptionsClass; virtual; + function GetSelectedCount(): Integer; override; function GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree; virtual; procedure HandleHotTrack(X, Y: TDimension); virtual; procedure HandleIncrementalSearch(CharCode: Word); virtual; @@ -1133,7 +1134,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) procedure InvalidateCache; procedure Loaded; override; procedure MainColumnChanged; virtual; - procedure MarkCutCopyNodes; virtual; + procedure MarkCutCopyNodes; override; procedure MouseMove(Shift: TShiftState; X, Y: TDimension); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure OriginalWMNCPaint(DC: HDC); virtual; @@ -1418,6 +1419,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) ChildrenOnly: Boolean): PVirtualNode; overload; function CopyTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean): PVirtualNode; overload; + procedure CutToClipboard(); override; procedure DeleteChildren(Node: PVirtualNode; ResetHasChildren: Boolean = False); procedure DeleteNode(Node: PVirtualNode; pReIndex: Boolean = True); overload; inline; procedure DeleteNodes(const pNodes: TNodeArray); @@ -3972,6 +3974,11 @@ function TBaseVirtualTree.GetSelected(Node: PVirtualNode): Boolean; Result := Assigned(Node) and (vsSelected in Node.States); end; +function TBaseVirtualTree.GetSelectedCount: Integer; +begin + Exit(FSelectionCount); +end; + function TBaseVirtualTree.GetSelectedData: TArray; var lItem: PVirtualNode; @@ -19812,6 +19819,13 @@ function TBaseVirtualTree.CutCopyNodes(ConsiderChildrenAbove: Boolean): TVTVirtu Result.FConsiderChildrenAbove := ConsiderChildrenAbove; end; +procedure TBaseVirtualTree.CutToClipboard; +begin + if (toReadOnly in TreeOptions.MiscOptions) then + exit; + inherited; +end; + //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.InitializedNodes(ConsiderChildrenAbove: Boolean): TVTVirtualNodeEnumeration; From 913fc431409166f04792113f3d9f313b00c610c4 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sun, 24 Sep 2023 17:57:36 +0200 Subject: [PATCH 13/28] Moved implementation of method RenderOLEData() from calss TVTAncestorVcl to TVTBaseAncestorVcl --- Source/VirtualTrees.AncestorVcl.pas | 100 ---------------------- Source/VirtualTrees.BaseAncestorFMX.pas | 4 +- Source/VirtualTrees.BaseAncestorVcl.pas | 105 +++++++++++++++++++++++- Source/VirtualTrees.BaseTree.pas | 6 +- 4 files changed, 110 insertions(+), 105 deletions(-) diff --git a/Source/VirtualTrees.AncestorVcl.pas b/Source/VirtualTrees.AncestorVcl.pas index 92438a17..189d65bd 100644 --- a/Source/VirtualTrees.AncestorVcl.pas +++ b/Source/VirtualTrees.AncestorVcl.pas @@ -29,8 +29,6 @@ TVTAncestorVcl = class abstract(TBaseVirtualTree) protected function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; override; - function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; override; - property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData; public //methods function PasteFromClipboard(): Boolean; override; @@ -48,105 +46,7 @@ implementation //---------------------------------------------------------------------------------------------------------------------- -function TVTAncestorVcl.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; - ForClipboard: Boolean): HResult; - -// Returns a memory expression of all currently selected nodes in the Medium structure. -// Note: The memory requirement of this method might be very high. This depends however on the requested storage format. -// For HGlobal (a global memory block) we need to render first all nodes to local memory and copy this then to -// the global memory in Medium. This is necessary because we have first to determine how much -// memory is needed before we can allocate it. Hence for a short moment we need twice the space as used by the -// nodes alone (plus the amount the nodes need in the tree anyway)! -// With IStream this does not happen. We directly stream out the nodes and pass the constructed stream along. - - //--------------- local function -------------------------------------------- - - procedure WriteNodes(Stream: TStream); - - var - Selection: TNodeArray; - I: Integer; - - begin - if ForClipboard then - Selection := GetSortedCutCopySet(True) - else - Selection := GetSortedSelection(True); - for I := 0 to High(Selection) do - WriteNode(Stream, Selection[I]); - end; - - //--------------- end local function ---------------------------------------- - -var - Data: PCardinal; - ResPointer: Pointer; - ResSize: Integer; - OLEStream: IStream; - VCLStream: TStream; - -begin - ZeroMemory (@Medium, SizeOf(Medium)); - - // We can render the native clipboard format in two different storage media. - if (FormatEtcIn.cfFormat = CF_VIRTUALTREE) and (FormatEtcIn.tymed and (TYMED_HGLOBAL or TYMED_ISTREAM) <> 0) then - begin - VCLStream := nil; - try - Medium.unkForRelease := nil; - // Return data in one of the supported storage formats, prefer IStream. - if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then - begin - // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). - // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal - // back which is not supported by TStreamAdapater). - CreateStreamOnHGlobal(0, True, OLEStream); - VCLStream := TOLEStream.Create(OLEStream); - WriteNodes(VCLStream); - // Rewind stream. - VCLStream.Position := 0; - Medium.tymed := TYMED_ISTREAM; - IUnknown(Medium.stm) := OLEStream; - Result := S_OK; - end - else - begin - VCLStream := TMemoryStream.Create; - WriteNodes(VCLStream); - ResPointer := TMemoryStream(VCLStream).Memory; - ResSize := VCLStream.Position; - - // Allocate memory to hold the string. - if ResSize > 0 then - begin - Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); - Data := GlobalLock(Medium.hGlobal); - // Store the size of the data too, for easy retrival. - Data^ := ResSize; - Inc(Data); - Move(ResPointer^, Data^, ResSize); - GlobalUnlock(Medium.hGlobal); - Medium.tymed := TYMED_HGLOBAL; - - Result := S_OK; - end - else - Result := E_FAIL; - end; - finally - // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around - // the OLEStream which exists independently. - VCLStream.Free; - end; - end - else // Ask application descendants to render self defined formats. - Result := DoRenderOLEData(FormatEtcIn, Medium, ForClipboard); -end; - -//---------------------------------------------------------------------------------------------------------------------- - function TVTAncestorVcl.DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; - begin Result := E_FAIL; if Assigned(FOnRenderOLEData) then diff --git a/Source/VirtualTrees.BaseAncestorFMX.pas b/Source/VirtualTrees.BaseAncestorFMX.pas index f5af1b41..c4fe6c63 100644 --- a/Source/VirtualTrees.BaseAncestorFMX.pas +++ b/Source/VirtualTrees.BaseAncestorFMX.pas @@ -65,7 +65,9 @@ TVTBaseAncestorFMX = class abstract(TRectangle) function PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; virtual; abstract; function GetSelectedCount(): Integer; virtual; abstract; procedure MarkCutCopyNodes; virtual; abstract; - protected //properties + function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; virtual; abstract; + function GetSortedSelection(Resolve: Boolean): TNodeArray; virtual; abstract; + procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; protected //properties property DottedBrushTreeLines: TStrokeBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; property DottedBrushGridLines: TStrokeBrush read FDottedBrushGridLines write FDottedBrushGridLines; public //methods diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index c7f70520..66aa1664 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -16,6 +16,7 @@ interface Winapi.oleacc, Winapi.ActiveX, Winapi.Messages, + System.Classes, Vcl.Controls, Vcl.Graphics, Vcl.StdCtrls, @@ -34,12 +35,16 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT; protected // methods function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; virtual; abstract; - function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; virtual; abstract; + function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; virtual; procedure NotifyAccessibleEvent(pEvent: DWord = EVENT_OBJECT_STATECHANGE); function PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; virtual; + //// Abtract method that are implemented in TBaseVirtualTree, keep in sync with TVTBaseAncestorFMX function GetSelectedCount(): Integer; virtual; abstract; procedure MarkCutCopyNodes; virtual; abstract; procedure DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []); virtual; abstract; + function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; virtual; abstract; + function GetSortedSelection(Resolve: Boolean): TNodeArray; virtual; abstract; + procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; protected //properties property DottedBrushTreeLines: TBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; property DottedBrushGridLines: TBrush read GetDottedBrushGridLines; @@ -100,11 +105,109 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) implementation uses + Vcl.AxCtrls, VirtualTrees.DataObject, + VirtualTrees.Clipboard, VirtualTrees.AccessibilityFactory; //---------------------------------------------------------------------------------------------------------------------- +function TVTBaseAncestorVcl.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; + +// Returns a memory expression of all currently selected nodes in the Medium structure. +// Note: The memory requirement of this method might be very high. This depends however on the requested storage format. +// For HGlobal (a global memory block) we need to render first all nodes to local memory and copy this then to +// the global memory in Medium. This is necessary because we have first to determine how much +// memory is needed before we can allocate it. Hence for a short moment we need twice the space as used by the +// nodes alone (plus the amount the nodes need in the tree anyway)! +// With IStream this does not happen. We directly stream out the nodes and pass the constructed stream along. + + //--------------- local function -------------------------------------------- + + procedure WriteNodes(Stream: TStream); + + var + Selection: TNodeArray; + I: Integer; + + begin + if ForClipboard then + Selection := GetSortedCutCopySet(True) + else + Selection := GetSortedSelection(True); + for I := 0 to High(Selection) do + WriteNode(Stream, Selection[I]); + end; + + //--------------- end local function ---------------------------------------- + +var + Data: PCardinal; + ResPointer: Pointer; + ResSize: Integer; + OLEStream: IStream; + VCLStream: TStream; + +begin + ZeroMemory (@Medium, SizeOf(Medium)); + + // We can render the native clipboard format in two different storage media. + if (FormatEtcIn.cfFormat = CF_VIRTUALTREE) and (FormatEtcIn.tymed and (TYMED_HGLOBAL or TYMED_ISTREAM) <> 0) then + begin + VCLStream := nil; + try + Medium.unkForRelease := nil; + // Return data in one of the supported storage formats, prefer IStream. + if FormatEtcIn.tymed and TYMED_ISTREAM <> 0 then + begin + // Create an IStream on a memory handle (here it is 0 which indicates to implicitely allocated a handle). + // Do not use TStreamAdapter as it is not compatible with OLE (when flushing the clipboard OLE wants the HGlobal + // back which is not supported by TStreamAdapater). + CreateStreamOnHGlobal(0, True, OLEStream); + VCLStream := TOLEStream.Create(OLEStream); + WriteNodes(VCLStream); + // Rewind stream. + VCLStream.Position := 0; + Medium.tymed := TYMED_ISTREAM; + IUnknown(Medium.stm) := OLEStream; + Result := S_OK; + end + else + begin + VCLStream := TMemoryStream.Create; + WriteNodes(VCLStream); + ResPointer := TMemoryStream(VCLStream).Memory; + ResSize := VCLStream.Position; + + // Allocate memory to hold the string. + if ResSize > 0 then + begin + Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, ResSize + SizeOf(Cardinal)); + Data := GlobalLock(Medium.hGlobal); + // Store the size of the data too, for easy retrival. + Data^ := ResSize; + Inc(Data); + Move(ResPointer^, Data^, ResSize); + GlobalUnlock(Medium.hGlobal); + Medium.tymed := TYMED_HGLOBAL; + + Result := S_OK; + end + else + Result := E_FAIL; + end; + finally + // We can free the VCL stream here since it was either a pure memory stream or only a wrapper around + // the OLEStream which exists independently. + VCLStream.Free; + end; + end + else // Ask application descendants to render self defined formats. + Result := DoRenderOLEData(FormatEtcIn, Medium, ForClipboard); +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TVTBaseAncestorVcl.CopyToClipboard; var diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 482ecd8b..6b48564f 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -1184,7 +1184,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) procedure ValidateNodeDataSize(var Size: Integer); virtual; procedure WndProc(var Message: TMessage); override; procedure WriteChunks(Stream: TStream; Node: PVirtualNode); virtual; - procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; + procedure WriteNode(Stream: TStream; Node: PVirtualNode); override; class procedure RaiseVTError(const Msg: string; HelpContext: Integer); static; procedure VclStyleChanged; virtual; @@ -1514,8 +1514,8 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) function GetPreviousVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode; function GetPreviousVisibleSibling(Node: PVirtualNode; IncludeFiltered: Boolean = False): PVirtualNode; function GetPreviousVisibleSiblingNoInit(Node: PVirtualNode; IncludeFiltered: Boolean = False): PVirtualNode; - function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; - function GetSortedSelection(Resolve: Boolean): TNodeArray; + function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; override; + function GetSortedSelection(Resolve: Boolean): TNodeArray; override; procedure GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect; var Text: string); virtual; function GetTreeRect: TRect; From 8a5bdfb9f259d92ba324e6a94f1a053af825aa99 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Wed, 27 Sep 2023 18:09:38 +0200 Subject: [PATCH 14/28] Prevent potential range check error in TVirtualTreeColumns.TotalWidth() --- Source/VirtualTrees.BaseTree.pas | 4 ++-- Source/VirtualTrees.Header.pas | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 6b48564f..76d11098 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -10275,8 +10275,8 @@ procedure TBaseVirtualTree.DoColumnResize(Column: TColumnIndex); Exclude(Run.States, vsHeightMeasured); Run := GetNextInitialized(Run); end; - - UpdateHorizontalScrollBar(True); + if Header.Columns.UpdateCount = 0 then + UpdateHorizontalScrollBar(True); if Column > NoColumn then begin // Invalidate client area from the current column all to the right (or left in RTL mode). diff --git a/Source/VirtualTrees.Header.pas b/Source/VirtualTrees.Header.pas index 67dca4ac..3f7bb320 100644 --- a/Source/VirtualTrees.Header.pas +++ b/Source/VirtualTrees.Header.pas @@ -280,6 +280,7 @@ TVirtualTreeColumns = class(TCollection) property Header: TVTHeader read FHeader; property TrackIndex : TColumnIndex read FTrackIndex write FTrackIndex; property TreeView : TCustomControl read GetTreeView; + property UpdateCount; end; TVirtualTreeColumnsClass = class of TVirtualTreeColumns; From c38fc9b12202e09df1f6f71ae8282f25fb9f6a87 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Thu, 5 Oct 2023 12:33:31 +0200 Subject: [PATCH 15/28] Improvements for issue #1088 --- Source/VirtualTrees.BaseTree.pas | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 76d11098..c3f131f3 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -12031,7 +12031,7 @@ procedure TBaseVirtualTree.DrawDottedHLine(const PaintInfo: TVTPaintInfo; Left, begin with PaintInfo do begin - Brush.Color := FColors.BackGroundColor; + DottedBrushTreeLines.Color := FColors.BackGroundColor; R := Rect(Min(Left, Right), Top, Max(Left, Right) + 1, Top + 1); Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, DottedBrushTreeLines.Handle); end; @@ -12057,10 +12057,17 @@ procedure TBaseVirtualTree.DrawGridVLine(const PaintInfo: TVTPaintInfo; Top, Bot R: TRect; begin R := Rect(Left, Min(Top, Bottom), Left + 1, Max(Top, Bottom) + 1); - if pFixedColumn then - StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(ttBranch), R, @R, CurrentPPI) - else - StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenSelectedNotFocused), R, @R, CurrentPPI); + if pFixedColumn and (TVtPaintOption.toShowVertGridLines in TreeOptions.PaintOptions) then // In case we showe grid lines, we must use a color for the fixed column that differentiates from the normal gridlines + StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenHot), R, @R, CurrentPPI) + else begin + if StyleServices.IsSystemStyle then // This approach does not work well for many VCL styles, so we added an else case + StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenSelectedNotFocused), R, @R, CurrentPPI) + else begin + //StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tbGroupBoxNormal), R, @R, CurrentPPI); + Brush.Color := FColors.TreeLineColor; + Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, Brush.Handle); + end; + end;// else end; //---------------------------------------------------------------------------------------------------------------------- From 5b31c3e1210f10944b05198a0e8a6c06fea7fc74 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sat, 14 Oct 2023 09:04:59 +0200 Subject: [PATCH 16/28] Fixed issue #1222: Tree lines not painted --- Doc/Class inheritance.txt | 14 ++++----- Source/VirtualTrees.BaseAncestorVcl.pas | 1 - Source/VirtualTrees.BaseTree.pas | 41 ++++++++++--------------- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/Doc/Class inheritance.txt b/Doc/Class inheritance.txt index 6f080d85..66a1927c 100644 --- a/Doc/Class inheritance.txt +++ b/Doc/Class inheritance.txt @@ -1,13 +1,13 @@ -TCustomControl TRectangle Base class of framework +TCustomControl TRectangle Base class of framework. | | -TVTBaseAncestorVcl TVTBaseAncestorFMX +TVTBaseAncestorVcl TVTBaseAncestorFMX Base class for VCL/FMX that adds some basic platform-specific stuff. | | -TVTBaseAncestor TVTBaseAncestor +TVTBaseAncestor TVTBaseAncestor Alias dependant on platform. | | -TBaseVirtualTree TBaseVirtualTree +TBaseVirtualTree TBaseVirtualTree Base class of Virtual TreeView that that does not include concrete drawing. | | -TVTAncestorVcl TVTAncestorFMX +TVTAncestorVcl TVTAncestorFMX Intermediate class that add platform specififc code which consumes methods of TBaseVirtualTree. | | -TVTAncestor TVTAncestor alias dependant on platform +TVTAncestor TVTAncestor Alias dependant on platform. | | -TCustomVirtualStringTree TCustomVirtualStringTree final control that is used +TCustomVirtualStringTree TCustomVirtualStringTree Final control that is used. diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index 66aa1664..ed0c0d37 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -47,7 +47,6 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; protected //properties property DottedBrushTreeLines: TBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; - property DottedBrushGridLines: TBrush read GetDottedBrushGridLines; public // methods destructor Destroy; override; procedure CopyToClipboard; virtual; diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index c3f131f3..2563b265 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -12029,12 +12029,23 @@ procedure TBaseVirtualTree.DrawDottedHLine(const PaintInfo: TVTPaintInfo; Left, R: TRect; begin - with PaintInfo do - begin - DottedBrushTreeLines.Color := FColors.BackGroundColor; - R := Rect(Min(Left, Right), Top, Max(Left, Right) + 1, Top + 1); - Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, DottedBrushTreeLines.Handle); - end; + R := Rect(Min(Left, Right), Top, Max(Left, Right) + 1, Top + 1); + Brush.Color := FColors.BackGroundColor; + Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, DottedBrushTreeLines.Handle);end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TBaseVirtualTree.DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, Bottom, Left: TDimension); + +// Draws a horizontal line with alternating pixels (this style is not supported for pens under Win9x). + +var + R: TRect; + +begin + R := Rect(Left, Min(Top, Bottom), Left + 1, Max(Top, Bottom) + 1); + Brush.Color := FColors.BackGroundColor; + Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, DottedBrushTreeLines.Handle); end; //---------------------------------------------------------------------------------------------------------------------- @@ -12072,24 +12083,6 @@ procedure TBaseVirtualTree.DrawGridVLine(const PaintInfo: TVTPaintInfo; Top, Bot //---------------------------------------------------------------------------------------------------------------------- -procedure TBaseVirtualTree.DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, Bottom, Left: TDimension); - -// Draws a horizontal line with alternating pixels (this style is not supported for pens under Win9x). - -var - R: TRect; - -begin - R := Rect(Left, Min(Top, Bottom), Left + 1, Max(Top, Bottom) + 1); - with PaintInfo, Canvas do - begin - Brush.Color := FColors.BackGroundColor; - Winapi.Windows.FillRect(Handle, R, DottedBrushTreeLines.Handle); - end; -end; - -//---------------------------------------------------------------------------------------------------------------------- - procedure TBaseVirtualTree.EndOperation(OperationKind: TVTOperationKind); // Called to indicate that a long-running operation has finished. From d28b32f4bada865b5df37447c13e00e8a25c1940 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sat, 14 Oct 2023 10:33:23 +0200 Subject: [PATCH 17/28] Fix for issue #1221: OnHeaderClick Event triggered twice if vclstyle enabled --- Source/VirtualTrees.Header.pas | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/VirtualTrees.Header.pas b/Source/VirtualTrees.Header.pas index 3f7bb320..9e739f1b 100644 --- a/Source/VirtualTrees.Header.pas +++ b/Source/VirtualTrees.Header.pas @@ -1743,11 +1743,12 @@ function TVTHeader.HandleMessage(var Message : TMessage) : Boolean; TBaseVirtualTreeCracker(FOwner).DoHeaderMouseUp(mbLeft, KeysToShiftState(Keys), XPos, YPos); end; WM_NCLBUTTONUP : - with TWMNCLButtonUp(Message) do begin - P := FOwner.ScreenToClient(Point(XCursor, YCursor)); + with TWMNCLButtonUp(Message) do + P := FOwner.ScreenToClient(Point(XCursor, YCursor)); TVirtualTreeColumnsCracker(FColumns).HandleClick(P, mbLeft, True, False); TBaseVirtualTreeCracker(FOwner).DoHeaderMouseUp(mbLeft, GetShiftState, P.X, P.Y + FHeight); + Result := True; end; end; From 8d52ac67d9b83408e1685e08891e729c99835bad Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sun, 15 Oct 2023 09:15:56 +0200 Subject: [PATCH 18/28] Minor cleanups related to issue #1222 --- Source/VirtualTrees.BaseAncestorVcl.pas | 8 -------- Source/VirtualTrees.BaseTree.pas | 13 ++++--------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index ed0c0d37..7164f814 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -31,7 +31,6 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) FAccessibleName: string; // The name the window is given for screen readers. FDottedBrushTreeLines: TBrush; // used to paint dotted lines without special pens - function GetDottedBrushGridLines: TBrush; procedure WMGetObject(var Message: TMessage); message WM_GETOBJECT; protected // methods function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; virtual; abstract; @@ -350,13 +349,6 @@ function TVTBaseAncestorVcl.SetScrollInfo(Bar: Integer; const ScrollInfo: TScrol //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorVcl.GetDottedBrushGridLines: TBrush; -begin - Result:= FDottedBrushTreeLines; -end; - -//---------------------------------------------------------------------------------------------------------------------- - function TVTBaseAncestorVcl.GetScrollInfo(Bar: Integer; var ScrollInfo: TScrollInfo): Boolean; begin Result:= WinApi.Windows.GetScrollInfo(Handle, Bar, ScrollInfo); diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 2563b265..a3f31868 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -12022,26 +12022,21 @@ function TBaseVirtualTree.DragOver(Source: TObject; KeyState: Integer; DragState //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DrawDottedHLine(const PaintInfo: TVTPaintInfo; Left, Right, Top: TDimension); - -// Draws a horizontal line with alternating pixels (this style is not supported for pens under Win9x). - +// Draws a horizontal line with alternating pixels var R: TRect; - begin R := Rect(Min(Left, Right), Top, Max(Left, Right) + 1, Top + 1); Brush.Color := FColors.BackGroundColor; - Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, DottedBrushTreeLines.Handle);end; + Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, DottedBrushTreeLines.Handle); +end; //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, Bottom, Left: TDimension); - -// Draws a horizontal line with alternating pixels (this style is not supported for pens under Win9x). - +// Draws a vertical line with alternating pixels var R: TRect; - begin R := Rect(Left, Min(Top, Bottom), Left + 1, Max(Top, Bottom) + 1); Brush.Color := FColors.BackGroundColor; From 68354c66f1bbbab1a400f6f288b3abbfc1fdf539 Mon Sep 17 00:00:00 2001 From: livius2 Date: Sun, 29 Oct 2023 18:53:26 +0100 Subject: [PATCH 19/28] Incorporate Last Years Changes and fixes to build on FMX I have incorporate last years changes. Patch include multiple fixes, to be able to build on FMX (on my side). Now i am ready to move forward :) --- Source/VirtualTrees.AncestorFMX.pas | 17 ++-- Source/VirtualTrees.BaseAncestorFMX.pas | 20 +++-- Source/VirtualTrees.BaseAncestorVcl.pas | 5 +- Source/VirtualTrees.BaseTree.pas | 78 +++++++++-------- Source/VirtualTrees.Classes.pas | 16 ++-- Source/VirtualTrees.DataObject.pas | 30 +++---- Source/VirtualTrees.DragImage.pas | 11 ++- Source/VirtualTrees.Export.pas | 2 +- Source/VirtualTrees.FMX.pas | 63 ++++++++++++++ Source/VirtualTrees.Header.pas | 108 +++++++++++++----------- Source/VirtualTrees.StyleHooks.pas | 2 - Source/VirtualTrees.Types.pas | 34 ++++++-- Source/VirtualTrees.Utils.pas | 5 ++ Source/VirtualTrees.WorkerThread.pas | 4 + Source/VirtualTrees.pas | 13 +-- 15 files changed, 257 insertions(+), 151 deletions(-) diff --git a/Source/VirtualTrees.AncestorFMX.pas b/Source/VirtualTrees.AncestorFMX.pas index 2f5f593a..3e9b8d1c 100644 --- a/Source/VirtualTrees.AncestorFMX.pas +++ b/Source/VirtualTrees.AncestorFMX.pas @@ -103,19 +103,12 @@ procedure TVTAncestorFMX.MouseUp(Button: TMouseButton; Shift: TShiftState; X: Si procedure TVTAncestorFMX.MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); //wymaga BaseTree Var M: TCMMouseWheel; - hInfo: THitInfo; P: TPoint; - isNC: Boolean; begin P:= Screen.MousePos; - if ClientRect.Contains(P) then - begin - isNc:= false; - end else - begin - isNC:= true; - P:= ClientToScreen(P); - end; + if not ClientRect.Contains(P) then + P:= ClientToScreen(P); + M.Msg:= CM_MOUSEWHEEL; M.ShiftState:= Shift; M.WheelDelta:= WheelDelta; @@ -126,6 +119,8 @@ procedure TVTAncestorFMX.MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled:= M.Result<>0; end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TVTAncestorFMX.NotifyAccessibleEvent(pEvent: Uint32); begin // Currently empty by intention as highly platfrom depedant @@ -210,7 +205,7 @@ function TVTAncestorFMX.GetClientRect: TRect; Result:= ClipRect; if Assigned(Header) then begin - if hoVisible in Header.Options then + if TVTHeaderOption.hoVisible in Header.Options then Inc(Result.Top, Header.Height); end; if FVScrollBar.Visible then diff --git a/Source/VirtualTrees.BaseAncestorFMX.pas b/Source/VirtualTrees.BaseAncestorFMX.pas index c4fe6c63..276e08c3 100644 --- a/Source/VirtualTrees.BaseAncestorFMX.pas +++ b/Source/VirtualTrees.BaseAncestorFMX.pas @@ -25,6 +25,7 @@ TVTBaseAncestorFMX = class abstract(TRectangle) private FDottedBrushTreeLines: TStrokeBrush; // used to paint dotted lines without special pens FDottedBrushGridLines: TStrokeBrush; // used to paint dotted lines without special pens + FInCreate: Boolean; function GetFillColor: TAlphaColor; procedure SetFillColor(const Value: TAlphaColor); @@ -67,7 +68,8 @@ TVTBaseAncestorFMX = class abstract(TRectangle) procedure MarkCutCopyNodes; virtual; abstract; function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; virtual; abstract; function GetSortedSelection(Resolve: Boolean): TNodeArray; virtual; abstract; - procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; protected //properties + procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; + protected //properties property DottedBrushTreeLines: TStrokeBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; property DottedBrushGridLines: TStrokeBrush read FDottedBrushGridLines write FDottedBrushGridLines; public //methods @@ -245,6 +247,7 @@ procedure TVTBaseAncestorFMX.Resize; constructor TVTBaseAncestorFMX.Create(AOwner: TComponent); begin + FInCreate:= true; inherited; FHandleAllocated:= true; @@ -283,6 +286,7 @@ constructor TVTBaseAncestorFMX.Create(AOwner: TComponent); //FVScrollBar.Margins.Bottom:= FVScrollBar.Width; SetAcceptsControls(false); + FInCreate:= false; end; //---------------------------------------------------------------------------------------------------------------------- @@ -373,7 +377,7 @@ procedure TVTBaseAncestorFMX.Invalidate(); //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorFMX.InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL; +function TVTBaseAncestorFMX.InvalidateRect(lpRect: PRect; bErase: Boolean): Boolean; begin Repaint; Result:= true; @@ -381,7 +385,7 @@ function TVTBaseAncestorFMX.InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL; //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorFMX.UpdateWindow(): BOOL; +function TVTBaseAncestorFMX.UpdateWindow(): Boolean; begin Repaint; Result:= true; @@ -389,7 +393,7 @@ function TVTBaseAncestorFMX.UpdateWindow(): BOOL; //---------------------------------------------------------------------------------------------------------------------- -function RedrawWindow(lprcUpdate: PRect; hrgnUpdate: NativeUInt; flags: UINT): BOOL; +function TVTBaseAncestorFMX.RedrawWindow(lprcUpdate: PRect; hrgnUpdate: NativeUInt; flags: UINT): Boolean; begin Repaint; Result:= true; @@ -397,7 +401,7 @@ function RedrawWindow(lprcUpdate: PRect; hrgnUpdate: NativeUInt; flags: UINT): B //---------------------------------------------------------------------------------------------------------------------- -function RedrawWindow(const lprcUpdate: TRect; hrgnUpdate: NativeUInt; flags: UINT): BOOL; +function TVTBaseAncestorFMX.RedrawWindow(const lprcUpdate: TRect; hrgnUpdate: NativeUInt; flags: UINT): Boolean; begin Repaint; Result:= true; @@ -566,7 +570,7 @@ procedure TVTBaseAncestorFMX.SetFont(const Value: TFont); //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorFMX.Focused(): Boolean +function TVTBaseAncestorFMX.Focused(): Boolean; begin Result:= IsFocused; end; @@ -580,7 +584,7 @@ function TVTBaseAncestorFMX.GetParentForm(Control: TControl; TopForm: Boolean = //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorFMX.SendWM_SETREDRAW(Updating: Boolean): NativeUInt; inline; +function TVTBaseAncestorFMX.SendWM_SETREDRAW(Updating: Boolean): NativeUInt; begin Repaint; Result:= 0; @@ -590,7 +594,7 @@ function TVTBaseAncestorFMX.SendWM_SETREDRAW(Updating: Boolean): NativeUInt; inl function TVTBaseAncestorFMX.GetSystemMetrics(nIndex: Integer): Integer; begin - {$IFNDEF MSWINDOWS} + {$IFDEF MSWINDOWS} Result:= GetSystemMetrics(nIndex); {$ELSE} case nIndex of diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index 7164f814..1672a327 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -48,7 +48,7 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) property DottedBrushTreeLines: TBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; public // methods destructor Destroy; override; - procedure CopyToClipboard; virtual; + procedure CopyToClipboard(); virtual; procedure CutToClipboard(); virtual; function PasteFromClipboard: Boolean; virtual; abstract; @@ -292,6 +292,8 @@ function TVTBaseAncestorVcl.InvalidateRect(lpRect: PRect; bErase: BOOL): BOOL; Result:= WinApi.Windows.InvalidateRect(Handle, lpRect, bErase); end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TVTBaseAncestorVcl.NotifyAccessibleEvent(pEvent: DWord = EVENT_OBJECT_STATECHANGE); begin if Assigned(AccessibleItem) then @@ -325,7 +327,6 @@ procedure TVTBaseAncestorVcl.WMGetObject(var Message: TMessage); end; end; - //---------------------------------------------------------------------------------------------------------------------- procedure TVTBaseAncestorVcl.ShowScrollBar(Bar: Integer; AShow: Boolean); diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index a3f31868..5c45bf02 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -1696,6 +1696,10 @@ implementation type + //These allow us access to protected members in the classes + TVirtualTreeColumnsCracker = class(TVirtualTreeColumns); + TVTHeaderCracker = class(TVTHeader); + TVirtualTreeColumnCracker = class(TVirtualTreeColumn); TBaseVirtualTreeCracker = class(TBaseVirtualTree); // streaming support @@ -1739,11 +1743,6 @@ TToggleAnimationData = record TCanvasEx = class(TCanvas); - //These allow us access to protected members in the classes - TVirtualTreeColumnsCracker = class(TVirtualTreeColumns); - TVTHeaderCracker = class(TVTHeader); - TVirtualTreeColumnCracker = class(TVirtualTreeColumn); - const MagicID: TMagicID = (#$2045, 'V', 'T', WideChar(VTTreeStreamVersion), ' ', #$2046); @@ -3227,9 +3226,9 @@ function TBaseVirtualTree.CollectSelectedNodesRTL(MainColumn: Integer; NodeLeft, begin // The initial minimal left border is determined by the identation level of the node and is dynamically adjusted. if toShowRoot in FOptions.PaintOptions then - Dec(NodeRight, (Integer((GetNodeLevel(Run) + 1)) * FIndent) + FMargin) + Dec(NodeRight, (TDimension((GetNodeLevel(Run) + 1)) * FIndent) + FMargin) else - Dec(NodeRight, (Integer(GetNodeLevel(Run)) * FIndent) + FMargin); + Dec(NodeRight, (TDimension(GetNodeLevel(Run)) * FIndent) + FMargin); // ----- main loop // Change selection depending on the node's rectangle being in the selection rectangle or not, but @@ -3881,7 +3880,7 @@ procedure TBaseVirtualTree.GetOffsets(pNode: PVirtualNode; out pOffsets: TVTOffs // Calculates the offset up to the given element and supplies them in an array. var lNodeLevel: Integer; - lNodeIndent: Integer; + lNodeIndent: TDimension; begin // If no specific column was given, assume the main column if pColumn = -1 then @@ -3905,10 +3904,10 @@ procedure TBaseVirtualTree.GetOffsets(pNode: PVirtualNode; out pOffsets: TVTOffs end else lNodeLevel := 1; - lNodeIndent := lNodeLevel * Integer(FIndent); + lNodeIndent := lNodeLevel * TDimension(FIndent); // toggle buttons Inc(pOffsets[TVTElement.ofsToggleButton], lNodeIndent); - Dec(pOffsets[TVTElement.ofsToggleButton], ((Integer(FIndent) - FPlusBM.Width) div 2) - 1 + FPlusBM.Width); //Compare PaintTree() relative line 107 + Dec(pOffsets[TVTElement.ofsToggleButton], Divide((TDimension(FIndent) - FPlusBM.Width), 2) - 1 + FPlusBM.Width); //Compare PaintTree() relative line 107 // checkbox Inc(pOffsets[TVTElement.ofsCheckBox], lNodeIndent); end;//if MainColumn @@ -3974,11 +3973,15 @@ function TBaseVirtualTree.GetSelected(Node: PVirtualNode): Boolean; Result := Assigned(Node) and (vsSelected in Node.States); end; +//---------------------------------------------------------------------------------------------------------------------- + function TBaseVirtualTree.GetSelectedCount: Integer; begin Exit(FSelectionCount); end; +//---------------------------------------------------------------------------------------------------------------------- + function TBaseVirtualTree.GetSelectedData: TArray; var lItem: PVirtualNode; @@ -3991,7 +3994,7 @@ function TBaseVirtualTree.GetSelectedData: TArray; begin Result[i] := Self.GetNodeData(lItem); lItem := Self.GetNextSelected(lItem); - Inc(i); + System.Inc(i); end; SetLength(Result, i); // See issue #927, SelectedCount may not yet be updated. end; @@ -4647,9 +4650,9 @@ procedure TBaseVirtualTree.PrepareBitmaps(NeedButtons, NeedLines: Boolean); begin if FButtonStyle = bsTriangle then begin - Brush.Color := clBlack; - Pen.Color := clBlack; - Polygon([Point(0, 2), Point(8, 2), Point(4, 6)]); + FMinusBM.Canvas.Brush.Color := clBlack; + FMinusBM.Canvas.Pen.Color := clBlack; + FMinusBM.Canvas.Polygon([Point(0, 2), Point(8, 2), Point(4, 6)]); end else begin @@ -4658,9 +4661,9 @@ procedure TBaseVirtualTree.PrepareBitmaps(NeedButtons, NeedLines: Boolean); begin case FButtonFillMode of fmTreeColor: - Brush.Color := FColors.BackGroundColor; + FMinusBM.Canvas.Brush.Color := FColors.BackGroundColor; fmWindowColor: - Brush.Color := clWindow; + FMinusBM.Canvas.Brush.Color := clWindow; end; Pen.Color := FColors.TreeLineColor; Rectangle(0, 0, Width, Height); @@ -4687,9 +4690,9 @@ procedure TBaseVirtualTree.PrepareBitmaps(NeedButtons, NeedLines: Boolean); begin if FButtonStyle = bsTriangle then begin - Brush.Color := clBlack; - Pen.Color := clBlack; - Polygon([Point(2, 0), Point(6, 4), Point(2, 8)]); + FPlusBM.Canvas.Brush.Color := clBlack; + FPlusBM.Canvas.Pen.Color := clBlack; + FPlusBM.Canvas.Polygon([Point(2, 0), Point(6, 4), Point(2, 8)]); end else begin @@ -4698,9 +4701,9 @@ procedure TBaseVirtualTree.PrepareBitmaps(NeedButtons, NeedLines: Boolean); begin case FButtonFillMode of fmTreeColor: - Brush.Color := FColors.BackGroundColor; + FPlusBM.Canvas.Brush.Color := FColors.BackGroundColor; fmWindowColor: - Brush.Color := clWindow; + FPlusBM.Canvas.Brush.Color := clWindow; end; Pen.Color := FColors.TreeLineColor; Rectangle(0, 0, Width, Height); @@ -9019,7 +9022,7 @@ procedure TBaseVirtualTree.ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; //---------------------------------------------------------------------------------------------------------------------- -procedure TBaseVirtualTree.ScaleNodeHeights(M, D: Integer); +procedure TBaseVirtualTree.ScaleNodeHeights(M, D: TDimension); var Run: PVirtualNode; lNewNodeTotalHeight: Cardinal; @@ -9046,6 +9049,7 @@ procedure TBaseVirtualTree.ScaleNodeHeights(M, D: Integer); EndUpdate(); end; end; + //---------------------------------------------------------------------------------------------------------------------- procedure TBaseVirtualTree.ChangeTreeStatesAsync(EnterStates, LeaveStates: TVirtualTreeStates); @@ -9874,26 +9878,26 @@ function TBaseVirtualTree.DetermineScrollDirections(X, Y: TDimension): TScrollDi if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then begin if (X - FLastClickPos.X) < -8 then - Include(Result, sdLeft); + Include(Result, TScrollDirection.sdLeft); if (X - FLastClickPos.X) > 8 then - Include(Result, sdRight); + Include(Result, TScrollDirection.sdRight); if (Y - FLastClickPos.Y) < -8 then - Include(Result, sdUp); + Include(Result, TScrollDirection.sdUp); if (Y - FLastClickPos.Y) > 8 then - Include(Result, sdDown); + Include(Result, TScrollDirection.sdDown); end else begin if (X < FDefaultNodeHeight) and (FEffectiveOffsetX <> 0) then - Include(Result, sdLeft); + Include(Result, TScrollDirection.sdLeft); if (ClientWidth + FEffectiveOffsetX < FRangeX) and (X > ClientWidth - FDefaultNodeHeight) then - Include(Result, sdRight); + Include(Result, TScrollDirection.sdRight); if (Y < FDefaultNodeHeight) and (FOffsetY <> 0) then - Include(Result, sdUp); + Include(Result, TScrollDirection.sdUp); if (ClientHeight - FOffsetY < FRangeY) and (Y > ClientHeight - FDefaultNodeHeight) then - Include(Result, sdDown); + Include(Result, TScrollDirection.sdDown); // Since scrolling during dragging is not handled via the timer we do a check here whether the auto // scroll timeout already has elapsed or not. @@ -9920,6 +9924,8 @@ procedure TBaseVirtualTree.DoAddToSelection(Node: PVirtualNode); FOnAddToSelection(Self, Node); end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TBaseVirtualTree.DoAdvancedHeaderDraw(var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements); begin @@ -10020,7 +10026,7 @@ procedure TBaseVirtualTree.DoBeforeCellPaint(Canvas: TCanvas; Node: PVirtualNode SetUpdateState(True); end; - Canvas.Font := Self.Font; // Fixes issue #298 + Canvas.Font.Assign(Self.Font); // Fixes issue #298 FOnBeforeCellPaint(Self, Canvas, Node, Column, CellPaintMode, CellRect, ContentRect); if CellPaintMode = cpmGetContentMargin then @@ -12027,7 +12033,7 @@ procedure TBaseVirtualTree.DrawDottedHLine(const PaintInfo: TVTPaintInfo; Left, R: TRect; begin R := Rect(Min(Left, Right), Top, Max(Left, Right) + 1, Top + 1); - Brush.Color := FColors.BackGroundColor; + PaintInfo.Canvas.Brush.Color := FColors.BackGroundColor; Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, DottedBrushTreeLines.Handle); end; @@ -12039,7 +12045,7 @@ procedure TBaseVirtualTree.DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, B R: TRect; begin R := Rect(Left, Min(Top, Bottom), Left + 1, Max(Top, Bottom) + 1); - Brush.Color := FColors.BackGroundColor; + PaintInfo.Canvas.Brush.Color := FColors.BackGroundColor; Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, DottedBrushTreeLines.Handle); end; @@ -12070,7 +12076,7 @@ procedure TBaseVirtualTree.DrawGridVLine(const PaintInfo: TVTPaintInfo; Top, Bot StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenSelectedNotFocused), R, @R, CurrentPPI) else begin //StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tbGroupBoxNormal), R, @R, CurrentPPI); - Brush.Color := FColors.TreeLineColor; + PaintInfo.Canvas.Brush.Color := FColors.TreeLineColor; Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, Brush.Handle); end; end;// else @@ -19814,6 +19820,8 @@ function TBaseVirtualTree.CutCopyNodes(ConsiderChildrenAbove: Boolean): TVTVirtu Result.FConsiderChildrenAbove := ConsiderChildrenAbove; end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TBaseVirtualTree.CutToClipboard; begin if (toReadOnly in TreeOptions.MiscOptions) then @@ -20911,7 +20919,7 @@ procedure TBaseVirtualTree.PaintTree(TargetCanvas: TCanvas; Window: TRect; Targe SavedTargetDC: Integer; PaintWidth: TDimension; CurrentNodeHeight: TDimension; - lEmptyListTextMargin: Integer; + lEmptyListTextMargin: TDimension; CellIsTouchingClientRight: Boolean; CellIsInLastColumn: Boolean; diff --git a/Source/VirtualTrees.Classes.pas b/Source/VirtualTrees.Classes.pas index b50708f4..856f28c4 100644 --- a/Source/VirtualTrees.Classes.pas +++ b/Source/VirtualTrees.Classes.pas @@ -108,8 +108,8 @@ procedure TBufferedRawByteString.Add(const S: RawByteString); FPosition := FStart + LastOffset; FEnd := FStart + NewLen; end; - Move(PAnsiChar(S)^, FPosition^, Len); - Inc(FPosition, Len); + System.Move(PAnsiChar(S)^, FPosition^, Len); + System.Inc(FPosition, Len); end; //---------------------------------------------------------------------------------------------------------------------- @@ -133,9 +133,9 @@ procedure TBufferedRawByteString.AddNewLine; FEnd := FStart + NewLen; end; FPosition^ := #13; - Inc(FPosition); + System.Inc(FPosition); FPosition^ := #10; - Inc(FPosition); + System.Inc(FPosition); end; //----------------- TBufferedString -------------------------------------------------------------------------------- @@ -179,8 +179,8 @@ procedure TBufferedString.Add(const S: string); FPosition := FStart + LastOffset; FEnd := FStart + NewLen; end; - Move(PWideChar(S)^, FPosition^, 2 * Len); - Inc(FPosition, Len); + System.Move(PWideChar(S)^, FPosition^, 2 * Len); + System.Inc(FPosition, Len); end; //---------------------------------------------------------------------------------------------------------------------- @@ -204,9 +204,9 @@ procedure TBufferedString.AddNewLine; FEnd := FStart + NewLen; end; FPosition^ := #13; - Inc(FPosition); + System.Inc(FPosition); FPosition^ := #10; - Inc(FPosition); + System.Inc(FPosition); end; diff --git a/Source/VirtualTrees.DataObject.pas b/Source/VirtualTrees.DataObject.pas index 8fe84908..5010ee3d 100644 --- a/Source/VirtualTrees.DataObject.pas +++ b/Source/VirtualTrees.DataObject.pas @@ -30,7 +30,7 @@ TVTDataObject = class(TInterfacedObject, IDataObject) protected function CanonicalIUnknown(const TestUnknown : IUnknown) : IUnknown; function EqualFormatEtc(FormatEtc1, FormatEtc2 : TFormatEtc) : Boolean; - function FindFormatEtc(TestFormatEtc : TFormatEtc; const FormatEtcArray : TFormatEtcArray) : integer; + function FindFormatEtc(TestFormatEtc : TFormatEtc; const FormatEtcArray : TFormatEtcArray) : Integer; function FindInternalStgMedium(Format : TClipFormat) : PStgMedium; function HGlobalClone(HGlobal : THandle) : THandle; function RenderInternalOLEData(const FormatEtcIn : TFormatEtc; var Medium : TStgMedium; var OLEResult : HResult) : Boolean; @@ -44,10 +44,10 @@ TVTDataObject = class(TInterfacedObject, IDataObject) constructor Create(AOwner : TCustomControl; ForClipboard : Boolean); virtual; destructor Destroy; override; - function DAdvise(const FormatEtc : TFormatEtc; advf : integer; const advSink : IAdviseSink; out dwConnection : integer) : HResult; virtual; stdcall; - function DUnadvise(dwConnection : integer) : HResult; virtual; stdcall; + function DAdvise(const FormatEtc : TFormatEtc; advf : Integer; const advSink : IAdviseSink; out dwConnection : Integer) : HResult; virtual; stdcall; + function DUnadvise(dwConnection : Integer) : HResult; virtual; stdcall; function EnumDAdvise(out enumAdvise : IEnumStatData) : HResult; virtual; stdcall; - function EnumFormatEtc(Direction : integer; out EnumFormatEtc : IEnumFormatEtc) : HResult; virtual; stdcall; + function EnumFormatEtc(Direction : Integer; out EnumFormatEtc : IEnumFormatEtc) : HResult; virtual; stdcall; function GetCanonicalFormatEtc(const FormatEtc : TFormatEtc; out FormatEtcOut : TFormatEtc) : HResult; virtual; stdcall; function GetData(const FormatEtcIn : TFormatEtc; out Medium : TStgMedium) : HResult; virtual; stdcall; function GetDataHere(const FormatEtc : TFormatEtc; out Medium : TStgMedium) : HResult; virtual; stdcall; @@ -80,7 +80,7 @@ constructor TVTDataObject.Create(AOwner : TCustomControl; ForClipboard : Boolean destructor TVTDataObject.Destroy; var - I : integer; + I : Integer; StgMedium : PStgMedium; begin // Cancel a pending clipboard operation if this data object was created for the clipboard and @@ -127,9 +127,9 @@ function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2 : TFormatEtc) : Boo //---------------------------------------------------------------------------------------------------------------------- -function TVTDataObject.FindFormatEtc(TestFormatEtc : TFormatEtc; const FormatEtcArray : TFormatEtcArray) : integer; +function TVTDataObject.FindFormatEtc(TestFormatEtc : TFormatEtc; const FormatEtcArray : TFormatEtcArray) : Integer; var - I : integer; + I : Integer; begin Result := - 1; for I := 0 to High(FormatEtcArray) do @@ -146,7 +146,7 @@ function TVTDataObject.FindFormatEtc(TestFormatEtc : TFormatEtc; const FormatEtc function TVTDataObject.FindInternalStgMedium(Format : TClipFormat) : PStgMedium; var - I : integer; + I : Integer; begin Result := nil; for I := 0 to High(InternalStgMediumArray) do @@ -211,7 +211,7 @@ function TVTDataObject.StgMediumIncRef(const InStgMedium : TStgMedium; var OutSt // This way when the caller frees the structure it sees the unkForRelease is not nil and calls Release on the object // instead of destroying the actual data. var - Len : integer; + Len : Integer; begin Result := S_OK; @@ -272,7 +272,7 @@ function TVTDataObject.StgMediumIncRef(const InStgMedium : TStgMedium; var OutSt //---------------------------------------------------------------------------------------------------------------------- -function TVTDataObject.DAdvise(const FormatEtc : TFormatEtc; advf : integer; const advSink : IAdviseSink; out dwConnection : integer) : HResult; +function TVTDataObject.DAdvise(const FormatEtc : TFormatEtc; advf : Integer; const advSink : IAdviseSink; out dwConnection : Integer) : HResult; // Advise sink management is greatly simplified by the IDataAdviseHolder interface. // We use this interface and forward all concerning calls to it. begin @@ -285,7 +285,7 @@ function TVTDataObject.DAdvise(const FormatEtc : TFormatEtc; advf : integer; con //---------------------------------------------------------------------------------------------------------------------- -function TVTDataObject.DUnadvise(dwConnection : integer) : HResult; +function TVTDataObject.DUnadvise(dwConnection : Integer) : HResult; begin if FAdviseHolder = nil then Result := E_NOTIMPL @@ -305,7 +305,7 @@ function TVTDataObject.EnumDAdvise(out enumAdvise : IEnumStatData) : HResult; //---------------------------------------------------------------------------------------------------------------------- -function TVTDataObject.EnumFormatEtc(Direction : integer; out EnumFormatEtc : IEnumFormatEtc) : HResult; +function TVTDataObject.EnumFormatEtc(Direction : Integer; out EnumFormatEtc : IEnumFormatEtc) : HResult; var NewList : TEnumFormatEtc; begin @@ -335,7 +335,7 @@ function TVTDataObject.GetData(const FormatEtcIn : TFormatEtc; out Medium : TStg // Data is requested by clipboard or drop target. This method dispatchs the call // depending on the data being requested. var - I : integer; + I : Integer; Data : PVTReference; begin // The tree reference format is always supported and returned from here. @@ -392,7 +392,7 @@ function TVTDataObject.GetDataHere(const FormatEtc : TFormatEtc; out Medium : TS function TVTDataObject.QueryGetData(const FormatEtc : TFormatEtc) : HResult; var - I : integer; + I : Integer; begin Result := DV_E_CLIPFORMAT; for I := 0 to High(FFormatEtcArray) do @@ -426,7 +426,7 @@ function TVTDataObject.SetData(const FormatEtc : TFormatEtc; var Medium : TStgMe // Allows dynamic adding to the IDataObject during its existance. Most noteably it is used to implement // IDropSourceHelper and allows to set a special format for optimized moves during a shell transfer. var - Index : integer; + Index : Integer; LocalStgMedium : PStgMedium; begin // See if we already have a format of that type available. diff --git a/Source/VirtualTrees.DragImage.pas b/Source/VirtualTrees.DragImage.pas index f7642fb8..face1aad 100644 --- a/Source/VirtualTrees.DragImage.pas +++ b/Source/VirtualTrees.DragImage.pas @@ -18,9 +18,14 @@ interface TVTBias = - 128 .. 127; // Simple move limitation for the drag image. - TVTDragMoveRestriction = (dmrNone, dmrHorizontalOnly, dmrVerticalOnly); - - TVTDragImageStates = set of (disHidden, // Internal drag image is currently hidden (always hidden if drag image helper interfaces are used). + TVTDragMoveRestriction = ( + dmrNone, + dmrHorizontalOnly, + dmrVerticalOnly + ); + + TVTDragImageStates = set of ( + disHidden, // Internal drag image is currently hidden (always hidden if drag image helper interfaces are used). disInDrag, // Drag image class is currently being used. disPrepared, // Drag image class is prepared. disSystemSupport // Running on Windows 2000 or higher. System supports drag images natively. diff --git a/Source/VirtualTrees.Export.pas b/Source/VirtualTrees.Export.pas index a694f088..2bfb985c 100644 --- a/Source/VirtualTrees.Export.pas +++ b/Source/VirtualTrees.Export.pas @@ -729,7 +729,7 @@ function ContentToRTF(Tree: TCustomVirtualStringTree; Source: TVSTTextSourceType end; // Call back the application to know about font customization. - CrackTree.Canvas.Font := CrackTree.Font; + CrackTree.Canvas.Font.Assign(CrackTree.Font); CrackTree.FFontChanged := False; CrackTree.DoPaintText(Run, CrackTree.Canvas, Index, ttNormal); diff --git a/Source/VirtualTrees.FMX.pas b/Source/VirtualTrees.FMX.pas index 9863ca75..15caa1a2 100644 --- a/Source/VirtualTrees.FMX.pas +++ b/Source/VirtualTrees.FMX.pas @@ -16,6 +16,7 @@ interface , System.UITypes , System.Types , System.ImageList + , System.Math.Vectors , FMX.ImgList , FMX.Graphics , FMX.Controls @@ -186,6 +187,9 @@ interface RDW_FRAME = $400; RDW_NOFRAME = $800; + { GetSystemMetrics() codes } + SM_CXVSCROLL = 2; + SM_CYHSCROLL = 3; var // Clipboard format IDs used in OLE drag'n drop and clipboard transfers. CF_VIRTUALTREE, @@ -519,6 +523,8 @@ TCanvasHelper = class helper for TCanvas procedure FrameRect(const AFocusRect: TRect); procedure RoundRect(X1, Y1, X2, Y2: Single; const XRadius, YRadius: Single); overload; procedure RoundRect(const Rect: TRect; const XRadius, YRadius: Single); overload; + procedure Polygon(const Points: TPolygon); + procedure Draw(const X, Y: Single; const Bitmap: TBitmap); end; TFontHelper = class helper for TFont @@ -539,6 +545,10 @@ procedure DrawArrow(ACanvas: TCanvas; Direction: TScrollDirection; Location: TPo procedure ChangeBiDiModeAlignment(var Alignment: TAlignment); +procedure OleUninitialize(); + +function timeGetTime: Int64; + implementation uses System.SysUtils @@ -549,53 +559,92 @@ implementation , VirtualTrees.Utils ; +//---------------------------------------------------------------------------------------------------------------------- + procedure DrawArrow(ACanvas: TCanvas; Direction: TScrollDirection; Location: TPoint; Size: Single); begin //TODO: DrawArrow implementation end; +//---------------------------------------------------------------------------------------------------------------------- + { TCanvasHelper } +procedure TCanvasHelper.Draw(const X, Y: Single; const Bitmap: TBitmap); +begin + DrawBitmap(Bitmap + , Rect(0, 0, Bitmap.Width, Bitmap.Height) + , Rect(X, Y, X+Bitmap.Width, Y+ Bitmap.Height) + , 1.0 + ); +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TCanvasHelper.DrawFocusRect(const AFocusRect: TRect); begin DrawDashRect(AFocusRect, 0, 0, AllCorners, 1.0{?}, $A0909090); end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TCanvasHelper.DrawRect(const ARect: TRectF); begin DrawRect(ARect, 0, 0, [], 1.0); end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TCanvasHelper.FillRect(const ARect: TRectF); begin FillRect(ARect, 0, 0, [], 1.0); end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TCanvasHelper.FrameRect(const AFocusRect: TRect); begin DrawRect(AFocusRect); end; +//---------------------------------------------------------------------------------------------------------------------- + function TCanvasHelper.GetBrush: TBrush; begin Result:= Fill; end; +//---------------------------------------------------------------------------------------------------------------------- + function TCanvasHelper.GetPen: TStrokeBrush; begin Result:= Stroke; end; +//---------------------------------------------------------------------------------------------------------------------- + +procedure TCanvasHelper.Polygon(const Points: TPolygon); +begin + DrawPolygon(Points, 1.0); +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TCanvasHelper.RoundRect(const Rect: TRect; const XRadius, YRadius: Single); begin DrawRect(Rect, XRadius, YRadius, allCorners, 1.0); end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TCanvasHelper.RoundRect(X1, Y1, X2, Y2: Single; const XRadius, YRadius: Single); begin RoundRect(Rect(X1, Y1, X2, Y2), XRadius, YRadius); end; + +//---------------------------------------------------------------------------------------------------------------------- + type TImageListHelper = class helper for TImageList function Add(aBitmap: TBitmap): integer; @@ -1668,6 +1717,20 @@ procedure ChangeBiDiModeAlignment(var Alignment: TAlignment); end; end; +//---------------------------------------------------------------------------------------------------------------------- + +procedure OleUninitialize(); +begin + //nothing +end; + +//---------------------------------------------------------------------------------------------------------------------- + +function timeGetTime: Int64; +begin + Result:= TThread.GetTickCount; +end; + { TChangeLink } //---------------------------------------------------------------------------------------------------------------------- diff --git a/Source/VirtualTrees.Header.pas b/Source/VirtualTrees.Header.pas index 9e739f1b..2f99fb22 100644 --- a/Source/VirtualTrees.Header.pas +++ b/Source/VirtualTrees.Header.pas @@ -636,7 +636,7 @@ procedure TVTHeader.AutoScale(); with TBitmap.Create do try Canvas.Font.Assign(FFont); - lMaxHeight := lMaxHeight { top spacing } + (lMaxHeight div 2) { minimum bottom spacing } + Canvas.TextHeight('Q'); + lMaxHeight := lMaxHeight { top spacing } + Divide(lMaxHeight, 2) { minimum bottom spacing } + Canvas.TextHeight('Q'); finally Free; end; @@ -738,8 +738,8 @@ procedure TVTHeader.SetHeight(Value : TDimension); begin with FFixedAreaConstraints do begin - RelativeMaxHeight := ((Tree.ClientHeight + FHeight) * FMaxHeightPercent) div 100; - RelativeMinHeight := ((Tree.ClientHeight + FHeight) * FMinHeightPercent) div 100; + RelativeMaxHeight := Divide((Tree.ClientHeight + FHeight) * FMaxHeightPercent, 100); + RelativeMinHeight := Divide((Tree.ClientHeight + FHeight) * FMinHeightPercent, 100); EffectiveMinHeight := IfThen(FMaxHeightPercent > 0, Min(RelativeMaxHeight, FMinHeight), FMinHeight); EffectiveMaxHeight := IfThen(FMinHeightPercent > 0, Max(RelativeMinHeight, FMaxHeight), FMaxHeight); @@ -1227,7 +1227,7 @@ procedure TVTHeader.DragTo(P : TPoint); if NewTarget >= 0 then begin FColumns.GetColumnBounds(NewTarget, Left, Right); - if (ClientP.X < ((Left + Right) div 2)) <> FColumns.DropBefore then + if (ClientP.X < Divide((Left + Right), 2)) <> FColumns.DropBefore then begin NeedRepaint := True; FColumns.DropBefore := not FColumns.DropBefore; @@ -1339,7 +1339,7 @@ function TVTHeader.HandleHeaderMouseMove(var Message : TWMMouseMove) : Boolean; P : TPoint; NextColumn, I : TColumnIndex; NewWidth : TDimension; - iOffsetX: Integer; + iOffsetX : TDimension; begin Result := False; @@ -1548,14 +1548,14 @@ function TVTHeader.HandleMessage(var Message : TMessage) : Boolean; begin case Message.Msg of WM_NCMBUTTONDBLCLK : - Button := mbMiddle; + Button := TMouseButton.mbMiddle; WM_NCRBUTTONDBLCLK : - Button := mbRight; + Button := TMouseButton.mbRight; else //WM_NCLBUTTONDBLCLK - Button := mbLeft; + Button := TMouseButton.mbLeft; end; - if Button = mbLeft then + if Button = TMouseButton.mbLeft then TVirtualTreeColumnsCracker(FColumns).AdjustDownColumn(P); TVirtualTreeColumnsCracker(FColumns).HandleClick(P, Button, True, True); end; @@ -1643,14 +1643,14 @@ function TVTHeader.HandleMessage(var Message : TMessage) : Boolean; //This is a good opportunity to notify the application. if not (csDesigning in Tree.ComponentState) and IsInHeader then - TBaseVirtualTreeCracker(FOwner).DoHeaderMouseDown(mbLeft, GetShiftState, P.X, P.Y + FHeight); + TBaseVirtualTreeCracker(FOwner).DoHeaderMouseDown(TMouseButton.mbLeft, GetShiftState, P.X, P.Y + FHeight); end; WM_NCRBUTTONDOWN : begin with TWMNCRButtonDown(Message) do P := FOwner.ScreenToClient(Point(XCursor, YCursor)); if InHeader(P) then - TBaseVirtualTreeCracker(FOwner).DoHeaderMouseDown(mbRight, GetShiftState, P.X, P.Y + FHeight); + TBaseVirtualTreeCracker(FOwner).DoHeaderMouseDown(TMouseButton.mbRight, GetShiftState, P.X, P.Y + FHeight); end; WM_NCRBUTTONUP : if not (csDesigning in FOwner.ComponentState) then @@ -1660,8 +1660,8 @@ function TVTHeader.HandleMessage(var Message : TMessage) : Boolean; P := FOwner.ScreenToClient(Point(XCursor, YCursor)); if InHeader(P) then begin - HandleMessage := TVirtualTreeColumnsCracker(FColumns).HandleClick(P, mbRight, True, False); - TBaseVirtualTreeCracker(FOwner).DoHeaderMouseUp(mbRight, GetShiftState, P.X, P.Y + FHeight); + HandleMessage := TVirtualTreeColumnsCracker(FColumns).HandleClick(P, TMouseButton.mbRight, True, False); + TBaseVirtualTreeCracker(FOwner).DoHeaderMouseUp(TMouseButton.mbRight, GetShiftState, P.X, P.Y + FHeight); end; end; //When the tree window has an active mouse capture then we only get "client-area" messages. @@ -1737,17 +1737,17 @@ function TVTHeader.HandleMessage(var Message : TMessage) : Boolean; with TVirtualTreeColumnsCracker(FColumns) do begin if DownIndex > NoColumn then - HandleClick(Point(XPos, YPos), mbLeft, False, False); + HandleClick(Point(XPos, YPos), TMouseButton.mbLeft, False, False); end; if FStates <> [] then - TBaseVirtualTreeCracker(FOwner).DoHeaderMouseUp(mbLeft, KeysToShiftState(Keys), XPos, YPos); + TBaseVirtualTreeCracker(FOwner).DoHeaderMouseUp(TMouseButton.mbLeft, KeysToShiftState(Keys), XPos, YPos); end; WM_NCLBUTTONUP : begin with TWMNCLButtonUp(Message) do P := FOwner.ScreenToClient(Point(XCursor, YCursor)); - TVirtualTreeColumnsCracker(FColumns).HandleClick(P, mbLeft, True, False); - TBaseVirtualTreeCracker(FOwner).DoHeaderMouseUp(mbLeft, GetShiftState, P.X, P.Y + FHeight); + TVirtualTreeColumnsCracker(FColumns).HandleClick(P, TMouseButton.mbLeft, True, False); + TBaseVirtualTreeCracker(FOwner).DoHeaderMouseUp(TMouseButton.mbLeft, GetShiftState, P.X, P.Y + FHeight); Result := True; end; end; @@ -1987,7 +1987,7 @@ procedure TVTHeader.RescaleHeader; //Rescale the fixed elements (fixed columns, header itself) to FixedAreaConstraints. var - FixedWidth, MaxFixedWidth, MinFixedWidth : Integer; + FixedWidth, MaxFixedWidth, MinFixedWidth : TDimension; //--------------- local function -------------------------------------------- @@ -2011,8 +2011,8 @@ procedure TVTHeader.RescaleHeader; with FFixedAreaConstraints do begin - MinFixedWidth := (Tree.ClientWidth * FMinWidthPercent) div 100; - MaxFixedWidth := (Tree.ClientWidth * FMaxWidthPercent) div 100; + MinFixedWidth := Divide(Tree.ClientWidth * FMinWidthPercent, 100); + MaxFixedWidth := Divide(Tree.ClientWidth * FMaxWidthPercent, 100); end; end; @@ -2180,6 +2180,8 @@ function TVTHeader.AreColumnsStored: Boolean; Result := not (csDesigning in Self.Treeview.ComponentState); end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TVTHeader.Assign(Source : TPersistent); begin @@ -2598,7 +2600,7 @@ function TVTHeader.ResizeColumns(ChangeBy : TDimension; RangeStartCol : TColumnI if (MaxReserveCol <= NoColumn) or (Constraints[MaxReserveCol - RangeStartCol] <= 10) then Result := False else - Dec(Constraints[MaxReserveCol - RangeStartCol], Constraints[MaxReserveCol - RangeStartCol] div 10); + Dec(Constraints[MaxReserveCol - RangeStartCol], Divide(Constraints[MaxReserveCol - RangeStartCol], 10)); end; //----------- end local functions ------------------------------------------- @@ -2715,6 +2717,7 @@ procedure TVTHeader.SaveToStream(const Stream : TStream); var Dummy : Integer; + DummyDimension: TDimension; Tmp : AnsiString; begin @@ -2737,8 +2740,8 @@ procedure TVTHeader.SaveToStream(const Stream : TStream); WriteBuffer(Dummy, SizeOf(Dummy)); Dummy := FBackgroundColor; WriteBuffer(Dummy, SizeOf(Dummy)); - Dummy := FHeight; - WriteBuffer(Dummy, SizeOf(Dummy)); + DummyDimension:= FHeight; + WriteBuffer(DummyDimension, SizeOf(DummyDimension)); Dummy := Integer(FOptions); WriteBuffer(Dummy, SizeOf(Dummy)); //PopupMenu is neither saved nor restored @@ -2751,8 +2754,8 @@ procedure TVTHeader.SaveToStream(const Stream : TStream); WriteBuffer(Dummy, SizeOf(Dummy)); //Need only to write one: size or height, I decided to write height. - Dummy := Height; - WriteBuffer(Dummy, SizeOf(Dummy)); + DummyDimension := Height; + WriteBuffer(DummyDimension, SizeOf(DummyDimension)); Tmp := UTF8Encode(Name); Dummy := Length(Tmp); WriteBuffer(Dummy, SizeOf(Dummy)); @@ -2774,12 +2777,13 @@ procedure TVTHeader.SaveToStream(const Stream : TStream); //Data introduced by stream version 5. Dummy := Integer(ParentFont); WriteBuffer(Dummy, SizeOf(Dummy)); - Dummy := Integer(FMaxHeight); - WriteBuffer(Dummy, SizeOf(Dummy)); - Dummy := Integer(FMinHeight); - WriteBuffer(Dummy, SizeOf(Dummy)); - Dummy := Integer(FDefaultHeight); - WriteBuffer(Dummy, SizeOf(Dummy)); + DummyDimension := FMaxHeight; + WriteBuffer(DummyDimension, SizeOf(DummyDimension)); + DummyDimension := FMinHeight; + WriteBuffer(DummyDimension, SizeOf(DummyDimension)); + DummyDimension := FDefaultHeight; + WriteBuffer(DummyDimension, SizeOf(DummyDimension)); + with FFixedAreaConstraints do begin Dummy := Integer(FMaxHeightPercent); @@ -2837,6 +2841,8 @@ constructor TVirtualTreeColumn.Create(Collection : TCollection); end; end; +//---------------------------------------------------------------------------------------------------------------------- + procedure TVirtualTreeColumn.SetCollection(Value : TCollection); begin inherited; @@ -3396,18 +3402,18 @@ procedure TVirtualTreeColumn.SetWidth(Value : TDimension); begin // The percentage values have precedence over the pixel values. If MaxWidthPercent > 0 then - TotalFixedMinWidth := Min((ClientWidth * MaxWidthPercent) div 100, TotalFixedMinWidth); + TotalFixedMinWidth := Min(Divide(ClientWidth * MaxWidthPercent, 100), TotalFixedMinWidth); If MinWidthPercent > 0 then - TotalFixedMaxWidth := Max((ClientWidth * MinWidthPercent) div 100, TotalFixedMaxWidth); + TotalFixedMaxWidth := Max(Divide(ClientWidth * MinWidthPercent, 100), TotalFixedMaxWidth); EffectiveMaxWidth := Min(TotalFixedMaxWidth - (Columns.GetVisibleFixedWidth - Self.FWidth), FMaxWidth); EffectiveMinWidth := Max(TotalFixedMinWidth - (Columns.GetVisibleFixedWidth - Self.FWidth), FMinWidth); Value := Min(Max(Value, EffectiveMinWidth), EffectiveMaxWidth); if MinWidthPercent > 0 then - Value := Max((ClientWidth * MinWidthPercent) div 100 - Columns.GetVisibleFixedWidth + Self.FWidth, Value); + Value := Max(Divide(ClientWidth * MinWidthPercent, 100) - Columns.GetVisibleFixedWidth + Self.FWidth, Value); if MaxWidthPercent > 0 then - Value := Min((ClientWidth * MaxWidthPercent) div 100 - Columns.GetVisibleFixedWidth + Self.FWidth, Value); + Value := Min(Divide(ClientWidth * MaxWidthPercent, 100) - Columns.GetVisibleFixedWidth + Self.FWidth, Value); end;// if HandleAllocated end; end @@ -3507,7 +3513,7 @@ procedure TVirtualTreeColumn.ComputeHeaderLayout(var PaintInfo : THeaderPaintInf end; // In any case, the sort glyph is vertically centered. - PaintInfo.SortGlyphPos.Y := (ClientSize.Y - PaintInfo.SortGlyphSize.cy) div 2; + PaintInfo.SortGlyphPos.Y := Divide(ClientSize.Y - PaintInfo.SortGlyphSize.cy, 2); end else begin @@ -3549,29 +3555,29 @@ procedure TVirtualTreeColumn.ComputeHeaderLayout(var PaintInfo : THeaderPaintInf if PaintInfo.ShowSortGlyph and not (UseText or PaintInfo.ShowHeaderGlyph) then begin // Center the sort glyph in the available area if nothing else is there. - PaintInfo.SortGlyphPos := Point((ClientSize.X - PaintInfo.SortGlyphSize.cx) div 2, (ClientSize.Y - PaintInfo.SortGlyphSize.cy) div 2); + PaintInfo.SortGlyphPos := Point(Divide(ClientSize.X - PaintInfo.SortGlyphSize.cx, 2), Divide(ClientSize.Y - PaintInfo.SortGlyphSize.cy, 2)); end else begin // Determine extents of text and glyph and calculate positions which are clear from the layout. if (Layout in [blGlyphLeft, blGlyphRight]) or not PaintInfo.ShowHeaderGlyph then begin - PaintInfo.GlyphPos.Y := (ClientSize.Y - HeaderGlyphSize.Y) div 2; + PaintInfo.GlyphPos.Y := Divide(ClientSize.Y - HeaderGlyphSize.Y, 2); // If the text is taller than the given height, perform no vertical centration as this // would make the text even less readable. //Using Max() fixes badly positioned text if Extra Large fonts have been activated in the Windows display options - TextPos.Y := Max( - 5, (ClientSize.Y - TextSize.cy) div 2); + TextPos.Y := Max( - 5, Divide(ClientSize.Y - TextSize.cy, 2)); end else begin if Layout = blGlyphTop then begin - PaintInfo.GlyphPos.Y := (ClientSize.Y - HeaderGlyphSize.Y - TextSize.cy - TextSpacing) div 2; + PaintInfo.GlyphPos.Y := Divide(ClientSize.Y - HeaderGlyphSize.Y - TextSize.cy - TextSpacing, 2); TextPos.Y := PaintInfo.GlyphPos.Y + HeaderGlyphSize.Y + TextSpacing; end else begin - TextPos.Y := (ClientSize.Y - HeaderGlyphSize.Y - TextSize.cy - TextSpacing) div 2; + TextPos.Y := Divide(ClientSize.Y - HeaderGlyphSize.Y - TextSize.cy - TextSpacing, 2); PaintInfo.GlyphPos.Y := TextPos.Y + TextSize.cy + TextSpacing; end; end; @@ -3594,7 +3600,7 @@ procedure TVirtualTreeColumn.ComputeHeaderLayout(var PaintInfo : THeaderPaintInf TextPos.X := MinLeft; if PaintInfo.ShowHeaderGlyph then begin - PaintInfo.GlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2; + PaintInfo.GlyphPos.X := Divide(ClientSize.X - HeaderGlyphSize.X, 2); if PaintInfo.GlyphPos.X < MinLeft then PaintInfo.GlyphPos.X := MinLeft; MinLeft := Max(TextPos.X + TextSize.cx + TextSpacing, PaintInfo.GlyphPos.X + HeaderGlyphSize.X + FSpacing); @@ -3626,14 +3632,14 @@ procedure TVirtualTreeColumn.ComputeHeaderLayout(var PaintInfo : THeaderPaintInf begin if Layout in [blGlyphTop, blGlyphBottom] then begin - PaintInfo.GlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2; - TextPos.X := (ClientSize.X - TextSize.cx) div 2; + PaintInfo.GlyphPos.X := Divide(ClientSize.X - HeaderGlyphSize.X, 2); + TextPos.X := Divide(ClientSize.X - TextSize.cx, 2); if PaintInfo.ShowSortGlyph then - Dec(TextPos.X, PaintInfo.SortGlyphSize.cx div 2); + Dec(TextPos.X, Divide(PaintInfo.SortGlyphSize.cx, 2)); end else begin - MinLeft := (ClientSize.X - HeaderGlyphSize.X - TextSpacing - TextSize.cx) div 2; + MinLeft := Divide(ClientSize.X - HeaderGlyphSize.X - TextSpacing - TextSize.cx, 2); if PaintInfo.ShowHeaderGlyph and (Layout = blGlyphLeft) then begin PaintInfo.GlyphPos.X := MinLeft; @@ -3682,7 +3688,7 @@ procedure TVirtualTreeColumn.ComputeHeaderLayout(var PaintInfo : THeaderPaintInf TextPos.X := MaxRight - TextSize.cx; if PaintInfo.ShowHeaderGlyph then begin - PaintInfo.GlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2; + PaintInfo.GlyphPos.X := Divide(ClientSize.X - HeaderGlyphSize.X, 2); if PaintInfo.GlyphPos.X + HeaderGlyphSize.X + FSpacing > MaxRight then PaintInfo.GlyphPos.X := MaxRight - HeaderGlyphSize.X - FSpacing; MaxRight := Min(TextPos.X - TextSpacing, PaintInfo.GlyphPos.X - FSpacing); @@ -4861,7 +4867,7 @@ procedure TVirtualTreeColumns.AnimatedResize(Column : TColumnIndex; NewWidth : T with TreeViewControl do try Steps := 32; - DX := (NewWidth - OldWidth) div Steps; + DX := Divide(NewWidth - OldWidth, Steps); // Determination of the scroll rectangle is a bit complicated since we neither want // to scroll the scrollbars nor the border of the treeview window. @@ -5783,7 +5789,7 @@ procedure TVirtualTreeColumns.PaintHeader(TargetCanvas : TCanvas; R : TRect; con TargetRect.Left := Target.X - R.Left + Items[Run].FLeft + RTLOffset; // TargetRect.Right will be set in the loop - ShowRightBorder := (Header.Style = hsThickButtons) or not (hoAutoResize in Header.Options) or (TreeViewControl.BevelKind = bkNone); + ShowRightBorder := (Header.Style = hsThickButtons) or not (hoAutoResize in Header.Options) or (TreeViewControl.BevelKind = TBevelKind.bkNone); // Now go for each button. while (Run > NoColumn) and (TargetRect.Left < MaxX) do @@ -5854,11 +5860,11 @@ procedure THeaderPaintInfo.DrawDropMark(); lArrowWidth : TDimension; begin lArrowWidth := TBaseVirtualTreeCracker(Self.Column.TreeViewControl).ScaledPixels(5); - Y := (PaintRectangle.Top + PaintRectangle.Bottom - 3 * lArrowWidth) div 2; + Y := Divide(PaintRectangle.Top + PaintRectangle.Bottom - 3 * lArrowWidth, 2); if DropMark = dmmLeft then DrawArrow(TargetCanvas, TScrollDirection.sdLeft, Point(PaintRectangle.Left, Y), lArrowWidth) else - DrawArrow(TargetCanvas, TScrollDirection.sdRight, Point(PaintRectangle.Right - lArrowWidth - (lArrowWidth div 2) {spacing}, Y), lArrowWidth); + DrawArrow(TargetCanvas, TScrollDirection.sdRight, Point(PaintRectangle.Right - lArrowWidth - Divide(lArrowWidth, 2) {spacing}, Y), lArrowWidth); end; procedure THeaderPaintInfo.DrawSortArrow(pDirection : TSortDirection); diff --git a/Source/VirtualTrees.StyleHooks.pas b/Source/VirtualTrees.StyleHooks.pas index 46ee44e6..0f9bbd52 100644 --- a/Source/VirtualTrees.StyleHooks.pas +++ b/Source/VirtualTrees.StyleHooks.pas @@ -704,8 +704,6 @@ procedure TVclStyleScrollBarsHook.WMNCLButtonDown(var Msg: TWMMouse); end; //---------------------------------------------------------------------------------------------------------------------- -//---------------------------------------------------------------------------------------------------------------------- - procedure TVclStyleScrollBarsHook.WMNCLButtonUp(var Msg: TWMMouse); var diff --git a/Source/VirtualTrees.Types.pas b/Source/VirtualTrees.Types.pas index be66ae08..a833f048 100644 --- a/Source/VirtualTrees.Types.pas +++ b/Source/VirtualTrees.Types.pas @@ -1632,50 +1632,66 @@ procedure TScrollBarOptions.Assign(Source : TPersistent); inherited; end; - +//---------------------------------------------------------------------------------------------------------------------- { TCheckStateHelper } -function TCheckStateHelper.IsDisabled : Boolean; +function TCheckStateHelper.IsDisabled: Boolean; begin Result := Self >= TCheckState.csUncheckedDisabled; end; -function TCheckStateHelper.IsChecked : Boolean; +//---------------------------------------------------------------------------------------------------------------------- + +function TCheckStateHelper.IsChecked: Boolean; begin Result := Self in [csCheckedNormal, csCheckedPressed, csCheckedDisabled]; end; -function TCheckStateHelper.IsUnChecked : Boolean; +//---------------------------------------------------------------------------------------------------------------------- + +function TCheckStateHelper.IsUnChecked: Boolean; begin Result := Self in [csUncheckedNormal, csUncheckedPressed, csUncheckedDisabled]; end; -function TCheckStateHelper.IsMixed : Boolean; +//---------------------------------------------------------------------------------------------------------------------- + +function TCheckStateHelper.IsMixed: Boolean; begin Result := Self in [csMixedNormal, csMixedPressed, csMixedDisabled]; end; -function TCheckStateHelper.GetEnabled : TCheckState; +//---------------------------------------------------------------------------------------------------------------------- + +function TCheckStateHelper.GetEnabled: TCheckState; begin Result := cEnabledState[Self]; end; -function TCheckStateHelper.GetPressed() : TCheckState; +//---------------------------------------------------------------------------------------------------------------------- + +function TCheckStateHelper.GetPressed(): TCheckState; begin Result := cPressedState[Self]; end; -function TCheckStateHelper.GetUnpressed() : TCheckState; +//---------------------------------------------------------------------------------------------------------------------- + +function TCheckStateHelper.GetUnpressed(): TCheckState; begin Result := cUnpressedState[Self]; end; -function TCheckStateHelper.GetToggled() : TCheckState; +//---------------------------------------------------------------------------------------------------------------------- + +function TCheckStateHelper.GetToggled(): TCheckState; begin Result := cToggledState[Self]; end; +//---------------------------------------------------------------------------------------------------------------------- + { TSortDirectionHelper } function TSortDirectionHelper.ToInt() : Integer; diff --git a/Source/VirtualTrees.Utils.pas b/Source/VirtualTrees.Utils.pas index 491e2dfa..f93f2fe0 100644 --- a/Source/VirtualTrees.Utils.pas +++ b/Source/VirtualTrees.Utils.pas @@ -1463,6 +1463,8 @@ procedure ScaleImageList(const ImgList: TImageList; M, D: Integer); end; end; +//---------------------------------------------------------------------------------------------------------------------- + function IsHighContrastEnabled(): Boolean; var l: HIGHCONTRAST; @@ -1471,11 +1473,14 @@ function IsHighContrastEnabled(): Boolean; Result := SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, @l, 0) and ((l.dwFlags and HCF_HIGHCONTRASTON) <> 0); end; +//---------------------------------------------------------------------------------------------------------------------- function Divide(const Dimension: Single; const DivideBy: Integer): Single; begin Result:= Dimension / DivideBy; end; +//---------------------------------------------------------------------------------------------------------------------- + function Divide(const Dimension: Integer; const DivideBy: Integer): Integer; begin Result:= Dimension div DivideBy; diff --git a/Source/VirtualTrees.WorkerThread.pas b/Source/VirtualTrees.WorkerThread.pas index a0bea0ad..4e74d70c 100644 --- a/Source/VirtualTrees.WorkerThread.pas +++ b/Source/VirtualTrees.WorkerThread.pas @@ -49,6 +49,7 @@ TBaseVirtualTreeCracker = class(TBaseVirtualTree) var WorkerThread: TWorkerThread = nil; + //----------------- TWorkerThread -------------------------------------------------------------------------------------- class procedure TWorkerThread.EnsureCreated(); @@ -58,6 +59,8 @@ class procedure TWorkerThread.EnsureCreated(); WorkerThread := TWorkerThread.Create(); end; +//---------------------------------------------------------------------------------------------------------------------- + class procedure TWorkerThread.Dispose(CanBlock: Boolean); var LRef: TThread; @@ -71,6 +74,7 @@ class procedure TWorkerThread.Dispose(CanBlock: Boolean); LRef.Free; end; +//---------------------------------------------------------------------------------------------------------------------- class procedure TWorkerThread.AddThreadReference; begin diff --git a/Source/VirtualTrees.pas b/Source/VirtualTrees.pas index 8249dee5..34d52837 100644 --- a/Source/VirtualTrees.pas +++ b/Source/VirtualTrees.pas @@ -802,7 +802,7 @@ procedure TCustomVirtualStringTree.InitializeTextProperties(var PaintInfo: TVTPa with PaintInfo do begin // Set default font values first. - Canvas.Font := Font; + Canvas.Font.Assign(Font); if Enabled then // Otherwise only those colors are used, which are passed from Font to Canvas.Font. Canvas.Font.Color := Colors.NodeFontColor else @@ -881,7 +881,7 @@ procedure TCustomVirtualStringTree.PaintNormalText(var PaintInfo: TVTPaintInfo; // Center the text vertically if it fits entirely into the content rect. if R.Bottom - R.Top > Height then - InflateRect(R, 0, (Height - R.Bottom - R.Top) div 2); + InflateRect(R, 0, Divide(Height - R.Bottom - R.Top, 2)); end else begin @@ -939,7 +939,7 @@ procedure TCustomVirtualStringTree.PaintStaticText(const PaintInfo: TVTPaintInfo begin with PaintInfo do begin - Canvas.Font := Font; + Canvas.Font.Assign(Font); if toFullRowSelect in TreeOptions.SelectionOptions then begin if Node = DropTargetNode then @@ -1116,6 +1116,7 @@ function TCustomVirtualStringTree.AddChild(Parent: PVirtualNode; UserData: Point end; end; +//---------------------------------------------------------------------------------------------------------------------- procedure TCustomVirtualStringTree.AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; var NextNonEmpty: TColumnIndex); @@ -1170,7 +1171,7 @@ function TCustomVirtualStringTree.CalculateTextWidth(Canvas: TCanvas; Node: PVir Result := 2 * TextMargin; if Length(Text) > 0 then begin - Canvas.Font := Font; + Canvas.Font.Assign(Font); DoPaintText(Node, Canvas, Column, ttNormal); Inc(Result, DoTextMeasuring(Canvas, Node, Column, Text).cx); @@ -1868,7 +1869,7 @@ procedure TCustomVirtualStringTree.GetTextInfo(Node: PVirtualNode; Column: TColu // Get default font and initialize the other parameters. inherited GetTextInfo(Node, Column, AFont, R, Text); - Canvas.Font := AFont; + Canvas.Font.Assign(AFont); FFontChanged := False; RedirectFontChangeEvent(Canvas); @@ -1888,7 +1889,7 @@ procedure TCustomVirtualStringTree.GetTextInfo(Node: PVirtualNode; Column: TColu R := GetDisplayRect(Node, Column, True, not (vsMultiline in Node.States)); if toShowHorzGridLines in TreeOptions.PaintOptions then Dec(R.Bottom); - InflateRect(R, 0, -(R.Bottom - R.Top - NewHeight) div 2); + InflateRect(R, 0, -Divide(R.Bottom - R.Top - NewHeight, 2)); end; //---------------------------------------------------------------------------------------------------------------------- From 2247ade8fcb61a037be062f9ba99a84b094a33ae Mon Sep 17 00:00:00 2001 From: livius2 Date: Tue, 31 Oct 2023 23:49:15 +0100 Subject: [PATCH 20/28] small step - extract TVirtualTreeHintWindow to VirtualTrees.AncestorVCL small step - extract TVirtualTreeHintWindow to VirtualTrees.AncestorVCL GetTreeFromDataObject - specific to VCL --- Source/VirtualTrees.AncestorVcl.pas | 405 ++++++++++++++++++++- Source/VirtualTrees.BaseAncestorVcl.pas | 59 ++++ Source/VirtualTrees.BaseTree.pas | 448 +----------------------- 3 files changed, 465 insertions(+), 447 deletions(-) diff --git a/Source/VirtualTrees.AncestorVcl.pas b/Source/VirtualTrees.AncestorVcl.pas index 189d65bd..7085edee 100644 --- a/Source/VirtualTrees.AncestorVcl.pas +++ b/Source/VirtualTrees.AncestorVcl.pas @@ -13,6 +13,9 @@ interface uses + Vcl.Controls, + Vcl.Themes, + Winapi.Messages, Winapi.Windows, Winapi.oleacc, Winapi.ActiveX, @@ -28,22 +31,50 @@ TVTAncestorVcl = class abstract(TBaseVirtualTree) FOnRenderOLEData: TVTRenderOLEDataEvent; // application/descendant defined clipboard formats protected + function GetHintWindowClass: THintWindowClass; override; + function GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree; override; function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; override; property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData; public //methods function PasteFromClipboard(): Boolean; override; end; + // The trees need an own hint window class because of Unicode output and adjusted font. + TVirtualTreeHintWindow = class(THintWindow) + strict private + FHintData: TVTHintData; + FTextHeight: TDimension; + procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED; + procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND; + strict protected + procedure CreateParams(var Params: TCreateParams); override; + procedure Paint; override; + // Mitigator function to use the correct style service for this context (either the style assigned to the control for Delphi > 10.4 or the application style) + function StyleServices(AControl: TControl = nil): TCustomStyleServices; + public + function CalcHintRect(MaxWidth: TDimension; const AHint: string; AData: Pointer): TRect; override; + function IsHintMsg(var Msg: TMsg): Boolean; override; + end; + implementation uses System.Classes, + Vcl.Graphics, + System.UITypes, Vcl.AxCtrls, + Vcl.Forms, + Vcl.GraphUtil, VirtualTrees.ClipBoard, - VirtualTrees.DataObject; + VirtualTrees.DataObject, + VirtualTrees.DragnDrop, + VirtualTrees.StyleHooks; resourcestring SClipboardFailed = 'Clipboard operation failed.'; +type + TBVTCracker = class(TBaseVirtualTree); + //---------------------------------------------------------------------------------------------------------------------- function TVTAncestorVcl.DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; @@ -55,6 +86,46 @@ function TVTAncestorVcl.DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Mediu //---------------------------------------------------------------------------------------------------------------------- +function TVTAncestorVcl.GetHintWindowClass: THintWindowClass; + +// Returns the default hint window class used for the tree. Descendants can override it to use their own classes. + +begin + Result := TVirtualTreeHintWindow; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +function TVTAncestorVcl.GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree; + +// Returns the owner/sender of the given data object by means of a special clipboard format +// or nil if the sender is in another process or no virtual tree at all. + +var + Medium: TStgMedium; + Data: PVTReference; + +begin + Result := nil; + if Assigned(DataObject) then + begin + StandardOLEFormat.cfFormat := CF_VTREFERENCE; + if DataObject.GetData(StandardOLEFormat, Medium) = S_OK then + begin + Data := GlobalLock(Medium.hGlobal); + if Assigned(Data) then + begin + if Data.Process = GetCurrentProcessID then + Result := Data.Tree; + GlobalUnlock(Medium.hGlobal); + end; + ReleaseStgMedium(Medium); + end; + end; +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TVTAncestorVcl.PasteFromClipboard(): Boolean; // Reads what is currently on the clipboard into the tree (if the format is supported). @@ -88,4 +159,336 @@ function TVTAncestorVcl.PasteFromClipboard(): Boolean; end; end; +//----------------- TVirtualTreeHintWindow ----------------------------------------------------------------------------- + +procedure TVirtualTreeHintWindow.CMTextChanged(var Message: TMessage); + +begin + // swallow this message to prevent the ancestor from resizing the window (we don't use the caption anyway) +end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TVirtualTreeHintWindow.WMEraseBkgnd(var Message: TWMEraseBkgnd); + +// The control is fully painted by own code so don't erase its background as this causes flickering. + +begin + Message.Result := 1; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TVirtualTreeHintWindow.CreateParams(var Params: TCreateParams); + +begin + inherited CreateParams(Params); + + with Params do + begin + Style := WS_POPUP; + ExStyle := ExStyle and not WS_EX_CLIENTEDGE; + end; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TVirtualTreeHintWindow.Paint(); +var + R: TRect; + Y: Integer; + S: string; + DrawFormat: Cardinal; + HintKind: TVTHintKind; + LClipRect: TRect; + + LColor: TColor; + LDetails: TThemedElementDetails; + LGradientStart: TColor; + LGradientEnd: TColor; + +begin + with FHintData do + begin + // Do actual painting only in the very first run. + // If the given node is nil then we have to display a header hint. + if (Node = nil) or (TBVTCracker(Tree).HintMode <> hmToolTip) then + begin + Canvas.Font := Screen.HintFont; + Canvas.Font.Height := MulDiv(Canvas.Font.Height, Tree.ScaledPixels(96), Screen.PixelsPerInch); // See issue #992 + Y := 2; + end + else + begin + Tree.GetTextInfo(Node, Column, Canvas.Font, R, S); + if LineBreakStyle = hlbForceMultiLine then + Y := 1 + else + Y := (R.Top - R.Bottom + Self.Height) div 2; + end; + + R := Rect(0, 0, Width, Height); + + HintKind := vhkText; + if Assigned(Node) then + TBVTCracker(Tree).DoGetHintKind(Node, Column, HintKind); + + if HintKind = vhkOwnerDraw then + begin + TBVTCracker(Tree).DoDrawHint(Canvas, Node, R, Column); + end + else + with Canvas do + begin + if TBVTCracker(Tree).VclStyleEnabled then + begin + InflateRect(R, -1, -1); // Fixes missing border when VCL styles are used + LDetails := StyleServices(Tree).GetElementDetails(thHintNormal); + if StyleServices(Tree).GetElementColor(LDetails, ecGradientColor1, LColor) and (LColor <> clNone) then + LGradientStart := LColor + else + LGradientStart := clInfoBk; + if StyleServices(Tree).GetElementColor(LDetails, ecGradientColor2, LColor) and (LColor <> clNone) then + LGradientEnd := LColor + else + LGradientEnd := clInfoBk; + if StyleServices(Tree).GetElementColor(LDetails, ecTextColor, LColor) and (LColor <> clNone) then + Font.Color := LColor + else + Font.Color := Screen.HintFont.Color; + GradientFillCanvas(Canvas, LGradientStart, LGradientEnd, R, gdVertical); + end + else + begin + // Still force tooltip back and text color. + Font.Color := clInfoText; + Pen.Color := clBlack; + Brush.Color := clInfoBk; + if StyleServices(Tree).Enabled and ((toThemeAware in TBVTCracker(Tree).TreeOptions.PaintOptions) or + (toUseExplorerTheme in TBVTCracker(Tree).TreeOptions.PaintOptions)) then + begin + if toUseExplorerTheme in TBVTCracker(Tree).TreeOptions.PaintOptions then // ToolTip style + StyleServices(Tree).DrawElement(Canvas.Handle, StyleServices(Tree).GetElementDetails(tttStandardNormal), R {$IF CompilerVersion >= 34}, nil, FCurrentPPI{$IFEND}) + else + begin // Hint style + LClipRect := R; + InflateRect(R, 4, 4); + StyleServices(Tree).DrawElement(Handle, StyleServices(Tree).GetElementDetails(tttStandardNormal), R, @LClipRect{$IF CompilerVersion >= 34}, FCurrentPPI{$IFEND}); + R := LClipRect; + StyleServices(Tree).DrawEdge(Handle, StyleServices(Tree).GetElementDetails(twWindowRoot), R, [eeRaisedOuter], [efRect]); + end; + end + else + if TBVTCracker(Tree).VclStyleEnabled then + StyleServices(Tree).DrawElement(Canvas.Handle, StyleServices(Tree).GetElementDetails(tttStandardNormal), R {$IF CompilerVersion >= 34}, nil, FCurrentPPI{$IFEND}) + else + Rectangle(R); + end; + // Determine text position and don't forget the border. + InflateRect(R, -1, -1); + DrawFormat := DT_TOP or DT_NOPREFIX; + SetBkMode(Handle, Winapi.Windows.TRANSPARENT); + R.Top := Y; + R.Left := R.Left + 3; // Make the text more centered + if Assigned(Node) and (LineBreakStyle = hlbForceMultiLine) then + DrawFormat := DrawFormat or DT_WORDBREAK; + Winapi.Windows.DrawTextW(Handle, PWideChar(HintText), Length(HintText), R, DrawFormat); + end; + end; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +function TVirtualTreeHintWindow.StyleServices(AControl: TControl): TCustomStyleServices; +begin + Result := VTStyleServices(AControl); +end; + +//---------------------------------------------------------------------------------------------------------------------- + +function TVirtualTreeHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect; + +var + TM: TTextMetric; + R: TRect; + +begin + try + if AData = nil then + // Defensive approach, it *can* happen that AData is nil. Maybe when several user defined hint classes are used. + Result := Rect(0, 0, 0, 0) + else + begin + // The hint window does not need any bidi mode setting but the caller of this method (TApplication.ActivateHint) + // does some unneccessary actions if the hint window is not left-to-right. + // The text alignment is based on the bidi mode passed in the hint data, hence we can + // simply set the window's mode to left-to-right (it might have been modified by the caller, if the + // tree window is right-to-left aligned). + BidiMode := bdLeftToRight; + + FHintData := PVTHintData(AData)^; + + with FHintData do + begin + // The draw tree gets its hint size by the application (but only if not a header hint is about to show). + // If the user will be drawing the hint, it gets its hint size by the application + // (but only if not a header hint is about to show). + // This size has already been determined in CMHintShow. + if Assigned(Node) and (not IsRectEmpty(HintRect)) then + Result := HintRect + else + begin + if Column <= NoColumn then + begin + BidiMode := Tree.BidiMode; + Alignment := TBVTCracker(Tree).Alignment; + end + else + begin + BidiMode := Tree.Header.Columns[Column].BidiMode; + Alignment := Tree.Header.Columns[Column].Alignment; + end; + + if BidiMode <> bdLeftToRight then + ChangeBidiModeAlignment(Alignment); + + if (Node = nil) or (TBVTCracker(Tree).HintMode <> hmToolTip) then + begin + Canvas.Font := Screen.HintFont; + Canvas.Font.Height := MulDiv(Canvas.Font.Height, Tree.ScaledPixels(96), Screen.PixelsPerInch); // See issue #992 + end + else + begin + Canvas.Font := Tree.Font; + with TBVTCracker(Tree) do + DoPaintText(Node, Self.Canvas, Column, ttNormal); + end; + + GetTextMetrics(Canvas.Handle, TM); + FTextHeight := TM.tmHeight; + + if Length(HintText) = 0 then + Result := Rect(0, 0, 0, 0) + else + begin + if Assigned(Node) and (TBVTCracker(Tree).HintMode = hmToolTip) then + begin + // Determine actual line break style depending on what was returned by the methods and what's in the node. + if LineBreakStyle = hlbDefault then + if (vsMultiline in Node.States) or HintText.Contains(#13) then + LineBreakStyle := hlbForceMultiLine + else + LineBreakStyle := hlbForceSingleLine; + + // Hint for a node. + if LineBreakStyle = hlbForceMultiLine then + begin + // Multiline tooltips use the columns width but extend the bottom border to fit the whole caption. + Result := Tree.GetDisplayRect(Node, Column, True, False); + R := Result; + + // On Windows NT/2K/XP the behavior of the tooltip is slightly different to that on Windows 9x/Me. + // We don't have Unicode word wrap on the latter so the tooltip gets as wide as the largest line + // in the caption (limited by carriage return), which results in unoptimal overlay of the tooltip. + Winapi.Windows.DrawTextW(Canvas.Handle, PWideChar(HintText), Length(HintText), R, DT_CALCRECT or DT_WORDBREAK); + if BidiMode = bdLeftToRight then + Result.Right := R.Right + TBVTCracker(Tree).TextMargin + else + Result.Left := R.Left - TBVTCracker(Tree).TextMargin + 1; + Result.Bottom := R.Bottom; + + Inc(Result.Right); + + // If the node height and the column width are both already large enough to cover the entire text, + // then we don't need the hint, though. + // However if the text is partially scrolled out of the client area then a hint is useful as well. + if (Tree.Header.Columns.Count > 0) and ((Tree.NodeHeight[Node] + 2) >= (Result.Bottom - Result.Top)) and + ((Tree.Header.Columns[Column].Width + 2) >= (Result.Right - Result.Left)) and not + ((Result.Left < 0) or (Result.Right > Tree.ClientWidth + 3) or + (Result.Top < 0) or (Result.Bottom > Tree.ClientHeight + 3)) then + begin + Result := Rect(0, 0, 0, 0); + Exit; + end; + end + else + begin + Result := TBVTCracker(Tree).LastHintRect; // = Tree.GetDisplayRect(Node, Column, True, True, True); see TBaseVirtualTree.CMHintShow + + { Fixes issue #623 + + Measure the rectangle to draw the text. The width of the result + is always adjusted according to the hint text because it may + be a custom hint coming in which can be larger or smaller than + the node text. + Earlier logic was using the current width of the node that was + either cutting off the hint text or producing undesired space + on the right. + } + R := Rect(0, 0, MaxWidth, FTextHeight); + Winapi.Windows.DrawTextW(Canvas.Handle, PWideChar(HintText), Length(HintText), R, DT_CALCRECT or DT_TOP or DT_NOPREFIX or DT_WORDBREAK); + if R.Right <> result.right - result.left then + begin + result.Right := result.Left + r.Right; + + //Space on right--taken from the code in the hmHint branch below. + if Assigned(Tree) then + Inc(Result.Right, TBVTCracker(Tree).TextMargin + TBVTCracker(Tree).Margin + Tree.ScaledPixels(4)); + end; + // Fix ends. + + if toShowHorzGridLines in TBVTCracker(Tree).TreeOptions.PaintOptions then + Dec(Result.Bottom); + end; + + // Include a one pixel border. + InflateRect(Result, 1, 1); + + // Make the coordinates relative. They will again be offset by the caller code. + OffsetRect(Result, -Result.Left - 1, -Result.Top - 1); + end + else + begin + // Hint for a header or non-tooltip hint. + + // Start with the base size of the hint in client coordinates. + Result := Rect(0, 0, MaxWidth, FTextHeight); + // Calculate the true size of the text rectangle. + Winapi.Windows.DrawTextW(Canvas.Handle, PWideChar(HintText), Length(HintText), Result, DT_CALCRECT or DT_TOP or DT_NOPREFIX or DT_WORDBREAK); + // The height of the text plus 2 pixels vertical margin plus the border determine the hint window height. + // Minus 4 because THintWindow.ActivateHint adds 4 to Rect.Bottom anyway. Note that it is not scaled because the RTL itself does not do any scaling either. + Inc(Result.Bottom, Tree.ScaledPixels(6) - 4); + // The text is centered horizontally with usual text margin for left and right borders (plus border). + if not Assigned(Tree) then + Exit; // Workaround, because we have seen several exceptions here caught by Eurekalog. Submitted as issue #114 to http://code.google.com/p/virtual-treeview/ + { Issue #623 Fix for strange space on the right. + Original logic was adding FTextHeight. Changed it to add FMargin instead and + it looks OK even if the hint font is larger. + } + Inc(Result.Right, TBVTCracker(Tree).TextMargin + + TBVTCracker(Tree).Margin + Tree.ScaledPixels(4)); //Issue #623 space on right + //+ FTextHeight); // Old code: We are extending the width here, but the text height scales with the text width and has a similar value as AveCharWdith * 2. + end; + end; + end; + end; + end; + except + Application.HandleException(Self); + end; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +function TVirtualTreeHintWindow.IsHintMsg(var Msg: TMsg): Boolean; + +// The VCL is a bit too generous when telling that an existing hint can be cancelled. Need to specify further here. + +begin + Result := inherited IsHintMsg(Msg) and HandleAllocated and IsWindowVisible(Handle); + // Avoid that mouse moves over the non-client area or cursor key presses cancel the current hint. + if Result and ((Msg.Message = WM_NCMOUSEMOVE) or ((Msg.Message >= WM_KEYFIRST) and (Msg.Message <= WM_KEYLAST) and (Msg.wparam in [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT]))) then + Result := False; +end; + end. diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index 1672a327..fa17cde2 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -103,6 +103,7 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) implementation uses + System.SyncObjs, Vcl.AxCtrls, VirtualTrees.DataObject, VirtualTrees.Clipboard, @@ -110,6 +111,64 @@ implementation //---------------------------------------------------------------------------------------------------------------------- +const + Grays: array[0..3] of TColor = (clWhite, clSilver, clGray, clBlack); + SysGrays: array[0..3] of TColor = (clWindow, clBtnFace, clBtnShadow, clBtnText); + +//not used curently anywhere, moved to VCL, to remove ifdef (gWatcher is declared in VirtualTrees.BaseTree) +procedure ConvertImageList(gWatcher: TCriticalSection; BaseVirtualTreeClass: TClass; IL: TImageList; const ImageName: string; ColorRemapping: Boolean = True); + +// Loads a bunch of images given by ImageName into IL. If ColorRemapping = True then a mapping of gray values to +// system colors is performed. + +var + lImages, + lOneImage: TBitmap; + I: Integer; + MaskColor: TColor; + Source, + Dest: TRect; + +begin + gWatcher.Enter(); + try + // Since we want the image list appearing in the correct system colors, we have to remap its colors. + lImages := TBitmap.Create; + lOneImage := TBitmap.Create; + if ColorRemapping then + lImages.Handle := CreateMappedRes(FindClassHInstance(BaseVirtualTreeClass), PChar(ImageName), Grays, SysGrays) + else + lImages.Handle := LoadBitmap(FindClassHInstance(BaseVirtualTreeClass), PChar(ImageName)); + + try + Assert(lImages.Height > 0, 'Internal image "' + ImageName + '" is missing or corrupt.'); + if lImages.Height = 0 then + Exit;// This should never happen, it prevents a division by zero exception below in the for loop, which we have seen in a few cases + // It is assumed that the image height determines also the width of one entry in the image list. + IL.Clear; + IL.Height := lImages.Height; + IL.Width := lImages.Height; + lOneImage.Width := IL.Width; + lOneImage.Height := IL.Height; + MaskColor := lImages.Canvas.Pixels[0, 0]; // this is usually clFuchsia + Dest := Rect(0, 0, IL.Width, IL.Height); + for I := 0 to (lImages.Width div lImages.Height) - 1 do + begin + Source := Rect(I * IL.Width, 0, (I + 1) * IL.Width, IL.Height); + lOneImage.Canvas.CopyRect(Dest, lImages.Canvas, Source); + IL.AddMasked(lOneImage, MaskColor); + end; + finally + lImages.Free; + lOneImage.Free; + end; + finally + gWatcher.Leave(); + end; +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TVTBaseAncestorVcl.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; // Returns a memory expression of all currently selected nodes in the Medium structure. diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 5c45bf02..aeedec7d 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -161,23 +161,6 @@ TVTHintData = record LineBreakStyle: TVTToolTipLineBreakStyle; end; - // The trees need an own hint window class because of Unicode output and adjusted font. - TVirtualTreeHintWindow = class(THintWindow) - strict private - FHintData: TVTHintData; - FTextHeight: TDimension; - procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED; - procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND; - strict protected - procedure CreateParams(var Params: TCreateParams); override; - procedure Paint; override; - // Mitigator function to use the correct style service for this context (either the style assigned to the control for Delphi > 10.4 or the application style) - function StyleServices(AControl: TControl = nil): TCustomStyleServices; - public - function CalcHintRect(MaxWidth: TDimension; const AHint: string; AData: Pointer): TRect; override; - function IsHintMsg(var Msg: TMsg): Boolean; override; - end; - // Communication interface between a tree editor and the tree itself (declared as using stdcall in case it // is implemented in a (C/C++) DLL). The GUID is not nessecary in Delphi but important for BCB users // to allow QueryInterface and _uuidof calls. @@ -1098,7 +1081,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) function GetColumnClass: TVirtualTreeColumnClass; virtual; function GetDefaultHintKind: TVTHintKind; virtual; function GetHeaderClass: TVTHeaderClass; virtual; - function GetHintWindowClass: THintWindowClass; virtual; + function GetHintWindowClass: THintWindowClass; virtual; abstract; procedure GetImageIndex(var Info: TVTPaintInfo; Kind: TVTImageKind; InfoIndex: TVTImageInfoIndex); virtual; function GetImageSize(Node: PVirtualNode; Kind: TVTImageKind = TVTImageKind.ikNormal; Column: TColumnIndex = 0; IncludePadding: Boolean = True): TSize; virtual; function GetNodeImageSize(Node: PVirtualNode): TSize; virtual; deprecated 'Use GetImageSize instead'; @@ -1806,67 +1789,6 @@ procedure QuickSort(const TheArray: TNodeArray; L, R: Integer); until I >= R; end; - -//---------------------------------------------------------------------------------------------------------------------- - - - - -const - Grays: array[0..3] of TColor = (clWhite, clSilver, clGray, clBlack); - SysGrays: array[0..3] of TColor = (clWindow, clBtnFace, clBtnShadow, clBtnText); - -procedure ConvertImageList(IL: TImageList; const ImageName: string; ColorRemapping: Boolean = True); - -// Loads a bunch of images given by ImageName into IL. If ColorRemapping = True then a mapping of gray values to -// system colors is performed. - -var - lImages, - lOneImage: TBitmap; - I: Integer; - MaskColor: TColor; - Source, - Dest: TRect; - -begin - gWatcher.Enter(); - try - // Since we want the image list appearing in the correct system colors, we have to remap its colors. - lImages := TBitmap.Create; - lOneImage := TBitmap.Create; - if ColorRemapping then - lImages.Handle := CreateMappedRes(FindClassHInstance(TBaseVirtualTree), PChar(ImageName), Grays, SysGrays) - else - lImages.Handle := LoadBitmap(FindClassHInstance(TBaseVirtualTree), PChar(ImageName)); - - try - Assert(lImages.Height > 0, 'Internal image "' + ImageName + '" is missing or corrupt.'); - if lImages.Height = 0 then - Exit;// This should never happen, it prevents a division by zero exception below in the for loop, which we have seen in a few cases - // It is assumed that the image height determines also the width of one entry in the image list. - IL.Clear; - IL.Height := lImages.Height; - IL.Width := lImages.Height; - lOneImage.Width := IL.Width; - lOneImage.Height := IL.Height; - MaskColor := lImages.Canvas.Pixels[0, 0]; // this is usually clFuchsia - Dest := Rect(0, 0, IL.Width, IL.Height); - for I := 0 to (lImages.Width div lImages.Height) - 1 do - begin - Source := Rect(I * IL.Width, 0, (I + 1) * IL.Width, IL.Height); - lOneImage.Canvas.CopyRect(Dest, lImages.Canvas, Source); - IL.AddMasked(lOneImage, MaskColor); - end; - finally - lImages.Free; - lOneImage.Free; - end; - finally - gWatcher.Leave(); - end; -end; - //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.CreateSystemImageSet(): TImageList; @@ -2001,339 +1923,6 @@ function TBaseVirtualTree.CreateSystemImageSet(): TImageList; end; -//----------------- TVirtualTreeHintWindow ----------------------------------------------------------------------------- - -procedure TVirtualTreeHintWindow.CMTextChanged(var Message: TMessage); - -begin - // swallow this message to prevent the ancestor from resizing the window (we don't use the caption anyway) -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVirtualTreeHintWindow.WMEraseBkgnd(var Message: TWMEraseBkgnd); - -// The control is fully painted by own code so don't erase its background as this causes flickering. - -begin - Message.Result := 1; -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVirtualTreeHintWindow.CreateParams(var Params: TCreateParams); - -begin - inherited CreateParams(Params); - - with Params do - begin - Style := WS_POPUP; - ExStyle := ExStyle and not WS_EX_CLIENTEDGE; - end; -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVirtualTreeHintWindow.Paint(); -var - R: TRect; - Y: Integer; - S: string; - DrawFormat: Cardinal; - HintKind: TVTHintKind; - LClipRect: TRect; - - LColor: TColor; - LDetails: TThemedElementDetails; - LGradientStart: TColor; - LGradientEnd: TColor; - -begin - with FHintData do - begin - // Do actual painting only in the very first run. - // If the given node is nil then we have to display a header hint. - if (Node = nil) or (Tree.FHintMode <> hmToolTip) then - begin - Canvas.Font := Screen.HintFont; - Canvas.Font.Height := MulDiv(Canvas.Font.Height, Tree.ScaledPixels(96), Screen.PixelsPerInch); // See issue #992 - Y := 2; - end - else - begin - Tree.GetTextInfo(Node, Column, Canvas.Font, R, S); - if LineBreakStyle = hlbForceMultiLine then - Y := 1 - else - Y := (R.Top - R.Bottom + Self.Height) div 2; - end; - - R := Rect(0, 0, Width, Height); - - HintKind := vhkText; - if Assigned(Node) then - Tree.DoGetHintKind(Node, Column, HintKind); - - if HintKind = vhkOwnerDraw then - begin - Tree.DoDrawHint(Canvas, Node, R, Column); - end - else - with Canvas do - begin - if Tree.VclStyleEnabled then - begin - InflateRect(R, -1, -1); // Fixes missing border when VCL styles are used - LDetails := StyleServices(Tree).GetElementDetails(thHintNormal); - if StyleServices(Tree).GetElementColor(LDetails, ecGradientColor1, LColor) and (LColor <> clNone) then - LGradientStart := LColor - else - LGradientStart := clInfoBk; - if StyleServices(Tree).GetElementColor(LDetails, ecGradientColor2, LColor) and (LColor <> clNone) then - LGradientEnd := LColor - else - LGradientEnd := clInfoBk; - if StyleServices(Tree).GetElementColor(LDetails, ecTextColor, LColor) and (LColor <> clNone) then - Font.Color := LColor - else - Font.Color := Screen.HintFont.Color; - GradientFillCanvas(Canvas, LGradientStart, LGradientEnd, R, gdVertical); - end - else - begin - // Still force tooltip back and text color. - Font.Color := clInfoText; - Pen.Color := clBlack; - Brush.Color := clInfoBk; - if StyleServices(Tree).Enabled and ((toThemeAware in Tree.TreeOptions.PaintOptions) or - (toUseExplorerTheme in Tree.TreeOptions.PaintOptions)) then - begin - if toUseExplorerTheme in Tree.TreeOptions.PaintOptions then // ToolTip style - StyleServices(Tree).DrawElement(Canvas.Handle, StyleServices(Tree).GetElementDetails(tttStandardNormal), R {$IF CompilerVersion >= 34}, nil, FCurrentPPI{$IFEND}) - else - begin // Hint style - LClipRect := R; - InflateRect(R, 4, 4); - StyleServices(Tree).DrawElement(Handle, StyleServices(Tree).GetElementDetails(tttStandardNormal), R, @LClipRect{$IF CompilerVersion >= 34}, FCurrentPPI{$IFEND}); - R := LClipRect; - StyleServices(Tree).DrawEdge(Handle, StyleServices(Tree).GetElementDetails(twWindowRoot), R, [eeRaisedOuter], [efRect]); - end; - end - else - if Tree.VclStyleEnabled then - StyleServices(Tree).DrawElement(Canvas.Handle, StyleServices(Tree).GetElementDetails(tttStandardNormal), R {$IF CompilerVersion >= 34}, nil, FCurrentPPI{$IFEND}) - else - Rectangle(R); - end; - // Determine text position and don't forget the border. - InflateRect(R, -1, -1); - DrawFormat := DT_TOP or DT_NOPREFIX; - SetBkMode(Handle, Winapi.Windows.TRANSPARENT); - R.Top := Y; - R.Left := R.Left + 3; // Make the text more centered - if Assigned(Node) and (LineBreakStyle = hlbForceMultiLine) then - DrawFormat := DrawFormat or DT_WORDBREAK; - Winapi.Windows.DrawTextW(Handle, PWideChar(HintText), Length(HintText), R, DrawFormat); - end; - end; -end; - -//---------------------------------------------------------------------------------------------------------------------- - -function TVirtualTreeHintWindow.StyleServices(AControl: TControl): TCustomStyleServices; -begin - Result := VTStyleServices(AControl); -end; - -//---------------------------------------------------------------------------------------------------------------------- - -function TVirtualTreeHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect; - -var - TM: TTextMetric; - R: TRect; - -begin - try - if AData = nil then - // Defensive approach, it *can* happen that AData is nil. Maybe when several user defined hint classes are used. - Result := Rect(0, 0, 0, 0) - else - begin - // The hint window does not need any bidi mode setting but the caller of this method (TApplication.ActivateHint) - // does some unneccessary actions if the hint window is not left-to-right. - // The text alignment is based on the bidi mode passed in the hint data, hence we can - // simply set the window's mode to left-to-right (it might have been modified by the caller, if the - // tree window is right-to-left aligned). - BidiMode := bdLeftToRight; - - FHintData := PVTHintData(AData)^; - - with FHintData do - begin - // The draw tree gets its hint size by the application (but only if not a header hint is about to show). - // If the user will be drawing the hint, it gets its hint size by the application - // (but only if not a header hint is about to show). - // This size has already been determined in CMHintShow. - if Assigned(Node) and (not IsRectEmpty(HintRect)) then - Result := HintRect - else - begin - if Column <= NoColumn then - begin - BidiMode := Tree.BidiMode; - Alignment := Tree.Alignment; - end - else - begin - BidiMode := Tree.Header.Columns[Column].BidiMode; - Alignment := Tree.Header.Columns[Column].Alignment; - end; - - if BidiMode <> bdLeftToRight then - ChangeBidiModeAlignment(Alignment); - - if (Node = nil) or (Tree.FHintMode <> hmToolTip) then - begin - Canvas.Font := Screen.HintFont; - Canvas.Font.Height := MulDiv(Canvas.Font.Height, Tree.ScaledPixels(96), Screen.PixelsPerInch); // See issue #992 - end - else - begin - Canvas.Font := Tree.Font; - with TBaseVirtualTreeCracker(Tree) do - DoPaintText(Node, Self.Canvas, Column, ttNormal); - end; - - GetTextMetrics(Canvas.Handle, TM); - FTextHeight := TM.tmHeight; - - if Length(HintText) = 0 then - Result := Rect(0, 0, 0, 0) - else - begin - if Assigned(Node) and (Tree.FHintMode = hmToolTip) then - begin - // Determine actual line break style depending on what was returned by the methods and what's in the node. - if LineBreakStyle = hlbDefault then - if (vsMultiline in Node.States) or HintText.Contains(#13) then - LineBreakStyle := hlbForceMultiLine - else - LineBreakStyle := hlbForceSingleLine; - - // Hint for a node. - if LineBreakStyle = hlbForceMultiLine then - begin - // Multiline tooltips use the columns width but extend the bottom border to fit the whole caption. - Result := Tree.GetDisplayRect(Node, Column, True, False); - R := Result; - - // On Windows NT/2K/XP the behavior of the tooltip is slightly different to that on Windows 9x/Me. - // We don't have Unicode word wrap on the latter so the tooltip gets as wide as the largest line - // in the caption (limited by carriage return), which results in unoptimal overlay of the tooltip. - Winapi.Windows.DrawTextW(Canvas.Handle, PWideChar(HintText), Length(HintText), R, DT_CALCRECT or DT_WORDBREAK); - if BidiMode = bdLeftToRight then - Result.Right := R.Right + Tree.FTextMargin - else - Result.Left := R.Left - Tree.FTextMargin + 1; - Result.Bottom := R.Bottom; - - Inc(Result.Right); - - // If the node height and the column width are both already large enough to cover the entire text, - // then we don't need the hint, though. - // However if the text is partially scrolled out of the client area then a hint is useful as well. - if (Tree.Header.Columns.Count > 0) and ((Tree.NodeHeight[Node] + 2) >= (Result.Bottom - Result.Top)) and - ((Tree.Header.Columns[Column].Width + 2) >= (Result.Right - Result.Left)) and not - ((Result.Left < 0) or (Result.Right > Tree.ClientWidth + 3) or - (Result.Top < 0) or (Result.Bottom > Tree.ClientHeight + 3)) then - begin - Result := Rect(0, 0, 0, 0); - Exit; - end; - end - else - begin - Result := Tree.FLastHintRect; // = Tree.GetDisplayRect(Node, Column, True, True, True); see TBaseVirtualTree.CMHintShow - - { Fixes issue #623 - - Measure the rectangle to draw the text. The width of the result - is always adjusted according to the hint text because it may - be a custom hint coming in which can be larger or smaller than - the node text. - Earlier logic was using the current width of the node that was - either cutting off the hint text or producing undesired space - on the right. - } - R := Rect(0, 0, MaxWidth, FTextHeight); - Winapi.Windows.DrawTextW(Canvas.Handle, PWideChar(HintText), Length(HintText), R, DT_CALCRECT or DT_TOP or DT_NOPREFIX or DT_WORDBREAK); - if R.Right <> result.right - result.left then - begin - result.Right := result.Left + r.Right; - - //Space on right--taken from the code in the hmHint branch below. - if Assigned(Tree) then - Inc(Result.Right, Tree.FTextMargin + Tree.FMargin + Tree.ScaledPixels(4)); - end; - // Fix ends. - - if toShowHorzGridLines in Tree.TreeOptions.PaintOptions then - Dec(Result.Bottom); - end; - - // Include a one pixel border. - InflateRect(Result, 1, 1); - - // Make the coordinates relative. They will again be offset by the caller code. - OffsetRect(Result, -Result.Left - 1, -Result.Top - 1); - end - else - begin - // Hint for a header or non-tooltip hint. - - // Start with the base size of the hint in client coordinates. - Result := Rect(0, 0, MaxWidth, FTextHeight); - // Calculate the true size of the text rectangle. - Winapi.Windows.DrawTextW(Canvas.Handle, PWideChar(HintText), Length(HintText), Result, DT_CALCRECT or DT_TOP or DT_NOPREFIX or DT_WORDBREAK); - // The height of the text plus 2 pixels vertical margin plus the border determine the hint window height. - // Minus 4 because THintWindow.ActivateHint adds 4 to Rect.Bottom anyway. Note that it is not scaled because the RTL itself does not do any scaling either. - Inc(Result.Bottom, Tree.ScaledPixels(6) - 4); - // The text is centered horizontally with usual text margin for left and right borders (plus border). - if not Assigned(Tree) then - Exit; // Workaround, because we have seen several exceptions here caught by Eurekalog. Submitted as issue #114 to http://code.google.com/p/virtual-treeview/ - { Issue #623 Fix for strange space on the right. - Original logic was adding FTextHeight. Changed it to add FMargin instead and - it looks OK even if the hint font is larger. - } - Inc(Result.Right, Tree.FTextMargin - + Tree.FMargin + Tree.ScaledPixels(4)); //Issue #623 space on right - //+ FTextHeight); // Old code: We are extending the width here, but the text height scales with the text width and has a similar value as AveCharWdith * 2. - end; - end; - end; - end; - end; - except - Application.HandleException(Self); - end; -end; - -//---------------------------------------------------------------------------------------------------------------------- - -function TVirtualTreeHintWindow.IsHintMsg(var Msg: TMsg): Boolean; - -// The VCL is a bit too generous when telling that an existing hint can be cancelled. Need to specify further here. - -begin - Result := inherited IsHintMsg(Msg) and HandleAllocated and IsWindowVisible(Handle); - // Avoid that mouse moves over the non-client area or cursor key presses cancel the current hint. - if Result and ((Msg.Message = WM_NCMOUSEMOVE) or ((Msg.Message >= WM_KEYFIRST) and (Msg.Message <= WM_KEYLAST) and (Msg.wparam in [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT]))) then - Result := False; -end; - - //----------------- TVTVirtualNodeEnumerator --------------------------------------------------------------------------- function TVTVirtualNodeEnumerator.GetCurrent: PVirtualNode; @@ -12343,16 +11932,6 @@ function TBaseVirtualTree.GetHeaderClass: TVTHeaderClass; //---------------------------------------------------------------------------------------------------------------------- -function TBaseVirtualTree.GetHintWindowClass: THintWindowClass; - -// Returns the default hint window class used for the tree. Descendants can override it to use their own classes. - -begin - Result := TVirtualTreeHintWindow; -end; - -//---------------------------------------------------------------------------------------------------------------------- - procedure TBaseVirtualTree.GetImageIndex(var Info: TVTPaintInfo; Kind: TVTImageKind; InfoIndex: TVTImageInfoIndex); // Retrieves the image index and an eventual customized image list for drawing. @@ -12492,31 +12071,8 @@ function TBaseVirtualTree.GetOptionsClass: TTreeOptionsClass; //---------------------------------------------------------------------------------------------------------------------- function TBaseVirtualTree.GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree; - -// Returns the owner/sender of the given data object by means of a special clipboard format -// or nil if the sender is in another process or no virtual tree at all. - -var - Medium: TStgMedium; - Data: PVTReference; - begin - Result := nil; - if Assigned(DataObject) then - begin - StandardOLEFormat.cfFormat := CF_VTREFERENCE; - if DataObject.GetData(StandardOLEFormat, Medium) = S_OK then - begin - Data := GlobalLock(Medium.hGlobal); - if Assigned(Data) then - begin - if Data.Process = GetCurrentProcessID then - Result := Data.Tree; - GlobalUnlock(Medium.hGlobal); - end; - ReleaseStgMedium(Medium); - end; - end; + Result:= nil; end; //---------------------------------------------------------------------------------------------------------------------- From 7c4f9b75a2023331d0c1de7bb99a1a8a8270941e Mon Sep 17 00:00:00 2001 From: livius2 Date: Thu, 2 Nov 2023 21:30:33 +0100 Subject: [PATCH 21/28] CreateSystemImageSet, SetWindowTheme and small cleanup another small step. - moved vcl code of CreateSystemImageSet - moved specific vcl SetWindowTheme - small cleanup of unused TCanvasEx, WideCR, WideLF --- Source/VirtualTrees.BaseAncestorFMX.pas | 19 ++- Source/VirtualTrees.BaseAncestorVcl.pas | 149 +++++++++++++++++++++++- Source/VirtualTrees.BaseTree.pas | 146 +---------------------- 3 files changed, 170 insertions(+), 144 deletions(-) diff --git a/Source/VirtualTrees.BaseAncestorFMX.pas b/Source/VirtualTrees.BaseAncestorFMX.pas index 276e08c3..e080368b 100644 --- a/Source/VirtualTrees.BaseAncestorFMX.pas +++ b/Source/VirtualTrees.BaseAncestorFMX.pas @@ -60,6 +60,8 @@ TVTBaseAncestorFMX = class abstract(TRectangle) procedure DragCanceled; virtual; abstract; procedure Resize; override; + function CreateSystemImageSet(): TImageList; + procedure SetWindowTheme(const Theme: string); virtual; procedure ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); virtual; abstract; function GetControlsAlignment: TAlignment; virtual; abstract; @@ -68,7 +70,7 @@ TVTBaseAncestorFMX = class abstract(TRectangle) procedure MarkCutCopyNodes; virtual; abstract; function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; virtual; abstract; function GetSortedSelection(Resolve: Boolean): TNodeArray; virtual; abstract; - procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; + procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; protected //properties property DottedBrushTreeLines: TStrokeBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; property DottedBrushGridLines: TStrokeBrush read FDottedBrushGridLines write FDottedBrushGridLines; @@ -606,4 +608,19 @@ function TVTBaseAncestorFMX.GetSystemMetrics(nIndex: Integer): Integer; {$ENDIF} end; +//---------------------------------------------------------------------------------------------------------------------- + +function TVTBaseAncestorFMX.CreateSystemImageSet(): TImageList; +begin + Result:= TImageList.Create(Self); + FillSystemCheckImages(Self, Result); +end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TVTBaseAncestorFMX.SetWindowTheme(const Theme: string); +begin + //nothing +end; + end. diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index fa17cde2..6e5ad0d8 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -37,6 +37,8 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; virtual; procedure NotifyAccessibleEvent(pEvent: DWord = EVENT_OBJECT_STATECHANGE); function PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Pointer; const BitsLinesCount: Word): TBrush; virtual; + function CreateSystemImageSet(): TImageList; + procedure SetWindowTheme(const Theme: string); virtual; //// Abtract method that are implemented in TBaseVirtualTree, keep in sync with TVTBaseAncestorFMX function GetSelectedCount(): Integer; virtual; abstract; procedure MarkCutCopyNodes; virtual; abstract; @@ -104,10 +106,17 @@ implementation uses System.SyncObjs, + System.SysUtils, Vcl.AxCtrls, + Vcl.Forms, + Vcl.Themes, + Winapi.CommCtrl, + Winapi.ShlObj, + Winapi.UxTheme, VirtualTrees.DataObject, VirtualTrees.Clipboard, - VirtualTrees.AccessibilityFactory; + VirtualTrees.AccessibilityFactory, + VirtualTrees.StyleHooks; //---------------------------------------------------------------------------------------------------------------------- @@ -283,6 +292,137 @@ procedure TVTBaseAncestorVcl.CopyToClipboard; end; end; +function TVTBaseAncestorVcl.CreateSystemImageSet: TImageList; + +// Creates a system check image set. +// Note: the DarkCheckImages and FlatImages image lists must already be filled, as some images from them are copied here. + +const + MaskColor: TColor = clRed; + cFlags = ILC_COLOR32 or ILC_MASK; + +var + BM: TBitmap; + Theme: HTHEME; + Details: TThemedElementDetails; + + //--------------------------------------------------------------------------- + + // Mitigator function to use the correct style service for this context (either the style assigned to the control for Delphi > 10.4 or the application style) + function StyleServices: TCustomStyleServices; + begin + Result := VTStyleServices(Self); + end; + + procedure AddSystemImage(IL: TImageList; Index: Integer); + const + States: array [0..19] of Integer = ( + RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDDISABLED, + RBS_CHECKEDNORMAL, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDDISABLED, + CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDDISABLED, + CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDDISABLED, + CBS_MIXEDNORMAL, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDDISABLED); + var + ButtonState: Cardinal; + ButtonType: Cardinal; + + begin + BM.Canvas.FillRect(Rect(0, 0, BM.Width, BM.Height)); + if StyleServices.Enabled and StyleServices.IsSystemStyle then + begin + if Index < 8 then + Details.Part := BP_RADIOBUTTON + else + Details.Part := BP_CHECKBOX; + Details.State := States[Index]; + DrawThemeBackground(Theme, BM.Canvas.Handle, Details.Part, Details.State, Rect(0, 0, BM.Width, BM.Height), nil); + end + else + begin + if Index < 8 then + ButtonType := DFCS_BUTTONRADIO + else + ButtonType := DFCS_BUTTONCHECK; + if Index >= 16 then + ButtonType := ButtonType or DFCS_BUTTON3STATE; + + case Index mod 4 of + 0: + ButtonState := 0; + 1: + ButtonState := DFCS_HOT; + 2: + ButtonState := DFCS_PUSHED; + else + ButtonState := DFCS_INACTIVE; + end; + if Index in [4..7, 12..19] then + ButtonState := ButtonState or DFCS_CHECKED; +// if Flat then +// ButtonState := ButtonState or DFCS_FLAT; + DrawFrameControl(BM.Canvas.Handle, Rect(0, 0, BM.Width, BM.Height), DFC_BUTTON, ButtonType or ButtonState); + end; + IL.AddMasked(BM, MaskColor); + end; + + //--------------- end local functions --------------------------------------- + +const + cDefaultCheckboxSize = 13;// Used when no other value is available +var + I: Integer; + lSize: TSize; + Res: Boolean; +begin + BM := TBitmap.Create; // Create a temporary bitmap, which holds the intermediate images. + try + Res := False; + // Retrieve the checkbox image size, prefer theme if available, fall back to GetSystemMetrics() otherwise, but this returns odd results on Windows 8 and higher in high-dpi scenarios. + if StyleServices.Enabled then + if StyleServices.IsSystemStyle then + begin + {$if CompilerVersion >= 33} + if TOSVersion.Check(10) and (TOSVersion.Build >= 15063) then + Theme := OpenThemeDataForDPI(Handle, 'BUTTON', CurrentPPI) + else + {$ifend} + Theme := OpenThemeData(Self.Handle, 'BUTTON'); + Details := StyleServices.GetElementDetails(tbCheckBoxUncheckedNormal); + Res := GetThemePartSize(Theme, BM.Canvas.Handle, Details.Part, Details.State, nil, TS_TRUE, lSize) = S_OK; + end + else + Res := StyleServices.GetElementSize(BM.Canvas.Handle, StyleServices.GetElementDetails(tbCheckBoxUncheckedNormal), TElementSize.esActual, lSize {$IF CompilerVersion >= 34}, Self.CurrentPPI{$IFEND}); + if not Res then begin + lSize := TSize.Create(GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK)); + if lSize.cx = 0 then begin // error? (Should happen rarely only) + lSize.cx := MulDiv(cDefaultCheckboxSize, Screen.PixelsPerInch, USER_DEFAULT_SCREEN_DPI); + lSize.cy := lSize.cx; + end;// if + end;//if + + Result := TImageList.CreateSize(lSize.cx, lSize.cy); + Result.Handle := ImageList_Create(Result.Width, Result.Height, cFlags, 0, Result.AllocBy); + Result.Masked := True; + Result.BkColor := clWhite; + + // Make the bitmap the same size as the image list is to avoid problems when adding. + BM.SetSize(Result.Width, Result.Height); + BM.Canvas.Brush.Color := MaskColor; + BM.Canvas.Brush.Style := bsSolid; + BM.Canvas.FillRect(Rect(0, 0, BM.Width, BM.Height)); + Result.AddMasked(BM, MaskColor); + + // Add the 20 system checkbox and radiobutton images. + for I := 0 to 19 do + AddSystemImage(Result, I); + if StyleServices.Enabled and StyleServices.IsSystemStyle then + CloseThemeData(Theme); + + finally + BM.Free; + end; +end; + procedure TVTBaseAncestorVcl.CutToClipboard; var lDataObject: IDataObject; @@ -409,6 +549,13 @@ function TVTBaseAncestorVcl.SetScrollInfo(Bar: Integer; const ScrollInfo: TScrol //---------------------------------------------------------------------------------------------------------------------- +procedure TVTBaseAncestorVcl.SetWindowTheme(const Theme: string); +begin + Winapi.UxTheme.SetWindowTheme(Handle, PWideChar(Theme), nil); +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TVTBaseAncestorVcl.GetScrollInfo(Bar: Integer; var ScrollInfo: TScrollInfo): Boolean; begin Result:= WinApi.Windows.GetScrollInfo(Handle, Bar, ScrollInfo); diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index aeedec7d..65ab8cdd 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -734,7 +734,6 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) NewRect: TRect): Boolean; procedure ClearNodeBackground(const PaintInfo: TVTPaintInfo; UseBackground, Floating: Boolean; R: TRect); function CompareNodePositions(Node1, Node2: PVirtualNode; ConsiderChildrenAbove: Boolean = False): Integer; - function CreateSystemImageSet(): TImageList; procedure DrawLineImage(const PaintInfo: TVTPaintInfo; X, Y, H, VAlign: TDimension; Style: TVTLineType; Reverse: Boolean); function FindInPositionCache(Node: PVirtualNode; var CurrentPos: TDimension): PVirtualNode; overload; function FindInPositionCache(Position: TDimension; var CurrentPos: TDimension): PVirtualNode; overload; @@ -1144,7 +1143,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) procedure SetChildCount(Node: PVirtualNode; NewChildCount: Cardinal); virtual; procedure SetFocusedNodeAndColumn(Node: PVirtualNode; Column: TColumnIndex); virtual; procedure SetRangeX(value: TDimension); - procedure SetWindowTheme(const Theme: string); + procedure SetWindowTheme(const Theme: string); override; procedure SetVisibleCount(value : Cardinal); procedure SkipNode(Stream: TStream); virtual; procedure StartOperation(OperationKind: TVTOperationKind); @@ -1724,15 +1723,10 @@ TToggleAnimationData = record MissedSteps: Double; end; - TCanvasEx = class(TCanvas); - const MagicID: TMagicID = (#$2045, 'V', 'T', WideChar(VTTreeStreamVersion), ' ', #$2046); - WideCR = Char(#13); - WideLF = Char(#10); - var gWatcher: TCriticalSection = nil; gInitialized: Integer = 0; // >0 if global structures have been initialized; otherwise 0 @@ -1789,140 +1783,6 @@ procedure QuickSort(const TheArray: TNodeArray; L, R: Integer); until I >= R; end; -//---------------------------------------------------------------------------------------------------------------------- - -function TBaseVirtualTree.CreateSystemImageSet(): TImageList; - -// Creates a system check image set. -// Note: the DarkCheckImages and FlatImages image lists must already be filled, as some images from them are copied here. - -const - MaskColor: TColor = clRed; - cFlags = ILC_COLOR32 or ILC_MASK; - -var - BM: TBitmap; - Theme: HTHEME; - Details: TThemedElementDetails; - - //--------------------------------------------------------------------------- - - // Mitigator function to use the correct style service for this context (either the style assigned to the control for Delphi > 10.4 or the application style) - function StyleServices: TCustomStyleServices; - begin - Result := VTStyleServices(Self); - end; - - procedure AddSystemImage(IL: TImageList; Index: Integer); - const - States: array [0..19] of Integer = ( - RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED, RBS_UNCHECKEDDISABLED, - RBS_CHECKEDNORMAL, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED, RBS_CHECKEDDISABLED, - CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDDISABLED, - CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDDISABLED, - CBS_MIXEDNORMAL, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDDISABLED); - var - ButtonState: Cardinal; - ButtonType: Cardinal; - - begin - BM.Canvas.FillRect(Rect(0, 0, BM.Width, BM.Height)); - if StyleServices.Enabled and StyleServices.IsSystemStyle then - begin - if Index < 8 then - Details.Part := BP_RADIOBUTTON - else - Details.Part := BP_CHECKBOX; - Details.State := States[Index]; - DrawThemeBackground(Theme, BM.Canvas.Handle, Details.Part, Details.State, Rect(0, 0, BM.Width, BM.Height), nil); - end - else - begin - if Index < 8 then - ButtonType := DFCS_BUTTONRADIO - else - ButtonType := DFCS_BUTTONCHECK; - if Index >= 16 then - ButtonType := ButtonType or DFCS_BUTTON3STATE; - - case Index mod 4 of - 0: - ButtonState := 0; - 1: - ButtonState := DFCS_HOT; - 2: - ButtonState := DFCS_PUSHED; - else - ButtonState := DFCS_INACTIVE; - end; - if Index in [4..7, 12..19] then - ButtonState := ButtonState or DFCS_CHECKED; -// if Flat then -// ButtonState := ButtonState or DFCS_FLAT; - DrawFrameControl(BM.Canvas.Handle, Rect(0, 0, BM.Width, BM.Height), DFC_BUTTON, ButtonType or ButtonState); - end; - IL.AddMasked(BM, MaskColor); - end; - - //--------------- end local functions --------------------------------------- - -const - cDefaultCheckboxSize = 13;// Used when no other value is available -var - I: Integer; - lSize: TSize; - Res: Boolean; -begin - BM := TBitmap.Create; // Create a temporary bitmap, which holds the intermediate images. - try - Res := False; - // Retrieve the checkbox image size, prefer theme if available, fall back to GetSystemMetrics() otherwise, but this returns odd results on Windows 8 and higher in high-dpi scenarios. - if StyleServices.Enabled then - if StyleServices.IsSystemStyle then - begin - {$if CompilerVersion >= 33} - if TOSVersion.Check(10) and (TOSVersion.Build >= 15063) then - Theme := OpenThemeDataForDPI(Handle, 'BUTTON', CurrentPPI) - else - {$ifend} - Theme := OpenThemeData(Self.Handle, 'BUTTON'); - Details := StyleServices.GetElementDetails(tbCheckBoxUncheckedNormal); - Res := GetThemePartSize(Theme, BM.Canvas.Handle, Details.Part, Details.State, nil, TS_TRUE, lSize) = S_OK; - end - else - Res := StyleServices.GetElementSize(BM.Canvas.Handle, StyleServices.GetElementDetails(tbCheckBoxUncheckedNormal), TElementSize.esActual, lSize {$IF CompilerVersion >= 34}, Self.CurrentPPI{$IFEND}); - if not Res then begin - lSize := TSize.Create(GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK)); - if lSize.cx = 0 then begin // error? (Should happen rarely only) - lSize.cx := MulDiv(cDefaultCheckboxSize, Screen.PixelsPerInch, USER_DEFAULT_SCREEN_DPI); - lSize.cy := lSize.cx; - end;// if - end;//if - - Result := TImageList.CreateSize(lSize.cx, lSize.cy); - Result.Handle := ImageList_Create(Result.Width, Result.Height, cFlags, 0, Result.AllocBy); - Result.Masked := True; - Result.BkColor := clWhite; - - // Make the bitmap the same size as the image list is to avoid problems when adding. - BM.SetSize(Result.Width, Result.Height); - BM.Canvas.Brush.Color := MaskColor; - BM.Canvas.Brush.Style := bsSolid; - BM.Canvas.FillRect(Rect(0, 0, BM.Width, BM.Height)); - Result.AddMasked(BM, MaskColor); - - // Add the 20 system checkbox and radiobutton images. - for I := 0 to 19 do - AddSystemImage(Result, I); - if StyleServices.Enabled and StyleServices.IsSystemStyle then - CloseThemeData(Theme); - - finally - BM.Free; - end; -end; - - //----------------- TVTVirtualNodeEnumerator --------------------------------------------------------------------------- function TVTVirtualNodeEnumerator.GetCurrent: PVirtualNode; @@ -5638,7 +5498,8 @@ procedure TBaseVirtualTree.SetWindowTheme(const Theme: string); begin FChangingTheme := True; - Winapi.UxTheme.SetWindowTheme(Handle, PWideChar(Theme), nil); + + inherited; end; //---------------------------------------------------------------------------------------------------------------------- @@ -12070,6 +11931,7 @@ function TBaseVirtualTree.GetOptionsClass: TTreeOptionsClass; end; //---------------------------------------------------------------------------------------------------------------------- + function TBaseVirtualTree.GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree; begin Result:= nil; From a3a333c77b183dbdacb3370c6763816964ed7937 Mon Sep 17 00:00:00 2001 From: livius2 Date: Wed, 8 Nov 2023 20:17:49 +0100 Subject: [PATCH 22/28] FMX scroll fixes + some virtal abstract Sort, DoMouseEnter, DoMouseLeave as virtal abstract. In FMX their exists in parent class so must be reintroduced. Some moves for FMX scroll. --- Source/VirtualTrees.AncestorFMX.pas | 92 ++++++++++++++++- Source/VirtualTrees.BaseAncestorFMX.pas | 131 ++++++------------------ Source/VirtualTrees.BaseAncestorVcl.pas | 5 + Source/VirtualTrees.BaseTree.pas | 6 +- 4 files changed, 124 insertions(+), 110 deletions(-) diff --git a/Source/VirtualTrees.AncestorFMX.pas b/Source/VirtualTrees.AncestorFMX.pas index 3e9b8d1c..ca82b78e 100644 --- a/Source/VirtualTrees.AncestorFMX.pas +++ b/Source/VirtualTrees.AncestorFMX.pas @@ -1,4 +1,4 @@ -unit VirtualTrees.BaseAncestorFMX; +unit VirtualTrees.AncestorFMX; {$SCOPEDENUMS ON} @@ -13,7 +13,9 @@ interface uses - VirtualTrees.BaseTree; + System.Classes, System.UITypes, + FMX.Graphics, + VirtualTrees.FMX, VirtualTrees.BaseTree; const EVENT_OBJECT_STATECHANGE = $800A; @@ -32,15 +34,29 @@ TVTAncestorFMX = class abstract(TBaseVirtualTree) function GetClientRect: TRect; override; procedure NotifyAccessibleEvent(pEvent: Uint32 = EVENT_OBJECT_STATECHANGE); virtual; + procedure HScrollChangeProc(Sender: TObject); override; + procedure VScrollChangeProc(Sender: TObject); override; + + procedure Resize; override; //TODO: CopyCutPaste - need to be implemented { function PasteFromClipboard(): Boolean; override; procedure CopyToClipboard(); override; procedure CutToClipboard(); override; } + public + constructor Create(AOwner: TComponent); override; end; implementation +uses + System.SysUtils, + FMX.Forms, + VirtualTrees.Header, + VirtualTrees.Types; + +type + TVTHeaderCracker = class(TVTHeader); //---------------------------------------------------------------------------------------------------------------------- @@ -61,7 +77,7 @@ procedure TVTAncestorFMX.MouseDown(Button: TMouseButton; Shift: TShiftState; X: P:= ClientToScreen(P); end; FillTWMMouse(MM, Button, Shift, P.X, P.Y, isNC, false); - if FHeader.HandleMessage(TMessage(MM)) then + if TVTHeaderCracker(Header).HandleMessage(TMessage(MM)) then exit;//!!! FillTWMMouse(MM, Button, Shift, X, Y, isNC, false); @@ -90,7 +106,7 @@ procedure TVTAncestorFMX.MouseUp(Button: TMouseButton; Shift: TShiftState; X: Si P:= ClientToScreen(P); end; FillTWMMouse(MM, Button, Shift, P.X, P.Y, isNC, true); - if FHeader.HandleMessage(TMessage(MM)) then + if TVTHeaderCracker(Header).HandleMessage(TMessage(MM)) then exit;//!!! FillTWMMouse(MM, Button, Shift, X, Y, isNC, true); @@ -152,7 +168,7 @@ function TVTAncestorFMX.PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Poi DestPitch := PixelFormatBytes[PatternBitmap.PixelFormat]; System.Move(PAlphaColorArray(BitmapData.Data)[0], PAlphaColorArray(Bits)[0], 8 * 4); } - for line:= 0 to LineLen-1 do + for line:= 0 to BitsLinesCount-1 do begin for bit:= 0 to 7 do begin @@ -186,6 +202,72 @@ function TVTAncestorFMX.PrepareDottedBrush(CurrentDottedBrush: TBrush; Bits: Poi //---------------------------------------------------------------------------------------------------------------------- +procedure TVTAncestorFMX.Resize; +Var M: TWMSize; +begin + inherited; + + if FInCreate then + exit; //!! + + M.Msg:= WM_SIZE; + M.SizeType:= SIZE_RESTORED; + M.Width:= Width; + M.Height:= Height; + M.Result:= 0; + WMSize(M); +end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TVTAncestorFMX.VScrollChangeProc(Sender: TObject); +Var M: TWMHScroll; +begin + M.Msg:= WM_VSCROLL; + M.ScrollCode:= SB_THUMBPOSITION; + M.Pos:= GetScrollPos(SB_VERT); + M.ScrollBar:= SB_VERT; + M.Result:= 0; + + WMVScroll(M); + Repaint; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +procedure TVTAncestorFMX.HScrollChangeProc(Sender: TObject); +Var M: TWMHScroll; +begin + M.Msg:= WM_HSCROLL; + M.ScrollCode:= SB_THUMBPOSITION; + M.Pos:= GetScrollPos(SB_HORZ); + M.ScrollBar:= SB_HORZ; + M.Result:= 0; + + WMHScroll(M); + Repaint; +end; + +//---------------------------------------------------------------------------------------------------------------------- + +constructor TVTAncestorFMX.Create(AOwner: TComponent); +begin + FInCreate:= true; + + inherited; + + BackgroundOffsetX:= 0; + BackgroundOffsetY:= 0; + Margin:= 4; + TextMargin:= 4; + DefaultNodeHeight:= 18; //??? + Indent:= 18; //??? + + FInCreate:= false; +end; + +//---------------------------------------------------------------------------------------------------------------------- + function TVTAncestorFMX.GetClientHeight: Single; begin Result:= ClientRect.Height; diff --git a/Source/VirtualTrees.BaseAncestorFMX.pas b/Source/VirtualTrees.BaseAncestorFMX.pas index e080368b..9d7ba60c 100644 --- a/Source/VirtualTrees.BaseAncestorFMX.pas +++ b/Source/VirtualTrees.BaseAncestorFMX.pas @@ -12,9 +12,12 @@ interface uses - System.Classes, System.UITypes - , FMX.Objects, FMX.Graphics, FMX.StdCtrls - , VirtualTrees.Types, VirtualTrees.FMX; + {$IFDEF MSWINDOWS} + WinApi.Windows, + {$ENDIF} + System.Classes, System.UITypes, + FMX.Objects, FMX.Graphics, FMX.Controls, FMX.StdCtrls, FMX.Forms, FMX.ImgList, + VirtualTrees.Types, VirtualTrees.FMX; type @@ -25,7 +28,7 @@ TVTBaseAncestorFMX = class abstract(TRectangle) private FDottedBrushTreeLines: TStrokeBrush; // used to paint dotted lines without special pens FDottedBrushGridLines: TStrokeBrush; // used to paint dotted lines without special pens - FInCreate: Boolean; + FInCreate: Boolean; function GetFillColor: TAlphaColor; procedure SetFillColor(const Value: TAlphaColor); @@ -60,8 +63,8 @@ TVTBaseAncestorFMX = class abstract(TRectangle) procedure DragCanceled; virtual; abstract; procedure Resize; override; - function CreateSystemImageSet(): TImageList; - procedure SetWindowTheme(const Theme: string); virtual; + function CreateSystemImageSet(): TImageList; + procedure SetWindowTheme(const Theme: string); virtual; procedure ChangeScale(M, D: Integer{$if CompilerVersion >= 31}; isDpiChange: Boolean{$ifend}); virtual; abstract; function GetControlsAlignment: TAlignment; virtual; abstract; @@ -71,6 +74,8 @@ TVTBaseAncestorFMX = class abstract(TRectangle) function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; virtual; abstract; function GetSortedSelection(Resolve: Boolean): TNodeArray; virtual; abstract; procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; + procedure DoMouseEnter(); reintroduce; overload; virtual; abstract; + procedure DoMouseLeave(); reintroduce; overload; virtual; abstract; protected //properties property DottedBrushTreeLines: TStrokeBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; property DottedBrushGridLines: TStrokeBrush read FDottedBrushGridLines write FDottedBrushGridLines; @@ -86,8 +91,8 @@ TVTBaseAncestorFMX = class abstract(TRectangle) function GetScrollInfo(Bar: Integer; var ScrollInfo: TScrollInfo): Boolean; function GetScrollPos(Bar: Integer): TDimension; function GetScrollBarForBar(Bar: Integer): TScrollBar; - procedure HScrollChangeProc(Sender: TObject); - procedure VScrollChangeProc(Sender: TObject); + procedure HScrollChangeProc(Sender: TObject); virtual; abstract; + procedure VScrollChangeProc(Sender: TObject); virtual; abstract; procedure CopyToClipboard; virtual; abstract; procedure CutToClipboard; virtual; abstract; @@ -136,6 +141,7 @@ TVTBaseAncestorFMX = class abstract(TRectangle) /// Simulate Windows GetSystemMetrics /// function GetSystemMetrics(nIndex: Integer): Integer; + procedure Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); reintroduce; overload; virtual; abstract; public //properties property Font: TFont read FFont write SetFont; property ClientRect: TRect read GetClientRect; @@ -182,20 +188,6 @@ class function TVTBaseAncestorFMX.KeysToShiftState(Keys: LongInt): TShiftState; //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorFMX.GetClientHeight: Single; -begin - Result:= ClientRect.Height; -end; - -//---------------------------------------------------------------------------------------------------------------------- - -function TVTBaseAncestorFMX.GetClientWidth: Single; -begin - Result:= ClientRect.Width; -end; - -//---------------------------------------------------------------------------------------------------------------------- - function TVTBaseAncestorFMX.GetFillColor: TAlphaColor; begin Result:= Fill.Color; @@ -203,50 +195,6 @@ function TVTBaseAncestorFMX.GetFillColor: TAlphaColor; //---------------------------------------------------------------------------------------------------------------------- -function TVTBaseAncestorFMX.GetClientRect: TRect; -begin - Result:= ClipRect; - if Assigned(FHeader) then - begin - if hoVisible in FHeader.FOptions then - Inc(Result.Top, FHeader.Height); - end; - if FVScrollBar.Visible then - Dec(Result.Right, FVScrollBar.Width); - if FHScrollBar.Visible then - Dec(Result.Bottom, FHScrollBar.Height); - - if Result.Left>Result.Right then - Result.Left:= Result.Right; - - if Result.Top>Result.Bottom then - Result.Top:= Result.Bottom; - - //OffsetRect(Result, OffsetX, OffsetY); - //Dec(Result.Left, -OffsetX); //increase width - //Dec(Result.Top, -OffsetY); //increase height -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTBaseAncestorFMX.Resize; -Var M: TWMSize; -begin - inherited; - - if FInCreate then - exit; //!! - - M.Msg:= WM_SIZE; - M.SizeType:= SIZE_RESTORED; - M.Width:= Width; - M.Height:= Height; - M.Result:= 0; - WMSize(M); -end; - -//---------------------------------------------------------------------------------------------------------------------- - constructor TVTBaseAncestorFMX.Create(AOwner: TComponent); begin FInCreate:= true; @@ -254,12 +202,6 @@ constructor TVTBaseAncestorFMX.Create(AOwner: TComponent); FHandleAllocated:= true; FUseRightToLeftAlignment:= false; - FBackgroundOffsetX:= 0; - FBackgroundOffsetY:= 0; - FMargin:= 4; - FTextMargin:= 4; - FDefaultNodeHeight:= 18; //??? - FIndent:= 18; //??? FBevelEdges:= [TBevelEdge.beLeft, TBevelEdge.beTop, TBevelEdge.beRight, TBevelEdge.beBottom]; FBevelInner:= TBevelCut.bvRaised; FBevelOuter:= TBevelCut.bvLowered; @@ -288,6 +230,7 @@ constructor TVTBaseAncestorFMX.Create(AOwner: TComponent); //FVScrollBar.Margins.Bottom:= FVScrollBar.Width; SetAcceptsControls(false); + FInCreate:= false; end; @@ -506,36 +449,6 @@ function TVTBaseAncestorFMX.GetScrollBarForBar(Bar: Integer): TScrollBar; //---------------------------------------------------------------------------------------------------------------------- -procedure TVTBaseAncestorFMX.HScrollChangeProc(Sender: TObject); -Var M: TWMHScroll; -begin - M.Msg:= WM_HSCROLL; - M.ScrollCode:= SB_THUMBPOSITION; - M.Pos:= GetScrollPos(SB_HORZ); - M.ScrollBar:= SB_HORZ; - M.Result:= 0; - - WMHScroll(M); - Repaint; -end; - -//---------------------------------------------------------------------------------------------------------------------- - -procedure TVTBaseAncestorFMX.VScrollChangeProc(Sender: TObject); -Var M: TWMHScroll; -begin - M.Msg:= WM_VSCROLL; - M.ScrollCode:= SB_THUMBPOSITION; - M.Pos:= GetScrollPos(SB_VERT); - M.ScrollBar:= SB_VERT; - M.Result:= 0; - - WMVScroll(M); - Repaint; -end; - -//---------------------------------------------------------------------------------------------------------------------- - procedure TVTBaseAncestorFMX.SetBiDiMode(Value: TBiDiMode); begin if FBiDiMode <> Value then @@ -618,6 +531,20 @@ function TVTBaseAncestorFMX.CreateSystemImageSet(): TImageList; //---------------------------------------------------------------------------------------------------------------------- +procedure TVTBaseAncestorFMX.SetWindowTheme(const Theme: string); +begin + //nothing +end; +//---------------------------------------------------------------------------------------------------------------------- + +function TVTBaseAncestorFMX.CreateSystemImageSet(): TImageList; +begin + Result:= TImageList.Create(Self); + FillSystemCheckImages(Self, Result); +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TVTBaseAncestorFMX.SetWindowTheme(const Theme: string); begin //nothing diff --git a/Source/VirtualTrees.BaseAncestorVcl.pas b/Source/VirtualTrees.BaseAncestorVcl.pas index 6e5ad0d8..ce624b59 100644 --- a/Source/VirtualTrees.BaseAncestorVcl.pas +++ b/Source/VirtualTrees.BaseAncestorVcl.pas @@ -46,6 +46,9 @@ TVTBaseAncestorVcl = class abstract(TCustomControl) function GetSortedCutCopySet(Resolve: Boolean): TNodeArray; virtual; abstract; function GetSortedSelection(Resolve: Boolean): TNodeArray; virtual; abstract; procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual; abstract; + procedure Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual; abstract; + procedure DoMouseEnter(); virtual; abstract; + procedure DoMouseLeave(); virtual; abstract; protected //properties property DottedBrushTreeLines: TBrush read FDottedBrushTreeLines write FDottedBrushTreeLines; public // methods @@ -292,6 +295,8 @@ procedure TVTBaseAncestorVcl.CopyToClipboard; end; end; +//---------------------------------------------------------------------------------------------------------------------- + function TVTBaseAncestorVcl.CreateSystemImageSet: TImageList; // Creates a system check image set. diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 65ab8cdd..bfb2f286 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -1025,8 +1025,8 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) function DoKeyAction(var CharCode: Word; var Shift: TShiftState): Boolean; virtual; procedure DoLoadUserData(Node: PVirtualNode; Stream: TStream); virtual; procedure DoMeasureItem(TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: TDimension); virtual; - procedure DoMouseEnter(); virtual; - procedure DoMouseLeave(); virtual; + procedure DoMouseEnter(); override; + procedure DoMouseLeave(); override; procedure DoNodeCopied(Node: PVirtualNode); virtual; function DoNodeCopying(Node, NewParent: PVirtualNode): Boolean; virtual; procedure DoNodeClick(const HitInfo: THitInfo); virtual; @@ -1545,7 +1545,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) procedure SetNodeData(pNode: PVirtualNode; pUserData: Pointer); overload; inline; procedure SetNodeData(pNode: PVirtualNode; const pUserData: IInterface); overload; inline; procedure SetNodeData(pNode: PVirtualNode; pUserData: T); overload; - procedure Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual; + procedure Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); override; procedure SortTree(Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual; procedure ToggleNode(Node: PVirtualNode); procedure UpdateHorizontalRange; virtual; From 1aac7ef7185d53929634e83b8c37066257116ef4 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Tue, 14 Nov 2023 21:55:13 +0100 Subject: [PATCH 23/28] Fix compiler warning RAD Studio 12 --- Source/VirtualTrees.BaseTree.pas | 2 +- VirtualTreesDevelopment.groupproj | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index bfb2f286..330256da 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -886,7 +886,6 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) procedure WMThemeChanged(var Message: TMessage); message WM_THEMECHANGED; procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL; function GetRangeX: TDimension; - function GetDoubleBuffered: Boolean; procedure SetDoubleBuffered(const Value: Boolean); function GetVclStyleEnabled: Boolean; inline; procedure SetOnPrepareButtonImages(const Value: TVTPrepareButtonImagesEvent); @@ -1079,6 +1078,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) ImgCheckState: TCheckState = csUncheckedNormal; ImgEnabled: Boolean = True): Integer; virtual; function GetColumnClass: TVirtualTreeColumnClass; virtual; function GetDefaultHintKind: TVTHintKind; virtual; + function GetDoubleBuffered: Boolean; {$if CompilerVersion >= 36}override;{$ifend} function GetHeaderClass: TVTHeaderClass; virtual; function GetHintWindowClass: THintWindowClass; virtual; abstract; procedure GetImageIndex(var Info: TVTPaintInfo; Kind: TVTImageKind; InfoIndex: TVTImageInfoIndex); virtual; diff --git a/VirtualTreesDevelopment.groupproj b/VirtualTreesDevelopment.groupproj index 8b8f6fe9..85fe4ceb 100644 --- a/VirtualTreesDevelopment.groupproj +++ b/VirtualTreesDevelopment.groupproj @@ -4,10 +4,10 @@ - + Packages\RAD Studio 10.4+\VirtualTreesD.dproj - + Packages\RAD Studio 10.4+\VirtualTreesR.dproj @@ -20,22 +20,22 @@ - + - + - + - + - + - + From 26deba0ab53bca91716a4f29fab8926c3a098a65 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Tue, 14 Nov 2023 21:59:53 +0100 Subject: [PATCH 24/28] We meanwhile have two InitializeGlobalStructures() methods, make sure to call them both. Issue #1134 --- Source/VirtualTrees.pas | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/VirtualTrees.pas b/Source/VirtualTrees.pas index 34d52837..0c231bb3 100644 --- a/Source/VirtualTrees.pas +++ b/Source/VirtualTrees.pas @@ -649,6 +649,7 @@ procedure InitializeGlobalStructures(); constructor TCustomVirtualStringTree.Create(AOwner: TComponent); begin + InitializeGlobalStructures(); inherited; FPreviouslySelected := nil; FDefaultText := cDefaultText; From bf359e1f257afc14a2bc8d9a019ff12d75b0dfe2 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Thu, 16 Nov 2023 17:04:28 +0100 Subject: [PATCH 25/28] Fix for #1228: Columns EndUpdate and duplicate position --- Source/VirtualTrees.Header.pas | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/VirtualTrees.Header.pas b/Source/VirtualTrees.Header.pas index 2f99fb22..625840d4 100644 --- a/Source/VirtualTrees.Header.pas +++ b/Source/VirtualTrees.Header.pas @@ -4404,6 +4404,7 @@ procedure TVirtualTreeColumns.FixPositions; I : Integer; begin + UpdatePositions(True); // Fix positions that too large, see #1179 for I := 0 to Count - 1 do begin @@ -5248,6 +5249,7 @@ function TVirtualTreeColumns.GetPreviousColumn(Column : TColumnIndex) : TColumnI Result := FPositionToIndex[Position - 1] else Result := InvalidColumn; + Assert(Position <> Result, 'The previous column must not have the same position as the given column.'); end; end; From cac4853c76a021b73df974ea82abd3d0dcc632e9 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sat, 18 Nov 2023 18:06:04 +0100 Subject: [PATCH 26/28] Improved fix for #1228 and #1179 --- Source/VirtualTrees.Header.pas | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Source/VirtualTrees.Header.pas b/Source/VirtualTrees.Header.pas index 625840d4..02c59d6a 100644 --- a/Source/VirtualTrees.Header.pas +++ b/Source/VirtualTrees.Header.pas @@ -4402,18 +4402,26 @@ procedure TVirtualTreeColumns.FixPositions; var I : Integer; - + LoopAgain: Boolean; begin - UpdatePositions(True); // Fix positions that too large, see #1179 - for I := 0 to Count - 1 do - begin - if Integer(Items[I].Position) >= Count then + // Fix duplicate positions, see #1228 + repeat + LoopAgain := False; + for I := 0 to Count - 1 do begin - UpdatePositions(True); - break; - end; - end; // for + if Integer(Items[I].FPosition) >= Count then + begin + Items[I].Position := Count -1; + LoopAgain := True; + end; + if (i < Count -1) and (Items[I].Position = Items[I+1].FPosition) then + begin + Dec(Items[I].FPosition); + LoopAgain := True; + end; + end; // for + until not LoopAgain; // Update position array for I := 0 to Count - 1 do From aa218047536025911e9ed4077f4546f35e2e7fc7 Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sat, 18 Nov 2023 18:42:59 +0100 Subject: [PATCH 27/28] Use TColors.GridColor for drawing grid line in all situations. Issue #1227 --- Source/VirtualTrees.BaseTree.pas | 21 +++++++++++++++++---- Source/VirtualTrees.Colors.pas | 3 ++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Source/VirtualTrees.BaseTree.pas b/Source/VirtualTrees.BaseTree.pas index 330256da..d47c6cca 100644 --- a/Source/VirtualTrees.BaseTree.pas +++ b/Source/VirtualTrees.BaseTree.pas @@ -1407,6 +1407,7 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor) procedure DeleteNodes(const pNodes: TNodeArray); procedure DeleteSelectedNodes; virtual; function Dragging: Boolean; + procedure DrawGridLine(Canvas: TCanvas; R: TRect); virtual; function EditNode(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; function EndEditNode: Boolean; procedure EndSynch; @@ -11501,13 +11502,23 @@ procedure TBaseVirtualTree.DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, B //---------------------------------------------------------------------------------------------------------------------- +procedure TBaseVirtualTree.DrawGridLine(Canvas: TCanvas; R: TRect); +begin + Canvas.Brush.Color := FColors.GridLineColor; + Canvas.Brush.Style := bsSolid; + Canvas.FillRect(R); + //StyleServices.DrawElement(Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenSelectedNotFocused), R, @R, CurrentPPI); +end; + +//---------------------------------------------------------------------------------------------------------------------- + procedure TBaseVirtualTree.DrawGridHLine(const PaintInfo: TVTPaintInfo; Left, Right, Top: TDimension); // Draws a horizontal grid line var R: TRect; begin R := Rect(Min(Left, Right), Top, Max(Left, Right) + 1, Top + 1); - StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenSelectedNotFocused), R, @R, CurrentPPI); + DrawGridLine(PaintInfo.Canvas, R) end; @@ -11523,11 +11534,13 @@ procedure TBaseVirtualTree.DrawGridVLine(const PaintInfo: TVTPaintInfo; Top, Bot StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenHot), R, @R, CurrentPPI) else begin if StyleServices.IsSystemStyle then // This approach does not work well for many VCL styles, so we added an else case - StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenSelectedNotFocused), R, @R, CurrentPPI) + begin + DrawGridLine(PaintInfo.Canvas, R) + //StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tlGroupHeaderLineOpenSelectedNotFocused), R, @R, CurrentPPI) + end else begin + DrawGridLine(PaintInfo.Canvas, R) //StyleServices.DrawElement(PaintInfo.Canvas.Handle, StyleServices.GetElementDetails(tbGroupBoxNormal), R, @R, CurrentPPI); - PaintInfo.Canvas.Brush.Color := FColors.TreeLineColor; - Winapi.Windows.FillRect(PaintInfo.Canvas.Handle, R, Brush.Handle); end; end;// else end; diff --git a/Source/VirtualTrees.Colors.pas b/Source/VirtualTrees.Colors.pas index 8a567219..78c1c079 100644 --- a/Source/VirtualTrees.Colors.pas +++ b/Source/VirtualTrees.Colors.pas @@ -52,7 +52,7 @@ TVTColors = class(TPersistent) clHighlight, //SelectionRectangleBorderColor clBtnShadow, //HeaderHotColor clHighlightText, //SelectionTextColor - clInactiveCaptionText //UnfocusedColor [IPK] + clInactiveCaptionText //UnfocusedColor [IPK] ); private FOwner : TCustomControl; @@ -82,6 +82,7 @@ TVTColors = class(TPersistent) property FocusedSelectionColor : TColor index cFocusedSelectionColor read GetColor write SetColor default clHighlight; ///The border color of selected nodes when the tree has the focus. property FocusedSelectionBorderColor : TColor index cFocusedSelectionBorderColor read GetColor write SetColor default clHighlight; + ///The color of the grid lines property GridLineColor : TColor index cGridLineColor read GetColor write SetColor default clBtnFace; property HeaderHotColor : TColor index cHeaderHotColor read GetColor write SetColor default clBtnShadow; property HotColor : TColor index cHotColor read GetColor write SetColor default clWindowText; From 111a4d8b467e9fefa69c0e94277db0181931e87e Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Wed, 29 Nov 2023 22:16:28 +0100 Subject: [PATCH 28/28] Minor improvement for issue #1228 --- Source/VirtualTrees.Header.pas | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/VirtualTrees.Header.pas b/Source/VirtualTrees.Header.pas index 02c59d6a..78991bfd 100644 --- a/Source/VirtualTrees.Header.pas +++ b/Source/VirtualTrees.Header.pas @@ -4415,9 +4415,12 @@ procedure TVirtualTreeColumns.FixPositions; Items[I].Position := Count -1; LoopAgain := True; end; - if (i < Count -1) and (Items[I].Position = Items[I+1].FPosition) then + if (i < Count -1) and (Items[I].Position = Items[I+1].FPosition) then begin - Dec(Items[I].FPosition); + if Items[I].FPosition > 0 then + Dec(Items[I].FPosition) + else + Inc(Items[I].FPosition); LoopAgain := True; end; end; // for