Bladeren bron

DEL: Unused components

Alexander Koblov 3 jaren geleden
bovenliggende
commit
defe1e12bd
88 gewijzigde bestanden met toevoegingen van 6 en 53055 verwijderingen
  1. 0 130
      components/lclextensions/delphicompat.pas
  2. 0 23
      components/lclextensions/include/carbon/delphicompat.inc
  3. 0 6
      components/lclextensions/include/carbon/lclext.inc
  4. 0 1
      components/lclextensions/include/carbon/uses.inc
  5. 0 2
      components/lclextensions/include/carbon/uses_lclext.inc
  6. 0 30
      components/lclextensions/include/generic/independentfunctions.inc
  7. 0 139
      components/lclextensions/include/generic/stubs.inc
  8. 0 35
      components/lclextensions/include/generic/unicodefunctions.inc
  9. 0 118
      components/lclextensions/include/gtk/delphicompat.inc
  10. 0 8
      components/lclextensions/include/gtk/lclext.inc
  11. 0 3
      components/lclextensions/include/gtk/uses.inc
  12. 0 2
      components/lclextensions/include/gtk/uses_lclext.inc
  13. 0 92
      components/lclextensions/include/gtk2/delphicompat.inc
  14. 0 6
      components/lclextensions/include/gtk2/lclext.inc
  15. 0 2
      components/lclextensions/include/gtk2/uses.inc
  16. 0 2
      components/lclextensions/include/gtk2/uses_lclext.inc
  17. 0 85
      components/lclextensions/include/qt/delphicompat.inc
  18. 0 6
      components/lclextensions/include/qt/lclext.inc
  19. 0 1
      components/lclextensions/include/qt/uses.inc
  20. 0 2
      components/lclextensions/include/qt/uses_lclext.inc
  21. 0 170
      components/lclextensions/include/win32/delphicompat.inc
  22. 0 27
      components/lclextensions/include/win32/lclext.inc
  23. 0 3
      components/lclextensions/include/win32/uses.inc
  24. 0 2
      components/lclextensions/include/win32/uses_lclext.inc
  25. 0 52
      components/lclextensions/lclext.pas
  26. 0 64
      components/lclextensions/lclextensions_package_doublecmd.lpk
  27. 0 20
      components/lclextensions/lclextensions_package_doublecmd.pas
  28. 0 149
      components/lclextensions/oleutils.pas
  29. 0 4
      components/lclextensions/readme.txt
  30. 0 674
      components/virtualtreeview/VTAccessibility.pas
  31. 0 123
      components/virtualtreeview/VTAccessibilityFactory.pas
  32. 0 49
      components/virtualtreeview/VTConfig.inc
  33. 0 32
      components/virtualtreeview/VTGraphics.pas
  34. 0 250
      components/virtualtreeview/VTHeaderPopup.pas
  35. 0 32981
      components/virtualtreeview/VirtualTrees.pas
  36. 0 345
      components/virtualtreeview/doublecmd.diff
  37. 0 48
      components/virtualtreeview/ideicons.lrs
  38. 0 2
      components/virtualtreeview/include/intf/carbon/olemethods.inc
  39. 0 23
      components/virtualtreeview/include/intf/carbon/vtgraphicsi.inc
  40. 0 2
      components/virtualtreeview/include/intf/carbon/vtvdragmanager.inc
  41. 0 790
      components/virtualtreeview/include/intf/dummydragmanager.inc
  42. 0 404
      components/virtualtreeview/include/intf/dummyolemethods.inc
  43. 0 2
      components/virtualtreeview/include/intf/gtk/olemethods.inc
  44. 0 67
      components/virtualtreeview/include/intf/gtk/vtgraphicsi.inc
  45. 0 2
      components/virtualtreeview/include/intf/gtk/vtvdragmanager.inc
  46. 0 2
      components/virtualtreeview/include/intf/gtk2/olemethods.inc
  47. 0 59
      components/virtualtreeview/include/intf/gtk2/vtgraphicsi.inc
  48. 0 2
      components/virtualtreeview/include/intf/gtk2/vtvdragmanager.inc
  49. 0 2
      components/virtualtreeview/include/intf/qt/olemethods.inc
  50. 0 858
      components/virtualtreeview/include/intf/qt/vtgraphicsi.inc
  51. 0 2
      components/virtualtreeview/include/intf/qt/vtvdragmanager.inc
  52. 0 396
      components/virtualtreeview/include/intf/win32/olemethods.inc
  53. 0 725
      components/virtualtreeview/include/intf/win32/vtgraphicsi.inc
  54. 0 726
      components/virtualtreeview/include/intf/win32/vtvdragmanager.inc
  55. 0 161
      components/virtualtreeview/lclconstants.inc
  56. 0 88
      components/virtualtreeview/lclfunctions.inc
  57. 0 5
      components/virtualtreeview/readme.txt
  58. 0 36
      components/virtualtreeview/registervirtualtreeview.pas
  59. 0 3
      components/virtualtreeview/units/carbon/fakeactivex.pas
  60. 0 37
      components/virtualtreeview/units/carbon/fakemmsystem.pas
  61. 0 1623
      components/virtualtreeview/units/carbon/virtualdragmanager.pas
  62. 0 58
      components/virtualtreeview/units/carbon/virtualpanningwindow.pas
  63. 0 420
      components/virtualtreeview/units/dummyactivex.inc
  64. 0 3
      components/virtualtreeview/units/gtk/fakeactivex.pas
  65. 0 38
      components/virtualtreeview/units/gtk/fakemmsystem.pas
  66. 0 1623
      components/virtualtreeview/units/gtk/virtualdragmanager.pas
  67. 0 58
      components/virtualtreeview/units/gtk/virtualpanningwindow.pas
  68. 0 3
      components/virtualtreeview/units/gtk2/fakeactivex.pas
  69. 0 34
      components/virtualtreeview/units/gtk2/fakemmsystem.pas
  70. 0 1623
      components/virtualtreeview/units/gtk2/virtualdragmanager.pas
  71. 0 58
      components/virtualtreeview/units/gtk2/virtualpanningwindow.pas
  72. 0 3
      components/virtualtreeview/units/qt/fakeactivex.pas
  73. 0 37
      components/virtualtreeview/units/qt/fakemmsystem.pas
  74. 0 1623
      components/virtualtreeview/units/qt/virtualdragmanager.pas
  75. 0 58
      components/virtualtreeview/units/qt/virtualpanningwindow.pas
  76. 0 1134
      components/virtualtreeview/units/win32/virtualdragmanager.pas
  77. 0 113
      components/virtualtreeview/units/win32/virtualpanningwindow.pas
  78. 0 2108
      components/virtualtreeview/virtualtrees.lrs
  79. 0 77
      components/virtualtreeview/virtualtreeview_package.lpk
  80. 0 22
      components/virtualtreeview/virtualtreeview_package.pas
  81. 0 87
      components/virtualtreeview/virtualtreeview_package_doublecmd.lpk
  82. 0 22
      components/virtualtreeview/virtualtreeview_package_doublecmd.pas
  83. 0 85
      components/virtualtreeview/vtlogger.pas
  84. 0 2039
      src/fileviews/ucolumnsfileviewvtv.pas
  85. 2 6
      src/fmain.pas
  86. 1 7
      src/frames/foptionscustomcolumns.pas
  87. 1 7
      src/frames/foptionsfilepanelscolors.pas
  88. 2 6
      src/umaincommands.pas

+ 0 - 130
components/lclextensions/delphicompat.pas

@@ -1,130 +0,0 @@
-unit DelphiCompat;
-
-{ Delphi Compatibility Unit
-
-  Copyright (C) 2007 Luiz Américo Pereira Câmara
-  [email protected]
-
-  This library is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Library General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or (at your
-  option) any later version with the following modification:
-
-  As a special exception, the copyright holders of this library give you
-  permission to link this library with independent modules to produce an
-  executable, regardless of the license terms of these independent modules,and
-  to copy and distribute the resulting executable under terms of your choice,
-  provided that you also meet, for each linked independent module, the terms
-  and conditions of the license of that module. An independent module is a
-  module which is not derived from or based on this library. If you modify
-  this library, you may extend this exception to your version of the library,
-  but you are not obligated to do so. If you do not wish to do so, delete this
-  exception statement from your version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
-  for more details.
-
-  You should have received a copy of the GNU Library General Public License
-  along with this library; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-}
-
-{$mode objfpc}{$H+}
-{.$define DEBUG_DELPHICOMPAT}
-
-interface
-
-uses
-  LMessages, Types, LCLType, Classes;
-
-const
-  //Messages
-  WM_GETDLGCODE = LM_GETDLGCODE;
-  WM_ERASEBKGND = LM_ERASEBKGND;
-  WM_VSCROLL = LM_VSCROLL;
-  WM_HSCROLL = LM_HSCROLL;
-  WM_CHAR = LM_CHAR;
-  WM_KEYDOWN = LM_KEYDOWN;
-  WM_KEYUP = LM_KEYUP;
-  WM_KILLFOCUS = LM_KILLFOCUS;
-  WM_SIZE = LM_SIZE;
-  WM_LBUTTONDBLCLK = LM_LBUTTONDBLCLK;
-  WM_LBUTTONDOWN = LM_LBUTTONDOWN;
-
-type
-  //TWM* types
-  TMessage = TLMessage;
-  TWMHScroll = TLMHScroll;
-  TWMVScroll = TLMVScroll;
-  TWMChar = TLMChar;
-  TWMKeyDown = TLMKeyDown;
-  TWMKeyUp = TLMKeyUp;
-  TWMKillFocus = TLMKillFocus;
-  TWMSize = TLMSize;
-  TWMLButtonDblClk = TLMLButtonDblClk;
-  TWMMeasureItem = TLMMeasureItem;
-  TWMDrawItem = TLMDrawItems;
-  
-function BeginDeferWindowPos(nNumWindows: LongInt):THandle;
-function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Rop: DWORD): Boolean;
-function CopyImage(hImage: THandle; uType:LongWord; cxDesired, cyDesired: LongInt; fuFlags:LongWord):THandle;
-
-function DeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter:THandle; x, y, cx, cy:longint; uFlags:LongWord):THandle;
-
-function EndDeferWindowPos(hWinPosInfo:THandle):Boolean;
-
-function GdiFlush: Boolean;
-function GetACP:LongWord;
-function GetBkColor(DC:HDC):COLORREF;
-function GetDCEx(hWnd:HWND; hrgnClip:HRGN; flags:DWORD):HDC;
-function GetKeyboardLayout(dwLayout:DWORD):THandle;
-function GetKeyboardState(lpKeyState:PBYTE):BOOLEAN;
-function GetLocaleInfo(Locale, LCType:LongWord; lpLCData:PChar; cchData:longint):longint;
-function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall;
-function GetTextAlign(hDC:HDC): LongWord;
-function GetTextExtentExPoint(DC: HDC; Str: PChar;
-  Count, MaxWidth: Integer; MaxCount, PartialWidths: PInteger;
-  var Size: TSize): BOOL;
-function GetTextExtentPoint32W(DC: HDC; Str: PWideChar; Count: Integer; out Size: TSize): Boolean;
-function GetWindowDC(hWnd:HWND):HDC;
-
-function ImageList_DragShowNolock(fShow: Boolean): Boolean;
-
-function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints; cPoints: UINT): Integer;
-function MultiByteToWideChar(CodePage, dwFlags:DWORD; lpMultiByteStr:PChar; cchMultiByte:longint; lpWideCharStr:PWideChar;cchWideChar:longint):longint;
-
-function OffsetRgn(hrgn:HRGN; nxOffset, nYOffset:longint):longint;
-
-function ScrollDC(DC:HDC; dx:longint; dy:longint; var lprcScroll:TRECT; var lprcClip:TRECT;hrgnUpdate:HRGN; lprcUpdate:PRECT):Boolean;
-function SetBrushOrgEx(DC:HDC; nXOrg, nYOrg:longint; lppt:PPOINT):Boolean;
-
-function ToAscii(uVirtKey, uScanCode:LongWord; lpKeyState: PByte; lpChar: PWord; uFlags:LongWord): LongInt;
-
-implementation
-
-
-uses
-{$i uses.inc}
-  LCLProc, Controls
-  {$ifdef DEBUG_DELPHICOMPAT}
-  ,multiloglcl, filechannel
-  {$endif}
-  ;
-
-{$ifdef DEBUG_DELPHICOMPAT}
-const
-  //Logger  classes
-  lcInfo = 0;
-  lcStack = 1;
-
-var
-  Logger: TLCLLogger;
-{$endif}
-
-
-{$i delphicompat.inc}
-
-end.

+ 0 - 23
components/lclextensions/include/carbon/delphicompat.inc

@@ -1,23 +0,0 @@
-
-{
-  Carbon Interface
-
-  Dummy implementation. Not tested. 
-  Waiting for someone with a Mac to implement it
-}
-
-{
-  Only a few functions are necessary to compile VirtualTreeView:
-}
-
-{.$define HAS_GETTEXTEXTENTEXPOINT}
-{.$define HAS_GETTEXTALIGN}
-{.$define HAS_GETWINDOWDC}
-{.$define HAS_OFFSETRGN}
-{.$define HAS_SETBRUSHORGEX}
-
-
-{$i ../generic/stubs.inc}
-{$i ../generic/independentfunctions.inc}
-{$i ../generic/unicodefunctions.inc}
-

+ 0 - 6
components/lclextensions/include/carbon/lclext.inc

@@ -1,6 +0,0 @@
-function DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean;
-begin
-  //todo: see if is possible todo it faster
-  Result := StretchMaskBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height,
-   Mask, 0, 0,  SRCCOPY);
-end;

+ 0 - 1
components/lclextensions/include/carbon/uses.inc

@@ -1 +0,0 @@
-  InterfaceBase, LCLIntf, Graphics, CarbonInt, CarbonCanvas, Math,

+ 0 - 2
components/lclextensions/include/carbon/uses_lclext.inc

@@ -1,2 +0,0 @@
-uses
-  LclIntf;

+ 0 - 30
components/lclextensions/include/generic/independentfunctions.inc

@@ -1,30 +0,0 @@
-
-function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints; cPoints: UINT): Integer;
-var
-  i: Integer;
-  XOffset, YOffset: SmallInt;
-  FromPoint, ToPoint: TPoint;
-begin
-  FromPoint := Point(0, 0);
-  ToPoint := Point(0, 0);
-  if hWndFrom <> 0 then
-    ClientToScreen(hWndFrom, FromPoint);
-  if hWndTo <> 0 then
-    ClientToScreen(hWndTo, ToPoint);
-  XOffset := (FromPoint.X - ToPoint.X);
-  YOffset := (FromPoint.Y - ToPoint.Y);
-  for i := 0 to cPoints - 1 do
-  begin
-    PPoint(@lpPoints)[i].x := XOffset + PPoint(@lpPoints)[i].x;
-    PPoint(@lpPoints)[i].y := YOffset + PPoint(@lpPoints)[i].y;
-  end;
-  Result := MakeLong(XOffset, YOffset);
-end;
-
-{$ifndef HAS_BITBLT}
-function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc,
-  YSrc: Integer; Rop: DWORD): Boolean;
-begin
-  Result := LCLIntf.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Rop);
-end;
-{$endif}

+ 0 - 139
components/lclextensions/include/generic/stubs.inc

@@ -1,139 +0,0 @@
-
-function BeginDeferWindowPos(nNumWindows:longint):THandle;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function CopyImage(hImage:THANDLE; uType:LongWord; cxDesired, cyDesired: LongInt; fuFlags:LongWord):THandle;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function DeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter:THandle; x, y, cx, cy:longint; uFlags:LongWord):THandle;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function EndDeferWindowPos(hWinPosInfo:THandle):Boolean;
-begin
-  Result := False;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function GdiFlush: Boolean;
-begin
-  Result := False;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function GetACP:LongWord;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-{$ifndef HAS_GETBKCOLOR}
-function GetBkColor(DC:HDC):COLORREF;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-{$endif}
-
-function GetDCEx(hWnd:HWND; hrgnClip:HRGN; flags:DWORD):HDC;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function GetKeyboardLayout(dwLayout:DWORD):THandle;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function GetKeyboardState(lpKeyState: System.PByte):BOOLEAN;
-begin
-  Result := False;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function GetLocaleInfo(Locale, LCType:LongWord; lpLCData:PChar; cchData:longint):longint;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-{$ifndef HAS_GETTEXTEXTENTEXPOINT}
-function GetTextExtentExPoint(DC: HDC; Str: PChar;
-  Count, MaxWidth: Integer; MaxCount, PartialWidths: PInteger;
-  var Size: TSize): BOOL;
-begin
-  Result := LCLIntf.GetTextExtentExPoint(DC, Str, Count, MaxWidth, MaxCount, PartialWidths, Size);
-end;
-{$endif}
-
-{$ifndef HAS_GETTEXTALIGN}
-function GetTextAlign(hDC:HDC): LongWord;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-{$endif}
-
-{$ifndef HAS_GETWINDOWDC}
-function GetWindowDC(hWnd:HWND):HDC;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-{$endif}
-
-function ImageList_DragShowNolock(fShow: Boolean): Boolean;
-begin
-  Result := False;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-function MultiByteToWideChar(CodePage, dwFlags:DWORD; lpMultiByteStr:PChar; cchMultiByte:longint; lpWideCharStr:PWideChar;cchWideChar:longint):longint;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-{$ifndef HAS_OFFSETRGN}
-function OffsetRgn(hrgn:HRGN; nxOffset, nYOffset:longint):longint;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-{$endif}
-
-function ScrollDC(DC:HDC; dx:longint; dy:longint; var lprcScroll:TRECT; var lprcClip:TRECT;hrgnUpdate:HRGN; lprcUpdate:PRECT):Boolean;
-begin
-  Result := False;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-
-{$ifndef HAS_SETBRUSHORGEX}
-function SetBrushOrgEx(DC:HDC; nXOrg, nYOrg:longint; lppt:PPOINT):Boolean;
-begin
-  Result := False;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;
-{$endif}
-
-function ToAscii(uVirtKey, uScanCode:LongWord; lpKeyState: System.PByte; lpChar: System.PWord; uFlags:LongWord):longint;
-begin
-  Result := 0;
-  {$ifdef DEBUG_DELPHICOMPAT} Logger.SendCallStack('Dummy WinAPI Implementation'); {$endif}
-end;

+ 0 - 35
components/lclextensions/include/generic/unicodefunctions.inc

@@ -1,35 +0,0 @@
-
-{
-GetUTF8ByteCount returns the number of bytes necessary to hold the requested number
-of characters (count). Not necessarily the number of characters is equal to the
-widestring length but here we assume it to skip the extra overhead
-}
-//todo do a function that convert the str and the count at one pass
-function GetUTF8ByteCount(const UTF8Str: UTF8String; WideCount: Integer): Integer;
-var
-  CharCount, CharLen, StrLen: Integer;
-  P: PChar;
-begin
-  Result := 0;
-  CharCount := 0;
-  P := PChar(UTF8Str);
-  StrLen := Length(UTF8Str);
-  WideCount := Min(WideCount, StrLen);
-  while (CharCount < WideCount) do
-  begin
-    CharLen := UTF8CharacterLength(P);
-    Inc(P, CharLen);
-    Inc(Result, CharLen);
-    Inc(CharCount);
-  end;
-  Result := Min(Result, StrLen);
-end;
-
-function GetTextExtentPoint32W(DC: HDC; Str: PWideChar; Count: Integer; out Size: TSize): Boolean;
-var
-  TempStr: UTF8String;
-begin
-  TempStr := UTF8Encode(WideString(Str));
-  Result := GetTextExtentPoint(DC, PChar(TempStr),
-    GetUTF8ByteCount(TempStr, Count), Size);
-end;

+ 0 - 118
components/lclextensions/include/gtk/delphicompat.inc

@@ -1,118 +0,0 @@
-
-{ This file is part of Delphi Compatibility Unit
-
-  Copyright (C) 2007 Luiz Américo Pereira Câmara
-  [email protected]
-
-  This library is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Library General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or (at your
-  option) any later version with the following modification:
-
-  As a special exception, the copyright holders of this library give you
-  permission to link this library with independent modules to produce an
-  executable, regardless of the license terms of these independent modules,and
-  to copy and distribute the resulting executable under terms of your choice,
-  provided that you also meet, for each linked independent module, the terms
-  and conditions of the license of that module. An independent module is a
-  module which is not derived from or based on this library. If you modify
-  this library, you may extend this exception to your version of the library,
-  but you are not obligated to do so. If you do not wish to do so, delete this
-  exception statement from your version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
-  for more details.
-
-  You should have received a copy of the GNU Library General Public License
-  along with this library; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-}
-
-{$define HAS_GETBKCOLOR}
-{$define HAS_GETTEXTEXTENTEXPOINT}
-{$define HAS_DRAWFRAMECONTROL}
-
-{$i ../generic/stubs.inc}
-{$i ../generic/independentfunctions.inc}
-{$i ../generic/unicodefunctions.inc}
-
-function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc,
-  YSrc: Integer; Rop: DWORD): Boolean;
-begin
-  Result := GTKWidgetSet.StretchCopyArea(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height,
-   0, XSrc, YSrc, Rop);
-end;
-
-function DrawFrameControl(DC: HDC; const Rect: TRect; uType, uState: LongWord): Boolean;
-begin
-  Result := LCLIntf.DrawFrameControl(DC, Rect, uType, uState);
-end;
-
-function GetBkColor(DC:HDC):COLORREF;
-begin
-  if GTKWidgetSet.IsValidDC(DC) then
-    Result := TGtkDeviceContext(DC).CurrentBackColor.ColorRef
-  else
-    Result := CLR_INVALID;
-end;
-
-function GetTextExtentExPoint(DC: HDC; Str: PChar; Count, MaxWidth: Integer;
-  MaxCount, PartialWidths: ObjPas.PInteger; var Size: TSize): BOOL;
-var
-  lbearing, rbearing, width, ascent,descent: LongInt;
-  UseFont : PGDKFont;
-  IsDBCSFont: Boolean;
-  NewCount,Accumulator,i: Integer;
-begin
-  //based in lcl code
-  Result := GTKWidgetSet.IsValidDC(DC);
-  if Result then
-  with TGtkDeviceContext(DC) do
-  begin
-    if (CurrentFont = nil) or (CurrentFont^.GDIFontObject = nil)
-    then begin
-      UseFont := GTKWidgetSet.GetDefaultGtkFont(false);
-    end
-    else begin
-      UseFont := CurrentFont^.GDIFontObject;
-    end;
-    If UseFont = nil then
-      DebugLn('WARNING: [TGtkWidgetSet.GetTextExtentPoint] Missing font')
-    else begin
-      descent:=0;
-      {
-      UpdateDCTextMetric(TDeviceContext(DC));
-      IsDBCSFont:=TDeviceContext(DC).DCTextMetric.IsDoubleByteChar;
-
-      if IsDBCSFont then begin
-        NewCount:=Count*2;
-        if FExtUTF8OutCacheSize<NewCount then begin
-          ReAllocMem(FExtUTF8OutCache,NewCount);
-          FExtUTF8OutCacheSize:=NewCount;
-        end;
-        NewCount:=UTF8ToDoubleByte(Str,Count,FExtUTF8OutCache)*2;
-        gdk_text_extents(UseFont, FExtUTF8OutCache, NewCount,
-                         @lbearing, @rBearing, @width, @ascent, @descent);
-      end else begin
-        gdk_text_extents(UseFont, Str, Count,
-                         @lbearing, @rBearing, @width, @ascent, @descent);
-      end;
-      }
-      gdk_text_extents(UseFont, Str, Count,@lbearing, @rBearing, @width, @ascent, @descent);
-      Size.cX := Width;
-      Size.cY := ascent+descent;
-      if PartialWidths <> nil then
-      begin
-        Accumulator:=0;
-        for i:= 0 to Count - 1 do
-        begin
-          Inc(Accumulator,gdk_char_width(UseFont,(Str+i)^));
-          PartialWidths[i]:=Accumulator;
-        end;
-      end;
-    end;
-  end;
-end;

+ 0 - 8
components/lclextensions/include/gtk/lclext.inc

@@ -1,8 +0,0 @@
-
-
-function DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean;
-begin
-  //todo: see if is possible todo it faster
-  Result := GTKWidgetSet.StretchCopyArea(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height,
-   Mask, XSrc, YSrc,  SRCCOPY);
-end;

+ 0 - 3
components/lclextensions/include/gtk/uses.inc

@@ -1,3 +0,0 @@
-
-  LCLIntf, Graphics, gtkdef, gdk, GTKProc, GtkInt, glib, gtk, Math,
-

+ 0 - 2
components/lclextensions/include/gtk/uses_lclext.inc

@@ -1,2 +0,0 @@
-uses
-  GtkInt;

+ 0 - 92
components/lclextensions/include/gtk2/delphicompat.inc

@@ -1,92 +0,0 @@
-{ This file is part of Delphi Compatibility Unit
-
-  Copyright (C) 2007 Luiz Américo Pereira Câmara
-  [email protected]
-
-  This library is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Library General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or (at your
-  option) any later version with the following modification:
-
-  As a special exception, the copyright holders of this library give you
-  permission to link this library with independent modules to produce an
-  executable, regardless of the license terms of these independent modules,and
-  to copy and distribute the resulting executable under terms of your choice,
-  provided that you also meet, for each linked independent module, the terms
-  and conditions of the license of that module. An independent module is a
-  module which is not derived from or based on this library. If you modify
-  this library, you may extend this exception to your version of the library,
-  but you are not obligated to do so. If you do not wish to do so, delete this
-  exception statement from your version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
-  for more details.
-
-  You should have received a copy of the GNU Library General Public License
-  along with this library; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-}
-
-{$MACRO ON}
-
-{$define HAS_GETBKCOLOR}
-{$define HAS_GETTEXTEXTENTEXPOINT}
-
-{$i ../generic/stubs.inc}
-{$i ../generic/independentfunctions.inc}
-{$i ../generic/unicodefunctions.inc}
-
-
-procedure pango_extents_to_pixels (ink_rect: PPangoRectangle;
-			  logical_rect: PPangoRectangle); cdecl; external 'libpango-1.0.so.0';
-
-function GetBkColor(DC:HDC):COLORREF;
-begin
-  if GTK2WidgetSet.IsValidDC(DC) then
-    Result := TGtkDeviceContext(DC).CurrentBackColor.ColorRef
-  else
-    Result := CLR_INVALID;
-end;
-
-function GetTextExtentExPoint(DC: HDC; Str: PChar;
-  Count, MaxWidth: Integer; MaxCount, PartialWidths: PInteger;
-  var Size: TSize): BOOL;
-var
-  layout: PPangoLayout;
-  i: Integer;
-  Rect: TPangoRectangle;
-  iter : PPangoLayoutIter;
-begin
-  Result := GTK2WidgetSet.IsValidDC(DC);
-  if Result then
-  with TGtk2DeviceContext(DC) do
-  begin
-    if (CurrentFont = nil) or (CurrentFont^.GDIFontObject = nil) then
-      layout := GTK2WidgetSet.GetDefaultGtkFont(false)
-    else
-      layout := CurrentFont^.GDIFontObject;
-    pango_layout_set_text(layout, Str, Count);
-    if PartialWidths = nil then
-      pango_layout_get_pixel_size (layout, @Size.cx, @Size.cy)
-    else
-      begin
-        i := 0;
-        Size.cx := 0;
-        Size.cy := 0;
-        iter := pango_layout_get_iter(layout);
-        repeat
-          pango_layout_iter_get_char_extents(iter,@Rect);
-          pango_extents_to_pixels(nil,@Rect);
-          inc(Size.cx, Rect.Width);
-          PartialWidths[i] := Size.cx;
-          if Size.cy < Rect.Height then
-            Size.cy := Rect.Height;
-          inc(i);
-        until not pango_layout_iter_next_char(iter);
-        pango_layout_iter_free(iter);
-      end;
-  end;
-end;

+ 0 - 6
components/lclextensions/include/gtk2/lclext.inc

@@ -1,6 +0,0 @@
-function DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean;
-begin
-  //todo: see if is possible todo it faster
-  Result := GTK2WidgetSet.StretchCopyArea(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height,
-   Mask, XSrc, YSrc,  SRCCOPY);
-end;

+ 0 - 2
components/lclextensions/include/gtk2/uses.inc

@@ -1,2 +0,0 @@
-
-  LCLIntf, Graphics, Gtk2Def, Gtk2Proc, Gtk2Int, pango, math,

+ 0 - 2
components/lclextensions/include/gtk2/uses_lclext.inc

@@ -1,2 +0,0 @@
-uses
-  Gtk2Int;

+ 0 - 85
components/lclextensions/include/qt/delphicompat.inc

@@ -1,85 +0,0 @@
-
-{
-  Qt Interface
-  
-  Initial implementation by Zeljan Rikalo
-}
-
-{$define HAS_GETBKCOLOR}
-{$define HAS_GETTEXTEXTENTEXPOINT}
-{$define HAS_GETTEXTALIGN}
-{$define HAS_GETWINDOWDC}
-{$define HAS_OFFSETRGN}
-{$define HAS_SETBRUSHORGEX}
-
-
-{$i ../generic/stubs.inc}
-{$i ../generic/independentfunctions.inc}
-{$i ../generic/unicodefunctions.inc}
-
-function GetBkColor(DC:HDC):COLORREF;
-var
-  Color: PQColor;
-begin
-  if QtWidgetSet.IsValidDC(DC) then
-  begin
-    Color := TQtDeviceContext(DC).BackgroundBrush.getColor;
-    TQColorToColorRef(Color^, Result);
-  end else
-    Result := CLR_INVALID;
-end;
-
-function GetTextExtentExPoint(DC: HDC; Str: PChar;
-  Count, MaxWidth: Integer; MaxCount, PartialWidths: PInteger;
-  var Size: TSize): BOOL;
-begin
-  Result := QtWidgetSet.GetTextExtentExPoint(DC, Str, Count, MaxWidth, MaxCount, PartialWidths, Size);
-end;
-
-function GetTextAlign(hDC:HDC): LongWord;
-var
-  QtDC: TQtDeviceContext;
-  QtFontMetrics: QFontMetricsH;
-  QtFont: QFontH;
-begin
-  Result := 0;
-  if not QtWidgetSet.IsValidDC(hdC) then
-    Exit;
-  QtDC := TQtDeviceContext(hDC);
-  QtFont := QtDC.vFont.FHandle;
-  QtFontMetrics := QFontMetrics_create(QtFont);
-  try
-  {TODO: FIXME we should save somehow text flags into QtDC
-   cause we don't have any function which returns current flags !}
-  finally
-    QFontMetrics_destroy(QtFontMetrics);
-  end;
-end;
-
-function GetWindowDC(hWnd:HWND): HDC;
-begin
-  Result := LCLIntf.GetDC(hWnd);
-end;
-
-function OffsetRgn(hrgn:HRGN; nxOffset, nYOffset:longint):longint;
-var
-  Region: TQtRegion;
-begin
-  Region := TQtRegion(hrgn);
-  QRegion_translate(Region.FHandle, nxOffset, nYOffset);
-  Result := Region.GetRegionType;
-end;
-
-function SetBrushOrgEx(DC:HDC; nXOrg, nYOrg:longint; lppt:PPOINT):Boolean;
-var
-  QtDC: TQtDeviceContext;
-begin
-  Result := False;
-  if not QtWidgetSet.IsValidDC(DC) then
-    Exit;
-  QtDC := TQtDeviceContext(DC);
-  if lppt <> nil then
-    QtDC.getBrushOrigin(lppt);
-  QtDC.setBrushOrigin(nXorg, nYOrg);
-  Result := True;
-end;

+ 0 - 6
components/lclextensions/include/qt/lclext.inc

@@ -1,6 +0,0 @@
-function DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean;
-begin
-  //todo: see if is possible todo it faster
-  Result := StretchMaskBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height,
-   Mask, 0, 0,  SRCCOPY);
-end;

+ 0 - 1
components/lclextensions/include/qt/uses.inc

@@ -1 +0,0 @@
-  InterfaceBase, LCLIntf, Graphics, qt4, qtint, qtobjects, qtwidgets, Math,

+ 0 - 2
components/lclextensions/include/qt/uses_lclext.inc

@@ -1,2 +0,0 @@
-uses
-  LclIntf;

+ 0 - 170
components/lclextensions/include/win32/delphicompat.inc

@@ -1,170 +0,0 @@
-
-{ This file is part of Delphi Compatibility Unit
-
-  Copyright (C) 2007 Luiz Américo Pereira Câmara
-  [email protected]
-
-  This library is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Library General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or (at your
-  option) any later version with the following modification:
-
-  As a special exception, the copyright holders of this library give you
-  permission to link this library with independent modules to produce an
-  executable, regardless of the license terms of these independent modules,and
-  to copy and distribute the resulting executable under terms of your choice,
-  provided that you also meet, for each linked independent module, the terms
-  and conditions of the license of that module. An independent module is a
-  module which is not derived from or based on this library. If you modify
-  this library, you may extend this exception to your version of the library,
-  but you are not obligated to do so. If you do not wish to do so, delete this
-  exception statement from your version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
-  for more details.
-
-  You should have received a copy of the GNU Library General Public License
-  along with this library; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-}
-
-function BeginDeferWindowPos(nNumWindows: longint): THandle;
-begin
-  Result:=Windows.BeginDeferWindowPos(nNumWindows);
-end;
-
-function BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc,
-  YSrc: Integer; Rop: DWORD): Boolean;
-begin
-  Result := Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Rop);
-end;
-
-function CopyImage(hImage: THANDLE; uType: LongWord; cxDesired,
-  cyDesired: LongInt; fuFlags: LongWord): THandle;
-begin
-  Result := Windows.CopyImage(hImage,uType,cxDesired,cyDesired,fuFlags);
-end;
-
-function CreatePatternBrush(hbmp: HBITMAP): HBRUSH;
-begin
-  Result := Windows.CreatePatternBrush(hbmp);
-end;
-
-function DeferWindowPos(hWinPosInfo, hWnd, hWndInsertAfter: THandle;
-  x, y, cx, cy: longint; uFlags: LongWord): THandle;
-begin
-  Result := Windows.DeferWindowPos(hWinPosInfo,hWnd,hWndInsertAfter,x,y,cx,cy,uFlags);
-end;
-
-function DrawFrameControl(DC: HDC; const Rect: TRect; uType, uState: LongWord): Boolean;
-begin
-  Result := Windows.DrawFrameControl(DC,Rect,uType,uState);
-end;
-
-function EndDeferWindowPos(hWinPosInfo: THandle): Boolean;
-begin
-  Result:=Windows.EndDeferWindowPos(hWinPosInfo);
-end;
-
-function GdiFlush: Boolean;
-begin
-  Result := Windows.GdiFlush;
-end;
-
-function GetACP: LongWord;
-begin
-  Result := Windows.GetACP;
-end;
-
-function GetBkColor(DC: HDC): LCLType.COLORREF;
-begin
-  Result := Windows.GetBkColor(DC);
-end;
-
-function GetDCEx(hWnd: HWND; hrgnClip: HRGN; flags: DWORD): HDC;
-begin
-  Result := Windows.GetDCEx(hWnd,hrgnClip,flags);
-end;
-
-function GetKeyboardLayout(dwLayout: DWORD): THandle;
-begin
-  Result := Windows.GetKeyboardLayout(dwLayout);
-end;
-
-function GetKeyboardState(lpKeyState: PBYTE): BOOLEAN;
-begin
-  Result := Windows.GetKeyboardState(lpKeyState);
-end;
-
-function GetLocaleInfo(Locale, LCType: LongWord; lpLCData: PChar;
-  cchData: longint): longint;
-begin
-  Result := Windows.GetLocaleInfo(Locale,LCType,lpLCData,cchData);
-end;
-
-function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall; external 'GDI32.DLL';
-
-function GetTextAlign(hDC: HDC): LongWord;
-begin
-  Result := Windows.GetTextAlign(hDC);
-end;
-
-function GetTextExtentExPoint(DC: LCLType.HDC; Str: PChar;
-  Count, MaxWidth: Integer; MaxCount, PartialWidths: ObjPas.PInteger;
-  var Size: TSize): BOOL;
-begin
-  Result := Windows.GetTextExtentExPoint(DC, Str, Count, MaxWidth, MaxCount, PartialWidths,  Size);
-end;
-
-function GetTextExtentPoint32W(DC: HDC; Str: PWideChar; Count: Integer; out Size: TSize): Boolean;
-begin
-  Result := Windows.GetTextExtentPointW(DC, Str, Count, Size);
-end;
-
-function GetWindowDC(hWnd: HWND): HDC;
-begin
-  Result := Windows.GetWindowDC(hWnd);
-end;
-
-function ImageList_DragShowNolock(fShow: Boolean): Boolean;
-begin
-  Result := CommCtrl.ImageList_DragShowNolock(fShow);
-end;
-
-function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints; cPoints: UINT
-  ): Integer;
-begin
-  Result:=Windows.MapWindowPoints(hWndFrom,hWndTo,lpPoints,cPoints);
-end;
-
-function MultiByteToWideChar(CodePage, dwFlags: DWORD; lpMultiByteStr: PChar;
-  cchMultiByte: longint; lpWideCharStr: PWideChar; cchWideChar: longint
-  ): longint;
-begin
-  Result := Windows.MultiByteToWideChar(CodePage,dwFlags,lpMultiByteStr,cchMultiByte,lpWideCharStr,cchWideChar);
-end;
-
-function OffsetRgn(hrgn: HRGN; nxOffset, nYOffset: longint): longint;
-begin
-  Result := Windows.OffsetRgn(hrgn,nxOffset,nYOffset);
-end;
-
-function SetBrushOrgEx(DC: LCLType.HDC; nXOrg, nYOrg: longint; lppt: Types.PPoint): Boolean;
-begin
-  Result := Windows.SetBrushOrgEx(DC,nXOrg,nYOrg,lppt);
-end;
-
-function ScrollDC(DC: LCLType.HDC; dx: longint; dy: longint; var lprcScroll: Types.TRect;
-  var lprcClip: Types.TRect; hrgnUpdate: LCLType.HRGN; lprcUpdate: Types.PRect): Boolean;
-begin
-  Result := Windows.ScrollDC(DC, dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate);
-end;
-
-function ToAscii(uVirtKey, uScanCode: LongWord; lpKeyState: PBYTE;
-  lpChar: PWORD; uFlags: LongWord): longint;
-begin
-  Result := Windows.ToAscii(uVirtKey,uScanCode,lpKeyState,lpChar,uFlags);
-end;

+ 0 - 27
components/lclextensions/include/win32/lclext.inc

@@ -1,27 +0,0 @@
-function DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean;
-var
-  MaskDC: HDC;
-  MaskObj: HGDIOBJ;
-  PrevTextColor, PrevBkColor: COLORREF;
-begin
-  //this is a stripped version of LCL.StretchMaskBlt
-  if Mask <> 0 then
-  begin
-    MaskDC := Windows.CreateCompatibleDC(DestDC);
-    MaskObj := Windows.SelectObject(MaskDC, Mask);
-
-    PrevTextColor := Windows.SetTextColor(DestDC, $00000000);
-    PrevBkColor := Windows.SetBkColor(DestDC, $00FFFFFF);
-    
-    Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC,  XSrc, YSrc, SRCINVERT);
-    Windows.BitBlt(DestDC, X, Y, Width, Height, MaskDC, XSrc, YSrc, SRCAND);
-    Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC,  XSrc, YSrc, SRCINVERT);
-    
-    Windows.SetTextColor(DestDC, PrevTextColor);
-    Windows.SetBkColor(DestDC, PrevBkColor);
-    Windows.SelectObject(MaskDC, MaskObj);
-    Windows.DeleteDC(MaskDC);
-  end
-  else
-    Result := Windows.BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, SRCCOPY);
-end;

+ 0 - 3
components/lclextensions/include/win32/uses.inc

@@ -1,3 +0,0 @@
-
-  Windows, win32proc, CommCtrl,
-

+ 0 - 2
components/lclextensions/include/win32/uses_lclext.inc

@@ -1,2 +0,0 @@
-  uses
-    Windows;

+ 0 - 52
components/lclextensions/lclext.pas

@@ -1,52 +0,0 @@
-unit LclExt;
-
-{ LCL Extension Unit
-
-  Copyright (C) 2007 Luiz Américo Pereira Câmara
-  [email protected]
-
-  This library is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Library General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or (at your
-  option) any later version with the following modification:
-
-  As a special exception, the copyright holders of this library give you
-  permission to link this library with independent modules to produce an
-  executable, regardless of the license terms of these independent modules,and
-  to copy and distribute the resulting executable under terms of your choice,
-  provided that you also meet, for each linked independent module, the terms
-  and conditions of the license of that module. An independent module is a
-  module which is not derived from or based on this library. If you modify
-  this library, you may extend this exception to your version of the library,
-  but you are not obligated to do so. If you do not wish to do so, delete this
-  exception statement from your version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
-  for more details.
-
-  You should have received a copy of the GNU Library General Public License
-  along with this library; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-}
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  Classes, SysUtils, LCLType, Graphics;
-
-function DirectMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc: Integer; Mask: HBITMAP): Boolean;
-
-implementation
-
-{$i uses_lclext.inc}
-
-
-{$i lclext.inc}
-
-end.
-

+ 0 - 64
components/lclextensions/lclextensions_package_doublecmd.lpk

@@ -1,64 +0,0 @@
-<?xml version="1.0"?>
-<CONFIG>
-  <Package Version="4">
-    <Name Value="lclextensions_package_doublecmd"/>
-    <AddToProjectUsesSection Value="True"/>
-    <Author Value="Luiz Americo Pereira Câmara"/>
-    <CompilerOptions>
-      <Version Value="10"/>
-      <SearchPaths>
-        <IncludeFiles Value="include/$(LCLWidgetType)"/>
-        <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
-      </SearchPaths>
-      <Parsing>
-        <SyntaxOptions>
-          <UseAnsiStrings Value="False"/>
-        </SyntaxOptions>
-      </Parsing>
-      <Linking>
-        <Debugging>
-          <GenerateDebugInfo Value="True"/>
-          <DebugInfoType Value="dsDwarf2Set"/>
-        </Debugging>
-      </Linking>
-      <Other>
-        <CompilerMessages>
-          <UseMsgFile Value="True"/>
-        </CompilerMessages>
-        <CompilerPath Value="$(CompPath)"/>
-      </Other>
-    </CompilerOptions>
-    <Description Value="LCL Extensions provides additional functions to be used together with LCL
-"/>
-    <License Value="Modified LGPL
-"/>
-    <Version Minor="4"/>
-    <Files Count="3">
-      <Item1>
-        <Filename Value="delphicompat.pas"/>
-        <UnitName Value="DelphiCompat"/>
-      </Item1>
-      <Item2>
-        <Filename Value="oleutils.pas"/>
-        <UnitName Value="oleutils"/>
-      </Item2>
-      <Item3>
-        <Filename Value="lclext.pas"/>
-        <UnitName Value="LclExt"/>
-      </Item3>
-    </Files>
-    <Type Value="RunAndDesignTime"/>
-    <RequiredPkgs Count="1">
-      <Item1>
-        <PackageName Value="LCL"/>
-      </Item1>
-    </RequiredPkgs>
-    <UsageOptions>
-      <UnitPath Value="$(PkgOutDir)"/>
-    </UsageOptions>
-    <PublishOptions>
-      <Version Value="2"/>
-      <IgnoreBinaries Value="False"/>
-    </PublishOptions>
-  </Package>
-</CONFIG>

+ 0 - 20
components/lclextensions/lclextensions_package_doublecmd.pas

@@ -1,20 +0,0 @@
-{ This file was automatically created by Lazarus. Do not edit!
-  This source is only used to compile and install the package.
- }
-
-unit lclextensions_package_doublecmd;
-
-interface
-
-uses
-  DelphiCompat, oleutils, LclExt, LazarusPackageIntf;
-
-implementation
-
-procedure Register;
-begin
-end;
-
-initialization
-  RegisterPackage('lclextensions_package_doublecmd', @Register);
-end.

+ 0 - 149
components/lclextensions/oleutils.pas

@@ -1,149 +0,0 @@
-unit oleutils;
-
-{ OLE helper functions
-
-  Copyright (C) 2007 Luiz Américo Pereira Câmara
-  [email protected]
-
-  This library is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Library General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or (at your
-  option) any later version with the following modification:
-
-  As a special exception, the copyright holders of this library give you
-  permission to link this library with independent modules to produce an
-  executable, regardless of the license terms of these independent modules,and
-  to copy and distribute the resulting executable under terms of your choice,
-  provided that you also meet, for each linked independent module, the terms
-  and conditions of the license of that module. An independent module is a
-  module which is not derived from or based on this library. If you modify
-  this library, you may extend this exception to your version of the library,
-  but you are not obligated to do so. If you do not wish to do so, delete this
-  exception statement from your version.
-
-  This program is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
-  for more details.
-
-  You should have received a copy of the GNU Library General Public License
-  along with this library; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-}
-
-
-//todo: add error handling
-
-{$mode objfpc}{$H+}
-
-interface
-{$ifdef Windows}
-uses
-  Windows, Classes, SysUtils, ActiveX;
-
-type
-
-  { TOLEStream }
-
-  TOLEStream = class (TStream)
-  private
-    FSrcStream: IStream;
-    procedure InternalSetSize(NewSize: LARGE_INTEGER);
-  public
-    constructor Create(const Stream: IStream);
-    function Read(var Buffer; Count: Integer): Integer; override;
-    function Seek(Offset: Integer; Origin: Word): Integer; overload; override;
-    procedure SetSize(const NewSize: Int64); override;
-    procedure SetSize(NewSize: Longint); override;
-    function Write(const Buffer; Count: Integer): Integer; override;
-  end;
-{$endif}
-implementation
-{$ifdef Windows}
-
-function ErrorString(Error: HRESULT): String;
-begin
-  case Error of
-    E_PENDING: Result:='E_PENDING';
-    S_FALSE: Result:='S_FALSE';
-    STG_E_MEDIUMFULL: Result:='STG_E_MEDIUMFULL';
-    STG_E_ACCESSDENIED: Result:= 'STG_E_ACCESSDENIED';
-    STG_E_CANTSAVE: Result:='STG_E_CANTSAVE';
-    STG_E_INVALIDPOINTER: Result:='STG_E_INVALIDPOINTER';
-    STG_E_REVERTED: Result:='STG_E_REVERTED';
-    STG_E_WRITEFAULT: Result:='STG_E_WRITEFAULT';
-    STG_E_INVALIDFUNCTION: Result:='STG_E_INVALIDFUNCTION';
- else
-   Result:='Unknow error';
- end;
-  
-end;
-
-{ TOLEStream }
-
-constructor TOLEStream.Create(const Stream: IStream);
-begin
-  inherited Create;
-  FSrcStream:=Stream;
-end;
-
-function TOLEStream.Read(var Buffer; Count: Integer): Integer;
-var
-  Res: HRESULT;
-begin
-  Res:=FSrcStream.Read(@Buffer, Count, @Result);
-  if Res <> S_OK then
-    Raise Exception.Create('TOLEStream - Error while reading: '+ErrorString(Res));
-end;
-
-function TOLEStream.Seek(Offset: Integer; Origin: Word): Integer;
-var
-  liResult, liOffset : LARGE_INTEGER;
-  Res: HRESULT;
-begin
-  //soFrom* constants are equal to STREAM_SEEK_* constants. Assume it here
-  liOffset.LowPart:=Offset;
-  liOffset.HighPart:=0;
-  Res:=FSrcStream.Seek(Int64(liOffset), Origin, Int64(liResult));
-  Result:=liResult.LowPart;
-  if Res <> S_OK then
-    Raise Exception.Create('TOLEStream - Error while seeking: '+ErrorString(Res));
-end;
-
-procedure TOLEStream.SetSize(NewSize: Longint);
-var
-  liSize: LARGE_INTEGER;
-begin
-  liSize.LowPart:=NewSize;
-  liSize.HighPart:=0;
-  InternalSetSize(liSize);
-end;
-
-procedure TOLEStream.SetSize(const NewSize: Int64);
-var
-  liSize: LARGE_INTEGER;
-begin
-  liSize.QuadPart:=NewSize;
-  InternalSetSize(liSize);
-end;
-
-procedure TOLEStream.InternalSetSize(NewSize: LARGE_INTEGER);
-var
-  Res:HRESULT;
-begin
-  Res:=FSrcStream.SetSize(Int64(NewSize));
-  if Res <> S_OK then
-    Raise Exception.Create('TOLEStream - Error while setting size: '+ErrorString(Res));
-end;
-
-function TOLEStream.Write(const Buffer; Count: Integer): Integer;
-var
-  Res: HRESULT;
-begin
-  Res:=FSrcStream.Write(@Buffer,Count,@Result);
-  if Res <> S_OK then
-    Raise Exception.Create('TOLEStream - Error while writing: '+ErrorString(Res));
-end;
-{$endif}
-end.
-

+ 0 - 4
components/lclextensions/readme.txt

@@ -1,4 +0,0 @@
-lclextensions v0.4
-http://code.google.com/p/luipack/
-
-Some modifications done so that it only compiles VirtualTreeView.

+ 0 - 674
components/virtualtreeview/VTAccessibility.pas

@@ -1,674 +0,0 @@
-unit VTAccessibility;
-
-// This unit implements iAccessible interfaces for the VirtualTree visual components
-// and the currently focused node.
-//
-// Written by Marco Zehe. (c) 2007
-
-interface
-
-uses Windows, Classes, ActiveX, oleacc, VirtualTrees, VTAccessibilityFactory, Controls;
-
-type
-  TVirtualTreeAccessibility = class(TInterfacedObject, IDispatch, IAccessible)
-  private
-    FVirtualTree: TVirtualStringTree;
-  public
-    { IAccessibility }
-    function Get_accParent(out ppdispParent: IDispatch): HResult; stdcall;
-    function Get_accChildCount(out pcountChildren: Integer): HResult; stdcall;
-    function Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult; stdcall;
-    function Get_accName(varChild: OleVariant; out pszName: WideString): HResult; stdcall;
-    function Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult; stdcall;
-    function Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; stdcall;
-    function Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult; stdcall;
-    function Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult; stdcall;
-    function Get_accHelp(varChild: OleVariant; out pszHelp: WideString): HResult; stdcall;
-    function Get_accHelpTopic(out pszHelpFile: WideString; varChild: OleVariant;
-                              out pidTopic: Integer): HResult; stdcall;
-    function Get_accKeyboardShortcut(varChild: OleVariant; out pszKeyboardShortcut: WideString): HResult; stdcall;
-    function Get_accFocus(out pvarChild: OleVariant): HResult; stdcall;
-    function Get_accSelection(out pvarChildren: OleVariant): HResult; stdcall;
-    function Get_accDefaultAction(varChild: OleVariant; out pszDefaultAction: WideString): HResult; stdcall;
-    function accSelect(flagsSelect: Integer; varChild: OleVariant): HResult; stdcall;
-    function accLocation(out pxLeft: Integer; out pyTop: Integer; out pcxWidth: Integer;
-                         out pcyHeight: Integer; varChild: OleVariant): HResult; stdcall;
-    function accNavigate(navDir: Integer; varStart: OleVariant; out pvarEndUpAt: OleVariant): HResult; stdcall;
-    function accHitTest(xLeft: Integer; yTop: Integer; out pvarChild: OleVariant): HResult; stdcall;
-    function accDoDefaultAction(varChild: OleVariant): HResult; stdcall;
-    function Set_accName(varChild: OleVariant; const pszName: WideString): HResult; stdcall;
-    function Set_accValue(varChild: OleVariant; const pszValue: WideString): HResult; stdcall;
-    {IDispatch}
-    function GetIDsOfNames(const IID: TGUID; Names: Pointer;
-      NameCount: Integer; LocaleID: Integer; DispIDs: Pointer): HRESULT; stdcall;
-    function GetTypeInfo(Index: Integer; LocaleID: Integer;
-      out TypeInfo): HRESULT; stdcall;
-    function GetTypeInfoCount(out Count: Integer): HRESULT; stdcall;
-    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
-      Flags: Word; var Params; VarResult: Pointer; ExcepInfo: Pointer;
-      ArgErr: Pointer): HRESULT; stdcall;
-    constructor Create(VirtualTree: TVirtualStringTree);
-  end;
-
-  TVirtualTreeItemAccessibility = class(TVirtualTreeAccessibility, IAccessible)
-    public
-    { IAccessibility }
-    function Get_accParent(out ppdispParent: IDispatch): HResult; stdcall;
-    function Get_accChildCount(out pcountChildren: Integer): HResult; stdcall;
-    function Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult; stdcall;
-    function Get_accName(varChild: OleVariant; out pszName: WideString): HResult; stdcall;
-    function Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult; stdcall;
-    function Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; stdcall;
-    function Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult; stdcall;
-    function Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult; stdcall;
-    function accLocation(out pxLeft: Integer;
-      out pyTop: Integer; out pcxWidth: Integer;
-      out pcyHeight: Integer; varChild: OleVariant): HResult; stdcall;
-    constructor Create(VirtualTree: TVirtualStringTree);
-  end;
-
-  TVTMultiColumnItemAccessibility = class(TVirtualTreeItemAccessibility, IAccessible)
-    private
-    function GetItemDescription(varChild: OleVariant; out pszDescription: WideString; IncludeMainColumn: boolean): HResult; stdcall;
-    public
-    { IAccessibility }
-    function Get_accName(varChild: OleVariant; out pszName: WideString): HResult; stdcall;
-    function Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; stdcall;
-  end;
-
-  TVTDefaultAccessibleProvider = class(TInterfacedObject, IVTAccessibleProvider)
-    function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible;
-  end;
-
-  TVTDefaultAccessibleItemProvider = class(TInterfacedObject, IVTAccessibleProvider)
-    function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible;
-  end;
-
-  TVTMultiColumnAccessibleItemProvider = class(TInterfacedObject, IVTAccessibleProvider)
-    function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible;
-  end;
-
-implementation
-
-uses Variants, SysUtils, Types, Forms;
-
-{ TVirtualTreeAccessibility }
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeAccessibility.accDoDefaultAction(varChild: OleVariant): HResult;
-// a default action is not supported.
-begin
-  Result := DISP_E_MEMBERNOTFOUND;
-end;
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeAccessibility.accHitTest(xLeft: Integer; yTop: Integer; out pvarChild: OleVariant): HResult;
-// returns the iAccessible object at the given point, if applicable.
-var
-  Pt: TPoint;
-  HitInfo: THitInfo;
-begin
-  Result := S_FALSE;
-  if FVirtualTree <> nil then
-  begin
-//    VariantInit(pvarChild);
-//    TVarData(pvarChild).VType := VT_I4;
-    Pt := fVirtualTree.ScreenToClient(Point(xLeft, yTop));
-    if fVirtualTree.FocusedNode <> nil then
-    begin
-      fVirtualTree.GetHitTestInfoAt(xLeft, yTop, false, HitInfo);
-      if FVirtualTree.FocusedNode = HitInfo.HitNode then
-      begin
-        pvarChild := FVirtualTree.AccessibleItem;
-        Result := S_OK;
-        exit;
-      end;
-    end;
-    if PtInRect(FVirtualTree.BoundsRect, Pt) then
-    begin
-      pvarChild := CHILDID_SELF;
-      Result := S_OK;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.accLocation(out pxLeft: Integer;
-  out pyTop: Integer; out pcxWidth: Integer;
-  out pcyHeight: Integer; varChild: OleVariant): HResult;
-// returns the location of the VirtualStringTree object.
-var
-  P: TPoint;
-begin
-  Result := S_FALSE;
-  if varChild = CHILDID_SELF then
-  begin
-    if FVirtualTree <> nil then
-    begin
-      P := FVirtualTree.ClientToScreen(FVirtualTree.ClientRect.TopLeft);
-      pxLeft := P.X;
-      pyTop := P.Y;
-      pcxWidth := FVirtualTree.Width;
-      pcyHeight := FVirtualTree.Height;
-      Result := S_OK;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.accNavigate(navDir: Integer; varStart: OleVariant;
-  out pvarEndUpAt: OleVariant): HResult;
-// This is not supported.
-begin
-  Result := DISP_E_MEMBERNOTFOUND;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accSelection(out pvarChildren: OleVariant): HResult;
-// returns the selected child ID, if any.
-begin
-  Result := s_false;
-  if FVirtualTree <> nil then
-    if fVirtualTree.FocusedNode <> nil then
-    begin
-      pvarChildren := 1;
-      result := s_OK;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-constructor TVirtualTreeAccessibility.Create(VirtualTree: TVirtualStringTree);
-// assigns the parent and current fields, and lets the control's iAccessible object know its address.
-begin
-  fVirtualTree := VirtualTree;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.GetIDsOfNames(const IID: TGUID;
-  Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HRESULT;
-// Not supported.
-begin
-  Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.GetTypeInfo(Index, LocaleID: Integer;
-  out TypeInfo): HRESULT;
-// not supported.
-begin
-  Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.GetTypeInfoCount(
-  out Count: Integer): HRESULT;
-// not supported.
-begin
-  Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult;
-// returns the iAccessible child, whicfh represents the focused item.
-begin
-  if varChild = CHILDID_SELF then
-  begin
-    ppdispChild := FVirtualTree.AccessibleItem;
-    Result := S_OK;
-  end
-  else
-    Result := E_INVALIDARG
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accChildCount(out pcountChildren: Integer): HResult;
-// Returns the number 1 for the one child: The focused item.
-begin
-  pcountChildren := 1;
-  Result := S_OK;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accDefaultAction(varChild: OleVariant; out pszDefaultAction: WideString): HResult;
-// Not supported.
-begin
-  Result := DISP_E_MEMBERNOTFOUND;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult;
-// returns the hint of the control, if assigned.
-begin
-  pszDescription := '';
-  Result := S_FALSE;
-  if varChild = CHILDID_SELF then
-  begin
-    if FVirtualTree <> nil then
-      pszDescription := GetLongHint(fVirtualTree.Hint);
-  end;
-  if Length(pszDescription) > 0 then
-    Result := S_OK;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accFocus(out pvarChild: OleVariant): HResult;
-// returns the child ID of 1, if assigned.
-begin
-  Result := s_false;
-  if fVirtualTree <> nil then
-  begin
-    if FVirtualTree.FocusedNode <> nil then
-    begin
-      pvarChild := fVirtualTree.AccessibleItem;
-      result := s_OK;
-    end
-    else begin
-      pvarChild := childid_self;
-      result := S_OK;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accHelp(varChild: OleVariant; out pszHelp: WideString): HResult;
-// Not supported.
-begin
-  Result := DISP_E_MEMBERNOTFOUND;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accHelpTopic(out pszHelpFile: WideString; varChild: OleVariant;
-                          out pidTopic: Integer): HResult;
-// Returns the HelpContext ID, if present. 
-begin
-  pszHelpFile := '';
-  pidTopic := 0;
-  Result := S_OK;
-  if varChild = CHILDID_SELF then
-    if FVirtualTree <> nil then
-    begin
-      pszHelpFile := Application.HelpFile;
-      pidTopic := FVirtualTree.HelpContext;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accKeyboardShortcut(varChild: OleVariant; out pszKeyboardShortcut: WideString): HResult;
-// Not supported.
-begin
-  pszKeyboardShortcut := '';
-  Result := S_FALSE;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accName(varChild: OleVariant; out pszName: WideString): HResult;
-// if set, returns the new published AccessibleName property.
-// otherwise, returns the default text.
-begin
-  pszName := '';
-  Result := S_FALSE;
-  if varChild = CHILDID_SELF then
-  begin
-    if FVirtualTree <> nil then
-    begin
-      if FVirtualTree.AccessibleName <> '' then
-        pszName := FVirtualTree.AccessibleName
-      else
-        PSZName := FVirtualTree.DefaultText;
-      result := S_OK;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accParent(out ppdispParent: IDispatch): HResult;
-// Returns false, the tree itself does not have a parent.
-begin
-  ppdispParent := nil;
-  Result := S_FALSE;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult;
-// tells MSAA that it is a TreeView.
-begin
-  Result := S_OK;
-//  VariantInit(pvarRole);
-//  TVarData(pvarRole).VType := VT_I4;
-  if varChild = CHILDID_SELF then
-  begin
-    if FVirtualTree <> nil then
-      pvarRole := ROLE_SYSTEM_OUTLINE
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.accSelect(flagsSelect: Integer; varChild: OleVariant): HResult;
-// since we're not supporting more than one item, this is not supported currently.
-begin
-  Result := DISP_E_MEMBERNOTFOUND;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult;
-// returns the state of the control.
-const
-  IsEnabled: array[Boolean] of Integer = (STATE_SYSTEM_UNAVAILABLE, 0);
-  HasPopup: array[Boolean] of Integer = (0, STATE_SYSTEM_HASPOPUP);
-  IsVisible: array[Boolean] of Integer = (STATE_SYSTEM_INVISIBLE, 0);
-begin
-  Result := S_OK;
-//  VariantInit(pvarState);
-//  TVarData(pvarState).VType := VT_I4;
-  if varChild = CHILDID_SELF then
-  begin
-    if FVirtualTree <> nil then
-    begin
-      pvarState := STATE_SYSTEM_FOCUSED or STATE_SYSTEM_FOCUSABLE or STATE_SYSTEM_HOTTRACKED;
-      pvarState := pvarState or IsVisible[FVirtualTree.Visible];
-      pvarState := pvarState or IsEnabled[FVirtualTree.Enabled];
-    end
-    else
-      Result := E_INVALIDARG;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult;
-// the TreeView control itself does not have a value, returning false here.
-begin
-  pszValue := '';
-  Result := S_FALSE;//DISP_E_MEMBERNOTFOUND;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Invoke(DispID: Integer; const IID: TGUID;
-  LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,
-  ArgErr: Pointer): HRESULT;
-// not supported.
-begin
-  Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Set_accName(varChild: OleVariant; const pszName: WideString): HResult; stdcall;
-// not supported.
-begin
-  Result := DISP_E_MEMBERNOTFOUND
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeAccessibility.Set_accValue(varChild: OleVariant; const pszValue: WideString): HResult;
-// not supported.
-begin
-  Result := DISP_E_MEMBERNOTFOUND
-end;
-
-{ TVirtualTreeItemAccessibility }
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.accLocation(out pxLeft, pyTop, pcxWidth,
-  pcyHeight: Integer; varChild: OleVariant): HResult;
-// returns the location of the current accessible item.
-var
-  P: TPoint;
-  DisplayRect: TRect;
-begin
-  Result := S_FALSE;
-  if varChild = CHILDID_SELF then
-  begin
-   if FVirtualTree.FocusedNode <> nil then
-    begin
-      DisplayRect := FVirtualTree.GetDisplayRect(FVirtualTree.FocusedNode, -1, TRUE, FALSE);
-      P := FVirtualTree.ClientToScreen(DisplayRect.TopLeft);
-      pxLeft := P.X;
-      pyTop := P.Y;
-      pcxWidth := DisplayRect.Right - DisplayRect.Left;
-      pcyHeight := DisplayRect.Bottom - DisplayRect.Top;
-      Result := S_OK;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-constructor TVirtualTreeItemAccessibility.Create(VirtualTree: TVirtualStringTree);
-// sets up the parent/child relationship.
-begin
-  fVirtualTree := VirtualTree;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult;
-// the item does not have children. Returning false.
-begin
-  ppdispChild := nil;
-  Result := S_FALSE;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.Get_accChildCount(out pcountChildren: Integer): HResult;
-// the item itself does not have children, returning 0.
-begin
-  pcountChildren := 0;
-  Result := S_OK;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult;
-// not supported for an item.
-begin
-  Result := DISP_E_MEMBERNOTFOUND;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.Get_accName(varChild: OleVariant; out pszName: WideString): HResult;
-// the name is the node's caption.
-begin
-  pszName := '';
-  Result := S_FALSE;
-  if varChild = childid_self then
-  begin
-    if FVirtualTree <> nil then
-      if FVirtualTree.FocusedNode <> nil then
-      begin
-        pszName := FVirtualTree.Text[FVirtualTree.FocusedNode, FVirtualTree.Header.MainColumn];
-        result := S_OK;
-      end
-      else begin
-        PSZName := FVirtualTree.DefaultText;
-        result := S_OK;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.Get_accParent(out ppdispParent: IDispatch): HResult;
-// tells MSAA that the VritualStringTree is its parent.
-begin
-  result := S_FALSE;
-  if FVirtualTree <> nil then
-  begin
-    ppdispParent := FVirtualTree.Accessible;
-    Result := S_OK;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult;
-// tells MSAA that it is a TreeView item as opposed to the TreeView itself.
-begin
-  Result := S_OK;
-//  VariantInit(pvarRole);
-//  TVarData(pvarRole).VType := VT_I4;
-  if varChild = childid_self then
-  begin
-    if FVirtualTree <> nil then
-      pvarRole := ROLE_SYSTEM_OUTLINEITEM
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult;
-// Tells MSAA the state the item is in.
-const
-  IsEnabled: array[Boolean] of Integer = (STATE_SYSTEM_UNAVAILABLE, 0);
-  HasPopup: array[Boolean] of Integer = (0, STATE_SYSTEM_HASPOPUP);
-  IsVisible: array[Boolean] of Integer = (STATE_SYSTEM_INVISIBLE, 0);
-  IsChecked: array[Boolean] of Integer = (0, STATE_SYSTEM_CHECKED);
-  IsExpanded: array[Boolean] of Integer = (0, STATE_SYSTEM_EXPANDED);
-  IsCollapsed: array[Boolean] of Integer = (0, STATE_SYSTEM_COLLAPSED);
-begin
-  Result := S_OK;
-//  VariantInit(pvarState);
-//  TVarData(pvarState).VType := VT_I4;
-  if varChild = childid_self then
-  begin
-    if FVirtualTree <> nil then
-    begin
-      pvarState := STATE_SYSTEM_FOCUSED or STATE_SYSTEM_FOCUSABLE or STATE_SYSTEM_HOTTRACKED;
-      pvarState := pvarState or IsVisible[FVirtualTree.Visible];
-      pvarState := pvarState or IsEnabled[FVirtualTree.Enabled];
-      if fVirtualTree.FocusedNode <> nil then
-      begin
-        pvarState := pvarState or IsChecked[csCheckedNormal = FVirtualTree.FocusedNode.CheckState];
-        pvarState := pvarState or IsExpanded[VSExpanded in FVirtualTree.FocusedNode.States];
-        if not (vsExpanded in FVirtualTree.FocusedNode.States) then
-          pvarState:= PvarState or IsCollapsed[vsHasChildren in FVirtualTree.FocusedNode.States];
-     end;
-    end
-    else
-      Result := E_INVALIDARG;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-function TVirtualTreeItemAccessibility.Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult;
-// for a TreeView item, the value is the nesting level number, 0-based.
-begin
-  pszValue := '';
-  Result := S_FALSE;//DISP_E_MEMBERNOTFOUND;
-  if varChild = childid_self then
-    if FVirtualTree <> nil then
-      if FVirtualTree.FocusedNode <> nil then
-      begin
-        PSZValue := IntToStr(FVirtualTree.GetNodeLevel(FVirtualTree.FocusedNode));
-        result := S_OK;
-      end;
-end;
-
-{ TVTMultiColumnItemAccessibility }
-
-function TVTMultiColumnItemAccessibility.GetItemDescription(
-  varChild: OleVariant; out pszDescription: WideString;
-  IncludeMainColumn: boolean): HResult;
-var
-  I: Integer;
-  sTemp: WideString;
-begin
-  pszDescription := '';
-  Result := S_FALSE;
-  if varChild = childid_self then
-  begin
-    if FVirtualTree <> nil then
-      if FVirtualTree.FocusedNode <> nil then
-      begin
-        if IncludeMainColumn then
-          pszDescription := FVirtualTree.Text[FVirtualTree.FocusedNode, FVirtualTree.Header.MainColumn]
-           +'; ';
-        for I := 0 to FVirtualTree.Header.Columns.Count - 1 do
-          if FVirtualTree.Header.MainColumn <> I then
-          begin
-            sTemp := FVirtualTree.Text[FVirtualTree.FocusedNode, I];
-            if sTemp <> '' then
-              pszDescription := pszDescription
-               +FVirtualTree.Header.Columns[I].Text
-               +': '
-               +sTemp
-               +'; ';
-          end;
-          if pszDescription <> '' then
-            if pszDescription[Length(pszDescription)-1] = ';' then
-              Delete(pszDescription, length(pszDescription)-1, 2);
-        result := S_OK;
-      end
-      else begin
-        PSZDescription := FVirtualTree.DefaultText;
-        result := S_OK;
-      end;
-  end;
-end;
-
-function TVTMultiColumnItemAccessibility.Get_accDescription(
-  varChild: OleVariant; out pszDescription: WideString): HResult;
-begin
-  result := GetItemDescription(varChild, pszDescription, false)
-end;
-
-function TVTMultiColumnItemAccessibility.Get_accName(varChild: OleVariant;
-  out pszName: WideString): HResult;
-begin
-  result := GetItemDescription(varChild, pszName, true)
-end;
-
-{ TVTDefaultAccessibleProvider }
-
-function TVTDefaultAccessibleProvider.CreateIAccessible(
-  ATree: TBaseVirtualTree): IAccessible;
-begin
-  result := TVirtualTreeAccessibility.Create(TVirtualStringTree(ATree));
-end;
-
-{ TVTDefaultAccessibleItemProvider }
-
-function TVTDefaultAccessibleItemProvider.CreateIAccessible(
-  ATree: TBaseVirtualTree): IAccessible;
-begin
-  result := TVirtualTreeItemAccessibility.Create(TVirtualStringTree(ATree));
-end;
-
-{ TVTMultiColumnAccessibleItemProvider }
-
-function TVTMultiColumnAccessibleItemProvider.CreateIAccessible(
-  ATree: TBaseVirtualTree): IAccessible;
-begin
-  result := nil;
-  if TVirtualStringTree(ATree).Header.UseColumns then
-    result := TVTMultiColumnItemAccessibility.Create(TVirtualStringTree(ATree));
-end;
-
-var
-  IDefaultAccessibleProvider: TVTDefaultAccessibleProvider;
-  IDefaultAccessibleItemProvider: TVTDefaultAccessibleItemProvider;
-  IMultiColumnAccessibleProvider: TVTMultiColumnAccessibleItemProvider;
-
-initialization
-  if VTAccessibleFactory = nil then
-    VTAccessibleFactory := TVTAccessibilityFactory.Create;
-  if IDefaultAccessibleProvider = nil then
-  begin
-    IDefaultAccessibleProvider := TVTDefaultAccessibleProvider.Create;
-    VTAccessibleFactory.RegisterAccessibleProvider(IDefaultAccessibleProvider);
-  end;
-  if IDefaultAccessibleItemProvider = nil then
-  begin
-    IDefaultAccessibleItemProvider := TVTDefaultAccessibleItemProvider.Create;
-    VTAccessibleFactory.RegisterAccessibleProvider(IDefaultAccessibleItemProvider);
-  end;
-  if IMultiColumnAccessibleProvider = nil then
-  begin
-    IMultiColumnAccessibleProvider := TVTMultiColumnAccessibleItemProvider.Create;
-    VTAccessibleFactory.RegisterAccessibleProvider(IMultiColumnAccessibleProvider);
-  end;
-finalization
-  if VTAccessibleFactory <> nil then
-  begin
-    VTAccessibleFactory.UnRegisterAccessibleProvider(IMultiColumnAccessibleProvider);
-    IMultiColumnAccessibleProvider := nil;
-      VTAccessibleFactory.UnRegisterAccessibleProvider(IDefaultAccessibleItemProvider);
-    IDefaultAccessibleItemProvider := nil;
-    VTAccessibleFactory.UnRegisterAccessibleProvider(IDefaultAccessibleProvider);
-    IDefaultAccessibleProvider := nil;
-  end;
-
-end.
-

+ 0 - 123
components/virtualtreeview/VTAccessibilityFactory.pas

@@ -1,123 +0,0 @@
-unit VTAccessibilityFactory;
-
-// class to create IAccessibles for the tree passed into it.
-// If not already assigned, creates IAccessibles for the tree itself
-// and the focused item
-// the tree accessible is returned when the tree receives an WM_GETOBJECT message
-// the AccessibleItem is returned when the Accessible is being asked for the first child
-// To create your own IAccessibles, use the VTStandardAccessible unit as a reference,
-// and assign your Accessibles to the variables in tthe unit's initialization.
-// You only need to add the unit to your project, and voilá, you have an accessible string tree!
-//
-// Written by Marco Zehe. (c) 2007
-
-interface
-
-uses
-  Classes, oleacc, VirtualTrees;
-
-type
-  IVTAccessibleProvider = interface
-    function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible;
-  end;
-
-  TVTAccessibilityFactory = class(TObject)
-  private
-    FAccessibleProviders: TInterfaceList;
-  public
-    constructor Create;
-    destructor Destroy; override;
-    function CreateIAccessible(ATree: TBaseVirtualTree): IAccessible;
-    procedure RegisterAccessibleProvider(AProvider: IVTAccessibleProvider);
-    procedure UnRegisterAccessibleProvider(AProvider: IVTAccessibleProvider);
-  end;
-
-var
-  VTAccessibleFactory: TVTAccessibilityFactory;
-
-implementation
-
-{ TVTAccessibilityFactory }
-
-constructor TVTAccessibilityFactory.Create;
-begin
-  inherited;
-  FAccessibleProviders := TInterfaceList.Create;
-  FAccessibleProviders.Clear;
-end;
-
-function TVTAccessibilityFactory.CreateIAccessible(
-  ATree: TBaseVirtualTree): IAccessible;
-var
-  I: Integer;
-  TmpIAccessible: IAccessible;
-// returns an IAccessible.
-// 1. If the Accessible property of the passed-in tree is nil,
-// the first registered element will be returned.
-// Usually, this is the IAccessible that provides information about the tree itself.
-// If it is not nil, we'll check whether the AccessibleItem is nil.
-// If it is, we'll look in the registered IAccessibles for the appropriate one.
-// Each IAccessibleProvider will check the tree for properties to determine whether it is responsible.
-// We'll work top to bottom, from the most complicated to the most simple.
-// 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
-  begin
-    if ATree.Accessible = nil then
-    begin
-      if FAccessibleProviders.Count > 0 then
-      begin
-        result := IVTAccessibleProvider(FAccessibleProviders.Items[0]).CreateIAccessible(ATree);
-        exit;
-      end;
-    end;
-    if ATree.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);
-          if TmpIAccessible <> nil then
-          begin
-            result := TmpIAccessible;
-            break;
-          end;
-        end;
-        if TmpIAccessible = nil then
-        begin
-          result := IVTAccessibleProvider(FAccessibleProviders.Items[0]).CreateIAccessible(ATree);
-        end;
-      end;
-    end
-    else begin
-      result := ATree.AccessibleItem;
-    end;
-  end;
-end;
-
-destructor TVTAccessibilityFactory.Destroy;
-begin
-  FAccessibleProviders.Free;
-  FAccessibleProviders := nil;
-  inherited;
-end;
-
-procedure TVTAccessibilityFactory.RegisterAccessibleProvider(
-  AProvider: IVTAccessibleProvider);
-// Ads a provider if it is not already registered
-begin
-  if FAccessibleProviders.IndexOf(AProvider) < 0 then
-    FAccessibleProviders.Add(AProvider)
-end;
-
-procedure TVTAccessibilityFactory.UnRegisterAccessibleProvider(
-  AProvider: IVTAccessibleProvider);
-// Unregisters/removes an IAccessible provider if it is present
-begin
-  if FAccessibleProviders.IndexOf(AProvider) >= 0 then
-    FAccessibleProviders.Remove(AProvider);
-end;
-
-end.

+ 0 - 49
components/virtualtreeview/VTConfig.inc

@@ -1,49 +0,0 @@
-// Configuration file for VirtualTrees.pas (see www.soft-gems.net).
-//
-// The content of this file is public domain. You may do with it whatever you like, provided the header stays fully intact
-// in all version and derivative work.
-//
-// The original code is VTConfig.inc, released October 5, 2004.
-//
-// The initial developer of the original code is Mike Lischke ([email protected], www.soft-gems.net).
-//----------------------------------------------------------------------------------------------------------------------
-
-{.$define UseFlatScrollbars}
-{.$define ReverseFullExpandHotKey} // Used to define Ctrl+'+' instead of Ctrl+Shift+'+' for full expand (and similar for collapsing).
-
-// Enable this switch for Windows XP theme support. If you compile with Delphi 6 or lower you must download and install
-// the Soft Gems Theme Manager package.
-{.$define ThemeSupport}
-
-// Virtual Treeview can use a tiny but very effective local memory manager for node allocation.
-// The local memory manager was implemented by David Clark from Caelo Software Inc.
-// See below for more info about it.
-{.$define UseLocalMemoryManager}
-
-
-//Lazarus port options
-{.$define EnableOLE}
-{.$define EnableNativeTVM}
-{.$define EnablePrint}
-{.$define EnableNCFunctions}
-{$define EnableAdvancedGraphics}
-{$define EnableAlphaBlend}
-{.$define EnableAccessible}
-{$define ThemeSupport}
-{$if defined(LCLWin32) or defined(LCLWinCE)}
-  {$define LCLWin}
-{$endif}
-{.$define DEBUG_VTV}
-{$define USE_DELPHICOMPAT}
-//since
-{$if not defined(USE_DELPHICOMPAT) and not defined(LCLWin)}
-  {$define INCOMPLETE_WINAPI}
-{$endif}
-
-//under linux the performance is poor with threading enabled
-{$ifdef Windows}
-  {.$define EnableThreadSupport}
-{$endif}
-{$ifdef CPU64}
-  {$define PACKARRAYPASCAL}
-{$endif}

+ 0 - 32
components/virtualtreeview/VTGraphics.pas

@@ -1,32 +0,0 @@
-unit VTGraphics; 
-
-{$mode delphi}
-
-interface
-
-uses
-  DelphiCompat, Types, LCLIntf, LCLType;
-
-type
-  // Describes the mode how to blend pixels.
-  TBlendMode = (
-    bmConstantAlpha,         // apply given constant alpha
-    bmPerPixelAlpha,         // use alpha value of the source pixel
-    bmMasterAlpha,           // use alpha value of source pixel and multiply it with the constant alpha value
-    bmConstantAlphaAndColor  // blend the destination color with the given constant color und the constant alpha value
-  );
-
-
-
-procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer);
-
-function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer;
-
-function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer;
-
-implementation
-
-{$i vtgraphicsi.inc}
-
-end.
-

+ 0 - 250
components/virtualtreeview/VTHeaderPopup.pas

@@ -1,250 +0,0 @@
-unit VTHeaderPopup;
-
-//----------------------------------------------------------------------------------------------------------------------
-// The contents of this file are subject to the Mozilla Public License
-// Version 1.1 (the "License"); you may not use this file except in
-// compliance with the License. You may obtain a copy of the License at
-// http://www.mozilla.org/MPL/
-//
-// Alternatively, you may redistribute this library, use and/or modify it under the terms of the
-// GNU Lesser General Public License as published by the Free Software Foundation;
-// either version 2.1 of the License, or (at your option) any later version.
-// You may obtain a copy of the LGPL at http://www.gnu.org/copyleft/.
-//
-// Software distributed under the License is distributed on an "AS IS"
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-// License for the specific language governing rights and limitations
-// under the License.
-//
-// The Original Code is VTHeaderPopup.pas.
-//
-// The Initial Developer of the Original Code is Ralf Junker <[email protected]>. All Rights Reserved.
-//
-// September 2004:
-//  - Bug fix: TVTHeaderPopupMenu.OnMenuItemClick used the wrong Tag member for the event.
-// 
-// Modified 12 Dec 2003 by Ralf Junker <[email protected]>.
-//   - Added missing default storage specifier for Options property.
-//   - To avoid mixing up image lists of different trees sharing the same header 
-//     popup, set the popup's image list to nil if hoShowImages is not in the 
-//     tree's header options.
-//   - Added an additional check for the PopupComponent property before casting 
-//     it hardly to a Virtual Treeview in OnMenuItemClick. See entry 31 Mar 2003.
-//
-// Modified 14 Sep 2003 by Mike Lischke <[email protected]>.
-//   - Renamed event type name to be consistent with other event types (e.g. used in VT).
-//   - Added event for hiding/showing columns.
-//   - DoXXX method are now virtual.
-//   - Conditional code rearrangement to get back Ctrl+Shift+Up/Down navigation.
-//
-// Modified 31 Mar 2003 by Mike Lischke <[email protected]>.
-//   - Added a check for the PopupComponent property before casting it hardly to 
-//     a Virtual Treeview. People might (accidentally) misuse the header popup.
-//
-// Modified 20 Oct 2002 by Borut Maricic <[email protected]>.
-//   - Added the possibility to use Troy Wolbrink's Unicode aware popup menu. 
-//     Define the compiler symbol TNT to enable it. You can get Troy's Unicode 
-//     controls collection from http://home.ccci.org/wolbrink/tnt/delphi_unicode_controls.htm.
-//
-// Modified 24 Feb 2002 by Ralf Junker <[email protected]>.
-//   - Fixed a bug where the OnAddHeaderPopupItem would interfere with 
-//     poAllowHideAll options.
-//   - All column indexes now consistently use TColumnIndex (instead of Integer).
-//
-// Modified 23 Feb 2002 by Ralf Junker <[email protected]>.
-//   - Added option to show menu items in the same order as the columns or in 
-//     original order.
-//   - Added option to prevent the user to hide all columns.
-//
-// Modified 17 Feb 2002 by Jim Kueneman <[email protected]>.
-//   - Added the event to filter the items as they are added to the menu.
-//----------------------------------------------------------------------------------------------------------------------
-{$mode delphi}
-
-interface
-
-uses
-  {$ifdef TNT}
-    TntMenus,
-  {$else}
-    Menus,
-  {$endif TNT}
-  VirtualTrees;
-
-type
-  TVTHeaderPopupOption = (
-    poOriginalOrder, // Show menu items in original column order as they were added to the tree.
-    poAllowHideAll   // Allows to hide all columns, including the last one.
-  );
-  TVTHeaderPopupOptions = set of TVTHeaderPopupOption;
-
-  TAddPopupItemType = (
-    apNormal,
-    apDisabled,
-    apHidden
-  );
-
-  TAddHeaderPopupItemEvent = procedure(const Sender: TBaseVirtualTree; const Column: TColumnIndex;
-    var Cmd: TAddPopupItemType) of object;
-  TColumnChangeEvent = procedure(const Sender: TBaseVirtualTree; const Column: TColumnIndex; Visible: Boolean) of object;
-
-  {$ifdef TNT}
-    TVTMenuItem = TTntMenuItem;
-  {$else}
-    TVTMenuItem = TMenuItem;
-  {$endif}
-
-  {$ifdef TNT}
-    TVTHeaderPopupMenu = class(TTntPopupMenu)
-  {$else}
-    TVTHeaderPopupMenu = class(TPopupMenu)
-  {$endif}
-  private
-    FOptions: TVTHeaderPopupOptions;
-
-    FOnAddHeaderPopupItem: TAddHeaderPopupItemEvent;
-    FOnColumnChange: TColumnChangeEvent;
-  protected
-    procedure DoAddHeaderPopupItem(const Column: TColumnIndex; out Cmd: TAddPopupItemType); virtual;
-    procedure DoColumnChange(Column: TColumnIndex; Visible: Boolean); virtual;
-    procedure OnMenuItemClick(Sender: TObject);
-  public
-    procedure Popup(x, y: Integer); override;
-  published
-    property Options: TVTHeaderPopupOptions read FOptions write FOptions default [];
-
-    property OnAddHeaderPopupItem: TAddHeaderPopupItemEvent read FOnAddHeaderPopupItem write FOnAddHeaderPopupItem;
-    property OnColumnChange: TColumnChangeEvent read FOnColumnChange write FOnColumnChange;
-  end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-implementation
-
-uses
-  {$ifdef TNT}
-    TnTClasses
-  {$else}
-    Classes
-  {$endif TNT};
-
-type
-  TVirtualTreeCast = class(TBaseVirtualTree); // Necessary to make the header accessible.
-
-//----------------- TVTHeaderPopupMenu ---------------------------------------------------------------------------------
-
-procedure TVTHeaderPopupMenu.DoAddHeaderPopupItem(const Column: TColumnIndex; out Cmd: TAddPopupItemType);
-
-begin
-  Cmd := apNormal;
-  if Assigned(FOnAddHeaderPopupItem) then
-    FOnAddHeaderPopupItem(TVirtualTreeCast(PopupComponent), Column, Cmd);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeaderPopupMenu.DoColumnChange(Column: TColumnIndex; Visible: Boolean);
-
-begin
-  if Assigned(FOnColumnChange) then
-    FOnColumnChange(TVirtualTreeCast(PopupComponent), Column, Visible);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeaderPopupMenu.OnMenuItemClick(Sender: TObject);
-
-begin
-  if Assigned(PopupComponent) and (PopupComponent is TBaseVirtualTree) then
-    with TVTMenuItem(Sender),
-      TVirtualTreeCast(PopupComponent).Header.Columns.Items[Tag] do
-    begin
-      if Checked then
-        Options := Options - [coVisible]
-      else
-        Options := Options + [coVisible];
-
-       DoColumnChange(TVTMenuItem(Sender).Tag, not Checked);
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeaderPopupMenu.Popup(x, y: Integer);
-
-var
-  I: Integer;
-  ColPos: TColumnPosition;
-  ColIdx: TColumnIndex;
-
-  NewMenuItem: TVTMenuItem;
-  Cmd: TAddPopupItemType;
-
-  VisibleCounter: Cardinal;
-  VisibleItem: TVTMenuItem;
-
-begin
-  if Assigned(PopupComponent) and (PopupComponent is TBaseVirtualTree) then
-  begin
-    // Delete existing menu items.
-    I := Items.Count;
-    while I > 0 do
-    begin
-      Dec(I);
-      Items[I].Free;
-    end;
-
-    // Add column menu items.
-    with TVirtualTreeCast(PopupComponent).Header do
-    begin
-      if hoShowImages in Options then
-        Self.Images := Images
-      else
-        // Remove a possible reference to image list of another tree previously assigned.
-        Self.Images := nil;
-      VisibleItem := nil;
-      VisibleCounter := 0;
-      for ColPos := 0 to Columns.Count - 1 do
-      begin
-        if poOriginalOrder in FOptions then
-          ColIdx := ColPos
-        else
-          ColIdx := Columns.ColumnFromPosition(ColPos);
-
-        with Columns[ColIdx] do
-        begin
-          if coVisible in Options then
-            Inc(VisibleCounter);
-          DoAddHeaderPopupItem(ColIdx, Cmd);
-          if Cmd <> apHidden then
-          begin
-            NewMenuItem := TVTMenuItem.Create(Self);
-            NewMenuItem.Tag := ColIdx;
-            NewMenuItem.Caption := Text;
-            NewMenuItem.Hint := Hint;
-            NewMenuItem.ImageIndex := ImageIndex;
-            NewMenuItem.Checked := coVisible in Options;
-            NewMenuItem.OnClick := OnMenuItemClick;
-            if Cmd = apDisabled then
-              NewMenuItem.Enabled := False
-            else
-              if coVisible in Options then
-                VisibleItem := NewMenuItem;
-            Items.Add(NewMenuItem);
-          end;
-        end;
-      end;
-
-      // Conditionally disable menu item of last enabled column.
-      if (VisibleCounter = 1) and (VisibleItem <> nil) and not (poAllowHideAll in FOptions) then
-        VisibleItem.Enabled := False;
-    end;
-  end;
-  
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-end.
-

+ 0 - 32981
components/virtualtreeview/VirtualTrees.pas

@@ -1,32981 +0,0 @@
-unit VirtualTrees;
-
-{$mode delphi}{$H+}
-{$packset 1}
-
-// Version 4.8.7
-//
-// The contents of this file are subject to the Mozilla Public License
-// Version 1.1 (the "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
-//
-// Alternatively, you may redistribute this library, use and/or modify it under the terms of the
-// GNU Lesser General Public License as published by the Free Software Foundation;
-// either version 2.1 of the License, or (at your option) any later version.
-// You may obtain a copy of the LGPL at http://www.gnu.org/copyleft/.
-//
-// Software distributed under the License is distributed on an "AS IS" basis,
-// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
-// specific language governing rights and limitations under the License.
-//
-// The original code is VirtualTrees.pas, released September 30, 2000.
-//
-// The initial developer of the original code is digital publishing AG (Munich, Germany, www.digitalpublishing.de),
-// written by Mike Lischke ([email protected], www.soft-gems.net).
-//
-// Portions created by digital publishing AG are Copyright
-// (C) 1999-2001 digital publishing AG. All Rights Reserved.
-//----------------------------------------------------------------------------------------------------------------------
-//
-//  April 2010
-//    - Bug fix: Removed active column changing from TBaseVirtualTree.WMKeyDown to re-gain standard conforming
-//               behaviour for VK_NEXT and VK_PRIOR
-//    - Bug fix: Paint option toUseExplorerTheme works properly without defining columns
-//    - Bug fix: TBaseVirtualTree.PrepareBitmaps now correctly closes the theme handle
-//  January 2010
-//   - Bug fix: TBaseVirtualTree.AdjustTotalHeight now longer calculates wrong total heights if nodes have been
-//              made invisible
-//   - Bug fix: TCustomVirtualStringTree.OnMeasureTextWidth now works as intended
-//   - Bug fix: Added missing $IFDEFs concerning theming support
-//   - Bug fix: Removed default from properties TVirtualTreeColumn.Color and TVirtualTreeColumn.BiDiMode
-//  July 2009
-//   - Bug fix: TWorkerThread will no longer reference the tree after it has been destroyed (Mantis issue #384)
-//   - Bug fix: TBaseVirtualTree.InternalConnectNode checked the expanded state of the wrong node if Mode was
-//              amAddChildFirst or amAddChildLast
-//  June 2009
-//   - Bug fix: fixed some issues concerning the vista theme handling
-//   - Improvement: removed hidden node handling in this branch
-//   - Improvement: reverted header click handling to old version to keep compatibility in this branch
-//   - Improvement: removed TVTPaintOption toHideTreeLinesIfThemed
-//  May 2009
-//   - Improvement: new TVTMiscOption toEditOnClick, toEditOnDblClick to control if editing can be started with a single
-//                  click or a double click
-//   - Bug fix: the internal pointers of TBufferedAnsiString are now PAnsiChar to work correctly with Delphi 2009
-//  April 2009
-//   - Bug fix: TBaseVirtualTree.GetVisibleParent no longer returns the given node in case it is fully visible
-//   - Improvement: fixed a potential issue in TVirtualTreeColumns.TotalWidth in case it is called before
-//                  FPositionToIndex is initialized
-//   - Bug fix: TBaseVirtualTree.CollectSelectedNodesLTR and TBaseVirtualTree.CollectSelectedNodesRTL handle straight
-//              vertical selection rectangles no longer as empty
-//   - Bug fix: TCheckImageKind.ckSystemDefault now works as intended
-//   - Improvement: made the following methods of TBaseVirtualTree virtual: PrepareCell, AddChild, BeginUpdate,
-//                  EndUpdate and SortTree
-//   - Improvement: made TBaseVirtualTree.PrepareCell protected
-//   - Improvement: moved some members of TVTEdit and TStringEditLink from private to protected
-//   - Improvement: re-designed header click handling
-//   - Improvement: new TVTPaintOption toShowHiddenNodes to globally ignore the hidden state of nodes
-//   - Improvement: individual nodes can now be hidden without affecting their children
-//   - Improvement: re-designed Explorer theme drawing
-//   - Bug fix: corrected allocation problems in TBufferedAnsiString and TWideBufferedString
-//  March 2009
-//   - Bug fix: fixed an issue in TVirtualTreeColumns.HandleClick that could lead to a case where no header click event
-//              is triggered
-//   - Bug fix: fixed an issue in TBaseVirtualTree.HandleHotTrack that could lead to an endless loop under certain
-//              conditions
-//   - Improvement: removed unused variables in TVirtualTreeColumn.ComputeHeaderLayout
-//   - Bug fix: corrected TBaseVirtualTree.GetVisibleParent
-//   - Improvement: extended hot node tracking to track the hot column too
-//   - Improvement: new THitPosition hiOnItemButtonExact used to draw hot buttons when using Windows Vista's Explorer
-//                  theme
-//   - Improvement: new TVTPaintOption toHideTreeLinesIfThemed to consider toShowTreeLines only if running unthemed
-//   - Improvement: new TVTPaintOption toUseExplorerTheme to draw the tree like Windows Vista's Explorer treeview
-//  February 2009
-//   - Bug fix: reverted the implementation of DrawTextW back to the one prior to 4.8.1 as the line end detection
-//              lead to a compiler warning under Delphi 2009
-//   - Bug fix: corrected implementation of GetStringDrawRect to match its declaration (UnicodeString vs WideString)
-//   - Bug fix: the node focus will no longer change if a TVTMiscOption.toGridExtensions is set and one clicks right of
-//              (or left of, if right-to-left reading) the last column
-//   - Bug fix: fixed an issue with TVTHeader.Assign that could lead to an access violation if the header is created at
-//              runtime
-//   - Bug fix: one can no longer change a node's height with the right mouse button even if toNodeHeightResize and
-//              toRightClickSelect are set
-//   - Improvement: TVTAutoOption.toDisableAutoScrollOnFocus now works for nodes too
-//   - Improvement: new property TBaseVirtualTree.SelectionLocked to disable changing the selection
-//   - Improvement: made the dual-scroll effect in TBaseVirtualTree.ToggleNode much smoother
-//   - Bug fix: removed off-by-1 errors in TBaseVirtualTree.ToggleNode
-//   - Bug fix: added a check for FUpdateCount to TBaseVirtualTree.SetUpdateState as otherwise every call to
-//              TBaseVirtualTree.DoBeforeCellPaint to get the cell content margin within an Begin/EndUpdate-block would
-//              re-enable painting
-//   - Bug fix: TVTHeader.HandleMessage could provide a wrong column index to OnBeforeColumnWidthTracking in some cases
-//   - Improvement: new properties TBaseVirtualTree.OnBeforeAutoFitColumn, TBaseVirtualTree.OnAfterAutoFitColumn
-//   - Improvement: new procedures TBaseVirtualTree.CancelOperation, TBaseVirtualTree.BeginOperation,
-//                  TBaseVirtualTree.EndOperation and new property TBaseVirtualTree.OperationCanceled to enable the
-//                  application to stop (possibly) long-running operations
-//   - Improvement: integrated changes from Andreas Hausladen
-//   - Improvement: integrated changes from Dmitry Zegebart where applicable
-//   - Bug fix: removed off-by-1 error in TBaseVirtualTree.GetDisplayRect
-//   - Bug fix: changed the size of the buffer used in TBaseVirtualTree.PaintTree to paint the area below the last node
-//              as the bitmap was not completely erased using previous size under certain conditions
-//   - Bug fix: fixed TBaseVirtualTree.GetPreviousLevel
-// January 2009
-//   - Bug fix: removed off-by-1 error in  TBaseVirtualTree.GetBottomNode
-//   - Improvement: improved speed of TBaseVirtualTree.GetMaxColumnWidth when using UseSmartColumnWidth
-//   - Version is now 4.8.0
-// December 2008
-//   - Bug fix: modified TBaseVirtualTree.UpdateHorizontalScrollbar and TBaseVirtualTree.UpdateVerticalScrollbar to
-//              recalculate the tree's dimensions even if an update is in progress
-//   - Improvement: renamed TVTHeaderState hsTracking and hsTrackPending to hsColumnWidthTracking and
-//                  hsColumnWidthTrackPending
-//   - Improvement: modified TBaseVirtualTree.GetFirstVisible and TBaseVirtualTree.GetFirstVisibleNoInit to optionally
-//                  take a node to specify where to start
-//   - Improvement: modified TVTAfterGetMaxColumnWidthEvent to make the result of TBaseVirtualTree.GetMaxColumnWidth
-//                  changable
-//   - Bug fix: corrected TBaseVirtualTree.GetMaxColumnWidth to consider toFixedIndent and no longer take nodes into
-//              account that are just above or below the visible area
-//   - Improvement: new property TVirtualTreeColumns.DefaultWidth
-//   - Improvement: new property TVTHeader.FixedAreaConstraints (new class TVTFixedAreaConstraints) to limit the
-//                  fixed area (header, fixed columns) to a percentage of the client area
-// November 2008
-//   - Improvement: new cursor added: crVertSplit used for height tracking
-//   - Improvement: changed type of TVTHeader.Height from Cardinal to Integer to make boundary checks easier
-//   - Improvement: new properties TVTHeader.MinHeight and TVTHeader.MaxHeight
-//   - Improvement: new VirtualTreeStates tsNodeHeightTracking and tsNodeHeightTrackPending
-//   - Improvement: new HeaderStates hsHeightTracking and hsHeightTrackPending
-//   - Improvement: new TVTMiscOption toNodeHeightResize to allow changing node heights via mouse
-//   - Improvement: new TVTHeaderOption hoHeightResize to allow changing header height via mouse
-//   - Improvement: new properties TBaseVirtualTree.OnHeaderHeightTracking, TBaseVirtualTree.OnHeaderDblClickResize,
-//                  TBaseVirtualTree.OnColumnWidthTracking, TBaseVirtualTree.OnColumnWidthDblClickResize,
-//                  TBaseVirtualTree.OnNodeHeightTracking, TBaseVirtualTree.OnNodeHeightDblClickResize
-//   - Improvement: new function TVTHeader.ResizeColumns to resize multiple columns at once
-//   - Improvement: TVTHeader.DetermineSplitterIndex is no longer influenced by non-resizable columns
-//   - Bug fix: TBaseVirtualTree.ToggleNode now uses DoStateChange to modify FStates
-//   - Bug fix: TBaseVirtualTree.DoBeforeCellPaint now saves the update rect if CellPaintMode is cpmGetContentMargin
-//              and restores it afterwards
-//   - Improvement: modified TBaseVirtualTree.CmMouseWheel to handle mice with wheel delta < 120 correctly
-//   - Improvement: modified TVTHeader.LoadFromStream and WriteToStream to save ParentFont
-//   - Improvement: TVTHeader.Font is now only stored by Delphi if ParentFont is False (Mantis issue #217)
-//   - Bug fix: corrected TVTHeader.Create to set TVTHeader.FOptions correctly to the default value (Mantis issue #333)
-//   - Improvement: new TVTAnimationOption toAdvancedAnimatedToggle to scroll the node to be toggled animatedly instead
-//                  of just scroll its child nodes animatedly
-//   - Improvement: added VirtualTreeState tsToggling to eliminate artefacts caused by TBaseVirtualTree.DoSetOffsetXY
-//                  while toggling
-//   - Bug fix: corrected button handling when toFixedIndent is set
-//   - Improvement: redesigned TBaseVirtualTree.ToggleNode to harmonize the visual toggle behaviour independent of
-//                  toChildrenAbove
-//   - Improvement: made TBaseVirtualTree.CanEdit public
-//   - Improvement: added parameter ConsiderChildrenAbove to TGetNextNodeProc
-//   - Improvement: modified all variants of TBaseVirtualTree.GetFirst and TBaseVirtualTree.GetLast to optionally
-//                  consider toChildrenAbove
-// October 2008
-//   - Bugfix: removed 'FVisibleCount := 0' from TBaseVirtualTree.Clear as this would lead to incorrect VisibleCount in
-//             read-only mode
-//   - Bugfix: fixed a condition in TBaseVirtualTree.ToggleCallback that could lead to artefacts
-//   - Improvement: changed the implementation of TBaseVirtualTree.GetNext/GetPrevious so that no penalties occur if
-//                  toChildrenAbove is not set
-//   - Improvement: TBaseVirtualTree.ToggleNode will no longer leave nodes with state vsToggeling if an exception
-//                  occurs
-//   - Improvement: improved behaviour of TBaseVirtualTree.ToggleNode in case toChildrenAbove is set
-//   - Bug fix: corrected TBaseVirtualTree.ScrollIntoView to behave as expected when no fixed columns exist
-//   - Bug fix: extended TBaseVirtualTree.InitializeLineImageAndSelectLevel to eliminate artifacts while scrolling with
-//              toChildrenAbove set
-//   - Bug fix: corrected CompareNodePositions to consider toChildrenAbove
-//   - Bug fix: corrected ToggleNode to scroll correctly if toChildrenAbove and toAnimatedToggle are set
-//   - Improvement: new TVTPaintOption toFixedIndent to draw the tree with a fixed ident (instead of node level
-//                  dependent indents)
-//   - Improvement: new TVTPaintOption toChildrenAbove to draw children nodes above their parent
-// August 2008
-//   - Improvement: redesigned and overloaded TBaseVirtualTree.ScrollIntoView in order to use vertical scrolling
-//                  separately
-//   - Improvement: optimized TBaseVirtualTree.ScrollIntoView for horizontal scrolling
-//   - Improvement: in TBaseVirtualTree.WMKeyDown column navigation for VK_PRIOR and VK_NEXT is now handled in same way
-//                  as row navigation
-//   - Improvement: new TVTHeaderOption hoDisableAnimatedResize to disable animated resize for all columns
-//   - Improvement: new TVTColumnOption coDisableAnimatedResize to disable animated resize for a specific column
-//   - Improvement: in TBaseVirtualTree.UpdateHorizontalScrollBar and TBaseVirtualTree.UpdateVerticalScrollBar scrollbar
-//                  updates now avoided for tsUpdating in FStates
-// July 2008
-//   - Improvement: in TBaseVirtualTree.WMHScroll the horizontal page scrolling now considers fixed columns
-//   - Improvement: in TBaseVirtualTree.ScrollIntoView the case of FFocusedColumn being invalid is considered
-//   - Improvement: in TBaseVirtualTree.HandleMouseDown DoFocusNode is not called if node focus did not change
-//   - Improvement: in TBaseVirtualTree.SetFocusedColumn the focused node will only be invalidate if it was actually
-//                  scrolled into view
-//   - Improvement: new TVTColumnOption coAllowFocus to affect column focus behaviour
-//   - Improvement: new function TVTHeader.AllowFocus to check wether a column can be focused
-//   - Improvement: in TBaseVirtualTree.SetFocusedColumn the old colunm and the new column are both invalidated
-//   - Improvement: merged latest changes from Jim into current code base.
-// June 2008
-//   - Improvement: new property TVirtualTreeColumns.Count
-//   - Bug fix: in TVirtualTreeColumns.AnimatedResize the column is validated (to avoid "List index out of bounds")
-//   - Improvement: the content retangle of the cell can be modified via the OnBeforeCellPaint event, the cell paint
-//                  mode indicates wether OnBeforeCellPaint is called for painting the cell or just for getting the
-//                  cell content margin
-//   - Improvement: new functions added: TBaseVirtualTree.DoGetCellContentMargins,
-//                  TCustomVirtualDrawTree.DoGetCellContentMargin
-//   - Improvement: new property: TCustomVirtualDrawTree.OnGetCellContentMargin
-//   - Improvement: in TBaseVirtualTree.GetMaxColumnWidth the cell content margin is considered
-//   - Improvement: in TBaseVirtualTree.CMHintShow the cell content margin is considered for singleline tooltips
-//   - Improvement: new function added: TVTHeader.DoGetPopupMenu (to query the application via TreeView.FOnGetPopupMenu
-//                  for a column specific header popup menu)
-//   - Improvement: new property added: TBaseVirtualTree.OnCanSplitterResizeColumn,
-//                  new function added: TVirtualTreeColumns.GetScrollWidth
-//   - Improvement: horizontal page scrolling now uses the average column width (of all visible, non-fixed columns) as
-//                  scroll amount
-//   - Improvement: procedure TBaseVirtualTree.CMMouseWheel redesigned
-//   - Bug fix: TVTHeader.DetermineSplitterIndex works correctly even when using fixed columns
-//   - Bug fix: on right-to-left BiDiMode TVirtualTreeColumns.PaintHeader respects (left) scroll bar correctly
-//   - Bug fix: for multiline tooltips also the column width is checked to determine the tooltip is needed or
-//              unnecessary
-//   - Improvement: the result value of GetUseSmartColumnWidth is initialized correctly
-//   - Improvement: added hoFullRepaintOnResize to TVTHeaderOption to enable full header repainting (instead of
-//                  repainting all subsequent columns only) on resizing a column
-//   - Bug fix: horizontal page scrolling via mouse wheel now works correctly, i.e. in TBaseVirtualTree.CMMouseWheel
-//              ScrollCount includes GetVisibleFixedWidth and FIndent
-//   - Improvement: new TVTColumnOption coSmartResize to avoid contradicting the virtual paradigm
-//   - Improvement: horizontal scrolling via mouse wheel can be forced by holding the shift key
-//   - Improvement: new parameter for function TBaseVirtualTree.GetMaxColumnWidth added: UseSmartColumnWidth (to
-//                  avoid contradicting the virtual paradigm, i.e. leave nodes out of consideration which are not in
-//                  view)
-//   - Improvement: new parameters for TVTHeader.AutoFitColumns added: SmartAutoFitType, RangeStartCol and
-//                  RangeEndCol
-//   - Improvement: new parameters for events FOUnknownnAfterAutoFitColumns, FOnBeforeAutoFitColumns, FOnAfterGetMaxColumnWidth
-//                  and FOnBeforeGetMaxColumnWidth added
-//   - Version is now 4.6.0
-// May 2008
-//   - Improvement: new properties: FOnAfterAutoFitColumns, FOnBeforeAutoFitColumns, FOnAfterGetMaxColumnWidth and
-//                  FOnBeforeGetMaxColumnWidth
-//   - Bug fix: FDropTargetNode is considered in TBaseVirtualTree.DoFreeNode
-// August 2007
-//   - for accessibility, added an OnGetImageText event that can be used to give accessible text to images used in nodes.
-//   - Implemented an ImageText property used by the VTAccessibility unit to retrieve text for a given node and its column.
-//   - Switched loading of accessibility libraries to dynamic from static to avoid problems in Win95
-// June 2007
-//   - Bug fix: Fixed a problem with potentially large amount of nodes (larger than 2 billion) in
-//              TBaseVirtualTree.SetChildCount.
-//   - Bug fix: remove hint if any in case the tree loses the focus.
-//   - Improvement: TVirtualTreeColumns.HandleClick is now virtual, introduced TVTHeader.DoSetSortColumn.
-//   - Bug fix: compiler error due to old variable reference when enabling flat scrollbars.
-// May 2007
-//   - Improvement: new functions: GetPreviousSelected, GetPreviousChecked, GetCheckedCount,
-//     GetPreviousCutCopy, GetCutCopyCount, GetFirstLeaf, GetNextLeaf,
-//     GetPreviousLeaf, GetFirstLevel, GetNextLevel, GetPreviousLevel
-//   - Improvement: new properties: CheckedCount, CutCopyCount
-//   - Improvement: DoFocusChanging for finding a valid column (TBaseVirtualTree.WMKeyDown)
-// March 2007
-//   - Improvement: adjusted accessibility implementation to compile with pre-BDS IDEs.
-//   - If a column is not visible, MultiColumnAccessibility now will not include it.
-// January 2007
-//   - Improvement: added code donation from Marco Zehe (with help from Sebastian Modersohn) which implements the
-//                  MS accessibility interface for Virtual Treeview.
-// December 2006
-//   - Improvement: bidi mode implementation finished (toAutoBidiColumnOrdering introduced)
-//   - Change: right-to-left flag removed from shorten string methods/events (not necessary)
-//   - Version is now 4.5.0
-// November 2006
-//   - Bug fix: Total height is wrong on reading from stream
-// September 2006
-//   - Bug fix: Mantis issue #326
-// July 2006
-//  - Change: value for crHeaderSplit cursor conflicts with other resource IDs, so I changed it.
-//  - Published OnStartDrag in VirtualDrawTree.
-// April 2006
-//   - Bug fix: check for MMX availabiltiy is missing in some places before calling MMX code
-//   - Bug fix: flag for VCL dragging was removed too late causing all kind of problems with mouse up code in VCL drag mode.
-//   - Bug fix: If the past mode in ProcessOLEData is amInsertAfter then nodes where inserted in the wrong order.
-// March 2006
-//   - Bug fix: total count and total height is wrong after loading from stream
-//   - Bug fix: variable node height computation
-//   - Bug fix: FLastChangedNode was not reset in DoFreeNode
-// February 2006
-//   - Improvement: GetFirstChecked now also has a default value for its state parameter.
-//   - Improvement: avoid potential reentrancy problems in paint code by checking for the paint state there.
-// January 2006
-//   - Bug fix: disabled images are now drawn like enabled ones (with respect to position, indices etc.).
-//   - Improvement: New property BottomSpace, allows to specify an additional area below the last node in the tree.
-//   - Bug fix: VT.EndUpdate did not invalidate the cache so the cache was never used again after that.
-//   - Improvement: tree states for double clicks (left, middle, right).
-// December 2005
-//   - Bug fix: check for column index for auto setting main column if the current one is deleted.
-//
-// For full document history see help file.
-//
-// Credits for their valuable assistance and code donations go to:
-//   Freddy Ertl, Marian Aldenh?vel, Thomas Bogenrieder, Jim Kuenemann, Werner Lehmann, Jens Treichler,
-//   Paul Gallagher (IBO tree), Ondrej Kelle, Ronaldo Melo Ferraz, Heri Bender, Roland Bed?rftig (BCB)
-//   Anthony Mills, Alexander Egorushkin (BCB), Mathias Torell (BCB), Frank van den Bergh, Vadim Sedulin, Peter Evans,
-//   Milan Vandrovec (BCB), Steve Moss, Joe White, David Clark, Anders Thomsen, Igor Afanasyev, Eugene Programmer,
-//   Corbin Dunn, Richard Pringle, Uli Gerhardt, Azza, Igor Savkic, Daniel Bauten, Timo Tegtmeier, Dmitry Zegebart,
-//   Andreas Hausladen
-// Beta testers:
-//   Freddy Ertl, Hans-J?rgen Schnorrenberg, Werner Lehmann, Jim Kueneman, Vadim Sedulin, Moritz Franckenstein,
-//   Wim van der Vegt, Franc v/d Westelaken
-// Indirect contribution (via publicly accessible work of those persons):
-//   Alex Denissov, Hiroyuki Hori (MMXAsm expert)
-// Documentation:
-//   Markus Spoettl and toolsfactory GbR (http://www.doc-o-matic.com/, sponsoring Soft Gems development
-//   with a free copy of the Doc-O-Matic help authoring system), Sven H. (Step by step tutorial)
-// CLX:
-//   Dmitri Dmitrienko (initial developer)
-// Source repository:
-//   Subversion (server), TortoiseSVN (client tools), Fisheye (Web interface)
-// Accessability implementation:
-//   Marco Zehe (with help from Sebastian Modersohn)
-// LCL Port:
-//   Luiz Am?rico Pereira C?mara
-//----------------------------------------------------------------------------------------------------------------------
-
-interface
-
-{$I VTConfig.inc}
-
-uses
-  {$ifdef Windows}
-  Windows,
-  ActiveX,
-  CommCtrl,
-  {$else}
-  FakeActiveX,
-  {$endif}
-  OleUtils,
-  LCLIntf,
-  {$ifdef USE_DELPHICOMPAT}
-  DelphiCompat,
-  LclExt,
-  {$endif}
-  virtualpanningwindow,
-  VTGraphics, //alpha blend functions
-  {$ifdef DEBUG_VTV}
-  vtlogger,
-  {$endif}
-  LCLType, LResources, LMessages, Types,
-  SysUtils, Classes, Graphics, Controls, Forms, ImgList, StdCtrls, Menus, Printers,
-  SyncObjs,  // Thread support
-  Clipbrd // Clipboard support
-  {$ifdef ThemeSupport}
-  , Themes , TmSchema
-  {$endif ThemeSupport}
-  {$ifdef EnableAccessible}
-  , oleacc // for MSAA IAccessible support
-  {$endif};
-
-const
-  {$I lclconstants.inc}
-
-  {$if defined(LCLGtk) or defined(LCLGtk2)}
-    {$define Gtk}
-  {$endif}
-
-  {$if defined(Gtk)}
-    {$define ManualClipNeeded}
-  {$endif}
-
-  {$if defined(LCLGtk2) or defined(LCLCarbon) or defined(LCLQt)}
-    {$define ContextMenuBeforeMouseUp}
-  {$endif}
-
-  VTMajorVersion = 4;
-  VTMinorVersion = 8;
-  VTReleaseVersion = 7;
-  VTTreeStreamVersion = 2;
-  VTHeaderStreamVersion = 6;    // The header needs an own stream version to indicate changes only relevant to the header.
-
-  CacheThreshold = 2000;        // Number of nodes a tree must at least have to start caching and at the same
-                                // time the maximum number of nodes between two cache entries.
-  FadeAnimationStepCount = 255; // Number of animation steps for hint fading (0..255).
-  ShadowSize = 5;               // Size in pixels of the hint shadow. This value has no influence on Win2K and XP systems
-                                // as those OSes have native shadow support.
-
-  // Special identifiers for columns.
-  NoColumn = -1;
-  InvalidColumn = -2;
-
-  // Indices for check state images used for checking.
-  ckEmpty                  =  0;  // an empty image used as place holder
-  // radio buttons
-  ckRadioUncheckedNormal   =  1;
-  ckRadioUncheckedHot      =  2;
-  ckRadioUncheckedPressed  =  3;
-  ckRadioUncheckedDisabled =  4;
-  ckRadioCheckedNormal     =  5;
-  ckRadioCheckedHot        =  6;
-  ckRadioCheckedPressed    =  7;
-  ckRadioCheckedDisabled   =  8;
-  // check boxes
-  ckCheckUncheckedNormal   =  9;
-  ckCheckUncheckedHot      = 10;
-  ckCheckUncheckedPressed  = 11;
-  ckCheckUncheckedDisabled = 12;
-  ckCheckCheckedNormal     = 13;
-  ckCheckCheckedHot        = 14;
-  ckCheckCheckedPressed    = 15;
-  ckCheckCheckedDisabled   = 16;
-  ckCheckMixedNormal       = 17;
-  ckCheckMixedHot          = 18;
-  ckCheckMixedPressed      = 19;
-  ckCheckMixedDisabled     = 20;
-  // simple button
-  ckButtonNormal           = 21;
-  ckButtonHot              = 22;
-  ckButtonPressed          = 23;
-  ckButtonDisabled         = 24;
-
-  // Instead using a TTimer class for each of the various events I use Windows timers with messages
-  // as this is more economical.
-  ExpandTimer = 1;
-  EditTimer = 2;
-  ScrollTimer = 4;
-  ChangeTimer = 5;
-  StructureChangeTimer = 6;
-  SearchTimer = 7;
-
-  // Need to use this message to release the edit link interface asynchronously.
-  WM_CHANGESTATE = WM_APP + 32;
-
-  // Virtual Treeview does not need to be subclassed by an eventual Theme Manager instance as it handles
-  // Windows XP theme painting itself. Hence the special message is used to prevent subclassing.
-  CM_DENYSUBCLASSING = CM_BASE + 2000;
-
-  // Decoupling message for auto-adjusting the internal edit window.
-  CM_AUTOADJUST = CM_BASE + 2005;
-
-  // VT's own clipboard formats,
-  // Note: The reference format is used internally to allow to link to a tree reference
-  //       to implement optimized moves and other back references.
-  CFSTR_VIRTUALTREE = 'Virtual Tree Data';
-  CFSTR_VTREFERENCE = 'Virtual Tree Reference';
-  CFSTR_HTML = 'HTML Format';
-  CFSTR_RTF = 'Rich Text Format';
-  CFSTR_RTFNOOBJS = 'Rich Text Format Without Objects';
-  CFSTR_CSV = 'CSV';
-
-  // Drag image helpers for Windows 2000 and up.
-  IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
-  CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-
-  SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}';
-  SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}';
-  SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}';
-
-  // Help identifiers for exceptions. Application developers are responsible to link them with actual help topics.
-  hcTFEditLinkIsNil      = 2000;
-  hcTFWrongMoveError     = 2001;
-  hcTFWrongStreamFormat  = 2002;
-  hcTFWrongStreamVersion = 2003;
-  hcTFStreamTooSmall     = 2004;
-  hcTFCorruptStream1     = 2005;
-  hcTFCorruptStream2     = 2006;
-  hcTFClipboardFailed    = 2007;
-  hcTFCannotSetUserData  = 2008;
-
-  // Header standard split cursor.
-  crHeaderSplit = TCursor(63);
-
-  // Height changing cursor.
-  crVertSplit = TCursor(62);
-  //Panning Cursors
-  crVT_MOVEALL = TCursor(64);
-  crVT_MOVEEW = TCursor(65);
-  crVT_MOVENS = TCursor(66);
-  crVT_MOVENW = TCursor(67);
-  crVT_MOVESW = TCursor(68);
-  crVT_MOVENE = TCursor(69);
-  crVT_MOVESE = TCursor(70);
-  crVT_MOVEW = TCursor(71);
-  crVT_MOVEE = TCursor(72);
-  crVT_MOVEN = TCursor(73);
-  crVT_MOVES = TCursor(74);
-
-  UtilityImageSize = 16; // Needed by descendants for hittests.
-
-  {$if defined(LCLCarbon) or defined(LCLCocoa)}
-    ssCtrlOS = ssMeta;     // Mac OS X fix
-  {$else}
-    ssCtrlOS = ssCtrl;
-  {$endif}
-
-var // Clipboard format IDs used in OLE drag'n drop and clipboard transfers.
-  CF_VIRTUALTREE,
-  CF_VTREFERENCE,
-  CF_VRTF,
-  CF_VRTFNOOBJS,   // Unfortunately CF_RTF* is already defined as being
-                   // registration strings so I have to use different identifiers.
-  CF_HTML,
-  CF_CSV: Word;
-
-  MMXAvailable: Boolean; // necessary to know because the blend code uses MMX instructions
-
-  IsWinNT: Boolean;      // Necessary to fix bugs in Win95/WinME (non-client area region intersection, edit resize)
-                         // and to allow for check of system dependent hint animation.
-  IsWinVistaOrAbove: Boolean;
-
-type
-  // The exception used by the trees.
-  EVirtualTreeError = class(Exception);
-
-  // Limits the speed interval which can be used for auto scrolling (milliseconds).
-  TAutoScrollInterval = 1..1000;
-
-  // Need to declare the correct WMNCPaint record as the VCL (D5-) doesn't.
-  TRealWMNCPaint = packed record
-    Msg: Cardinal;
-    Rgn: HRGN;
-    lParam: Integer;
-    Result: Integer;
-  end;
-
-  // Be careful when adding new states as this might change the size of the type which in turn
-  // changes the alignment in the node record as well as the stream chunks.
-  // Do not reorder the states and always add new states at the end of this enumeration in order to avoid
-  // breaking existing code.
-  TVirtualNodeState = (
-    vsInitialized,       // Set after the node has been initialized.
-    vsChecking,          // Node's check state is changing, avoid propagation.
-    vsCutOrCopy,         // Node is selected as cut or copy and paste source.
-    vsDisabled,          // Set if node is disabled.
-    vsDeleting,          // Set when the node is about to be freed.
-    vsExpanded,          // Set if the node is expanded.
-    vsHasChildren,       // Indicates the presence of child nodes without actually setting them.
-    vsVisible,           // Indicate whether the node is visible or not (independent of the expand states of its parents).
-    vsSelected,          // Set if the node is in the current selection.
-    vsInitialUserData,   // Set if (via AddChild or InsertNode) initial user data has been set which requires OnFreeNode.
-    vsAllChildrenHidden, // Set if vsHasChildren is set and no child node has the vsVisible flag set.
-    vsClearing,          // A node's children are being deleted. Don't register structure change event.
-    vsMultiline,         // Node text is wrapped at the cell boundaries instead of being shorted.
-    vsHeightMeasured,    // Node height has been determined and does not need a recalculation.
-    vsToggling           // Set when a node is expanded/collapsed to prevent recursive calls.
-  );
-  TVirtualNodeStates = set of TVirtualNodeState;
-
-  // States used in InitNode to indicate states a node shall initially have.
-  TVirtualNodeInitState = (
-    ivsDisabled,
-    ivsExpanded,
-    ivsHasChildren,
-    ivsMultiline,
-    ivsSelected
-  );
-  TVirtualNodeInitStates = set of TVirtualNodeInitState;
-
-  TVTScrollBarStyle = (
-    sbmRegular,
-    sbmFlat,
-    sbm3D
-  );
-
-  // Options per column.
-  TVTColumnOption = (
-    coAllowClick,            // Column can be clicked (must be enabled too).
-    coDraggable,             // Column can be dragged.
-    coEnabled,               // Column is enabled.
-    coParentBidiMode,        // Column uses the parent's bidi mode.
-    coParentColor,           // Column uses the parent's background color.
-    coResizable,             // Column can be resized.
-    coShowDropMark,          // Column shows the drop mark if it is currently the drop target.
-    coVisible,               // Column is shown.
-    coAutoSpring,            // Column takes part in the auto spring feature of the header (must be resizable too).
-    coFixed,                 // Column is fixed and can not be selected or scrolled etc.
-    coSmartResize,           // Column is resized to its largest entry which is in view (instead of its largest
-                             // visible entry).
-    coAllowFocus,            // Column can be focused.
-    coDisableAnimatedResize, // Column resizing is not animated.
-    coWrapCaption,           // Caption could be wrapped across several header lines to fit columns width.
-    coUseCaptionAlignment    // Column's caption has its own aligment.
-  );
-  TVTColumnOptions = set of TVTColumnOption;
-
-  // These flags are used to indicate where a click in the header happened.
-  TVTHeaderHitPosition = (
-    hhiNoWhere,         // No column is involved (possible only if the tree is smaller than the client area).
-    hhiOnColumn,        // On a column.
-    hhiOnIcon,          // On the bitmap associated with a column.
-    hhiOnCheckbox       // On the checkbox if enabled.
-  );
-  TVTHeaderHitPositions = set of TVTHeaderHitPosition;
-
-  // These flags are returned by the hit test method.
-  THitPosition = (
-    hiAbove,             // above the client area (if relative) or the absolute tree area
-    hiBelow,             // below the client area (if relative) or the absolute tree area
-    hiNowhere,           // no node is involved (possible only if the tree is not as tall as the client area)
-    hiOnItem,            // on the bitmaps/buttons or label associated with an item
-    hiOnItemButton,      // on the button associated with an item
-    hiOnItemButtonExact, // exactly on the button associated with an item
-    hiOnItemCheckbox,    // on the checkbox if enabled
-    hiOnItemIndent,      // in the indentation area in front of a node
-    hiOnItemLabel,       // on the normal text area associated with an item
-    hiOnItemLeft,        // in the area to the left of a node's text area (e.g. when right aligned or centered)
-    hiOnItemRight,       // in the area to the right of a node's text area (e.g. if left aligned or centered)
-    hiOnNormalIcon,      // on the "normal" image
-    hiOnStateIcon,       // on the state image
-    hiToLeft,            // to the left of the client area (if relative) or the absolute tree area
-    hiToRight,           // to the right of the client area (if relative) or the absolute tree area
-    hiUpperSplitter,     // in the upper splitter area of a node
-    hiLowerSplitter      // in the lower splitter area of a node
-  );
-  THitPositions = set of THitPosition;
-
-  TCheckType = (
-    ctNone,
-    ctTriStateCheckBox,
-    ctCheckBox,
-    ctRadioButton,
-    ctButton
-  );
-
-  // The check states include both, transient and fluent (temporary) states. The only temporary state defined so
-  // far is the pressed state.
-  TCheckState = (
-    csUncheckedNormal,  // unchecked and not pressed
-    csUncheckedPressed, // unchecked and pressed
-    csCheckedNormal,    // checked and not pressed
-    csCheckedPressed,   // checked and pressed
-    csMixedNormal,      // 3-state check box and not pressed
-    csMixedPressed      // 3-state check box and pressed
-  );
-
-  TCheckImageKind = (
-    ckLightCheck,     // gray cross
-    ckDarkCheck,      // black cross
-    ckLightTick,      // gray tick mark
-    ckDarkTick,       // black tick mark
-    ckFlat,           // flat images (no 3D border)
-    ckXP,             // Windows XP style
-    ckCustom,         // application defined check images
-    ckSystemFlat,     // Flat system defined check images.
-    ckSystemDefault   // Uses the system check images, theme aware.
-  );
-
-  // mode to describe a move action
-  TVTNodeAttachMode = (
-    amNoWhere,        // just for simplified tests, means to ignore the Add/Insert command
-    amInsertBefore,   // insert node just before destination (as sibling of destination)
-    amInsertAfter,    // insert node just after destionation (as sibling of destination)
-    amAddChildFirst,  // add node as first child of destination
-    amAddChildLast    // add node as last child of destination
-  );
-
-  // modes to determine drop position further
-  TDropMode = (
-    dmNowhere,
-    dmAbove,
-    dmOnNode,
-    dmBelow
-  );
-
-  // operations basically allowed during drag'n drop
-  TDragOperation = (
-    doCopy,
-    doMove,
-    doLink
-  );
-  TDragOperations = set of TDragOperation;
-
-  TVTImageKind = (
-    ikNormal,
-    ikSelected,
-    ikState,
-    ikOverlay
-  );
-
-  TVTHintMode = (
-    hmDefault,            // show the hint of the control
-    hmHint,               // show node specific hint string returned by the application
-    hmHintAndDefault,     // same as hmHint but show the control's hint if no node is concerned
-    hmTooltip             // show the text of the node if it isn't already fully shown
-  );
-
-  // Indicates how to format a tooltip.
-  TVTTooltipLineBreakStyle = (
-    hlbDefault,           // Use multi-line style of the node.
-    hlbForceSingleLine,   // Use single line hint.
-    hlbForceMultiLine     // Use multi line hint.
-  );
-
-  TMouseButtons = set of TMouseButton;
-
-  // Used to describe the action to do when using the OnBeforeItemErase event.
-  TItemEraseAction = (
-    eaColor,   // Use the provided color to erase the background instead the one of the tree.
-    eaDefault, // The tree should erase the item's background (bitmap or solid).
-    eaNone     // Do nothing. Let the application paint the background.
-  );
-
-
-  // There is a heap of switchable behavior in the tree. Since published properties may never exceed 4 bytes,
-  // which limits sets to at most 32 members, and because for better overview tree options are splitted
-  // in various sub-options and are held in a commom options class.
-  //
-  // Options to customize tree appearance:
-  TVTPaintOption = (
-    toHideFocusRect,           // Avoid drawing the dotted rectangle around the currently focused node.
-    toHideSelection,           // Selected nodes are drawn as unselected nodes if the tree is unfocused.
-    toHotTrack,                // Track which node is under the mouse cursor.
-    toPopupMode,               // Paint tree as would it always have the focus (useful for tree combo boxes etc.)
-    toShowBackground,          // Use the background image if there's one.
-    toShowButtons,             // Display collapse/expand buttons left to a node.
-    toShowDropmark,            // Show the dropmark during drag'n drop operations.
-    toShowHorzGridLines,       // Display horizontal lines to simulate a grid.
-    toShowRoot,                // Show lines also at top level (does not show the hidden/internal root node).
-    toShowTreeLines,           // Display tree lines to show hierarchy of nodes.
-    toShowVertGridLines,       // Display vertical lines (depending on columns) to simulate a grid.
-    toThemeAware,              // Draw UI elements (header, tree buttons etc.) according to the current theme if
-                               // enabled (Windows XP+ only, application must be themed).
-    toUseBlendedImages,        // Enable alpha blending for ghosted nodes or those which are being cut/copied.
-    toGhostedIfUnfocused,      // Ghosted images are still shown as ghosted if unfocused (otherwise the become non-ghosted
-                               // images).
-    toFullVertGridLines,       // Display vertical lines over the full client area, not only the space occupied by nodes.
-                               // This option only has an effect if toShowVertGridLines is enabled too.
-    toAlwaysHideSelection,     // Do not draw node selection, regardless of focused state.
-    toUseBlendedSelection,     // Enable alpha blending for node selections.
-    toStaticBackground,        // Show simple static background instead of a tiled one.
-    toChildrenAbove,           // Display child nodes above their parent.
-    toFixedIndent,             // Draw the tree with a fixed indent.
-    toUseExplorerTheme         // Use the explorer theme if run under Windows Vista (or above).
-  );
-  TVTPaintOptions = set of TVTPaintOption;
-
-  // Options to toggle animation support:
-  TVTAnimationOption = (
-    toAnimatedToggle,          // Expanding and collapsing a node is animated (quick window scroll).
-    toAdvancedAnimatedToggle   // Do some advanced animation effects when toggling a node.
-  );
-  TVTAnimationOptions = set of TVTAnimationOption;
-
-  // Options which toggle automatic handling of certain situations:
-  TVTAutoOption = (
-    toAutoDropExpand,           // Expand node if it is the drop target for more than a certain time.
-    toAutoExpand,               // Nodes are expanded (collapsed) when getting (losing) the focus.
-    toAutoScroll,               // Scroll if mouse is near the border while dragging or selecting.
-    toAutoScrollOnExpand,       // Scroll as many child nodes in view as possible after expanding a node.
-    toAutoSort,                 // Sort tree when Header.SortColumn or Header.SortDirection change or sort node if
-                                // child nodes are added.
-    toAutoSpanColumns,          // Large entries continue into next column(s) if there's no text in them (no clipping).
-    toAutoTristateTracking,     // Checkstates are automatically propagated for tri state check boxes.
-    toAutoHideButtons,          // Node buttons are hidden when there are child nodes, but all are invisible.
-    toAutoDeleteMovedNodes,     // Delete nodes which where moved in a drag operation (if not directed otherwise).
-    toDisableAutoscrollOnFocus, // Disable scrolling a node or column into view if it gets focused.
-    toDisableAutoscrollHorizontal, // Only autoscroll on focus vertically never horizontally
-    toAutoChangeScale,          // Change default node height automatically if the system's font scale is set to big fonts.
-    toAutoFreeOnCollapse,       // Frees any child node after a node has been collapsed (HasChildren flag stays there).
-    toDisableAutoscrollOnEdit,  // Do not center a node horizontally when it is edited.
-    toAutoBidiColumnOrdering    // When set then columns (if any exist) will be reordered from lowest index to highest index
-                                // and vice versa when the tree's bidi mode is changed.
-  );
-  TVTAutoOptions = set of TVTAutoOption;
-
-  // Options which determine the tree's behavior when selecting nodes:
-  TVTSelectionOption = (
-    toDisableDrawSelection,    // Prevent user from selecting with the selection rectangle in multiselect mode.
-    toExtendedFocus,           // Entries other than in the main column can be selected, edited etc.
-    toFullRowSelect,           // Hit test as well as selection highlight are not constrained to the text of a node.
-    toLevelSelectConstraint,   // Constrain selection to the same level as the selection anchor.
-    toMiddleClickSelect,       // Allow selection, dragging etc. with the middle mouse button. This and toWheelPanning
-                               // are mutual exclusive.
-    toMultiSelect,             // Allow more than one node to be selected.
-    toRightClickSelect,        // Allow selection, dragging etc. with the right mouse button.
-    toSiblingSelectConstraint, // Constrain selection to nodes with same parent.
-    toCenterScrollIntoView,    // Center nodes vertically in the client area when scrolling into view.
-    toSimpleDrawSelection      // Simplifies draw selection, so a node's caption does not need to intersect with the
-                               // selection rectangle.
-  );
-  TVTSelectionOptions = set of TVTSelectionOption;
-
-  // Options which do not fit into any of the other groups:
-  TVTMiscOption = (
-    toAcceptOLEDrop,            // Register tree as OLE accepting drop target
-    toCheckSupport,             // Show checkboxes/radio buttons.
-    toEditable,                 // Node captions can be edited.
-    toFullRepaintOnResize,      // Fully invalidate the tree when its window is resized (CS_HREDRAW/CS_VREDRAW).
-    toGridExtensions,           // Use some special enhancements to simulate and support grid behavior.
-    toInitOnSave,               // Initialize nodes when saving a tree to a stream.
-    toReportMode,               // Tree behaves like TListView in report mode.
-    toToggleOnDblClick,         // Toggle node expansion state when it is double clicked.
-    toWheelPanning,             // Support for mouse panning (wheel mice only). This option and toMiddleClickSelect are
-                                // mutal exclusive, where panning has precedence.
-    toReadOnly,                 // The tree does not allow to be modified in any way. No action is executed and
-                                // node editing is not possible.
-    toVariableNodeHeight,       // When set then GetNodeHeight will trigger OnMeasureItem to allow variable node heights.
-    toFullRowDrag,              // Start node dragging by clicking anywhere in it instead only on the caption or image.
-                                // Must be used together with toDisableDrawSelection.
-    toNodeHeightResize,         // Allows changing a node's height via mouse.
-    toNodeHeightDblClickResize, // Allows to reset a node's height to FDefaultNodeHeight via a double click.
-    toEditOnClick,              // Editing mode can be entered with a single click
-    toEditOnDblClick            // Editing mode can be entered with a double click
-  );
-  TVTMiscOptions = set of TVTMiscOption;
-
-  // Options to control data export
-  TVTExportMode = (
-    emAll,        // export all records (regardless checked state)
-    emChecked,    // export checked records only
-    emUnchecked   // export unchecked records only
-  );
-
-const
-  DefaultPaintOptions = [toShowButtons, toShowDropmark, toShowTreeLines, toShowRoot, toThemeAware, toUseBlendedImages];
-  DefaultAnimationOptions = [];
-  DefaultAutoOptions = [toAutoDropExpand, toAutoTristateTracking, toAutoScrollOnExpand, toAutoDeleteMovedNodes];
-  DefaultSelectionOptions = [];
-  DefaultMiscOptions = [toAcceptOLEDrop, toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning,
-    toEditOnClick];
-  DefaultColumnOptions = [coAllowClick, coDraggable, coEnabled, coParentColor, coParentBidiMode, coResizable,
-    coShowDropmark, coVisible, coAllowFocus];
-
-type
-  TBaseVirtualTree = class;
-  TVirtualTreeClass = class of TBaseVirtualTree;
-
-  PVirtualNode = ^TVirtualNode;
-
-  TColumnIndex = type Integer;
-  TColumnPosition = type Cardinal;
-
-  // This record must already be defined here and not later because otherwise BCB users will not be able
-  // to compile (conversion done by BCB is wrong).
-  TCacheEntry = record
-    Node: PVirtualNode;
-    AbsoluteTop: Cardinal;
-  end;
-
-  TCache = array of TCacheEntry;
-  TNodeArray = array of PVirtualNode;
-
-  TCustomVirtualTreeOptions = class(TPersistent)
-  private
-    FOwner: TBaseVirtualTree;
-    FPaintOptions: TVTPaintOptions;
-    FAnimationOptions: TVTAnimationOptions;
-    FAutoOptions: TVTAutoOptions;
-    FSelectionOptions: TVTSelectionOptions;
-    FMiscOptions: TVTMiscOptions;
-    FExportMode: TVTExportMode;
-    procedure SetAnimationOptions(const Value: TVTAnimationOptions);
-    procedure SetAutoOptions(const Value: TVTAutoOptions);
-    procedure SetMiscOptions(const Value: TVTMiscOptions);
-    procedure SetPaintOptions(const Value: TVTPaintOptions);
-    procedure SetSelectionOptions(const Value: TVTSelectionOptions);
-  protected
-    property AnimationOptions: TVTAnimationOptions read FAnimationOptions write SetAnimationOptions
-      default DefaultAnimationOptions;
-    property AutoOptions: TVTAutoOptions read FAutoOptions write SetAutoOptions default DefaultAutoOptions;
-    property ExportMode: TVTExportMode read FExportMode write FExportMode default emAll;
-    property MiscOptions: TVTMiscOptions read FMiscOptions write SetMiscOptions default DefaultMiscOptions;
-    property PaintOptions: TVTPaintOptions read FPaintOptions write SetPaintOptions default DefaultPaintOptions;
-    property SelectionOptions: TVTSelectionOptions read FSelectionOptions write SetSelectionOptions
-      default DefaultSelectionOptions;
-  public
-    constructor Create(AOwner: TBaseVirtualTree); virtual;
-
-    procedure AssignTo(Dest: TPersistent); override;
-
-    property Owner: TBaseVirtualTree read FOwner;
-  end;
-
-  TTreeOptionsClass = class of TCustomVirtualTreeOptions;
-
-  TVirtualTreeOptions = class(TCustomVirtualTreeOptions)
-  published
-    property AnimationOptions;
-    property AutoOptions;
-    property ExportMode;
-    property MiscOptions;
-    property PaintOptions;
-    property SelectionOptions;
-  end;
-
-  // Used in the CF_VTREFERENCE clipboard format.
-  PVTReference = ^TVTReference;
-  TVTReference = record
-    Process: Cardinal;
-    Tree: TBaseVirtualTree;
-  end;
-
-  TVirtualNode = record
-    Index,                   // index of node with regard to its parent
-    ChildCount: Cardinal;    // number of child nodes
-    NodeHeight: Word;        // 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.)
-    CheckType: TCheckType;   // indicates which check type shall be used for this node
-    Dummy: Byte;             // dummy value to fill DWORD boundary
-    TotalCount,              // sum of this node, all of its child nodes and their child nodes etc.
-    TotalHeight: Cardinal;   // height in pixels this node covers on screen including the height of all of its
-                             // children
-    // Note: Some copy routines require that all pointers (as well as the data area) in a node are
-    //       located at the end of the node! Hence if you want to add new member fields (except pointers to internal
-    //       data) then put them before field Parent.
-    Parent,                  // reference to the node's parent (for the root this contains the treeview)
-    PrevSibling,             // link to the node's previous sibling or nil if it is the first node
-    NextSibling,             // link to the node's next sibling or nil if it is the last node
-    FirstChild,              // link to the node's first child...
-    LastChild: PVirtualNode; // link to the node's last child...
-    Data: record end;        // this is a placeholder, each node gets extra data determined by NodeDataSize
-  end;
-
-  // Structure used when info about a certain position in the tree is needed.
-  THitInfo = record
-    HitNode: PVirtualNode;
-    HitPositions: THitPositions;
-    HitColumn: TColumnIndex;
-  end;
-
-  // auto scroll directions
-  TScrollDirections = set of (
-    sdLeft,
-    sdUp,
-    sdRight,
-    sdDown
-  );
-
-  // OLE drag'n drop support
-  TFormatEtcArray = array of TFormatEtc;
-  TFormatArray = array of Word;
-
-  // IDataObject.SetData support
-  TInternalStgMedium = packed record
-    Format: TClipFormat;
-    Medium: TStgMedium;
-  end;
-  TInternalStgMediumArray = array of TInternalStgMedium;
-
-  TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc)
-  private
-    FTree: TBaseVirtualTree;
-    FFormatEtcArray: TFormatEtcArray;
-    FCurrentIndex: Integer;
-  public
-    constructor Create(Tree: TBaseVirtualTree; AFormatEtcArray: TFormatEtcArray);
-
-    function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
-    function Next(celt: LongWord; out elt: FormatEtc;pceltFetched:pULong=nil): HResult; stdcall;
-    function Reset: HResult; stdcall;
-    function Skip(celt: LongWord): HResult; stdcall;
-  end;
-
-  // ----- OLE drag'n drop handling
-
-  IDropTargetHelper = interface(IUnknown)
-    [SID_IDropTargetHelper]
-    function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function DragLeave: HRESULT; stdcall;
-    function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Show(fShow: Boolean): HRESULT; stdcall;
-  end;
-
-  PSHDragImage = ^TSHDragImage;
-  TSHDragImage = packed record
-    sizeDragImage: TSize;
-    ptOffset: TPoint;
-    hbmpDragImage: HBITMAP;
-    ColorRef: TColorRef;
-  end;
-
-  IDragSourceHelper = interface(IUnknown)
-    [SID_IDragSourceHelper]
-    function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall;
-    function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall;
-  end;
-
-  IVTDragManager = interface(IUnknown)
-    ['{C4B25559-14DA-446B-8901-0C879000EB16}']
-    procedure ForceDragLeave; stdcall;
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TBaseVirtualTree; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-
-    property DataObject: IDataObject read GetDataObject;
-    property DragSource: TBaseVirtualTree read GetDragSource;
-    property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported;
-    property IsDropTarget: Boolean read GetIsDropTarget;
-  end;
-
-  // This data object is used in two different places. One is for clipboard operations and the other while dragging.
-  TVTDataObject = class(TInterfacedObject, IDataObject)
-  private
-    FOwner: TBaseVirtualTree;          // The tree which provides clipboard or drag data.
-    FForClipboard: Boolean;            // Determines which data to render with GetData.
-    FFormatEtcArray: TFormatEtcArray;
-    FInternalStgMediumArray: TInternalStgMediumArray;  // The available formats in the DataObject
-    FAdviseHolder: IDataAdviseHolder;  // Reference to an OLE supplied implementation for advising.
-  protected
-    function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-    function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-    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;
-    function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-      CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-    property ForClipboard: Boolean read FForClipboard;
-    property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray;
-    property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray;
-    property Owner: TBaseVirtualTree read FOwner;
-  public
-    constructor Create(AOwner: TBaseVirtualTree; ForClipboard: Boolean); virtual;
-    destructor Destroy; override;
-
-    function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord):
-      HResult; virtual; stdcall;
-    function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall;
-    Function EnumDAdvise(out enumAdvise : IEnumStatData):HResult;virtual;StdCall;
-    function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall;
-    function GetCanonicalFormatEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):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;
-    function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall;
-    function SetData(const FormatEtc: TFormatEtc; const Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall;
-  end;
-
-  // TVTDragManager is a class to manage drag and drop in a Virtual Treeview.
-  TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget)
-  private
-    FOwner,                            // The tree which is responsible for drag management.
-    FDragSource: TBaseVirtualTree;     // Reference to the source tree if the source was a VT, might be different than
-                                       // the owner tree.
-    FIsDropTarget: Boolean;            // True if the owner is currently the drop target.
-    FDataObject: IDataObject;          // A reference to the data object passed in by DragEnter (only used when the owner
-                                       // tree is the current drop target).
-    FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support
-    FFullDragging: BOOL;               // True, if full dragging is currently enabled in the system.
-
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TBaseVirtualTree; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-  public
-    constructor Create(AOwner: TBaseVirtualTree); virtual;
-    destructor Destroy; override;
-
-    function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-      var Effect: LongWord): HResult; stdcall;
-    function DragLeave: HResult; stdcall;
-    function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    procedure ForceDragLeave; stdcall;
-    {$IF (FPC_FULLVERSION < 020601) and DEFINED(LCLWin32)}
-    function GiveFeedback(Effect: Longint): HResult; stdcall;
-    function QueryContinueDrag(EscapePressed: BOOL; KeyState: Longint): HResult; stdcall;
-    {$ELSE}
-    function GiveFeedback(Effect: LongWord): HResult; stdcall;
-    function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall;
-    {$ENDIF}
-  end;
-
-  PVTHintData = ^TVTHintData;
-  TVTHintData = record
-    Tree: TBaseVirtualTree;
-    Node: PVirtualNode;
-    Column: TColumnIndex;
-    HintRect: TRect;            // used for draw trees only, string trees get the size from the hint string
-    DefaultHint: String;    // used only if there is no node specific hint string available
-                                // or a header hint is about to appear
-    HintText: String;       // set when size of the hint window is calculated
-    HintInfo: PHintInfo;
-  end;
-
-  // The trees need an own hint window class because of Unicode output and adjusted font.
-
-  { TVirtualTreeHintWindow }
-
-  TVirtualTreeHintWindow = class(THintWindow)
-  private
-    FHintData: TVTHintData;
-    procedure WMShowWindow(var Message: TLMShowWindow); message LM_SHOWWINDOW;
-  public
-    function CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect; override;
-    procedure Paint; override;
-  end;
-
-  // Drag image support for the tree.
-  TVTTransparency = 0..255;
-  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).
-    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.
-  );
-
-  // Class to manage header and tree drag image during a drag'n drop operation.
-  TVTDragImage = class
-  private
-    FOwner: TBaseVirtualTree;
-    FBackImage,                        // backup of overwritten screen area
-    FAlphaImage,                       // target for alpha blending
-    FDragImage: TBitmap;               // the actual drag image to blend to screen
-    FImagePosition,                    // position of image (upper left corner) in screen coordinates
-    FLastPosition: TPoint;             // last mouse position in screen coordinates
-    FTransparency: TVTTransparency;    // alpha value of the drag image (0 - fully transparent, 255 - fully opaque)
-    FPreBlendBias,                     // value to darken or lighten the drag image before it is blended
-    FPostBlendBias: TVTBias;           // value to darken or lighten the alpha blend result
-    FFade: Boolean;                    // determines whether to fade the drag image from center to borders or not
-    FRestriction: TVTDragMoveRestriction;  // determines in which directions the drag image can be moved
-    FColorKey: TColor;                 // color to make fully transparent regardless of any other setting
-    FStates: TVTDragImageStates;       // Determines the states of the drag image class.
-    function GetVisible: Boolean;      // True if the drag image is currently hidden (used only when dragging)
-  protected
-    procedure InternalShowDragImage(ScreenDC: HDC);
-    procedure MakeAlphaChannel(Source, Target: TBitmap);
-  public
-    constructor Create(AOwner: TBaseVirtualTree);
-    destructor Destroy; override;
-
-    function DragTo(const P: TPoint; ForceRepaint: Boolean): Boolean;
-    procedure EndDrag;
-    function GetDragImageRect: TRect;
-    procedure HideDragImage;
-    procedure PrepareDrag(DragImage: TBitmap; const ImagePosition, HotSpot: TPoint; const DataObject: IDataObject);
-    procedure RecaptureBackground(Tree: TBaseVirtualTree; R: TRect; VisibleRegion: HRGN; CaptureNCArea,
-      ReshowDragImage: Boolean);
-    procedure ShowDragImage;
-    function WillMove(const P: TPoint): Boolean;
-
-    property ColorKey: TColor read FColorKey write FColorKey default clWindow;
-    property Fade: Boolean read FFade write FFade default False;
-    property MoveRestriction: TVTDragMoveRestriction read FRestriction write FRestriction default dmrNone;
-    property PostBlendBias: TVTBias read FPostBlendBias write FPostBlendBias default 0;
-    property PreBlendBias: TVTBias read FPreBlendBias write FPreBlendBias default 0;
-    property Transparency: TVTTransparency read FTransparency write FTransparency default 128;
-    property Visible: Boolean read GetVisible;
-  end;
-
-  // tree columns implementation
-  TVirtualTreeColumns = class;
-  TVTHeader = class;
-
-  TVirtualTreeColumnStyle = (
-    vsText,
-    vsOwnerDraw
-  );
-
-
-  TVTHeaderColumnLayout = (
-    blGlyphLeft,
-    blGlyphRight,
-    blGlyphTop,
-    blGlyphBottom
-  );
-
-  TVirtualTreeColumn = class(TCollectionItem)
-  private
-    FText,
-    FHint: String;
-    FLeft,
-    FWidth: Integer;
-    FPosition: TColumnPosition;
-    FMinWidth: Integer;
-    FMaxWidth: Integer;
-    FStyle: TVirtualTreeColumnStyle;
-    FImageIndex: TImageIndex;
-    FBiDiMode: TBiDiMode;
-    FLayout: TVTHeaderColumnLayout;
-    FMargin,
-    FSpacing: Integer;
-    FOptions: TVTColumnOptions;
-    FTag: Integer;
-    FAlignment: TAlignment;
-    FCaptionAlignment: TAlignment;     // Alignment of the caption.
-    FLastWidth: Integer;
-    FColor: TColor;
-    FBonusPixel: Boolean;
-    FSpringRest: Single;               // Accumulator for width adjustment when auto spring option is enabled.
-    FCaptionText: String;
-    FCheckBox: Boolean;
-    FCheckType: TCheckType;
-    FCheckState: TCheckState;
-    FImageRect: TRect;
-    FHasImage: Boolean;
-    function GetCaptionAlignment: TAlignment;
-    function GetLeft: Integer;
-    function IsBiDiModeStored: Boolean;
-    function IsCaptionAlignmentStored: Boolean;
-    function IsColorStored: Boolean;
-    procedure SetAlignment(const Value: TAlignment);
-    procedure SetBiDiMode(Value: TBiDiMode);
-    procedure SetCaptionAlignment(const Value: TAlignment);
-    procedure SetCheckBox(Value: Boolean);
-    procedure SetCheckState(Value: TCheckState);
-    procedure SetCheckType(Value: TCheckType);
-    procedure SetColor(const Value: TColor);
-    procedure SetImageIndex(Value: TImageIndex);
-    procedure SetLayout(Value: TVTHeaderColumnLayout);
-    procedure SetMargin(Value: Integer);
-    procedure SetMaxWidth(Value: Integer);
-    procedure SetMinWidth(Value: Integer);
-    procedure SetOptions(Value: TVTColumnOptions);
-    procedure SetPosition(Value: TColumnPosition);
-    procedure SetSpacing(Value: Integer);
-    procedure SetStyle(Value: TVirtualTreeColumnStyle);
-   procedure SetText(const Value: String);
-    procedure SetWidth(Value: Integer);
-  protected
-    procedure ComputeHeaderLayout(DC: HDC; const Client: TRect; UseHeaderGlyph, UseSortGlyph: Boolean;
-      var HeaderGlyphPos, SortGlyphPos: TPoint; var TextBounds: TRect; DrawFormat: Cardinal;
-      CalculateTextRect: Boolean = False);
-    procedure GetAbsoluteBounds(var Left, Right: Integer);
-    function GetDisplayName: string; override;
-    function GetOwner: TVirtualTreeColumns; reintroduce;
-  public
-    constructor Create(Collection: TCollection); override;
-    destructor Destroy; override;
-
-    procedure Assign(Source: TPersistent); override;
-    function Equals(OtherColumnObj: TObject): Boolean; virtual;
-    function GetRect: TRect; virtual;
-    procedure LoadFromStream(const Stream: TStream; Version: Integer);
-    procedure ParentBiDiModeChanged;
-    procedure ParentColorChanged;
-    procedure RestoreLastWidth;
-    procedure SaveToStream(const Stream: TStream);
-    function UseRightToLeftReading: Boolean;
-
-    property Left: Integer read GetLeft;
-    property Owner: TVirtualTreeColumns read GetOwner;
-  published
-    property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
-    property BiDiMode: TBiDiMode read FBiDiMode write SetBiDiMode stored IsBiDiModeStored default bdLeftToRight;
-    property CaptionAlignment: TAlignment read GetCaptionAlignment write SetCaptionAlignment
-      stored IsCaptionAlignmentStored default taLeftJustify;
-    property CaptionText: String read FCaptionText stored False;
-    property CheckType: TCheckType read FCheckType write SetCheckType default ctCheckBox;
-    property CheckState: TCheckState read FCheckState write SetCheckState default csUncheckedNormal;
-    property CheckBox: Boolean read FCheckBox write SetCheckBox default False;
-    property Color: TColor read FColor write SetColor stored IsColorStored;
-    property Hint: String read FHint write FHint;
-    property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;
-    property Layout: TVTHeaderColumnLayout read FLayout write SetLayout default blGlyphLeft;
-    property Margin: Integer read FMargin write SetMargin default 4;
-    property MaxWidth: Integer read FMaxWidth write SetMaxWidth default 10000;
-    property MinWidth: Integer read FMinWidth write SetMinWidth default 10;
-    property Options: TVTColumnOptions read FOptions write SetOptions default DefaultColumnOptions;
-    property Position: TColumnPosition read FPosition write SetPosition;
-    property Spacing: Integer read FSpacing write SetSpacing default 4;
-    property Style: TVirtualTreeColumnStyle read FStyle write SetStyle default vsText;
-    property Tag: Integer read FTag write FTag default 0;
-    property Text: String read FText write SetText;
-    property Width: Integer read FWidth write SetWidth default 50;
-  end;
-
-  TVirtualTreeColumnClass = class of TVirtualTreeColumn;
-
-  TColumnsArray = array of TVirtualTreeColumn;
-  TCardinalArray = array of Cardinal;
-  TIndexArray = array of TColumnIndex;
-
-  TVirtualTreeColumns = class(TCollection)
-  private
-    FHeader: TVTHeader;
-    FHeaderBitmap: TBitmap;               // backbuffer for drawing
-    FHoverIndex,                          // currently "hot" column
-    FDownIndex,                           // Column on which a mouse button is held down.
-    FTrackIndex: TColumnIndex;            // Index of column which is currently being resized
-    FClickIndex: TColumnIndex;            // last clicked column
-    FPositionToIndex: TIndexArray;
-    FDefaultWidth: Integer;               // the width columns are created with
-    FNeedPositionsFix: Boolean;           // True if FixPositions must still be called after DFM loading or Bidi mode change.
-    FClearing: Boolean;                   // True if columns are being deleted entirely.
-
-    // drag support
-    FDragIndex: TColumnIndex;             // index of column currently being dragged
-    FDropTarget: TColumnIndex;            // current target column (index) while dragging
-    FDropBefore: Boolean;                 // True if drop position is in the left half of a column, False for the right
-                                          // side to drop the dragged column to
-    function GetCount: Integer;
-    function GetItem(Index: TColumnIndex): TVirtualTreeColumn;
-    function GetNewIndex(P: TPoint; var OldIndex: TColumnIndex): Boolean;
-    procedure SetDefaultWidth(Value: Integer);
-    procedure SetItem(Index: TColumnIndex; Value: TVirtualTreeColumn);
-  protected
-    procedure AdjustAutoSize(CurrentIndex: TColumnIndex; Force: Boolean = False);
-    function AdjustDownColumn(P: TPoint): TColumnIndex;
-    function AdjustHoverColumn(const P: TPoint): Boolean;
-    procedure AdjustPosition(Column: TVirtualTreeColumn; Position: Cardinal);
-    function CanSplitterResize(P: TPoint; Column: TColumnIndex): Boolean;
-    procedure DoCanSplitterResize(P: TPoint; Column: TColumnIndex; var Allowed: Boolean);
-    procedure DrawButtonText(DC: HDC; Caption: String; Bounds: TRect; Enabled, Hot: Boolean; DrawFormat: Cardinal;
-      WrapCaption: Boolean);
-    procedure DrawXPButton(DC: HDC; const ButtonR: TRect; DrawSplitter, Down, Hover: Boolean);
-    procedure FixPositions;
-    function GetColumnAndBounds(const P: TPoint; var ColumnLeft, ColumnRight: Integer; Relative: Boolean = True): Integer;
-    function GetOwner: TPersistent; override;
-    procedure HandleClick(P: TPoint; Button: TMouseButton; Force, DblClick: Boolean); virtual;
-    procedure IndexChanged(OldIndex, NewIndex: Integer);
-    procedure InitializePositionArray;
-    procedure ReorderColumns(RTL: Boolean);
-    procedure Update(Item: TCollectionItem); override;
-    procedure UpdatePositions(Force: Boolean = False);
-
-    property HeaderBitmap: TBitmap read FHeaderBitmap;
-    property PositionToIndex: TIndexArray read FPositionToIndex;
-  public
-    constructor Create(AOwner: TVTHeader);
-    destructor Destroy; override;
-
-    function Add: TVirtualTreeColumn; virtual;
-    procedure AnimatedResize(Column: TColumnIndex; NewWidth: Integer);
-    procedure Assign(Source: TPersistent); override;
-    procedure Clear; virtual;
-    function ColumnFromPosition(const P: TPoint; Relative: Boolean = True): TColumnIndex; overload; virtual;
-    function ColumnFromPosition(PositionIndex: TColumnPosition): TColumnIndex; overload; virtual;
-    function Equals(OtherColumnsObj: TObject): Boolean;
-    procedure GetColumnBounds(Column: TColumnIndex; out Left, Right: Integer);
-    function GetFirstVisibleColumn(ConsiderAllowFocus: Boolean = False): TColumnIndex;
-    function GetLastVisibleColumn(ConsiderAllowFocus: Boolean = False): TColumnIndex;
-    function GetNextColumn(Column: TColumnIndex): TColumnIndex;
-    function GetNextVisibleColumn(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex;
-    function GetPreviousColumn(Column: TColumnIndex): TColumnIndex;
-    function GetPreviousVisibleColumn(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex;
-    function GetScrollWidth: Integer;
-    function GetVisibleColumns: TColumnsArray;
-    function GetVisibleFixedWidth: Integer;
-    function IsValidColumn(Column: TColumnIndex): Boolean;
-    procedure LoadFromStream(const Stream: TStream; Version: Integer);
-    procedure PaintHeader(DC: HDC; const R: TRect; HOffset: Integer); virtual;
-    procedure SaveToStream(const Stream: TStream);
-    function TotalWidth: Integer;
-
-    property Count: Integer read GetCount;
-    property ClickIndex: TColumnIndex read FClickIndex;
-    property DefaultWidth: Integer read FDefaultWidth write SetDefaultWidth default 50;
-    property Items[Index: TColumnIndex]: TVirtualTreeColumn read GetItem write SetItem; default;
-    property Header: TVTHeader read FHeader;
-    property TrackIndex: TColumnIndex read FTrackIndex;
-  end;
-
-  TVirtualTreeColumnsClass = class of TVirtualTreeColumns;
-
-  TVTConstraintPercent = 0..100;
-  TVTFixedAreaConstraints = class(TPersistent)
-  private
-    FHeader: TVTHeader;
-    FMaxHeightPercent,
-    FMaxWidthPercent,
-    FMinHeightPercent,
-    FMinWidthPercent: TVTConstraintPercent;
-    FOnChange: TNotifyEvent;
-    procedure SetConstraints(Index: Integer; Value: TVTConstraintPercent);
-  protected
-    procedure Change;
-    property Header: TVTHeader read FHeader;
-  public
-    constructor Create(AOwner: TVTHeader);
-
-    procedure Assign(Source: TPersistent); override;
-    property OnChange: TNotifyEvent read FOnChange write FOnChange;
-  published
-    property MaxHeightPercent: TVTConstraintPercent index 0 read FMaxHeightPercent write SetConstraints default 0;
-    property MaxWidthPercent: TVTConstraintPercent index 1 read FMaxWidthPercent write SetConstraints default 0;
-    property MinHeightPercent: TVTConstraintPercent index 2 read FMinHeightPercent write SetConstraints default 0;
-    property MinWidthPercent: TVTConstraintPercent index 3 read FMinWidthPercent write SetConstraints default 0;
-  end;
-
-  TVTHeaderStyle = (
-    hsThickButtons,    // TButton look and feel
-    hsFlatButtons,     // flatter look than hsThickButton, like an always raised flat TToolButton
-    hsPlates,          // flat TToolButton look and feel (raise on hover etc.)
-    hsXPStyle          // Windows XP style
-  );
-
-  TVTHeaderOption = (
-    hoAutoResize,            // Adjust a column so that the header never exceeds the client width of the owner control.
-    hoColumnResize,          // Resizing columns with the mouse is allowed.
-    hoDblClickResize,        // Allows a column to resize itself to its largest entry.
-    hoDrag,                  // Dragging columns is allowed.
-    hoHotTrack,              // Header captions are highlighted when mouse is over a particular column.
-    hoOwnerDraw,             // Header items with the owner draw style can be drawn by the application via event.
-    hoRestrictDrag,          // Header can only be dragged horizontally.
-    hoShowHint,              // Show application defined header hint.
-    hoShowImages,            // Show header images.
-    hoShowSortGlyphs,        // Allow visible sort glyphs.
-    hoVisible,               // Header is visible.
-    hoAutoSpring,            // Distribute size changes of the header to all columns, which are sizable and have the
-                             // coAutoSpring option enabled. hoAutoResize must be enabled too.
-    hoFullRepaintOnResize,   // Fully invalidate the header (instead of subsequent columns only) when a column is resized.
-    hoDisableAnimatedResize, // Disable animated resize for all columns.
-    hoHeightResize,          // Allow resizing header height via mouse.
-    hoHeightDblClickResize   // Allow the header to resize itself to its default height.
-  );
-  TVTHeaderOptions = set of TVTHeaderOption;
-
-  THeaderState = (
-    hsAutoSizing,      // auto size chain is in progess, do not trigger again on WM_SIZE
-    hsDragging,        // header dragging is in progress (only if enabled)
-    hsDragPending,     // left button is down, user might want to start dragging a column
-    hsLoading,         // The header currently loads from stream, so updates are not necessary.
-    hsColumnWidthTracking,     // column resizing is in progress
-    hsColumnWidthTrackPending, // left button is down, user might want to start resize a column
-    hsHeightTracking,          // height resizing is in progress
-    hsHeightTrackPending,      // left button is down, user might want to start changing height
-    hsResizing,                // multi column resizing in progress
-    hsScaling,                 // the header is scaled after a change of FixedAreaConstraints or client size
-    hsNeedScaling              // the header needs to be scaled
-  );
-  THeaderStates = set of THeaderState;
-
-  TSortDirection = (
-    sdAscending,
-    sdDescending
-  );
-
-  // describes the used column resize behaviour for AutoFitColumns
-  TSmartAutoFitType = (
-    smaAllColumns,      // consider nodes in view only for all columns
-    smaNoColumn,        // consider nodes in view only for no column
-    smaUseColumnOption  // use coSmartResize of the corresponding column
-  );
-
-  // desribes what made a structure change event happen
-  TChangeReason = (
-    crIgnore,       // used as placeholder
-    crAccumulated,  // used for delayed changes
-    crChildAdded,   // one or more child nodes have been added
-    crChildDeleted, // one or more child nodes have been deleted
-    crNodeAdded,    // a node has been added
-    crNodeCopied,   // a node has been duplicated
-    crNodeMoved     // a node has been moved to a new place
-  );
-
-  TVTHeader = class(TPersistent)
-  private
-    FOwner: TBaseVirtualTree;
-    FColumns: TVirtualTreeColumns;
-    FHeight: Integer;
-    FFont: TFont;
-    FParentFont: Boolean;
-    FOptions: TVTHeaderOptions;
-    FStates: THeaderStates;            // Used to keep track of internal states the header can enter.
-    FTrackPoint: TPoint;               // Client coordinate where the tracking started.
-    FStyle: TVTHeaderStyle;            // button style
-    FBackground: TColor;
-    FAutoSizeIndex: TColumnIndex;
-    FPopupMenu: TPopupMenu;
-    FMainColumn: TColumnIndex;         // the column which holds the tree
-    FMaxHeight: Integer;
-    FMinHeight: Integer;
-    FDefaultHeight: Integer;
-    FFixedAreaConstraints: TVTFixedAreaConstraints; // Percentages for the fixed area (header, fixed columns).
-    FImages: TCustomImageList;
-    FImageChangeLink: TChangeLink;     // connections to the image list to get notified about changes
-    FSortColumn: TColumnIndex;
-    FSortDirection: TSortDirection;
-    FTrackStart: TPoint;               // client coordinates of the tracking start point
-    FDragStart: TPoint;                // initial mouse drag position
-    FDragImage: TVTDragImage;          // drag image management during header drag
-    FLastWidth: Integer;               // Used to adjust spring columns. This is the width of all visible columns,
-                                       // not the header rectangle.
-    procedure FontChanged(Sender: TObject);
-    function GetMainColumn: TColumnIndex;
-    function GetUseColumns: Boolean;
-    function IsFontStored: Boolean;
-    procedure SetAutoSizeIndex(Value: TColumnIndex);
-    procedure SetBackground(Value: TColor);
-    procedure SetColumns(Value: TVirtualTreeColumns);
-    procedure SetDefaultHeight(Value: Integer);
-    procedure SetFont(const Value: TFont);
-    procedure SetHeight(Value: Integer);
-    procedure SetImages(const Value: TCustomImageList);
-    procedure SetMainColumn(Value: TColumnIndex);
-    procedure SetMaxHeight(Value: Integer);
-    procedure SetMinHeight(Value: Integer);
-    procedure SetOptions(Value: TVTHeaderOptions);
-    procedure SetParentFont(Value: Boolean);
-    procedure SetSortColumn(Value: TColumnIndex);
-    procedure SetSortDirection(const Value: TSortDirection);
-    procedure SetStyle(Value: TVTHeaderStyle);
-  protected
-    procedure ChangeScale(M, D: Integer); virtual;
-    function DetermineSplitterIndex(const P: TPoint): Boolean; virtual;
-    procedure DoAfterAutoFitColumn(Column: TColumnIndex); virtual;
-    procedure DoAfterColumnWidthTracking(Column: TColumnIndex); virtual;
-    procedure DoAfterHeightTracking; virtual;
-    function DoBeforeAutoFitColumn(Column: TColumnIndex; SmartAutoFitType: TSmartAutoFitType): Boolean; virtual;
-    procedure DoBeforeColumnWidthTracking(Column: TColumnIndex; Shift: TShiftState); virtual;
-    procedure DoBeforeHeightTracking(Shift: TShiftState); virtual;
-    function DoColumnWidthDblClickResize(Column: TColumnIndex; P: TPoint; Shift: TShiftState): Boolean; virtual;
-    function DoColumnWidthTracking(Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint): Boolean; virtual;
-    function DoGetPopupMenu(Column: TColumnIndex; Position: TPoint): TPopupMenu; virtual;
-    function DoHeightTracking(var P: TPoint; Shift: TShiftState): Boolean; virtual;
-    function DoHeightDblClickResize(var P: TPoint; Shift: TShiftState): Boolean; virtual;
-    procedure DoSetSortColumn(Value: TColumnIndex); virtual;
-    procedure DragTo(const P: TPoint);
-    procedure FixedAreaConstraintsChanged(Sender: TObject);
-    function GetColumnsClass: TVirtualTreeColumnsClass; virtual;
-    function GetOwner: TPersistent; override;
-    function GetShiftState: TShiftState;
-    function HandleHeaderMouseMove(var Message: TLMMouseMove): Boolean;
-    function HandleMessage(var Message: TLMessage): Boolean; virtual;
-    procedure ImageListChange(Sender: TObject);
-    procedure PrepareDrag(P, Start: TPoint);
-    procedure RecalculateHeader; virtual;
-    procedure RescaleHeader;
-    procedure UpdateMainColumn;
-    procedure UpdateSpringColumns;
-  public
-    constructor Create(AOwner: TBaseVirtualTree); virtual;
-    destructor Destroy; override;
-
-    function AllowFocus(ColumnIndex: TColumnIndex): Boolean;
-    procedure Assign(Source: TPersistent); override;
-    procedure AutoFitColumns(Animated: Boolean = True; SmartAutoFitType: TSmartAutoFitType = smaUseColumnOption;
-      RangeStartCol: Integer = NoColumn; RangeEndCol: Integer = NoColumn);
-    function InHeader(const P: TPoint): Boolean; virtual;
-    function InHeaderSplitterArea(P: TPoint): Boolean; virtual;
-    procedure Invalidate(Column: TVirtualTreeColumn; ExpandToBorder: Boolean = False);
-    procedure LoadFromStream(const Stream: TStream); virtual;
-    function ResizeColumns(ChangeBy: Integer; RangeStartCol: TColumnIndex; RangeEndCol: TColumnIndex;
-      Options: TVTColumnOptions = [coVisible]): Integer;
-    procedure RestoreColumns;
-    procedure SaveToStream(const Stream: TStream); virtual;
-
-    property DragImage: TVTDragImage read FDragImage;
-    property States: THeaderStates read FStates;
-    property Treeview: TBaseVirtualTree read FOwner;
-    property UseColumns: Boolean read GetUseColumns;
-  published
-    property AutoSizeIndex: TColumnIndex read FAutoSizeIndex write SetAutoSizeIndex;
-    property Background: TColor read FBackground write SetBackground default clBtnFace;
-    property Columns: TVirtualTreeColumns read FColumns write SetColumns;
-    property DefaultHeight: Integer read FDefaultHeight write SetDefaultHeight;
-    property Font: TFont read FFont write SetFont stored IsFontStored;
-    property FixedAreaConstraints: TVTFixedAreaConstraints read FFixedAreaConstraints write FFixedAreaConstraints;
-    property Height: Integer read FHeight write SetHeight default 17;
-    property Images: TCustomImageList read FImages write SetImages;
-    property MainColumn: TColumnIndex read GetMainColumn write SetMainColumn default 0;
-    property MaxHeight: Integer read FMaxHeight write SetMaxHeight default 10000;
-    property MinHeight: Integer read FMinHeight write SetMinHeight default 10;
-    property Options: TVTHeaderOptions read FOptions write SetOptions default [hoColumnResize, hoDrag, hoShowSortGlyphs];
-    property ParentFont: Boolean read FParentFont write SetParentFont default False;
-    property PopupMenu: TPopupMenu read FPopupMenu write FPopUpMenu;
-    property SortColumn: TColumnIndex read FSortColumn write SetSortColumn default NoColumn;
-    property SortDirection: TSortDirection read FSortDirection write SetSortDirection default sdAscending;
-    property Style: TVTHeaderStyle read FStyle write SetStyle default hsThickButtons;
-  end;
-
-  TVTHeaderClass = class of TVTHeader;
-
-  // 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.
-  IVTEditLink = interface
-    ['{2BE3EAFA-5ACB-45B4-9D9A-B58BCC496E17}']
-    function BeginEdit: Boolean; stdcall;                  // Called when editing actually starts.
-    function CancelEdit: Boolean; stdcall;                 // Called when editing has been cancelled by the tree.
-    function EndEdit: Boolean; stdcall;                    // Called when editing has been finished by the tree.
-    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
-                                                           // Called after creation to allow a setup.
-    function GetBounds: TRect; stdcall;                    // Called to get the current size of the edit window
-                                                           // (only important if the edit resizes itself).
-    procedure ProcessMessage(var Message: TLMessage); stdcall;
-                                                           // Used to forward messages to the edit window(s)-
-    procedure SetBounds(R: TRect); stdcall;                // Called to place the editor.
-  end;
-
-  // Indicates in the OnUpdating event what state the tree is currently in.
-  TVTUpdateState = (
-    usBegin,       // The tree just entered the update state (BeginUpdate call for the first time).
-    usBeginSynch,  // The tree just entered the synch update state (BeginSynch call for the first time).
-    usSynch,       // Begin/EndSynch has been called but the tree did not change the update state.
-    usUpdate,      // Begin/EndUpdate has been called but the tree did not change the update state.
-    usEnd,         // The tree just left the update state (EndUpdate called for the last level).
-    usEndSynch     // The tree just left the synch update state (EndSynch called for the last level).
-  );
-
-  // Used during owner draw of the header to indicate which drop mark for the column must be drawn.
-  TVTDropMarkMode = (
-    dmmNone,
-    dmmLeft,
-    dmmRight
-  );
-
-  // This structure carries all important information about header painting and is used in the advanced header painting.
-  THeaderPaintInfo = record
-    TargetCanvas: TCanvas;
-    Column: TVirtualTreeColumn;
-    PaintRectangle: TRect;
-    TextRectangle: TRect;
-    IsHoverIndex,
-    IsDownIndex,
-    IsEnabled,
-    ShowHeaderGlyph,
-    ShowSortGlyph,
-    ShowRightBorder: Boolean;
-    DropMark: TVTDropMarkMode;
-    GlyphPos,
-    SortGlyphPos: TPoint;
-  end;
-
-  // These elements are used both to query the application, which of them it wants to draw itself and to tell it during
-  // painting, which elements must be drawn during the advanced custom draw events.
-  THeaderPaintElements = set of (
-    hpeBackground,
-    hpeDropMark,
-    hpeHeaderGlyph,
-    hpeSortGlyph,
-    hpeText
-  );
-
-  // Various events must be handled at different places than they were initiated or need
-  // a persistent storage until they are reset.
-  TVirtualTreeStates = set of (
-    tsCancelHintAnimation,    // Set when a new hint is about to show but an old hint is still being animated.
-    tsChangePending,          // A selection change is pending.
-    tsCheckPropagation,       // Set during automatic check state propagation.
-    tsCollapsing,             // A full collapse operation is in progress.
-    tsToggleFocusedSelection, // Node selection was modifed using Ctrl-click. Change selection state on next mouse up.
-    tsClearPending,           // Need to clear the current selection on next mouse move.
-    tsClipboardFlushing,      // Set during flushing the clipboard to avoid freeing the content.
-    tsCopyPending,            // Indicates a pending copy operation which needs to be finished.
-    tsCutPending,             // Indicates a pending cut operation which needs to be finished.
-    tsDrawSelPending,         // Multiselection only. User held down the left mouse button on a free
-                              // area and might want to start draw selection.
-    tsDrawSelecting,          // Multiselection only. Draw selection has actually started.
-    tsEditing,                // Indicates that an edit operation is currently in progress.
-    tsEditPending,            // An mouse up start edit if dragging has not started.
-    tsExpanding,              // A full expand operation is in progress.
-    tsNodeHeightTracking,     // A node height changing operation is in progress.
-    tsNodeHeightTrackPending, // left button is down, user might want to start changing a node's height.
-    tsHint,                   // Set when our hint is visible or soon will be.
-    tsInAnimation,            // Set if the tree is currently in an animation loop.
-    tsIncrementalSearching,   // Set when the user starts incremental search.
-    tsIncrementalSearchPending, // Set in WM_KEYDOWN to tell to use the char in WM_CHAR for incremental search.
-    tsIterating,              // Set when IterateSubtree is currently in progress.
-    tsKeyCheckPending,        // A check operation is under way, initiated by a key press (space key). Ignore mouse.
-    tsLeftButtonDown,         // Set when the left mouse button is down.
-    tsLeftDblClick,           // Set when the left mouse button was doubly clicked.
-    tsMouseCheckPending,      // A check operation is under way, initiated by a mouse click. Ignore space key.
-    tsMiddleButtonDown,       // Set when the middle mouse button is down.
-    tsMiddleDblClick,         // Set when the middle mouse button was doubly clicked.
-    tsNeedScale,              // On next ChangeScale scale the default node height.
-    tsNeedRootCountUpdate,    // Set if while loading a root node count is set.
-    tsOLEDragging,            // OLE dragging in progress.
-    tsOLEDragPending,         // User has requested to start delayed dragging.
-    tsPainting,               // The tree is currently painting itself.
-    tsRightButtonDown,        // Set when the right mouse button is down.
-    tsRightDblClick,          // Set when the right mouse button was doubly clicked.
-    tsPopupMenuShown,         // The user clicked the right mouse button, which might cause a popup menu to appear.
-    tsScrolling,              // Set when autoscrolling is active.
-    tsScrollPending,          // Set when waiting for the scroll delay time to elapse.
-    tsSizing,                 // Set when the tree window is being resized. This is used to prevent recursive calls
-                              // due to setting the scrollbars when sizing.
-    tsStopValidation,         // Cache validation can be stopped (usually because a change has occured meanwhile).
-    tsStructureChangePending, // The structure of the tree has been changed while the update was locked.
-    tsSynchMode,              // Set when the tree is in synch mode, where no timer events are triggered.
-    tsThumbTracking,          // Stop updating the horizontal scroll bar while dragging the vertical thumb and vice versa.
-    tsToggling,               // A toggle operation (for some node) is in progress.
-    tsUpdateHiddenChildrenNeeded, // Pending update for the hidden children flag after massive visibility changes.
-    tsUpdating,               // The tree does currently not update its window because a BeginUpdate has not yet ended.
-    tsUseCache,               // The tree's node caches are validated and non-empty.
-    tsUserDragObject,         // Signals that the application created an own drag object in OnStartDrag.
-    tsUseThemes,              // The tree runs under WinXP+, is theme aware and themes are enabled.
-    tsValidating,             // The tree's node caches are currently validated.
-    tsValidationNeeded,       // Something in the structure of the tree has changed. The cache needs validation.
-    tsVCLDragging,            // VCL drag'n drop in progress.
-    tsVCLDragPending,         // One-shot flag to avoid clearing the current selection on implicit mouse up for VCL drag.
-    tsWheelPanning,           // Wheel mouse panning is active or soon will be.
-    tsWheelScrolling,         // Wheel mouse scrolling is active or soon will be.
-    tsWindowCreating          // Set during window handle creation to avoid frequent unnecessary updates.
-  );
-
-  TChangeStates = set of (
-    csStopValidation,         // Cache validation can be stopped (usually because a change has occured meanwhile).
-    csUseCache,               // The tree's node caches are validated and non-empty.
-    csValidating,             // The tree's node caches are currently validated.
-    csValidationNeeded        // Something in the structure of the tree has changed. The cache needs validation.
-  );
-
-  // determines whether and how the drag image is to show
-  TVTDragImageKind = (
-    diComplete,       // show a complete drag image with all columns, only visible columns are shown
-    diMainColumnOnly, // show only the main column (the tree column)
-    diNoImage         // don't show a drag image at all
-  );
-
-  // Switch for OLE and VCL drag'n drop. Because it is not possible to have both simultanously.
-  TVTDragType = (
-    dtOLE,
-    dtVCL
-  );
-
-  // options which determine what to draw in PaintTree
-  TVTInternalPaintOption = (
-    poBackground,       // draw background image if there is any and it is enabled
-    poColumnColor,      // erase node's background with the column's color
-    poDrawFocusRect,    // draw focus rectangle around the focused node
-    poDrawSelection,    // draw selected nodes with the normal selection color
-    poDrawDropMark,     // draw drop mark if a node is currently the drop target
-    poGridLines,        // draw grid lines if enabled
-    poMainOnly,         // draw only the main column
-    poSelectedOnly      // draw only selected nodes
-  );
-  TVTInternalPaintOptions = set of TVTInternalPaintOption;
-
-  // Determines the look of a tree's lines.
-  TVTLineStyle = (
-    lsCustomStyle,           // application provides a line pattern
-    lsDotted,                // usual dotted lines (default)
-    lsSolid                  // simple solid lines
-  );
-
-  // TVTLineType is used during painting a tree
-  TVTLineType = (
-    ltNone,          // no line at all
-    ltBottomRight,   // a line from bottom to the center and from there to the right
-    ltTopDown,       // a line from top to bottom
-    ltTopDownRight,  // a line from top to bottom and from center to the right
-    ltRight,         // a line from center to the right
-    ltTopRight,      // a line from bottom to center and from there to the right
-    // special styles for alternative drawings of tree lines
-    ltLeft,          // a line from top to bottom at the left
-    ltLeftBottom     // a combination of ltLeft and a line at the bottom from left to right
-  );
-
-  // Determines how to draw tree lines.
-  TVTLineMode = (
-    lmNormal,        // usual tree lines (as in TTreeview)
-    lmBands          // looks similar to a Nassi-Schneidermann diagram
-  );
-
-  // A collection of line type IDs which is used while painting a node.
-  TLineImage = array of TVTLineType;
-
-  TVTScrollIncrement = 1..10000;
-
-  // Export type
-  TVTExportType = (
-    etRTF,   // contentToRTF
-    etHTML,  // contentToHTML
-    etText,  // contentToText
-    etExcel, // supported by external tools
-    etWord,  // supported by external tools
-    etCustom // supported by external tools
-  );
-
-  TVTNodeExportEvent   = function (Sender: TBaseVirtualTree; aExportType: TVTExportType; Node: PVirtualNode): Boolean of object;
-  TVTColumnExportEvent = procedure (Sender: TBaseVirtualTree; aExportType: TVTExportType; Column: TVirtualTreeColumn) of object;
-  TVTTreeExportEvent   = procedure(Sender: TBaseVirtualTree; aExportType: TVTExportType) of object;
-
-  // A class to manage scroll bar aspects.
-  TScrollBarOptions = class(TPersistent)
-  private
-    FAlwaysVisible: Boolean;
-    FOwner: TBaseVirtualTree;
-    FScrollBars: TScrollStyle;                   // used to hide or show vertical and/or horizontal scrollbar
-    FScrollBarStyle: TVTScrollBarStyle;            // kind of scrollbars to use
-    FIncrementX,
-    FIncrementY: TVTScrollIncrement;             // number of pixels to scroll in one step (when auto scrolling)
-    procedure SetAlwaysVisible(Value: Boolean);
-    procedure SetScrollBars(Value: TScrollStyle);
-    procedure SetScrollBarStyle(Value: TVTScrollBarStyle);
-  protected
-    function GetOwner: TPersistent; override;
-  public
-    constructor Create(AOwner: TBaseVirtualTree);
-
-    procedure Assign(Source: TPersistent); override;
-  published
-    property AlwaysVisible: Boolean read FAlwaysVisible write SetAlwaysVisible default False;
-    property HorizontalIncrement: TVTScrollIncrement read FIncrementX write FIncrementX default 20;
-    property ScrollBars: TScrollStyle read FScrollbars write SetScrollBars default ssBoth;
-    property ScrollBarStyle: TVTScrollBarStyle read FScrollBarStyle write SetScrollBarStyle default sbmRegular;
-    property VerticalIncrement: TVTScrollIncrement read FIncrementY write FIncrementY default 20;
-  end;
-
-  // class to collect all switchable colors into one place
-  TVTColors = class(TPersistent)
-  private
-    FOwner: TBaseVirtualTree;
-    FColors: array[0..14] of TColor;
-    function GetColor(const Index: Integer): TColor;
-    procedure SetColor(const Index: Integer; const Value: TColor);
-  public
-    constructor Create(AOwner: TBaseVirtualTree);
-
-    procedure Assign(Source: TPersistent); override;
-  published
-    property BorderColor: TColor index 7 read GetColor write SetColor default clBtnFace;
-    property DisabledColor: TColor index 0 read GetColor write SetColor default clBtnShadow;
-    property DropMarkColor: TColor index 1 read GetColor write SetColor default clHighlight;
-    property DropTargetColor: TColor index 2 read GetColor write SetColor default clHighLight;
-    property DropTargetBorderColor: TColor index 11 read GetColor write SetColor default clHighLight;
-    property FocusedSelectionColor: TColor index 3 read GetColor write SetColor default clHighLight;
-    property FocusedSelectionBorderColor: TColor index 9 read GetColor write SetColor default clHighLight;
-    property GridLineColor: TColor index 4 read GetColor write SetColor default clBtnFace;
-    property HeaderHotColor: TColor index 14 read GetColor write SetColor default clBtnShadow;
-    property HotColor: TColor index 8 read GetColor write SetColor default clWindowText;
-    property SelectionRectangleBlendColor: TColor index 12 read GetColor write SetColor default clHighlight;
-    property SelectionRectangleBorderColor: TColor index 13 read GetColor write SetColor default clHighlight;
-    property TreeLineColor: TColor index 5 read GetColor write SetColor default clBtnShadow;
-    property UnfocusedSelectionColor: TColor index 6 read GetColor write SetColor default clBtnFace;
-    property UnfocusedSelectionBorderColor: TColor index 10 read GetColor write SetColor default clBtnFace;
-  end;
-
-  // For painting a node and its columns/cells a lot of information must be passed frequently around.
-  TVTImageInfo = record
-    Index: Integer;           // Index in the associated image list.
-    XPos,                     // Horizontal position in the current target canvas.
-    YPos: Integer;            // Vertical position in the current target canvas.
-    Ghosted: Boolean;         // Flag to indicate that the image must be drawn slightly lighter.
-    Images: TCustomImageList; // The image list to be used for painting.
-  end;
-
-  TVTImageInfoIndex = (
-    iiNormal,
-    iiState,
-    iiCheck,
-    iiOverlay
-  );
-
-  // Options which are used when modifying the scroll offsets.
-  TScrollUpdateOptions = set of (
-    suoRepaintHeader,        // if suoUpdateNCArea is also set then invalidate the header
-    suoRepaintScrollbars,    // if suoUpdateNCArea is also set then repaint both scrollbars after updating them
-    suoScrollClientArea,     // scroll and invalidate the proper part of the client area
-    suoUpdateNCArea          // update non-client area (scrollbars, header)
-  );
-
-  // Determines the look of a tree's buttons.
-  TVTButtonStyle = (
-    bsRectangle,             // traditional Windows look (plus/minus buttons)
-    bsTriangle               // traditional Macintosh look
-  );
-
-  // TButtonFillMode is only used when the button style is bsRectangle and determines how to fill the interior.
-  TVTButtonFillMode = (
-    fmTreeColor,             // solid color, uses the tree's background color
-    fmWindowColor,           // solid color, uses clWindow
-    fmShaded,                // color gradient, Windows XP style (legacy code, use toThemeAware on Windows XP instead)
-    fmTransparent            // transparent color, use the item's background color
-  );
-
-  TVTPaintInfo = record
-    Canvas: TCanvas;              // the canvas to paint on
-    PaintOptions: TVTInternalPaintOptions;  // a copy of the paint options passed to PaintTree
-    Node: PVirtualNode;           // the node to paint
-    Column: TColumnIndex;         // the node's column index to paint
-    Position: TColumnPosition;    // the column position of the node
-    CellRect,                     // the node cell
-    ContentRect: TRect;           // the area of the cell used for the node's content
-    NodeWidth: Integer;           // the actual node width
-    Alignment: TAlignment;        // how to align within the node rectangle
-    CaptionAlignment: TAlignment; // how to align text within the caption rectangle
-    BidiMode: TBidiMode;          // directionality to be used for painting
-    BrushOrigin: TPoint;          // the alignment for the brush used to draw dotted lines
-    ImageInfo: array[TVTImageInfoIndex] of TVTImageInfo; // info about each possible node image
-  end;
-
-  // Method called by the Animate routine for each animation step.
-  TVTAnimationCallback = function(Step, StepSize: Integer; Data: Pointer): Boolean of object;
-
-  TVTIncrementalSearch = (
-    isAll,                   // search every node in tree, initialize if necessary
-    isNone,                  // disable incremental search
-    isInitializedOnly,       // search only initialized nodes, skip others
-    isVisibleOnly            // search only visible nodes, initialize if necessary
-  );
-
-  // Determines which direction to use when advancing nodes during an incremental search.
-  TVTSearchDirection = (
-    sdForward,
-    sdBackward
-  );
-
-  // Determines where to start incremental searching for each key press.
-  TVTSearchStart = (
-    ssAlwaysStartOver,       // always use the first/last node (depending on direction) to search from
-    ssLastHit,               // use the last found node
-    ssFocusedNode            // use the currently focused node
-  );
-
-  // Determines how to use the align member of a node.
-  TVTNodeAlignment = (
-    naFromBottom,            // the align member specifies amount of units (usually pixels) from top border of the node
-    naFromTop,               // align is to be measured from bottom
-    naProportional           // align is to be measure in percent of the entire node height and relative to top
-  );
-
-  // Determines how to draw the selection rectangle used for draw selection.
-  TVTDrawSelectionMode = (
-    smDottedRectangle,       // same as DrawFocusRect
-    smBlendedRectangle       // alpha blending, uses special colors (see TVTColors)
-  );
-
-  // Determines for which purpose the cell paint event is called.
-  TVTCellPaintMode = (
-    cpmPaint,                // painting the cell
-    cpmGetContentMargin      // getting cell content margin
-  );
-
-  // Determines which sides of the cell content margin should be considered.
-  TVTCellContentMarginType = (
-    ccmtAllSides,            // consider all sides
-    ccmtTopLeftOnly,         // consider top margin and left margin only
-    ccmtBottomRightOnly      // consider bottom margin and right margin only
-  );
-
-  TClipboardFormats = class(TStringList)
-  private
-    FOwner: TBaseVirtualTree;
-  public
-    constructor Create(AOwner: TBaseVirtualTree); virtual;
-
-    function Add(const S: string): Integer; override;
-    procedure Insert(Index: Integer; const S: string); override;
-    property Owner: TBaseVirtualTree read FOwner;
-  end;
-
-  // ----- Event prototypes:
-
-  // node enumeration
-  TVTGetNodeProc = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean) of object;
-
-  // node events
-  TVTChangingEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; var Allowed: Boolean) of object;
-  TVTCheckChangingEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; var NewState: TCheckState;
-    var Allowed: Boolean) of object;
-  TVTChangeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode) of object;
-  TVTStructureChangeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Reason: TChangeReason) of object;
-  TVTEditCancelEvent = procedure(Sender: TBaseVirtualTree; Column: TColumnIndex) of object;
-  TVTEditChangingEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    var Allowed: Boolean) of object;
-  TVTEditChangeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex) of object;
-  TVTFreeNodeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode) of object;
-  TVTFocusChangingEvent = procedure(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode; OldColumn,
-    NewColumn: TColumnIndex; var Allowed: Boolean) of object;
-  TVTFocusChangeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex) of object;
-  TVTGetImageEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
-    var Ghosted: Boolean; var ImageIndex: Integer) of object;
-  TVTGetImageExEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
-    var Ghosted: Boolean; var ImageIndex: Integer; var ImageList: TCustomImageList) of object;
-  TVTGetImageTextEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
-    var ImageText: String) of object;
-  TVTHotNodeChangeEvent = procedure(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode) of object;
-  TVTInitChildrenEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal) of object;
-  TVTInitNodeEvent = procedure(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
-    var InitialStates: TVirtualNodeInitStates) of object;
-  TVTPopupEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; const P: TPoint;
-    var AskParent: Boolean; var PopupMenu: TPopupMenu) of object;
-  TVTHelpContextEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    var HelpContext: Integer) of object;
-  TVTCreateEditorEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    out EditLink: IVTEditLink) of object;
-  TVTSaveNodeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream) of object;
-
-  // header/column events
-  TVTHeaderClickEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X,
-    Y: Integer) of object;
-  TVTHeaderMouseEvent = procedure(Sender: TVTHeader; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) of object;
-  TVTHeaderMouseMoveEvent = procedure(Sender: TVTHeader; Shift: TShiftState; X, Y: Integer) of object;
-  TVTBeforeHeaderHeightTrackingEvent = procedure(Sender: TVTHeader; Shift: TShiftState) of object;
-  TVTAfterHeaderHeightTrackingEvent = procedure(Sender: TVTHeader) of object;
-  TVTHeaderHeightTrackingEvent = procedure(Sender: TVTHeader; var P: TPoint; Shift: TShiftState; var Allowed: Boolean) of object;
-  TVTHeaderHeightDblClickResizeEvent = procedure(Sender: TVTHeader; var P: TPoint; Shift: TShiftState; var Allowed: Boolean) of object;
-  TVTHeaderNotifyEvent = procedure(Sender: TVTHeader; Column: TColumnIndex) of object;
-  TVTHeaderDraggingEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; var Allowed: Boolean) of object;
-  TVTHeaderDraggedEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; OldPosition: Integer) of object;
-  TVTHeaderDraggedOutEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; const DropPosition: TPoint) of object;
-  TVTHeaderPaintEvent = procedure(Sender: TVTHeader; HeaderCanvas: TCanvas; Column: TVirtualTreeColumn; const R: TRect; Hover,
-    Pressed: Boolean; DropMark: TVTDropMarkMode) of object;
-  TVTHeaderPaintQueryElementsEvent = procedure(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
-    var Elements: THeaderPaintElements) of object;
-  TVTAdvancedHeaderPaintEvent = procedure(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
-    const Elements: THeaderPaintElements) of object;
-  TVTBeforeAutoFitColumnsEvent = procedure(Sender: TVTHeader; var SmartAutoFitType: TSmartAutoFitType) of object;
-  TVTBeforeAutoFitColumnEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; var SmartAutoFitType: TSmartAutoFitType;
-    var Allowed: Boolean) of object;
-  TVTAfterAutoFitColumnEvent = procedure(Sender: TVTHeader; Column: TColumnIndex) of object;
-  TVTAfterAutoFitColumnsEvent = procedure(Sender: TVTHeader) of object;
-  TVTColumnClickEvent = procedure (Sender: TBaseVirtualTree; Column: TColumnIndex; Shift: TShiftState) of object;
-  TVTColumnDblClickEvent = procedure (Sender: TBaseVirtualTree; Column: TColumnIndex; Shift: TShiftState) of object;
-  TVTColumnWidthDblClickResizeEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; Shift: TShiftState; P: TPoint;
-    var Allowed: Boolean) of object;
-  TVTBeforeColumnWidthTrackingEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; Shift: TShiftState) of object;
-  TVTAfterColumnWidthTrackingEvent = procedure(Sender: TVTHeader; Column: TColumnIndex) of object;
-  TVTColumnWidthTrackingEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint;
-    var Allowed: Boolean) of object;
-  TVTGetHeaderCursorEvent = procedure(Sender: TVTHeader; var Cursor: HCURSOR) of object;
-  TVTBeforeGetMaxColumnWidthEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; var UseSmartColumnWidth: Boolean) of object;
-  TVTAfterGetMaxColumnWidthEvent = procedure(Sender: TVTHeader; Column: TColumnIndex; var MaxWidth: Integer) of object;
-  TVTCanSplitterResizeColumnEvent = procedure(Sender: TVTHeader; P: TPoint; Column: TColumnIndex; var Allowed: Boolean) of object;
-
-  // move, copy and node tracking events
-  TVTNodeMovedEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode) of object;
-  TVTNodeMovingEvent = procedure(Sender: TBaseVirtualTree; Node, Target: PVirtualNode;
-    var Allowed: Boolean) of object;
-  TVTNodeCopiedEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode) of object;
-  TVTNodeCopyingEvent = procedure(Sender: TBaseVirtualTree; Node, Target: PVirtualNode;
-    var Allowed: Boolean) of object;
-  TVTNodeHeightTrackingEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState;
-    var TrackPoint: TPoint; P: TPoint; var Allowed: Boolean) of object;
-  TVTNodeHeightDblClickResizeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    Shift: TShiftState; P: TPoint; var Allowed: Boolean) of object;
-
-  // drag'n drop/OLE events
-  TVTCreateDragManagerEvent = procedure(Sender: TBaseVirtualTree; out DragManager: IVTDragManager) of object;
-  TVTCreateDataObjectEvent = procedure(Sender: TBaseVirtualTree; out IDataObject: IDataObject) of object;
-  TVTDragAllowedEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    var Allowed: Boolean) of object;
-  TVTDragOverEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState;
-    const Pt: TPoint; Mode: TDropMode; var Effect: LongWord; var Accept: Boolean) of object;
-  TVTDragDropEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; {DataObject: IDataObject;}
-    Formats: TFormatArray; Shift: TShiftState; const Pt: TPoint; var Effect: LongWord; Mode: TDropMode) of object;
-  TVTRenderOLEDataEvent = procedure(Sender: TBaseVirtualTree; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-    ForClipboard: Boolean; var Result: HRESULT) of object;
-  TVTGetUserClipboardFormatsEvent = procedure(Sender: TBaseVirtualTree; var Formats: TFormatEtcArray) of object;
-
-  // paint events
-  TVTBeforeItemEraseEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect;
-    var ItemColor: TColor; var EraseAction: TItemEraseAction) of object;
-  TVTAfterItemEraseEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    const ItemRect: TRect) of object;
-  TVTBeforeItemPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    const ItemRect: TRect; var CustomDraw: Boolean) of object;
-  TVTAfterItemPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    const ItemRect: TRect) of object;
-  TVTBeforeCellPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect) of object;
-  TVTAfterCellPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    Column: TColumnIndex; const CellRect: TRect) of object;
-  TVTPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas) of object;
-  TVTBackgroundPaintEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; const R: TRect;
-    var Handled: Boolean) of object;
-  TVTGetLineStyleEvent = procedure(Sender: TBaseVirtualTree; var Bits: Pointer) of object;
-  TVTMeasureItemEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    var NodeHeight: Integer) of object;
-
-  // search, sort
-  TVTCompareEvent = procedure(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex;
-    var Result: Integer) of object;
- TVTIncrementalSearchEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; const SearchText: String;
-    var Result: Integer) of object;
-
-  // miscellaneous
-  TVTGetNodeDataSizeEvent = procedure(Sender: TBaseVirtualTree; var NodeDataSize: Integer) of object;
-  TVTKeyActionEvent = procedure(Sender: TBaseVirtualTree; var CharCode: Word; var Shift: TShiftState;
-    var DoDefault: Boolean) of object;
-  TVTScrollEvent = procedure(Sender: TBaseVirtualTree; DeltaX, DeltaY: Integer) of object;
-  TVTUpdatingEvent = procedure(Sender: TBaseVirtualTree; State: TVTUpdateState) of object;
-  TVTGetCursorEvent = procedure(Sender: TBaseVirtualTree; var Cursor: TCursor) of object;
-  TVTStateChangeEvent = procedure(Sender: TBaseVirtualTree; Enter, Leave: TVirtualTreeStates) of object;
-  TVTGetCellIsEmptyEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    var IsEmpty: Boolean) of object;
-  TVTScrollbarShowEvent = procedure(Sender: TBaseVirtualTree; Bar: Integer; Show: Boolean) of object;
-
-  // Helper types for node iterations.
-  TGetFirstNodeProc = function: PVirtualNode of object;
-  TGetNextNodeProc = function(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode of object;
-
-  // ----- TBaseVirtualTree
-  TBaseVirtualTree = class(TCustomControl)
-  private
-    //FBorderStyle: TBorderStyle;
-    FHeader: TVTHeader;
-    FRoot: PVirtualNode;
-    FDefaultNodeHeight,
-    FIndent: Cardinal;
-    FOptions: TCustomVirtualTreeOptions;
-    FUpdateCount: Cardinal;                      // update stopper, updates of the tree control are only done if = 0
-    FSynchUpdateCount: Cardinal;                 // synchronizer, causes all events which are usually done via timers
-                                                 // to happen immediately, regardless of the normal update state
-    FNodeDataSize: Integer;                      // number of bytes to allocate with each node (in addition to its base
-                                                 // structure and the internal data), if -1 then do callback
-    FStates: TVirtualTreeStates;                 // various active/pending states the tree needs to consider
-    FLastSelected,
-    FFocusedNode: PVirtualNode;
-    FEditColumn,                                 // column to be edited (focused node)
-    FFocusedColumn: TColumnIndex;                // NoColumn if no columns are active otherwise the last hit column of
-                                                 // the currently focused node
-    FHeightTrackPoint: TPoint;                   // Starting point of a node's height changing operation.
-    FHeightTrackNode: PVirtualNode;              // Node which height is being changed.
-    FHeightTrackColumn: TColumnIndex;            // Initial column where the height changing operation takes place.
-    FScrollDirections: TScrollDirections;        // directions to scroll client area into depending on mouse position
-    FLastStructureChangeReason: TChangeReason;   // Used for delayed structure change event.
-    FLastStructureChangeNode,                    // dito
-    FLastChangedNode,                            // used for delayed change event
-    FCurrentHotNode: PVirtualNode;               // Node over which the mouse is hovering.
-    FCurrentHotColumn: TColumnIndex;             // Column over which the mouse is hovering.
-    FHotNodeButtonHit: Boolean;                  // Indicates wether the mouse is hovering over the hot node's button.
-    FLastSelRect,
-    FNewSelRect: TRect;                          // used while doing draw selection
-    FHotCursor: TCursor;                         // can be set to additionally indicate the current hot node
-    FHintMode: TVTHintMode;                      // determines the kind of the hint window
-    FHintData: TVTHintData;                      // used while preparing the hint window
-    FChangeDelay: Cardinal;                      // used to delay OnChange event
-    FEditDelay: Cardinal;                        // determines time to elapse before a node goes into edit mode
-    FPositionCache: TCache;                      // array which stores node references ordered by vertical positions
-                                                 // (see also DoValidateCache for more information)
-    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
-    FCheckNode: PVirtualNode;                    // node which "captures" a check event
-    FPendingCheckState: TCheckState;             // the new state the check node will get if all went fine
-    FCheckPropagationCount: Cardinal;            // nesting level of check propagation (WL, 05.02.2004)
-    FLastSelectionLevel: Integer;                // keeps the last node level for constrained multiselection
-    FDrawSelShiftState: TShiftState;             // keeps the initial shift state when the user starts selection with
-                                                 // the mouse
-    FEditLink: IVTEditLink;                      // used to comunicate with an application defined editor
-    FTempNodeCache: TNodeArray;                  // used at various places to hold temporarily a bunch of node refs.
-    FTempNodeCount: Cardinal;                    // number of nodes in FTempNodeCache
-    FBackground: TPicture;                       // A background image loadable at design and runtime.
-    FMargin: Integer;                            // horizontal border distance
-    FTextMargin: Integer;                        // space between the node's text and its horizontal bounds
-    FBackgroundOffsetX,
-    FBackgroundOffsetY: Integer;                 // used to fine tune the position of the background image
-    FAnimationDuration: Cardinal;                // specifies how long an animation shall take (expanding, hint)
-    FWantTabs: Boolean;                          // If True then the tree also consumes the tab key.
-    FNodeAlignment: TVTNodeAlignment;            // determines how to interpret the align member of a node
-    FHeaderRect: TRect;                          // Space which the header currently uses in the control (window coords).
-    FLastHintRect: TRect;                        // Area which the mouse must leave to reshow a hint.
-    FUpdateRect: TRect;
-
-    // paint support and images
-    FPlusBM,
-    FMinusBM,                                    // small bitmaps used for tree buttons
-    FHotPlusBM,
-    FHotMinusBM: TBitmap;                        // small bitmaps used for hot tree buttons 
-    FImages,                                     // normal images in the tree
-    FStateImages: TCustomImageList;              // state images in the tree
-    FCustomCheckImages: TBitmap;                 // application defined check images
-    FCheckImageKind: TCheckImageKind;            // light or dark, cross marks or tick marks
-    FCheckImages: TBitmap;                       // Reference to global image list to be used for the check images.
-    FImageChangeLink,
-    FStateChangeLink,
-    FCustomCheckChangeLink: TChangeLink;         // connections to the image lists
-    FOldFontChange: TNotifyEvent;                // helper method pointer for tracking font changes in the off screen buffer
-    FFontChanged: Boolean;                       // flag for keeping informed about font changes in the off screen buffer
-    FColors: TVTColors;                          // class comprising all customizable colors in the tree
-    FButtonStyle: TVTButtonStyle;                // style of the tree buttons
-    FButtonFillMode: TVTButtonFillMode;          // for rectangular tree buttons only: how to fill them
-    FLineStyle: TVTLineStyle;                    // style of the tree lines
-    FLineMode: TVTLineMode;                      // tree lines or bands etc.
-    FDottedBrush: HBRUSH;                        // used to paint dotted lines without special pens
-    FSelectionCurveRadius: Cardinal;             // radius for rounded selection rectangles
-    FSelectionBlendFactor: Byte;                 // Determines the factor by which the selection rectangle is to be
-                                                 // faded if enabled.
-    FDrawSelectionMode: TVTDrawSelectionMode;    // determines the paint mode for draw selection
-
-    // alignment and directionality support
-    FAlignment: TAlignment;                      // default alignment of the tree if no columns are shown
-
-    // drag'n drop and clipboard support
-    FDragImageKind: TVTDragImageKind;            // determines whether or not and what to show in the drag image
-    FDragOperations: TDragOperations;            // determines which operations are allowed during drag'n drop
-    FDragThreshold: Integer;                     // used to determine when to actually start a drag'n drop operation
-    FDragManager: IVTDragManager;                // drag'n drop, cut'n paste
-    FDropTargetNode: PVirtualNode;               // node currently selected as drop target
-    FLastDropMode: TDropMode;                    // set while dragging and used to track changes
-    FDragSelection: TNodeArray;                  // temporary copy of FSelection used during drag'n drop
-    FDragType: TVTDragType;                      // used to switch between OLE and VCL drag'n drop
-    FDragImage: TVTDragImage;                    // drag image management
-    FDragWidth,
-    FDragHeight: Integer;                        // size of the drag image, the larger the more CPU power is needed
-    FClipboardFormats: TClipboardFormats;        // a list of clipboard format descriptions enabled for this tree
-    FLastVCLDragTarget: PVirtualNode;            // A node cache for VCL drag'n drop (keywords: DragLeave on DragDrop).
-    FVCLDragEffect: LongWord;                     // A cache for VCL drag'n drop to keep the current drop effect.
-
-    // scroll support
-    FScrollBarOptions: TScrollBarOptions;        // common properties of horizontal and vertical scrollbar
-    FAutoScrollInterval: TAutoScrollInterval;    // determines speed of auto scrolling
-    FAutoScrollDelay: Cardinal;                  // amount of milliseconds to wait until autoscrolling becomes active
-    FAutoExpandDelay: Cardinal;                  // amount of milliseconds to wait until a node is expanded if it is the
-                                                 // drop target
-    FOffsetX: Integer;
-    FOffsetY: Integer;                           // Determines left and top scroll offset.
-    FEffectiveOffsetX: Integer;                  // Actual position of the horizontal scroll bar (varies depending on bidi mode).
-    FRangeX,
-    FRangeY: Cardinal;                           // current virtual width and height of the tree
-    FBottomSpace: Cardinal;                      // Extra space below the last node.
-
-    FDefaultPasteMode: TVTNodeAttachMode;        // Used to determine where to add pasted nodes to.
-    FSingletonNodeArray: TNodeArray;             // Contains only one element for quick addition of single nodes
-                                                 // to the selection.
-    FDragScrollStart: Cardinal;                  // Contains the start time when a tree does auto scrolling as drop target.
-
-    // search
-    FIncrementalSearch: TVTIncrementalSearch;    // Used to determine whether and how incremental search is to be used.
-    FSearchTimeout: Cardinal;                    // Number of milliseconds after which to stop incremental searching.
-    FSearchBuffer: String;                 // Collects a sequence of keypresses used to do incremental searching.
-    FLastSearchNode: PVirtualNode;               // Reference to node which was last found as search fit.
-    FSearchDirection: TVTSearchDirection;        // Direction to incrementally search the tree.
-    FSearchStart: TVTSearchStart;                // Where to start iteration on each key press.
-
-    // miscellanous
-    FTotalInternalDataSize: Cardinal;            // Cache of the sum of the necessary internal data size for all tree
-                                                 // classes derived from this base class.
-    FPanningWindow: TVirtualPanningWindow;       // Helper window for wheel panning
-    FLastClickPos: TPoint;                       // Used for retained drag start and wheel mouse scrolling.
-    FOperationCount: Cardinal;                   // Counts how many nested long-running operations are in progress.
-    FOperationCanceled: Boolean;                 // Used to indicate that a long-running operation should be canceled.
-
-    {$ifdef EnableAccessible}
-    // MSAA support
-    FAccessible: IAccessible;                    // The IAccessible interface to the window itself.
-    FAccessibleItem: IAccessible;                // The IAccessible to the item that currently has focus.
-    FAccessibleName: string;                     // The name the window is given for screen readers.
-    {$endif}
-    // export
-    FOnBeforeNodeExport: TVTNodeExportEvent;     // called before exporting a node
-    FOnNodeExport: TVTNodeExportEvent;
-    FOnAfterNodeExport: TVTNodeExportEvent;      // called after exporting a node
-    FOnBeforeColumnExport: TVTColumnExportEvent; // called before exporting a column
-    FOnColumnExport: TVTColumnExportEvent;
-    FOnAfterColumnExport: TVTColumnExportEvent;  // called after  exporting a column
-    FOnBeforeTreeExport: TVTTreeExportEvent;     // called before starting the export
-    FOnAfterTreeExport: TVTTreeExportEvent;      // called after finishing the export
-    FOnBeforeHeaderExport: TVTTreeExportEvent;   // called before exporting the header
-    FOnAfterHeaderExport: TVTTreeExportEvent;    // called after exporting the header
-
-    // common events
-    FOnChange: TVTChangeEvent;                   // selection change
-    FOnStructureChange: TVTStructureChangeEvent; // structural change like adding nodes etc.
-    FOnInitChildren: TVTInitChildrenEvent;       // called when a node's children are needed (expanding etc.)
-    FOnInitNode: TVTInitNodeEvent;               // called when a node needs to be initialized (child count etc.)
-    FOnFreeNode: TVTFreeNodeEvent;               // called when a node is about to be destroyed, user data can and should
-                                                 // be freed in this event
-    FOnGetImage: TVTGetImageEvent;               // Used to retrieve the image index of a given node.
-    FOnGetImageEx: TVTGetImageExEvent;           // Used to retrieve the image index of a given node along with a custom
-                                                 // image list.
-    FOnGetImageText: TVTGetImageTextEvent;               // Used to retrieve the image alternative text of a given node.
-                                                         // Used by the accessibility interface to provide useful text for status images.
-    FOnHotChange: TVTHotNodeChangeEvent;         // called when the current "hot" node (that is, the node under the mouse)
-                                                 // changes and hot tracking is enabled
-    FOnExpanding,                                // called just before a node is expanded
-    FOnCollapsing: TVTChangingEvent;             // called just before a node is collapsed
-    FOnChecking: TVTCheckChangingEvent;          // called just before a node's check state is changed
-    FOnExpanded,                                 // called after a node has been expanded
-    FOnCollapsed,                                // called after a node has been collapsed
-    FOnChecked: TVTChangeEvent;                  // called after a node's check state has been changed
-    FOnResetNode: TVTChangeEvent;                // called when a node is set to be uninitialized
-    FOnNodeMoving: TVTNodeMovingEvent;           // called just before a node is moved from one parent node to another
-                                                 // (this can be cancelled)
-    FOnNodeMoved: TVTNodeMovedEvent;             // called after a node and its children have been moved to another
-                                                 // parent node (probably another tree, but within the same application)
-    FOnNodeCopying: TVTNodeCopyingEvent;         // called when an node is copied to another parent node (probably in
-                                                 // another tree, but within the same application, can be cancelled)
-    FOnNodeHeightTracking: TVTNodeHeightTrackingEvent;             // called when a node's height is being changed via mouse
-    FOnNodeHeightDblClickResize: TVTNodeHeightDblClickResizeEvent; // called when a node's vertical splitter is double clicked
-    FOnNodeCopied: TVTNodeCopiedEvent;           // call after a node has been copied
-    FOnEditing: TVTEditChangingEvent;            // called just before a node goes into edit mode
-    FOnEditCancelled: TVTEditCancelEvent;        // called when editing has been cancelled
-    FOnEdited: TVTEditChangeEvent;               // called when editing has successfully been finished
-    FOnFocusChanging: TVTFocusChangingEvent;     // called when the focus is about to go to a new node and/or column
-                                                 // (can be cancelled)
-    FOnFocusChanged: TVTFocusChangeEvent;        // called when the focus goes to a new node and/or column
-    FOnGetPopupMenu: TVTPopupEvent;              // called when the popup for a node or the header needs to be shown
-    FOnGetHelpContext: TVTHelpContextEvent;      // called when a node specific help theme should be called
-    FOnCreateEditor: TVTCreateEditorEvent;       // called when a node goes into edit mode, this allows applications
-                                                 // to supply their own editor
-    FOnLoadNode,                                 // called after a node has been loaded from a stream (file, clipboard,
-                                                 // OLE drag'n drop) to allow an application to load their own data
-                                                 // saved in OnSaveNode
-    FOnSaveNode: TVTSaveNodeEvent;               // called when a node needs to be serialized into a stream
-                                                 // (see OnLoadNode) to give the application the opportunity to save
-                                                 // their node specific, persistent data (note: never save memory
-                                                 // references)
-
-    // header/column mouse events
-    FOnAfterAutoFitColumn: TVTAfterAutoFitColumnEvent;
-    FOnAfterAutoFitColumns: TVTAfterAutoFitColumnsEvent;
-    FOnBeforeAutoFitColumns: TVTBeforeAutoFitColumnsEvent;
-    FOnBeforeAutoFitColumn: TVTBeforeAutoFitColumnEvent;
-    FOnHeaderClick,                              // mouse events for the header, just like those for a control
-    FOnHeaderImageClick,
-    FOnHeaderCheckBoxClick: TVTHeaderClickEvent;
-    FOnHeaderDblClick: TVTHeaderClickEvent;
-    FOnAfterHeaderHeightTracking: TVTAfterHeaderHeightTrackingEvent;
-    FOnBeforeHeaderHeightTracking: TVTBeforeHeaderHeightTrackingEvent;
-    FOnHeaderHeightTracking: TVTHeaderHeightTrackingEvent;
-    FOnHeaderHeightDblClickResize: TVTHeaderHeightDblClickResizeEvent;
-    FOnHeaderMouseDown,
-    FOnHeaderMouseUp: TVTHeaderMouseEvent;
-    FOnHeaderMouseMove: TVTHeaderMouseMoveEvent;
-    FOnAfterGetMaxColumnWidth: TVTAfterGetMaxColumnWidthEvent;
-    FOnBeforeGetMaxColumnWidth: TVTBeforeGetMaxColumnWidthEvent;
-    FOnColumnClick: TVTColumnClickEvent;
-    FOnColumnDblClick: TVTColumnDblClickEvent;
-    FOnColumnResize: TVTHeaderNotifyEvent;
-    FOnColumnWidthDblClickResize: TVTColumnWidthDblClickResizeEvent;
-    FOnAfterColumnWidthTracking: TVTAfterColumnWidthTrackingEvent;
-    FOnBeforeColumnWidthTracking: TVTBeforeColumnWidthTrackingEvent;
-    FOnColumnWidthTracking: TVTColumnWidthTrackingEvent;
-    FOnGetHeaderCursor: TVTGetHeaderCursorEvent; // triggered to allow the app. to use customized cursors for the header
-    FOnCanSplitterResizeColumn: TVTCanSplitterResizeColumnEvent;
-
-    // paint events
-    FOnAfterPaint,                               // triggered when the tree has entirely been painted
-    FOnBeforePaint: TVTPaintEvent;               // triggered when the tree is about to be painted
-    FOnAfterItemPaint: TVTAfterItemPaintEvent;   // triggered after an item has been painted
-    FOnBeforeItemPaint: TVTBeforeItemPaintEvent; // triggered when an item is about to be painted
-    FOnBeforeItemErase: TVTBeforeItemEraseEvent; // triggered when an item's background is about to be erased
-    FOnAfterItemErase: TVTAfterItemEraseEvent;   // triggered after an item's background has been erased
-    FOnAfterCellPaint: TVTAfterCellPaintEvent;   // triggered after a column of an item has been painted
-    FOnBeforeCellPaint: TVTBeforeCellPaintEvent; // triggered when a column of an item is about to be painted
-    FOnHeaderDraw: TVTHeaderPaintEvent;          // Used when owner draw is enabled for the header and a column is set
-                                                 // to owner draw mode.
-    FOnHeaderDrawQueryElements: TVTHeaderPaintQueryElementsEvent; // Used for advanced header painting to query the
-                                                 // application for the elements, which are drawn by it and which should
-                                                 // be drawn by the tree.
-    FOnAdvancedHeaderDraw: TVTAdvancedHeaderPaintEvent; // Used when owner draw is enabled for the header and a column
-                                                 // is set to owner draw mode. But only if OnHeaderDrawQueryElements
-                                                 // returns at least one element to be drawn by the application.
-                                                 // In this case OnHeaderDraw is not used.
-    FOnGetLineStyle: TVTGetLineStyleEvent;       // triggered when a custom line style is used and the pattern brush
-                                                 // needs to be build
-    FOnPaintBackground: TVTBackgroundPaintEvent; // triggered if a part of the tree's background must be erased which is
-                                                 // not covered by any node
-    FOnMeasureItem: TVTMeasureItemEvent;         // Triggered when a node is about to be drawn and its height was not yet
-                                                 // determined by the application.
-
-    // drag'n drop events
-    FOnCreateDragManager: TVTCreateDragManagerEvent; // called to allow for app./descendant defined drag managers
-    FOnCreateDataObject: TVTCreateDataObjectEvent; // called to allow for app./descendant defined data objects
-    FOnDragAllowed: TVTDragAllowedEvent;         // used to get permission for manual drag in mouse down
-    FOnDragOver: TVTDragOverEvent;               // called for every mouse move
-    FOnDragDrop: TVTDragDropEvent;               // called on release of mouse button (if drop was allowed)
-    FOnHeaderDragged: TVTHeaderDraggedEvent;     // header (column) drag'n drop
-    FOnHeaderDraggedOut: TVTHeaderDraggedOutEvent; // header (column) drag'n drop, which did not result in a valid drop.
-    FOnHeaderDragging: TVTHeaderDraggingEvent;   // header (column) drag'n drop
-    FOnRenderOLEData: TVTRenderOLEDataEvent;     // application/descendant defined clipboard formats
-    FOnGetUserClipboardFormats: TVTGetUserClipboardFormatsEvent; // gives application/descendants the opportunity to
-                                                 // add own clipboard formats on the fly
-
-    // miscellanous events
-    FOnGetNodeDataSize: TVTGetNodeDataSizeEvent; // Called if NodeDataSize is -1.
-    FOnKeyAction: TVTKeyActionEvent;             // Used to selectively prevent key actions (full expand on Ctrl+'+' etc.).
-    FOnScroll: TVTScrollEvent;                   // Called when one or both paint offsets changed.
-    FOnUpdating: TVTUpdatingEvent;               // Called from BeginUpdate, EndUpdate, BeginSynch and EndSynch.
-    FOnGetCursor: TVTGetCursorEvent;             // Called to allow the app. to set individual cursors.
-    FOnStateChange: TVTStateChangeEvent;         // Called whenever a state in the tree changes.
-    FOnGetCellIsEmpty: TVTGetCellIsEmptyEvent;   // Called when the tree needs to know if a cell is empty.
-    FOnShowScrollbar: TVTScrollbarShowEvent;     // Called when a scrollbar is changed in its visibility.
-
-    // search, sort
-    FOnCompareNodes: TVTCompareEvent;            // used during sort
-    FOnIncrementalSearch: TVTIncrementalSearchEvent; // triggered on every key press (not key down)
-
-    procedure AdjustCoordinatesByIndent(var PaintInfo: TVTPaintInfo; Indent: Integer);
-    procedure AdjustImageBorder(ImageWidth, ImageHeight: Integer; BidiMode: TBidiMode; VAlign: Integer; var R: TRect;
-      var ImageInfo: TVTImageInfo);
-    procedure AdjustTotalCount(Node: PVirtualNode; Value: Integer; Relative: Boolean = False);
-    procedure AdjustTotalHeight(Node: PVirtualNode; Value: Integer; Relative: Boolean = False);
-    function CalculateCacheEntryCount: Integer;
-    procedure CalculateVerticalAlignments(ShowImages, ShowStateImages: Boolean; Node: PVirtualNode; out VAlign,
-      VButtonAlign: Integer);
-    function ChangeCheckState(Node: PVirtualNode; Value: TCheckState): Boolean;
-    function CollectSelectedNodesLTR(MainColumn, NodeLeft, NodeRight: Integer; Alignment: TAlignment; OldRect: TRect;
-      const NewRect: TRect): Boolean;
-    function CollectSelectedNodesRTL(MainColumn, NodeLeft, NodeRight: Integer; Alignment: TAlignment; OldRect: TRect;
-      const NewRect: TRect): Boolean;
-    procedure ClearNodeBackground(const PaintInfo: TVTPaintInfo; UseBackground, Floating: Boolean; R: TRect);
-    function CompareNodePositions(Node1, Node2: PVirtualNode; ConsiderChildrenAbove: Boolean = False): Integer;
-    function DetermineLineImageAndSelectLevel(Node: PVirtualNode; out LineImage: TLineImage): Integer;
-    procedure DrawLineImage(const PaintInfo: TVTPaintInfo; X, Y, H, VAlign: Integer; Style: TVTLineType; Reverse: Boolean);
-    function FindInPositionCache(Node: PVirtualNode; var CurrentPos: Cardinal): PVirtualNode; overload;
-    function FindInPositionCache(Position: Cardinal; var CurrentPos: Cardinal): PVirtualNode; overload;
-    procedure FixupTotalCount(Node: PVirtualNode);
-    procedure FixupTotalHeight(Node: PVirtualNode);
-    function GetBottomNode: PVirtualNode;
-    function GetCheckedCount: Integer;
-    function GetCheckState(Node: PVirtualNode): TCheckState;
-    function GetCheckType(Node: PVirtualNode): TCheckType;
-    function GetChildCount(Node: PVirtualNode): Cardinal;
-    function GetChildrenInitialized(Node: PVirtualNode): Boolean;
-    function GetCutCopyCount: Integer;
-    function GetDisabled(Node: PVirtualNode): Boolean;
-    function GetDragManager: IVTDragManager;
-    function GetExpanded(Node: PVirtualNode): Boolean;
-    function GetFullyVisible(Node: PVirtualNode): Boolean;
-    function GetHasChildren(Node: PVirtualNode): Boolean;
-    function GetMultiline(Node: PVirtualNode): Boolean;
-    function GetNodeHeight(Node: PVirtualNode): Cardinal;
-    function GetNodeParent(Node: PVirtualNode): PVirtualNode;
-    function GetOffsetXY: TPoint;
-    function GetRootNodeCount: Cardinal;
-    function GetSelected(Node: PVirtualNode): Boolean;
-    function GetTopNode: PVirtualNode;
-    function GetTotalCount: Cardinal;
-    function GetVerticalAlignment(Node: PVirtualNode): Byte;
-    function GetVisible(Node: PVirtualNode): Boolean;
-    function GetVisiblePath(Node: PVirtualNode): Boolean;
-    procedure HandleClickSelection(LastFocused, NewNode: PVirtualNode; Shift: TShiftState; DragPending: Boolean);
-    function HandleDrawSelection(X, Y: Integer): Boolean;
-    function HasVisibleNextSibling(Node: PVirtualNode): Boolean;
-    function HasVisiblePreviousSibling(Node: PVirtualNode): Boolean;
-    procedure ImageListChange(Sender: TObject);
-    procedure InitializeFirstColumnValues(var PaintInfo: TVTPaintInfo);
-    procedure InitRootNode(OldSize: Cardinal = 0);
-    procedure InterruptValidation;
-    function IsFirstVisibleChild(Parent, Node: PVirtualNode): Boolean;
-    function IsLastVisibleChild(Parent, Node: PVirtualNode): Boolean;
-    procedure LimitPaintingToArea(Canvas: TCanvas; ClipRect: TRect; VisibleRegion: HRGN = 0);
-    //lcl
-    procedure LoadPanningCursors;
-    function MakeNewNode: PVirtualNode;
-    {$ifdef PACKARRAYPASCAL}
-    function PackArray(const TheArray: TNodeArray; Count: Integer): Integer;
-    {$else}
-    function PackArray(TheArray: TNodeArray; Count: Integer): Integer;
-    {$endif}
-    procedure PrepareBitmaps(NeedButtons, NeedLines: Boolean);
-    procedure SetAlignment(const Value: TAlignment);
-    procedure SetAnimationDuration(const Value: Cardinal);
-    procedure SetBackground(const Value: TPicture);
-    procedure SetBackgroundOffset(const Index, Value: Integer);
-    procedure SetBottomNode(Node: PVirtualNode);
-    procedure SetBottomSpace(const Value: Cardinal);
-    procedure SetButtonFillMode(const Value: TVTButtonFillMode);
-    procedure SetButtonStyle(const Value: TVTButtonStyle);
-    procedure SetCheckImageKind(Value: TCheckImageKind);
-    procedure SetCheckState(Node: PVirtualNode; Value: TCheckState);
-    procedure SetCheckType(Node: PVirtualNode; Value: TCheckType);
-    procedure SetChildCount(Node: PVirtualNode; NewChildCount: Cardinal);
-    procedure SetClipboardFormats(const Value: TClipboardFormats);
-    procedure SetColors(const Value: TVTColors);
-    procedure SetCustomCheckImages(const Value: TBitmap);
-    procedure SetDefaultNodeHeight(Value: Cardinal);
-    procedure SetDisabled(Node: PVirtualNode; Value: Boolean);
-    procedure SetExpanded(Node: PVirtualNode; Value: Boolean);
-    procedure SetFocusedColumn(Value: TColumnIndex);
-    procedure SetFocusedNode(Value: PVirtualNode);
-    procedure SetFullyVisible(Node: PVirtualNode; Value: Boolean);
-    procedure SetHasChildren(Node: PVirtualNode; Value: Boolean);
-    procedure SetHeader(const Value: TVTHeader);
-    procedure SetImages(const Value: TCustomImageList);
-    procedure SetIndent(Value: Cardinal);
-    procedure SetLineMode(const Value: TVTLineMode);
-    procedure SetLineStyle(const Value: TVTLineStyle);
-    procedure SetMargin(Value: Integer);
-    procedure SetMultiline(Node: PVirtualNode; const Value: Boolean);
-    procedure SetNodeAlignment(const Value: TVTNodeAlignment);
-    procedure SetNodeDataSize(Value: Integer);
-    procedure SetNodeHeight(Node: PVirtualNode; Value: Cardinal);
-    procedure SetNodeParent(Node: PVirtualNode; const Value: PVirtualNode);
-    procedure SetOffsetX(const Value: Integer);
-    procedure SetOffsetXY(const Value: TPoint);
-    procedure SetOffsetY(const Value: Integer);
-    procedure SetOptions(const Value: TCustomVirtualTreeOptions);
-    procedure SetRootNodeCount(Value: Cardinal);
-    procedure SetScrollBarOptions(Value: TScrollBarOptions);
-    procedure SetSearchOption(const Value: TVTIncrementalSearch);
-    procedure SetSelected(Node: PVirtualNode; Value: Boolean);
-    procedure SetSelectionCurveRadius(const Value: Cardinal);
-    procedure SetStateImages(const Value: TCustomImageList);
-    procedure SetTextMargin(Value: Integer);
-    procedure SetTopNode(Node: PVirtualNode);
-    procedure SetUpdateState(Updating: Boolean);
-    procedure SetVerticalAlignment(Node: PVirtualNode; Value: Byte);
-    procedure SetVisible(Node: PVirtualNode; Value: Boolean);
-    procedure SetVisiblePath(Node: PVirtualNode; Value: Boolean);
-    procedure StaticBackground(Source: TBitmap; Target: TCanvas; const Offset: TPoint; const R: TRect);
-    procedure TileBackground(Source: TBitmap; Target: TCanvas; const Offset: TPoint; R: TRect);
-    function ToggleCallback(Step, StepSize: Integer; Data: Pointer): Boolean;
-  protected
-    procedure CMColorChange(var Message: TLMessage); message CM_COLORCHANGED;
-    procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED;
-    procedure CMDenySubclassing(var Message: TLMessage); message CM_DENYSUBCLASSING;
-    //procedure CMDrag(var Message: TCMDrag); message CM_DRAG;
-    procedure CMFontChanged(var Message: TLMessage); message CM_FONTCHANGED;
-    procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
-    procedure CMMouseLeave(var Message: TLMessage); message CM_MOUSELEAVE;
-    procedure CMMouseWheel(var Message: TLMMouseEvent); message LM_MOUSEWHEEL;
-    {$ifdef EnableNativeTVM}
-    procedure TVMGetItem(var Message: TLMessage); message TVM_GETITEM;
-    procedure TVMGetItemRect(var Message: TLMessage); message TVM_GETITEMRECT;
-    procedure TVMGetNextItem(var Message: TLMessage); message TVM_GETNEXTITEM;
-    {$endif}
-    procedure WMCancelMode(var Message: TLMNoParams); message LM_CANCELMODE;
-    procedure WMChangeState(var Message: TLMessage); message WM_CHANGESTATE;
-    procedure WMChar(var Message: TLMChar); message LM_CHAR;
-    procedure WMContextMenu(var Message: TLMContextMenu); message LM_CONTEXTMENU;
-    procedure WMCopy(var Message: TLMNoParams); message LM_COPY;
-    procedure WMCut(var Message: TLMNoParams); message LM_CUT;
-    procedure WMEnable(var Message: TLMNoParams); message LM_ENABLE;
-    procedure WMEraseBkgnd(var Message: TLMEraseBkgnd); message LM_ERASEBKGND;
-    procedure WMGetDlgCode(var Message: TLMNoParams); message LM_GETDLGCODE;
-    {$ifdef EnableAccessible}
-    procedure WMGetObject(var Message: TLMessage);{ message WM_GETOBJECT;}
-    {$endif}
-    procedure WMHScroll(var Message: TLMHScroll); message LM_HSCROLL;
-    procedure WMKeyDown(var Message: TLMKeyDown); message LM_KEYDOWN;
-    procedure WMKeyUp(var Message: TLMKeyUp); message LM_KEYUP;
-    procedure WMKillFocus(var Msg: TLMKillFocus); message LM_KILLFOCUS;
-    procedure WMLButtonDblClk(var Message: TLMLButtonDblClk); message LM_LBUTTONDBLCLK;
-    procedure WMLButtonDown(var Message: TLMLButtonDown); message LM_LBUTTONDOWN;
-    procedure WMLButtonUp(var Message: TLMLButtonUp); message LM_LBUTTONUP;
-    procedure WMMButtonDblClk(var Message: TLMMButtonDblClk); message LM_MBUTTONDBLCLK;
-    procedure WMMButtonDown(var Message: TLMMButtonDown); message LM_MBUTTONDOWN;
-    procedure WMMButtonUp(var Message: TLMMButtonUp); message LM_MBUTTONUP;
-    {$ifdef EnableNCFunctions}
-    procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
-    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
-    procedure WMNCPaint(var Message: TRealWMNCPaint); message WM_NCPAINT;
-    {$endif}
-    procedure WMPaint(var Message: TLMPaint); message LM_PAINT;
-    procedure WMPaste(var Message: TLMNoParams); message LM_PASTE;
-    {$ifdef EnablePrintFunctions}
-    procedure WMPrint(var Message: TWMPrint); message WM_PRINT;
-    procedure WMPrintClient(var Message: TWMPrintClient); message WM_PRINTCLIENT;
-    {$endif}
-    procedure WMRButtonDblClk(var Message: TLMRButtonDblClk); message LM_RBUTTONDBLCLK;
-    procedure WMRButtonDown(var Message: TLMRButtonDown); message LM_RBUTTONDOWN;
-    procedure WMRButtonUp(var Message: TLMRButtonUp); message LM_RBUTTONUP;
-    procedure WMSetFocus(var Msg: TLMSetFocus); message LM_SETFOCUS;
-    procedure WMSize(var Message: TLMSize); message LM_SIZE;
-    procedure WMTimer(var Message: TLMTimer); message LM_TIMER;
-    {$ifdef ThemeSupport}
-    {$ifdef Windows}
-      procedure WMThemeChanged(var Message: TLMessage); message WM_THEMECHANGED;
-    {$endif}
-    {$endif ThemeSupport}
-    procedure WMVScroll(var Message: TLMVScroll); message LM_VSCROLL;
-    procedure AddToSelection(Node: PVirtualNode); overload; virtual;
-    procedure AddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean = False); overload; virtual;
-    procedure AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex); virtual;
-    procedure AdjustPanningCursor(X, Y: Integer); virtual;
-    procedure AdviseChangeEvent(StructureChange: Boolean; Node: PVirtualNode; Reason: TChangeReason); virtual;
-    function AllocateInternalDataArea(Size: Cardinal): Cardinal; virtual;
-    procedure Animate(Steps, Duration: Cardinal; Callback: TVTAnimationCallback; Data: Pointer); virtual;
-    procedure BeginOperation;
-    function CalculateSelectionRect(X, Y: Integer): Boolean; virtual;
-    function CanAutoScroll: Boolean; virtual;
-    function CanScroll(const ClientMousePos: TPoint): Boolean; virtual;
-    function CanShowDragImage: Boolean; virtual;
-    procedure Change(Node: PVirtualNode); virtual;
-    procedure ChangeScale(M, D: Integer); override;
-    //lcl
-    procedure CheckImageListNeeded;
-    function CheckParentCheckState(Node: PVirtualNode; NewCheckState: TCheckState): Boolean; virtual;
-    procedure ClearTempCache; virtual;
-    function ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual;
-    function ComputeRTLOffset(ExcludeScrollbar: Boolean = False): Integer; virtual;
-    function CountLevelDifference(Node1, Node2: PVirtualNode): Integer; virtual;
-    function CountVisibleChildren(Node: PVirtualNode): Cardinal; virtual;
-    procedure CreateParams(var Params: TCreateParams); override;
-    procedure CreateWnd; override;
-    procedure DestroyHandle; override;
-    procedure DetermineHiddenChildrenFlag(Node: PVirtualNode); virtual;
-    procedure DetermineHiddenChildrenFlagAllNodes; virtual;
-    procedure DetermineHitPositionLTR(var HitInfo: THitInfo; Offset, Right: Integer; Alignment: TAlignment); virtual;
-    procedure DetermineHitPositionRTL(var HitInfo: THitInfo; Offset, Right: Integer; Alignment: TAlignment); virtual;
-    function DetermineNextCheckState(CheckType: TCheckType; CheckState: TCheckState): TCheckState; virtual;
-    function DetermineScrollDirections(X, Y: Integer): TScrollDirections; virtual;
-    procedure DoAdvancedHeaderDraw(var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements); virtual;
-    procedure DoAfterCellPaint(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const CellRect: TRect); virtual;
-    procedure DoAfterItemErase(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect); virtual;
-    procedure DoAfterItemPaint(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect); virtual;
-    procedure DoAfterPaint(Canvas: TCanvas); virtual;
-    procedure DoAutoScroll(X, Y: Integer); virtual;
-    procedure DoAutoSize; override;
-    function DoBeforeDrag(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual;
-    procedure DoBeforeCellPaint(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
-      CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect); virtual;
-    procedure DoBeforeItemErase(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect; var Color: TColor;
-      var EraseAction: TItemEraseAction); virtual;
-    function DoBeforeItemPaint(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect): Boolean; virtual;
-    procedure DoBeforePaint(Canvas: TCanvas); virtual;
-    function DoCancelEdit: Boolean; virtual;
-    procedure DoCanEdit(Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean); virtual;
-    procedure DoChange(Node: PVirtualNode); virtual;
-    procedure DoCheckClick(Node: PVirtualNode; NewCheckState: TCheckState); virtual;
-    procedure DoChecked(Node: PVirtualNode); virtual;
-    function DoChecking(Node: PVirtualNode; var NewCheckState: TCheckState): Boolean; virtual;
-    procedure DoCollapsed(Node: PVirtualNode); virtual;
-    function DoCollapsing(Node: PVirtualNode): Boolean; virtual;
-    procedure DoColumnClick(Column: TColumnIndex; Shift: TShiftState); virtual;
-    procedure DoColumnDblClick(Column: TColumnIndex; Shift: TShiftState); virtual;
-    procedure DoColumnResize(Column: TColumnIndex); virtual;
-    function DoCompare(Node1, Node2: PVirtualNode; Column: TColumnIndex): Integer; virtual;
-    function DoCreateDataObject: IDataObject; virtual;
-    function DoCreateDragManager: IVTDragManager; virtual;
-    function DoCreateEditor(Node: PVirtualNode; Column: TColumnIndex): IVTEditLink; virtual;
-    procedure DoDragging(P: TPoint); virtual;
-    procedure DoDragExpand; virtual;
-    function DoDragMsg(ADragMessage: TDragMessage; APosition: TPoint;
-      ADragObject: TDragObject; ATarget: TControl; ADocking: Boolean): LRESULT; override;
-    function DoDragOver(Source: TObject; Shift: TShiftState; State: TDragState; const Pt: TPoint; Mode: TDropMode;
-      var Effect: LongWord): Boolean; virtual;
-    procedure DoDragDrop(Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; const Pt: TPoint;
-      var Effect: LongWord; Mode: TDropMode); virtual;
-    procedure DoEdit; virtual;
-    procedure DoEndDrag(Target: TObject; X, Y: Integer); override;
-    function DoEndEdit: Boolean; virtual;
-    procedure DoExpanded(Node: PVirtualNode); virtual;
-    function DoExpanding(Node: PVirtualNode): Boolean; virtual;
-    procedure DoFocusChange(Node: PVirtualNode; Column: TColumnIndex); virtual;
-    function DoFocusChanging(OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex): Boolean; virtual;
-    procedure DoFocusNode(Node: PVirtualNode; Ask: Boolean); virtual;
-    procedure DoFreeNode(Node: PVirtualNode); virtual;
-    function DoGetCellContentMargin(Node: PVirtualNode; Column: TColumnIndex;
-      CellContentMarginType: TVTCellContentMarginType = ccmtAllSides; Canvas: TCanvas = nil): TPoint; virtual;
-    procedure DoGetCursor(var Cursor: TCursor); virtual;
-    procedure DoGetHeaderCursor(var Cursor: HCURSOR); virtual;
-    function DoGetImageIndex(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
-      var Ghosted: Boolean; var Index: Integer): TCustomImageList; virtual;
-    procedure DoGetImageText(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
-      var ImageText: String); virtual;
-    procedure DoGetLineStyle(var Bits: Pointer); virtual;
-    function DoGetNodeHint(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; virtual;
-    function DoGetNodeTooltip(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; virtual;
-    function DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; virtual;
-    function DoGetPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Position: TPoint): TPopupMenu; virtual;
-    procedure DoGetUserClipboardFormats(var Formats: TFormatEtcArray); virtual;
-    procedure DoHeaderClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
-    procedure DoHeaderDblClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
-    procedure DoHeaderImageClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
-    procedure DoHeaderCheckBoxClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
-    procedure DoHeaderDragged(Column: TColumnIndex; OldPosition: TColumnPosition); virtual;
-    procedure DoHeaderDraggedOut(Column: TColumnIndex; const DropPosition: TPoint); virtual;
-    function DoHeaderDragging(Column: TColumnIndex): Boolean; virtual;
-    procedure DoHeaderDraw(Canvas: TCanvas; Column: TVirtualTreeColumn; const R: TRect; Hover, Pressed: Boolean;
-      DropMark: TVTDropMarkMode); virtual;
-    procedure DoHeaderDrawQueryElements(var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements); virtual;
-    procedure DoHeaderMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
-    procedure DoHeaderMouseMove(Shift: TShiftState; X, Y: Integer); virtual;
-    procedure DoHeaderMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
-    procedure DoHotChange(Old, New: PVirtualNode); virtual;
-    function DoIncrementalSearch(Node: PVirtualNode; const Text: String): Integer; virtual;
-    procedure DoInitChildren(Node: PVirtualNode; var ChildCount: Cardinal); virtual;
-    procedure DoInitNode(Parent, Node: PVirtualNode; var InitStates: TVirtualNodeInitStates); virtual;
-    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: Integer); virtual;
-    procedure DoNodeCopied(Node: PVirtualNode); virtual;
-    function DoNodeCopying(Node, NewParent: PVirtualNode): Boolean; virtual;
-    function DoNodeHeightDblClickResize(Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState;
-      P: TPoint): Boolean; virtual;
-    function DoNodeHeightTracking(Node: PVirtualNode; Column: TColumnIndex;  Shift: TShiftState;
-      var TrackPoint: TPoint; P: TPoint): Boolean; virtual;
-    procedure DoNodeMoved(Node: PVirtualNode); virtual;
-    function DoNodeMoving(Node, NewParent: PVirtualNode): Boolean; virtual;
-    function DoPaintBackground(Canvas: TCanvas; const R: TRect): Boolean; virtual;
-    procedure DoPaintDropMark(Canvas: TCanvas; Node: PVirtualNode; const R: TRect); virtual;
-    procedure DoPaintNode(var PaintInfo: TVTPaintInfo); virtual;
-    procedure DoPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Position: TPoint); virtual;
-    function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-      ForClipboard: Boolean): HRESULT; virtual;
-    procedure DoReset(Node: PVirtualNode); virtual;
-    procedure DoSaveUserData(Node: PVirtualNode; Stream: TStream); virtual;
-    procedure DoScroll(DeltaX, DeltaY: Integer); virtual;
-    function DoSetOffsetXY(Value: TPoint; Options: TScrollUpdateOptions; ClipRect: PRect = nil): Boolean; virtual;
-    procedure DoShowScrollbar(Bar: Integer; Show: Boolean); virtual;
-    procedure DoStartDrag(var DragObject: TDragObject); override;
-    procedure DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []); virtual;
-    procedure DoStructureChange(Node: PVirtualNode; Reason: TChangeReason); virtual;
-    procedure DoTimerScroll; virtual;
-    procedure DoUpdating(State: TVTUpdateState); virtual;
-    function DoValidateCache: Boolean; virtual;
-    procedure DragAndDrop(AllowedEffects: LongWord; DataObject: IDataObject;
-      DragEffect: LongWord); virtual;
-    procedure DragCanceled; override;
-    function DragDrop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-      var Effect: LongWord): HResult; reintroduce; virtual;
-    function DragEnter(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; virtual;
-    procedure DragFinished; virtual;
-    procedure DragLeave; virtual;
-    function DragOver(Source: TObject; KeyState: LongWord; DragState: TDragState; Pt: TPoint;
-      var Effect: LongWord): HResult; reintroduce; virtual;
-    procedure DrawDottedHLine(const PaintInfo: TVTPaintInfo; Left, Right, Top: Integer); virtual;
-    procedure DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, Bottom, Left: Integer); virtual;
-    procedure EndOperation;
-    function FindNodeInSelection(P: PVirtualNode; out Index: Integer; LowBound, HighBound: Integer): Boolean; virtual;
-    procedure FinishChunkHeader(Stream: TStream; StartPos, EndPos: Integer); virtual;
-    procedure FontChanged(AFont: TObject); virtual;
-    function GetBorderDimensions: TSize; virtual;
-    function GetCheckImage(Node: PVirtualNode; ImgCheckType: TCheckType = ctNone;
-      ImgCheckState: TCheckState = csUncheckedNormal; ImgEnabled: Boolean = False): Integer; virtual;
-    function GetClientRect: TRect; override;
-    function GetColumnClass: TVirtualTreeColumnClass; virtual;
-    function GetHeaderClass: TVTHeaderClass; virtual;
-    function GetHintWindowClass: THintWindowClass; virtual;
-    procedure GetImageIndex(var Info: TVTPaintInfo; Kind: TVTImageKind; InfoIndex: TVTImageInfoIndex;
-      DefaultImages: TCustomImageList); virtual;
-    function GetMaxRightExtend: Cardinal; virtual;
-    procedure GetNativeClipboardFormats(var Formats: TFormatEtcArray); virtual;
-    function GetOperationCanceled: Boolean;
-    function GetOptionsClass: TTreeOptionsClass; virtual;
-    function GetTreeFromDataObject(const DataObject: IDataObject): TBaseVirtualTree; virtual;
-    procedure HandleHotTrack(X, Y: Integer); virtual;
-    procedure HandleIncrementalSearch(CharCode: Word); virtual;
-    procedure HandleMouseDblClick(var Message: TLMMouse; const HitInfo: THitInfo); virtual;
-    procedure HandleMouseDown(var Message: TLMMouse; var HitInfo: THitInfo); virtual;
-    procedure HandleMouseUp(Keys: PtrUInt; const HitInfo: THitInfo); virtual;
-    function HasImage(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex): Boolean; virtual;
-    function HasPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Pos: TPoint): Boolean; virtual;
-    procedure InitChildren(Node: PVirtualNode); virtual;
-    procedure InitNode(Node: PVirtualNode); virtual;
-    procedure InternalAddFromStream(Stream: TStream; Version: Integer; Node: PVirtualNode); virtual;
-    function InternalAddToSelection(Node: PVirtualNode; ForceInsert: Boolean): Boolean; overload;
-    function InternalAddToSelection(const NewItems: TNodeArray; NewLength: Integer;
-      ForceInsert: Boolean): Boolean; overload;
-    procedure InternalCacheNode(Node: PVirtualNode); virtual;
-    procedure InternalClearSelection; virtual;
-    procedure InternalConnectNode(Node, Destination: PVirtualNode; Target: TBaseVirtualTree; Mode: TVTNodeAttachMode); virtual;
-    function InternalData(Node: PVirtualNode): Pointer;
-    procedure InternalDisconnectNode(Node: PVirtualNode; KeepFocus: Boolean; Reindex: Boolean = True); virtual;
-    function InternalGetNodeAt(X, Y: Integer): PVirtualNode; overload;
-    function InternalGetNodeAt(X, Y: Integer; Relative: Boolean; var NodeTop: Integer): PVirtualNode; overload;
-    procedure InternalRemoveFromSelection(Node: PVirtualNode); virtual;
-    procedure InvalidateCache;
-    procedure Loaded; override;
-    procedure MainColumnChanged; virtual;
-    procedure MarkCutCopyNodes; virtual;
-    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
-    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
-    {$ifdef EnableNCFunctions}
-    procedure OriginalWMNCPaint(DC: HDC); virtual;
-    {$endif}
-    procedure Paint; override;
-    procedure PaintCheckImage(const PaintInfo: TVTPaintInfo); virtual;
-    procedure PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean); virtual;
-    procedure PaintNodeButton(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const R: TRect; ButtonX,
-      ButtonY: Integer; BidiMode: TBiDiMode); virtual;
-    procedure PaintTreeLines(const PaintInfo: TVTPaintInfo; VAlignment, IndentSize: Integer;
-      LineImage: TLineImage); virtual;
-    procedure PaintSelectionRectangle(Target: TCanvas; WindowOrgX: Integer; const SelectionRect: TRect;
-      TargetRect: TRect); virtual;
-    procedure PrepareCell(var PaintInfo: TVTPaintInfo; WindowOrgX, MaxWidth: Integer); virtual;    
-    function ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType,
-      ChunkSize: Integer): Boolean; virtual;
-    procedure ReadNode(Stream: TStream; Version: Integer; Node: PVirtualNode); virtual;
-    procedure RedirectFontChangeEvent(Canvas: TCanvas); virtual;
-    procedure RemoveFromSelection(Node: PVirtualNode); virtual;
-    function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; virtual;
-    procedure ResetRangeAnchor; virtual;
-    procedure RestoreFontChangeEvent(Canvas: TCanvas); virtual;
-    procedure SelectNodes(StartNode, EndNode: PVirtualNode; AddOnly: Boolean); virtual;
-    procedure SetFocusedNodeAndColumn(Node: PVirtualNode; Column: TColumnIndex); virtual;
-    procedure SkipNode(Stream: TStream); virtual;
-    procedure StartWheelPanning(const Position: TPoint); virtual;
-    procedure StopWheelPanning; virtual;
-    procedure StructureChange(Node: PVirtualNode; Reason: TChangeReason); virtual;
-    function SuggestDropEffect(Source: TObject; Shift: TShiftState; const Pt: TPoint; AllowedEffects: LongWord): LongWord; virtual;
-    procedure ToggleSelection(StartNode, EndNode: PVirtualNode); virtual;
-    procedure UnselectNodes(StartNode, EndNode: PVirtualNode); virtual;
-    //lcl
-    procedure UpdateCheckImageList;
-    procedure UpdateColumnCheckState(Col: TVirtualTreeColumn);
-    procedure UpdateDesigner; virtual;
-    procedure UpdateEditBounds; virtual;
-    procedure UpdateHeaderRect; virtual;
-    procedure UpdateWindowAndDragImage(const Tree: TBaseVirtualTree; TreeRect: TRect; UpdateNCArea,
-      ReshowDragImage: Boolean); virtual;
-    procedure ValidateCache; virtual;
-    procedure ValidateNodeDataSize(var Size: Integer); virtual;
-    procedure WndProc(var Message: TLMessage); override;
-    procedure WriteChunks(Stream: TStream; Node: PVirtualNode); virtual;
-    procedure WriteNode(Stream: TStream; Node: PVirtualNode); virtual;
-
-    property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
-    property AnimationDuration: Cardinal read FAnimationDuration write SetAnimationDuration default 200;
-    property AutoExpandDelay: Cardinal read FAutoExpandDelay write FAutoExpandDelay default 1000;
-    property AutoScrollDelay: Cardinal read FAutoScrollDelay write FAutoScrollDelay default 1000;
-    property AutoScrollInterval: TAutoScrollInterval read FAutoScrollInterval write FAutoScrollInterval default 1;
-    property Background: TPicture read FBackground write SetBackground;
-    property BackgroundOffsetX: Integer index 0 read FBackgroundOffsetX write SetBackgroundOffset default 0;
-    property BackgroundOffsetY: Integer index 1 read FBackgroundOffsetY write SetBackgroundOffset default 0;
-    //property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
-    property BottomSpace: Cardinal read FBottomSpace write SetBottomSpace default 0;
-    property ButtonFillMode: TVTButtonFillMode read FButtonFillMode write SetButtonFillMode default fmTreeColor;
-    property ButtonStyle: TVTButtonStyle read FButtonStyle write SetButtonStyle default bsRectangle;
-    property ChangeDelay: Cardinal read FChangeDelay write FChangeDelay default 0;
-    property CheckImageKind: TCheckImageKind read FCheckImageKind write SetCheckImageKind default ckSystemDefault;
-    property ClipboardFormats: TClipboardFormats read FClipboardFormats write SetClipboardFormats;
-    property Colors: TVTColors read FColors write SetColors;
-    property CustomCheckImages: TBitmap read FCustomCheckImages write SetCustomCheckImages;
-    property DefaultNodeHeight: Cardinal read FDefaultNodeHeight write SetDefaultNodeHeight default 18;
-    property DefaultPasteMode: TVTNodeAttachMode read FDefaultPasteMode write FDefaultPasteMode default amAddChildLast;
-    property DragHeight: Integer read FDragHeight write FDragHeight default 350;
-    property DragImageKind: TVTDragImageKind read FDragImageKind write FDragImageKind default diComplete;
-    property DragOperations: TDragOperations read FDragOperations write FDragOperations default [doCopy, doMove];
-    property DragSelection: TNodeArray read FDragSelection;
-    property DragType: TVTDragType read FDragType write FDragType default dtOLE;
-    property DragWidth: Integer read FDragWidth write FDragWidth default 200;
-    property DrawSelectionMode: TVTDrawSelectionMode read FDrawSelectionMode write FDrawSelectionMode
-      default smDottedRectangle;
-    property EditColumn: TColumnIndex read FEditColumn write FEditColumn;
-    property EditDelay: Cardinal read FEditDelay write FEditDelay default 1000;
-    property Header: TVTHeader read FHeader write SetHeader;
-    property HeaderRect: TRect read FHeaderRect;
-    property HintMode: TVTHintMode read FHintMode write FHintMode default hmDefault;
-    property HotCursor: TCursor read FHotCursor write FHotCursor default crDefault;
-    property Images: TCustomImageList read FImages write SetImages;
-    property IncrementalSearch: TVTIncrementalSearch read FIncrementalSearch write SetSearchOption default isNone;
-    property IncrementalSearchDirection: TVTSearchDirection read FSearchDirection write FSearchDirection default sdForward;
-    property IncrementalSearchStart: TVTSearchStart read FSearchStart write FSearchStart default ssFocusedNode;
-    property IncrementalSearchTimeout: Cardinal read FSearchTimeout write FSearchTimeout default 1000;
-    property Indent: Cardinal read FIndent write SetIndent default 18;
-    property LastClickPos: TPoint read FLastClickPos write FLastClickPos;
-    property LastDropMode: TDropMode read FLastDropMode write FlastDropMode;
-    property LineMode: TVTLineMode read FLineMode write SetLineMode default lmNormal;
-    property LineStyle: TVTLineStyle read FLineStyle write SetLineStyle default lsDotted;
-    property Margin: Integer read FMargin write SetMargin default 4;
-    property NodeAlignment: TVTNodeAlignment read FNodeAlignment write SetNodeAlignment default naProportional;
-    property NodeDataSize: Integer read FNodeDataSize write SetNodeDataSize default -1;
-    property OperationCanceled: Boolean read GetOperationCanceled;
-    property RootNodeCount: Cardinal read GetRootNodeCount write SetRootNodeCount default 0;
-    property ScrollBarOptions: TScrollBarOptions read FScrollBarOptions write SetScrollBarOptions;
-    property SelectionBlendFactor: Byte read FSelectionBlendFactor write FSelectionBlendFactor default 128;
-    property SelectionCurveRadius: Cardinal read FSelectionCurveRadius write SetSelectionCurveRadius default 0;
-    property StateImages: TCustomImageList read FStateImages write SetStateImages;
-    property TextMargin: Integer read FTextMargin write SetTextMargin default 4;
-    property TotalInternalDataSize: Cardinal read FTotalInternalDataSize;
-    property TreeOptions: TCustomVirtualTreeOptions read FOptions write SetOptions;
-    property WantTabs: Boolean read FWantTabs write FWantTabs default False;
-
-    property OnAdvancedHeaderDraw: TVTAdvancedHeaderPaintEvent read FOnAdvancedHeaderDraw write FOnAdvancedHeaderDraw;
-    property OnAfterAutoFitColumn: TVTAfterAutoFitColumnEvent read FOnAfterAutoFitColumn write FOnAfterAutoFitColumn;
-    property OnAfterAutoFitColumns: TVTAfterAutoFitColumnsEvent read FOnAfterAutoFitColumns write FOnAfterAutoFitColumns;
-    property OnAfterCellPaint: TVTAfterCellPaintEvent read FOnAfterCellPaint write FOnAfterCellPaint;
-    property OnAfterColumnExport : TVTColumnExportEvent read FOnAfterColumnExport write FOnAfterColumnExport;
-    property OnAfterColumnWidthTracking: TVTAfterColumnWidthTrackingEvent read FOnAfterColumnWidthTracking write FOnAfterColumnWidthTracking;
-    property OnAfterGetMaxColumnWidth: TVTAfterGetMaxColumnWidthEvent read FOnAfterGetMaxColumnWidth write FOnAfterGetMaxColumnWidth;
-    property OnAfterHeaderExport: TVTTreeExportEvent read FOnBeforeHeaderExport write FOnBeforeHeaderExport;
-    property OnAfterHeaderHeightTracking: TVTAfterHeaderHeightTrackingEvent read FOnAfterHeaderHeightTracking
-      write FOnAfterHeaderHeightTracking;
-    property OnAfterItemErase: TVTAfterItemEraseEvent read FOnAfterItemErase write FOnAfterItemErase;
-    property OnAfterItemPaint: TVTAfterItemPaintEvent read FOnAfterItemPaint write FOnAfterItemPaint;
-    property OnAfterNodeExport: TVTNodeExportEvent read FOnAfterNodeExport write FOnAfterNodeExport;
-    property OnAfterPaint: TVTPaintEvent read FOnAfterPaint write FOnAfterPaint;
-    property OnAfterTreeExport: TVTTreeExportEvent read FOnAfterTreeExport write FOnAfterTreeExport;
-    property OnBeforeAutoFitColumn: TVTBeforeAutoFitColumnEvent read FOnBeforeAutoFitColumn write FOnBeforeAutoFitColumn;
-    property OnBeforeAutoFitColumns: TVTBeforeAutoFitColumnsEvent read FOnBeforeAutoFitColumns write FOnBeforeAutoFitColumns;
-    property OnBeforeCellPaint: TVTBeforeCellPaintEvent read FOnBeforeCellPaint write FOnBeforeCellPaint;
-    property OnBeforeColumnExport: TVTColumnExportEvent read FOnBeforeColumnExport write FOnBeforeColumnExport;
-    property OnBeforeColumnWidthTracking: TVTBeforeColumnWidthTrackingEvent read FOnBeforeColumnWidthTracking
-      write FOnBeforeColumnWidthTracking;
-    property OnBeforeGetMaxColumnWidth: TVTBeforeGetMaxColumnWidthEvent read FOnBeforeGetMaxColumnWidth write FOnBeforeGetMaxColumnWidth;
-    property OnBeforeHeaderExport: TVTTreeExportEvent read FOnBeforeHeaderExport write FOnBeforeHeaderExport;
-    property OnBeforeHeaderHeightTracking: TVTBeforeHeaderHeightTrackingEvent read FOnBeforeHeaderHeightTracking
-      write FOnBeforeHeaderHeightTracking;
-    property OnBeforeItemErase: TVTBeforeItemEraseEvent read FOnBeforeItemErase write FOnBeforeItemErase;
-    property OnBeforeItemPaint: TVTBeforeItemPaintEvent read FOnBeforeItemPaint write FOnBeforeItemPaint;
-    property OnBeforeNodeExport: TVTNodeExportEvent read FOnBeforeNodeExport write FOnBeforeNodeExport;
-    property OnBeforePaint: TVTPaintEvent read FOnBeforePaint write FOnBeforePaint;
-    property OnBeforeTreeExport: TVTTreeExportEvent read FOnBeforeTreeExport write FOnBeforeTreeExport;
-    property OnCanSplitterResizeColumn: TVTCanSplitterResizeColumnEvent read FOnCanSplitterResizeColumn write FOnCanSplitterResizeColumn;
-    property OnChange: TVTChangeEvent read FOnChange write FOnChange;
-    property OnChecked: TVTChangeEvent read FOnChecked write FOnChecked;
-    property OnChecking: TVTCheckChangingEvent read FOnChecking write FOnChecking;
-    property OnCollapsed: TVTChangeEvent read FOnCollapsed write FOnCollapsed;
-    property OnCollapsing: TVTChangingEvent read FOnCollapsing write FOnCollapsing;
-    property OnColumnClick: TVTColumnClickEvent read FOnColumnClick write FOnColumnClick;
-    property OnColumnDblClick: TVTColumnDblClickEvent read FOnColumnDblClick write FOnColumnDblClick;
-    property OnColumnExport : TVTColumnExportEvent read FOnColumnExport write FOnColumnExport;
-    property OnColumnResize: TVTHeaderNotifyEvent read FOnColumnResize write FOnColumnResize;
-    property OnColumnWidthDblClickResize: TVTColumnWidthDblClickResizeEvent read FOnColumnWidthDblClickResize
-      write FOnColumnWidthDblClickResize;
-    property OnColumnWidthTracking: TVTColumnWidthTrackingEvent read FOnColumnWidthTracking write FOnColumnWidthTracking;
-    property OnCompareNodes: TVTCompareEvent read FOnCompareNodes write FOnCompareNodes;
-    property OnCreateDataObject: TVTCreateDataObjectEvent read FOnCreateDataObject write FOnCreateDataObject;
-    property OnCreateDragManager: TVTCreateDragManagerEvent read FOnCreateDragManager write FOnCreateDragManager;
-    property OnCreateEditor: TVTCreateEditorEvent read FOnCreateEditor write FOnCreateEditor;
-    property OnDragAllowed: TVTDragAllowedEvent read FOnDragAllowed write FOnDragAllowed;
-    property OnDragOver: TVTDragOverEvent read FOnDragOver write FOnDragOver;
-    property OnDragDrop: TVTDragDropEvent read FOnDragDrop write FOnDragDrop;
-    property OnEditCancelled: TVTEditCancelEvent read FOnEditCancelled write FOnEditCancelled;
-    property OnEditing: TVTEditChangingEvent read FOnEditing write FOnEditing;
-    property OnEdited: TVTEditChangeEvent read FOnEdited write FOnEdited;
-    property OnExpanded: TVTChangeEvent read FOnExpanded write FOnExpanded;
-    property OnExpanding: TVTChangingEvent read FOnExpanding write FOnExpanding;
-    property OnFocusChanged: TVTFocusChangeEvent read FOnFocusChanged write FOnFocusChanged;
-    property OnFocusChanging: TVTFocusChangingEvent read FOnFocusChanging write FOnFocusChanging;
-    property OnFreeNode: TVTFreeNodeEvent read FOnFreeNode write FOnFreeNode;
-    property OnGetCellIsEmpty: TVTGetCellIsEmptyEvent read FOnGetCellIsEmpty write FOnGetCellIsEmpty;
-    property OnGetCursor: TVTGetCursorEvent read FOnGetCursor write FOnGetCursor;
-    property OnGetHeaderCursor: TVTGetHeaderCursorEvent read FOnGetHeaderCursor write FOnGetHeaderCursor;
-    property OnGetHelpContext: TVTHelpContextEvent read FOnGetHelpContext write FOnGetHelpContext;
-    property OnGetImageIndex: TVTGetImageEvent read FOnGetImage write FOnGetImage;
-    property OnGetImageIndexEx: TVTGetImageExEvent read FOnGetImageEx write FOnGetImageEx;
-    property OnGetImageText: TVTGetImageTextEvent read FOnGetImageText write FOnGetImageText;
-    property OnGetLineStyle: TVTGetLineStyleEvent read FOnGetLineStyle write FOnGetLineStyle;
-    property OnGetNodeDataSize: TVTGetNodeDataSizeEvent read FOnGetNodeDataSize write FOnGetNodeDataSize;
-    property OnGetPopupMenu: TVTPopupEvent read FOnGetPopupMenu write FOnGetPopupMenu;
-    property OnGetUserClipboardFormats: TVTGetUserClipboardFormatsEvent read FOnGetUserClipboardFormats
-      write FOnGetUserClipboardFormats;
-    property OnHeaderCheckBoxClick: TVTHeaderClickEvent read FOnHeaderCheckBoxClick write FOnHeaderCheckBoxClick;
-    property OnHeaderClick: TVTHeaderClickEvent read FOnHeaderClick write FOnHeaderClick;
-    property OnHeaderDblClick: TVTHeaderClickEvent read FOnHeaderDblClick write FOnHeaderDblClick;
-    property OnHeaderDragged: TVTHeaderDraggedEvent read FOnHeaderDragged write FOnHeaderDragged;
-    property OnHeaderDraggedOut: TVTHeaderDraggedOutEvent read FOnHeaderDraggedOut write FOnHeaderDraggedOut;
-    property OnHeaderDragging: TVTHeaderDraggingEvent read FOnHeaderDragging write FOnHeaderDragging;
-    property OnHeaderDraw: TVTHeaderPaintEvent read FOnHeaderDraw write FOnHeaderDraw;
-    property OnHeaderDrawQueryElements: TVTHeaderPaintQueryElementsEvent read FOnHeaderDrawQueryElements
-      write FOnHeaderDrawQueryElements;
-    property OnHeaderHeightTracking: TVTHeaderHeightTrackingEvent read FOnHeaderHeightTracking
-      write FOnHeaderHeightTracking;
-    property OnHeaderHeightDblClickResize: TVTHeaderHeightDblClickResizeEvent read FOnHeaderHeightDblClickResize
-      write FOnHeaderHeightDblClickResize;
-    property OnHeaderImageClick: TVTHeaderClickEvent read FOnHeaderImageClick write FOnHeaderImageClick;
-    property OnHeaderMouseDown: TVTHeaderMouseEvent read FOnHeaderMouseDown write FOnHeaderMouseDown;
-    property OnHeaderMouseMove: TVTHeaderMouseMoveEvent read FOnHeaderMouseMove write FOnHeaderMouseMove;
-    property OnHeaderMouseUp: TVTHeaderMouseEvent read FOnHeaderMouseUp write FOnHeaderMouseUp;
-    property OnHotChange: TVTHotNodeChangeEvent read FOnHotChange write FOnHotChange;
-    property OnIncrementalSearch: TVTIncrementalSearchEvent read FOnIncrementalSearch write FOnIncrementalSearch;
-    property OnInitChildren: TVTInitChildrenEvent read FOnInitChildren write FOnInitChildren;
-    property OnInitNode: TVTInitNodeEvent read FOnInitNode write FOnInitNode;
-    property OnKeyAction: TVTKeyActionEvent read FOnKeyAction write FOnKeyAction;
-    property OnLoadNode: TVTSaveNodeEvent read FOnLoadNode write FOnLoadNode;
-    property OnMeasureItem: TVTMeasureItemEvent read FOnMeasureItem write FOnMeasureItem;
-    property OnNodeCopied: TVTNodeCopiedEvent read FOnNodeCopied write FOnNodeCopied;
-    property OnNodeCopying: TVTNodeCopyingEvent read FOnNodeCopying write FOnNodeCopying;
-    property OnNodeExport: TVTNodeExportEvent read FOnNodeExport write FOnNodeExport;
-    property OnNodeHeightTracking: TVTNodeHeightTrackingEvent read FOnNodeHeightTracking write FOnNodeHeightTracking;
-    property OnNodeHeightDblClickResize: TVTNodeHeightDblClickResizeEvent read FOnNodeHeightDblClickResize
-      write FOnNodeHeightDblClickResize;
-    property OnNodeMoved: TVTNodeMovedEvent read FOnNodeMoved write FOnNodeMoved;
-    property OnNodeMoving: TVTNodeMovingEvent read FOnNodeMoving write FOnNodeMoving;
-    property OnPaintBackground: TVTBackgroundPaintEvent read FOnPaintBackground write FOnPaintBackground;
-    property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData;
-    property OnResetNode: TVTChangeEvent read FOnResetNode write FOnResetNode;
-    property OnSaveNode: TVTSaveNodeEvent read FOnSaveNode write FOnSaveNode;
-    property OnScroll: TVTScrollEvent read FOnScroll write FOnScroll;
-    property OnShowScrollbar: TVTScrollbarShowEvent read FOnShowScrollbar write FOnShowScrollbar;
-    property OnStateChange: TVTStateChangeEvent read FOnStateChange write FOnStateChange;
-    property OnStructureChange: TVTStructureChangeEvent read FOnStructureChange write FOnStructureChange;
-    property OnUpdating: TVTUpdatingEvent read FOnUpdating write FOnUpdating;
-  public
-    constructor Create(AOwner: TComponent); override;
-    destructor Destroy; override;
-
-    function AbsoluteIndex(Node: PVirtualNode): Cardinal;
-    function AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode; virtual;
-    procedure AddFromStream(Stream: TStream; TargetNode: PVirtualNode);
-    procedure AfterConstruction; override;
-    procedure Assign(Source: TPersistent); override;
-    procedure BeginDrag(Immediate: Boolean; Threshold: Integer = -1);
-    procedure BeginSynch;
-    procedure BeginUpdate; virtual;
-    procedure CancelCutOrCopy;
-    function CancelEditNode: Boolean;
-    procedure CancelOperation;
-    function CanEdit(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual;
-    procedure Clear; virtual;
-    procedure ClearChecked;
-    procedure ClearSelection;
-    function CopyTo(Source: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode;
-      ChildrenOnly: Boolean): PVirtualNode; overload;
-    function CopyTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode;
-      ChildrenOnly: Boolean): PVirtualNode; overload;
-    procedure CopyToClipBoard; virtual;
-    procedure CutToClipBoard; virtual;
-    procedure DefaultHandler(var AMessage); override;
-    procedure DeleteChildren(Node: PVirtualNode; ResetHasChildren: Boolean = False);
-    procedure DeleteNode(Node: PVirtualNode; Reindex: Boolean = True);
-    procedure DeleteSelectedNodes; virtual;
-    function Dragging: Boolean;
-    function EditNode(Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual;
-    function EndEditNode: Boolean;
-    procedure EndSynch;
-    procedure EndUpdate; virtual;
-    function ExecuteAction(Action: TBasicAction): Boolean; override;
-    procedure FinishCutOrCopy;
-    procedure FlushClipboard;
-    procedure FullCollapse(Node: PVirtualNode = nil);  virtual;
-    procedure FullExpand(Node: PVirtualNode = nil); virtual;
-    {$ifndef fpc}
-    function GetControlsAlignment: TAlignment; override;
-    {$endif}
-    function GetDisplayRect(Node: PVirtualNode; Column: TColumnIndex; TextOnly: Boolean; Unclipped: Boolean = False;
-      ApplyCellContentMargin: Boolean = False): TRect;
-    function GetFirst(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetFirstChecked(State: TCheckState = csCheckedNormal; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetFirstChild(Node: PVirtualNode): PVirtualNode;
-    function GetFirstCutCopy(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetFirstInitialized(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetFirstLeaf: PVirtualNode;
-    function GetFirstLevel(NodeLevel: Cardinal): PVirtualNode;
-    function GetFirstNoInit(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetFirstSelected(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetFirstVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-    function GetFirstVisibleChild(Node: PVirtualNode): PVirtualNode;
-    function GetFirstVisibleChildNoInit(Node: PVirtualNode): PVirtualNode;
-    function GetFirstVisibleNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-    procedure GetHitTestInfoAt(X, Y: Integer; Relative: Boolean; var HitInfo: THitInfo); virtual;
-    function GetLast(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetLastInitialized(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetLastNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetLastChild(Node: PVirtualNode): PVirtualNode;
-    function GetLastChildNoInit(Node: PVirtualNode): PVirtualNode;
-    function GetLastVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-    function GetLastVisibleChild(Node: PVirtualNode): PVirtualNode;
-    function GetLastVisibleChildNoInit(Node: PVirtualNode): PVirtualNode;
-    function GetLastVisibleNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-    function GetMaxColumnWidth(Column: TColumnIndex; UseSmartColumnWidth: Boolean = False): Integer;
-    function GetNext(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetNextChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal;
-      ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetNextCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetNextInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetNextLeaf(Node: PVirtualNode): PVirtualNode;
-    function GetNextLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
-    function GetNextNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetNextSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetNextSibling(Node: PVirtualNode): PVirtualNode;
-    function GetNextSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-    function GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-    function GetNextVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-    function GetNextVisibleSibling(Node: PVirtualNode): PVirtualNode;
-    function GetNextVisibleSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-    function GetNodeAt(X, Y: Integer): PVirtualNode; overload;
-    function GetNodeAt(X, Y: Integer; Relative: Boolean; var NodeTop: Integer): PVirtualNode; overload;
-    function GetNodeData(Node: PVirtualNode): Pointer;
-    function GetNodeLevel(Node: PVirtualNode): Cardinal;
-    function GetPrevious(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetPreviousChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal;
-      ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetPreviousCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetPreviousInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetPreviousLeaf(Node: PVirtualNode): PVirtualNode;
-    function GetPreviousLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
-    function GetPreviousNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetPreviousSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-    function GetPreviousSibling(Node: PVirtualNode): PVirtualNode;
-    function GetPreviousSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-    function GetPreviousVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-    function GetPreviousVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-    function GetPreviousVisibleSibling(Node: PVirtualNode): PVirtualNode;
-    function GetPreviousVisibleSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-    function GetSortedCutCopySet(Resolve: Boolean): TNodeArray;
-    function GetSortedSelection(Resolve: Boolean): TNodeArray;
-    procedure GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect;
-      out Text: String); virtual;
-    function GetTreeRect: TRect;
-    function GetVisibleParent(Node: PVirtualNode): PVirtualNode;
-    function HasAsParent(Node, PotentialParent: PVirtualNode): Boolean;
-    function InsertNode(Node: PVirtualNode; Mode: TVTNodeAttachMode; UserData: Pointer = nil): PVirtualNode;
-    procedure InvalidateChildren(Node: PVirtualNode; Recursive: Boolean);
-    procedure InvalidateColumn(Column: TColumnIndex);
-    function InvalidateNode(Node: PVirtualNode): TRect; virtual;
-    procedure InvalidateToBottom(Node: PVirtualNode);
-    procedure InvertSelection(VisibleOnly: Boolean);
-    function IsEditing: Boolean;
-    function IsMouseSelecting: Boolean;
-    function IterateSubtree(Node: PVirtualNode; Callback: TVTGetNodeProc; Data: Pointer; Filter: TVirtualNodeStates = [];
-      DoInit: Boolean = False; ChildNodesOnly: Boolean = False): PVirtualNode;
-    procedure LoadFromFile(const FileName: TFileName); virtual;
-    procedure LoadFromStream(Stream: TStream); virtual;
-    procedure MeasureItemHeight(const Canvas: TCanvas; Node: PVirtualNode);
-    procedure MoveTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean); overload;
-    procedure MoveTo(Node: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode;
-      ChildrenOnly: Boolean); overload;
-    procedure PaintTree(TargetCanvas: TCanvas; const Window: TRect; Target: TPoint; PaintOptions: TVTInternalPaintOptions;
-      PixelFormat: TPixelFormat = pfDevice);
-    function PasteFromClipboard: Boolean; virtual;
-    procedure PrepareDragImage(HotSpot: TPoint; const DataObject: IDataObject);
-    {$ifdef EnablePrint}
-    procedure Print(Printer: TPrinter; PrintHeader: Boolean);
-    {$endif}
-    function ProcessDrop(DataObject: IDataObject; TargetNode: PVirtualNode; var Effect: LongWord; Mode:
-      TVTNodeAttachMode): Boolean;
-    function ProcessOLEData(Source: TBaseVirtualTree; DataObject: IDataObject; TargetNode: PVirtualNode;
-      Mode: TVTNodeAttachMode; Optimized: Boolean): Boolean;
-    procedure RepaintNode(Node: PVirtualNode);
-    procedure ReinitChildren(Node: PVirtualNode; Recursive: Boolean); virtual;
-    procedure ReinitNode(Node: PVirtualNode; Recursive: Boolean); virtual;
-    procedure ResetNode(Node: PVirtualNode); virtual;
-    procedure SaveToFile(const FileName: TFileName);
-    procedure SaveToStream(Stream: TStream; Node: PVirtualNode = nil); virtual;
-    function ScrollIntoView(Node: PVirtualNode; Center: Boolean; Horizontally: Boolean = False): Boolean; overload;
-    function ScrollIntoView(Column: TColumnIndex; Center: Boolean): Boolean; overload;
-    procedure SelectAll(VisibleOnly: Boolean);
-    procedure Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual;
-    procedure SortTree(Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True); virtual;
-    procedure ToggleNode(Node: PVirtualNode);
-    function UpdateAction(Action: TBasicAction): Boolean; override;
-    procedure UpdateHorizontalScrollBar(DoRepaint: Boolean);
-    procedure UpdateScrollBars(DoRepaint: Boolean); virtual;
-    procedure UpdateVerticalScrollBar(DoRepaint: Boolean);
-    //lcl: reenable in case TControl implementation change to match Delphi
-//  function UseRightToLeftReading: Boolean;
-    procedure ValidateChildren(Node: PVirtualNode; Recursive: Boolean);
-    procedure ValidateNode(Node: PVirtualNode; Recursive: Boolean);
-    {$ifdef EnableAccessible}
-    property Accessible: IAccessible read FAccessible write FAccessible;
-    property AccessibleItem: IAccessible read FAccessibleItem write FAccessibleItem;
-    property AccessibleName: string read FAccessibleName write FAccessibleName;
-    {$endif}
-    property BottomNode: PVirtualNode read GetBottomNode write SetBottomNode;
-    property CheckedCount: Integer read GetCheckedCount;
-    property CheckImages: TBitmap read FCheckImages;
-    property CheckState[Node: PVirtualNode]: TCheckState read GetCheckState write SetCheckState;
-    property CheckType[Node: PVirtualNode]: TCheckType read GetCheckType write SetCheckType;
-    property ChildCount[Node: PVirtualNode]: Cardinal read GetChildCount write SetChildCount;
-    property ChildrenInitialized[Node: PVirtualNode]: Boolean read GetChildrenInitialized;
-    property CutCopyCount: Integer read GetCutCopyCount;
-    property DragImage: TVTDragImage read FDragImage;
-    property VTVDragManager: IVTDragManager read GetDragManager;
-    property DropTargetNode: PVirtualNode read FDropTargetNode;
-    property EditLink: IVTEditLink read FEditLink;
-    property Expanded[Node: PVirtualNode]: Boolean read GetExpanded write SetExpanded;
-    property FocusedColumn: TColumnIndex read FFocusedColumn write SetFocusedColumn default InvalidColumn;
-    property FocusedNode: PVirtualNode read FFocusedNode write SetFocusedNode;
-    property Font;
-    property FullyVisible[Node: PVirtualNode]: Boolean read GetFullyVisible write SetFullyVisible;
-    property HasChildren[Node: PVirtualNode]: Boolean read GetHasChildren write SetHasChildren;
-    property HotNode: PVirtualNode read FCurrentHotNode;
-    property IsDisabled[Node: PVirtualNode]: Boolean read GetDisabled write SetDisabled;
-    property IsVisible[Node: PVirtualNode]: Boolean read GetVisible write SetVisible;
-    property MultiLine[Node: PVirtualNode]: Boolean read GetMultiline write SetMultiline;
-    property NodeHeight[Node: PVirtualNode]: Cardinal read GetNodeHeight write SetNodeHeight;
-    property NodeParent[Node: PVirtualNode]: PVirtualNode read GetNodeParent write SetNodeParent;
-    property OffsetX: Integer read FOffsetX write SetOffsetX;
-    property OffsetXY: TPoint read GetOffsetXY write SetOffsetXY;
-    property OffsetY: Integer read FOffsetY write SetOffsetY;
-    property RootNode: PVirtualNode read FRoot;
-    property SearchBuffer: String read FSearchBuffer;
-    property Selected[Node: PVirtualNode]: Boolean read GetSelected write SetSelected;
-    property SelectionLocked: Boolean read FSelectionLocked write FSelectionLocked;
-    property TotalCount: Cardinal read GetTotalCount;
-    property TreeStates: TVirtualTreeStates read FStates write FStates;
-    property SelectedCount: Integer read FSelectionCount;
-    property TopNode: PVirtualNode read GetTopNode write SetTopNode;
-    property VerticalAlignment[Node: PVirtualNode]: Byte read GetVerticalAlignment write SetVerticalAlignment;
-    property VisibleCount: Cardinal read FVisibleCount;
-    property VisiblePath[Node: PVirtualNode]: Boolean read GetVisiblePath write SetVisiblePath;
-    property UpdateCount: Cardinal read FUpdateCount;
-  end;
-
-
-  // --------- TCustomVirtualStringTree
-
-  // Options regarding strings (useful only for the string tree and descendants):
-  TVTStringOption = (
-    toSaveCaptions,          // If set then the caption is automatically saved with the tree node, regardless of what is
-                             // saved in the user data.
-    toShowStaticText,        // Show static text in a caption which can be differently formatted than the caption
-                             // but cannot be edited.
-    toAutoAcceptEditChange   // Automatically accept changes during edit if the user finishes editing other then
-                             // VK_RETURN or ESC. If not set then changes are cancelled.
-  );
-  TVTStringOptions = set of TVTStringOption;
-
-const
-  DefaultStringOptions = [toSaveCaptions, toAutoAcceptEditChange];
-
-type
-  TCustomStringTreeOptions = class(TCustomVirtualTreeOptions)
-  private
-    FStringOptions: TVTStringOptions;
-    procedure SetStringOptions(const Value: TVTStringOptions);
-  protected
-    property StringOptions: TVTStringOptions read FStringOptions write SetStringOptions default DefaultStringOptions;
-  public
-    constructor Create(AOwner: TBaseVirtualTree); override;
-
-    procedure AssignTo(Dest: TPersistent); override;
-  end;
-
-  TStringTreeOptions = class(TCustomStringTreeOptions)
-  published
-    property AnimationOptions;
-    property AutoOptions;
-    property ExportMode;
-    property MiscOptions;
-    property PaintOptions;
-    property SelectionOptions;
-    property StringOptions;
-  end;
-
-  TCustomVirtualStringTree = class;
-
-  // Edit support classes.
-  TStringEditLink = class;
-
-  { TVTEdit }
-
-  TVTEdit = class(TCustomEdit)
-  private
-    procedure CMAutoAdjust(var Message: TLMessage); message CM_AUTOADJUST;
-    procedure CMExit(var Message: TLMessage); message CM_EXIT;
-    procedure CNCommand(var Message: TLMCommand); message CN_COMMAND;
-    procedure DoRelease(Data: PtrInt);
-    procedure WMChar(var Message: TLMChar); message LM_CHAR;
-    procedure WMDestroy(var Message: TLMDestroy); message LM_DESTROY;
-    procedure WMGetDlgCode(var Message: TLMNoParams); message LM_GETDLGCODE;
-    procedure WMKeyDown(var Message: TLMKeyDown); message LM_KEYDOWN;
-  protected
-    FRefLink: IVTEditLink;
-    FLink: TStringEditLink;
-    procedure AutoAdjustSize; virtual;
-    procedure CreateParams(var Params: TCreateParams); override;
-  public
-    constructor Create(Link: TStringEditLink); reintroduce;
-
-    procedure Release;
-
-    property AutoSelect;
-    property AutoSize;
-    property BorderStyle;
-    property CharCase;
-    //property HideSelection;
-    property MaxLength;
-    //property OEMConvert;
-    property PasswordChar;
-  end;
-
-  TStringEditLink = class(TInterfacedObject, IVTEditLink)
-  private
-    FEdit: TVTEdit;                  // A normal custom edit control.
-    procedure SetEdit(const Value: TVTEdit);
-  protected
-    FTree: TCustomVirtualStringTree; // A back reference to the tree calling.
-    FNode: PVirtualNode;             // The node to be edited.
-    FColumn: TColumnIndex;           // The column of the node.
-    FAlignment: TAlignment;
-    FTextBounds: TRect;              // Smallest rectangle around the text.
-    FStopping: Boolean;              // Set to True when the edit link requests stopping the edit action.
-  public
-    constructor Create; virtual;
-    destructor Destroy; override;
-
-    function BeginEdit: Boolean; virtual; stdcall;
-    function CancelEdit: Boolean; virtual; stdcall;
-    property Edit: TVTEdit read FEdit write SetEdit;
-    function EndEdit: Boolean; virtual; stdcall;
-    function GetBounds: TRect; virtual; stdcall;
-    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; stdcall;
-    procedure ProcessMessage(var Message: TLMessage); virtual; stdcall;
-    procedure SetBounds(R: TRect); virtual; stdcall;
-  end;
-
-  // Describes the type of text to return in the text and draw info retrival events.
-  TVSTTextType = (
-    ttNormal,      // normal label of the node, this is also the text which can be edited
-    ttStatic       // static (non-editable) text after the normal text
-  );
-
-  // Describes the source to use when converting a string tree into a string for clipboard etc.
-  TVSTTextSourceType = (
-    tstAll,             // All nodes are rendered. Initialization is done on the fly.
-    tstInitialized,     // Only initialized nodes are rendered.
-    tstSelected,        // Only selected nodes are rendered.
-    tstCutCopySet,      // Only nodes currently marked as being in the cut/copy clipboard set are rendered.
-    tstVisible          // Only visible nodes are rendered.
-  );
-
-  TVTPaintText = procedure(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
-    TextType: TVSTTextType) of object;
-  TVSTGetTextEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    TextType: TVSTTextType; var CellText: String) of object;
-  TVSTGetHintEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: String) of object;
-  // New text can only be set for variable caption.
-  TVSTNewTextEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    const NewText: String) of object;
-  TVSTShortenStringEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    Column: TColumnIndex; const S: String; TextSpace: Integer; var Result: String;
-    var Done: Boolean) of object;
-  TVTMeasureTextWidthEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    Column: TColumnIndex; const Text: String; var Width: Integer) of object;
-  TVTDrawTextEvent = procedure(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
-    Column: TColumnIndex; const Text: String; const CellRect: TRect; var DefaultDraw: Boolean) of object;
-
-  // Helper class to speed up rendering text formats for clipboard and drag'n drop transfers.
-
-  { TBufferedUTF8String }
-
-  TBufferedUTF8String = class
-  private
-    FStart,
-    FPosition,
-    FEnd: PChar;
-    function GetAsAnsiString: AnsiString;
-    function GetAsUTF16String: UnicodeString;
-    function GetAsUTF8String: String;
-  public
-    destructor Destroy; override;
-
-    procedure Add(const S: String);
-    procedure AddNewLine;
-
-    property AsAnsiString: AnsiString read GetAsAnsiString;
-    property AsUTF8String: String read GetAsUTF8String;
-    property AsUTF16String: UnicodeString read GetAsUTF16String;
-  end;
-
-  { TCustomVirtualStringTree }
-
-  TCustomVirtualStringTree = class(TBaseVirtualTree)
-  private
-    FDefaultText: String;                      // text to show if there's no OnGetText event handler (e.g. at design time)
-    FTextHeight: Integer;                          // true size of the font
-    FEllipsisWidth: Integer;                       // width of '...' for the current font
-    FInternalDataOffset: Cardinal;                 // offset to the internal data of the string tree
-
-    FOnPaintText: TVTPaintText;                    // triggered before either normal or fixed text is painted to allow
-                                                   // even finer customization (kind of sub cell painting)
-    FOnGetText: TVSTGetTextEvent;                  // used to retrieve the string to be displayed for a specific node
-    FOnGetHint: TVSTGetHintEvent;                  // used to retrieve the hint to be displayed for a specific node
-    FOnNewText: TVSTNewTextEvent;                  // used to notify the application about an edited node caption
-    FOnShortenString: TVSTShortenStringEvent;      // used to allow the application a customized string shortage
-    FOnMeasureTextWidth: TVTMeasureTextWidthEvent; // used to adjust the width of the cells
-    FOnDrawText: TVTDrawTextEvent;                 // used to custom draw the node text 
-
-    procedure AddContentToBuffer(Buffer: TBufferedUTF8String; Source: TVSTTextSourceType; const Separator: String);
-    function GetImageText(Node: PVirtualNode; Kind: TVTImageKind;
-      Column: TColumnIndex): String;
-    procedure GetRenderStartValues(Source: TVSTTextSourceType; out Node: PVirtualNode;
-      out NextNodeProc: TGetNextNodeProc);
-    function GetOptions: TCustomStringTreeOptions;
-    function GetText(Node: PVirtualNode; Column: TColumnIndex): String;
-    procedure InitializeTextProperties(var PaintInfo: TVTPaintInfo);
-    procedure PaintNormalText(var PaintInfo: TVTPaintInfo; TextOutFlags: Integer; Text: String);
-    procedure PaintStaticText(const PaintInfo: TVTPaintInfo; TextOutFlags: Integer; const Text: String);
-    procedure SetDefaultText(const Value: String);
-    procedure SetOptions(const Value: TCustomStringTreeOptions);
-    procedure SetText(Node: PVirtualNode; Column: TColumnIndex; const Value: String);
-    procedure CMFontChanged(var Msg: TLMessage); message CM_FONTCHANGED;
-  protected
-    procedure AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex); override;
-    function CanExportNode(Node: PVirtualNode): Boolean;
-    function CalculateTextWidth(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String): Integer; virtual;
-    function ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean; override;
-    function DoCreateEditor(Node: PVirtualNode; Column: TColumnIndex): IVTEditLink; override;
-    function DoGetNodeHint(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; override;
-    function DoGetNodeTooltip(Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle): String; override;
-    function DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; override;
-    procedure DoGetText(Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
-      var Text: String); virtual;
-    function DoIncrementalSearch(Node: PVirtualNode; const Text: String): Integer; override;
-    procedure DoNewText(Node: PVirtualNode; Column: TColumnIndex; const Text: String); virtual;
-    procedure DoPaintNode(var PaintInfo: TVTPaintInfo); override;
-    procedure DoPaintText(Node: PVirtualNode; const Canvas: TCanvas; Column: TColumnIndex;
-      TextType: TVSTTextType); virtual;
-    function DoShortenString(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const S: String; Width: Integer;
-      EllipsisWidth: Integer = 0): String; virtual;
-    procedure DoTextDrawing(var PaintInfo: TVTPaintInfo; const Text: String; CellRect: TRect; DrawFormat: Cardinal); virtual;
-    function DoTextMeasuring(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String): Integer; virtual;
-    function GetOptionsClass: TTreeOptionsClass; override;
-    function InternalData(Node: PVirtualNode): Pointer;
-    procedure MainColumnChanged; override;
-    function ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType,
-      ChunkSize: Integer): Boolean; override;
-    function RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HResult; override;
-    procedure WriteChunks(Stream: TStream; Node: PVirtualNode); override;
-
-    property DefaultText: String read FDefaultText write SetDefaultText;
-    property EllipsisWidth: Integer read FEllipsisWidth;
-    property TreeOptions: TCustomStringTreeOptions read GetOptions write SetOptions;
-
-    property OnGetHint: TVSTGetHintEvent read FOnGetHint write FOnGetHint;
-    property OnGetText: TVSTGetTextEvent read FOnGetText write FOnGetText;
-    property OnNewText: TVSTNewTextEvent read FOnNewText write FOnNewText;
-    property OnPaintText: TVTPaintText read FOnPaintText write FOnPaintText;
-    property OnShortenString: TVSTShortenStringEvent read FOnShortenString write FOnShortenString;
-    property OnMeasureTextWidth: TVTMeasureTextWidthEvent read FOnMeasureTextWidth write FOnMeasureTextWidth;
-    property OnDrawText: TVTDrawTextEvent read FOnDrawText write FOnDrawText;
-  public
-    constructor Create(AOwner: TComponent); override;
-    function ComputeNodeHeight(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; S: String = ''): Integer; virtual;
-    function ContentToClipboard(Format: Word; Source: TVSTTextSourceType): HGLOBAL;
-    procedure ContentToCustom(Source: TVSTTextSourceType);
-    function ContentToHTML(Source: TVSTTextSourceType; const Caption: String = ''): String;
-    function ContentToRTF(Source: TVSTTextSourceType): AnsiString;
-    function ContentToAnsi(Source: TVSTTextSourceType; const Separator: String): AnsiString;
-    function ContentToText(Source: TVSTTextSourceType; const Separator: String): AnsiString; inline;
-    function ContentToUnicode(Source: TVSTTextSourceType; const Separator: String): UnicodeString; inline;
-    function ContentToUTF16(Source: TVSTTextSourceType; const Separator: String): UnicodeString;
-    function ContentToUTF8(Source: TVSTTextSourceType; const Separator: String): String;
-    {$ifndef LCLWin32}
-    procedure CopyToClipBoard; override;
-    procedure CutToClipBoard; override;
-    {$endif}
-    procedure GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect;
-      out Text: String); override;
-    function InvalidateNode(Node: PVirtualNode): TRect; override;
-    function Path(Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; Delimiter: Char): String;
-    procedure ReinitNode(Node: PVirtualNode; Recursive: Boolean); override;
-
-    property ImageText[Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex]: String read GetImageText;
-    property Text[Node: PVirtualNode; Column: TColumnIndex]: String read GetText write SetText;
-  end;
-
-  TVirtualStringTree = class(TCustomVirtualStringTree)
-  private
-    function GetOptions: TStringTreeOptions;
-    procedure SetOptions(const Value: TStringTreeOptions);
-  protected
-    function GetOptionsClass: TTreeOptionsClass; override;
-  public
-    property Canvas;
-  published
-    {$ifdef EnableAccessible}
-    property AccessibleName;
-    {$endif}
-    property Action;
-    property Align;
-    property Alignment;
-    property Anchors;
-    property AnimationDuration;
-    property AutoExpandDelay;
-    property AutoScrollDelay;
-    property AutoScrollInterval;
-    property Background;
-    property BackgroundOffsetX;
-    property BackgroundOffsetY;
-    property BiDiMode;
-    //property BevelEdges;
-    //property BevelInner;
-    //property BevelOuter;
-    //property BevelKind;
-    //property BevelWidth;
-    property BorderSpacing;
-    property BorderStyle default bsSingle;
-    property BottomSpace;
-    property ButtonFillMode;
-    property ButtonStyle;
-    property BorderWidth;
-    property ChangeDelay;
-    property CheckImageKind;
-    property ClipboardFormats;
-    property Color;
-    property Colors;
-    property Constraints;
-    //todo: see a way to set CustomCheckImages at design time
-    //property CustomCheckImages;
-    property DefaultNodeHeight;
-    property DefaultPasteMode;
-    property DefaultText;
-    property DragCursor;
-    property DragHeight;
-    property DragKind;
-    property DragImageKind;
-    property DragMode;
-    property DragOperations;
-    property DragType;
-    property DragWidth;
-    property DrawSelectionMode;
-    property EditDelay;
-    property Enabled;
-    property Font;
-    property Header;
-    property HintMode;
-    property HotCursor;
-    property Images;
-    property IncrementalSearch;
-    property IncrementalSearchDirection;
-    property IncrementalSearchStart;
-    property IncrementalSearchTimeout;
-    property Indent;
-    property LineMode;
-    property LineStyle;
-    property Margin;
-    property NodeAlignment;
-    property NodeDataSize;
-    property OperationCanceled;
-    property ParentBiDiMode;
-    property ParentColor default False;
-    property ParentFont;
-    property ParentShowHint;
-    property PopupMenu;
-    property RootNodeCount;
-    property ScrollBarOptions;
-    property SelectionBlendFactor;
-    property SelectionCurveRadius;
-    property ShowHint;
-    property StateImages;
-    property TabOrder;
-    property TabStop default True;
-    property TextMargin;
-    property TreeOptions: TStringTreeOptions read GetOptions write SetOptions;
-    property Visible;
-    property WantTabs;
-
-    property OnAdvancedHeaderDraw;
-    property OnAfterAutoFitColumn;
-    property OnAfterAutoFitColumns;
-    property OnAfterCellPaint;
-    property OnAfterColumnExport;
-    property OnAfterColumnWidthTracking;
-    property OnAfterGetMaxColumnWidth;
-    property OnAfterHeaderExport;
-    property OnAfterHeaderHeightTracking;
-    property OnAfterItemErase;
-    property OnAfterItemPaint;
-    property OnAfterNodeExport;
-    property OnAfterPaint;
-    property OnAfterTreeExport;
-    property OnBeforeAutoFitColumn;
-    property OnBeforeAutoFitColumns;
-    property OnBeforeCellPaint;
-    property OnBeforeColumnExport;
-    property OnBeforeColumnWidthTracking;
-    property OnBeforeGetMaxColumnWidth;
-    property OnBeforeHeaderExport;
-    property OnBeforeHeaderHeightTracking;
-    property OnBeforeItemErase;
-    property OnBeforeItemPaint;
-    property OnBeforeNodeExport;
-    property OnBeforePaint;
-    property OnBeforeTreeExport;
-    property OnCanSplitterResizeColumn;
-    property OnChange;
-    property OnChecked;
-    property OnChecking;
-    property OnClick;
-    property OnCollapsed;
-    property OnCollapsing;
-    property OnColumnClick;
-    property OnColumnDblClick;
-    property OnColumnExport;
-    property OnColumnResize;
-    property OnColumnWidthDblClickResize;
-    property OnColumnWidthTracking;
-    property OnCompareNodes;
-    property OnContextPopup;
-    property OnCreateDataObject;
-    property OnCreateDragManager;
-    property OnCreateEditor;
-    property OnDblClick;
-    property OnDragAllowed;
-    property OnDragOver;
-    property OnDragDrop;
-    property OnDrawText;
-    property OnEditCancelled;
-    property OnEdited;
-    property OnEditing;
-    property OnEndDock;
-    property OnEndDrag;
-    property OnEnter;
-    property OnExit;
-    property OnExpanded;
-    property OnExpanding;
-    property OnFocusChanged;
-    property OnFocusChanging;
-    property OnFreeNode;
-    property OnGetCellIsEmpty;
-    property OnGetCursor;
-    property OnGetHeaderCursor;
-    property OnGetText;
-    property OnPaintText;
-    property OnGetHelpContext;
-    property OnGetImageIndex;
-    property OnGetImageIndexEx;
-    property OnGetImageText;
-    property OnGetHint;
-    property OnGetLineStyle;
-    property OnGetNodeDataSize;
-    property OnGetPopupMenu;
-    property OnGetUserClipboardFormats;
-    property OnHeaderCheckBoxClick;
-    property OnHeaderClick;
-    property OnHeaderDblClick;
-    property OnHeaderDragged;
-    property OnHeaderDraggedOut;
-    property OnHeaderDragging;
-    property OnHeaderDraw;
-    property OnHeaderDrawQueryElements;
-    property OnHeaderHeightDblClickResize;
-    property OnHeaderHeightTracking;
-    property OnHeaderImageClick;
-    property OnHeaderMouseDown;
-    property OnHeaderMouseMove;
-    property OnHeaderMouseUp;
-    property OnHotChange;
-    property OnIncrementalSearch;
-    property OnInitChildren;
-    property OnInitNode;
-    property OnKeyAction;
-    property OnKeyDown;
-    property OnKeyPress;
-    property OnKeyUp;
-    property OnLoadNode;
-    property OnMeasureItem;
-    property OnMeasureTextWidth;
-    property OnMouseDown;
-    property OnMouseMove;
-    property OnMouseUp;
-    property OnMouseWheel;
-    property OnNewText;
-    property OnNodeCopied;
-    property OnNodeCopying;
-    property OnNodeExport;
-    property OnNodeHeightDblClickResize;
-    property OnNodeHeightTracking;
-    property OnNodeMoved;
-    property OnNodeMoving;
-    property OnPaintBackground;
-    property OnRenderOLEData;
-    property OnResetNode;
-    property OnResize;
-    property OnSaveNode;
-    property OnScroll;
-    property OnShortenString;
-    property OnShowScrollbar;
-    property OnStartDock;
-    property OnStartDrag;
-    property OnStateChange;
-    property OnStructureChange;
-    property OnUpdating;
-    property OnUTF8KeyPress;
-  end;
-
-  TVTDrawHintEvent = procedure(Sender: TBaseVirtualTree; HintCanvas: TCanvas; Node: PVirtualNode; const R: TRect;
-    Column: TColumnIndex) of object;
-  TVTDrawNodeEvent = procedure(Sender: TBaseVirtualTree; const PaintInfo: TVTPaintInfo) of object;
-  TVTGetCellContentMarginEvent = procedure(Sender: TBaseVirtualTree; HintCanvas: TCanvas; Node: PVirtualNode;
-    Column: TColumnIndex; CellContentMarginType: TVTCellContentMarginType; var CellContentMargin: TPoint) of object;
-  TVTGetNodeWidthEvent = procedure(Sender: TBaseVirtualTree; HintCanvas: TCanvas; Node: PVirtualNode;
-    Column: TColumnIndex; var NodeWidth: Integer) of object;
-  TVTGetHintSizeEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
-    var R: TRect) of object;
-
-  // Tree descendant to let an application draw its stuff itself.
-  TCustomVirtualDrawTree = class(TBaseVirtualTree)
-  private
-    FOnDrawNode: TVTDrawNodeEvent;
-    FOnGetCellContentMargin: TVTGetCellContentMarginEvent;
-    FOnGetNodeWidth: TVTGetNodeWidthEvent;
-    FOnGetHintSize: TVTGetHintSizeEvent;
-    FOnDrawHint: TVTDrawHintEvent;
-  protected
-    procedure DoDrawHint(Canvas: TCanvas; Node: PVirtualNode; const R: TRect; Column: TColumnIndex);
-    function DoGetCellContentMargin(Node: PVirtualNode; Column: TColumnIndex;
-      CellContentMarginType: TVTCellContentMarginType = ccmtAllSides; Canvas: TCanvas = nil): TPoint; override;
-    procedure DoGetHintSize(Node: PVirtualNode; Column: TColumnIndex; var R: TRect); virtual;
-    function DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer; override;
-    procedure DoPaintNode(var PaintInfo: TVTPaintInfo); override;
-
-    property OnDrawHint: TVTDrawHintEvent read FOnDrawHint write FOnDrawHint;
-    property OnDrawNode: TVTDrawNodeEvent read FOnDrawNode write FOnDrawNode;
-    property OnGetCellContentMargin: TVTGetCellContentMarginEvent read FOnGetCellContentMargin write FOnGetCellContentMargin;
-    property OnGetHintSize: TVTGetHintSizeEvent read FOnGetHintSize write FOnGetHintSize;
-    property OnGetNodeWidth: TVTGetNodeWidthEvent read FOnGetNodeWidth write FOnGetNodeWidth;
-  end;
-
-  TVirtualDrawTree = class(TCustomVirtualDrawTree)
-  private
-    function GetOptions: TVirtualTreeOptions;
-    procedure SetOptions(const Value: TVirtualTreeOptions);
-  protected
-    function GetOptionsClass: TTreeOptionsClass; override;
-  public
-    property Canvas;
-  published
-    property Action;
-    property Align;
-    property Alignment;
-    property Anchors;
-    property AnimationDuration;
-    property AutoExpandDelay;
-    property AutoScrollDelay;
-    property AutoScrollInterval;
-    property Background;
-    property BackgroundOffsetX;
-    property BackgroundOffsetY;
-    property BiDiMode;
-    //property BevelEdges;
-    //property BevelInner;
-    //property BevelOuter;
-    //property BevelKind;
-   // property BevelWidth;
-    property BorderSpacing;
-    property BorderStyle default bsSingle;
-    property BottomSpace;
-    property ButtonFillMode;
-    property ButtonStyle;
-    property BorderWidth;
-    property ChangeDelay;
-    property CheckImageKind;
-    property ClipboardFormats;
-    property Color;
-    property Colors;
-    property Constraints;
-    property CustomCheckImages;
-    property DefaultNodeHeight;
-    property DefaultPasteMode;
-    property DragCursor;
-    property DragHeight;
-    property DragKind;
-    property DragImageKind;
-    property DragMode;
-    property DragOperations;
-    property DragType;
-    property DragWidth;
-    property DrawSelectionMode;
-    property EditDelay;
-    property Enabled;
-    property Font;
-    property Header;
-    property HintMode;
-    property HotCursor;
-    property Images;
-    property IncrementalSearch;
-    property IncrementalSearchDirection;
-    property IncrementalSearchStart;
-    property IncrementalSearchTimeout;
-    property Indent;
-    property LineMode;
-    property LineStyle;
-    property Margin;
-    property NodeAlignment;
-    property NodeDataSize;
-    property OperationCanceled;
-    property ParentBiDiMode;
-    property ParentColor default False;
-    property ParentFont;
-    property ParentShowHint;
-    property PopupMenu;
-    property RootNodeCount;
-    property ScrollBarOptions;
-    property SelectionBlendFactor;
-    property SelectionCurveRadius;
-    property ShowHint;
-    property StateImages;
-    property TabOrder;
-    property TabStop default True;
-    property TextMargin;
-    property TreeOptions: TVirtualTreeOptions read GetOptions write SetOptions;
-    property Visible;
-    property WantTabs;
-
-    property OnAdvancedHeaderDraw;
-    property OnAfterAutoFitColumn;
-    property OnAfterAutoFitColumns;
-    property OnAfterCellPaint;
-    property OnAfterColumnExport;
-    property OnAfterColumnWidthTracking;
-    property OnAfterGetMaxColumnWidth;
-    property OnAfterHeaderExport;
-    property OnAfterHeaderHeightTracking;
-    property OnAfterItemErase;
-    property OnAfterItemPaint;
-    property OnAfterNodeExport;
-    property OnAfterPaint;
-    property OnAfterTreeExport;
-    property OnBeforeAutoFitColumn;
-    property OnBeforeAutoFitColumns;
-    property OnBeforeCellPaint;
-    property OnBeforeColumnExport;
-    property OnBeforeColumnWidthTracking;
-    property OnBeforeGetMaxColumnWidth;
-    property OnBeforeHeaderExport;
-    property OnBeforeHeaderHeightTracking;
-    property OnBeforeItemErase;
-    property OnBeforeItemPaint;
-    property OnBeforeNodeExport;
-    property OnBeforePaint;
-    property OnBeforeTreeExport;
-    property OnCanSplitterResizeColumn;
-    property OnChange;
-    property OnChecked;
-    property OnChecking;
-    property OnClick;
-    property OnCollapsed;
-    property OnCollapsing;
-    property OnColumnClick;
-    property OnColumnDblClick;
-    property OnColumnExport;
-    property OnColumnResize;
-    property OnColumnWidthDblClickResize;
-    property OnColumnWidthTracking;
-    property OnCompareNodes;
-    property OnContextPopup;
-    property OnCreateDataObject;
-    property OnCreateDragManager;
-    property OnCreateEditor;
-    property OnDblClick;
-    property OnDragAllowed;
-    property OnDragOver;
-    property OnDragDrop;
-    property OnDrawHint;
-    property OnDrawNode;
-    property OnEdited;
-    property OnEditing;
-    property OnEndDock;
-    property OnEndDrag;
-    property OnEnter;
-    property OnExit;
-    property OnExpanded;
-    property OnExpanding;
-    property OnFocusChanged;
-    property OnFocusChanging;
-    property OnFreeNode;
-    property OnGetCellIsEmpty;
-    property OnGetCursor;
-    property OnGetHeaderCursor;
-    property OnGetHelpContext;
-    property OnGetHintSize;
-    property OnGetImageIndex;
-    property OnGetImageIndexEx;
-    property OnGetLineStyle;
-    property OnGetNodeDataSize;
-    property OnGetNodeWidth;
-    property OnGetPopupMenu;
-    property OnGetUserClipboardFormats;
-    property OnHeaderCheckBoxClick;
-    property OnHeaderClick;
-    property OnHeaderDblClick;
-    property OnHeaderDragged;
-    property OnHeaderDraggedOut;
-    property OnHeaderDragging;
-    property OnHeaderDraw;
-    property OnHeaderDrawQueryElements;
-    property OnHeaderHeightTracking;
-    property OnHeaderHeightDblClickResize;
-    property OnHeaderImageClick;
-    property OnHeaderMouseDown;
-    property OnHeaderMouseMove;
-    property OnHeaderMouseUp;
-    property OnHotChange;
-    property OnIncrementalSearch;
-    property OnInitChildren;
-    property OnInitNode;
-    property OnKeyAction;
-    property OnKeyDown;
-    property OnKeyPress;
-    property OnKeyUp;
-    property OnLoadNode;
-    property OnMeasureItem;
-    property OnMouseDown;
-    property OnMouseMove;
-    property OnMouseUp;
-    property OnMouseWheel;
-    property OnNodeCopied;
-    property OnNodeCopying;
-    property OnNodeExport;
-    property OnNodeHeightTracking;
-    property OnNodeHeightDblClickResize;
-    property OnNodeMoved;
-    property OnNodeMoving;
-    property OnPaintBackground;
-    property OnRenderOLEData;
-    property OnResetNode;
-    property OnResize;
-    property OnSaveNode;
-    property OnScroll;
-    property OnShowScrollbar;
-    property OnStartDock;
-    property OnStartDrag;
-    property OnStateChange;
-    property OnStructureChange;
-    property OnUpdating;
-    property OnUTF8KeyPress;
-  end;
-
-// OLE Clipboard and drag'n drop helper
-procedure EnumerateVTClipboardFormats(TreeClass: TVirtualTreeClass; const List: TStrings); overload;
-procedure EnumerateVTClipboardFormats(TreeClass: TVirtualTreeClass; var Formats: TFormatEtcArray); overload;
-function GetVTClipboardFormatDescription(AFormat: Word): string;
-procedure RegisterVTClipboardFormat(AFormat: Word; TreeClass: TVirtualTreeClass; Priority: Cardinal); overload;
-function RegisterVTClipboardFormat(Description: string; TreeClass: TVirtualTreeClass; Priority: Cardinal;
-  tymed: Integer = TYMED_HGLOBAL; ptd: PDVTargetDevice = nil; dwAspect: Integer = DVASPECT_CONTENT;
-  lindex: Integer = -1): Word; overload;
-
-// utility routines
-{$ifdef EnablePrint}
-procedure PrtStretchDrawDIB(Canvas: TCanvas; DestRect: TRect; ABitmap: TBitmap);
-{$endif}
-function ShortenString(DC: HDC; const S: String; Width: Integer; EllipsisWidth: Integer = 0): String;
-function TreeFromNode(Node: PVirtualNode): TBaseVirtualTree;
-procedure GetStringDrawRect(DC: HDC; const S: String; var Bounds: TRect; DrawFormat: Cardinal);
-function WrapString(DC: HDC; const S: String; const Bounds: TRect; RTL: Boolean;
-  DrawFormat: Cardinal): String;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-implementation
-
-uses
-  StrUtils, Math,
-  {$ifdef EnableOLE}
-  //AxCtrls,       // TOLEStream
-  {$endif}
-  {$ifdef UseFlatScrollbars}
-    FlatSB,                // wrapper for systems without flat SB support
-  {$endif UseFlatScrollbars}
-  {$ifdef Windows}
-  MMSystem,                // for animation timer (does not include further resources)
-  {$else}
-  FakeMMSystem,
-  {$endif}
-  TypInfo,                 // for migration stuff
-  ActnList,
-  StdActns,                // for standard action support
-  GraphType,
-  LCLProc
-  {$ifdef EnableAccessible}
-  ,VTAccessibilityFactory
-  {$endif};  // accessibility helper class
-
-resourcestring
-  // Localizable strings.
-  SEditLinkIsNil = 'Edit link must not be nil.';
-  SWrongMoveError = 'Target node cannot be a child node of the node to be moved.';
-  SWrongStreamFormat = 'Unable to load tree structure, the format is wrong.';
-  SWrongStreamVersion = 'Unable to load tree structure, the version is unknown.';
-  SStreamTooSmall = 'Unable to load tree structure, not enough data available.';
-  SCorruptStream1 = 'Stream data corrupt. A node''s anchor chunk is missing.';
-  SCorruptStream2 = 'Stream data corrupt. Unexpected data after node''s end position.';
-  SClipboardFailed = 'Clipboard operation failed.';
-  SCannotSetUserData = 'Cannot set initial user data because there is not enough user data space allocated.';
-
-const
-  ClipboardStates = [tsCopyPending, tsCutPending];
-  DefaultScrollUpdateFlags = [suoRepaintHeader, suoRepaintScrollbars, suoScrollClientArea, suoUpdateNCArea];
-  MinimumTimerInterval = 1; // minimum resolution for timeGetTime
-  TreeNodeSize = (SizeOf(TVirtualNode) + 3) and not 3; // used for node allocation and access to internal data
-
-  // Lookup to quickly convert a specific check state into its pressed counterpart and vice versa.
-  PressedState: array[TCheckState] of TCheckState = (
-    csUncheckedPressed, csUncheckedPressed, csCheckedPressed, csCheckedPressed, csMixedPressed, csMixedPressed
-  );
-  UnpressedState: array[TCheckState] of TCheckState = (
-    csUncheckedNormal, csUncheckedNormal, csCheckedNormal, csCheckedNormal, csMixedNormal, csMixedNormal
-  );
-  MouseButtonDown = [tsLeftButtonDown, tsMiddleButtonDown, tsRightButtonDown];
-
-  // Do not modify the copyright in any way! Usage of this unit is prohibited without the copyright notice
-  // in the compiled binary file.
-  Copyright: string = 'Virtual Treeview ? 1999, 2010 Mike Lischke';
-
-var
-  //Workaround to LCL bug 8553
-  {$ifndef LCLWin32}
-  pf32bit: TPixelFormat = pfDevice;
-  {$endif}
-
-  StandardOLEFormat: TFormatEtc = (
-    // Format must later be set.
-    cfFormat: 0;
-    // No specific target device to render on.
-    ptd: nil;
-    // Normal content to render.
-    dwAspect: DVASPECT_CONTENT;
-    // No specific page of multipage data (we don't use multipage data by default).
-    lindex: -1;
-    // Acceptable storage formats are IStream and global memory. The first is preferred.
-    tymed: TYMED_ISTREAM or TYMED_HGLOBAL;
-  );
-
-
-type // streaming support
-  TMagicID = array[0..5] of Char;
-
-  TChunkHeader = record
-    ChunkType,
-    ChunkSize: Integer;      // contains the size of the chunk excluding the header
-  end;
-
-  // base information about a node
-  TBaseChunkBody = packed record
-    ChildCount,
-    NodeHeight: Cardinal;
-    States: TVirtualNodeStates;
-    Align: Byte;
-    CheckState: TCheckState;
-    CheckType: TCheckType;
-    Reserved: Cardinal;
-  end;
-
-  TBaseChunk = packed record
-    Header: TChunkHeader;
-    Body: TBaseChunkBody;
-  end;
-
-  // Toggle animation modes.
-  TToggleAnimationMode = (
-    tamScrollUp,
-    tamScrollDown,
-    tamNoScroll
-  );
-
-  // Internally used data for animations.
-  TToggleAnimationData = record
-    Window: HWND;               // copy of the tree's window handle
-    DC: HDC;                    // the DC of the window to erase uncovered parts
-    Brush: HBRUSH;              // the brush to be used to erase uncovered parts
-    R1,
-    R2: TRect;                    // animation rectangles
-    Mode1,
-    Mode2: TToggleAnimationMode;  // animation modes
-    ScaleFactor: Double;          // the factor between the missing step size when doing two animations
-    MissedSteps: Double;
-  end;
-
-const
-  CheckImagesStrings: array [TCheckImageKind] of String =
-    ('VT_CHECK_LIGHT',
-    'VT_CHECK_DARK',
-    'VT_TICK_LIGHT',
-    'VT_TICK_DARK',
-    'VT_FLAT',
-    'VT_XP',
-    '',//ckCustom,
-    // Only the button images are used for ckSystem *
-    // The check buttons are draw at fly as requested
-    'VT_FLAT',//ckSystemFlat
-    'VT_CHECK_DARK' //ckSystemDefault
-     );
-  MagicID: TMagicID = (#$45, 'V', 'T', Char(VTTreeStreamVersion), ' ', #$46);
-
-  // chunk IDs
-  NodeChunk = 1;
-  BaseChunk = 2;        // chunk containing node state, check state, child node count etc.
-                        // this chunk is immediately followed by all child nodes
-  CaptionChunk = 3;     // used by the string tree to store a node's caption
-  UserChunk = 4;        // used for data supplied by the application
-
-  {$ifdef UseFlatScrollbars}
-    ScrollBarProp: array[TScrollBarStyle] of Integer = (
-      FSB_REGULAR_MODE,
-      FSB_FLAT_MODE,
-      FSB_ENCARTA_MODE
-    );
-  {$endif}
-
-  RTLFlag: array[Boolean] of Integer = (0, ETO_RTLREADING);
-  AlignmentToDrawFlag: array[TAlignment] of Cardinal = (DT_LEFT, DT_RIGHT, DT_CENTER);
-
-  WideCR = WideChar(#13);
-  WideLF = WideChar(#10);
-
-type
-  // internal worker thread
-  TWorkerThread = class(TThread)
-  private
-    FCurrentTree: TBaseVirtualTree;
-    FWaiterList: TThreadList;
-    FRefCount: Cardinal;
-  protected
-    procedure CancelValidation(Tree: TBaseVirtualTree);
-    procedure ChangeTreeStates(EnterStates, LeaveStates: TChangeStates);
-    procedure Execute; override;
-  public
-    constructor Create(CreateSuspended: Boolean);
-    destructor Destroy; override;
-
-    procedure AddTree(Tree: TBaseVirtualTree);
-    procedure RemoveTree(Tree: TBaseVirtualTree);
-
-    property CurrentTree: TBaseVirtualTree read FCurrentTree;
-  end;
-
-var
-  WorkerThread: TWorkerThread;
-  WorkEvent: TEvent;
-  UtilityImages: TBitmap;              // some small additional images (e.g for header dragging)
-  Initialized: Boolean;                // True if global structures have been initialized.
-  NeedToUnitialize: Boolean;           // True if the OLE subsystem could be initialized successfully.
-
-//----------------- TClipboardFormats ----------------------------------------------------------------------------------
-
-type
-  PClipboardFormatListEntry = ^TClipboardFormatListEntry;
-  TClipboardFormatListEntry = record
-    Description: string;               // The string used to register the format with Windows.
-    TreeClass: TVirtualTreeClass;      // The tree class which supports rendering this format.
-    Priority: Cardinal;                // Number which determines the order of formats used in IDataObject.
-    FormatEtc: TFormatEtc;             // The definition of the format in the IDataObject.
-  end;
-
-  TClipboardFormatList = class
-  private
-    FList: TFpList;
-    procedure Sort;
-  public
-    constructor Create;
-    destructor Destroy; override;
-
-    procedure Add(FormatString: string; AClass: TVirtualTreeClass; Priority: Cardinal; AFormatEtc: TFormatEtc);
-    procedure Clear;
-    procedure EnumerateFormats(TreeClass: TVirtualTreeClass; var Formats: TFormatEtcArray;
-      const AllowedFormats: TClipboardFormats = nil); overload;
-    procedure EnumerateFormats(TreeClass: TVirtualTreeClass; const Formats: TStrings); overload;
-    function FindFormat(FormatString: string): PClipboardFormatListEntry; overload;
-    function FindFormat(FormatString: string; var Fmt: Word): TVirtualTreeClass; overload;
-    function FindFormat(Fmt: Word; out Description: string): TVirtualTreeClass; overload;
-  end;
-
-var
-  InternalClipboardFormats: TClipboardFormatList;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-constructor TClipboardFormatList.Create;
-
-begin
-  FList := TFpList.Create;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TClipboardFormatList.Destroy;
-
-begin
-  Clear;
-  FList.Free;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TClipboardFormatList.Sort;
-
-// Sorts all entry for priority (increasing priority value).
-
-  //--------------- local function --------------------------------------------
-
-  procedure QuickSort(L, R: Integer);
-
-  var
-    I, J: Integer;
-    P, T: PClipboardFormatListEntry;
-
-  begin
-    repeat
-      I := L;
-      J := R;
-      P := FList[(L + R) shr 1];
-      repeat
-        while PClipboardFormatListEntry(FList[I]).Priority < P.Priority do
-          Inc(I);
-        while PClipboardFormatListEntry(Flist[J]).Priority > P.Priority do
-          Dec(J);
-        if I <= J then
-        begin
-          T := Flist[I];
-          FList[I] := FList[J];
-          FList[J] := T;
-          Inc(I);
-          Dec(J);
-        end;
-      until I > J;
-      if L < J then
-        QuickSort(L, J);
-      L := I;
-    until I >= R;
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-begin
-  if FList.Count > 1 then
-    QuickSort(0, FList.Count - 1);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TClipboardFormatList.Add(FormatString: string; AClass: TVirtualTreeClass; Priority: Cardinal;
-  AFormatEtc: TFormatEtc);
-
-// Adds the given data to the internal list. The priority value is used to sort formats for importance. Larger priority
-// values mean less priority.
-
-var
-  Entry: PClipboardFormatListEntry;
-
-begin
-  New(Entry);
-  Entry.Description := FormatString;
-  Entry.TreeClass := AClass;
-  Entry.Priority := Priority;
-  Entry.FormatEtc := AFormatEtc;
-  FList.Add(Entry);
-
-  Sort;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TClipboardFormatList.Clear;
-
-var
-  I: Integer;
-
-begin
-  for I := 0 to FList.Count - 1 do
-    Dispose(PClipboardFormatListEntry(FList[I]));
-  FList.Clear;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TClipboardFormatList.EnumerateFormats(TreeClass: TVirtualTreeClass; var Formats: TFormatEtcArray;
-  const AllowedFormats: TClipboardFormats = nil);
-
-// Returns a list of format records for the given class. If assigned the AllowedFormats is used to limit the
-// enumerated formats to those described in the list.
-
-var
-  I, Count: Integer;
-  Entry: PClipboardFormatListEntry;
-
-begin
-  SetLength(Formats, FList.Count);
-  Count := 0;
-  for I := 0 to FList.Count - 1 do
-  begin
-    Entry := FList[I];
-    // Does the tree class support this clipboard format?
-    if TreeClass.InheritsFrom(Entry.TreeClass) then
-    begin
-      // Is this format allowed to be included?
-      if (AllowedFormats = nil) or (AllowedFormats.IndexOf(Entry.Description) > -1) then
-      begin
-        // The list could change before we use the FormatEtc so it is best not to pass a pointer to the true FormatEtc
-        // structure. Instead make a copy and send that.
-        Formats[Count] := Entry.FormatEtc;
-        Inc(Count);
-      end;
-    end;
-  end;
-  SetLength(Formats, Count);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TClipboardFormatList.EnumerateFormats(TreeClass: TVirtualTreeClass; const Formats: TStrings);
-
-// Returns a list of format descriptions for the given class.
-
-var
-  I: Integer;
-  Entry: PClipboardFormatListEntry;
-
-begin
-  for I := 0 to FList.Count - 1 do
-  begin
-    Entry := FList[I];
-    if TreeClass.InheritsFrom(Entry.TreeClass) then
-      Formats.Add(Entry.Description);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TClipboardFormatList.FindFormat(FormatString: string): PClipboardFormatListEntry;
-
-var
-  I: Integer;
-  Entry: PClipboardFormatListEntry;
-
-begin
-  Result := nil;
-  for I := FList.Count - 1 downto 0 do
-  begin
-    Entry := FList[I];
-    if CompareText(Entry.Description, FormatString) = 0 then
-    begin
-      Result := Entry;
-      Break;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TClipboardFormatList.FindFormat(FormatString: string; var Fmt: Word): TVirtualTreeClass;
-
-var
-  I: Integer;
-  Entry: PClipboardFormatListEntry;
-
-begin
-  Result := nil;
-  for I := FList.Count - 1 downto 0 do
-  begin
-    Entry := FList[I];
-    if CompareText(Entry.Description, FormatString) = 0 then
-    begin
-      Result := Entry.TreeClass;
-      Fmt := Entry.FormatEtc.cfFormat;
-      Break;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TClipboardFormatList.FindFormat(Fmt: Word; out Description: string): TVirtualTreeClass;
-
-var
-  I: Integer;
-  Entry: PClipboardFormatListEntry;
-
-begin
-  Result := nil;
-  for I := FList.Count - 1 downto 0 do
-  begin
-    Entry := FList[I];
-    if Entry.FormatEtc.cfFormat = Fmt then
-    begin
-      Result := Entry.TreeClass;
-      Description := Entry.Description;
-      Break;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-type
-  TClipboardFormatEntry = record
-    ID: Word;
-    Description: string;
-  end;
-
-var
-  ClipboardDescriptions: array [1..CF_MAX - 1] of TClipboardFormatEntry = (
-    (ID: CF_TEXT; Description: 'Plain text'), // Do not localize
-    (ID: CF_BITMAP; Description: 'Windows bitmap'), // Do not localize
-    (ID: CF_METAFILEPICT; Description: 'Windows metafile'), // Do not localize
-    (ID: CF_SYLK; Description: 'Symbolic link'), // Do not localize
-    (ID: CF_DIF; Description: 'Data interchange format'), // Do not localize
-    (ID: CF_TIFF; Description: 'Tiff image'), // Do not localize
-    (ID: CF_OEMTEXT; Description: 'OEM text'), // Do not localize
-    (ID: CF_DIB; Description: 'DIB image'), // Do not localize
-    (ID: CF_PALETTE; Description: 'Palette data'), // Do not localize
-    (ID: CF_PENDATA; Description: 'Pen data'), // Do not localize
-    (ID: CF_RIFF; Description: 'Riff audio data'), // Do not localize
-    (ID: CF_WAVE; Description: 'Wav audio data'), // Do not localize
-    (ID: CF_UNICODETEXT; Description: 'Unicode text'), // Do not localize
-    (ID: CF_ENHMETAFILE; Description: 'Enhanced metafile image'), // Do not localize
-    (ID: CF_HDROP; Description: 'File name(s)'), // Do not localize
-    (ID: CF_LOCALE; Description: 'Locale descriptor') // Do not localize
-  );
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure EnumerateVTClipboardFormats(TreeClass: TVirtualTreeClass; const List: TStrings);
-
-begin
-  if InternalClipboardFormats = nil then
-    InternalClipboardFormats := TClipboardFormatList.Create;
-  InternalClipboardFormats.EnumerateFormats(TreeClass, List);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure EnumerateVTClipboardFormats(TreeClass: TVirtualTreeClass; var Formats: TFormatEtcArray);
-
-begin
-  if InternalClipboardFormats = nil then
-    InternalClipboardFormats := TClipboardFormatList.Create;
-  InternalClipboardFormats.EnumerateFormats(TreeClass, Formats);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function GetVTClipboardFormatDescription(AFormat: Word): string;
-
-begin
-  if InternalClipboardFormats = nil then
-    InternalClipboardFormats := TClipboardFormatList.Create;
-  if InternalClipboardFormats.FindFormat(AFormat, Result) = nil then
-    Result := '';
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure RegisterVTClipboardFormat(AFormat: Word; TreeClass: TVirtualTreeClass; Priority: Cardinal);
-
-// Registers the given clipboard format for the given TreeClass.
-
-var
-  I: Integer;
-  FormatEtc: TFormatEtc;
-
-begin
-  if InternalClipboardFormats = nil then
-    InternalClipboardFormats := TClipboardFormatList.Create;
-
-  // Assumes a HGlobal format.
-  FormatEtc.cfFormat := AFormat;
-  FormatEtc.ptd := nil;
-  FormatEtc.dwAspect := DVASPECT_CONTENT;
-  FormatEtc.lindex := -1;
-  FormatEtc.tymed := TYMED_HGLOBAL;
-
-  // Determine description string of the given format. For predefined formats we need the lookup table because they
-  // don't have a description string. For registered formats the description string is the string which was used
-  // to register them.
-  if AFormat < CF_MAX then
-  begin
-    for I := 1 to High(ClipboardDescriptions) do
-      if ClipboardDescriptions[I].ID = AFormat then
-      begin
-        InternalClipboardFormats.Add(ClipboardDescriptions[I].Description, TreeClass, Priority, FormatEtc);
-        Break;
-      end;
-  end
-  else
-  begin
-    InternalClipboardFormats.Add(ClipboardFormatToMimeType(AFormat), TreeClass, Priority, FormatEtc);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function RegisterVTClipboardFormat(Description: string; TreeClass: TVirtualTreeClass; Priority: Cardinal;
-  tymed: Integer = TYMED_HGLOBAL; ptd: PDVTargetDevice = nil; dwAspect: Integer = DVASPECT_CONTENT;
-  lindex: Integer = -1): Word;
-
-// Alternative method to register a certain clipboard format for a given tree class. Registration with the
-// clipboard is done here too and the assigned ID returned by the function.
-// tymed may contain or'ed TYMED constants which allows to register several storage formats for one clipboard format.
-
-var
-  FormatEtc: TFormatEtc;
-
-begin
-  if InternalClipboardFormats = nil then
-    InternalClipboardFormats := TClipboardFormatList.Create;
-  Result := ClipboardRegisterFormat(Description);
-  FormatEtc.cfFormat := Result;
-  FormatEtc.ptd := ptd;
-  FormatEtc.dwAspect := dwAspect;
-  FormatEtc.lindex := lindex;
-  FormatEtc.tymed := tymed;
-  InternalClipboardFormats.Add(Description, TreeClass, Priority, FormatEtc);
-end;
-
-//----------------- utility functions ----------------------------------------------------------------------------------
-
-procedure ShowError(Msg: String; HelpContext: Integer);
-
-begin
-  raise EVirtualTreeError.CreateHelp(Msg, HelpContext);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TreeFromNode(Node: PVirtualNode): TBaseVirtualTree;
-
-// Returns the tree the node currently belongs to or nil if the node is not attached to a tree.
-
-begin
-  Assert(Assigned(Node), 'Node must not be nil.');
-
-  // The root node is marked by having its NextSibling (and PrevSibling) pointing to itself.
-  while Assigned(Node) and (Node.NextSibling <> Node) do
-    Node := Node.Parent;
-  if Assigned(Node) then
-    Result := TBaseVirtualTree(Node.Parent)
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function OrderRect(const R: TRect): TRect;
-
-// Converts the incoming rectangle so that left and top are always less than or equal to right and bottom.
-
-begin
-  if R.Left < R.Right then
-  begin
-    Result.Left := R.Left;
-    Result.Right := R.Right;
-  end
-  else
-  begin
-    Result.Left := R.Right;
-    Result.Right := R.Left;
-  end;
-  if R.Top < R.Bottom then
-  begin
-    Result.Top := R.Top;
-    Result.Bottom := R.Bottom;
-  end
-  else
-  begin
-    Result.Top := R.Bottom;
-    Result.Bottom := R.Top;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure QuickSort(const TheArray: TNodeArray; L, R: Integer);
-
-var
-  I, J: Integer;
-  P, T: Pointer;
-
-begin
-  repeat
-    I := L;
-    J := R;
-    P := TheArray[(L + R) shr 1];
-    repeat
-      while TheArray[I] < P do
-        Inc(I);
-      while TheArray[J] > P do
-        Dec(J);
-      if I <= J then
-      begin
-        T := TheArray[I];
-        TheArray[I] := TheArray[J];
-        TheArray[J] := T;
-        Inc(I);
-        Dec(J);
-      end;
-    until I > J;
-    if L < J then
-      QuickSort(TheArray, L, J);
-    L := I;
-  until I >= R;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-//todo: Unify the procedure or change to widgetset specific
-// Currently the UTF-8 version is broken.
-// the unicode version is used when all winapi is available
-
-{$ifndef INCOMPLETE_WINAPI}
-function ShortenString(DC: HDC; const S: String; Width: Integer; EllipsisWidth: Integer = 0): String;
-
-// Adjusts the given string S so that it fits into the given width. EllipsisWidth gives the width of
-// the three points to be added to the shorted string. If this value is 0 then it will be determined implicitely.
-// For higher speed (and multiple entries to be shorted) specify this value explicitely.
-// Note: It is assumed that the string really needs shortage. Check this in advance.
-
-var
-  Size: TSize;
-  Len: Integer;
-  L, H, N, W: Integer;
-  WideStr: UnicodeString;
-begin
-  WideStr := UTF8Decode(S);
-  Len := Length(WideStr);
-  if (Len = 0) or (Width <= 0) then
-    Result := ''
-  else
-  begin
-    // Determine width of triple point using the current DC settings (if not already done).
-    if EllipsisWidth = 0 then
-    begin
-      GetTextExtentPoint32W(DC, '...', 3, Size);
-      EllipsisWidth := Size.cx;
-    end;
-
-    if Width <= EllipsisWidth then
-      Result := ''
-    else
-    begin
-      // Do a binary search for the optimal string length which fits into the given width.
-      L := 0;
-      H := Len - 1;
-      while L < H do
-      begin
-        N := (L + H + 1) shr 1;
-        GetTextExtentPoint32W(DC, PWideChar(WideStr), N, Size);
-        W := Size.cx + EllipsisWidth;
-        if W <= Width then
-          L := N
-        else
-          H := N - 1;
-      end;
-      Result := UTF8Encode(Copy(WideStr, 1, L) + '...');
-    end;
-  end;
-end;
-{$else}
-function ShortenString(DC: HDC; const S: String; Width: Integer; EllipsisWidth: Integer = 0): String;
-
-// Adjusts the given string S so that it fits into the given width. EllipsisWidth gives the width of
-// the three points to be added to the shorted string. If this value is 0 then it will be determined implicitely.
-// For higher speed (and multiple entries to be shorted) specify this value explicitely.
-// Note: It is assumed that the string really needs shortage. Check this in advance.
-
-var
-  Size: TSize;
-  Len: Integer;
-  L, H, N, W: Integer;
-begin
-  Len := Length(S);
-  if (Len = 0) or (Width <= 0) then
-    Result := ''
-  else
-  begin
-    // Determine width of triple point using the current DC settings (if not already done).
-    if EllipsisWidth = 0 then
-    begin
-      GetTextExtentPoint32(DC, '...', 3, Size);
-      EllipsisWidth := Size.cx;
-    end;
-
-    if Width <= EllipsisWidth then
-      Result := ''
-    else
-    begin
-      // Do a binary search for the optimal string length which fits into the given width.
-      L := 0;
-      H := Len - 1;
-      while L < H do
-      begin
-        N := (L + H + 1) shr 1;
-        GetTextExtentPoint32(DC, PAnsiChar(S), N, Size);
-        W := Size.cx + EllipsisWidth;
-        if W <= Width then
-          L := N
-        else
-          H := N - 1;
-      end;
-      Result := Copy(S, 1, L) + '...';
-    end;
-  end;
-end;
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-
-function WrapString(DC: HDC; const S: String; const Bounds: TRect; RTL: Boolean;
-  DrawFormat: Cardinal): String;
-
-// Wrap the given string S so that it fits into a space of given width.
-// RTL determines if right-to-left reading is active.
-
-var
-  Width,
-  Len,
-  WordCounter,
-  WordsInLine,
-  I, W: Integer;
-  Buffer,
-  Line: String;
-  Words: Array of String;
-  R: TRect;
-
-begin
-  Result := '';
-  Width := Bounds.Right - Bounds.Left;
-  R := Rect(0, 0, 0, 0);
-
-  // Leading and trailing are ignored.
-  Buffer := Trim(S);
-  Len := Length(Buffer);
-  if Len < 1 then
-    Exit;
-
-  // Count the words in the string.
-  WordCounter := 1;
-  for I := 1 to Len do
-    if Buffer[I] = ' ' then
-      Inc(WordCounter);
-  SetLength(Words, WordCounter);
-
-  if RTL then
-  begin
-    // At first we split the string into words with the last word being the
-    // first element in Words.
-    W := 0;
-    for I := 1 to Len do
-      if Buffer[I] = ' ' then
-        Inc(W)
-      else
-        Words[W] := Words[W] + Buffer[I];
-
-    // Compose Result.
-    while WordCounter > 0 do
-    begin
-      WordsInLine := 0;
-      Line := '';
-
-      while WordCounter > 0 do
-      begin
-        GetStringDrawRect(DC, Line + IfThen(WordsInLine > 0, ' ', '') + Words[WordCounter - 1], R, DrawFormat);
-        if R.Right > Width then
-        begin
-          // If at least one word fits into this line then continue with the next line.
-          if WordsInLine > 0 then
-            Break;
-
-          Buffer := Words[WordCounter - 1];
-          if Len > 1 then
-          begin
-            for Len := Length(Buffer) - 1 downto 2 do
-            begin
-              GetStringDrawRect(DC, RightStr(Buffer, Len), R, DrawFormat);
-              if R.Right <= Width then
-                Break;
-            end;
-          end
-          else
-            Len := Length(Buffer);
-
-          Line := Line + RightStr(Buffer, Max(Len, 1));
-          Words[WordCounter - 1] := LeftStr(Buffer, Length(Buffer) - Max(Len, 1));
-          if Words[WordCounter - 1] = '' then
-            Dec(WordCounter);
-          Break;
-        end
-        else
-        begin
-          Dec(WordCounter);
-          Line := Words[WordCounter] + IfThen(WordsInLine > 0, ' ', '') + Line;
-          Inc(WordsInLine);
-        end;
-      end;
-
-      Result := Result + Line + LineEnding;
-    end;
-  end
-  else
-  begin
-    // At first we split the string into words with the last word being the
-    // first element in Words.
-    W := WordCounter - 1;
-    for I := 1 to Len do
-      if Buffer[I] = ' ' then
-        Dec(W)
-      else
-        Words[W] := Words[W] + Buffer[I];
-
-    // Compose Result.
-    while WordCounter > 0 do
-    begin
-      WordsInLine := 0;
-      Line := '';
-
-      while WordCounter > 0 do
-      begin
-        GetStringDrawRect(DC, Line + IfThen(WordsInLine > 0, ' ', '') + Words[WordCounter - 1], R, DrawFormat);
-        if R.Right > Width then
-        begin
-          // If at least one word fits into this line then continue with the next line.
-          if WordsInLine > 0 then
-            Break;
-
-          Buffer := Words[WordCounter - 1];
-          if Len > 1 then
-          begin
-            for Len := Length(Buffer) - 1 downto 2 do
-            begin
-              GetStringDrawRect(DC, LeftStr(Buffer, Len), R, DrawFormat);
-              if R.Right <= Width then
-                Break;
-            end;
-          end
-          else
-            Len := Length(Buffer);
-
-          Line := Line + LeftStr(Buffer, Max(Len, 1));
-          Words[WordCounter - 1] := RightStr(Buffer, Length(Buffer) - Max(Len, 1));
-          if Words[WordCounter - 1] = '' then
-            Dec(WordCounter);
-          Break;
-        end
-        else
-        begin
-          Dec(WordCounter);
-          Line := Line + IfThen(WordsInLine > 0, ' ', '') + Words[WordCounter];
-          Inc(WordsInLine);
-        end;
-      end;
-
-      Result := Result + Line + LineEnding;
-    end;
-  end;
-
-  Len := Length(Result) - Length(LineEnding);
-  if CompareByte(Result[Len + 1], String(LineEnding)[1], Length(LineEnding)) = 0 then
-    SetLength(Result, Len);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// Calculates bounds of a drawing rectangle for the given string
-
-procedure GetStringDrawRect(DC: HDC; const S: String; var Bounds: TRect; DrawFormat: Cardinal);
-begin
-  Bounds.Right := Bounds.Left + 1;
-  Bounds.Bottom := Bounds.Top + 1;
-
-  DrawText(DC, PChar(S), Length(S), Bounds, DrawFormat or DT_CALCRECT);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure FillDragRectangles(DragWidth, DragHeight, DeltaX, DeltaY: Integer; out RClip, RScroll, RSamp1, RSamp2, RDraw1,
-  RDraw2: TRect);
-
-// Fills the given rectangles with values which can be used while dragging around an image
-// (used in DragMove of the drag manager and DragTo of the header columns).
-
-begin
-  // ScrollDC limits
-  RClip := Rect(0, 0, DragWidth, DragHeight);
-  if DeltaX > 0 then
-  begin
-    // move to the left
-    if DeltaY = 0 then
-    begin
-      // move only to the left
-      // background movement
-      RScroll := Rect(0, 0, DragWidth - DeltaX, DragHeight);
-      RSamp1 := Rect(0, 0, DeltaX, DragHeight);
-      RDraw1 := Rect(DragWidth - DeltaX, 0, DeltaX, DragHeight);
-    end
-    else
-      if DeltaY < 0 then
-      begin
-        // move to bottom left
-        RScroll := Rect(0, -DeltaY, DragWidth - DeltaX, DragHeight);
-        RSamp1 := Rect(0, 0, DeltaX, DragHeight);
-        RSamp2 := Rect(DeltaX, DragHeight + DeltaY, DragWidth - DeltaX, -DeltaY);
-        RDraw1 := Rect(0, 0, DragWidth - DeltaX, -DeltaY);
-        RDraw2 := Rect(DragWidth - DeltaX, 0, DeltaX, DragHeight);
-      end
-      else
-      begin
-        // move to upper left
-        RScroll := Rect(0, 0, DragWidth - DeltaX, DragHeight - DeltaY);
-        RSamp1 := Rect(0, 0, DeltaX, DragHeight);
-        RSamp2 := Rect(DeltaX, 0, DragWidth - DeltaX, DeltaY);
-        RDraw1 := Rect(0, DragHeight - DeltaY, DragWidth - DeltaX, DeltaY);
-        RDraw2 := Rect(DragWidth - DeltaX, 0, DeltaX, DragHeight);
-      end;
-  end
-  else
-    if DeltaX = 0 then
-    begin
-      // vertical movement only
-      if DeltaY < 0 then
-      begin
-        // move downwards
-        RScroll := Rect(0, -DeltaY, DragWidth, DragHeight);
-        RSamp2 := Rect(0, DragHeight + DeltaY, DragWidth, -DeltaY);
-        RDraw2 := Rect(0, 0, DragWidth, -DeltaY);
-      end
-      else
-      begin
-        // move upwards
-        RScroll := Rect(0, 0, DragWidth, DragHeight - DeltaY);
-        RSamp2 := Rect(0, 0, DragWidth, DeltaY);
-        RDraw2 := Rect(0, DragHeight - DeltaY, DragWidth, DeltaY);
-      end;
-    end
-    else
-    begin
-      // move to the right
-      if DeltaY > 0 then
-      begin
-        // move up right
-        RScroll := Rect(-DeltaX, 0, DragWidth, DragHeight);
-        RSamp1 := Rect(0, 0, DragWidth + DeltaX, DeltaY);
-        RSamp2 := Rect(DragWidth + DeltaX, 0, -DeltaX, DragHeight);
-        RDraw1 := Rect(0, 0, -DeltaX, DragHeight);
-        RDraw2 := Rect(-DeltaX, DragHeight - DeltaY, DragWidth + DeltaX, DeltaY);
-      end
-      else
-        if DeltaY = 0 then
-        begin
-          // to the right only
-          RScroll := Rect(-DeltaX, 0, DragWidth, DragHeight);
-          RSamp1 := Rect(DragWidth + DeltaX, 0, -DeltaX, DragHeight);
-          RDraw1 := Rect(0, 0, -DeltaX, DragHeight);
-        end
-        else
-        begin
-          // move down right
-          RScroll := Rect(-DeltaX, -DeltaY, DragWidth, DragHeight);
-          RSamp1 := Rect(0, DragHeight + DeltaY, DragWidth + DeltaX, -DeltaY);
-          RSamp2 := Rect(DragWidth + DeltaX, 0, -DeltaX, DragHeight);
-          RDraw1 := Rect(0, 0, -DeltaX, DragHeight);
-          RDraw2 := Rect(-DeltaX, 0, DragWidth + DeltaX, -DeltaY);
-        end;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function GetRGBColor(Value: TColor): DWORD;
-
-// Little helper to convert a Delphi color to an image list color.
-
-begin
-  Result := ColorToRGB(Value);
-  case Result of
-    clNone:
-      Result := CLR_NONE;
-    clDefault:
-      Result := CLR_DEFAULT;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-{$ifdef CPU64}
-
-function HasMMX: Boolean;
-begin
-  Result := True;
-end;
-
-{$else}
-
-function HasMMX: Boolean;
-
-// Helper method to determine whether the current processor supports MMX.
-
-asm
-        PUSH    EBX
-        XOR     EAX, EAX     // Result := False
-        PUSHFD               // determine if the processor supports the CPUID command
-        POP     EDX
-        MOV     ECX, EDX
-        XOR     EDX, $200000
-        PUSH    EDX
-        POPFD
-        PUSHFD
-        POP     EDX
-        XOR     ECX, EDX
-        JZ      @1           // no CPUID support so we can't even get to the feature information
-        PUSH    EDX
-        POPFD
-
-        MOV     EAX, 1
-        DW      $A20F        // CPUID, EAX contains now version info and EDX feature information
-        MOV     EBX, EAX     // free EAX to get the result value
-        XOR     EAX, EAX     // Result := False
-        CMP     EBX, $50
-        JB      @1           // if processor family is < 5 then it is not a Pentium class processor
-        TEST    EDX, $800000
-        JZ      @1           // if the MMX bit is not set then we don't have MMX
-        INC     EAX          // Result := True
-@1:
-        POP     EBX
-end;
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-{$ifdef EnablePrint}
-procedure PrtStretchDrawDIB(Canvas: TCanvas; DestRect: TRect; ABitmap: TBitmap);
-
-// Stretch draw on to the new canvas.
-
-var
-  Header,
-  Bits: Pointer;
-  HeaderSize,
-  BitsSize: Cardinal;
-
-begin
-  GetDIBSizes(ABitmap.Handle, HeaderSize, BitsSize);
-
-  GetMem(Header, HeaderSize);
-  GetMem(Bits, BitsSize);
-  try
-    GetDIB(ABitmap.Handle, ABitmap.Palette, Header^, Bits^);
-    StretchDIBits(Canvas.Handle, DestRect.Left, DestRect.Top, DestRect.Right - DestRect.Left, DestRect.Bottom -
-      DestRect.Top, 0, 0, ABitmap.Width, ABitmap.Height, Bits, TBitmapInfo(Header^), DIB_RGB_COLORS, SRCCOPY);
-  finally
-    FreeMem(Header);
-    FreeMem(Bits);
-  end;
-end;
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-{$ifdef EnableAccessible}
-procedure GetAccessibilityFactory;
-
-// Accessibility helper function to create a singleton class that will create or return
-// the IAccessible interface for the tree and the focused node.
-
-begin
-  // Check to see if the class has already been created.
-  if VTAccessibleFactory = nil then
-    VTAccessibleFactory := TVTAccessibilityFactory.Create;
-end;
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure InitializeGlobalStructures;
-
-// initialization of stuff global to the unit
-
-begin
-  Initialized := True;
-
-  // For the drag image a fast MMX blend routine is used. We have to make sure MMX is available.
-  MMXAvailable := HasMMX;
-
-  // There is a bug in Win95 and WinME (and potentially in Win98 too) regarding GetDCEx which causes sometimes
-  // serious trouble within GDI (see method WMNCPaint).
-
-  //IsWinNT := (Win32Platform and VER_PLATFORM_WIN32_NT) <> 0;
-  IsWinNT := True;
-
-  {$ifdef EnableOLE}
-  // Initialize OLE subsystem for drag'n drop and clipboard operations.
-  //todo: replace by Suceeded (see in windows unit)
-  NeedToUnitialize := OleInitialize(nil) in [S_FALSE,S_OK];
-  {$endif}
-  // Register the tree reference clipboard format. Others will be handled in InternalClipboarFormats.
-  CF_VTREFERENCE := ClipboardRegisterFormat(CFSTR_VTREFERENCE);
-
-  UtilityImages := TBitmap.Create;
-  UtilityImages.Transparent := True;
-  UtilityImages.LoadFromLazarusResource('VT_UTILITIES');
-
-  // Specify an useful timer resolution for timeGetTime.
-  timeBeginPeriod(MinimumTimerInterval);
-
-  // Delphi (at least version 6 and lower) does not provide a standard split cursor.
-  // Hence we have to load our own.
-  Screen.Cursors[crHeaderSplit] := LoadCursorFromLazarusResource('VT_HEADERSPLIT');
-  Screen.Cursors[crVertSplit] := LoadCursorFromLazarusResource('VT_VERTSPLIT');
-  // Clipboard format registration.
-  // Native clipboard format. Needs a new identifier and has an average priority to allow other formats to take over.
-  // This format is supposed to use the IStream storage format but unfortunately this does not work when
-  // OLEFlushClipboard is used. Hence it is disabled until somebody finds a solution.
-  CF_VIRTUALTREE := RegisterVTClipboardFormat(CFSTR_VIRTUALTREE, TBaseVirtualTree, 50, TYMED_HGLOBAL {or TYMED_ISTREAM});
-  // Specialized string tree formats.
-  CF_HTML := RegisterVTClipboardFormat(CFSTR_HTML, TCustomVirtualStringTree, 80);
-  CF_VRTFNOOBJS := RegisterVTClipboardFormat(CFSTR_RTFNOOBJS, TCustomVirtualStringTree, 84);
-  CF_VRTF := RegisterVTClipboardFormat(CFSTR_RTF, TCustomVirtualStringTree, 85);
-  CF_CSV := RegisterVTClipboardFormat(CFSTR_CSV, TCustomVirtualStringTree, 90);
-  // Predefined clipboard formats. Just add them to the internal list.
-  RegisterVTClipboardFormat(CF_TEXT, TCustomVirtualStringTree, 100);
-  RegisterVTClipboardFormat(CF_UNICODETEXT, TCustomVirtualStringTree, 95);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure FinalizeGlobalStructures;
-
-begin
-  timeEndPeriod(MinimumTimerInterval);
-
-  FreeAndNil(UtilityImages);
-
-  if NeedToUnitialize then
-    OleUninitialize;
-end;
-
-//----------------- TWorkerThread --------------------------------------------------------------------------------------
-
-procedure AddThreadReference;
-
-begin
-  if WorkerThread = nil then
-  begin
-    // Create an event used to trigger our worker thread when something is to do.
-    WorkEvent := TEvent.Create(nil, False, False, '');
-    //todo: see how to check if a event was succesfully created under linux since handle is allways 0
-    {$ifdef Windows}
-    if WorkEvent.Handle = TEventHandle(0) then
-      Raise Exception.Create('VirtualTreeView - Error creating TEvent instance');
-    {$endif}
-    // Create worker thread, initialize it and send it to its wait loop.
-    WorkerThread := TWorkerThread.Create(False);
-  end;
-  Inc(WorkerThread.FRefCount);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure ReleaseThreadReference(Tree: TBaseVirtualTree);
-
-begin
-  if Assigned(WorkerThread) then
-  begin
-    Dec(WorkerThread.FRefCount);
-
-    // Make sure there is no reference remaining to the releasing tree.
-    Tree.InterruptValidation;
-
-    if WorkerThread.FRefCount = 0 then
-    begin
-      with WorkerThread do
-      begin
-        Terminate;
-        WorkEvent.SetEvent;
-
-        //lcl: probably not necessary under fpc. Remove later
-        // The following work around is no longer necessary with Delphi 6 and up.
-        {$ifndef fpc}
-          // There is a problem when the thread is freed in the exit code of a DLL. This can happen when a tree is
-          // destroyed on unload of a DLL (e.g. control panel applet). In this case only the main thread will get
-          // CPU time, other threads will never awake again. The VCL however waits for a thread when freeing it
-          // which will result in a deadlock (the WaitFor call does not return because the thread does not get CPU time).
-          // If a thread is however suspended then the VCL does not wait and all is fine.
-          if IsLibrary then
-            Suspend;
-        {$endif}
-
-        WorkerThread.Free;
-      end;
-      WorkerThread := nil;
-      WorkEvent.Free;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-constructor TWorkerThread.Create(CreateSuspended: Boolean);
-
-begin
-  inherited Create(CreateSuspended);
-  FWaiterList := TThreadList.Create;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TWorkerThread.Destroy;
-
-begin
-  // First let the ancestor stop the thread before freeing our resources.
-  inherited;
-
-  FWaiterList.Free;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TWorkerThread.CancelValidation(Tree: TBaseVirtualTree);
-
-var
-  Msg: TMsg;
-
-begin
-  // Wait for any references to this tree to be released.
-  // Pump WM_CHANGESTATE messages so the thread doesn't block on SendMessage calls.
-  while FCurrentTree = Tree do
-  begin
-    if Tree.HandleAllocated and PeekMessage(Msg, Tree.Handle, WM_CHANGESTATE, WM_CHANGESTATE, PM_REMOVE) then
-    begin
-      //todo: see if is correct / will work
-      Application.ProcessMessages;
-      //TranslateMessage(Msg);
-      //DispatchMessage(Msg);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TWorkerThread.ChangeTreeStates(EnterStates, LeaveStates: TChangeStates);
-
-begin
-  if Assigned(FCurrentTree) and (FCurrentTree.HandleAllocated) then
-    SendMessage(FCurrentTree.Handle, WM_CHANGESTATE, Byte(EnterStates), Byte(LeaveStates));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TWorkerThread.Execute;
-
-// Does some background tasks, like validating tree caches.
-
-var
-  EnterStates,
-  LeaveStates: TChangeStates;
-
-begin
-  while not Terminated do
-  begin
-    WorkEvent.WaitFor(INFINITE);
-    if not Terminated then
-    begin
-      // Get the next waiting tree.
-      with FWaiterList.LockList do
-      try
-        if Count > 0 then
-        begin
-          FCurrentTree := Items[0];
-          // Remove this tree from waiter list.
-          Delete(0);
-          // If there is yet another tree to work on then set the work event to keep looping.
-          if Count > 0 then
-            WorkEvent.SetEvent;
-        end
-        else
-          FCurrentTree := nil;
-      finally
-        FWaiterList.UnlockList;
-      end;
-
-      // Something to do?
-      if Assigned(FCurrentTree) then
-      begin
-        try
-          ChangeTreeStates([csValidating], [csUseCache]);
-          EnterStates := [];
-          if not (tsStopValidation in FCurrentTree.FStates) and FCurrentTree.DoValidateCache then
-            EnterStates := [csUseCache];
-
-        finally
-          LeaveStates := [csValidating, csStopValidation];
-          if csUseCache in EnterStates then
-            Include(LeaveStates, csValidationNeeded);
-          ChangeTreeStates(EnterStates, LeaveStates);
-          FCurrentTree := nil;
-        end;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TWorkerThread.AddTree(Tree: TBaseVirtualTree);
-
-begin
-  Assert(Assigned(Tree), 'Tree must not be nil.');
-
-  // Remove validation stop flag, just in case it is still set.
-  Tree.DoStateChange([], [tsStopValidation]);
-  with FWaiterList.LockList do
-  try
-    if IndexOf(Tree) = -1 then
-      Add(Tree);
-  finally
-    FWaiterList.UnlockList;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TWorkerThread.RemoveTree(Tree: TBaseVirtualTree);
-
-begin
-  Assert(Assigned(Tree), 'Tree must not be nil.');
-
-  with FWaiterList.LockList do
-  try
-    Remove(Tree);
-  finally
-    FWaiterList.UnlockList;
-  end;
-  CancelValidation(Tree);
-end;
-
-//----------------- TBufferedUTF8String --------------------------------------------------------------------------------
-const
-  AllocIncrement = 2 shl 11;  // Must be a power of 2.
-
-destructor TBufferedUTF8String.Destroy;
-
-begin
-  FreeMem(FStart);
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBufferedUTF8String.GetAsAnsiString: AnsiString;
-begin
-  //an implicit conversion is done
-  Result := AsUTF16String;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBufferedUTF8String.GetAsUTF16String: UnicodeString;
-begin
-  //todo: optimize
-  Result := UTF8Decode(AsUTF8String);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBufferedUTF8String.GetAsUTF8String: String;
-begin
-  SetString(Result, FStart, FPosition - FStart);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBufferedUTF8String.Add(const S: String);
-
-var
-  NewLen,
-  LastOffset,
-  Len: Integer;
-
-begin
-  Len := Length(S);
-  // Make room for the new string.
-  if FEnd - FPosition <= Len then
-  begin
-    // Round up NewLen so it is always a multiple of AllocIncrement.
-    NewLen := FEnd - FStart + (Len + AllocIncrement - 1) and not (AllocIncrement - 1);
-    // Keep last offset to restore it correctly in the case that FStart gets a new memory block assigned.
-    LastOffset := FPosition - FStart;
-    ReallocMem(FStart, NewLen);
-    FPosition := FStart + LastOffset;
-    FEnd := FStart + NewLen;
-  end;
-  Move(PChar(S)^, FPosition^, Len);
-  Inc(FPosition, Len);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBufferedUTF8String.AddNewLine;
-
-var
-  NewLen,
-  LastOffset: Integer;
-
-begin
-  // Make room for the CR/LF characters.
-  if FEnd - FPosition <= 4 then
-  begin
-    //todo: see in calculation of NewLen is correct for String
-    // Round up NewLen so it is always a multiple of AllocIncrement.
-    NewLen := FEnd - FStart + (2 + AllocIncrement - 1) and not (AllocIncrement - 1);
-    // Keep last offset to restore it correctly in the case that FStart gets a new memory block assigned.
-    LastOffset := FPosition - FStart;
-    ReallocMem(FStart, NewLen);
-    FPosition := FStart + LastOffset;
-    FEnd := FStart + NewLen;
-  end;
-  FPosition^ := #13;
-  Inc(FPosition);
-  FPosition^ := #10;
-  Inc(FPosition);
-end;
-
-//----------------- TCustomVirtualTreeOptions --------------------------------------------------------------------------
-
-constructor TCustomVirtualTreeOptions.Create(AOwner: TBaseVirtualTree);
-
-begin
-  FOwner := AOwner;
-
-  FPaintOptions := DefaultPaintOptions;
-  FAnimationOptions := DefaultAnimationOptions;
-  FAutoOptions := DefaultAutoOptions;
-  FSelectionOptions := DefaultSelectionOptions;
-  FMiscOptions := DefaultMiscOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualTreeOptions.SetAnimationOptions(const Value: TVTAnimationOptions);
-
-begin
-  FAnimationOptions := Value;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualTreeOptions.SetAutoOptions(const Value: TVTAutoOptions);
-
-var
-  ChangedOptions: TVTAutoOptions;
-
-begin
-  if FAutoOptions <> Value then
-  begin
-    // Exclusive ORing to get all entries wich are in either set but not in both.
-    ChangedOptions := FAutoOptions + Value - (FAutoOptions * Value);
-    FAutoOptions := Value;
-    with FOwner do
-      if (toAutoSpanColumns in ChangedOptions) and not (csLoading in ComponentState) and HandleAllocated then
-        Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualTreeOptions.SetMiscOptions(const Value: TVTMiscOptions);
-
-var
-  ToBeSet,
-  ToBeCleared: TVTMiscOptions;
-
-begin
-  if FMiscOptions <> Value then
-  begin
-    ToBeSet := Value - FMiscOptions;
-    ToBeCleared := FMiscOptions - Value;
-    FMiscOptions := Value;
-    {$ifndef Windows}
-    Exclude(FMiscOptions,toAcceptOLEDrop);
-    Exclude(ToBeCleared,toAcceptOLEDrop);
-    Exclude(ToBeSet,toAcceptOLEDrop);
-    {$endif}
-    with FOwner do
-      if not (csLoading in ComponentState) and HandleAllocated then
-      begin
-        if toCheckSupport in ToBeSet + ToBeCleared then
-        begin
-          CheckImageListNeeded;
-          Invalidate;
-        end;
-        if not (csDesigning in ComponentState) then
-        begin
-          if toFullRepaintOnResize in (TobeSet + ToBeCleared) then
-            //todo_lcl_check
-            RecreateWnd(FOwner);
-          if toAcceptOLEDrop in ToBeSet then
-            RegisterDragDrop(Handle, DragManager as IDropTarget);
-          if toAcceptOLEDrop in ToBeCleared then
-            RevokeDragDrop(Handle);
-        end;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualTreeOptions.SetPaintOptions(const Value: TVTPaintOptions);
-
-var
-  ToBeSet,
-  ToBeCleared: TVTPaintOptions;
-
-begin
-  if FPaintOptions <> Value then
-  begin
-    ToBeSet := Value - FPaintOptions;
-    ToBeCleared := FPaintOptions - Value;
-    FPaintOptions := Value;
-    with FOwner do
-      if HandleAllocated then
-      begin
-        {$ifdef ThemeSupport}
-        //todo
-        //  if (tsUseThemes in FStates) or (toThemeAware in ToBeSet) then
-        //    if (toUseExplorerTheme in ToBeSet) and IsWinVistaOrAbove then
-        //      SetWindowTheme(Handle, 'explorer', nil)
-        //    else
-        //      SetWindowTheme(Handle, '', nil);
-        {$endif ThemeSupport}
-
-        if not (csLoading in ComponentState) then
-        begin
-          {$ifdef ThemeSupport}
-            if (toThemeAware in ToBeSet + ToBeCleared) or (toUseExplorerTheme in ToBeSet + ToBeCleared) then
-            begin
-              if (toThemeAware in ToBeSet) and ThemeServices.ThemesEnabled then
-                DoStateChange([tsUseThemes])
-              else
-                if (toThemeAware in ToBeCleared) then
-                  DoStateChange([], [tsUseThemes]);
-
-              PrepareBitmaps(True, False);
-              RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_VALIDATE or RDW_FRAME);
-            end
-            else
-          {$endif ThemeSupport}
-          Invalidate;
-        end;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualTreeOptions.SetSelectionOptions(const Value: TVTSelectionOptions);
-
-var
-  ToBeSet,
-  ToBeCleared: TVTSelectionOptions;
-
-begin
-  if FSelectionOptions <> Value then
-  begin
-    ToBeSet := Value - FSelectionOptions;
-    ToBeCleared := FSelectionOptions - Value;
-    FSelectionOptions := Value;
-
-    with FOwner do
-    begin
-      if (toMultiSelect in (ToBeCleared + ToBeSet)) or
-        ([toLevelSelectConstraint, toSiblingSelectConstraint] * ToBeSet <> []) then
-        ClearSelection;
-
-      if (toExtendedFocus in ToBeCleared) and (FFocusedColumn > 0) and HandleAllocated then
-      begin
-        FFocusedColumn := FHeader.MainColumn;
-        Invalidate;
-      end;
-
-      if not (toExtendedFocus in FSelectionOptions) then
-        FFocusedColumn := FHeader.MainColumn;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualTreeOptions.AssignTo(Dest: TPersistent);
-
-begin
-  if Dest is TCustomVirtualTreeOptions then
-  begin
-    with TCustomVirtualTreeOptions(Dest) do
-    begin
-      PaintOptions := Self.PaintOptions;
-      AnimationOptions := Self.AnimationOptions;
-      AutoOptions := Self.AutoOptions;
-      SelectionOptions := Self.SelectionOptions;
-      MiscOptions := Self.MiscOptions;
-    end;
-  end
-  else
-    inherited;
-end;
-
-{$i vtvdragmanager.inc}
-
-//----------------- TVirtualTreeHintWindow -----------------------------------------------------------------------------
-
-procedure TVirtualTreeHintWindow.WMShowWindow(var Message: TLMShowWindow);
-
-// Clear hint data when the window becomes hidden.
-
-begin
-  if not Message.Show then
-  begin
-    // Don't touch the last hint rectangle stored in the associated tree to avoid flickering in certain situations.
-    Finalize(FHintData);
-    FillChar(FHintData, SizeOf(FHintData), 0);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeHintWindow.Paint;
-
-begin
-  with FHintData do
-  begin
-    if Tree is TCustomVirtualDrawTree and Assigned(Node) then
-    begin
-      // The draw tree has by default no hint text so let it draw the hint itself.
-      // HintBorderWidth is a private constant in hint code and is set to two
-      TCustomVirtualDrawTree(Tree).DoDrawHint(Canvas, Node,
-        Rect(0, 0, Width - 2, Height - 2), Column);
-    end
-    else
-      inherited;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect;
-var
-  P: TPoint;
-begin
-  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
-    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).
-      // This size has already been determined in CMHintShow.
-      if (Tree is TCustomVirtualDrawTree) and Assigned(Node) then
-        Result := HintRect
-      else
-      begin
-        //todo remove this define as soon as 0.9.30 is released to avoid future problems
-        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;
-        //select font according to the type of hint
-        if (Node = nil) or (Tree.FHintMode <> hmToolTip) then
-          Canvas.Font := Screen.HintFont
-        else
-        begin
-          Canvas.Font := Tree.Font;
-          //necessary to set customized fonts
-          if Tree is TCustomVirtualStringTree then
-            with TCustomVirtualStringTree(Tree) do
-              DoPaintText(Node, Self.Canvas, Column, ttNormal);
-          //force the default hint font color
-          Canvas.Font.Color := Screen.HintFont.Color;
-        end;
-
-        //let THintWindow do the job
-        Result := inherited CalcHintRect(MaxWidth, AHint, AData);
-        //fix position taking into account bidimode and control bounds
-        if (Tree.HintMode <> hmTooltip) or ((Result.Right - Result.Left) < Tree.Width) then
-        begin
-          if BiDiMode = bdLeftToRight then
-          begin
-            P := Tree.ClientToScreen(Point(0, 0));
-            HintInfo^.HintPos.X := Max(P.X, HintInfo^.HintPos.X);
-          end
-          else
-          begin
-            if (Tree.HintMode = hmTooltip) and (Node <> nil) then
-            begin
-              P := Tree.ClientToScreen(Point(Min(Tree.ClientWidth, HintInfo^.CursorRect.Right), 0));
-              Dec(P.X, Result.Right);
-              HintInfo^.HintPos.X := Max(P.X, HintInfo^.HintPos.X);
-            end
-            else
-              Dec(HintInfo^.HintPos.X, Result.Right - 20);
-          end;
-        end;
-      end;
-    end;
-  end;
-end;
-
-//----------------- TVTDragImage ---------------------------------------------------------------------------------------
-
-constructor TVTDragImage.Create(AOwner: TBaseVirtualTree);
-
-begin
-  FOwner := AOwner;
-  FTransparency := 128;
-  FPreBlendBias := 0;
-  FPostBlendBias := 0;
-  FFade := False;
-  FRestriction := dmrNone;
-  FColorKey := clNone;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDragImage.Destroy;
-
-begin
-  EndDrag;
-
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragImage.GetVisible: Boolean;
-
-// Returns True if the internal drag image is used (i.e. the system does not natively support drag images) and
-// the internal image is currently visible on screen.
-
-begin
-  Result := FStates * [disHidden, disInDrag, disPrepared, disSystemSupport] = [disInDrag, disPrepared];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragImage.InternalShowDragImage(ScreenDC: HDC);
-
-// Frequently called helper routine to actually do the blend and put it onto the screen.
-// Only used if the system does not support drag images.
-
-var
-  BlendMode: TBlendMode;
-
-begin
-  with FAlphaImage do
-    BitBlt(Canvas.Handle, 0, 0, Width, Height, FBackImage.Canvas.Handle, 0, 0, SRCCOPY);
-  if not FFade and (FColorKey = clNone) then
-    BlendMode := bmConstantAlpha
-  else
-    BlendMode := bmMasterAlpha;
-  with FDragImage do
-    AlphaBlend(Canvas.Handle, FAlphaImage.Canvas.Handle, Rect(0, 0, Width, Height), Point(0, 0), BlendMode,
-      FTransparency, FPostBlendBias);
-
-  with FAlphaImage do
-    BitBlt(ScreenDC, FImagePosition.X, FImagePosition.Y, Width, Height, Canvas.Handle, 0, 0, SRCCOPY);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragImage.MakeAlphaChannel(Source, Target: TBitmap);
-
-// Helper method to create a proper alpha channel in Target (which must be in 32 bit pixel format), depending
-// on the settings for the drag image and the color values in Source.
-// Only used if the system does not support drag images.
-
-type
-  PBGRA = ^TBGRA;
-  TBGRA = packed record
-    case Boolean of
-      False:
-        (Color: Cardinal);
-      True:
-        (BGR: array[0..2] of Byte;
-         Alpha: Byte);
-  end;
-
-var
-  Color,
-  ColorKeyRef: COLORREF;
-  UseColorKey: Boolean;
-  SourceRun,
-  TargetRun: PBGRA;
-  X, Y,
-  MaxDimension,
-  HalfWidth,
-  HalfHeight: Integer;
-  T: Extended;
-  SourceBits, TargetBits: Pointer;
-
-begin
-  {$ifdef EnableAdvancedGraphics}
-  SourceBits := GetBitmapBitsFromBitmap(Source.Handle);
-  TargetBits := GetBitmapBitsFromBitmap(Target.Handle);
-
-  if (SourceBits = nil) or (TargetBits = nil) then
-    Exit;
-
-  UseColorKey := ColorKey <> clNone;
-  ColorKeyRef := ColorToRGB(ColorKey) and $FFFFFF;
-  // Color values are in the form BGR (red on LSB) while bitmap colors are in the form ARGB (blue on LSB)
-  // hence we have to swap red and blue in the color key.
-  with TBGRA(ColorKeyRef) do
-  begin
-    X := BGR[0];
-    BGR[0] := BGR[2];
-    BGR[2] := X;
-  end;
-
-  with Target do
-  begin
-    MaxDimension := Max(Width, Height);
-
-    HalfWidth := Width div 2;
-    HalfHeight := Height div 2;
-    for Y := 0 to Height - 1 do
-    begin
-      TargetRun := CalculateScanline(TargetBits, Width, Height, Y);
-      SourceRun := CalculateScanline(SourceBits, Source.Width, Source.Height, Y);
-      for X := 0 to Width - 1 do
-      begin
-        Color := SourceRun.Color and $FFFFFF;
-        if UseColorKey and (Color = ColorKeyRef) then
-          TargetRun.Alpha := 0
-        else
-        begin
-          // If the color is not the given color key (or none is used) then do full calculation of a bell curve.
-          T := exp(-8 * Sqrt(Sqr((X - HalfWidth) / MaxDimension) + Sqr((Y - HalfHeight) / MaxDimension)));
-          TargetRun.Alpha := Round(255 * T);
-        end;
-        Inc(SourceRun);
-        Inc(TargetRun);
-      end;
-    end;
-  end;
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragImage.DragTo(const P: TPoint; ForceRepaint: Boolean): Boolean;
-
-// Moves the drag image to a new position, which is determined from the passed point P and the previous
-// mouse position.
-// ForceRepaint is True if something on the screen changed and the back image must be refreshed.
-
-var
-  ScreenDC: HDC;
-  DeltaX,
-  DeltaY: Integer;
-
-  // optimized drag image move support
-  RSamp1,
-  RSamp2,       // newly added parts from screen which will be overwritten
-  RDraw1,
-  RDraw2,       // parts to be restored to screen
-  RScroll,
-  RClip: TRect; // ScrollDC of the existent background
-
-begin
-  // Determine distances to move the drag image. Take care for restrictions.
-  case FRestriction of
-    dmrHorizontalOnly:
-      begin
-        DeltaX := FLastPosition.X - P.X;
-        DeltaY := 0;
-      end;
-    dmrVerticalOnly:
-      begin
-        DeltaX := 0;
-        DeltaY := FLastPosition.Y - P.Y;
-      end;
-  else // dmrNone
-    DeltaX := FLastPosition.X - P.X;
-    DeltaY := FLastPosition.Y - P.Y;
-  end;
-
-  Result := (DeltaX <> 0) or (DeltaY <> 0) or ForceRepaint;
-  if Result then
-  begin
-    if Visible then
-    begin
-      // All this stuff is only called if we have to handle the drag image ourselves. If the system supports
-      // drag image then this is all never executed.
-      ScreenDC := GetDC(0);
-      try
-        if (Abs(DeltaX) >= FDragImage.Width) or (Abs(DeltaY) >= FDragImage.Height) or ForceRepaint then
-        begin
-          // If moved more than image size then just restore old screen and blit image to new position.
-          BitBlt(ScreenDC, FImagePosition.X, FImagePosition.Y, FBackImage.Width, FBackImage.Height,
-            FBackImage.Canvas.Handle, 0, 0, SRCCOPY);
-
-          if ForceRepaint then
-            UpdateWindow(FOwner.Handle);
-
-          Inc(FImagePosition.X, -DeltaX);
-          Inc(FImagePosition.Y, -DeltaY);
-
-          BitBlt(FBackImage.Canvas.Handle, 0, 0, FBackImage.Width, FBackImage.Height, ScreenDC, FImagePosition.X,
-            FImagePosition.Y, SRCCOPY);
-        end
-        else
-        begin
-          // overlapping copy
-          FillDragRectangles(FDragImage.Width, FDragImage.Height, DeltaX, DeltaY, RClip, RScroll, RSamp1, RSamp2, RDraw1,
-            RDraw2);
-
-          with FBackImage.Canvas do
-          begin
-            // restore uncovered areas of the screen
-            if DeltaX = 0 then
-            begin
-              with RDraw2 do
-                BitBlt(ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, Right, Bottom, Handle, Left, Top,
-                  SRCCOPY);
-            end
-            else
-            begin
-              if DeltaY = 0 then
-              begin
-                with RDraw1 do
-                  BitBlt(ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, Right, Bottom, Handle, Left, Top,
-                    SRCCOPY);
-              end
-              else
-              begin
-                with RDraw1 do
-                  BitBlt(ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, Right, Bottom, Handle, Left, Top,
-                    SRCCOPY);
-                with RDraw2 do
-                  BitBlt(ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top, Right, Bottom, Handle, Left, Top,
-                    SRCCOPY);
-              end;
-            end;
-
-            //todo: implement ScrollDC. Alternatively reimplement drag operations
-            {$ifndef INCOMPLETE_WINAPI}
-            // move existent background
-            ScrollDC(Handle, DeltaX, DeltaY, RScroll, RClip, 0, nil);
-            {$endif}
-
-            Inc(FImagePosition.X, -DeltaX);
-            Inc(FImagePosition.Y, -DeltaY);
-
-            // Get first and second additional rectangle from screen.
-            if DeltaX = 0 then
-            begin
-              with RSamp2 do
-                BitBlt(Handle, Left, Top, Right, Bottom, ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top,
-                  SRCCOPY);
-            end
-            else
-              if DeltaY = 0 then
-              begin
-                with RSamp1 do
-                  BitBlt(Handle, Left, Top, Right, Bottom, ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top,
-                    SRCCOPY);
-              end
-              else
-              begin
-                with RSamp1 do
-                  BitBlt(Handle, Left, Top, Right, Bottom, ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top,
-                    SRCCOPY);
-                with RSamp2 do
-                  BitBlt(Handle, Left, Top, Right, Bottom, ScreenDC, FImagePosition.X + Left, FImagePosition.Y + Top,
-                    SRCCOPY);
-              end;
-          end;
-        end;
-        InternalShowDragImage(ScreenDC);
-      finally
-        ReleaseDC(0, ScreenDC);
-      end;
-    end;
-    FLastPosition.X := P.X;
-    FLastPosition.Y := P.Y;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragImage.EndDrag;
-
-begin
-  HideDragImage;
-  FStates := FStates - [disInDrag, disPrepared];
-
-  FBackImage.Free;
-  FBackImage := nil;
-  FDragImage.Free;
-  FDragImage := nil;
-  FAlphaImage.Free;
-  FAlphaImage := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragImage.GetDragImageRect: TRect;
-
-// Returns the current size and position of the drag image (screen coordinates).
-
-begin
-  if Visible then
-  begin
-    with FBackImage do
-      Result := Rect(FImagePosition.X, FImagePosition.Y, FImagePosition.X + Width, FImagePosition.Y + Height);
-  end
-  else
-    Result := Rect(0, 0, 0, 0);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragImage.HideDragImage;
-
-var
-  ScreenDC: HDC;
-
-begin
-  if Visible then
-  begin
-    Include(FStates, disHidden);
-    ScreenDC := GetDC(0);
-    try
-      // restore screen
-      with FBackImage do
-        BitBlt(ScreenDC, FImagePosition.X, FImagePosition.Y, Width, Height, Canvas.Handle, 0, 0, SRCCOPY);
-    finally
-      ReleaseDC(0, ScreenDC);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragImage.PrepareDrag(DragImage: TBitmap; const ImagePosition, HotSpot: TPoint; const DataObject: IDataObject);
-
-// Creates all necessary structures to do alpha blended dragging using the given image.
-// ImagePostion and Hotspot are given in screen coordinates. The first determines where to place the drag image while
-// the second is the initial mouse position.
-// This method also determines whether the system supports drag images natively. If so then only minimal structures
-// are created.
-
-var
-  Width,
-  Height: Integer;
-  DragSourceHelper: IDragSourceHelper;
-  DragInfo: TSHDragImage;
-
-begin
-  Width := DragImage.Width;
-  Height := DragImage.Height;
-
-  // Determine whether the system supports the drag helper interfaces.
-  if Assigned(DataObject) and Succeeded(CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER,
-    IID_IDragSourceHelper, DragSourceHelper)) then
-  begin
-    Include(FStates, disSystemSupport);
-
-    // Supply the drag source helper with our drag image.
-    DragInfo.sizeDragImage.cx := Width;
-    DragInfo.sizeDragImage.cy := Height;
-    DragInfo.ptOffset.x := Width div 2;
-    DragInfo.ptOffset.y := Height div 2;
-    //todo: replace CopyImage. Alternatively reimplement Drag support
-    {$ifndef INCOMPLETE_WINAPI}
-    DragInfo.hbmpDragImage := CopyImage(DragImage.Handle, IMAGE_BITMAP, Width, Height, LR_COPYRETURNORG);
-    {$else}
-    DragInfo.hbmpDragImage := 0;
-    {$endif}
-    DragInfo.ColorRef := ColorToRGB(FColorKey);
-    if not Succeeded(DragSourceHelper.InitializeFromBitmap(DragInfo, DataObject)) then
-    begin
-      DeleteObject(DragInfo.hbmpDragImage);
-      Exclude(FStates, disSystemSupport);
-    end;
-  end
-  else
-    Exclude(FStates, disSystemSupport);
-
-  if MMXAvailable and not (disSystemSupport in FStates) then
-  begin
-    FLastPosition := HotSpot;
-
-    FDragImage := TBitmap.Create;
-    FDragImage.PixelFormat := pf32Bit;
-    FDragImage.Width := Width;
-    FDragImage.Height := Height;
-
-    FAlphaImage := TBitmap.Create;
-    FAlphaImage.PixelFormat := pf32Bit;
-    FAlphaImage.Width := Width;
-    FAlphaImage.Height := Height;
-
-    FBackImage := TBitmap.Create;
-    FBackImage.PixelFormat := pf32Bit;
-    FBackImage.Width := Width;
-    FBackImage.Height := Height;
-
-    // Copy the given drag image and apply pre blend bias if required.
-    if FPreBlendBias = 0 then
-      with FDragImage do
-        BitBlt(Canvas.Handle, 0, 0, Width, Height, DragImage.Canvas.Handle, 0, 0, SRCCOPY)
-    else
-      AlphaBlend(DragImage.Canvas.Handle, FDragImage.Canvas.Handle, Rect(0, 0, Width, Height), Point(0, 0),
-        bmConstantAlpha, 255, FPreBlendBias);
-
-    // Create a proper alpha channel also if no fading is required (transparent parts).
-    MakeAlphaChannel(DragImage, FDragImage);
-
-    FImagePosition := ImagePosition;
-
-    // Initially the drag image is hidden and will be shown during the immediately following DragEnter event.
-    FStates := FStates + [disInDrag, disHidden, disPrepared];
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragImage.RecaptureBackground(Tree: TBaseVirtualTree; R: TRect; VisibleRegion: HRGN;
-  CaptureNCArea, ReshowDragImage: Boolean);
-
-// Notification by the drop target tree to update the background image because something in the tree has changed.
-// Note: The passed rectangle is given in client coordinates of the current drop target tree (given in Tree).
-//       The caller does not check if the given rectangle is actually within the drag image. Hence this method must do
-//       all the checks.
-// This method does nothing if the system manages the drag image.
-{$ifndef INCOMPLETE_WINAPI}
-var
-  DragRect,
-  ClipRect: TRect;
-  PaintTarget: TPoint;
-  PaintOptions: TVTInternalPaintOptions;
-  ScreenDC: HDC;
-{$endif}
-
-begin
-  //todo: reimplement
-  {$ifndef INCOMPLETE_WINAPI}
-  // Recapturing means we want the tree to paint the new part into our back bitmap instead to the screen.
-  if Visible then
-  begin
-    // Create the minimum rectangle to be recaptured.
-    MapWindowPoints(Tree.Handle, 0, R, 2);
-    DragRect := GetDragImageRect;
-    IntersectRect(R, R, DragRect);
-
-    OffsetRgn(VisibleRegion, -DragRect.Left, -DragRect.Top);
-
-    // The target position for painting in the drag image is relative and can be determined from screen coordinates too.
-    PaintTarget.X := R.Left - DragRect.Left;
-    PaintTarget.Y := R.Top - DragRect.Top;
-
-    // The source rectangle is determined by the offsets in the tree.
-    MapWindowPoints(0, Tree.Handle, R, 2);
-    OffsetRect(R, -Tree.FOffsetX, -Tree.FOffsetY);
-
-    // Finally let the tree paint the relevant part and upate the drag image on screen.
-    PaintOptions := [poBackground, poColumnColor, poDrawFocusRect, poDrawDropMark, poDrawSelection, poGridLines];
-    with FBackImage do
-    begin
-      ClipRect.TopLeft := PaintTarget;
-      ClipRect.Right := ClipRect.Left + R.Right - R.Left;
-      ClipRect.Bottom := ClipRect.Top + R.Bottom - R.Top;
-      Tree.LimitPaintingToArea(Canvas, ClipRect, VisibleRegion);
-      Tree.PaintTree(Canvas, R, PaintTarget, PaintOptions);
-
-      if CaptureNCArea then
-      begin
-        // For the non-client area we only need the visible region of the window as limit for painting.
-        SelectClipRgn(Canvas.Handle, VisibleRegion);
-        // Since WM_PRINT cannot be given a position where to draw we simply move the window origin and
-        // get the same effect.
-        GetWindowRect(Tree.Handle, ClipRect);
-        SetWindowOrgEx(Canvas.Handle, DragRect.Left - ClipRect.Left, DragRect.Top - ClipRect.Top, nil);
-        //todo: see what todo here
-        //Tree.Perform(WM_PRINT, Integer(Canvas.Handle), PRF_NONCLIENT);
-        SetWindowOrgEx(Canvas.Handle, 0, 0, nil);
-      end;
-      SelectClipRgn(Canvas.Handle, 0);
-
-      if ReshowDragImage then
-      begin
-        GDIFlush;
-        ScreenDC := GetDC(0);
-        try
-          InternalShowDragImage(ScreenDC);
-        finally
-          ReleaseDC(0, ScreenDC);
-        end;
-      end;
-    end;
-  end;
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragImage.ShowDragImage;
-
-// Shows the drag image after it has been hidden by HideDragImage.
-// Note: there might be a new background now.
-// Also this method does nothing if the system manages the drag image.
-{$ifndef INCOMPLETE_WINAPI}
-var
-  ScreenDC: HDC;
-{$endif}
-
-begin
-  {$ifndef INCOMPLETE_WINAPI}
-  if FStates * [disInDrag, disHidden, disPrepared, disSystemSupport] = [disInDrag, disHidden, disPrepared] then
-  begin
-    Exclude(FStates, disHidden);
-
-    GDIFlush;
-    ScreenDC := GetDC(0);
-    try
-      BitBlt(FBackImage.Canvas.Handle, 0, 0, FBackImage.Width, FBackImage.Height, ScreenDC, FImagePosition.X,
-        FImagePosition.Y, SRCCOPY);
-
-      InternalShowDragImage(ScreenDC);
-    finally
-      ReleaseDC(0, ScreenDC);
-    end;
-  end;
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragImage.WillMove(const P: TPoint): Boolean;
-
-// This method determines whether the drag image would "physically" move when DragTo would be called with the same
-// target point.
-// Always returns False if the system drag image support is available.
-
-var
-  DeltaX,
-  DeltaY: Integer;
-
-begin
-  Result := Visible;
-  if Result then
-  begin
-    // Determine distances to move the drag image. Take care for restrictions.
-    case FRestriction of
-      dmrHorizontalOnly:
-        begin
-          DeltaX := FLastPosition.X - P.X;
-          DeltaY := 0;
-        end;
-      dmrVerticalOnly:
-        begin
-          DeltaX := 0;
-          DeltaY := FLastPosition.Y - P.Y;
-        end;
-    else // dmrNone
-      DeltaX := FLastPosition.X - P.X;
-      DeltaY := FLastPosition.Y - P.Y;
-    end;
-
-    Result := (DeltaX <> 0) or (DeltaY <> 0);
-  end;
-end;
-
-//----------------- TVirtualTreeColumn ---------------------------------------------------------------------------------
-
-constructor TVirtualTreeColumn.Create(Collection: TCollection);
-
-begin
-  FMinWidth := 10;
-  FMaxWidth := 10000;
-  FImageIndex := -1;
-  FMargin := 4;
-  FSpacing := 4;
-  FText := '';
-  FOptions := DefaultColumnOptions;
-  FAlignment := taLeftJustify;
-  FBidiMode := bdLeftToRight;
-  FColor := clWindow;
-  FLayout := blGlyphLeft;
-  FBonusPixel := False;
-  FCaptionAlignment := taLeftJustify;
-  FCheckType := ctCheckBox;
-  FCheckState := csUncheckedNormal;
-  FCheckBox := False;
-  FHasImage := False;
-
-  inherited Create(Collection);
-
-  FWidth := Owner.FDefaultWidth;
-  FLastWidth := Owner.FDefaultWidth;
-  //lcl: setting FPosition here will override the Design time value
-  //FPosition := Owner.Count - 1;
-  // Read parent bidi mode and color values as default values.
-  ParentBiDiModeChanged;
-  ParentColorChanged;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVirtualTreeColumn.Destroy;
-
-var
-  I: Integer;
-
-  //--------------- local function ---------------------------------------------
-
-  procedure AdjustColumnIndex(var ColumnIndex: TColumnIndex);
-
-  begin
-    if Index = ColumnIndex then
-      ColumnIndex := NoColumn
-    else
-      if Index < ColumnIndex then
-        Dec(ColumnIndex);
-  end;
-
-  //--------------- end local function -----------------------------------------
-
-begin
-  // Check if this column is somehow referenced by its collection parent or the header.
-  with Owner do
-  begin
-    // If the columns collection object is currently deleting all columns
-    // then we don't need to check the various cached indices individually.
-    if not FClearing then
-    begin
-      IndexChanged(Index, -1);
-
-      AdjustColumnIndex(FHoverIndex);
-      AdjustColumnIndex(FDownIndex);
-      AdjustColumnIndex(FTrackIndex);
-      AdjustColumnIndex(FClickIndex);
-
-      with Header do
-      begin
-        AdjustColumnIndex(FAutoSizeIndex);
-        if Index = FMainColumn then
-        begin
-          // If the current main column is about to be destroyed then we have to find a new main column.
-          FMainColumn := NoColumn;
-          for I := 0 to Count - 1 do
-            if I <> Index then
-            begin
-              FMainColumn := I;
-              Break;
-            end;
-        end;
-        AdjustColumnIndex(FSortColumn);
-      end;
-    end;
-  end;
-
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.GetCaptionAlignment: TAlignment;
-
-begin
-  if coUseCaptionAlignment in FOptions then
-    Result := FCaptionAlignment
-  else
-    Result := FAlignment;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.GetLeft: Integer;
-
-begin
-  Result := FLeft;
-  if [coVisible, coFixed] * FOptions <> [coVisible, coFixed] then
-    Dec(Result, Owner.Header.Treeview.FEffectiveOffsetX);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.IsBiDiModeStored: Boolean;
-
-begin
-  Result := not (coParentBiDiMode in FOptions);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.IsCaptionAlignmentStored: Boolean;
-
-begin
-  Result := coUseCaptionAlignment in FOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.IsColorStored: Boolean;
-
-begin
-  Result := not (coParentColor in FOptions);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetAlignment(const Value: TAlignment);
-
-begin
-  if FAlignment <> Value then
-  begin
-    FAlignment := Value;
-    Changed(False);
-    // Setting the alignment affects also the tree, hence invalidate it too.
-    Owner.Header.TreeView.Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetBiDiMode(Value: TBiDiMode);
-
-begin
-  if Value <> FBiDiMode then
-  begin
-    FBiDiMode := Value;
-    Exclude(FOptions, coParentBiDiMode);
-    Changed(False);
-    // Setting the alignment affects also the tree, hence invalidate it too.
-    Owner.Header.TreeView.Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetCaptionAlignment(const Value: TAlignment);
-
-begin
-  if not (coUseCaptionAlignment in FOptions) or (FCaptionAlignment <> Value) then
-  begin
-    FCaptionAlignment := Value;
-    Exclude(FOptions, coUseCaptionAlignment);
-    // Setting the alignment affects also the tree, hence invalidate it too.
-    Owner.Header.Invalidate(Self);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetColor(const Value: TColor);
-
-begin
-  if FColor <> Value then
-  begin
-    FColor := Value;
-    Exclude(FOptions, coParentColor);
-    Changed(False);
-    Owner.Header.TreeView.Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetCheckBox(Value: boolean);
-
-begin
-  if Value <> FCheckBox then
-  begin
-    FCheckBox := Value;
-    //lcl
-    if FCheckBox then
-      Owner.Header.Treeview.CheckImageListNeeded;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetCheckState(Value: TCheckState);
-
-begin
-  if Value <> FCheckState then
-  begin
-    FCheckState := Value;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetCheckType(Value: TCheckType);
-
-begin
-  if Value <> FCheckType then
-  begin
-    FCheckType := Value;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetImageIndex(Value: TImageIndex);
-
-begin
-  if Value <> FImageIndex then
-  begin
-    FImageIndex := Value;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetLayout(Value: TVTHeaderColumnLayout);
-
-begin
-  if FLayout <> Value then
-  begin
-    FLayout := Value;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetMargin(Value: Integer);
-
-begin
-  // Compatibility setting for -1.
-  if Value < 0 then
-    Value := 4;
-  if FMargin <> Value then
-  begin
-    FMargin := Value;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetMaxWidth(Value: Integer);
-
-begin
-  if Value < FMinWidth then
-    Value := FMinWidth;
-  if not IsWinNT and (Value > 10000) then
-    Value := 10000;
-  FMaxWidth := Value;
-  SetWidth(FWidth);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetMinWidth(Value: Integer);
-
-begin
-  if Value < 0 then
-    Value := 0;
-  if Value > FMaxWidth then
-    Value := FMaxWidth;
-  FMinWidth := Value;
-  SetWidth(FWidth);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetOptions(Value: TVTColumnOptions);
-
-var
-  ToBeSet,
-  ToBeCleared: TVTColumnOptions;
-  AVisibleChanged,
-  ColorChanged: Boolean;
-
-begin
-  if FOptions <> Value then
-  begin
-    ToBeCleared := FOptions - Value;
-    ToBeSet := Value - FOptions;
-
-    FOptions := Value;
-
-    AVisibleChanged := coVisible in (ToBeSet + ToBeCleared);
-    ColorChanged := coParentColor in ToBeSet;
-
-    if coParentBidiMode in ToBeSet then
-      ParentBiDiModeChanged;
-    if ColorChanged then
-      ParentColorChanged;
-
-    if coAutoSpring in ToBeSet then
-      FSpringRest := 0;
-
-    if ((coFixed in ToBeSet) or (coFixed in ToBeCleared)) and (coVisible in FOptions) then
-      Owner.Header.RescaleHeader;
-
-    Changed(False);
-    // Need to repaint and adjust the owner tree too.
-
-    //lcl: fpc refuses to compile the original code by no aparent reason.
-    //Found: Was confounding TControl.VisibleChanged
-    with Owner, Header.Treeview do
-      if not (csLoading in ComponentState) and (AVisibleChanged or ColorChanged) and (UpdateCount = 0) and
-        HandleAllocated then
-      begin
-        Invalidate;
-        if AVisibleChanged then
-          UpdateHorizontalScrollBar(False);
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetPosition(Value: TColumnPosition);
-
-var
-  Temp: TColumnIndex;
-
-begin
-  if csLoading in Owner.Header.Treeview.ComponentState then
-    // Only cache the position for final fixup when loading from DFM.
-    FPosition := Value
-  else
-  begin
-    if Value >= TColumnPosition(Collection.Count) then
-      Value := Collection.Count - 1;
-    if FPosition <> Value then
-    begin
-      with Owner do
-      begin
-        InitializePositionArray;
-        Header.Treeview.CancelEditNode;
-        AdjustPosition(Self, Value);
-        Self.Changed(False);
-
-        // Need to repaint.
-        with Header do
-        begin
-          if (UpdateCount = 0) and Treeview.HandleAllocated then
-          begin
-            Invalidate(Self);
-            Treeview.Invalidate;
-          end;
-        end;
-      end;
-
-      // If the moved column is now within the fixed columns then we make it fixed as well. If it's not
-      // we clear the fixed state (in case that fixed column is moved outside fixed area).
-      if (coFixed in FOptions) and (FPosition > 0) then
-        Temp := Owner.ColumnFromPosition(FPosition - 1)
-      else
-        Temp := Owner.ColumnFromPosition(FPosition + 1);
-
-      if Temp <> NoColumn then
-      begin
-        if coFixed in Owner[Temp].Options then
-          Options := Options + [coFixed]
-        else
-          Options := Options - [coFixed]
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetSpacing(Value: Integer);
-
-begin
-  if FSpacing <> Value then
-  begin
-    FSpacing := Value;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetStyle(Value: TVirtualTreeColumnStyle);
-
-begin
-  if FStyle <> Value then
-  begin
-    FStyle := Value;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetText(const Value: String);
-
-begin
-  if FText <> Value then
-  begin
-    FText := Value;
-    Changed(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SetWidth(Value: Integer);
-
-var
-  EffectiveMaxWidth,
-  EffectiveMinWidth,
-  TotalFixedMaxWidth,
-  TotalFixedMinWidth: Integer;
-  I: TColumnIndex;
-
-begin
-  if not (hsScaling in Owner.FHeader.FStates) then
-    if ([coVisible, coFixed] * FOptions = [coVisible, coFixed]) then
-    begin
-      with Owner, FHeader, FFixedAreaConstraints, TreeView do
-      begin
-        TotalFixedMinWidth := 0;
-        TotalFixedMaxWidth := 0;
-        for I := 0 to FColumns.Count - 1 do
-          if ([coVisible, coFixed] * FColumns[I].FOptions = [coVisible, coFixed]) then
-          begin
-            Inc(TotalFixedMaxWidth, FColumns[I].FMaxWidth);
-            Inc(TotalFixedMinWidth, FColumns[I].FMinWidth);
-          end;
-
-        // The percentage values have precedence over the pixel values.
-        TotalFixedMinWidth := IfThen(FMaxWidthPercent > 0,
-                                     Min((ClientWidth * FMaxWidthPercent) div 100, TotalFixedMinWidth),
-                                     TotalFixedMinWidth);
-        TotalFixedMaxWidth := IfThen(FMinWidthPercent > 0,
-                                     Max((ClientWidth * FMinWidthPercent) div 100, TotalFixedMaxWidth),
-                                     TotalFixedMaxWidth);
-
-        EffectiveMaxWidth := Min(TotalFixedMaxWidth - (GetVisibleFixedWidth - Self.FWidth), FMaxWidth);
-        EffectiveMinWidth := Max(TotalFixedMinWidth - (GetVisibleFixedWidth - Self.FWidth), FMinWidth);
-        Value := Min(Max(Value, EffectiveMinWidth), EffectiveMaxWidth);
-
-        if FMinWidthPercent > 0 then
-          Value := Max((ClientWidth * FMinWidthPercent) div 100 - GetVisibleFixedWidth + Self.FWidth, Value);
-        if FMaxWidthPercent > 0 then
-          Value := Min((ClientWidth * FMaxWidthPercent) div 100 - GetVisibleFixedWidth + Self.FWidth, Value);
-      end;
-    end
-    else
-      Value := Min(Max(Value, FMinWidth), FMaxWidth);
-
-  if FWidth <> Value then
-  begin
-    FLastWidth := FWidth;
-    if not (hsResizing in Owner.Header.States) then
-      FBonusPixel := False;
-    with Owner, Header do
-    begin
-      if not (hoAutoResize in FOptions) or (Index <> FAutoSizeIndex) then
-      begin
-        FWidth := Value;
-        UpdatePositions;
-      end;
-      if not (csLoading in Treeview.ComponentState) and (UpdateCount = 0) then
-      begin
-        if hoAutoResize in FOptions then
-          AdjustAutoSize(Index);
-        Treeview.DoColumnResize(Index);
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.ComputeHeaderLayout(DC: HDC; const Client: TRect; UseHeaderGlyph, UseSortGlyph: Boolean;
-  var HeaderGlyphPos, SortGlyphPos: TPoint; var TextBounds: TRect; DrawFormat: Cardinal;
-  CalculateTextRect: Boolean = False);
-
-// The layout of a column header is determined by a lot of factors. This method takes them all into account and
-// determines all necessary positions and bounds:
-// - for the header text
-// - the header glyph
-// - the sort glyph
-
-var
-  TextSize: TSize;
-  TextPos,
-  ClientSize,
-  HeaderGlyphSize,
-  SortGlyphSize: TPoint;
-  CurrentAlignment: TAlignment;
-  MinLeft,
-  MaxRight,
-  TextSpacing: Integer;
-  UseText: Boolean;
-  R: TRect;
-
-begin
-  UseText := Length(FText) > 0;
-  // If nothing is to show then don't waste time with useless preparation.
-  if not (UseText or UseHeaderGlyph or UseSortGlyph) then
-    Exit;
-
-  CurrentAlignment := CaptionAlignment;
-  if FBidiMode <> bdLeftToRight then
-    ChangeBiDiModeAlignment(CurrentAlignment);
-
-  // Calculate sizes of the involved items.
-  ClientSize := Point(Client.Right - Client.Left, Client.Bottom - Client.Top);
-  with Owner, Header do
-  begin
-    if UseHeaderGlyph then
-      if not FCheckBox then
-        HeaderGlyphSize := Point(FImages.Width, FImages.Height)
-      else
-        HeaderGlyphSize := Point(Treeview.CheckImages.Width, Treeview.CheckImages.Height)
-    else
-      HeaderGlyphSize := Point(0, 0);
-    if UseSortGlyph then
-    begin
-      SortGlyphSize := Point(UtilityImages.Height, UtilityImages.Height);
-      // In any case, the sort glyph is vertically centered.
-      SortGlyphPos.Y := (ClientSize.Y - SortGlyphSize.Y) div 2;
-    end
-    else
-      SortGlyphSize := Point(0, 0);
-  end;
-
-  if UseText then
-  begin
-    if not (coWrapCaption in FOptions) then
-    begin
-      FCaptionText := FText;
-      GetTextExtentPoint32(DC, PChar(FText), Length(FText), TextSize);
-      Inc(TextSize.cx, 2);
-      TextBounds := Rect(0, 0, TextSize.cx, TextSize.cy);
-    end
-    else
-    begin
-      R := Client;
-      if FCaptionText = '' then
-        FCaptionText := FText;
-
-      GetStringDrawRect(DC, FCaptionText, R, DrawFormat);
-      TextSize.cx := Client.Right - Client.Left;
-      TextSize.cy := R.Bottom - R.Top;
-      TextBounds  := Rect(0, 0, TextSize.cx, TextSize.cy);
-    end;
-    TextSpacing := FSpacing;
-  end
-  else
-  begin
-    TextSpacing := 0;
-    TextSize.cx := 0;
-    TextSize.cy := 0;
-  end;
-
-  // Check first for the special case where nothing is shown except the sort glyph.
-  if UseSortGlyph and not (UseText or UseHeaderGlyph) then
-  begin
-    // Center the sort glyph in the available area if nothing else is there.
-    SortGlyphPos := Point((ClientSize.X - SortGlyphSize.X) div 2, (ClientSize.Y - SortGlyphSize.Y) div 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 UseHeaderGlyph then
-    begin
-      HeaderGlyphPos.Y := (ClientSize.Y - HeaderGlyphSize.Y) div 2;
-      // If the text is taller than the given height, perform no vertical centration as this
-      // would make the text even less readable.
-      if TextSize.cy >= ClientSize.Y then
-        TextPos.Y := 0
-      else
-        TextPos.Y := (ClientSize.Y - TextSize.cy) div 2;
-    end
-    else
-    begin
-      if Layout = blGlyphTop then
-      begin
-        HeaderGlyphPos.Y := (ClientSize.Y - HeaderGlyphSize.Y - TextSize.cy - TextSpacing) div 2;
-        TextPos.Y := HeaderGlyphPos.Y + HeaderGlyphSize.Y + TextSpacing;
-      end
-      else
-      begin
-        TextPos.Y := (ClientSize.Y - HeaderGlyphSize.Y - TextSize.cy - TextSpacing) div 2;
-        HeaderGlyphPos.Y := TextPos.Y + TextSize.cy + TextSpacing;
-      end;
-    end;
-
-    // Each alignment needs special consideration.
-    case CurrentAlignment of
-      taLeftJustify:
-        begin
-          MinLeft := FMargin;
-          if UseSortGlyph and (FBidiMode <> bdLeftToRight) then
-          begin
-            // In RTL context is the sort glyph placed on the left hand side.
-            SortGlyphPos.X := MinLeft;
-            Inc(MinLeft, SortGlyphSize.X + FSpacing);
-          end;
-          if Layout in [blGlyphTop, blGlyphBottom] then
-          begin
-            // Header glyph is above or below text, so both must be considered when calculating
-            // the left positition of the sort glyph (if it is on the right hand side).
-            TextPos.X := MinLeft;
-            if UseHeaderGlyph then
-            begin
-              HeaderGlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2;
-              if HeaderGlyphPos.X < MinLeft then
-                HeaderGlyphPos.X := MinLeft;
-              MinLeft := Max(TextPos.X + TextSize.cx + TextSpacing, HeaderGlyphPos.X + HeaderGlyphSize.X + FSpacing);
-            end
-            else
-              MinLeft := TextPos.X + TextSize.cx + TextSpacing;
-          end
-          else
-          begin
-            // Everything is lined up. TextSpacing might be 0 if there is no text.
-            // This simplifies the calculation because no extra tests are necessary.
-            if UseHeaderGlyph and (Layout = blGlyphLeft) then
-            begin
-              HeaderGlyphPos.X := MinLeft;
-              Inc(MinLeft, HeaderGlyphSize.X + FSpacing);
-            end;
-            TextPos.X := MinLeft;
-            Inc(MinLeft, TextSize.cx + TextSpacing);
-            if UseHeaderGlyph and (Layout = blGlyphRight) then
-            begin
-              HeaderGlyphPos.X := MinLeft;
-              Inc(MinLeft, HeaderGlyphSize.X + FSpacing);
-            end;
-          end;
-          if UseSortGlyph and (FBidiMode = bdLeftToRight) then
-            SortGlyphPos.X := MinLeft;
-        end;
-      taCenter:
-        begin
-          if Layout in [blGlyphTop, blGlyphBottom] then
-          begin
-            HeaderGlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2;
-            TextPos.X := (ClientSize.X - TextSize.cx) div 2;
-            if UseSortGlyph then
-              Dec(TextPos.X, SortGlyphSize.X div 2);
-          end
-          else
-          begin
-            MinLeft := (ClientSize.X - HeaderGlyphSize.X - TextSpacing - TextSize.cx) div 2;
-            if UseHeaderGlyph and (Layout = blGlyphLeft) then
-            begin
-              HeaderGlyphPos.X := MinLeft;
-              Inc(MinLeft, HeaderGlyphSize.X + TextSpacing);
-            end;
-            TextPos.X := MinLeft;
-            Inc(MinLeft, TextSize.cx + TextSpacing);
-            if UseHeaderGlyph and (Layout = blGlyphRight) then
-              HeaderGlyphPos.X := MinLeft;
-          end;
-          if UseHeaderGlyph then
-          begin
-            MinLeft := Min(HeaderGlyphPos.X, TextPos.X);
-            MaxRight := Max(HeaderGlyphPos.X + HeaderGlyphSize.X, TextPos.X + TextSize.cx);
-          end
-          else
-          begin
-            MinLeft := TextPos.X;
-            MaxRight := TextPos.X + TextSize.cx;
-          end;
-          // Place the sort glyph directly to the left or right of the larger item.
-          if UseSortGlyph then
-            if FBidiMode = bdLeftToRight then
-            begin
-              // Sort glyph on the right hand side.
-              SortGlyphPos.X := MaxRight + FSpacing;
-            end
-            else
-            begin
-              // Sort glyph on the left hand side.
-              SortGlyphPos.X := MinLeft - FSpacing - SortGlyphSize.X;
-            end;
-        end;
-    else
-      // taRightJustify
-      MaxRight := ClientSize.X - FMargin;
-      if UseSortGlyph and (FBidiMode = bdLeftToRight) then
-      begin
-        // In LTR context is the sort glyph placed on the right hand side.
-        Dec(MaxRight, SortGlyphSize.X);
-        SortGlyphPos.X := MaxRight;
-        Dec(MaxRight, FSpacing);
-      end;
-      if Layout in [blGlyphTop, blGlyphBottom] then
-      begin
-        TextPos.X := MaxRight - TextSize.cx;
-        if UseHeaderGlyph then
-        begin
-          HeaderGlyphPos.X := (ClientSize.X - HeaderGlyphSize.X) div 2;
-          if HeaderGlyphPos.X + HeaderGlyphSize.X + FSpacing > MaxRight then
-            HeaderGlyphPos.X := MaxRight - HeaderGlyphSize.X - FSpacing;
-          MaxRight := Min(TextPos.X - TextSpacing, HeaderGlyphPos.X - FSpacing);
-        end
-        else
-          MaxRight := TextPos.X - TextSpacing;
-      end
-      else
-      begin
-        // Everything is lined up. TextSpacing might be 0 if there is no text.
-        // This simplifies the calculation because no extra tests are necessary.
-        if UseHeaderGlyph and (Layout = blGlyphRight) then
-        begin
-          HeaderGlyphPos.X := MaxRight -  HeaderGlyphSize.X;
-          MaxRight := HeaderGlyphPos.X - FSpacing;
-        end;
-        TextPos.X := MaxRight - TextSize.cx;
-        MaxRight := TextPos.X - TextSpacing;
-        if UseHeaderGlyph and (Layout = blGlyphLeft) then
-        begin
-          HeaderGlyphPos.X := MaxRight - HeaderGlyphSize.X;
-          MaxRight := HeaderGlyphPos.X - FSpacing;
-        end;
-      end;
-      if UseSortGlyph and (FBidiMode <> bdLeftToRight) then
-        SortGlyphPos.X := MaxRight - SortGlyphSize.X;
-    end;
-  end;
-
-  // Once the position of each element is determined there remains only one but important step.
-  // The horizontal positions of every element must be adjusted so that it always fits into the
-  // given header area. This is accomplished by shorten the text appropriately.
-
-  // These are the maximum bounds. Nothing goes beyond them.
-  MinLeft := FMargin;
-  MaxRight := ClientSize.X - FMargin;
-  if UseSortGlyph then
-  begin
-    if FBidiMode = bdLeftToRight then
-    begin
-      // Sort glyph on the right hand side.
-      if SortGlyphPos.X + SortGlyphSize.X > MaxRight then
-        SortGlyphPos.X := MaxRight - SortGlyphSize.X;
-      MaxRight := SortGlyphPos.X - FSpacing;
-    end;
-
-    // Consider also the left side of the sort glyph regardless of the bidi mode.
-    if SortGlyphPos.X < MinLeft then
-      SortGlyphPos.X := MinLeft;
-    // Left border needs only adjustment if the sort glyph marks the left border.
-    if FBidiMode <> bdLeftToRight then
-      MinLeft := SortGlyphPos.X + SortGlyphSize.X + FSpacing;
-
-    // Finally transform sort glyph to its actual position.
-    with SortGlyphPos do
-    begin
-      Inc(X, Client.Left);
-      Inc(Y, Client.Top);
-    end;
-  end;
-  if UseHeaderGlyph then
-  begin
-    if HeaderGlyphPos.X + HeaderGlyphSize.X > MaxRight then
-      HeaderGlyphPos.X := MaxRight - HeaderGlyphSize.X;
-    if Layout = blGlyphRight then
-      MaxRight := HeaderGlyphPos.X - FSpacing;
-    if HeaderGlyphPos.X < MinLeft then
-      HeaderGlyphPos.X := MinLeft;
-    if Layout = blGlyphLeft then
-      MinLeft := HeaderGlyphPos.X + HeaderGlyphSize.X + FSpacing;
-    // Finally transform header glyph to its actual position.
-    with HeaderGlyphPos do
-    begin
-      Inc(X, Client.Left);
-      Inc(Y, Client.Top);
-    end;
-  end;
-  if UseText then
-  begin
-    if TextPos.X < MinLeft then
-      TextPos.X := MinLeft;
-    OffsetRect(TextBounds, TextPos.X, TextPos.Y);
-    if TextBounds.Right > MaxRight then
-      TextBounds.Right := MaxRight;
-    OffsetRect(TextBounds, Client.Left, Client.Top);
-
-    if coWrapCaption in FOptions then
-    begin
-      // Wrap the column caption if necessary.
-      R := TextBounds;
-      FCaptionText := WrapString(DC, FText, R, DT_RTLREADING and DrawFormat <> 0, DrawFormat);
-      GetStringDrawRect(DC, FCaptionText, R, DrawFormat);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.GetAbsoluteBounds(var Left, Right: Integer);
-
-// Returns the column's left and right bounds in header coordinates, that is, independent of the scrolling position.
-
-begin
-  Left := FLeft;
-  Right := FLeft + FWidth;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.GetDisplayName: string;
-
-// Returns the column text otherwise the column id is returned
-
-begin
-  if Length(FText) > 0 then
-    Result := FText
-  else
-    Result := Format('Column %d', [Index]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.GetOwner: TVirtualTreeColumns;
-
-begin
-  Result := Collection as TVirtualTreeColumns;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.Assign(Source: TPersistent);
-
-var
-  OldOptions: TVTColumnOptions;
-
-begin
-  if Source is TVirtualTreeColumn then
-  begin
-    OldOptions := FOptions;
-    FOptions := [];
-
-    BiDiMode := TVirtualTreeColumn(Source).BiDiMode;
-    ImageIndex := TVirtualTreeColumn(Source).ImageIndex;
-    Layout := TVirtualTreeColumn(Source).Layout;
-    Margin := TVirtualTreeColumn(Source).Margin;
-    MaxWidth := TVirtualTreeColumn(Source).MaxWidth;
-    MinWidth := TVirtualTreeColumn(Source).MinWidth;
-    Position := TVirtualTreeColumn(Source).Position;
-    Spacing := TVirtualTreeColumn(Source).Spacing;
-    Style := TVirtualTreeColumn(Source).Style;
-    Text := TVirtualTreeColumn(Source).Text;
-    Hint := TVirtualTreeColumn(Source).Hint;
-    Width := TVirtualTreeColumn(Source).Width;
-    Alignment := TVirtualTreeColumn(Source).Alignment;
-    CaptionAlignment := TVirtualTreeColumn(Source).CaptionAlignment;
-    Color := TVirtualTreeColumn(Source).Color;
-    Tag := TVirtualTreeColumn(Source).Tag;
-
-    // Order is important. Assign options last.
-    FOptions := OldOptions;
-    Options := TVirtualTreeColumn(Source).Options;
-
-    Changed(False);
-  end
-  else
-    inherited Assign(Source);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.Equals(OtherColumnObj: TObject): Boolean;
-var
- OtherColumn : TVirtualTreeColumn;
-begin
-  if OtherColumnObj is TVirtualTreeColumn then
-  begin
-    OtherColumn :=  TVirtualTreeColumn (OtherColumnObj);
-    Result := (BiDiMode = OtherColumn.BiDiMode) and
-      (ImageIndex = OtherColumn.ImageIndex) and
-      (Layout = OtherColumn.Layout) and
-      (Margin = OtherColumn.Margin) and
-      (MaxWidth = OtherColumn.MaxWidth) and
-      (MinWidth = OtherColumn.MinWidth) and
-      (Position = OtherColumn.Position) and
-      (Spacing = OtherColumn.Spacing) and
-      (Style = OtherColumn.Style) and
-      (Text = OtherColumn.Text) and
-      (Hint = OtherColumn.Hint) and
-      (Width = OtherColumn.Width) and
-      (Alignment = OtherColumn.Alignment) and
-      (CaptionAlignment = OtherColumn.CaptionAlignment) and
-      (Color = OtherColumn.Color) and
-      (Tag = OtherColumn.Tag) and
-      (Options = OtherColumn.Options)
-  end
-  else
-    Result := False
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.GetRect: TRect;
-
-// Returns the rectangle this column occupies in the header (relative to (0, 0) of the non-client area).
-
-begin
-  with TVirtualTreeColumns(GetOwner).FHeader do
-    Result := Treeview.FHeaderRect;
-  Inc(Result.Left, FLeft);
-  Result.Right := Result.Left + FWidth;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.LoadFromStream(const Stream: TStream; Version: Integer);
-
-var
-  Dummy: Integer;
-  S: String;
-
-begin
-  with Stream do
-  begin
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    SetLength(S, Dummy);
-    ReadBuffer(PChar(S)^, Dummy);
-    Text := S;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    SetLength(FHint, Dummy);
-    ReadBuffer(PChar(FHint)^, Dummy);
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Width := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    MinWidth := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    MaxWidth := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Style := TVirtualTreeColumnStyle(Dummy);
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    ImageIndex := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Layout := TVTHeaderColumnLayout(Dummy);
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Margin := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Spacing := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    BiDiMode := TBiDiMode(Dummy);
-
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Options := TVTColumnOptions(Word(Dummy and $FFFF));
-
-    // Parts which have been introduced/changed with header stream version 1+.
-    // LCL port started with header stream version 6 so no need to do the check here
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Tag := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Alignment := TAlignment(Dummy);
-
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Color := TColor(Dummy);
-
-    if coUseCaptionAlignment in FOptions then
-    begin
-      ReadBuffer(Dummy, SizeOf(Dummy));
-      CaptionAlignment := TAlignment(Dummy);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.ParentBiDiModeChanged;
-
-var
-  Columns: TVirtualTreeColumns;
-
-begin
-  if coParentBiDiMode in FOptions then
-  begin
-    Columns := GetOwner as TVirtualTreeColumns;
-    if Assigned(Columns) and (FBidiMode <> Columns.FHeader.Treeview.BiDiMode) then
-    begin
-      FBiDiMode := Columns.FHeader.Treeview.BiDiMode;
-      Changed(False);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.ParentColorChanged;
-
-var
-  Columns: TVirtualTreeColumns;
-  TreeViewColor: TColor;
-begin
-  if coParentColor in FOptions then
-  begin
-    Columns := GetOwner as TVirtualTreeColumns;
-    if Assigned(Columns) then
-    begin
-      TreeViewColor := Columns.FHeader.Treeview.Brush.Color;
-      if FColor <> TreeViewColor then
-      begin
-        FColor := TreeViewColor;
-        Changed(False);
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.RestoreLastWidth;
-
-begin
-  TVirtualTreeColumns(GetOwner).AnimatedResize(Index, FLastWidth);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumn.SaveToStream(const Stream: TStream);
-
-var
-  Dummy: Integer;
-
-begin
-  with Stream do
-  begin
-    Dummy := Length(FText);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    WriteBuffer(PChar(FText)^, Dummy);
-    Dummy := Length(FHint);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    WriteBuffer(PChar(FHint)^, Dummy);
-    WriteBuffer(FWidth, SizeOf(FWidth));
-    WriteBuffer(FMinWidth, SizeOf(FMinWidth));
-    WriteBuffer(FMaxWidth, SizeOf(FMaxWidth));
-    Dummy := Ord(FStyle);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    Dummy := FImageIndex;
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    Dummy := Ord(FLayout);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    WriteBuffer(FMargin, SizeOf(FMargin));
-    WriteBuffer(FSpacing, SizeOf(FSpacing));
-    Dummy := Ord(FBiDiMode);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    Dummy := Word(FOptions);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-
-    // parts introduced with stream version 1
-    WriteBuffer(FTag, SizeOf(Dummy));
-    Dummy := Cardinal(FAlignment);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-
-    // parts introduced with stream version 2
-    Dummy := Integer(FColor);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-
-    // parts introduced with stream version 6
-    if coUseCaptionAlignment in FOptions then
-    begin
-      Dummy := Cardinal(FCaptionAlignment);
-      WriteBuffer(Dummy, SizeOf(Dummy));
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumn.UseRightToLeftReading: Boolean;
-
-begin
-  Result := FBiDiMode <> bdLeftToRight;
-end;
-
-//----------------- TVirtualTreeColumns --------------------------------------------------------------------------------
-
-constructor TVirtualTreeColumns.Create(AOwner: TVTHeader);
-
-var
-  ColumnClass: TVirtualTreeColumnClass;
-
-begin
-  FHeader := AOwner;
-
-  // Determine column class to be used in the header.
-  ColumnClass := AOwner.FOwner.GetColumnClass;
-  // The owner tree always returns the default tree column class if not changed by application/descendants.
-  inherited Create(ColumnClass);
-
-  FHeaderBitmap := TBitmap.Create;
-  FHeaderBitmap.PixelFormat := pf32Bit;
-
-  FHoverIndex := NoColumn;
-  FDownIndex := NoColumn;
-  FClickIndex := NoColumn;
-  FDropTarget := NoColumn;
-  FTrackIndex := NoColumn;
-  FDefaultWidth := 50;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVirtualTreeColumns.Destroy;
-
-begin
-  FHeaderBitmap.Free;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetCount: Integer;
-
-begin
-  Result := inherited Count;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetItem(Index: TColumnIndex): TVirtualTreeColumn;
-
-begin
-  Result := TVirtualTreeColumn(inherited GetItem(Index));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetNewIndex(P: TPoint; var OldIndex: TColumnIndex): Boolean;
-
-var
-  NewIndex: Integer;
-
-begin
-  Result := False;
-  // convert to local coordinates
-  Inc(P.Y, FHeader.FHeight);
-  NewIndex := ColumnFromPosition(P);
-  if NewIndex <> OldIndex then
-  begin
-    if OldIndex > NoColumn then
-      FHeader.Invalidate(Items[OldIndex]);
-    OldIndex := NewIndex;
-    if OldIndex > NoColumn then
-      FHeader.Invalidate(Items[OldIndex]);
-    Result := True;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.SetDefaultWidth(Value: Integer);
-
-begin
-  FDefaultWidth := Value;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.SetItem(Index: TColumnIndex; Value: TVirtualTreeColumn);
-
-begin
-  inherited SetItem(Index, Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.AdjustAutoSize(CurrentIndex: TColumnIndex; Force: Boolean = False);
-
-// Called only if the header is in auto-size mode which means a column needs to be so large
-// that it fills all the horizontal space not occupied by the other columns.
-// CurrentIndex (if not InvalidColumn) describes which column has just been resized.
-
-var
-  NewValue,
-  AutoIndex,
-  Index,
-  RestWidth: Integer;
-
-begin
-  if Count > 0 then
-  begin
-    // Determine index to be used for auto resizing. This is usually given by the owner's AutoSizeIndex, but
-    // could be different if the column whose resize caused the invokation here is either the auto column itself
-    // or visually to the right of the auto size column.
-    AutoIndex := FHeader.FAutoSizeIndex;
-    if (AutoIndex < 0) or (AutoIndex >= Count) then
-      AutoIndex := Count - 1;
-
-    if AutoIndex >= 0 then
-    begin
-      with FHeader.Treeview do
-      begin
-        if HandleAllocated then
-          RestWidth := ClientWidth
-        else
-          RestWidth := Width;
-      end;
-
-      // Go through all columns and calculate the rest space remaining.
-      for Index := 0 to Count - 1 do
-        if (Index <> AutoIndex) and (coVisible in Items[Index].FOptions) then
-          Dec(RestWidth, Items[Index].Width);
-
-      with Items[AutoIndex] do
-      begin
-        NewValue := Max(MinWidth, Min(MaxWidth, RestWidth));
-        if Force or (FWidth <> NewValue) then
-        begin
-          FWidth := NewValue;
-          UpdatePositions;
-          FHeader.Treeview.DoColumnResize(AutoIndex);
-        end;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.AdjustDownColumn(P: TPoint): TColumnIndex;
-
-// Determines the column from the given position and returns it. If this column is allowed to be clicked then
-// it is also kept for later use.
-
-begin
-  // Convert to local coordinates.
-  Inc(P.Y, FHeader.FHeight);
-  Result := ColumnFromPosition(P);
-  if (Result > NoColumn) and (Result <> FDownIndex) and (coAllowClick in Items[Result].FOptions) and
-    (coEnabled in Items[Result].FOptions) then
-  begin
-    if FDownIndex > NoColumn then
-      FHeader.Invalidate(Items[FDownIndex]);
-    FDownIndex := Result;
-    FHeader.Invalidate(Items[FDownIndex]);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.AdjustHoverColumn(const P: TPoint): Boolean;
-
-// Determines the new hover column index and returns True if the index actually changed else False.
-
-begin
-  Result := GetNewIndex(P, FHoverIndex);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.AdjustPosition(Column: TVirtualTreeColumn; Position: Cardinal);
-
-// Reorders the column position array so that the given column gets the given position.
-
-var
-  OldPosition: Cardinal;
-
-begin
-  OldPosition := Column.Position;
-  if OldPosition <> Position then
-  begin
-    if OldPosition < Position then
-    begin
-      // column will be moved up so move down other entries
-      Move(FPositionToIndex[OldPosition + 1], FPositionToIndex[OldPosition], (Position - OldPosition) * SizeOf(Cardinal));
-    end
-    else
-    begin
-      // column will be moved down so move up other entries
-      Move(FPositionToIndex[Position], FPositionToIndex[Position + 1], (OldPosition - Position) * SizeOf(Cardinal));
-    end;
-    FPositionToIndex[Position] := Column.Index;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.CanSplitterResize(P: TPoint; Column: TColumnIndex): Boolean;
-begin
-  Result := (Column > NoColumn) and ([coResizable, coVisible] * Items[Column].FOptions = [coResizable, coVisible]);
-  DoCanSplitterResize(P, Column, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.DoCanSplitterResize(P: TPoint; Column: TColumnIndex; var Allowed: Boolean);
-begin
-  if Assigned(FHeader.Treeview.FOnCanSplitterResizeColumn) then
-    FHeader.Treeview.FOnCanSplitterResizeColumn(FHeader, P, Column, Allowed);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.DrawButtonText(DC: HDC; Caption: String; Bounds: TRect; Enabled, Hot: Boolean;
-    DrawFormat: Cardinal; WrapCaption: Boolean);
-
-var
-  TextSpace: Integer;
-  Size: TSize;
-
-begin
-  if not WrapCaption then
-  begin
-    // Do we need to shorten the caption due to limited space?
-    GetTextExtentPoint32(DC, PChar(Caption), Length(Caption), Size);
-    TextSpace := Bounds.Right - Bounds.Left;
-    if TextSpace < Size.cx then
-      Caption := ShortenString(DC, Caption, TextSpace);
-  end;
-
-  SetBkMode(DC, TRANSPARENT);
-  if not Enabled then
-  begin
-    OffsetRect(Bounds, 1, 1);
-    SetTextColor(DC, ColorToRGB(clBtnHighlight));
-    DrawText(DC, PChar(Caption), Length(Caption), Bounds, DrawFormat);
-    OffsetRect(Bounds, -1, -1);
-    SetTextColor(DC, ColorToRGB(clBtnShadow));
-    DrawText(DC, PChar(Caption), Length(Caption), Bounds, DrawFormat);
-  end
-  else
-  begin
-    if Hot then
-      SetTextColor(DC, ColorToRGB(FHeader.Treeview.FColors.HeaderHotColor))
-    else
-      SetTextColor(DC, ColorToRGB(FHeader.FFont.Color));
-    DrawText(DC, PChar(Caption), Length(Caption), Bounds, DrawFormat);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// XP style header button legacy code. This procedure is only used on non-XP systems to simulate the themed
-// header style.
-// Note: the theme elements displayed here only correspond to the standard themes of Windows XP
-
-const
-  XPMainHeaderColorUp = $DBEAEB;       // Main background color of the header if drawn as being not pressed.
-  XPMainHeaderColorDown = $D8DFDE;     // Main background color of the header if drawn as being pressed.
-  XPMainHeaderColorHover = $F3F8FA;    // Main background color of the header if drawn as being under the mouse pointer.
-  XPDarkSplitBarColor = $B2C5C7;       // Dark color of the splitter bar.
-  XPLightSplitBarColor = $FFFFFF;      // Light color of the splitter bar.
-  XPDarkGradientColor = $B8C7CB;       // Darkest color in the bottom gradient. Other colors will be interpolated.
-  XPDownOuterLineColor = $97A5A5;      // Down state border color.
-  XPDownMiddleLineColor = $B8C2C1;     // Down state border color.
-  XPDownInnerLineColor = $C9D1D0;      // Down state border color.
-
-procedure TVirtualTreeColumns.DrawXPButton(DC: HDC; const ButtonR: TRect; DrawSplitter, Down, Hover: Boolean);
-
-// Helper procedure to draw an Windows XP like header button.
-
-var
-  PaintBrush: HBRUSH;
-  Pen,
-  OldPen: HPEN;
-  PenColor,
-  FillColor: COLORREF;
-  dRed, dGreen, dBlue: Single;
-  Width,
-  XPos: Integer;
-
-begin
-  if Down then
-    FillColor := XPMainHeaderColorDown
-  else
-    if Hover then
-      FillColor := XPMainHeaderColorHover
-    else
-      FillColor := XPMainHeaderColorUp;
-  PaintBrush := CreateSolidBrush(FillColor);
-  FillRect(DC, ButtonR, PaintBrush);
-  DeleteObject(PaintBrush);
-
-  if DrawSplitter and not (Down or Hover) then
-  begin
-    // One solid pen for the dark line...
-    Pen := CreatePen(PS_SOLID, 1, XPDarkSplitBarColor);
-    OldPen := SelectObject(DC, Pen);
-    MoveToEx(DC, ButtonR.Right - 2, ButtonR.Top + 3, nil);
-    LineTo(DC, ButtonR.Right - 2, ButtonR.Bottom - 5);
-    // ... and one solid pen for the light line.
-    Pen := CreatePen(PS_SOLID, 1, XPLightSplitBarColor);
-    DeleteObject(SelectObject(DC, Pen));
-    MoveToEx(DC, ButtonR.Right - 1, ButtonR.Top + 3, nil);
-    LineTo(DC, ButtonR.Right - 1, ButtonR.Bottom - 5);
-    SelectObject(DC, OldPen);
-    DeleteObject(Pen);
-  end;
-
-  if Down then
-  begin
-    // Down state. Three lines to draw.
-    // First one is the outer line, drawn at left, bottom and right.
-    Pen := CreatePen(PS_SOLID, 1, XPDownOuterLineColor);
-    OldPen := SelectObject(DC, Pen);
-    MoveToEx(DC, ButtonR.Left, ButtonR.Top, nil);
-    LineTo(DC, ButtonR.Left, ButtonR.Bottom - 1);
-    LineTo(DC, ButtonR.Right - 1, ButtonR.Bottom - 1);
-    LineTo(DC, ButtonR.Right - 1, ButtonR.Top - 1);
-
-    // Second one is the middle line, which is a bit lighter.
-    Pen := CreatePen(PS_SOLID, 1, XPDownMiddleLineColor);
-    DeleteObject(SelectObject(DC, Pen));
-    MoveToEx(DC, ButtonR.Left + 1, ButtonR.Bottom - 2, nil);
-    LineTo(DC, ButtonR.Left + 1, ButtonR.Top);
-    LineTo(DC, ButtonR.Right - 1, ButtonR.Top);
-
-    // Third line is the inner line, which is even lighter than the middle line.
-    Pen := CreatePen(PS_SOLID, 1, XPDownInnerLineColor);
-    DeleteObject(SelectObject(DC, Pen));
-    MoveToEx(DC, ButtonR.Left + 2, ButtonR.Bottom - 2, nil);
-    LineTo(DC, ButtonR.Left + 2, ButtonR.Top + 1);
-    LineTo(DC, ButtonR.Right - 1, ButtonR.Top + 1);
-
-    // Housekeeping:
-    SelectObject(DC, OldPen);
-    DeleteObject(Pen);
-  end
-  else
-    if Hover then
-    begin
-      // Hover state. There are three lines at the bottom border, but they are rendered in a way which
-      // requires expensive construction.
-      Width := ButtonR.Right - ButtonR.Left;
-      if Width <= 32 then
-      begin
-        BitBlt(DC, ButtonR.Right - 16, ButtonR.Bottom - 3, UtilityImageSize, 3, UtilityImages.Canvas.Handle,
-           8 * UtilityImageSize, 0, SRCCOPY);
-        //ImageList_DrawEx(UtilityImages.Handle, 8, DC, ButtonR.Right - 16, ButtonR.Bottom - 3, 16, 3, CLR_NONE, CLR_NONE,
-        //  ILD_NORMAL);
-        BitBlt(DC, ButtonR.Left, ButtonR.Bottom - 3, Width div 2, 3, UtilityImages.Canvas.Handle,
-            6 * UtilityImageSize, 0, SRCCOPY);
-        //ImageList_DrawEx(UtilityImages.Handle, 6, DC, ButtonR.Left, ButtonR.Bottom - 3, Width div 2, 3, CLR_NONE,
-        //  CLR_NONE, ILD_NORMAL);
-      end
-      else
-      begin
-        BitBlt(DC, ButtonR.Left, ButtonR.Bottom - 3, UtilityImageSize, 3, UtilityImages.Canvas.Handle,
-            6 * UtilityImageSize, 0, SRCCOPY);
-        //ImageList_DrawEx(UtilityImages.Handle, 6, DC, ButtonR.Left, ButtonR.Bottom - 3, 16, 3, CLR_NONE, CLR_NONE,
-        //  ILD_NORMAL);
-        // Replicate inner part as many times as need to fill up the button rectangle.
-        XPos := ButtonR.Left + 16;
-        repeat
-          BitBlt(DC, XPos, ButtonR.Bottom - 3, UtilityImageSize, 3, UtilityImages.Canvas.Handle,
-            7 * UtilityImageSize, 0, SRCCOPY);
-          //ImageList_DrawEx(UtilityImages.Handle, 7, DC, XPos, ButtonR.Bottom - 3, 16, 3, CLR_NONE, CLR_NONE, ILD_NORMAL);
-          Inc(XPos, 16);
-        until XPos + 16 >= ButtonR.Right;
-        BitBlt(DC, ButtonR.Right - 16, ButtonR.Bottom - 3, UtilityImageSize, 3, UtilityImages.Canvas.Handle,
-            8 * UtilityImageSize, 0, SRCCOPY);
-        //ImageList_DrawEx(UtilityImages.Handle, 8, DC, ButtonR.Right - 16, ButtonR.Bottom - 3, 16, 3, CLR_NONE, CLR_NONE,
-        //  ILD_NORMAL);
-      end;
-    end
-    else
-    begin
-      // There is a three line gradient near the bottom border which transforms from the button color to a dark,
-      // clBtnFace like color (here XPDarkGradientColor).
-      PenColor := XPMainHeaderColorUp;
-      dRed := ((PenColor and $FF) - (XPDarkGradientColor and $FF)) / 3;
-      dGreen := (((PenColor shr 8) and $FF) - ((XPDarkGradientColor shr 8) and $FF)) / 3;
-      dBlue := (((PenColor shr 16) and $FF) - ((XPDarkGradientColor shr 16) and $FF)) / 3;
-
-      // First line:
-      PenColor := PenColor - Round(dRed) - Round(dGreen) shl 8 - Round(dBlue) shl 16;
-      Pen := CreatePen(PS_SOLID, 1, PenColor);
-      OldPen := SelectObject(DC, Pen);
-      MoveToEx(DC, ButtonR.Left, ButtonR.Bottom - 3, nil);
-      LineTo(DC, ButtonR.Right, ButtonR.Bottom - 3);
-
-      // Second line:
-      PenColor := PenColor - Round(dRed) - Round(dGreen) shl 8 - Round(dBlue) shl 16;
-      Pen := CreatePen(PS_SOLID, 1, PenColor);
-      DeleteObject(SelectObject(DC, Pen));
-      MoveToEx(DC, ButtonR.Left, ButtonR.Bottom - 2, nil);
-      LineTo(DC, ButtonR.Right, ButtonR.Bottom - 2);
-
-      // Third line:
-      Pen := CreatePen(PS_SOLID, 1, XPDarkGradientColor);
-      DeleteObject(SelectObject(DC, Pen));
-      MoveToEx(DC, ButtonR.Left, ButtonR.Bottom - 1, nil);
-      LineTo(DC, ButtonR.Right, ButtonR.Bottom - 1);
-
-      // Housekeeping:
-      DeleteObject(SelectObject(DC, OldPen));
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.FixPositions;
-
-// Fixes column positions after loading from DFM or Bidi mode change.
-
-var
-  I: Integer;
-
-begin
-  for I := 0 to Count - 1 do
-    FPositionToIndex[Items[I].Position] := I;
-
-  FNeedPositionsFix := False;
-  UpdatePositions(True);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetColumnAndBounds(const P: TPoint; var ColumnLeft, ColumnRight: Integer;
-  Relative: Boolean = True): Integer;
-
-// Returns the column where the mouse is currently in as well as the left and right bound of
-// this column (Left and Right are undetermined if no column is involved).
-
-var
-  I: Integer;
-
-begin
-  Result := InvalidColumn;
-  if Relative and (P.X > Header.Columns.GetVisibleFixedWidth) then
-    ColumnLeft := -FHeader.Treeview.FEffectiveOffsetX
-  else
-    ColumnLeft := 0;
-
-  if FHeader.Treeview.UseRightToLeftAlignment then
-    Inc(ColumnLeft, FHeader.Treeview.ComputeRTLOffset(True));
-    
-  for I := 0 to Count - 1 do
-    with Items[FPositionToIndex[I]] do
-      if coVisible in FOptions then
-      begin
-        ColumnRight := ColumnLeft + FWidth;
-        if P.X < ColumnRight then
-        begin
-          Result := FPositionToIndex[I];
-          Exit;
-        end;
-        ColumnLeft := ColumnRight;
-      end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetOwner: TPersistent;
-
-begin
-  Result := FHeader;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.HandleClick(P: TPoint; Button: TMouseButton; Force, DblClick: Boolean);
-
-// Generates a click event if the mouse button has been released over the same column it was pressed first.
-// Alternatively, Force might be set to True to indicate that the down index does not matter (right, middle and
-// double click).
-
-var
-  NewClickIndex: Integer;
-  Shift: TShiftState;
-
-begin
-  // Convert vertical position to local coordinates.
-  Inc(P.Y, FHeader.FHeight);
-  NewClickIndex := ColumnFromPosition(P);
-  if (NewClickIndex > NoColumn) and (coAllowClick in Items[NewClickIndex].FOptions) and
-    ((NewClickIndex = FDownIndex) or Force) then
-  begin
-    FClickIndex := NewClickIndex;
-    Shift := FHeader.GetShiftState;
-    if DblClick then
-      Shift := Shift + [ssDouble];
-    if Items[NewClickIndex].FHasImage and PtInRect(Items[NewClickIndex].FImageRect, P) then
-    begin
-      if Items[NewClickIndex].CheckBox then
-      begin
-        FHeader.Treeview.UpdateColumnCheckState(Items[NewClickIndex]);
-        FHeader.Treeview.DoHeaderCheckBoxClick(NewClickIndex, Button, Shift, P.X, P.Y);
-      end
-      else
-        FHeader.Treeview.DoHeaderImageClick(NewClickIndex, Button, Shift, P.X, P.Y)
-    end
-    else
-      FHeader.Treeview.DoHeaderClick(NewClickIndex, Button, Shift, P.X, P.Y);
-    FHeader.Invalidate(Items[NewClickIndex]);
-  end
-  else
-    FClickIndex := NoColumn;
-
-  if (FClickIndex > NoColumn) and (FClickIndex <> NewClickIndex) then
-    FHeader.Invalidate(Items[FClickIndex]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.IndexChanged(OldIndex, NewIndex: Integer);
-
-// Called by a column when its index in the collection changes. If NewIndex is -1 then the column is
-// about to be removed, otherwise it is moved to a new index.
-// The method will then update the position array to reflect the change.
-
-var
-  I: Integer;
-  Increment: Integer;
-  Lower,
-  Upper: Integer;
-
-begin
-  if NewIndex = -1 then
-  begin
-    // Find position in the array with the old index.
-    Upper := High(FPositionToIndex);
-    for I := 0 to Upper do
-    begin
-      if FPositionToIndex[I] = OldIndex then
-      begin
-        // Index found. Move all higher entries one step down and remove the last entry.
-        if I < Upper then
-          Move(FPositionToIndex[I + 1], FPositionToIndex[I], (Upper - I) * SizeOf(Integer));
-      end;
-      // Decrease all indices, which are greater than the index to be deleted.
-      if FPositionToIndex[I] > OldIndex then
-        Dec(FPositionToIndex[I]);
-    end;
-    SetLength(FPositionToIndex, High(FPositionToIndex));
-  end
-  else
-  begin
-    if OldIndex < NewIndex then
-      Increment := -1
-    else
-      Increment := 1;
-
-    Lower := Min(OldIndex, NewIndex);
-    Upper := Max(OldIndex, NewIndex);
-    for I := 0 to High(FPositionToIndex) do
-    begin
-      if (FPositionToIndex[I] >= Lower) and (FPositionToIndex[I] < Upper) then
-        Inc(FPositionToIndex[I], Increment)
-      else
-        if FPositionToIndex[I] = OldIndex then
-          FPositionToIndex[I] := NewIndex;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.InitializePositionArray;
-
-// Ensures that the column position array contains as many entries as columns are defined.
-// The array is resized and initialized with default values if needed.
-
-var
-  I, OldSize: Integer;
-  Changed: Boolean;
-
-begin
-  if Count <> Length(FPositionToIndex) then
-  begin
-    OldSize := Length(FPositionToIndex);
-    SetLength(FPositionToIndex, Count);
-    if Count > OldSize then
-    begin
-      // New items have been added, just set their position to the same as their index.
-      for I := OldSize to Count - 1 do
-        FPositionToIndex[I] := I;
-    end
-    else
-    begin
-      // Items have been deleted, so reindex remaining entries by decrementing values larger than the highest
-      // possible index until no entry is higher than this limit.
-      repeat
-        Changed := False;
-        for I := 0 to Count - 1 do
-          if FPositionToIndex[I] >= Count then
-          begin
-            Dec(FPositionToIndex[I]);
-            Changed := True;
-          end;
-      until not Changed;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.ReorderColumns(RTL: Boolean);
-
-var
-  I: Integer;
-
-begin
-  if RTL then
-  begin
-    for I := 0 to Count - 1 do
-      FPositionToIndex[I] := Count - I - 1;
-  end
-  else
-  begin
-    for I := 0 to Count - 1 do
-      FPositionToIndex[I] := I;
-  end;
-
-  UpdatePositions(True);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.Update(Item: TCollectionItem);
-
-begin
-  //lcl
-  // Skip while Destroying
-  if csDestroying in FHeader.TreeView.ComponentState then
-    Exit;
-  // This is the only place which gets notified when a new column has been added or removed
-  // and we need this event to adjust the column position array.
-  InitializePositionArray;
-  if csLoading in Header.Treeview.ComponentState then
-    FNeedPositionsFix := True
-  else
-    UpdatePositions;
-
-  // The first column which is created is by definition also the main column.
-  if (Count > 0) and (Header.FMainColumn < 0) then
-    FHeader.FMainColumn := 0;
-
-  if not (csLoading in Header.Treeview.ComponentState) and not (hsLoading in FHeader.FStates) then
-  begin
-    with FHeader do
-    begin
-      if hoAutoResize in FOptions then
-        AdjustAutoSize(InvalidColumn);
-      if Assigned(Item) then
-        Invalidate(Item as TVirtualTreeColumn)
-      else
-        if Treeview.HandleAllocated then
-        begin
-          Treeview.UpdateHorizontalScrollBar(False);
-          Invalidate(nil);
-          Treeview.Invalidate;
-        end;
-
-      if not (tsUpdating in Treeview.FStates) then
-        // This is mainly to let the designer know when a change occurs at design time which
-        // doesn't involve the object inspector (like column resizing with the mouse).
-        // This does NOT include design time code as the communication is done via an interface.
-        Treeview.UpdateDesigner;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.UpdatePositions(Force: Boolean = False);
-
-// Recalculates the left border of every column and updates their position property according to the
-// PostionToIndex array which primarily determines where each column is placed visually.
-
-var
-  I, RunningPos: Integer;
-  
-begin
-  if not FNeedPositionsFix and (Force or (UpdateCount = 0)) then
-  begin
-    RunningPos := 0;
-    for I := 0 to High(FPositionToIndex) do
-      with Items[FPositionToIndex[I]] do
-      begin
-        FPosition := I;
-        FLeft := RunningPos;
-        if coVisible in FOptions then
-          Inc(RunningPos, FWidth);
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.Add: TVirtualTreeColumn;
-
-begin
-  Result := TVirtualTreeColumn(inherited Add);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.AnimatedResize(Column: TColumnIndex; NewWidth: Integer);
-
-// Resizes the given column animated by scrolling the window DC.
-{$ifndef INCOMPLETE_WINAPI}
-var
-  OldWidth: Integer;
-  DC: HDC;
-  I,
-  Steps,
-  DX: Integer;
-  HeaderScrollRect,
-  ScrollRect,
-  R: TRect;
-
-  NewBrush,
-  LastBrush: HBRUSH;
-{$endif}
-begin
-  //todo: reimplement
-  {$ifndef INCOMPLETE_WINAPI}
-  if not IsValidColumn(Column) then exit; // Just in case.
-
-  // Make sure the width constrains are considered.
-  if NewWidth < Items[Column].FMinWidth then
-     NewWidth := Items[Column].FMinWidth;
-  if NewWidth > Items[Column].FMaxWidth then
-     NewWidth := Items[Column].FMaxWidth;
-
-  OldWidth := Items[Column].Width;
-  // Nothing to do if the width is the same.
-  if OldWidth <> NewWidth then
-  begin
-    if not ( (hoDisableAnimatedResize in FHeader.Options) or
-             (coDisableAnimatedResize in Items[Column].Options) ) then
-    begin
-      DC := GetWindowDC(FHeader.Treeview.Handle);
-      with FHeader.Treeview do
-      try
-        Steps := 32;
-        DX := (NewWidth - OldWidth) div 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.
-        HeaderScrollRect := FHeaderRect;
-        ScrollRect := HeaderScrollRect;
-        // Exclude the header itself from scrolling.
-        ScrollRect.Top := ScrollRect.Bottom;
-        ScrollRect.Bottom := ScrollRect.Top + ClientHeight;
-        ScrollRect.Right := ScrollRect.Left + ClientWidth;
-        with Items[Column] do
-          Inc(ScrollRect.Left, FLeft + FWidth);
-        HeaderScrollRect.Left := ScrollRect.Left;
-        HeaderScrollRect.Right := ScrollRect.Right;
-
-        // When the new width is larger then avoid artefacts on the left hand side
-        // by deleting a small stripe
-        if NewWidth > OldWidth then
-        begin
-          R := ScrollRect;
-          NewBrush := CreateSolidBrush(ColorToRGB(Brush.Color));
-          LastBrush := SelectObject(DC, NewBrush);
-          R.Right := R.Left + DX;
-          FillRect(DC, R, NewBrush);
-          SelectObject(DC, LastBrush);
-          DeleteObject(NewBrush);
-        end
-        else
-        begin
-          Inc(HeaderScrollRect.Left, DX);
-          Inc(ScrollRect.Left, DX);
-        end;
-
-        for I := 0 to Steps - 1 do
-        begin
-          ScrollDC(DC, DX, 0, HeaderScrollRect, HeaderScrollRect, 0, nil);
-          Inc(HeaderScrollRect.Left, DX);
-          ScrollDC(DC, DX, 0, ScrollRect, ScrollRect, 0, nil);
-          Inc(ScrollRect.Left, DX);
-          Sleep(1);
-        end;
-      finally
-        ReleaseDC(Handle, DC);
-      end;
-    end;
-    Items[Column].Width := NewWidth;
-  end;
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.Assign(Source: TPersistent);
-
-begin
-  // Let the collection class assign the items.
-  inherited;
-
-  if Source is TVirtualTreeColumns then
-  begin
-    // Copying the position array is the only needed task here.
-    FPositionToIndex := Copy(TVirtualTreeColumns(Source).FPositionToIndex, 0, MaxInt);
-
-    // Make sure the left edges are correct after assignment.
-    FNeedPositionsFix := False;
-    UpdatePositions(True);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.Clear;
-
-begin
-  FClearing := True;
-  try
-    // Since we're freeing all columns, the following have to be true when we're done.
-    FHoverIndex := NoColumn;
-    FDownIndex := NoColumn;
-    FTrackIndex := NoColumn;
-    FClickIndex := NoColumn;
-
-    with Header do
-      if not (hsLoading in FStates) then
-      begin
-        FAutoSizeIndex := NoColumn;
-        FMainColumn := NoColumn;
-        FSortColumn := NoColumn;
-      end;
-
-    inherited Clear;
-  finally
-    FClearing := False;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.ColumnFromPosition(const P: TPoint; Relative: Boolean = True): TColumnIndex;
-
-// Determines the current column based on the position passed in P.
-
-var
-  I, Sum: Integer;
-
-begin
-  Result := InvalidColumn;
-
-  // The position must be within the header area, but we extend the vertical bounds to the entire treeview area.
-  if (P.X >= 0) and (P.Y >= 0) and (P.Y <= FHeader.TreeView.Height) then
-    with FHeader, Treeview do
-    begin
-      if Relative and (P.X > GetVisibleFixedWidth) then
-        Sum := -FEffectiveOffsetX
-      else
-        Sum := 0;
-
-      if UseRightToLeftAlignment then
-        Inc(Sum, ComputeRTLOffset(True));
-
-      for I := 0 to Count - 1 do
-        if coVisible in Items[FPositionToIndex[I]].FOptions then
-        begin
-          Inc(Sum, Items[FPositionToIndex[I]].Width);
-          if P.X < Sum then
-          begin
-            Result := FPositionToIndex[I];
-            Break;
-          end;
-        end;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.ColumnFromPosition(PositionIndex: TColumnPosition): TColumnIndex;
-
-// Returns the index of the column at the given position.
-
-begin
-  if Integer(PositionIndex) < Length(FPositionToIndex) then
-    Result := FPositionToIndex[PositionIndex]
-  else
-    Result := NoColumn;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.Equals(OtherColumnsObj: TObject): Boolean;
-
-// Compares itself with the given set of columns and returns True if all published properties are the same
-// (including column order), otherwise False is returned.
-
-var
-  I: Integer;
-  OtherColumns : TVirtualTreeColumns;
-
-begin
-  if not (OtherColumnsObj is TVirtualTreeColumns) then
-  begin
-    Result := False;
-    Exit
-  end;
-
-  OtherColumns := TVirtualTreeColumns (OtherColumnsObj);
-
-  // Same number of columns?
-  Result := OtherColumns.Count = Count;
-  if Result then
-  begin
-    // Same order of columns?
-    Result := CompareMem(Pointer(FPositionToIndex), Pointer(OtherColumns.FPositionToIndex),
-      Length(FPositionToIndex) * SizeOf(TColumnIndex));
-    if Result then
-    begin
-      for I := 0 to Count - 1 do
-        if not Items[I].Equals(OtherColumns[I]) then
-        begin
-          Result := False;
-          Break;
-        end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.GetColumnBounds(Column: TColumnIndex; out Left, Right: Integer);
-
-// Returns the left and right bound of the given column. If Column is NoColumn then the entire client width is returned.
-
-begin
-  if Column <= NoColumn then
-  begin
-    Left := 0;
-    Right := FHeader.Treeview.ClientWidth;
-  end
-  else
-  begin
-    Left := Items[Column].Left;
-    Right := Left + Items[Column].Width;
-    if FHeader.Treeview.UseRightToLeftAlignment then
-    begin
-      Inc(Left, FHeader.Treeview.ComputeRTLOffset(True));
-      Inc(Right, FHeader.Treeview.ComputeRTLOffset(True));
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetScrollWidth: Integer;
-
-// Returns the average width of all visible, non-fixed columns. If there is no such column the indent is returned.
-
-var
-  I: Integer;
-  ScrollColumnCount: Integer;
-
-begin
-
-  Result := 0;
-
-  ScrollColumnCount := 0;
-  for I := 0 to FHeader.Columns.Count - 1 do
-  begin
-    if ([coVisible, coFixed] * FHeader.Columns[I].Options = [coVisible]) then
-    begin
-      Inc(Result, FHeader.Columns[I].Width);
-      Inc(ScrollColumnCount);
-    end;
-  end;
-
-  if ScrollColumnCount > 0 then // use average width
-    Result := Round(Result / ScrollColumnCount)
-  else // use indent
-    Result := Integer(FHeader.Treeview.FIndent);
-
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetFirstVisibleColumn(ConsiderAllowFocus: Boolean = False): TColumnIndex;
-
-// Returns the index of the first visible column or "InvalidColumn" if either no columns are defined or
-// all columns are hidden.
-// If ConsiderAllowFocus is True then the column has not only to be visible but also focus has to be allowed.
-
-var
-  I: Integer;
-
-begin
-  Result := InvalidColumn;
-  for I := 0 to Count - 1 do
-    if (coVisible in Items[FPositionToIndex[I]].FOptions) and
-       ( (not ConsiderAllowFocus) or
-         (coAllowFocus in Items[FPositionToIndex[I]].FOptions)
-       ) then
-    begin
-      Result := FPositionToIndex[I];
-      Break;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetLastVisibleColumn(ConsiderAllowFocus: Boolean = False): TColumnIndex;
-
-// Returns the index of the last visible column or "InvalidColumn" if either no columns are defined or
-// all columns are hidden.
-// If ConsiderAllowFocus is True then the column has not only to be visible but also focus has to be allowed.
-
-var
-  I: Integer;
-
-begin
-  Result := InvalidColumn;
-  for I := Count - 1 downto 0 do
-    if (coVisible in Items[FPositionToIndex[I]].FOptions) and
-       ( (not ConsiderAllowFocus) or
-         (coAllowFocus in Items[FPositionToIndex[I]].FOptions)
-       ) then
-    begin
-      Result := FPositionToIndex[I];
-      Break;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetNextColumn(Column: TColumnIndex): TColumnIndex;
-
-// Returns the next column in display order. Column is the index of an item in the collection (a column).
-
-var
-  Position: Integer;
-
-begin
-  if Column < 0 then
-    Result := InvalidColumn
-  else
-  begin
-    Position := Items[Column].Position;
-    if Position < Count - 1 then
-      Result := FPositionToIndex[Position + 1]
-    else
-      Result := InvalidColumn;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetNextVisibleColumn(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex;
-
-// Returns the next visible column in display order, Column is an index into the columns list.
-// If ConsiderAllowFocus is True then the column has not only to be visible but also focus has to be allowed.
-
-begin
-  Result := Column;
-  repeat
-    Result := GetNextColumn(Result);
-  until (Result = InvalidColumn) or
-        ( (coVisible in Items[Result].FOptions) and
-          ( (not ConsiderAllowFocus) or
-            (coAllowFocus in Items[Result].FOptions)
-          )
-        );
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetPreviousColumn(Column: TColumnIndex): TColumnIndex;
-
-// Returns the previous column in display order, Column is an index into the columns list.
-
-var
-  Position: Integer;
-
-begin
-  if Column < 0 then
-    Result := InvalidColumn
-  else
-  begin
-    Position := Items[Column].Position;
-    if Position > 0 then
-      Result := FPositionToIndex[Position - 1]
-    else
-      Result := InvalidColumn;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetPreviousVisibleColumn(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex;
-
-// Returns the previous visible column in display order, Column is an index into the columns list.
-// If ConsiderAllowFocus is True then the column has not only to be visible but also focus has to be allowed.
-
-begin
-  Result := Column;
-  repeat
-    Result := GetPreviousColumn(Result);
-  until (Result = InvalidColumn) or
-        ( (coVisible in Items[Result].FOptions) and
-          ( (not ConsiderAllowFocus) or
-            (coAllowFocus in Items[Result].FOptions)
-          )
-        );
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetVisibleColumns: TColumnsArray;
-
-// Returns a list of all currently visible columns in actual order.
-
-var
-  I, Counter: Integer;
-
-begin
-  SetLength(Result, Count);
-  Counter := 0;
-
-  for I := 0 to Count - 1 do
-    if coVisible in Items[FPositionToIndex[I]].FOptions then
-    begin
-      Result[Counter] := Items[FPositionToIndex[I]];
-      Inc(Counter);
-    end;
-  // Set result length to actual visible count.
-  SetLength(Result, Counter);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.GetVisibleFixedWidth: Integer;
-
-// Determines the horizontal space all visible and fixed columns occupy.
-
-var
-  I: Integer;
-
-begin
-  Result := 0;
-  for I := 0 to Count - 1 do
-  begin
-    if Items[I].Options * [coVisible, coFixed] = [coVisible, coFixed] then
-      Inc(Result, Items[I].Width);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.IsValidColumn(Column: TColumnIndex): Boolean;
-
-// Determines whether the given column is valid or not, that is, whether it is one of the current columns.
-
-begin
-  Result := (Column > NoColumn) and (Column < Count);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.LoadFromStream(const Stream: TStream; Version: Integer);
-
-var
-  I,
-  ItemCount: Integer;
-
-begin
-  Clear;
-  Stream.ReadBuffer(ItemCount, SizeOf(ItemCount));
-  // number of columns
-  if ItemCount > 0 then
-  begin
-    BeginUpdate;
-    try
-      for I := 0 to ItemCount - 1 do
-        Add.LoadFromStream(Stream, Version);
-      SetLength(FPositionToIndex, ItemCount);
-      Stream.ReadBuffer(FPositionToIndex[0], ItemCount * SizeOf(Cardinal));
-      UpdatePositions(True);
-    finally
-      EndUpdate;
-    end;
-  end;
-
-  // Data introduced with header stream version 5
-  // LCL port started with header stream version 6 so no need to do the check here
-  Stream.ReadBuffer(FDefaultWidth, SizeOf(FDefaultWidth));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.PaintHeader(DC: HDC; const R: TRect; HOffset: Integer);
-
-// Main paint method to draw the header.
-
-const
-  SortGlyphs: array[TSortDirection, Boolean] of Integer = ( // ascending/descending, normal/XP style
-    (3, 5) {ascending}, (2, 4) {descending}
-  );
-
-var
-  I, Y,
-  SortIndex: Integer;
-  Run: TRect;
-  RightBorderFlag,
-  NormalButtonStyle,
-  NormalButtonFlags,
-  PressedButtonStyle,
-  PressedButtonFlags,
-  RaisedButtonStyle,
-  RaisedButtonFlags: Cardinal;
-  DrawFormat: Cardinal;
-  Images: TCustomImageList;
-  ButtonRgn: HRGN;
-  OwnerDraw,
-  WrapCaption,
-  AdvancedOwnerDraw: Boolean;
-  {$ifdef ThemeSupport}
-    Details: TThemedElementDetails;
-  {$endif ThemeSupport}
-
-  PaintInfo: THeaderPaintInfo;
-  RequestedElements,
-  ActualElements: THeaderPaintElements;
-
-  Temp: TRect;
-  ColCaptionText: String;
-  ColImages: TCustomImageList;
-  ColImageIndex: Integer;
-
-begin
-  Run := FHeader.Treeview.FHeaderRect;
-  FHeaderBitmap.Width := Max(Run.Right, R.Right - R.Left);
-  FHeaderBitmap.Height := Run.Bottom;
-  OwnerDraw := (hoOwnerDraw in FHeader.FOptions) and Assigned(FHeader.Treeview.FOnHeaderDraw) and
-    not (csDesigning in FHeader.Treeview.ComponentState);
-  AdvancedOwnerDraw := (hoOwnerDraw in FHeader.FOptions) and Assigned(FHeader.Treeview.FOnAdvancedHeaderDraw) and
-    Assigned(FHeader.Treeview.FOnHeaderDrawQueryElements) and not (csDesigning in FHeader.Treeview.ComponentState);
-  // If both draw posibillities are specified then prefer the advanced way.
-  if AdvancedOwnerDraw then
-    OwnerDraw := False;
-
-  FillChar(PaintInfo, SizeOf(PaintInfo),#0);
-  PaintInfo.TargetCanvas := FHeaderBitmap.Canvas;
-
-  with PaintInfo, TargetCanvas do
-  begin
-    Font := FHeader.FFont;
-
-    RaisedButtonStyle := 0;
-    RaisedButtonFlags := 0;
-    case FHeader.Style of
-      hsThickButtons:
-        begin
-          NormalButtonStyle := BDR_RAISEDINNER or BDR_RAISEDOUTER;
-          NormalButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_MIDDLE or BF_SOFT or BF_ADJUST;
-          PressedButtonStyle := BDR_RAISEDINNER or BDR_RAISEDOUTER;
-          PressedButtonFlags := NormalButtonFlags or BF_RIGHT or BF_FLAT or BF_ADJUST;
-        end;
-      hsFlatButtons:
-        begin
-          NormalButtonStyle := BDR_RAISEDINNER;
-          NormalButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_MIDDLE or BF_ADJUST;
-          PressedButtonStyle := BDR_SUNKENOUTER;
-          PressedButtonFlags := BF_RECT or BF_MIDDLE or BF_ADJUST;
-        end;
-    else
-      // hsPlates or hsXPStyle, values are not used in the latter case
-      begin
-        NormalButtonStyle := BDR_RAISEDINNER;
-        NormalButtonFlags := BF_RECT or BF_MIDDLE or BF_SOFT or BF_ADJUST;
-        PressedButtonStyle := BDR_SUNKENOUTER;
-        PressedButtonFlags := BF_RECT or BF_MIDDLE or BF_ADJUST;
-        RaisedButtonStyle := BDR_RAISEDINNER;
-        RaisedButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_MIDDLE or BF_ADJUST;
-      end;
-    end;
-
-    // Use shortcut for the images.
-    Images := FHeader.FImages;
-
-    // Erase background of the header.
-    // See if the application wants to do that on its own.
-    RequestedElements := [];
-    if AdvancedOwnerDraw then
-    begin
-      PaintInfo.PaintRectangle := R;
-      PaintInfo.Column := nil;
-      FHeader.Treeview.DoHeaderDrawQueryElements(PaintInfo, RequestedElements);
-    end;
-
-    if hpeBackground in RequestedElements then
-    begin
-      FHeader.Treeview.DoAdvancedHeaderDraw(PaintInfo, [hpeBackground]);
-    end
-    else
-    begin
-      {$ifdef ThemeSupport}
-        if tsUseThemes in FHeader.Treeview.FStates then
-        begin
-          Details := ThemeServices.GetElementDetails(thHeaderItemRightNormal);
-          ThemeServices.DrawElement(Handle, Details, R, @R);
-        end
-        else
-      {$endif ThemeSupport}
-        if FHeader.Style = hsXPStyle then
-          DrawXPButton(Handle, Run, False, False, False)
-        else
-        begin
-          Brush.Color := FHeader.FBackground;
-          FillRect(R);
-        end;
-    end;
-
-    Run.Top := R.Top;
-    Run.Right := R.Left;
-    Run.Bottom := R.Bottom;
-    // Run.Left is set in the loop
-
-    // Consider right-to-left directionality.
-    with FHeader.Treeview do
-      if UseRightToLeftAlignment then
-        Inc(Run.Right, ComputeRTLOffset);
-
-    Temp := Run;
-    //todo_lcl_check
-    ShowRightBorder := (FHeader.Style = hsThickButtons) or not (hoAutoResize in FHeader.FOptions);// or
-      //(FHeader.Treeview.BevelKind = bkNone);
-
-    // Now go for each button.
-    for I := 0 to Count - 1 do
-    begin
-      with Items[FPositionToIndex[I]] do
-        if coVisible in FOptions then
-        begin
-          if not (coFixed in FOptions) then
-          begin
-            Inc(Run.Right, HOffset);
-            HOffset := 0;
-          end;
-
-          Temp := Rect(Temp.Right, Run.Top, Max(Temp.Right, Run.Right + Width), Run.Bottom);
-
-          Run.Left := Run.Right;
-          Inc(Run.Right, Width);
-          // Skip columns which are not visible at all.
-          if (Run.Right > R.Left) and (Run.Right > Temp.Left)  then
-          begin
-            // Stop painting if the rectangle is filled.
-            if Run.Left > R.Right then
-              Break;
-
-            // Create a clip region to avoid overpainting any other area which does not belong to this column.
-            if Temp.Right > R.Right then
-              Temp.Right := R.Right;
-            if Temp.Left < R.Left then
-              Temp.Left := R.Left;
-
-            ButtonRgn := CreateRectRgnIndirect(Temp);
-            SelectClipRgn(Handle, ButtonRgn);
-            DeleteObject(ButtonRgn);
-
-            //lclheader
-            //Under Delphi/VCL, unlike LCL, the hover index is not changed while dragging.
-            //Here we check if dragging and not draw as hover
-            IsHoverIndex := (Integer(FPositionToIndex[I]) = FHoverIndex) and (hoHotTrack in FHeader.FOptions) and
-              (coEnabled in FOptions) and not (hsDragging in FHeader.States);
-            IsDownIndex := Integer(FPositionToIndex[I]) = FDownIndex;
-            if (coShowDropMark in FOptions) and (Integer(FPositionToIndex[I]) = FDropTarget) and
-              (Integer(FPositionToIndex[I]) <> FDragIndex) then
-            begin
-              if FDropBefore then
-                DropMark := dmmLeft
-              else
-                DropMark := dmmRight;
-            end
-            else
-              DropMark := dmmNone;
-            IsEnabled := (coEnabled in FOptions) and (FHeader.Treeview.Enabled);
-            ShowHeaderGlyph := (hoShowImages in FHeader.FOptions) and Assigned(Images) and (FImageIndex > -1);
-            ShowSortGlyph := (Integer(FPositionToIndex[I]) = FHeader.FSortColumn) and (hoShowSortGlyphs in FHeader.FOptions);
-            WrapCaption := coWrapCaption in FOptions;
-
-            PaintRectangle := Run;
-
-            // This path for text columns or advanced owner draw.
-            if (Style = vsText) or not OwnerDraw or AdvancedOwnerDraw then
-            begin
-              // See if the application wants to draw part of the header itself.
-              RequestedElements := [];
-              if AdvancedOwnerDraw then
-              begin
-                PaintInfo.Column := Items[FPositionToIndex[I]];
-                FHeader.Treeview.DoHeaderDrawQueryElements(PaintInfo, RequestedElements);
-              end;
-
-              if ShowRightBorder or (I < Count - 1) then
-                RightBorderFlag := BF_RIGHT
-              else
-                RightBorderFlag := 0;
-
-              if hpeBackground in RequestedElements then
-                FHeader.Treeview.DoAdvancedHeaderDraw(PaintInfo, [hpeBackground])
-              else
-              begin
-                // Draw button first before setting the clip region.
-                {$ifdef ThemeSupport}
-                  if tsUseThemes in FHeader.Treeview.FStates then
-                  begin
-                    if IsDownIndex then
-                      Details := ThemeServices.GetElementDetails(thHeaderItemPressed)
-                    else
-                      if IsHoverIndex then
-                        Details := ThemeServices.GetElementDetails(thHeaderItemHot)
-                      else
-                        Details := ThemeServices.GetElementDetails(thHeaderItemNormal);
-                    ThemeServices.DrawElement(Handle, Details, PaintRectangle, @PaintRectangle);
-                  end
-                  else
-                {$endif ThemeSupport}
-                begin
-                  if FHeader.Style = hsXPStyle then
-                    DrawXPButton(Handle, PaintRectangle, RightBorderFlag <> 0, IsDownIndex, IsHoverIndex)
-                  else
-                    if IsDownIndex then
-                      DrawEdge(Handle, PaintRectangle, PressedButtonStyle, PressedButtonFlags)
-                    else
-                      // Plates have the special case of raising on mouse over.
-                      if (FHeader.Style = hsPlates) and IsHoverIndex and
-                        (coAllowClick in FOptions) and (coEnabled in FOptions) then
-                        DrawEdge(Handle, PaintRectangle, RaisedButtonStyle, RaisedButtonFlags or RightBorderFlag)
-                      else
-                        DrawEdge(Handle, PaintRectangle, NormalButtonStyle, NormalButtonFlags or RightBorderFlag);
-                end;
-              end;
-            end;
-
-            PaintRectangle := Run;
-            if (Style = vsText) or not OwnerDraw or AdvancedOwnerDraw then
-            begin
-              // calculate text and glyph position
-              InflateRect(PaintRectangle, -2, -2);
-              DrawFormat := DT_TOP or DT_NOPREFIX;
-              case CaptionAlignment of
-                taLeftJustify  : DrawFormat := DrawFormat or DT_LEFT;
-                taRightJustify : DrawFormat := DrawFormat or DT_RIGHT;
-                taCenter       : DrawFormat := DrawFormat or DT_CENTER;
-              end;
-              if UseRightToLeftReading then
-                DrawFormat := DrawFormat + DT_RTLREADING;
-              ComputeHeaderLayout(Handle, PaintRectangle, ShowHeaderGlyph, ShowSortGlyph, GlyphPos, SortGlyphPos,
-                TextRectangle, DrawFormat);
-
-              // Move glyph and text one pixel to the right and down to simulate a pressed button.
-              if IsDownIndex then
-              begin
-                OffsetRect(TextRectangle, 1, 1);
-                Inc(GlyphPos.X);
-                Inc(GlyphPos.Y);
-                Inc(SortGlyphPos.X);
-                Inc(SortGlyphPos.Y);
-              end;
-
-              // Advanced owner draw allows to paint elements, which would normally not be painted (because of space
-              // limitations, empty captions etc.).
-              ActualElements := RequestedElements * [hpeHeaderGlyph, hpeSortGlyph, hpeDropMark, hpeText];
-
-              // main glyph
-              FHasImage := False;
-              if not (hpeHeaderGlyph in ActualElements) and ShowHeaderGlyph and
-                (not ShowSortGlyph or (FBidiMode <> bdLeftToRight) or (GlyphPos.X + Images.Width <= SortGlyphPos.X) ) then
-              begin
-                if not FCheckBox then
-                begin
-                  ColImages := Images;
-                  ColImageIndex := FImageIndex;
-                  ColImages.Draw(FHeaderBitmap.Canvas, GlyphPos.X, GlyphPos.Y, ColImageIndex, IsEnabled );
-                end
-                else
-                begin
-                  with Header.Treeview do
-                  begin
-                    CheckImageListNeeded;
-                    ColImageIndex := GetCheckImage(nil, FCheckType, FCheckState, IsEnabled);
-                    {$ifdef USE_DELPHICOMPAT}
-                    with FCheckImages do
-                      DirectMaskBlt(FHeaderBitmap.Canvas.Handle, GlyphPos.X, GlyphPos.Y,
-                        Height, Height, Canvas.Handle, ColImageIndex * Height, 0, MaskHandle);
-                    {$else}
-                    with FCheckImages do
-                      StretchMaskBlt(FHeaderBitmap.Canvas.Handle, GlyphPos.X, GlyphPos.Y,
-                        Height, Height, Canvas.Handle, ColImageIndex * Height, 0,
-                        Height, Height, MaskHandle, ColImageIndex * Height, 0, SRCCOPY);
-                    {$endif}
-                  end;
-                end;
-
-                FHasImage := True;
-                with FImageRect do
-                begin
-                  Left := GlyphPos.X;
-                  Top := GlyphPos.Y;
-                  Right := Left + ColImages.Width;
-                  Bottom := Top + ColImages.Height;
-                end;
-              end;
-
-              // caption
-              if WrapCaption then
-                ColCaptionText := FCaptionText
-              else
-                ColCaptionText := Text;
-
-              if not (hpeText in ActualElements) and (Length(Text) > 0) then
-                DrawButtonText(Handle, ColCaptionText, TextRectangle, IsEnabled, IsHoverIndex and (hoHotTrack in FHeader.FOptions) and
-                not (tsUseThemes in FHeader.Treeview.FStates), DrawFormat, WrapCaption );
-
-              // sort glyph
-              if not (hpeSortGlyph in ActualElements) and ShowSortGlyph then
-              begin
-                SortIndex := SortGlyphs[FHeader.FSortDirection, tsUseThemes in FHeader.Treeview.FStates];
-                {$ifdef USE_DELPHICOMPAT}
-                DirectMaskBlt(FHeaderBitmap.Canvas.Handle, SortGlyphPos.X, SortGlyphPos.Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle,
-                  SortIndex * UtilityImageSize, 0, UtilityImages.MaskHandle);
-                {$else}
-                StretchMaskBlt(FHeaderBitmap.Canvas.Handle, SortGlyphPos.X, SortGlyphPos.Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle,
-                  SortIndex * UtilityImageSize, 0, UtilityImageSize, UtilityImageSize, UtilityImages.MaskHandle,SortIndex * UtilityImageSize, 0, SRCCOPY);
-                {$endif}
-              end;
-
-              // Show an indication if this column is the current drop target in a header drag operation.
-              if not (hpeDropMark in ActualElements) and (DropMark <> dmmNone) then
-              begin
-                Y := (PaintRectangle.Top + PaintRectangle.Bottom - UtilityImages.Height) div 2;
-                if DropMark = dmmLeft then
-                  {$ifdef USE_DELPHICOMPAT}
-                  DirectMaskBlt(FHeaderBitmap.Canvas.Handle, PaintRectangle.Left, Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle,
-                    0, 0, UtilityImages.MaskHandle)
-                  {$else}
-                  StretchMaskBlt(FHeaderBitmap.Canvas.Handle, PaintRectangle.Left, Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle,
-                    0, 0, UtilityImageSize, UtilityImageSize, UtilityImages.MaskHandle, 0, 0, SRCCOPY)
-                  {$endif}
-                else
-                  {$ifdef USE_DELPHICOMPAT}
-                  DirectMaskBlt(FHeaderBitmap.Canvas.Handle, PaintRectangle.Right - 16, Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle,
-                    UtilityImageSize, 0, UtilityImages.MaskHandle);
-                  {$else}
-                  StretchMaskBlt(FHeaderBitmap.Canvas.Handle, PaintRectangle.Right - 16, Y, UtilityImageSize, UtilityImageSize, UtilityImages.Canvas.Handle,
-                    UtilityImageSize, 0, UtilityImageSize, UtilityImageSize, UtilityImages.MaskHandle, UtilityImageSize, 0, SRCCOPY);
-                  {$endif}
-              end;
-
-              if ActualElements <> [] then
-              begin
-                SaveHandleState;
-                FHeader.Treeview.DoAdvancedHeaderDraw(PaintInfo, ActualElements);
-                RestoreHandleState;
-              end;
-            end
-            else // Let application draw the header.
-              FHeader.Treeview.DoHeaderDraw(FHeaderBitmap.Canvas, Items[FPositionToIndex[I]], PaintRectangle, IsHoverIndex,
-                IsDownIndex, DropMark);
-            SelectClipRgn(Handle, 0);
-          end;
-        end;
-    end;
-
-    // Blit the result to target.
-    with R do
-      BitBlt(DC, Left, Top, Right - Left, Bottom - Top, Handle, Left, Top, SRCCOPY);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualTreeColumns.SaveToStream(const Stream: TStream);
-
-var
-  I: Integer;
-
-begin
-  I := Count;
-  Stream.WriteBuffer(I, SizeOf(I));
-  if I > 0 then
-  begin
-    for I := 0 to Count - 1 do
-      TVirtualTreeColumn(Items[I]).SaveToStream(Stream);
-
-    Stream.WriteBuffer(FPositionToIndex[0], Count * SizeOf(Cardinal));
-  end;
-
-  // Data introduced with header stream version 5.
-  Stream.WriteBuffer(DefaultWidth, SizeOf(DefaultWidth));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualTreeColumns.TotalWidth: Integer;
-
-var
-  LastColumn: TColumnIndex;
-
-begin
-  Result := 0;
-  if (Count > 0) and (Length(FPositionToIndex) > 0) then
-  begin
-    LastColumn := FPositionToIndex[Count - 1];
-    if not (coVisible in Items[LastColumn].FOptions) then
-      LastColumn := GetPreviousVisibleColumn(LastColumn);
-    if LastColumn > NoColumn then
-      with Items[LastColumn] do
-        Result := FLeft + FWidth
-  end;
-end;
-
-//----------------- TVTFixedAreaConstraints ----------------------------------------------------------------------------
-
-constructor TVTFixedAreaConstraints.Create(AOwner: TVTHeader);
-
-begin
-  inherited Create;
-
-  FHeader := AOwner;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTFixedAreaConstraints.SetConstraints(Index: Integer; Value: TVTConstraintPercent);
-
-begin
-  case Index of
-    0:
-      if Value <> FMaxHeightPercent then
-      begin
-        FMaxHeightPercent := Value;
-        if (Value > 0) and (Value < FMinHeightPercent) then
-          FMinHeightPercent := Value;
-        Change;
-      end;
-    1:
-      if Value <> FMaxWidthPercent then
-      begin
-        FMaxWidthPercent := Value;
-        if (Value > 0) and (Value < FMinWidthPercent) then
-          FMinWidthPercent := Value;
-        Change;
-      end;
-    2:
-      if Value <> FMinHeightPercent then
-      begin
-        FMinHeightPercent := Value;
-        if (FMaxHeightPercent > 0) and (Value > FMaxHeightPercent) then
-          FMaxHeightPercent := Value;
-        Change;
-      end;
-    3:
-      if Value <> FMinWidthPercent then
-      begin
-        FMinWidthPercent := Value;
-        if (FMaxWidthPercent > 0) and (Value > FMaxWidthPercent) then
-          FMaxWidthPercent := Value;
-        Change;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTFixedAreaConstraints.Change;
-
-begin
-  if Assigned(FOnChange) then
-    FOnChange(Self);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTFixedAreaConstraints.Assign(Source: TPersistent);
-
-begin
-  if Source is TVTFixedAreaConstraints then
-  begin
-    FMaxHeightPercent := TVTFixedAreaConstraints(Source).FMaxHeightPercent;
-    FMaxWidthPercent := TVTFixedAreaConstraints(Source).FMaxWidthPercent;
-    FMinHeightPercent := TVTFixedAreaConstraints(Source).FMinHeightPercent;
-    FMinWidthPercent := TVTFixedAreaConstraints(Source).FMinWidthPercent;
-    Change;
-  end
-  else
-    inherited;
-end;
-
-//----------------- TVTHeader -----------------------------------------------------------------------------------------
-
-constructor TVTHeader.Create(AOwner: TBaseVirtualTree);
-
-begin
-  inherited Create;
-  FOwner := AOwner;
-  FColumns := GetColumnsClass.Create(Self);
-  FHeight := 17;
-  FDefaultHeight := 17;
-  FMinHeight := 10;
-  FMaxHeight := 10000;
-  FFont := TFont.Create;
-  FFont.OnChange := FontChanged;
-  FParentFont := False;
-  FBackground := clBtnFace;
-  FOptions := [hoColumnResize, hoDrag, hoShowSortGlyphs];
-
-  FImageChangeLink := TChangeLink.Create;
-  FImageChangeLink.OnChange := ImageListChange;
-
-  FSortColumn := NoColumn;
-  FSortDirection := sdAscending;
-  FMainColumn := NoColumn;
-
-  FDragImage := TVTDragImage.Create(AOwner);
-  with FDragImage do
-  begin
-    Fade := False;
-    PostBlendBias := 0;
-    PreBlendBias := -50;
-    Transparency := 140;
-  end;
-
-  FFixedAreaConstraints := TVTFixedAreaConstraints.Create(Self);
-  FFixedAreaConstraints.OnChange := FixedAreaConstraintsChanged;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTHeader.Destroy;
-
-begin
-  FDragImage.Free;
-  FFixedAreaConstraints.Free;
-  FImageChangeLink.Free;
-  FFont.Free;
-  FColumns.Clear; // TCollection's Clear method is not virtual, so we have to call our own Clear method manually.
-  FColumns.Free;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.FontChanged(Sender: TObject);
-
-begin
-  Invalidate(nil);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.GetMainColumn: TColumnIndex;
-
-begin
-  if FColumns.Count > 0 then
-    Result := FMainColumn
-  else
-    Result := NoColumn;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.GetUseColumns: Boolean;
-
-begin
-  Result := FColumns.Count > 0;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.IsFontStored: Boolean;
-
-begin
-  Result := not ParentFont;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetAutoSizeIndex(Value: TColumnIndex);
-
-begin
-  if FAutoSizeIndex <> Value then
-  begin
-    FAutoSizeIndex := Value;
-    if hoAutoResize in FOptions then
-      Columns.AdjustAutoSize(InvalidColumn);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetBackground(Value: TColor);
-
-begin
-  if FBackground <> Value then
-  begin
-    FBackground := Value;
-    Invalidate(nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetColumns(Value: TVirtualTreeColumns);
-
-begin
-  FColumns.Assign(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetDefaultHeight(Value: Integer);
-
-begin
-  if Value < FMinHeight then
-    Value := FMinHeight;
-  if Value > FMaxHeight then
-    Value := FMaxHeight;
-
-  if FHeight = FDefaultHeight then
-    SetHeight(Value);
-  FDefaultHeight := Value;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetFont(const Value: TFont);
-
-begin
-  FFont.Assign(Value);
-  FParentFont := False;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetHeight(Value: Integer);
-
-var
-  RelativeMaxHeight,
-  RelativeMinHeight,
-  EffectiveMaxHeight,
-  EffectiveMinHeight: Integer;
-
-begin
-  if not TreeView.HandleAllocated then
-  begin
-    FHeight := Value;
-    Include(FStates, hsNeedScaling);
-  end
-  else
-  begin
-    with FFixedAreaConstraints do
-    begin
-      RelativeMaxHeight := ((Treeview.ClientHeight + FHeight) * FMaxHeightPercent) div 100;
-      RelativeMinHeight := ((Treeview.ClientHeight + FHeight) * FMinHeightPercent) div 100;
-
-      EffectiveMinHeight := IfThen(FMaxHeightPercent > 0, Min(RelativeMaxHeight, FMinHeight), FMinHeight);
-      EffectiveMaxHeight := IfThen(FMinHeightPercent > 0, Max(RelativeMinHeight, FMaxHeight), FMaxHeight);
-
-      Value := Min(Max(Value, EffectiveMinHeight), EffectiveMaxHeight);
-      if FMinHeightPercent > 0 then
-        Value := Max(RelativeMinHeight, Value);
-      if FMaxHeightPercent > 0 then
-        Value := Min(RelativeMaxHeight, Value);
-    end;
-
-    if FHeight <> Value then
-    begin
-      FHeight := Value;
-      if not (csLoading in Treeview.ComponentState) and not (hsScaling in FStates) then
-        RecalculateHeader;
-      Treeview.Invalidate;
-      UpdateWindow(Treeview.Handle);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetImages(const Value: TCustomImageList);
-
-begin
-  if FImages <> Value then
-  begin
-    if Assigned(FImages) then
-    begin
-      FImages.UnRegisterChanges(FImageChangeLink);
-      FImages.RemoveFreeNotification(FOwner);
-    end;
-    FImages := Value;
-    if Assigned(FImages) then
-    begin
-      FImages.RegisterChanges(FImageChangeLink);
-      FImages.FreeNotification(FOwner);
-    end;
-    if not (csLoading in Treeview.ComponentState) then
-      Invalidate(nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetMainColumn(Value: TColumnIndex);
-
-begin
-  if csLoading in Treeview.ComponentState then
-    FMainColumn := Value
-  else
-  begin
-    if Value < 0 then
-      Value := 0;
-    if Value > FColumns.Count - 1 then
-      Value := FColumns.Count - 1;
-    if Value <> FMainColumn then
-    begin
-      FMainColumn := Value;
-      if Treeview.HandleAllocated then
-      begin
-        Treeview.MainColumnChanged;
-        if not (toExtendedFocus in Treeview.FOptions.FSelectionOptions) then
-          Treeview.FocusedColumn := Value;
-        Treeview.Invalidate;
-      end
-      else
-      begin
-        if not (toExtendedFocus in Treeview.FOptions.FSelectionOptions) then
-          Treeview.FFocusedColumn := Value;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetMaxHeight(Value: Integer);
-
-begin
-  if Value < FMinHeight then
-    Value := FMinHeight;
-  if not IsWinNT and (Value > 10000) then
-    Value := 10000;
-  FMaxHeight := Value;
-  SetHeight(FHeight);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetMinHeight(Value: Integer);
-
-begin
-  if Value < 0 then
-    Value := 0;
-  if Value > FMaxHeight then
-    Value := FMaxHeight;
-  FMinHeight := Value;
-  SetHeight(FHeight);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetOptions(Value: TVTHeaderOptions);
-
-var
-  ToBeSet,
-  ToBeCleared: TVTHeaderOptions;
-
-begin
-  ToBeSet := Value - FOptions;
-  ToBeCleared := FOptions - Value;
-  FOptions := Value;
-
-  if (hoAutoResize in (ToBeSet + ToBeCleared)) and (FColumns.Count > 0) then
-  begin
-    FColumns.AdjustAutoSize(InvalidColumn);
-    if Treeview.HandleAllocated then
-    begin
-      Treeview.UpdateHorizontalScrollBar(False);
-      if hoAutoResize in ToBeSet then
-        Treeview.Invalidate;
-    end;
-  end;
-
-  if not (csLoading in Treeview.ComponentState) and Treeview.HandleAllocated then
-  begin
-    if hoVisible in (ToBeSet + ToBeCleared) then
-      RecalculateHeader;
-    Invalidate(nil);
-    Treeview.Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetParentFont(Value: Boolean);
-
-begin
-  if FParentFont <> Value then
-  begin
-    FParentFont := Value;
-    if FParentFont then
-      FFont.Assign(FOwner.Font);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetSortColumn(Value: TColumnIndex);
-
-begin
-  if csLoading in Treeview.ComponentState then
-    FSortColumn := Value
-  else
-    DoSetSortColumn(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetSortDirection(const Value: TSortDirection);
-
-begin
-  if Value <> FSortDirection then
-  begin
-    FSortDirection := Value;
-    Invalidate(nil);
-    if (toAutoSort in Treeview.FOptions.FAutoOptions) and (Treeview.FUpdateCount = 0) then
-      Treeview.SortTree(FSortColumn, FSortDirection, True);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SetStyle(Value: TVTHeaderStyle);
-
-begin
-  if FStyle <> Value then
-  begin
-    FStyle := Value;
-    if not (csLoading in Treeview.ComponentState) then
-      Invalidate(nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.ChangeScale(M, D: Integer);
-
-begin
-  FFont.Size := MulDiv(FFont.Size, M, D);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.DetermineSplitterIndex(const P: TPoint): Boolean;
-
-// Tries to find the index of that column whose right border corresponds to P.
-// Result is True if column border was hit (with -3..+5 pixels tolerance).
-// For continuous resizing the current track index and the column's left/right border are set.
-// Note: The hit test is checking from right to left (or left to right in RTL mode) to make enlarging of zero-sized
-//       columns possible.
-
-var
-  I,
-  VisibleFixedWidth: Integer;
-  SplitPoint: Integer;
-
-  //--------------- local function --------------------------------------------
-
-  function IsNearBy(IsFixedCol: Boolean; LeftTolerance, RightTolerance: Integer): Boolean;
-
-  begin
-    if IsFixedCol then
-      Result := (P.X < SplitPoint + Treeview.FEffectiveOffsetX + RightTolerance) and (P.X > SplitPoint + Treeview.FEffectiveOffsetX - LeftTolerance)
-    else
-      Result := (P.X > VisibleFixedWidth) and (P.X < SplitPoint + RightTolerance) and (P.X > SplitPoint - LeftTolerance);
-  end;
-
-  //--------------- end local function ----------------------------------------
-  
-begin
-  Result := False;
-  FColumns.FTrackIndex := NoColumn;
-
-  VisibleFixedWidth := FColumns.GetVisibleFixedWidth;
-
-  if FColumns.Count > 0 then
-  begin
-    if Treeview.UseRightToLeftAlignment then
-    begin
-      SplitPoint := -Treeview.FEffectiveOffsetX;
-      if Integer(Treeview.FRangeX) < Treeview.ClientWidth then
-        Inc(SplitPoint, Treeview.ClientWidth - Integer(Treeview.FRangeX));
-
-      for I := 0 to FColumns.Count - 1 do
-        with FColumns, Items[FPositionToIndex[I]] do
-          if coVisible in FOptions then
-          begin
-            if IsNearBy(coFixed in FOptions, 5, 3) then
-            begin
-              if CanSplitterResize(P, FPositionToIndex[I]) then
-              begin
-                Result := True;
-                FTrackIndex := FPositionToIndex[I];
-
-                // Keep the right border of this column. This and the current mouse position
-                // directly determine the current column width.
-                FTrackPoint.X := SplitPoint + IfThen(coFixed in FOptions, Treeview.FEffectiveOffsetX) + FWidth;
-                FTrackPoint.Y := P.Y;
-              Break;
-            end;
-            end;
-            Inc(SplitPoint, FWidth);
-          end;
-    end
-    else
-    begin
-      SplitPoint := -Treeview.FEffectiveOffsetX + Integer(Treeview.FRangeX);
-
-      for I := FColumns.Count - 1 downto 0 do
-        with FColumns, Items[FPositionToIndex[I]] do
-          if coVisible in FOptions then
-          begin
-            if IsNearBy(coFixed in FOptions, 3, 5) then
-            begin
-              if CanSplitterResize(P, FPositionToIndex[I]) then
-              begin
-                Result := True;
-                FTrackIndex := FPositionToIndex[I];
-
-                // Keep the left border of this column. This and the current mouse position
-                // directly determine the current column width.
-                FTrackPoint.X := SplitPoint + IfThen(coFixed in FOptions, Treeview.FEffectiveOffsetX) - FWidth;
-                FTrackPoint.Y := P.Y;
-              Break;
-            end;
-            end;
-            Dec(SplitPoint, FWidth);
-          end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.DoAfterAutoFitColumn(Column: TColumnIndex);
-
-begin
-  if Assigned(TreeView.FOnAfterAutoFitColumn) then
-    TreeView.FOnAfterAutoFitColumn(Self, Column);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.DoAfterColumnWidthTracking(Column: TColumnIndex);
-
-// Tell the application that a column width tracking operation has been finished.
-
-begin
-  if Assigned(TreeView.FOnAfterColumnWidthTracking) then
-    TreeView.FOnAfterColumnWidthTracking(Self, Column);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.DoAfterHeightTracking;
-
-// Tell the application that a height tracking operation has been finished.
-
-begin
-  if Assigned(TreeView.FOnAfterHeaderHeightTracking) then
-    TreeView.FOnAfterHeaderHeightTracking(Self);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.DoBeforeAutoFitColumn(Column: TColumnIndex; SmartAutoFitType: TSmartAutoFitType): Boolean;
-
-// Query the application if we may autofit a column.
-
-begin
-  Result := True;
-  if Assigned(TreeView.FOnBeforeAutoFitColumn) then
-    TreeView.FOnBeforeAutoFitColumn(Self, Column, SmartAutoFitType, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.DoBeforeColumnWidthTracking(Column: TColumnIndex; Shift: TShiftState);
-
-// Tell the a application that a column width tracking operation may begin.
-
-begin
-  if Assigned(TreeView.FOnBeforeColumnWidthTracking) then
-    TreeView.FOnBeforeColumnWidthTracking(Self, Column, Shift);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.DoBeforeHeightTracking(Shift: TShiftState);
-
-// Tell the application that a height tracking operation may begin.
-
-begin
-  if Assigned(TreeView.FOnBeforeHeaderHeightTracking) then
-    TreeView.FOnBeforeHeaderHeightTracking(Self, Shift);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.DoColumnWidthDblClickResize(Column: TColumnIndex; P: TPoint; Shift: TShiftState): Boolean;
-
-// Queries the application whether a double click on the column splitter should resize the column.
-
-begin
-  Result := True;
-  if Assigned(TreeView.FOnColumnWidthDblClickResize) then
-    TreeView.FOnColumnWidthDblClickResize(Self, Column, Shift, P, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.DoColumnWidthTracking(Column: TColumnIndex; Shift: TShiftState; var TrackPoint: TPoint; P: TPoint): Boolean;
-
-begin
-  Result := True;
-  if Assigned(TreeView.FOnColumnWidthTracking) then
-    TreeView.FOnColumnWidthTracking(Self, Column, Shift, TrackPoint, P, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.DoGetPopupMenu(Column: TColumnIndex; Position: TPoint): TPopupMenu; 
-
-// Queries the application whether there is a column specific header popup menu.
-
-var
-  AskParent: Boolean;
-
-begin
-  Result := nil;
-  if Assigned(TreeView.FOnGetPopupMenu) then
-    TreeView.FOnGetPopupMenu(TreeView, nil, Column, Position, AskParent, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.DoHeightTracking(var P: TPoint; Shift: TShiftState): Boolean;
-
-begin
-  Result := True;
-  if Assigned(TreeView.FOnHeaderHeightTracking) then
-    TreeView.FOnHeaderHeightTracking(Self, P, Shift, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.DoHeightDblClickResize(var P: TPoint; Shift: TShiftState): Boolean;
-
-begin
-  Result := True;
-  if Assigned(TreeView.FOnHeaderHeightDblClickResize) then
-    TreeView.FOnHeaderHeightDblClickResize(Self, P, Shift, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.DoSetSortColumn(Value: TColumnIndex);
-
-begin
-  if Value < NoColumn then
-    Value := NoColumn;
-  if Value > Columns.Count - 1 then
-    Value := Columns.Count - 1;
-  if FSortColumn <> Value then
-  begin
-    if FSortColumn > NoColumn then
-      Invalidate(Columns[FSortColumn]);
-    FSortColumn := Value;
-    if FSortColumn > NoColumn then
-      Invalidate(Columns[FSortColumn]);
-    if (toAutoSort in Treeview.FOptions.FAutoOptions) and (Treeview.FUpdateCount = 0) then
-      Treeview.SortTree(FSortColumn, FSortDirection, True);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.DragTo(const P: TPoint);
-
-// Moves the drag image to a new position, which is determined from the passed point P and the previous
-// mouse position.
-
-var
-  I,
-  NewTarget: Integer;
-  // optimized drag image move support
-  ClientP: TPoint;
-  Left,
-  Right: Integer;
-  NeedRepaint: Boolean; // True if the screen needs an update (changed drop target or drop side)
-
-begin
-  // Determine new drop target and which side of it is prefered.
-  ClientP := Treeview.ScreenToClient(P);
-  // Make coordinates relative to (0, 0) of the non-client area.
-  Inc(ClientP.Y, FHeight);
-  NewTarget := FColumns.ColumnFromPosition(ClientP);
-  NeedRepaint := (NewTarget <> InvalidColumn) and (NewTarget <> FColumns.FDropTarget);
-  if NewTarget >= 0 then
-  begin
-    FColumns.GetColumnBounds(NewTarget, Left, Right);
-    if (ClientP.X < ((Left + Right) div 2)) <> FColumns.FDropBefore then
-    begin
-      NeedRepaint := True;
-      FColumns.FDropBefore := not FColumns.FDropBefore;
-    end;
-  end;
-
-  if NeedRepaint then
-  begin
-    // Invalidate columns which need a repaint.
-    if FColumns.FDropTarget > NoColumn then
-    begin
-      I := FColumns.FDropTarget;
-      FColumns.FDropTarget := NoColumn;
-      Invalidate(FColumns.Items[I]);
-    end;
-    if (NewTarget > NoColumn) and (NewTarget <> FColumns.FDropTarget) then
-    begin
-      Invalidate(FColumns.Items[NewTarget]);
-      FColumns.FDropTarget := NewTarget;
-    end;
-  end;
-
-  FDragImage.DragTo(P, NeedRepaint);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.FixedAreaConstraintsChanged(Sender: TObject);
-
-// This method gets called when FFixedAreaConstraints is changed.
-
-begin
-  Include(FStates, hsNeedScaling);
-  if Treeview.HandleAllocated then
-    RescaleHeader;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.GetColumnsClass: TVirtualTreeColumnsClass;
-
-// Returns the class to be used for the actual column implementation. descendants may optionally override this and
-// return their own class.
-
-begin
-  Result := TVirtualTreeColumns;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.GetOwner: TPersistent;
-
-begin
-  Result := FOwner;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.GetShiftState: TShiftState;
-
-begin
-  Result := [];
-  if GetKeyState(VK_SHIFT) < 0 then
-    Include(Result, ssShift);
-  if GetKeyState(VK_LWIN) < 0 then      // Mac OS X substitute of ssCtrl
-    Include(Result, ssMeta);
-  if GetKeyState(VK_CONTROL) < 0 then
-    Include(Result, ssCtrl);
-  if GetKeyState(VK_MENU) < 0 then
-    Include(Result, ssAlt);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.HandleHeaderMouseMove(var Message: TLMMouseMove): Boolean;
-
-var
-  P: TPoint;
-  I: TColumnIndex;
-
-begin
-  Result := False;
-  with Message do
-  begin
-    P := Point(XPos, YPos);
-    if hsColumnWidthTrackPending in FStates then
-    begin
-      FStates := FStates - [hsColumnWidthTrackPending] + [hsColumnWidthTracking];
-      HandleHeaderMouseMove := True;
-      Result := 0;
-    end
-    else if hsHeightTrackPending in FStates then
-    begin
-      FStates := FStates - [hsHeightTrackPending] + [hsHeightTracking];
-      HandleHeaderMouseMove := True;
-      Result := 0;
-    end
-    else
-      if hsColumnWidthTracking in FStates then
-      begin
-        if DoColumnWidthTracking(FColumns.FTrackIndex, GetShiftState, FTrackPoint, P) then
-        if Treeview.UseRightToLeftAlignment then
-            FColumns[FColumns.FTrackIndex].Width := FTrackPoint.X - XPos
-        else
-            FColumns[FColumns.FTrackIndex].Width := XPos - FTrackPoint.X;
-        HandleHeaderMouseMove := True;
-        Result := 0;
-      end
-      else if hsHeightTracking in FStates then
-      begin
-        //lclheader
-        //fixes setting height
-        Dec(P.Y, FHeight);
-        if DoHeightTracking(P, GetShiftState) then
-          SetHeight(Integer(FHeight) + P.Y);
-        HandleHeaderMouseMove := True;
-        Result := 0;
-      end
-      else
-      begin
-        if hsDragPending in FStates then
-        begin
-          P := Treeview.ClientToScreen(P);
-          // start actual dragging if allowed
-          if (hoDrag in FOptions) and Treeview.DoHeaderDragging(FColumns.FDownIndex) then
-          begin
-            if ((Abs(FDragStart.X - P.X) > DragManager.DragThreshold) or
-               (Abs(FDragStart.Y - P.Y) > DragManager.DragThreshold)) then
-            begin
-              {$ifdef DEBUG_VTV}Logger.Send([lcDrag], 'HandleHeaderMouseMove - DragIndex: %d - DownIndex: %d',
-                [FColumns.FDragIndex, FColumns.FDownIndex]);{$endif}
-              I := FColumns.FDownIndex;
-              FColumns.FDownIndex := NoColumn;
-              FColumns.FHoverIndex := NoColumn;
-              if I > NoColumn then
-                Invalidate(FColumns[I]);
-              //todo: implement drag image under gtk
-              PrepareDrag(P, FDragStart);
-              FStates := FStates - [hsDragPending] + [hsDragging];
-              HandleHeaderMouseMove := True;
-              Result := 0;
-            end;
-          end;
-        end
-        else
-          if hsDragging in FStates then
-          begin
-            DragTo(Treeview.ClientToScreen(P));
-            HandleHeaderMouseMove := True;
-            Result := 0;
-          end;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.HandleMessage(var Message: TLMessage): Boolean;
-
-// The header gets here the opportunity to handle certain messages before they reach the tree. This is important
-// because the tree needs to handle various non-client area messages for the header as well as some dragging/tracking
-// events.
-// By returning True the message will not be handled further, otherwise the message is then dispatched
-// to the proper message handlers.
-
-var
-  P: TPoint;
-  R: TRect;
-  I: TColumnIndex;
-  OldPosition: Integer;
-  HitIndex: TColumnIndex;
-  NewCursor: HCURSOR;
-  Button: TMouseButton;
-  Menu: TPopupMenu;
-  IsInHeader,
-  IsHSplitterHit,
-  IsVSplitterHit: Boolean;
-
-  //--------------- local function --------------------------------------------
-
-  function HSPlitterHit: Boolean;
-
-  var
-    NextCol: TColumnIndex;
-
-  begin
-    Result := (hoColumnResize in FOptions) and DetermineSplitterIndex(P);
-    if Result and not InHeader(P) then
-    begin
-      NextCol := FColumns.GetNextVisibleColumn(FColumns.FTrackIndex);
-      if not (coFixed in FColumns[FColumns.FTrackIndex].Options) or (NextCol <= NoColumn) or
-         (coFixed in FColumns[NextCol].Options) or (P.Y > Integer(Treeview.FRangeY)) then
-        Result := False;
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-begin
-  Result := False;
-  case Message.Msg of
-    LM_SIZE:
-      begin
-        if not (tsWindowCreating in FOwner.FStates) then
-          if (hoAutoResize in FOptions) and not (hsAutoSizing in FStates) then
-        begin
-          FColumns.AdjustAutoSize(InvalidColumn);
-          Invalidate(nil);
-          end
-          else if not (hsScaling in FStates) then
-          begin
-            RescaleHeader;
-            Invalidate(nil);
-        end;
-      end;
-    CM_PARENTFONTCHANGED:
-      if FParentFont then
-        FFont.Assign(FOwner.Font);
-    CM_BIDIMODECHANGED:
-      for I := 0 to FColumns.Count - 1 do
-        if coParentBiDiMode in FColumns[I].FOptions then
-          FColumns[I].ParentBiDiModeChanged;
-    LM_MBUTTONDOWN:
-      begin
-        //lclheader: NCMessages are given in screen coordinates unlike the ordinary
-        with TLMMButtonDown(Message) do
-          P:= Point(XPos, YPos);
-          //P := Treeview.ScreenToClient(Point(XPos, YPos));
-        if InHeader(P) then
-          FOwner.DoHeaderMouseDown(mbMiddle, GetShiftState, P.X, P.Y + Integer(FHeight));
-      end;
-    LM_MBUTTONUP:
-      begin
-        with TLMMButtonUp(Message) do
-          P:= Point(XPos, YPos);
-          //P := FOwner.ScreenToClient(Point(XPos, YPos));
-        if InHeader(P) then
-        begin
-          FColumns.HandleClick(P, mbMiddle, True, False);
-          FOwner.DoHeaderMouseUp(mbMiddle, GetShiftState, P.X, P.Y + Integer(FHeight));
-          FColumns.FDownIndex := NoColumn;
-        end;
-      end;
-    LM_LBUTTONDBLCLK,
-    LM_MBUTTONDBLCLK,
-    LM_RBUTTONDBLCLK:
-      begin
-        with TLMLButtonDblClk(Message) do
-          P := Point(XPos, YPos);
-
-        if (hoHeightDblClickResize in FOptions) and InHeaderSplitterArea(P) and (FDefaultHeight > 0) then
-        begin
-          if DoHeightDblClickResize(P, GetShiftState) and (FDefaultHeight > 0) then
-            SetHeight(FMinHeight);
-          Result := True;
-        end
-        else if HSplitterHit and (Message.Msg = LM_LBUTTONDBLCLK) and
-          (hoDblClickResize in FOptions) and (FColumns.FTrackIndex > NoColumn) then
-        begin
-          // If the click was on a splitter then resize column to smallest width.
-          if DoColumnWidthDblClickResize(FColumns.FTrackIndex, P, GetShiftState) then
-            AutoFitColumns(True, smaUseColumnOption, Columns.FTrackIndex, Columns.FTrackIndex);
-          Message.Result := 0;
-          Result := True;
-        end
-        else if InHeader(P) and (Message.Msg <> LM_LBUTTONDBLCLK) then
-        begin
-          case Message.Msg of
-            LM_MBUTTONDBLCLK:
-              Button := mbMiddle;
-            LM_RBUTTONDBLCLK:
-              Button := mbRight;
-          else
-            // WM_NCLBUTTONDBLCLK
-            Button := mbLeft;
-          end;
-          FColumns.HandleClick(P, Button, True, True);
-        end;
-      end;
-    // The "hot" area of the headers horizontal splitter is partly within the client area of the the tree, so we need
-    // to handle WM_LBUTTONDOWN here, too.
-    LM_LBUTTONDOWN:
-      begin
-        if csDesigning in Treeview.ComponentState then
-          Exit;
-
-        Application.CancelHint;
-
-        // make sure no auto scrolling is active...
-        KillTimer(Treeview.Handle, ScrollTimer);
-        Treeview.DoStateChange([], [tsScrollPending, tsScrolling]);
-        // ... pending editing is cancelled (actual editing remains active)
-        KillTimer(Treeview.Handle, EditTimer);
-        Treeview.DoStateChange([], [tsEditPending]);
-
-        with TLMLButtonDown(Message) do
-        begin
-          // want the drag start point in screen coordinates
-          P := Point(XPos, YPos);
-          FDragStart := Treeview.ClientToScreen(P);
-          //FDragStart := Point(XPos, YPos);
-          //P := Treeview.ScreenToClient(FDragStart);
-        end;
-
-        IsInHeader := InHeader(P);
-        IsVSplitterHit := (hoHeightResize in FOptions) and InHeaderSplitterArea(P);
-        IsHSplitterHit := HSplitterHit;
-
-        if IsVSplitterHit or IsHSplitterHit then
-          begin
-            FTrackStart := P;
-          FColumns.FHoverIndex := NoColumn;
-          if IsVSplitterHit then
-          begin
-            DoBeforeHeightTracking(GetShiftState);
-            Include(FStates, hsHeightTrackPending)
-          end
-          else
-          begin
-            DoBeforeColumnWidthTracking(FColumns.FTrackIndex, GetShiftState);
-            Include(FStates, hsColumnWidthTrackPending);
-          end;
-
-            SetCapture(Treeview.Handle);
-            Result := True;
-            Message.Result := 0;
-          end
-        else if IsInHeader then
-          begin
-            HitIndex := Columns.AdjustDownColumn(P);
-            if (hoDrag in FOptions) and (HitIndex > NoColumn) and (coDraggable in FColumns[HitIndex].FOptions) then
-            begin
-              // Show potential drag operation.
-              // Disabled columns do not start a drag operation because they can't be clicked.
-              Include(FStates, hsDragPending);
-              SetCapture(Treeview.Handle);
-              Result := True;
-              Message.Result := 0;
-            end;
-          end;
-
-        // This is a good opportunity to notify the application.
-        if IsInHeader then
-          FOwner.DoHeaderMouseDown(mbLeft, GetShiftState, P.X, P.Y + Integer(FHeight));
-        end;
-    LM_RBUTTONDOWN:
-      begin
-        with TLMRButtonDown(Message) do
-          P:=Point(XPos,YPos);
-          //P := FOwner.ScreenToClient(Point(XPos, YPos));
-        if InHeader(P) then
-          FOwner.DoHeaderMouseDown(mbRight, GetShiftState, P.X, P.Y + Integer(FHeight));
-      end;
-    LM_RBUTTONUP:
-      if not (csDesigning in FOwner.ComponentState) then
-        with TLMRButtonUp(Message) do
-        begin
-          Application.CancelHint;
-
-          P := Point(XPos,YPos);
-          //P := FOwner.ScreenToClient(Point(XPos, YPos));
-          if InHeader(P) then
-          begin
-            FColumns.HandleClick(P, mbRight, True, False);
-            FOwner.DoHeaderMouseUp(mbRight, GetShiftState, P.X, P.Y + Integer(FHeight));
-            FColumns.FDownIndex := NoColumn;
-            FColumns.FTrackIndex := NoColumn;
-
-            Menu := FPopupMenu;
-            if not Assigned(Menu) then
-              Menu := DoGetPopupMenu(FColumns.ColumnFromPosition(Point(P.X, P.Y + Integer(FHeight))), P);
-
-            // Trigger header popup if there's one.
-            if Assigned(Menu) then
-            begin
-              KillTimer(Treeview.Handle, ScrollTimer);
-              FColumns.FHoverIndex := NoColumn;
-              Treeview.DoStateChange([], [tsScrollPending, tsScrolling]);
-              Menu.PopupComponent := Treeview;
-              P := Treeview.ClientToScreen(Point(XPos, YPos));
-              Menu.Popup(P.X, P.Y);
-              HandleMessage := True;
-            end;
-          end;
-        end;
-    // When the tree window has an active mouse capture then we only get "client-area" messages.
-    LM_LBUTTONUP:
-      begin
-        Application.CancelHint;
-
-        if FStates <> [] then
-        begin
-          ReleaseCapture;
-          //lcl
-          if hsColumnWidthTracking in FStates then
-          begin
-            if not InHeader(SmallPointToPoint(TLMLButtonUp(Message).Pos)) then
-              TreeView.Cursor := crDefault;
-          end;
-          if hsDragging in FStates then
-          begin
-            // successfull dragging moves columns
-            with TLMLButtonUp(Message) do
-              P := Treeview.ClientToScreen(Point(XPos, YPos));
-            GetWindowRect(Treeview.Handle, R);
-            {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Header - EndDrag / R',R);{$endif}
-            with FColumns do
-            begin
-              {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Header - EndDrag / FDropTarget: %d FDragIndex: %d FDragIndexPosition: %d',
-                [FDropTarget, FDragIndex, FColumns[FDragIndex].Position]);{$endif}
-              {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Header - EndDrag / FDropBefore', FColumns.FDropBefore);{$endif}
-              FDragImage.EndDrag;
-              if (FDropTarget > -1) and (FDropTarget <> FDragIndex) and PtInRect(R, P) then
-              begin
-                {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Header - EndDrag / FDropTargetPosition', FColumns[FDropTarget].Position);{$endif}
-                OldPosition := FColumns[FDragIndex].Position;
-                if FColumns.FDropBefore then
-                begin
-                  if FColumns[FDragIndex].Position < FColumns[FDropTarget].Position then
-                    FColumns[FDragIndex].Position := Max(0, FColumns[FDropTarget].Position - 1)
-                  else
-                    FColumns[FDragIndex].Position := FColumns[FDropTarget].Position;
-                end
-                else
-                begin
-                  if FColumns[FDragIndex].Position < FColumns[FDropTarget].Position then
-                    FColumns[FDragIndex].Position := FColumns[FDropTarget].Position
-                  else
-                    FColumns[FDragIndex].Position := FColumns[FDropTarget].Position + 1;
-                end;
-                Treeview.DoHeaderDragged(FDragIndex, OldPosition);
-              end
-              else
-                Treeview.DoHeaderDraggedOut(FDragIndex, P);
-              FDropTarget := NoColumn;
-            end;
-            Invalidate(nil);
-          end;
-          Result := True;
-          Message.Result := 0;
-        end;
-
-        case Message.Msg of
-          LM_LBUTTONUP:
-            with TLMLButtonUp(Message) do
-            begin
-              if FColumns.FDownIndex > NoColumn then
-                FColumns.HandleClick(Point(XPos, YPos), mbLeft, False, False);
-              if FStates <> [] then
-                FOwner.DoHeaderMouseUp(mbLeft, KeysToShiftState(Keys), XPos, YPos);
-            end;
-          //todo: there's a difference here
-          {
-          LM_NCLBUTTONUP:
-            with TLMLButtonUp(Message) do
-            begin
-              P := FOwner.ScreenToClient(Point(XPos, YPos));
-              FColumns.HandleClick(P, mbLeft, False, False);
-              FOwner.DoHeaderMouseUp(mbLeft, GetShiftState, P.X, P.Y + Integer(FHeight));
-            end;
-          }
-        end;
-
-        if FColumns.FTrackIndex > NoColumn then
-        begin
-          if hsColumnWidthTracking in FStates then
-            DoAfterColumnWidthTracking(FColumns.FTrackIndex);
-          Invalidate(Columns[FColumns.FTrackIndex]);
-          FColumns.FTrackIndex := NoColumn;
-        end;
-        if FColumns.FDownIndex > NoColumn then
-        begin
-          Invalidate(Columns[FColumns.FDownIndex]);
-          FColumns.FDownIndex := NoColumn;
-        end;
-        if hsHeightTracking in FStates then
-          DoAfterHeightTracking;
-
-        FStates := FStates - [hsDragging, hsDragPending,
-                              hsColumnWidthTracking, hsColumnWidthTrackPending,
-                              hsHeightTracking, hsHeightTrackPending];
-      end;
-    // hovering, mouse leave detection
-    CM_MOUSELEAVE:
-      with FColumns do
-      begin
-        if FHoverIndex > NoColumn then
-          Invalidate(Items[FHoverIndex]);
-        FHoverIndex := NoColumn;
-        FClickIndex := NoColumn;
-        FDownIndex := NoColumn;
-      end;
-    //todo: see the difference to below
-    LM_MOUSEMOVE:
-      with TLMMouseMove(Message), FColumns do
-      begin
-        //lcl
-        HandleMessage := HandleHeaderMouseMove(TLMMouseMove(Message));
-
-        P := Point(XPos,YPos);
-        //P := Treeview.ScreenToClient(Point(XPos, YPos));
-        IsInHeader := InHeader(P);
-        if IsInHeader then
-        begin
-          Treeview.DoHeaderMouseMove(GetShiftState, P.X, P.Y);
-          if ((AdjustHoverColumn(P)) or ((FDownIndex > NoColumn) and (FHoverIndex <> FDownIndex))) then
-          begin
-            Invalidate(nil);
-            // todo: under lcl, the hint is show even if HintMouseMessage is not implemented
-            // Is it necessary here?
-            // use Delphi's internal hint handling for header hints too
-            if hoShowHint in FOptions then
-            begin
-              // client coordinates!
-              XPos := P.x;
-              YPos := P.y;
-              Application.HintMouseMessage(Treeview, Message);
-            end;
-          end;
-        end
-        else
-        begin
-          if FHoverIndex > NoColumn then
-            Invalidate(Items[FHoverIndex]);
-          FHoverIndex := NoColumn;
-          FClickIndex := NoColumn;
-          FDownIndex := NoColumn;
-        end;
-        //Adjust Cursor
-        if not (csDesigning in FOwner.ComponentState) and (FStates = []) then
-        begin
-          //todo: see a way to store the user defined cursor.
-          IsHSplitterHit := IsInHeader and HSplitterHit;
-          IsVSplitterHit := (hoHeightResize in FOptions) and InHeaderSplitterArea(P);
-          
-          if IsVSplitterHit or IsHSplitterHit then
-          begin
-            NewCursor := crDefault;
-            if IsVSplitterHit and (hoHeightResize in FOptions) then
-              NewCursor := crVertSplit
-            else if IsHSplitterHit then
-              NewCursor := crHeaderSplit;
-
-            Treeview.DoGetHeaderCursor(NewCursor);
-            if NewCursor <> crDefault then
-            begin
-              Treeview.Cursor := NewCursor;
-              HandleMessage := True;
-              Message.Result := 1;
-            end;
-          end;
-        end
-        else
-        begin
-          Message.Result := 1;
-          HandleMessage := True;
-        end;
-      end;
-    LM_KEYDOWN,
-    LM_KILLFOCUS:
-      if (Message.Msg = LM_KILLFOCUS) or
-         (TLMKeyDown(Message).CharCode = VK_ESCAPE) then
-      begin
-        if hsDragging in FStates then
-        begin
-          ReleaseCapture;
-          FDragImage.EndDrag;
-          Exclude(FStates, hsDragging);
-          FColumns.FDropTarget := NoColumn;
-          Invalidate(nil);
-          Result := True;
-          Message.Result := 0;
-        end
-        else
-        begin
-          if [hsColumnWidthTracking, hsHeightTracking] * FStates <> [] then
-          begin
-            ReleaseCapture;
-            if hsColumnWidthTracking in FStates then
-              DoAfterColumnWidthTracking(FColumns.FTrackIndex);
-            if hsHeightTracking in FStates then
-              DoAfterHeightTracking;
-            Result := True;
-            Message.Result := 0;
-          end;
-
-          FStates := FStates - [hsColumnWidthTracking, hsColumnWidthTrackPending,
-                                hsHeightTracking, hsHeightTrackPending];
-        end;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.ImageListChange(Sender: TObject);
-
-begin
-  if not (csDestroying in Treeview.ComponentState) then
-    Invalidate(nil);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.PrepareDrag(P, Start: TPoint);
-
-// Initializes dragging of the header, P is the current mouse postion and Start the initial mouse position.
-
-var
-  HeaderR: TRect;
-  Image: TBitmap;
-  ImagePos: TPoint;
-  DragColumn: TVirtualTreeColumn;
-
-begin
-  // Determine initial position of drag image (screen coordinates).
-  FColumns.FDropTarget := NoColumn;
-  Start := Treeview.ScreenToClient(Start);
-  FColumns.FDragIndex := FColumns.ColumnFromPosition(Start);
-  DragColumn := FColumns[FColumns.FDragIndex];
-
-  HeaderR := Treeview.FHeaderRect;
-
-  // Set right border of the header rectangle to the maximum extent.
-  // Adjust top border too, it is already covered elsewhere.
-  HeaderR.Right := FColumns.TotalWidth;
-  HeaderR.Top := 0;
-
-  // Take out influence of border since we need a seamless drag image.
-  OffsetRect(HeaderR, -Treeview.BorderWidth, -Treeview.BorderWidth);
-  if Treeview.UseRightToLeftAlignment then
-    Dec(HeaderR.Left, Treeview.ComputeRTLOffset);
-
-  Image := TBitmap.Create;
-  with Image do
-  try
-    PixelFormat := pf32Bit;
-    Width := DragColumn.Width;
-    Height := FHeight;
-
-    // Erase the entire image with the color key value, for the case not everything
-    // in the image is covered by the header image.
-    Canvas.Brush.Color := clBtnFace;
-    Canvas.FillRect(Rect(0, 0, Width, Height));
-
-    // Now move the window origin of bitmap DC so that although the entire header is painted
-    // only the dragged column becomes visible.
-    SetWindowOrgEx(Canvas.Handle, DragColumn.FLeft, 0, nil);
-    FColumns.PaintHeader(Canvas.Handle, HeaderR, 0);
-    SetWindowOrgEx(Canvas.Handle, 0, 0, nil);
-
-    if Treeview.UseRightToLeftAlignment then
-      ImagePos := Treeview.ClientToScreen(Point(DragColumn.Left + Treeview.ComputeRTLOffset(True), 0))
-    else
-      ImagePos := Treeview.ClientToScreen(Point(DragColumn.Left, 0));
-    //lclheader
-    // Column rectangles are given in local window coordinates not client coordinates.
-    // The above statement is not valid under LCL
-    //Dec(ImagePos.Y, FHeight);
-
-    if hoRestrictDrag in FOptions then
-      FDragImage.MoveRestriction := dmrHorizontalOnly
-    else
-      FDragImage.MoveRestriction := dmrNone;
-    FDragImage.PrepareDrag(Image, ImagePos, P, nil);
-    FDragImage.ShowDragImage;
-  finally
-    Image.Free;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.RecalculateHeader;
-
-// Initiate a recalculation of the non-client area of the owner tree.
-
-begin
-  if Treeview.HandleAllocated then
-  begin
-    Treeview.UpdateHeaderRect;
-    //lclheader
-    //not necessary since header is draw inside client area
-    //SetWindowPos(Treeview.Handle, 0, 0, 0, 0, 0, SWP_FRAMECHANGED or SWP_NOMOVE or SWP_NOACTIVATE or SWP_NOOWNERZORDER or
-    //  SWP_NOSENDCHANGING or SWP_NOSIZE or SWP_NOZORDER);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.RescaleHeader;
-
-// Rescale the fixed elements (fixed columns, header itself) to FixedAreaConstraints.
-
-var
-  FixedWidth,
-  MaxFixedWidth,
-  MinFixedWidth: Integer;
-
-  //--------------- local function --------------------------------------------
-
-  procedure ComputeConstraints;
-
-  var
-    I: TColumnIndex;
-
-  begin
-    with FColumns do
-    begin
-      I := GetFirstVisibleColumn;
-      while I > NoColumn do
-      begin
-        if (coFixed in FColumns[I].Options) and (FColumns[I].Width < FColumns[I].MinWidth) then
-          FColumns[I].FWidth := FColumns[I].FMinWidth;
-        I := GetNextVisibleColumn(I);
-      end;
-      FixedWidth := GetVisibleFixedWidth;
-    end;
-
-    with FFixedAreaConstraints do
-    begin
-      MinFixedWidth := (TreeView.ClientWidth * FMinWidthPercent) div 100;
-      MaxFixedWidth := (TreeView.ClientWidth * FMaxWidthPercent) div 100;
-    end;
-  end;
-
-  //----------- end local function --------------------------------------------
-
-begin
-  if ([csLoading, csReading, csWriting, csDestroying] * Treeview.ComponentState = []) and not
-     (hsLoading in FStates) and Treeview.HandleAllocated then
-  begin
-    Include(FStates, hsScaling);
-
-    SetHeight(FHeight);
-    RecalculateHeader;
-
-    with FFixedAreaConstraints do
-      if (FMinHeightPercent > 0) or (FMaxHeightPercent > 0) then
-      begin
-        ComputeConstraints;
-
-        with FColumns do
-          if (FMaxWidthPercent > 0) and (FixedWidth > MaxFixedWidth) then
-            ResizeColumns(MaxFixedWidth - FixedWidth, 0, Count - 1, [coVisible, coFixed])
-          else if (FMinWidthPercent > 0) and (FixedWidth < MinFixedWidth) then
-            ResizeColumns(MinFixedWidth - FixedWidth, 0, Count - 1, [coVisible, coFixed]);
-
-        FColumns.UpdatePositions;
-      end;
-
-    Exclude(FStates, hsScaling);
-    Exclude(FStates, hsNeedScaling);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.UpdateMainColumn;
-
-// Called once the load process of the owner tree is done.
-
-begin
-  if FMainColumn < 0 then
-    FMainColumn := 0;
-  if FMainColumn > FColumns.Count - 1 then
-    FMainColumn := FColumns.Count - 1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.UpdateSpringColumns;
-
-var
-  I: TColumnIndex;
-  SpringCount: Integer;
-  Sign: Integer;
-  ChangeBy: Single;
-  Difference: Single;
-  NewAccumulator: Single;
-
-begin
-  with TreeView do
-    ChangeBy := FHeaderRect.Right - FHeaderRect.Left - FLastWidth;
-  if (hoAutoSpring in FOptions) and (FLastWidth <> 0) and (ChangeBy <> 0) then
-  begin
-    // Stay positive if downsizing the control.
-    if ChangeBy < 0 then
-      Sign := -1
-    else
-      Sign := 1;
-    ChangeBy := Abs(ChangeBy);
-    // Count how many columns have spring enabled.
-    SpringCount := 0;
-    for I := 0 to FColumns.Count-1 do
-      if [coVisible, coAutoSpring] * FColumns[I].FOptions = [coVisible, coAutoSpring] then
-        Inc(SpringCount);
-    if SpringCount > 0 then
-    begin
-      // Calculate the size to add/sub to each columns.
-      Difference := ChangeBy / SpringCount;
-      // Adjust the column's size accumulators and resize if the result is >= 1.
-      for I := 0 to FColumns.Count - 1 do
-        if [coVisible, coAutoSpring] * FColumns[I].FOptions = [coVisible, coAutoSpring] then
-        begin
-          // Sum up rest changes from previous runs and the amount from this one and store it in the
-          // column. If there is at least one pixel difference then do a resize and reset the accumulator.
-          NewAccumulator := FColumns[I].FSpringRest + Difference;
-          // Set new width if at least one pixel size difference is reached.
-          if NewAccumulator >= 1 then
-            FColumns[I].SetWidth(FColumns[I].FWidth + (Trunc(NewAccumulator) * Sign));
-          FColumns[I].FSpringRest := Frac(NewAccumulator);
-
-          // Keep track of the size count.
-          ChangeBy := ChangeBy - Difference;
-          // Exit loop if resize count drops below freezing point.
-          if ChangeBy < 0 then
-            Break;
-        end;
-    end;
-  end;
-  with TreeView do
-    FLastWidth := FHeaderRect.Right - FHeaderRect.Left;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.AllowFocus(ColumnIndex: TColumnIndex): Boolean;
-begin
-  Result := False;
-  if not FColumns.IsValidColumn(ColumnIndex) then exit; // Just in case.
-
-  Result := (coAllowFocus in FColumns[ColumnIndex].Options);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.Assign(Source: TPersistent);
-
-begin
-  if Source is TVTHeader then
-  begin
-    AutoSizeIndex := TVTHeader(Source).AutoSizeIndex;
-    Background := TVTHeader(Source).Background;
-    Columns := TVTHeader(Source).Columns;
-    Font := TVTHeader(Source).Font;
-    FixedAreaConstraints.Assign(TVTHeader(Source).FixedAreaConstraints);
-    Height := TVTHeader(Source).Height;
-    Images := TVTHeader(Source).Images;
-    MainColumn := TVTHeader(Source).MainColumn;
-    Options := TVTHeader(Source).Options;
-    ParentFont := TVTHeader(Source).ParentFont;
-    PopupMenu := TVTHeader(Source).PopupMenu;
-    SortColumn := TVTHeader(Source).SortColumn;
-    SortDirection := TVTHeader(Source).SortDirection;
-    Style := TVTHeader(Source).Style;
-
-    RescaleHeader;
-  end
-  else
-    inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.AutoFitColumns(Animated: Boolean = True; SmartAutoFitType: TSmartAutoFitType = smaUseColumnOption;
-  RangeStartCol: Integer = NoColumn; RangeEndCol: Integer = NoColumn);
-
-  //--------------- local functions -------------------------------------------
-
-  function GetUseSmartColumnWidth(ColumnIndex: TColumnIndex): Boolean;
-
-  begin
-    Result := False;
-    case SmartAutoFitType of
-      smaAllColumns:
-        Result := True;
-      smaNoColumn:
-        Result := False;
-      smaUseColumnOption:
-        Result := coSmartResize in FColumns.Items[ColumnIndex].FOptions;
-    end;
-  end;
-
-  //----------------------------------------------------------------------------
-
-  procedure DoAutoFitColumn(Column: TColumnIndex);
-
-  begin
-    with FColumns do
-      if ([coResizable, coVisible] * Items[FPositionToIndex[Column]].FOptions = [coResizable, coVisible]) and
-            DoBeforeAutoFitColumn(FPositionToIndex[Column], SmartAutoFitType) and not TreeView.OperationCanceled then
-      begin
-        if Animated then
-          AnimatedResize(FPositionToIndex[Column], Treeview.GetMaxColumnWidth(FPositionToIndex[Column],
-            GetUseSmartColumnWidth(FPositionToIndex[Column])))
-        else
-          FColumns[FPositionToIndex[Column]].Width := Treeview.GetMaxColumnWidth(FPositionToIndex[Column],
-            GetUseSmartColumnWidth(FPositionToIndex[Column]));
-
-        DoAfterAutoFitColumn(FPositionToIndex[Column]);
-      end;
-  end;
-
-  //--------------- end local functions ----------------------------------------
-
-var
-  I: Integer;
-  StartCol,
-  EndCol: Integer;
-
-begin
-  StartCol := Max(NoColumn + 1, RangeStartCol);
-
-  if RangeEndCol <= NoColumn then
-    EndCol := FColumns.Count - 1
-  else
-    EndCol := Min(RangeEndCol, FColumns.Count - 1);
-
-  if StartCol > EndCol then
-    Exit; // nothing to do
-
-  TreeView.BeginOperation;
-  if Assigned(TreeView.FOnBeforeAutoFitColumns) then
-    TreeView.FOnBeforeAutoFitColumns(Self, SmartAutoFitType);
-
-  for I := StartCol to EndCol do
-    DoAutoFitColumn(I);
-
-  if Assigned(TreeView.FOnAfterAutoFitColumns) then
-    TreeView.FOnAfterAutoFitColumns(Self);
-  Treeview.EndOperation;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.InHeader(const P: TPoint): Boolean;
-
-// Determines whether the given point (client coordinates!) is within the header rectangle (non-client coordinates).
-
-begin
-  //lclheader
-  //todo: remove this function and use PtInRect directly ??
-  Result := PtInRect(TreeView.FHeaderRect, P);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.InHeaderSplitterArea(P: TPoint): Boolean;
-
-// Determines whether the given point (client coordinates!) hits the horizontal splitter area of the header.
-
-var
-  R: TRect;
-
-begin
-  Result := (hoVisible in FOptions);
-  if Result then
-  begin
-    R := Treeview.FHeaderRect;
-    R.Top := R.Bottom - 2;
-    Inc(R.Bottom, 2);
-    Result := PtInRect(R, P);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.Invalidate(Column: TVirtualTreeColumn; ExpandToBorder: Boolean = False);
-
-// Because the header is in the non-client area of the tree it needs some special handling in order to initiate its
-// repainting.
-// If ExpandToBorder is True then not only the given column but everything or (depending on hoFullRepaintOnResize) just
-// everything to its right (or left, in RTL mode) will be invalidated (useful for resizing). This makes only sense when
-// a column is given.
-
-var
-  R: TRect;
-
-begin
-  if (hoVisible in FOptions) and Treeview.HandleAllocated then
-    with Treeview do
-    begin
-      if Column = nil then
-        R := FHeaderRect
-      else
-      begin
-        R := Column.GetRect;
-        if not (coFixed in Column.Options) then
-          OffsetRect(R, -FEffectiveOffsetX, 0);
-        if UseRightToLeftAlignment then
-          OffsetRect(R, ComputeRTLOffset, 0);
-        if ExpandToBorder then
-        begin
-          if (hoFullRepaintOnResize in FHeader.FOptions) then
-          begin
-            R.Left := FHeaderRect.Left;
-            R.Right := FHeaderRect.Right;
-          end else
-          begin
-            if UseRightToLeftAlignment then
-              R.Left := FHeaderRect.Left
-            else
-              R.Right := FHeaderRect.Right;
-          end;
-        end;
-      end;
-    //lclheader
-    RedrawWindow(Handle, @R, 0, RDW_FRAME or RDW_INVALIDATE or RDW_VALIDATE or RDW_NOINTERNALPAINT or
-      RDW_NOERASE or RDW_NOCHILDREN);
-
-    {
-    // Current position of the owner in screen coordinates.
-    GetWindowRect(Handle, RW);
-
-    // Consider the header within this rectangle.
-    OffsetRect(R, RW.Left, RW.Top);
-
-    // Expressed in client coordinates (because RedrawWindow wants them so, they will actually become negative).
-    MapWindowPoints(0, Handle, R, 2);
-    RedrawWindow(Handle, @R, 0, RDW_FRAME or RDW_INVALIDATE or RDW_VALIDATE or RDW_NOINTERNALPAINT or
-      RDW_NOERASE or RDW_NOCHILDREN);
-    }
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.LoadFromStream(const Stream: TStream);
-
-// restore the state of the header from the given stream
-
-var
-  Dummy,
-  Version: Integer;
-  S: AnsiString;
-  OldOptions: TVTHeaderOptions;
-
-begin
-  Include(FStates, hsLoading);
-  with Stream do
-  try
-    // Switch off all options which could influence loading the columns (they will be later set again).
-    OldOptions := FOptions;
-    FOptions := [];
-
-    // Determine whether the stream contains data without a version number.
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    if Dummy > -1 then
-    begin
-      // Seek back to undo the read operation if this is an old stream format.
-      Seek(-SizeOf(Dummy), soFromCurrent);
-      Version := -1;
-    end
-    else // Read version number if this is a "versionized" format.
-      ReadBuffer(Version, SizeOf(Version));
-    Columns.LoadFromStream(Stream, Version);
-
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    AutoSizeIndex := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Background := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Height := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    FOptions := OldOptions;
-    Options := TVTHeaderOptions(Word(Dummy));
-    // PopupMenu is neither saved nor restored
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    Style := TVTHeaderStyle(Dummy);
-    // TFont has no own save routine so we do it manually
-    with Font do
-    begin
-      ReadBuffer(Dummy, SizeOf(Dummy));
-      Color := Dummy;
-      ReadBuffer(Dummy, SizeOf(Dummy));
-      Height := Dummy;
-      ReadBuffer(Dummy, SizeOf(Dummy));
-      SetLength(S, Dummy);
-      ReadBuffer(PAnsiChar(S)^, Dummy);
-      Name := S;
-      ReadBuffer(Dummy, SizeOf(Dummy));
-      Pitch := TFontPitch(Dummy);
-      ReadBuffer(Dummy, SizeOf(Dummy));
-      Style := TFontStyles(LongWord(Dummy));
-    end;
-    // LCL port started with header stream version 6 so no need to do the check here
-    // Read data introduced by stream version 1+.
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    MainColumn := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    SortColumn := Dummy;
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    SortDirection := TSortDirection(Byte(Dummy));
-
-    // Read data introduced by stream version 5+.
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    ParentFont := Boolean(Dummy);
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    FMaxHeight := Integer(Dummy);
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    FMinHeight := Integer(Dummy);
-    ReadBuffer(Dummy, SizeOf(Dummy));
-    FDefaultHeight := Integer(Dummy);
-    with FFixedAreaConstraints do
-    begin
-      ReadBuffer(Dummy, SizeOf(Dummy));
-      FMaxHeightPercent := TVTConstraintPercent(Dummy);
-      ReadBuffer(Dummy, Sizeof(Dummy));
-      FMaxWidthPercent := TVTConstraintPercent(Dummy);
-      ReadBuffer(Dummy, SizeOf(Dummy));
-      FMinHeightPercent := TVTConstraintPercent(Dummy);
-      ReadBuffer(Dummy, Sizeof(Dummy));
-      FMinWidthPercent := TVTConstraintPercent(Dummy);
-    end
-  finally
-    Exclude(FStates, hsLoading);
-    Treeview.DoColumnResize(NoColumn);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTHeader.ResizeColumns(ChangeBy: Integer; RangeStartCol: TColumnIndex; RangeEndCol: TColumnIndex;
-  Options: TVTColumnOptions = [coVisible]): Integer;
-
-// Distribute the given width change to a range of columns. A 'fair' way is used to distribute ChangeBy to the columns,
-// while ensuring that everything that can be distributed will be distributed.
-
-var
-  Start,
-  I: TColumnIndex;
-  ColCount,
-  ToGo,
-  Sign,
-  Rest,
-  MaxDelta,
-  Difference: Integer;
-  Constraints,
-  Widths: Array of Integer;
-  BonusPixel: Boolean;
-
-  //--------------- local functions -------------------------------------------
-
-  function IsResizable (Column: TColumnIndex): Boolean;
-
-  begin
-    if BonusPixel then
-      Result := Widths[Column - RangeStartCol] < Constraints[Column - RangeStartCol]
-    else
-      Result := Widths[Column - RangeStartCol] > Constraints[Column - RangeStartCol];
-  end;
-
-  //---------------------------------------------------------------------------
-
-  procedure IncDelta(Column: TColumnIndex);
-
-  begin
-    if BonusPixel then
-      Inc(MaxDelta, FColumns[Column].MaxWidth - Widths[Column - RangeStartCol])
-    else
-      Inc(MaxDelta, Widths[Column - RangeStartCol] - Constraints[Column - RangeStartCol]);
-  end;
-
-  //---------------------------------------------------------------------------
-
-  function ChangeWidth(Column: TColumnIndex; Delta: Integer): Integer;
-
-  begin
-    if Delta > 0 then
-      Delta := Min(Delta, Constraints[Column - RangeStartCol] - Widths[Column - RangeStartCol])
-    else
-      Delta := Max(Delta, Constraints[Column - RangeStartCol] - Widths[Column - RangeStartCol]);
-
-    Inc(Widths[Column - RangeStartCol], Delta);
-    Dec(ToGo, Abs(Delta));
-    Result := Abs(Delta);
-  end;
-
-  //---------------------------------------------------------------------------
-
-  function ReduceConstraints: Boolean;
-
-  var
-    MaxWidth,
-    MaxReserveCol,
-    Column: TColumnIndex;
-
-  begin
-    Result := True;
-    if not (hsScaling in FStates) or BonusPixel then
-      Exit;
-
-    MaxWidth := 0;
-    MaxReserveCol := NoColumn;
-    for Column := RangeStartCol to RangeEndCol do
-      if (Options * FColumns[Column].FOptions = Options) and
-         (FColumns[Column].FWidth > MaxWidth) then
-      begin
-        MaxWidth := Widths[Column - RangeStartCol];
-        MaxReserveCol := Column;
-      end;
-
-    if (MaxReserveCol <= NoColumn) or (Constraints[MaxReserveCol - RangeStartCol] <= 10) then
-      Result := False
-    else
-      Dec(Constraints[MaxReserveCol - RangeStartCol],
-          Constraints[MaxReserveCol - RangeStartCol] div 10);
-  end;
-
-  //----------- end local functions -------------------------------------------
-
-begin
-  Result := 0;
-  if ChangeBy <> 0 then
-  begin
-    // Do some initialization here
-    BonusPixel := ChangeBy > 0;
-    Sign := IfThen(BonusPixel, 1, -1);
-    Start := IfThen(BonusPixel, RangeStartCol, RangeEndCol);
-    ToGo := Abs(ChangeBy);
-    SetLength(Widths, RangeEndCol - RangeStartCol + 1);
-    SetLength(Constraints, RangeEndCol - RangeStartCol + 1);
-    for I := RangeStartCol to RangeEndCol do
-    begin
-      Widths[I - RangeStartCol] := FColumns[I].FWidth;
-      Constraints[I - RangeStartCol] := IfThen(BonusPixel, FColumns[I].MaxWidth, FColumns[I].MinWidth);
-    end;
-
-    repeat
-      repeat
-        MaxDelta := 0;
-        ColCount := 0;
-        for I := RangeStartCol to RangeEndCol do
-          if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then
-          begin
-            Inc(ColCount);
-            IncDelta(I);
-          end;
-        if MaxDelta < Abs(ChangeBy) then
-          if not ReduceConstraints then
-            Break;
-      until (MaxDelta >= Abs(ChangeBy)) or not (hsScaling in FStates);
-
-      if ColCount = 0 then
-        Break;
-
-      ToGo := Min(ToGo, MaxDelta);
-      Difference := ToGo div ColCount;
-      Rest := ToGo mod ColCount;
-
-      if Difference > 0 then
-        for I := RangeStartCol to RangeEndCol do
-          if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then
-            ChangeWidth(I, Difference * Sign);
-
-      // Now distribute Rest.
-      I := Start;
-      while Rest > 0 do
-      begin
-        if (Options * FColumns[I].FOptions = Options) and IsResizable(I) then
-          if FColumns[I].FBonusPixel <> BonusPixel then
-          begin
-            Dec(Rest, ChangeWidth(I, Sign));
-            FColumns[I].FBonusPixel := BonusPixel;
-          end;
-        Inc(I, Sign);
-        if (BonusPixel and (I > RangeEndCol)) or (not BonusPixel and (I < RangeStartCol)) then
-        begin
-          for I := RangeStartCol to RangeEndCol do
-            if Options * FColumns[I].FOptions = Options then
-              FColumns[I].FBonusPixel := not FColumns[I].FBonusPixel;
-          I := Start;
-        end;
-      end;
-    until ToGo <= 0;
-
-    // Now set the computed widths. We also compute the result here.
-    Include(FStates, hsResizing);
-    for I := RangeStartCol to RangeEndCol do
-      if (Options * FColumns[I].FOptions = Options) then
-      begin
-        Inc(Result, Widths[I - RangeStartCol] - FColumns[I].FWidth);
-        FColumns[I].SetWidth(Widths[I - RangeStartCol]);
-      end;
-    Exclude(FStates, hsResizing);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.RestoreColumns;
-
-// Restores all columns to their width which they had before they have been auto fitted.
-
-var
-  I: TColumnIndex;
-
-begin
-  with FColumns do
-    for I := Count - 1 downto 0 do
-      if [coResizable, coVisible] * Items[FPositionToIndex[I]].FOptions = [coResizable, coVisible] then
-        Items[I].RestoreLastWidth;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTHeader.SaveToStream(const Stream: TStream);
-
-// Saves the complete state of the header into the provided stream.
-
-var
-  Dummy: Integer;
-  Tmp: AnsiString;
-
-begin
-  with Stream do
-  begin
-    // In previous version of VT was no header stream version defined.
-    // For feature enhancements it is necessary, however, to know which stream
-    // format we are trying to load.
-    // In order to distict from non-version streams an indicator is inserted.
-    Dummy := -1;
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    // Write current stream version number, nothing more is required at the time being.
-    Dummy := VTHeaderStreamVersion;
-    WriteBuffer(Dummy, SizeOf(Dummy));
-
-    // Save columns in case they depend on certain options (like auto size).
-    Columns.SaveToStream(Stream);
-
-    Dummy := FAutoSizeIndex;
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    Dummy := FBackground;
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    Dummy := FHeight;
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    Dummy := Word(FOptions);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    // PopupMenu is neither saved nor restored
-    Dummy := Ord(FStyle);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    // TFont has no own save routine so we do it manually
-    with Font do
-    begin
-      Dummy := Color;
-      WriteBuffer(Dummy, SizeOf(Dummy));
-
-      // Need only to write one: size or height, I decided to write height.
-      Dummy := Height;
-      WriteBuffer(Dummy, SizeOf(Dummy));
-      Tmp := Name;
-      Dummy := Length(Tmp);
-      WriteBuffer(Dummy, SizeOf(Dummy));
-      WriteBuffer(PAnsiChar(Tmp)^, Dummy);
-      Dummy := Ord(Pitch);
-      WriteBuffer(Dummy, SizeOf(Dummy));
-      Dummy := Integer(Style);
-      WriteBuffer(Dummy, SizeOf(Dummy));
-    end;
-
-    // Data introduced by stream version 1.
-    Dummy := FMainColumn;
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    Dummy := FSortColumn;
-    WriteBuffer(Dummy, SizeOf(Dummy));
-    Dummy := Byte(FSortDirection);
-    WriteBuffer(Dummy, SizeOf(Dummy));
-
-    // 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));
-    with FFixedAreaConstraints do
-    begin
-      Dummy := Integer(FMaxHeightPercent);
-      WriteBuffer(Dummy, SizeOf(Dummy));
-      Dummy := Integer(FMaxWidthPercent);
-      WriteBuffer(Dummy, SizeOf(Dummy));
-      Dummy := Integer(FMinHeightPercent);
-      WriteBuffer(Dummy, SizeOf(Dummy));
-      Dummy := Integer(FMinWidthPercent);
-      WriteBuffer(Dummy, SizeOf(Dummy));
-    end
-  end;
-end;
-
-//----------------- TScrollBarOptions ----------------------------------------------------------------------------------
-
-constructor TScrollBarOptions.Create(AOwner: TBaseVirtualTree);
-
-begin
-  inherited Create;
-
-  FOwner := AOwner;
-  FAlwaysVisible := False;
-  FScrollBarStyle := sbmRegular;
-  FScrollBars := ssBoth;
-  FIncrementX := 20;
-  FIncrementY := 20;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TScrollBarOptions.SetAlwaysVisible(Value: Boolean);
-
-begin
-  if FAlwaysVisible <> Value then
-  begin
-    FAlwaysVisible := Value;
-    //todo_lcl_check
-    if not (csLoading in FOwner.ComponentState) and FOwner.HandleAllocated then
-      RecreateWnd(FOwner);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TScrollBarOptions.SetScrollBars(Value: TScrollStyle);
-
-begin
-  if FScrollbars <> Value then
-  begin
-    FScrollBars := Value;
-    //todo_lcl_check
-    if not (csLoading in FOwner.ComponentState) and FOwner.HandleAllocated then
-      RecreateWnd(FOwner);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TScrollBarOptions.SetScrollBarStyle(Value: TVTScrollBarStyle);
-
-begin
-  {$ifndef UseFlatScrollbars}
-    Assert(Value = sbmRegular, 'Flat scrollbars styles are disabled. Enable UseFlatScrollbars in VTConfig.inc for' +
-      'flat scrollbar support.');
-  {$endif UseFlatScrollbars}
-
-  if FScrollBarStyle <> Value then
-  begin
-    FScrollBarStyle := Value;
-    {$ifdef UseFlatScrollbars}
-      if FOwner.HandleAllocated then
-      begin
-        // If set to regular style then don't use the emulation mode of the FlatSB APIs but the original APIs.
-        // This is necessary because the FlatSB APIs don't respect NC paint request with limited update region
-        // (which is necessary for the transparent drag image).
-        FOwner.RecreateWnd;
-      end;
-    {$endif UseFlatScrollbars}
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TScrollBarOptions.GetOwner: TPersistent;
-
-begin
-  Result := FOwner;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TScrollBarOptions.Assign(Source: TPersistent);
-
-begin
-  if Source is TScrollBarOptions then
-  begin
-    AlwaysVisible := TScrollBarOptions(Source).AlwaysVisible;
-    HorizontalIncrement := TScrollBarOptions(Source).HorizontalIncrement;
-    ScrollBars := TScrollBarOptions(Source).ScrollBars;
-    ScrollBarStyle := TScrollBarOptions(Source).ScrollBarStyle;
-    VerticalIncrement := TScrollBarOptions(Source).VerticalIncrement;
-  end
-  else
-    inherited;
-end;
-
-//----------------- TVTColors ------------------------------------------------------------------------------------------
-
-constructor TVTColors.Create(AOwner: TBaseVirtualTree);
-
-begin
-  FOwner := AOwner;
-  FColors[0] := clBtnShadow;      // DisabledColor
-  FColors[1] := clHighlight;      // DropMarkColor
-  FColors[2] := clHighLight;      // DropTargetColor
-  FColors[3] := clHighLight;      // FocusedSelectionColor
-  FColors[4] := clBtnFace;        // GridLineColor
-  FColors[5] := clBtnShadow;      // TreeLineColor
-  FColors[6] := clBtnFace;        // UnfocusedSelectionColor
-  FColors[7] := clBtnFace;        // BorderColor
-  FColors[8] := clWindowText;     // HotColor
-  FColors[9] := clHighLight;      // FocusedSelectionBorderColor
-  FColors[10] := clBtnFace;       // UnfocusedSelectionBorderColor
-  FColors[11] := clHighlight;     // DropTargetBorderColor
-  FColors[12] := clHighlight;     // SelectionRectangleBlendColor
-  FColors[13] := clHighlight;     // SelectionRectangleBorderColor
-  FColors[14] := clBtnShadow;     // HeaderHotColor
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTColors.GetColor(const Index: Integer): TColor;
-
-begin
-  Result := FColors[Index];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTColors.SetColor(const Index: Integer; const Value: TColor);
-
-begin
-  if FColors[Index] <> Value then
-  begin
-    FColors[Index] := Value;
-    if not (csLoading in FOwner.ComponentState) and FOwner.HandleAllocated then
-    begin
-      // Cause helper bitmap rebuild if the button color changed.
-      case Index of
-        5:
-          begin
-            FOwner.PrepareBitmaps(True, False);
-            FOwner.Invalidate;
-          end;
-        7:
-          RedrawWindow(FOwner.Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_NOERASE or RDW_NOCHILDREN)
-      else
-        FOwner.Invalidate;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTColors.Assign(Source: TPersistent);
-
-begin
-  if Source is TVTColors then
-  begin
-    FColors := TVTColors(Source).FColors;
-    if FOwner.FUpdateCount = 0 then
-      FOwner.Invalidate;
-  end
-  else
-    inherited;
-end;
-
-//----------------- TClipboardFormats ----------------------------------------------------------------------------------
-
-constructor TClipboardFormats.Create(AOwner: TBaseVirtualTree);
-
-begin
-  FOwner := AOwner;
-  Sorted := True;
-  Duplicates := dupIgnore;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TClipboardFormats.Add(const S: string): Integer;
-
-// Restrict additions to the clipbard formats to only those which are registered with the owner tree or one of its
-// ancestors.
-
-var
-  Format: Word;
-  RegisteredClass: TVirtualTreeClass;
-
-begin
-  RegisteredClass := InternalClipboardFormats.FindFormat(S, Format);
-  if Assigned(RegisteredClass) and FOwner.ClassType.InheritsFrom(RegisteredClass) then
-    Result := inherited Add(S)
-  else
-    Result := -1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TClipboardFormats.Insert(Index: Integer; const S: string);
-
-// Restrict additions to the clipbard formats to only those which are registered with the owner tree or one of its
-// ancestors.
-
-var
-  Format: Word;
-  RegisteredClass: TVirtualTreeClass;
-
-begin
-  RegisteredClass := InternalClipboardFormats.FindFormat(S, Format);
-  if Assigned(RegisteredClass) and FOwner.ClassType.InheritsFrom(RegisteredClass) then
-    inherited Insert(Index, S);
-end;
-
-//----------------- TBaseVirtualTree -----------------------------------------------------------------------------------
-
-constructor TBaseVirtualTree.Create(AOwner: TComponent);
-
-begin
-  if not Initialized then
-    InitializeGlobalStructures;
-
-  inherited;
-
-  ControlStyle := ControlStyle - [csSetCaption] + [csCaptureMouse, csOpaque, csReplicatable, csDisplayDragImage,
-    csReflector];
-  FTotalInternalDataSize := 0;
-  FNodeDataSize := -1;
-  Width := 200;
-  Height := 100;
-  TabStop := True;
-  ParentColor := False;
-  FDefaultNodeHeight := 18;
-  FDragOperations := [doCopy, doMove];
-  FHotCursor := crDefault;
-  FScrollBarOptions := TScrollBarOptions.Create(Self);
-  FFocusedColumn := NoColumn;
-  FDragImageKind := diComplete;
-  FLastSelectionLevel := -1;
-  FSelectionBlendFactor := 128;
-
-  FIndent := 18;
-
-  FPlusBM := TBitmap.Create;
-  FHotPlusBM := TBitmap.Create;
-  FMinusBM := TBitmap.Create;
-  FHotMinusBM := TBitmap.Create;
-  BorderStyle := bsSingle;
-  FButtonStyle := bsRectangle;
-  FButtonFillMode := fmTreeColor;
-
-  FHeader := GetHeaderClass.Create(Self);
-
-  // we have an own double buffer handling
-  DoubleBuffered := False;
-
-  FCheckImageKind := ckSystemDefault;
-
-  FImageChangeLink := TChangeLink.Create;
-  FImageChangeLink.OnChange := ImageListChange;
-  FStateChangeLink := TChangeLink.Create;
-  FStateChangeLink.OnChange := ImageListChange;
-  FCustomCheckChangeLink := TChangeLink.Create;
-  FCustomCheckChangeLink.OnChange := ImageListChange;
-
-  FAutoExpandDelay := 1000;
-  FAutoScrollDelay := 1000;
-  FAutoScrollInterval := 1;
-
-  FBackground := TPicture.Create;
-
-  FDefaultPasteMode := amAddChildLast;
-  FMargin := 4;
-  FTextMargin := 4;
-  FDragType := dtOLE;
-  FDragHeight := 350;
-  FDragWidth := 200;
-
-  FColors := TVTColors.Create(Self);
-  FEditDelay := 1000;
-
-  FDragImage := TVTDragImage.Create(Self);
-  with FDragImage do
-  begin
-    Fade := True;
-    PostBlendBias := 0;
-    PreBlendBias := 0;
-    Transparency := 200;
-  end;
-
-  SetLength(FSingletonNodeArray, 1);
-  FAnimationDuration := 200;
-  FSearchTimeout := 1000;
-  FSearchStart := ssFocusedNode;
-  FNodeAlignment := naProportional;
-  FLineStyle := lsDotted;
-  FIncrementalSearch := isNone;
-  FClipboardFormats := TClipboardFormats.Create(Self);
-  FOptions := GetOptionsClass.Create(Self);
-
-  {$ifdef EnableThreadSupport}
-  AddThreadReference;
-  {$endif}
-
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TBaseVirtualTree.Destroy;
-
-begin
-  Exclude(FOptions.FMiscOptions, toReadOnly);
-  {$ifdef EnableThreadSupport}
-  ReleaseThreadReference(Self);
-  {$endif}
-  StopWheelPanning;
-  //lcl
-  FPanningWindow.Free;
-
-  // Just in case it didn't happen already release the edit link.
-  FEditLink := nil;
-  FClipboardFormats.Free;
-  // Clear will also free the drag manager if it is still alive.
-  Clear;
-  FDragImage.Free;
-  FColors.Free;
-  FBackground.Free;
-  FImageChangeLink.Free;
-  FStateChangeLink.Free;
-  FCustomCheckChangeLink.Free;
-  FScrollBarOptions.Free;
-  FOptions.Free;
-
-  // The window handle must be destroyed before the header is freed because it is needed in WM_NCDESTROY.
-  //todo_lcl_check
-  {
-  if HandleAllocated then
-    DestroyWindowHandle;
-  }
-  FreeAndNil(FHeader);
-
-  if FCheckImages <> FCustomCheckImages then
-    FCheckImages.Free;
-
-  FreeMem(FRoot);
-
-  FPlusBM.Free;
-  FHotPlusBM.Free;
-  FMinusBM.Free;
-  FHotMinusBM.Free;
-
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AdjustCoordinatesByIndent(var PaintInfo: TVTPaintInfo; Indent: Integer);
-
-// During painting of the main column some coordinates must be adjusted due to the tree lines.
-// The offset resulting from the tree lines and indentation level is given in Indent.
-
-var
-  Offset: Integer;
-
-begin
-  with PaintInfo do
-  begin
-    Offset := Indent * Integer(FIndent);
-    if BidiMode = bdLeftToRight then
-    begin
-      Inc(ContentRect.Left, Offset);
-      Inc(ImageInfo[iiNormal].XPos, Offset);
-      Inc(ImageInfo[iiState].XPos, Offset);
-      Inc(ImageInfo[iiCheck].XPos, Offset);
-    end
-    else
-    begin
-      Dec(ContentRect.Right, Offset);
-      Dec(ImageInfo[iiNormal].XPos, Offset);
-      Dec(ImageInfo[iiState].XPos, Offset);
-      Dec(ImageInfo[iiCheck].XPos, Offset);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AdjustImageBorder(ImageWidth, ImageHeight: Integer; BidiMode: TBidiMode; VAlign: Integer; var R: TRect;
-  var ImageInfo: TVTImageInfo);
-
-// Depending on the width of the image list as well as the given bidi mode R must be adjusted.
-
-begin
-  if BidiMode = bdLeftToRight then
-  begin
-    ImageInfo.XPos := R.Left;
-    Inc(R.Left, ImageWidth + 2);
-  end
-  else
-  begin
-    ImageInfo.XPos := R.Right - Images.Width;
-    Dec(R.Right, ImageWidth + 2);
-  end;
-  ImageInfo.YPos := R.Top + VAlign - ImageHeight div 2;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AdjustTotalCount(Node: PVirtualNode; Value: Integer; Relative: Boolean = False);
-
-// Sets a node's total count to the given value and recursively adjusts the parent's total count
-// (actually, the adjustment is done iteratively to avoid function call overheads).
-
-var
-  Difference: Integer;
-  Run: PVirtualNode;
-
-begin
-  if Relative then
-    Difference := Value
-  else
-    Difference := Integer(Value) - Integer(Node.TotalCount);
-  if Difference <> 0 then
-  begin
-    Run := Node;
-    // Root node has as parent the tree view.
-    while Assigned(Run) and (Run <> Pointer(Self)) do
-    begin
-      Inc(Integer(Run.TotalCount), Difference);
-      Run := Run.Parent;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AdjustTotalHeight(Node: PVirtualNode; Value: Integer; Relative: Boolean = False);
-
-// Sets a node's total height to the given value and recursively adjusts the parent's total height.
-
-var
-  Difference: Integer;
-  Run: PVirtualNode;
-
-begin
-  if Relative then
-    Difference := Value
-  else
-    Difference := Integer(Value) - Integer(Node.TotalHeight);
-  if Difference <> 0 then
-  begin
-    Run := Node;
-    repeat
-      Inc(Integer(Run.TotalHeight), Difference);
-      // If the node is not visible or the parent node is not expanded or we are already at the top
-      // then nothing more remains to do.
-      if not (vsVisible in Run.States) or (Run = FRoot) or
-        (Run.Parent = nil) or not (vsExpanded in Run.Parent.States) then
-        Break;
-
-      Run := Run.Parent;
-    until False;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CalculateCacheEntryCount: Integer;
-
-// Calculates the size of the position cache.
-
-begin
-  if FVisibleCount > 1 then
-    Result := Ceil(FVisibleCount / CacheThreshold)
-  else
-    Result := 0;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CalculateVerticalAlignments(ShowImages, ShowStateImages: Boolean; Node: PVirtualNode;
-  out VAlign, VButtonAlign: Integer);
-
-// Calculates the vertical alignment of the given node and its associated expand/collapse button during
-// a node paint cycle depending on the required node alignment style.
-
-begin
-  // For absolute alignment the calculation is trivial.
-  case FNodeAlignment of
-    naFromTop:
-      VAlign := Node.Align;
-    naFromBottom:
-      VAlign := NodeHeight[Node] - Node.Align;
-  else // naProportional
-    // Consider button and line alignment, but make sure neither the image nor the button (whichever is taller)
-    // go out of the entire node height (100% means bottom alignment to the node's bounds).
-    if ShowImages or ShowStateImages then
-    begin
-      if ShowImages then
-        VAlign := FImages.Height
-      else
-        VAlign := FStateImages.Height;
-      VAlign := MulDiv((Integer(NodeHeight[Node]) - VAlign), Node.Align, 100) + VAlign div 2;
-    end
-    else
-      if toShowButtons in FOptions.FPaintOptions then
-        VAlign := MulDiv((Integer(NodeHeight[Node]) - FPlusBM.Height), Node.Align, 100) + FPlusBM.Height div 2
-      else
-        VAlign := MulDiv(Node.NodeHeight, Node.Align, 100);
-  end;
-
-  VButtonAlign := VAlign - FPlusBM.Height div 2;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ChangeCheckState(Node: PVirtualNode; Value: TCheckState): Boolean;
-
-// Sets the check state of the node according to the given value and the node's check type.
-// If the check state must be propagated to the parent nodes and one of them refuses to change then
-// nothing happens and False is returned, otherwise True.
-
-var
-  Run: PVirtualNode;
-  UncheckedCount,
-  MixedCheckCount,
-  CheckedCount: Cardinal;
-
-begin
-  Result := not (vsChecking in Node.States);
-  with Node^ do
-  if Result then
-  begin
-    Include(States, vsChecking);
-    if not (vsInitialized in States) then
-      InitNode(Node);
-
-    // Indicate that we are going to propagate check states up and down the hierarchy.
-    if FCheckPropagationCount = 0 then // WL, 05.02.2004: Do not enter tsCheckPropagation more than once
-      DoStateChange([tsCheckPropagation]);
-    Inc(FCheckPropagationCount); // WL, 05.02.2004
-    // Do actions which are associated with the given check state.
-    case CheckType of
-      // Check state change with additional consequences for check states of the children.
-      ctTriStateCheckBox:
-        begin
-          // Propagate state down to the children.
-          if toAutoTristateTracking in FOptions.FAutoOptions then
-            case Value of
-              csUncheckedNormal:
-                if Node.ChildCount > 0 then
-                begin
-                  Run := FirstChild;
-                  CheckedCount := 0;
-                  MixedCheckCount := 0;
-                  UncheckedCount := 0;
-                  while Assigned(Run) do
-                  begin
-                    if Run.CheckType in [ctCheckBox, ctTriStateCheckBox] then
-                    begin
-                      SetCheckState(Run, csUncheckedNormal);
-                      // Check if the new child state was set successfully, otherwise we have to adjust the
-                      // node's new check state accordingly.
-                      case Run.CheckState of
-                        csCheckedNormal:
-                          Inc(CheckedCount);
-                        csMixedNormal:
-                          Inc(MixedCheckCount);
-                        csUncheckedNormal:
-                          Inc(UncheckedCount);
-                      end;
-                    end;
-                    Run := Run.NextSibling;
-                  end;
-
-                  // If there is still a mixed state child node checkbox then this node must be mixed checked too.
-                  if MixedCheckCount > 0 then
-                    Value := csMixedNormal
-                  else
-                    // If nodes are normally checked child nodes then the unchecked count determines what
-                    // to set for the node itself.
-                    if CheckedCount > 0 then
-                      if UncheckedCount > 0 then
-                        Value := csMixedNormal
-                      else
-                        Value := csCheckedNormal;
-                end;
-              csCheckedNormal:
-                if Node.ChildCount > 0 then
-                begin
-                  Run := FirstChild;
-                  CheckedCount := 0;
-                  MixedCheckCount := 0;
-                  UncheckedCount := 0;
-                  while Assigned(Run) do
-                  begin
-                    if Run.CheckType in [ctCheckBox, ctTriStateCheckBox] then
-                    begin
-                      SetCheckState(Run, csCheckedNormal);
-                      // Check if the new child state was set successfully, otherwise we have to adjust the
-                      // node's new check state accordingly.
-                      case Run.CheckState of
-                        csCheckedNormal:
-                          Inc(CheckedCount);
-                        csMixedNormal:
-                          Inc(MixedCheckCount);
-                        csUncheckedNormal:
-                          Inc(UncheckedCount);
-                      end;
-                    end;
-                    Run := Run.NextSibling;
-                  end;
-
-                  // If there is still a mixed state child node checkbox then this node must be mixed checked too.
-                  if MixedCheckCount > 0 then
-                    Value := csMixedNormal
-                  else
-                    // If nodes are normally checked child nodes then the unchecked count determines what
-                    // to set for the node itself.
-                    if CheckedCount > 0 then
-                      if UncheckedCount > 0 then
-                        Value := csMixedNormal
-                      else
-                        Value := csCheckedNormal;
-                end;
-            end;
-        end;
-      // radio button check state change
-      ctRadioButton:
-        if Value = csCheckedNormal then
-        begin
-          // Make sure only this node is checked.
-          Run := Parent.FirstChild;
-          while Assigned(Run) do
-          begin
-            if Run.CheckType = ctRadioButton then
-              Run.CheckState := csUncheckedNormal;
-            Run := Run.NextSibling;
-          end;
-          Invalidate;
-        end;
-    end;
-
-    if Result then
-      CheckState := Value // Set new check state
-    else
-      CheckState := UnpressedState[CheckState]; // Reset dynamic check state.
-
-    // Propagate state up to the parent.
-    if not (vsInitialized in Parent.States) then
-      InitNode(Parent);
-    if (toAutoTristateTracking in FOptions.FAutoOptions) and ([vsChecking, vsDisabled] * Parent.States = []) and
-      (CheckType in [ctCheckBox, ctTriStateCheckBox]) and (Parent <> FRoot) and
-      (Parent.CheckType = ctTriStateCheckBox) then
-      Result := CheckParentCheckState(Node, Value)
-    else
-      Result := True;
-
-    InvalidateNode(Node);
-    Exclude(States, vsChecking);
-
-    Dec(FCheckPropagationCount); // WL, 05.02.2004
-    if FCheckPropagationCount = 0 then // WL, 05.02.2004: Allow state change event after all check operations finished
-      DoStateChange([], [tsCheckPropagation]);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CollectSelectedNodesLTR(MainColumn, NodeLeft, NodeRight: Integer; Alignment: TAlignment;
-  OldRect: TRect; const NewRect: TRect): Boolean;
-
-// Helper routine used when a draw selection takes place. This version handles left-to-right directionality.
-// In the process of adding or removing nodes the current selection is modified which requires to pack it after
-// the function returns. Another side effect of this method is that a temporary list of nodes will be created
-// (see also InternalCacheNode) which must be inserted into the current selection by the caller.
-
-var
-  Run,
-  NextNode: PVirtualNode;
-  TextRight,
-  TextLeft,
-  CheckOffset,
-  CurrentTop,
-  CurrentRight,
-  NextTop,
-  NextColumn,
-  NodeWidth,
-  Dummy: Integer;
-  MinY, MaxY: Integer;
-  ImageOffset,
-  StateImageOffset: Integer;
-  IsInOldRect,
-  IsInNewRect: Boolean;
-
-  // quick check variables for various parameters
-  WithCheck,
-  WithImages,
-  WithStateImages,
-  DoSwitch,
-  AutoSpan: Boolean;
-  SimpleSelection: Boolean;
-
-begin
-  // A priori nothing changes.
-  Result := False;
-
-  // Determine minimum and maximum vertical coordinates to limit iteration to.
-  MinY := Min(OldRect.Top, NewRect.Top);
-  MaxY := Max(OldRect.Bottom, NewRect.Bottom);
-
-  // Initialize short hand variables to speed up tests below.
-  DoSwitch := ssCtrlOS in FDrawSelShiftState;
-  WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages);
-  // Don't check the events here as descendant trees might have overriden the DoGetImageIndex method.
-  WithImages := Assigned(FImages);
-  if WithImages then
-    ImageOffset := FImages.Width + 2
-  else
-    ImageOffset := 0;
-  WithStateImages := Assigned(FStateImages);
-  if WithStateImages then
-    StateImageOffset := FStateImages.Width + 2
-  else
-    StateImageOffset := 0;
-  if WithCheck then
-    CheckOffset := FCheckImages.Height + 2
-  else
-    CheckOffset := 0;
-  AutoSpan := FHeader.UseColumns and (toAutoSpanColumns in FOptions.FAutoOptions);
-  SimpleSelection := toSimpleDrawSelection in FOptions.FSelectionOptions;
-
-  // This is the node to start with.
-  Run := InternalGetNodeAt(0, MinY, False, CurrentTop);
-
-  if Assigned(Run) then
-  begin
-    // The initial minimal left border is determined by the identation level of the node and is dynamically adjusted.
-    if toShowRoot in FOptions.FPaintOptions then
-      Inc(NodeLeft, Integer((GetNodeLevel(Run) + 1) * FIndent) + FMargin)
-    else
-      Inc(NodeLeft, Integer(GetNodeLevel(Run) * FIndent) + FMargin);
-
-    // ----- main loop
-    // Change selection depending on the node's rectangle being in the selection rectangle or not, but
-    // touch only those nodes which overlap either the old selection rectangle or the new one but not both.
-    repeat
-      // Collect offsets for check, normal and state images.
-      TextLeft := NodeLeft;
-      if WithCheck and (Run.CheckType <> ctNone) then
-        Inc(TextLeft, CheckOffset);
-      if WithImages and HasImage(Run, ikNormal, MainColumn) then
-        Inc(TextLeft, ImageOffset);
-      if WithStateImages and HasImage(Run, ikState, MainColumn) then
-        Inc(TextLeft, StateImageOffset);
-
-      // Ensure the node's height is determined.
-      MeasureItemHeight(Canvas, Run);
-
-      NextTop := CurrentTop + Integer(NodeHeight[Run]);
-
-      // Simple selection allows to draw the selection rectangle anywhere. No intersection with node captions is
-      // required. Only top and bottom bounds of the rectangle matter.
-      if SimpleSelection then
-      begin
-        IsInOldRect := (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom);
-        IsInNewRect := (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom);
-      end
-      else
-      begin
-        // The right column border might be extended if column spanning is enabled.
-        if AutoSpan then
-        begin
-          with FHeader.FColumns do
-          begin
-            NextColumn := MainColumn;
-            repeat
-              Dummy := GetNextVisibleColumn(NextColumn);
-              if (Dummy = InvalidColumn) or not ColumnIsEmpty(Run, Dummy) or
-                (Items[Dummy].BidiMode <> bdLeftToRight) then
-                Break;
-              NextColumn := Dummy;
-            until False;
-            if NextColumn = MainColumn then
-              CurrentRight := NodeRight
-            else
-              GetColumnBounds(NextColumn, Dummy, CurrentRight);
-          end;
-        end
-        else
-          CurrentRight := NodeRight;
-
-        // Check if we need the node's width. This is the case when the node is not left aligned or the
-        // left border of the selection rectangle is to the right of the left node border.
-        if (TextLeft < OldRect.Left) or (TextLeft < NewRect.Left) or (Alignment <> taLeftJustify) then
-        begin
-          NodeWidth := DoGetNodeWidth(Run, MainColumn);
-          if NodeWidth >= (CurrentRight - TextLeft) then
-            TextRight := CurrentRight
-          else
-            case Alignment of
-              taLeftJustify:
-                TextRight := TextLeft + NodeWidth;
-              taCenter:
-                begin
-                  TextLeft := (TextLeft + CurrentRight - NodeWidth) div 2;
-                  TextRight := TextLeft + NodeWidth;
-                end;
-            else
-              // taRightJustify
-              TextRight := CurrentRight;
-              TextLeft := TextRight - NodeWidth;
-            end;
-        end
-        else
-          TextRight := CurrentRight;
-
-        // Now determine whether we need to change the state.
-        IsInOldRect := (OldRect.Left <= TextRight) and (OldRect.Right >= TextLeft) and
-          (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom);
-        IsInNewRect := (NewRect.Left <= TextRight) and (NewRect.Right >= TextLeft) and
-          (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom);
-      end;
-
-      if IsInOldRect xor IsInNewRect then
-      begin
-        Result := True;
-        if DoSwitch then
-        begin
-          if vsSelected in Run.States then
-            InternalRemoveFromSelection(Run)
-          else
-            InternalCacheNode(Run);
-        end
-        else
-        begin
-          if IsInNewRect then
-            InternalCacheNode(Run)
-          else
-            InternalRemoveFromSelection(Run);
-        end;
-      end;
-
-      CurrentTop := NextTop;
-      // Get next visible node and update left node position.
-      NextNode := GetNextVisibleNoInit(Run, True);
-      if NextNode = nil then
-        Break;
-      Inc(NodeLeft, CountLevelDifference(Run, NextNode) * Integer(FIndent));
-      Run := NextNode;
-    until CurrentTop > MaxY;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CollectSelectedNodesRTL(MainColumn, NodeLeft, NodeRight: Integer; Alignment: TAlignment;
-  OldRect: TRect; const NewRect: TRect): Boolean;
-
-// Helper routine used when a draw selection takes place. This version handles right-to-left directionality.
-// See also comments in CollectSelectedNodesLTR.
-
-var
-  Run,
-  NextNode: PVirtualNode;
-  TextRight,
-  TextLeft,
-  CheckOffset,
-  CurrentTop,
-  CurrentLeft,
-  NextTop,
-  NextColumn,
-  NodeWidth,
-  Dummy: Integer;
-  MinY, MaxY: Integer;
-  ImageOffset,
-  StateImageOffset: Integer;
-  IsInOldRect,
-  IsInNewRect: Boolean;
-
-  // quick check variables for various parameters
-  WithCheck,
-  WithImages,
-  WithStateImages,
-  DoSwitch,
-  AutoSpan: Boolean;
-  SimpleSelection: Boolean;
-
-begin
-  // A priori nothing changes.
-  Result := False;
-  // Switch the alignment to the opposite value in RTL context.
-  ChangeBiDiModeAlignment(Alignment);
-
-  // Determine minimum and maximum vertical coordinates to limit iteration to.
-  MinY := Min(OldRect.Top, NewRect.Top);
-  MaxY := Max(OldRect.Bottom, NewRect.Bottom);
-
-  // Initialize short hand variables to speed up tests below.
-  DoSwitch := ssCtrlOS in FDrawSelShiftState;
-  WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages);
-  // Don't check the events here as descendant trees might have overriden the DoGetImageIndex method.
-  WithImages := Assigned(FImages);
-  if WithImages then
-    ImageOffset := FImages.Width + 2
-  else
-    ImageOffset := 0;
-  WithStateImages := Assigned(FStateImages);
-  if WithStateImages then
-    StateImageOffset := FStateImages.Width + 2
-  else
-    StateImageOffset := 0;
-  if WithCheck then
-    CheckOffset := FCheckImages.Height + 2
-  else
-    CheckOffset := 0;
-  AutoSpan := FHeader.UseColumns and (toAutoSpanColumns in FOptions.FAutoOptions);
-  SimpleSelection := toSimpleDrawSelection in FOptions.FSelectionOptions;
-
-  // This is the node to start with.
-  Run := InternalGetNodeAt(0, MinY, False, CurrentTop);
-
-  if Assigned(Run) then
-  begin
-    // The initial minimal left border is determined by the identation level of the node and is dynamically adjusted.
-    if toShowRoot in FOptions.FPaintOptions then
-      Dec(NodeRight, Integer((GetNodeLevel(Run) + 1) * FIndent) + FMargin)
-    else
-      Dec(NodeRight, Integer(GetNodeLevel(Run) * FIndent) + FMargin);
-
-    // ----- main loop
-    // Change selection depending on the node's rectangle being in the selection rectangle or not, but
-    // touch only those nodes which overlap either the old selection rectangle or the new one but not both.
-    repeat
-      // Collect offsets for check, normal and state images.
-      TextRight := NodeRight;
-      if WithCheck and (Run.CheckType <> ctNone) then
-        Dec(TextRight, CheckOffset);
-      if WithImages and HasImage(Run, ikNormal, MainColumn) then
-        Dec(TextRight, ImageOffset);
-      if WithStateImages and HasImage(Run, ikState, MainColumn) then
-        Dec(TextRight, StateImageOffset);
-
-      // Ensure the node's height is determined.
-      MeasureItemHeight(Canvas, Run);
-
-      NextTop := CurrentTop + Integer(NodeHeight[Run]);
-
-      // Simple selection allows to draw the selection rectangle anywhere. No intersection with node captions is
-      // required. Only top and bottom bounds of the rectangle matter.
-      if SimpleSelection then
-      begin
-        IsInOldRect := (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom);
-        IsInNewRect := (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom);
-      end
-      else
-      begin
-        // The left column border might be extended if column spanning is enabled.
-        if AutoSpan then
-        begin
-          NextColumn := MainColumn;
-          repeat
-            Dummy := FHeader.FColumns.GetPreviousVisibleColumn(NextColumn);
-            if (Dummy = InvalidColumn) or not ColumnIsEmpty(Run, Dummy) or
-              (FHeader.FColumns[Dummy].BiDiMode = bdLeftToRight) then
-              Break;
-            NextColumn := Dummy;
-          until False;
-          if NextColumn = MainColumn then
-            CurrentLeft := NodeLeft
-          else
-            FHeader.FColumns.GetColumnBounds(NextColumn, CurrentLeft, Dummy);
-        end
-        else
-          CurrentLeft := NodeLeft;
-
-        // Check if we need the node's width. This is the case when the node is not left aligned (in RTL context this
-        // means actually right aligned) or the right border of the selection rectangle is to the left
-        // of the right node border.
-        if (TextRight > OldRect.Right) or (TextRight > NewRect.Right) or (Alignment <> taRightJustify) then
-        begin
-          NodeWidth := DoGetNodeWidth(Run, MainColumn);
-          if NodeWidth >= (TextRight - CurrentLeft) then
-            TextLeft := CurrentLeft
-          else
-            case Alignment of
-              taLeftJustify:
-                begin
-                  TextLeft := CurrentLeft;
-                  TextRight := TextLeft + NodeWidth;
-                end;
-              taCenter:
-                begin
-                  TextLeft := (TextRight + CurrentLeft - NodeWidth) div 2;
-                  TextRight := TextLeft + NodeWidth;
-                end;
-            else
-              // taRightJustify
-              TextLeft := TextRight - NodeWidth;
-            end;
-        end
-        else
-          TextLeft := CurrentLeft;
-
-        // Now determine whether we need to change the state.
-        IsInOldRect := (OldRect.Right >= TextLeft) and (OldRect.Left <= TextRight) and
-          (NextTop > OldRect.Top) and (CurrentTop < OldRect.Bottom);
-        IsInNewRect := (NewRect.Right >= TextLeft) and (NewRect.Left <= TextRight) and
-          (NextTop > NewRect.Top) and (CurrentTop < NewRect.Bottom);
-      end;
-
-      if IsInOldRect xor IsInNewRect then
-      begin
-        Result := True;
-        if DoSwitch then
-        begin
-          if vsSelected in Run.States then
-            InternalRemoveFromSelection(Run)
-          else
-            InternalCacheNode(Run);
-        end
-        else
-        begin
-          if IsInNewRect then
-            InternalCacheNode(Run)
-          else
-            InternalRemoveFromSelection(Run);
-        end;
-      end;
-
-      CurrentTop := NextTop;
-      // Get next visible node and update left node position.
-      NextNode := GetNextVisibleNoInit(Run, True);
-      if NextNode = nil then
-        Break;
-      Dec(NodeRight, CountLevelDifference(Run, NextNode) * Integer(FIndent));
-      Run := NextNode;
-    until CurrentTop > MaxY;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ClearNodeBackground(const PaintInfo: TVTPaintInfo; UseBackground, Floating: Boolean;
-  R: TRect);
-
-// Erases a node's background depending on what the application decides to do.
-// UseBackground determines whether or not to use the background picture, while Floating indicates
-// that R is given in coordinates of the small node bitmap or the superordinated target bitmap used in PaintTree.
-
-var
-  BackColor: TColor;
-  EraseAction: TItemEraseAction;
-  Offset: TPoint;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'ClearNodeBackground');{$endif}
-  with PaintInfo do
-  begin
-    EraseAction := eaDefault;
-    BackColor := Brush.Color;
-    if Floating then
-    begin
-      Offset := Point(-FEffectiveOffsetX, R.Top);
-      OffsetRect(R, 0, -Offset.Y);
-    end
-    else
-      Offset := Point(0, 0);
-
-    DoBeforeItemErase(Canvas, Node, R, Backcolor, EraseAction);
-
-    with Canvas do
-    begin
-      case EraseAction of
-        eaNone:
-          ;
-        eaColor:
-          begin
-            // User has given a new background color.
-            Brush.Color := BackColor;
-            FillRect(R);
-          end;
-      else // eaDefault
-        if UseBackground then
-        begin
-          if toStaticBackground in TreeOptions.PaintOptions then
-            StaticBackground(FBackground.Bitmap, Canvas, Offset, R)
-          else
-            TileBackground(FBackground.Bitmap, Canvas, Offset, R);
-        end
-        else
-        begin
-          //clear the node background
-          //note there's a bug in original VTV that can lead to wrong node paint
-          //so, here the node is always cleared even if is selected
-          Brush.Color := Self.Brush.Color;
-          FillRect(R);
-          {$ifdef DEBUG_VTV}Logger.SendColor([lcPaintDetails],'Clearing a node background - Brush.Color', Brush.Color);{$endif}
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Clearing Rectangle (R)', R);{$endif}
-
-          if (poDrawSelection in PaintOptions) and (toFullRowSelect in FOptions.FSelectionOptions) and
-             (vsSelected in Node.States) and not (toUseBlendedSelection in FOptions.PaintOptions) and not
-             ((tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) and IsWinVistaOrAbove) then
-          begin
-            {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails, lcDrag], 'Draw the background of a selected node');{$endif}
-            if toShowHorzGridLines in FOptions.PaintOptions then
-              Dec(R.Bottom);
-            if Focused or (toPopupMode in FOptions.FPaintOptions) then
-            begin
-              Brush.Color := FColors.FocusedSelectionColor;
-              Pen.Color := FColors.FocusedSelectionBorderColor;
-            end
-            else
-            begin
-              Brush.Color := FColors.UnfocusedSelectionColor;
-              Pen.Color := FColors.UnfocusedSelectionBorderColor;
-            end;
-
-            with R do
-              RoundRect(Left, Top, Right, Bottom, FSelectionCurveRadius, FSelectionCurveRadius);
-          end;
-        end;
-      end;
-      DoAfterItemErase(Canvas, Node, R);
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'ClearNodeBackground');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CompareNodePositions(Node1, Node2: PVirtualNode; ConsiderChildrenAbove: Boolean = False): Integer;
-
-// Tries hard and smart to quickly determine whether Node1's structural position is before Node2's position.
-// If ConsiderChildrenAbove is True, the nodes will be compared with their visual order in mind.
-// Returns 0 if Node1 = Node2, < 0 if Node1 is located before Node2 else > 0.
-
-var
-  Run1,
-  Run2: PVirtualNode;
-  Level1,
-  Level2: Cardinal;
-
-begin
-  Assert(Assigned(Node1) and Assigned(Node2), 'Nodes must never be nil.');
-
-  if Node1 = Node2 then
-    Result := 0
-  else
-  begin
-    if HasAsParent(Node1, Node2) then
-      Result := IfThen(ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions), -1, 1)
-    else
-      if HasAsParent(Node2, Node1) then
-        Result := IfThen(ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions), 1, -1)
-      else
-      begin
-        // the given nodes are neither equal nor are they parents of each other, so go up to FRoot
-        // for each node and compare the child indices of the top level parents
-        // Note: neither Node1 nor Node2 can be FRoot at this point as this (a bit strange) circumstance would
-        //       be caught by the previous code.
-
-        // start lookup at the same level
-        Level1 := GetNodeLevel(Node1);
-        Level2 := GetNodeLevel(Node2);
-        Run1 := Node1;
-        while Level1 > Level2 do
-        begin
-          Run1 := Run1.Parent;
-          Dec(Level1);
-        end;
-        Run2 := Node2;
-        while Level2 > Level1 do
-        begin
-          Run2 := Run2.Parent;
-          Dec(Level2);
-        end;
-
-        // now go up until we find a common parent node (loop will safely stop at FRoot if the nodes
-        // don't share a common parent)
-        while Run1.Parent <> Run2.Parent do
-        begin
-          Run1 := Run1.Parent;
-          Run2 := Run2.Parent;
-        end;
-        Result := Integer(Run1.Index) - Integer(Run2.Index);
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DetermineLineImageAndSelectLevel(Node: PVirtualNode; out LineImage: TLineImage): Integer;
-
-// This method is used during paint cycles and initializes an array of line type IDs. These IDs are used to paint
-// the tree lines in front of the given node.
-// Additionally an initial count of selected parents is determined and returned which is used for specific painting.
-
-var
-  X: Integer;
-  Run: PVirtualNode;
-
-begin
-  Result := 0;
-  if toShowRoot in FOptions.FPaintOptions then
-    X := 1
-  else
-    X := 0;
-  Run := Node;
-  // Determine indentation level of top node.
-  while Run.Parent <> FRoot do
-  begin
-    Inc(X);
-    Run := Run.Parent;
-    // Count selected nodes (FRoot is never selected).
-    if vsSelected in Run.States then
-      Inc(Result);
-  end;
-
-  // Set initial size of line index array, this will automatically initialized all entries to ltNone.
-  SetLength(LineImage, X);
-
-  // Only use lines if requested.
-  if toShowTreeLines in FOptions.FPaintOptions then
-  begin
-    if toChildrenAbove in FOptions.FPaintOptions then
-    begin
-      Dec(X);
-      if not HasVisiblePreviousSibling(Node) then
-      begin
-        if (Node.Parent <> FRoot) or HasVisibleNextSibling(Node) then
-          LineImage[X] := ltBottomRight
-        else
-          LineImage[X] := ltRight;
-      end
-      else if (Node.Parent = FRoot) and (not HasVisibleNextSibling(Node)) then
-        LineImage[X] := ltTopRight
-      else
-        LineImage[X] := ltTopDownRight;
-
-      // Now go up to the root to determine the rest.
-      Run := Node.Parent;
-      while Run <> FRoot do
-      begin
-        Dec(X);
-        if HasVisiblePreviousSibling(Run) then
-          LineImage[X] := ltTopDown;
-
-        Run := Run.Parent;
-      end;
-    end
-    else
-    begin
-      // Start over parent traversal if necessary.
-      Run := Node;
-
-      if Run.Parent <> FRoot then
-      begin
-        // The very last image (the one immediately before the item label) is different.
-        if HasVisibleNextSibling(Run) then
-          LineImage[X - 1] := ltTopDownRight
-        else
-          LineImage[X - 1] := ltTopRight;
-        Run := Run.Parent;
-
-        // Now go up all parents.
-        repeat
-          if Run.Parent = FRoot then
-            Break;
-          Dec(X);
-          if HasVisibleNextSibling(Run) then
-            LineImage[X - 1] := ltTopDown
-          else
-            LineImage[X - 1] := ltNone;
-          Run := Run.Parent;
-        until False;
-      end;
-
-      // Prepare root level. Run points at this stage to a top level node.
-      if (toShowRoot in FOptions.FPaintOptions) and (toShowTreeLines in FOptions.FPaintOptions) then
-      begin
-        // Is the top node a root node?
-        if Run = Node then
-        begin
-          // First child gets the bottom-right bitmap if it isn't also the only child.
-          if IsFirstVisibleChild(FRoot, Run) then
-            // Is it the only child?
-            if IsLastVisibleChild(FRoot, Run) then
-              LineImage[0] := ltRight
-            else
-              LineImage[0] := ltBottomRight
-          else
-            // real last child
-            if IsLastVisibleChild(FRoot, Run) then
-              LineImage[0] := ltTopRight
-            else
-              LineImage[0] := ltTopDownRight;
-        end
-        else
-        begin
-          // No, top node is not a top level node. So we need different painting.
-          if HasVisibleNextSibling(Run) then
-            LineImage[0] := ltTopDown
-          else
-            LineImage[0] := ltNone;
-        end;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DrawLineImage(const PaintInfo: TVTPaintInfo; X, Y, H, VAlign: Integer; Style: TVTLineType;
-  Reverse: Boolean);
-
-// Draws (depending on Style) one of the 5 line types of the tree.
-// If Reverse is True then a right-to-left column is being drawn, hence horizontal lines must be mirrored.
-// X and Y describe the left upper corner of the line image rectangle, while H denotes its height (and width).
-
-var
-  HalfWidth,
-  TargetX: Integer;
-
-begin
-  HalfWidth := Integer(FIndent) div 2;
-  if Reverse then
-    TargetX := 0
-  else
-    TargetX := FIndent;
-
-  with PaintInfo.Canvas do
-  begin
-    case Style of
-      ltBottomRight:
-        begin
-          DrawDottedVLine(PaintInfo, Y + VAlign, Y + H, X + HalfWidth);
-          DrawDottedHLine(PaintInfo, X + HalfWidth, X + TargetX, Y + VAlign);
-        end;
-      ltTopDown:
-        DrawDottedVLine(PaintInfo, Y, Y + H, X + HalfWidth);
-      ltTopDownRight:
-        begin
-          DrawDottedVLine(PaintInfo, Y, Y + H, X + HalfWidth);
-          DrawDottedHLine(PaintInfo, X + HalfWidth, X + TargetX, Y + VAlign);
-        end;
-      ltRight:
-        DrawDottedHLine(PaintInfo, X + HalfWidth, X + TargetX, Y + VAlign);
-      ltTopRight:
-        begin
-          DrawDottedVLine(PaintInfo, Y, Y + VAlign, X + HalfWidth);
-          DrawDottedHLine(PaintInfo, X + HalfWidth, X + TargetX, Y + VAlign);
-        end;
-      ltLeft: // left can also mean right for RTL context
-        if Reverse then
-          DrawDottedVLine(PaintInfo, Y, Y + H, X + Integer(FIndent))
-        else
-          DrawDottedVLine(PaintInfo, Y, Y + H, X);
-      ltLeftBottom:
-        if Reverse then
-        begin
-          DrawDottedVLine(PaintInfo, Y, Y + H, X + Integer(FIndent));
-          DrawDottedHLine(PaintInfo, X, X + Integer(FIndent), Y + H);
-        end
-        else
-        begin
-          DrawDottedVLine(PaintInfo, Y, Y + H, X);
-          DrawDottedHLine(PaintInfo, X, X + Integer(FIndent), Y + H);
-        end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.FindInPositionCache(Node: PVirtualNode; var CurrentPos: Cardinal): PVirtualNode;
-
-// Looks through the position cache and returns the node whose top position is the largest one which is smaller or equal
-// to the position of the given node.
-
-var
-  L, H, I: Integer;
-
-begin
-  L := 0;
-  H := High(FPositionCache);
-  while L <= H do
-  begin
-    I := (L + H) shr 1;
-    if CompareNodePositions(FPositionCache[I].Node, Node) <= 0 then
-      L := I + 1
-    else
-      H := I - 1;
-  end;
-  if L = 0 then // High(FPositionCache) = -1
-  begin
-    Result := nil;
-    CurrentPos := 0;
-  end
-  else
-  begin
-    Result := FPositionCache[L - 1].Node;
-    CurrentPos := FPositionCache[L - 1].AbsoluteTop;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.FindInPositionCache(Position: Cardinal; var CurrentPos: Cardinal): PVirtualNode;
-
-// Looks through the position cache and returns the node whose top position is the largest one which is smaller or equal
-// to the given vertical position.
-// The returned node does not necessarily occupy the given position but is the nearest one to start
-// iterating from to approach the real node for a given position. CurrentPos receives the actual position of the found
-// node which is needed for further iteration.
-
-var
-  L, H, I: Integer;
-
-begin
-  L := 0;
-  H := High(FPositionCache);
-  while L <= H do
-  begin
-    I := (L + H) shr 1;
-    if FPositionCache[I].AbsoluteTop <= Position then
-      L := I + 1
-    else
-      H := I - 1;
-  end;
-  if L = 0 then // High(FPositionCache) = -1
-  begin
-    Result := nil;
-    CurrentPos := 0;
-  end
-  else
-  begin
-    Result := FPositionCache[L - 1].Node;
-    CurrentPos := FPositionCache[L - 1].AbsoluteTop;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.FixupTotalCount(Node: PVirtualNode);
-
-// Called after loading a subtree from stream. The child count in each node is already set but not
-// their total count.
-
-var
-  Child: PVirtualNode;
-  
-begin
-  // Initial total count is set to one on node creation.
-  Child := Node.FirstChild;
-  while Assigned(Child) do
-  begin
-    FixupTotalCount(Child);
-    Inc(Node.TotalCount, Child.TotalCount);
-    Child := Child.NextSibling;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.FixupTotalHeight(Node: PVirtualNode);
-
-// Called after loading a subtree from stream. The individual height of each node is set already,
-// but their total height needs an adjustment depending on their visibility state.
-
-var
-  Child: PVirtualNode;
-  
-begin
-  // Initial total height is set to the node height on load.
-  Child := Node.FirstChild;
-
-  if vsExpanded in Node.States then
-  begin
-    while Assigned(Child) do
-    begin
-      FixupTotalHeight(Child);
-      if vsVisible in Child.States then
-        Inc(Node.TotalHeight, Child.TotalHeight);
-      Child := Child.NextSibling;
-    end;
-  end
-  else
-  begin
-    // The node is collapsed, so just update the total height of its child nodes.
-    while Assigned(Child) do
-    begin
-      FixupTotalHeight(Child);
-      Child := Child.NextSibling;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetBottomNode: PVirtualNode;
-
-begin
-  Result := InternalGetNodeAt(0, ClientHeight - 1);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetCheckedCount: Integer;
-
-var
-  Node: PVirtualNode;
-
-begin
-  Result := 0;
-  Node := GetFirstChecked;
-  while Assigned(Node) do begin
-     Inc(Result);
-     Node := GetNextChecked(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetCheckState(Node: PVirtualNode): TCheckState;
-
-begin
-  Result := Node.CheckState;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetCheckType(Node: PVirtualNode): TCheckType;
-
-begin
-  Result := Node.CheckType;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetChildCount(Node: PVirtualNode): Cardinal;
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := FRoot.ChildCount
-  else
-    Result := Node.ChildCount;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetChildrenInitialized(Node: PVirtualNode): Boolean;
-
-begin
-  Result := not (vsHasChildren in Node.States) or (Node.ChildCount > 0);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetCutCopyCount: Integer;
-
-var
-  Node: PVirtualNode;
-
-begin
-  Result := 0;
-  Node := GetFirstCutCopy;
-  while Assigned(Node) do begin
-     Inc(Result);
-     Node := GetNextCutCopy(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetDisabled(Node: PVirtualNode): Boolean;
-
-begin
-  Result := Assigned(Node) and (vsDisabled in Node.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetDragManager: IVTDragManager;
-
-// Returns the internal drag manager interface. If this does not yet exist then it is created here.
-
-begin
-  if FDragManager = nil then
-  begin
-    FDragManager := DoCreateDragManager;
-    if FDragManager = nil then
-      FDragManager := TVTDragManager.Create(Self);
-  end;
-
-  Result := FDragManager;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetExpanded(Node: PVirtualNode): Boolean;
-
-begin
-  if Assigned(Node) then
-    Result := vsExpanded in Node.States
-  else
-    Result := False;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFullyVisible(Node: PVirtualNode): Boolean;
-
-// Determines whether the given node has the visibility flag set as well as all its parents are expanded.
-
-begin
-  Assert(Assigned(Node), 'Invalid parameter.');
-  Result := vsVisible in Node.States;
-  if Result and (Node <> FRoot) then
-    Result := VisiblePath[Node];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetHasChildren(Node: PVirtualNode): Boolean;
-
-begin
-  if Assigned(Node) then
-    Result := vsHasChildren in Node.States
-  else
-    Result := vsHasChildren in FRoot.States;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetMultiline(Node: PVirtualNode): Boolean;
-
-begin
-  Result := Assigned(Node) and (Node <> FRoot) and (vsMultiline in Node.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNodeHeight(Node: PVirtualNode): Cardinal;
-
-begin
-  if Assigned(Node) and (Node <> FRoot) then
-  begin
-    if toVariableNodeHeight in FOptions.FMiscOptions then
-    begin
-      if not (vsInitialized in Node.States) then
-        InitNode(Node);
-
-      // Ensure the node's height is determined.
-      MeasureItemHeight(Canvas, Node);
-    end;
-    Result := Node.NodeHeight
-  end
-  else
-    Result := 0;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNodeParent(Node: PVirtualNode): PVirtualNode;
-
-begin
-  if Assigned(Node) and (Node.Parent <> FRoot) then
-    Result := Node.Parent
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetOffsetXY: TPoint;
-
-begin
-  Result := Point(FOffsetX, FOffsetY);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetRootNodeCount: Cardinal;
-
-begin
-  Result := FRoot.ChildCount;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetSelected(Node: PVirtualNode): Boolean;
-
-begin
-  Result := Assigned(Node) and (vsSelected in Node.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetTopNode: PVirtualNode;
-begin
-  Result := InternalGetNodeAt(0, 0);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetTotalCount: Cardinal;
-
-begin
-  Inc(FUpdateCount);
-  try
-    ValidateNode(FRoot, True);
-  finally
-    Dec(FUpdateCount);
-  end;
-  // The root node itself doesn't count as node.
-  Result := FRoot.TotalCount - 1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetVerticalAlignment(Node: PVirtualNode): Byte;
-
-begin
-  Result := Node.Align;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetVisible(Node: PVirtualNode): Boolean;
-
-// Determines if the given node is marked as being visible.
-
-begin
-  if Node = nil then
-    Node := FRoot;
-
-  if not (vsInitialized in Node.States) then
-    InitNode(Node);
-
-  Result := vsVisible in Node.States;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetVisiblePath(Node: PVirtualNode): Boolean;
-
-// Determines if all parents of the given node are expanded and have the visibility flag set.
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameters.');
-
-  // FRoot is always expanded
-  repeat
-    Node := Node.Parent;
-  until (Node = FRoot) or not (vsExpanded in Node.States) or not (vsVisible in Node.States);
-
-  Result := Node = FRoot;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.HandleClickSelection(LastFocused, NewNode: PVirtualNode; Shift: TShiftState;
-  DragPending: Boolean);
-
-// Handles multi-selection with mouse click.
-
-begin
-  // Ctrl key down
-  if ssCtrlOS in Shift then
-  begin
-    if ssShift in Shift then
-    begin
-      SelectNodes(FRangeAnchor, NewNode, True);
-      Invalidate;
-    end
-    else
-    begin
-      if not (toSiblingSelectConstraint in FOptions.SelectionOptions) then
-        FRangeAnchor := NewNode;
-      // Delay selection change if a drag operation is pending.
-      // Otherwise switch selection state here.
-      if DragPending then
-        DoStateChange([tsToggleFocusedSelection])
-      else
-        if vsSelected in NewNode.States then
-          RemoveFromSelection(NewNode)
-        else
-          AddToSelection(NewNode);
-    end;
-  end
-  else
-    // Shift key down
-    if ssShift in Shift then
-    begin
-      if FRangeAnchor = nil then
-        FRangeAnchor := FRoot.FirstChild;
-
-      // select node range
-      if Assigned(FRangeAnchor) then
-      begin
-        SelectNodes(FRangeAnchor, NewNode, False);
-        Invalidate;
-      end;
-    end
-    else
-    begin
-      // any other case
-      if not (vsSelected in NewNode.States) then
-      begin
-        AddToSelection(NewNode);
-        InvalidateNode(NewNode);
-      end;
-      // assign new reference item
-      FRangeAnchor := NewNode;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.HandleDrawSelection(X, Y: Integer): Boolean;
-
-// Handles multi-selection with a focus rectangle.
-// Result is True if something changed in selection.
-
-var
-  OldRect,
-  NewRect: TRect;
-  MainColumn: TColumnIndex;
-  MaxValue: Integer;
-
-  // limits of a node and its text
-  NodeLeft,
-  NodeRight: Integer;
-
-  // alignment and directionality
-  CurrentBidiMode: TBidiMode;
-  CurrentAlignment: TAlignment;
-
-begin
-  Result := False;
-
-  // Selection changes are only done if the user drew a selection rectangle large
-  // enough to exceed the threshold.
-  if (FRoot.TotalCount > 1) and (tsDrawSelecting in FStates) then
-  begin
-    // Effective handling of node selection is done by using two rectangles stored in FSelectRec.
-    OldRect := OrderRect(FLastSelRect);
-    NewRect := OrderRect(FNewSelRect);
-    ClearTempCache;
-
-    MainColumn := FHeader.MainColumn;
-
-    // Alignment and bidi mode determine where the node text is located within a node.
-    if MainColumn <= NoColumn then
-    begin
-      CurrentBidiMode := BidiMode;
-      CurrentAlignment := Alignment;
-    end
-    else
-    begin
-      CurrentBidiMode := FHeader.FColumns[MainColumn].BidiMode;
-      CurrentAlignment := FHeader.FColumns[MainColumn].Alignment;
-    end;
-
-    // Determine initial left border of first node (take column reordering into account).
-    if FHeader.UseColumns then
-    begin
-      // The mouse coordinates don't include any horizontal scrolling hence take this also
-      // out from the returned column position.
-      NodeLeft := FHeader.FColumns[MainColumn].Left - FEffectiveOffsetX;
-      NodeRight := NodeLeft + FHeader.FColumns[MainColumn].Width;
-    end
-    else
-    begin
-      NodeLeft := 0;
-      NodeRight := ClientWidth;
-    end;
-    if CurrentBidiMode = bdLeftToRight then
-      Result := CollectSelectedNodesLTR(MainColumn, NodeLeft, NodeRight, CurrentAlignment, OldRect, NewRect)
-    else
-      Result := CollectSelectedNodesRTL(MainColumn, NodeLeft, NodeRight, CurrentAlignment, OldRect, NewRect);
-  end;
-
-  if Result then
-  begin
-    // Do some housekeeping if there was a change.
-    MaxValue := PackArray(FSelection, FSelectionCount);
-    if MaxValue > -1 then
-    begin
-      FSelectionCount := MaxValue;
-      SetLength(FSelection, FSelectionCount);
-    end;
-    if FTempNodeCount > 0 then
-    begin
-      AddToSelection(FTempNodeCache, FTempNodeCount);
-      ClearTempCache;
-    end;
-
-    Change(nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.HasVisibleNextSibling(Node: PVirtualNode): Boolean;
-
-// Helper method to determine if the given node has a visible next sibling. This is needed to
-// draw correct tree lines.
-
-begin
-  // Check if there is a sibling at all.
-  Result := Assigned(Node.NextSibling);
-
-  if Result then
-  begin
-    repeat
-      Node := Node.NextSibling;
-      Result := vsVisible in Node.States;
-    until Result or (Node.NextSibling = nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.HasVisiblePreviousSibling(Node: PVirtualNode): Boolean;
-
-// Helper method to determine if the given node has a visible previous sibling. This is needed to
-// draw correct tree lines.
-
-begin
-  // Check if there is a sibling at all.
-  Result := Assigned(Node.PrevSibling);
-
-  if Result then
-  begin
-    repeat
-      Node := Node.PrevSibling;
-      Result := vsVisible in Node.States;
-    until Result or (Node.PrevSibling = nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ImageListChange(Sender: TObject);
-
-begin
-  if not (csDestroying in ComponentState) then
-    Invalidate;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InitializeFirstColumnValues(var PaintInfo: TVTPaintInfo);
-
-// Determines initial index, position and cell size of the first visible column.
-
-begin
-  PaintInfo.Column := FHeader.FColumns.GetFirstVisibleColumn;
-  with FHeader.FColumns, PaintInfo do
-  begin
-    if Column > NoColumn then
-    begin
-      CellRect.Right := CellRect.Left + Items[Column].Width;
-      Position := Items[Column].Position;
-    end
-    else
-      Position := 0;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InitRootNode(OldSize: Cardinal = 0);
-
-// Reinitializes the root node.
-
-var
-  NewSize: Cardinal;
-
-begin
-  NewSize := TreeNodeSize + FTotalInternalDataSize;
-  if FRoot = nil then
-    FRoot := AllocMem(NewSize)
-  else
-  begin
-    ReallocMem(FRoot, NewSize);
-    FillChar(PAnsiChar(PAnsiChar(FRoot) + OldSize)^, NewSize - OldSize, 0);
-  end;
-
-  with FRoot^ do
-  begin
-    // Indication that this node is the root node.
-    PrevSibling := FRoot;
-    NextSibling := FRoot;
-    Parent := Pointer(Self);
-    States := [vsInitialized, vsExpanded, vsHasChildren, vsVisible];
-    TotalHeight := FDefaultNodeHeight;
-    TotalCount := 1;
-    TotalHeight := FDefaultNodeHeight;
-    NodeHeight := FDefaultNodeHeight;
-    Align := 50;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InterruptValidation;
-
-var
-  WasValidating: Boolean;
-
-begin
-  DoStateChange([tsStopValidation], [tsUseCache]);
-  {$ifdef EnableThreadSupport}
-  // Check the worker thread existance. It might already be gone (usually on destruction of the last tree).
-  if Assigned(WorkerThread) then
-  begin
-    WasValidating := (tsValidating in FStates);
-    WorkerThread.RemoveTree(Self);
-    if WasValidating then
-      DoStateChange([tsValidationNeeded]);
-  end;
-  {$endif}
-end;
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.IsFirstVisibleChild(Parent, Node: PVirtualNode): Boolean;
-
-// Helper method to check if Node is the same as the first visible child of Parent.
-
-var
-  Run: PVirtualNode;
-
-begin
-  // Find first visible child.
-  Run := Parent.FirstChild;
-  while Assigned(Run) and not (vsVisible in Run.States) do
-    Run := Run.NextSibling;
-
-  Result := Assigned(Run) and (Run = Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.IsLastVisibleChild(Parent, Node: PVirtualNode): Boolean;
-
-// Helper method to check if Node is the same as the last visible child of Parent.
-
-var
-  Run: PVirtualNode;
-
-begin
-  // Find last visible child.
-  Run := Parent.LastChild;
-  while Assigned(Run) and not (vsVisible in Run.States) do
-    Run := Run.PrevSibling;
-
-  Result := Assigned(Run) and (Run = Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.LimitPaintingToArea(Canvas: TCanvas; ClipRect: TRect; VisibleRegion: HRGN = 0);
-
-// Limits further painting onto the given canvas to the given rectangle.
-// VisibleRegion is an optional region which can be used to limit drawing further.
-
-var
-  ClipRegion: HRGN;
-
-begin
-  // Regions expect their coordinates in device coordinates, hence we have to transform the region rectangle.
-  LPtoDP(Canvas.Handle, ClipRect, 2);
-  ClipRegion := CreateRectRgnIndirect(ClipRect);
-  if VisibleRegion <> 0 then
-    CombineRgn(ClipRegion, ClipRegion, VisibleRegion, RGN_AND);
-  SelectClipRgn(Canvas.Handle, ClipRegion);
-  DeleteObject(ClipRegion);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.LoadPanningCursors;
-
-begin
-  with Screen do
-  begin
-    Cursors[crVT_MOVEALL]:=LoadCursorFromLazarusResource('VT_MOVEALL');
-    Cursors[crVT_MOVEEW]:=LoadCursorFromLazarusResource('VT_MOVEEW');
-    Cursors[crVT_MOVENS]:=LoadCursorFromLazarusResource('VT_MOVENS');
-    Cursors[crVT_MOVENW]:=LoadCursorFromLazarusResource('VT_MOVENW');
-    Cursors[crVT_MOVESW]:=LoadCursorFromLazarusResource('VT_MOVESW');
-    Cursors[crVT_MOVESE]:=LoadCursorFromLazarusResource('VT_MOVESE');
-    Cursors[crVT_MOVENE]:=LoadCursorFromLazarusResource('VT_MOVENE');
-    Cursors[crVT_MOVEW]:=LoadCursorFromLazarusResource('VT_MOVEW');
-    Cursors[crVT_MOVEE]:=LoadCursorFromLazarusResource('VT_MOVEE');
-    Cursors[crVT_MOVEN]:=LoadCursorFromLazarusResource('VT_MOVEN');
-    Cursors[crVT_MOVES]:=LoadCursorFromLazarusResource('VT_MOVES');
-  end;
-end;
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.MakeNewNode: PVirtualNode;
-
-var
-  Size: Cardinal;
-
-begin
-  Size := TreeNodeSize;
-  if not (csDesigning in ComponentState) then
-  begin
-    // Make sure FNodeDataSize is valid.
-    if FNodeDataSize = -1 then
-      ValidateNodeDataSize(FNodeDataSize);
-
-    // Take record alignment into account.
-    Inc(Size, FNodeDataSize);
-  end;
-
-  Result := AllocMem(Size + FTotalInternalDataSize);
-
-  // Fill in some default values.
-  with Result^ do
-  begin
-    TotalCount := 1;
-    TotalHeight := FDefaultNodeHeight;
-    NodeHeight := FDefaultNodeHeight;
-    States := [vsVisible];
-    Align := 50;
-  end;
-end;
-
-{$ifdef PACKARRAYPASCAL}
-
-function TBaseVirtualTree.PackArray(const TheArray: TNodeArray; Count: Integer): Integer;
-var
-  Source, Dest: ^PVirtualNode;
-  ConstOne: PtrInt;
-begin
-  Source := Pointer(TheArray);
-  ConstOne := 1;
-  Result := 0;
-  // Do the fastest scan possible to find the first entry
-  while (Count <> 0) and {not Odd(NativeInt(Source^))} (PtrInt(Source^) and ConstOne = 0) do
-  begin
-    Inc(Result);
-    Inc(Source);
-    Dec(Count);
-  end;
-
-  if Count <> 0 then
-  begin
-    Dest := Source;
-    repeat
-      // Skip odd entries
-      if {not Odd(NativeInt(Source^))} PtrInt(Source^) and ConstOne = 0 then
-      begin
-        Dest^ := Source^;
-        Inc(Result);
-        Inc(Dest);
-      end;
-      Inc(Source); // Point to the next entry
-      Dec(Count);
-    until Count = 0;
-  end;
-end;
-
-{$else}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$IMPLICITEXCEPTIONS OFF}
-
-function TBaseVirtualTree.PackArray(TheArray: TNodeArray; Count: Integer): Integer; assembler;
-
-// Removes all entries from the selection array which are no longer in use. The selection array must be sorted for this
-// algo to work. Values which must be removed are marked with bit 0 (LSB) set. This little trick works because memory
-// is always allocated DWORD aligned. Since the selection array must be sorted while determining the entries to be
-// removed it is much more efficient to increment the entry in question instead of setting it to nil (which would break
-// the ordered appearance of the list).
-//
-// On enter EAX contains self reference, EDX the address to TheArray and ECX Count
-// The returned value is the number of remaining entries in the array, so the caller can reallocate (shorten)
-// the selection array if needed or -1 if nothing needs to be changed.
-
-asm
-        PUSH    EBX
-        PUSH    EDI
-        PUSH    ESI
-        MOV     ECX, EDX               //fpc: count is in EDX. Move to ECX
-        MOV     ESI, [EBP+8]           //fpc: TheArray is in EBP+8
-        MOV     EDX, -1
-        JCXZ    @@Finish               // Empty list?
-        INC     EDX                    // init remaining entries counter
-        MOV     EDI, ESI               // source and destination point to the list memory
-        MOV     EBX, 1                 // use a register instead of immediate operant to check against
-@@PreScan:
-        TEST    [ESI], EBX             // do the fastest scan possible to find the first entry
-                                       // which must be removed
-        JNZ     @@DoMainLoop
-        INC     EDX
-        ADD     ESI, 4
-        DEC     ECX
-        JNZ     @@PreScan
-        JMP     @@Finish
-
-@@DoMainLoop:
-        MOV     EDI, ESI
-@@MainLoop:
-        TEST    [ESI], EBX             // odd entry?
-        JNE     @@Skip                 // yes, so skip this one
-        MOVSD                          // else move the entry to new location
-        INC     EDX                    // count the moved entries
-        DEC     ECX
-        JNZ     @@MainLoop             // do it until all entries are processed
-        JMP     @@Finish
-
-@@Skip:
-        ADD     ESI, 4                 // point to the next entry
-        DEC     ECX
-        JNZ     @@MainLoop             // do it until all entries are processed
-@@Finish:
-        MOV     EAX, EDX               // prepare return value
-        POP     ESI
-        POP     EDI
-        POP     EBX
-end;
-
-{$IMPLICITEXCEPTIONS ON}
-
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PrepareBitmaps(NeedButtons, NeedLines: Boolean);
-
-// initializes the contents of the internal bitmaps
-
-const
-  LineBitsDotted: array [0..8] of Word = ($55, $AA, $55, $AA, $55, $AA, $55, $AA, $55);
-  LineBitsSolid: array [0..7] of Word = (0, 0, 0, 0, 0, 0, 0, 0);
-
-var
-  PatternBitmap: HBITMAP;
-  Bits: Pointer;
-  Size: TSize;
-  {$ifdef ThemeSupport}
-    //Theme: HTHEME;
-    R: TRect;
- 
-const
-  TVP_HOTGLYPH = 4;
-    
-  {$endif ThemeSupport}
-
-  //--------------- local function --------------------------------------------
-
-  procedure FillBitmap (ABitmap: TBitmap);
-  begin
-    with ABitmap, Canvas do
-    begin
-      ABitmap.Width := Size.cx;
-      ABitmap.Height := Size.cy;
-
-      {$Ifdef ThemeSupport}
-        if IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) then
-        begin
-          if (FHeader.FMainColumn > NoColumn) and not
-             (coParentColor in FHeader.FColumns[FHeader.FMainColumn].FOptions) then
-            Brush.Color := FHeader.FColumns[FHeader.FMainColumn].Color
-          else
-            Brush.Color := Self.Brush.Color;
-        end
-        else
-        begin
-      {$EndIf ThemeSupport}
-          MaskHandle := 0;
-          Transparent := True;
-          TransparentColor := clFuchsia;
-          Brush.Color := clFuchsia;
-      {$Ifdef ThemeSupport}
-        end;
-      {$EndIf ThemeSupport}
-      
-      FillRect(Rect(0, 0, ABitmap.Width, ABitmap.Height));
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-begin
-  Size.cx := 9;
-  Size.cy := 9;
-
-  {$ifdef ThemeSupport}
-  //todo
-  {
-    if tsUseThemes in FStates then
-    begin
-      Theme := OpenThemeData(Handle, 'TREEVIEW');
-      if IsWinVistaOrAbove and (toUseExplorerTheme in FOptions.FPaintOptions) then
-      begin
-        R := Rect(0, 0, 100, 100);
-        GetThemePartSize(Theme, FPlusBM.Canvas.Handle, TVP_GLYPH, GLPS_OPENED, @R, TS_TRUE, Size);
-      end;
-    end
-    else
-      Theme := 0;
-   }
-  {$endif ThemeSupport}
-
-  if NeedButtons then
-  begin
-    with FMinusBM, Canvas do
-    begin
-      // box is always of odd size
-      FillBitmap(FMinusBM);
-      FillBitmap(FHotMinusBM);
-      if not (IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions)) then
-      begin
-        if FButtonStyle = bsTriangle then
-        begin
-          Brush.Color := clBlack;
-          Pen.Color := clBlack;
-          Polygon([Point(0, 2), Point(8, 2), Point(4, 6)]);
-        end
-        else
-        begin
-          // Button style is rectangular. Now ButtonFillMode determines how to fill the interior.
-          if FButtonFillMode in [fmTreeColor, fmWindowColor, fmTransparent] then
-          begin
-            case FButtonFillMode of
-              fmTreeColor:
-                Brush.Color := Self.Brush.Color;
-              fmWindowColor:
-                Brush.Color := clWindow;
-            end;
-            Pen.Color := FColors.TreeLineColor;
-            Rectangle(0, 0, Width, Height);
-            Pen.Color := Self.Font.Color;
-            MoveTo(2, Width div 2);
-            LineTo(Width - 2 , Width div 2);
-          end
-          else
-            FMinusBM.LoadFromLazarusResource('VT_XPBUTTONMINUS');
-          FHotMinusBM.Canvas.Draw(0, 0, FMinusBM);
-        end;
-      end;
-    end;
-
-    with FPlusBM, Canvas do
-    begin
-      FillBitmap(FPlusBM);
-      FillBitmap(FHotPlusBM);
-      if not (IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions)) then
-      begin
-        if FButtonStyle = bsTriangle then
-        begin
-          Brush.Color := clBlack;
-          Pen.Color := clBlack;
-          Polygon([Point(2, 0), Point(6, 4), Point(2, 8)]);
-        end
-        else
-        begin
-          // Button style is rectangular. Now ButtonFillMode determines how to fill the interior.
-          if FButtonFillMode in [fmTreeColor, fmWindowColor, fmTransparent] then
-          begin
-            case FButtonFillMode of
-              fmTreeColor:
-                Brush.Color := Self.Brush.Color;
-              fmWindowColor:
-                Brush.Color := clWindow;
-            end;
-
-            Pen.Color := FColors.TreeLineColor;
-            Rectangle(0, 0, Width, Height);
-            Pen.Color := Self.Font.Color;
-            MoveTo(2, Width div 2);
-            LineTo(Width - 2 , Width div 2);
-            MoveTo(Width div 2, 2);
-            LineTo(Width div 2, Width - 2);
-          end
-          else
-            FPlusBM.LoadFromLazarusResource('VT_XPBUTTONPLUS');
-          FHotPlusBM.Canvas.Draw(0, 0, FPlusBM);
-        end;
-      end;
-    end;
-
-    {$ifdef ThemeSupport}
-    //todo
-      // Overwrite glyph images if theme is active.
-      {
-      if (tsUseThemes in FStates) and (Theme <> 0) then
-      begin
-        R := Rect(0, 0, Size.cx, Size.cy);
-        DrawThemeBackground(Theme, FPlusBM.Canvas.Handle, TVP_GLYPH, GLPS_CLOSED, R, nil);
-        DrawThemeBackground(Theme, FMinusBM.Canvas.Handle, TVP_GLYPH, GLPS_OPENED, R, nil);
-        if IsWinVistaOrAbove and (toUseExplorerTheme in FOptions.FPaintOptions) then
-        begin
-          DrawThemeBackground(Theme, FHotPlusBM.Canvas.Handle, TVP_HOTGLYPH, GLPS_CLOSED, R, nil);
-          DrawThemeBackground(Theme, FHotMinusBM.Canvas.Handle, TVP_HOTGLYPH, GLPS_OPENED, R, nil);
-        end
-        else
-        begin
-          FHotPlusBM.Canvas.Draw(0, 0, FPlusBM);
-          FHotMinusBM.Canvas.Draw(0, 0, FMinusBM);
-        end;
-      end;
-      }
-    {$endif ThemeSupport}
-  end;
-
-  if NeedLines then
-  begin
-    if FDottedBrush <> 0 then
-      DeleteObject(FDottedBrush);
-
-    case FLineStyle of
-      lsDotted:
-        Bits := @LineBitsDotted;
-      lsSolid:
-        Bits := @LineBitsSolid;
-    else // lsCustomStyle
-      Bits := @LineBitsDotted;
-      DoGetLineStyle(Bits);
-    end;
-    PatternBitmap := CreateBitmap(8, 8, 1, 1, Bits);
-    FDottedBrush := CreatePatternBrush(PatternBitmap);
-    DeleteObject(PatternBitmap);
-  end;
-
-  {$ifdef ThemeSupport}
-  //  if Theme <> 0 then
-  //    CloseThemeData(Theme);
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetAlignment(const Value: TAlignment);
-
-begin
-  if FAlignment <> Value then
-  begin
-    FAlignment := Value;
-    if not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetAnimationDuration(const Value: Cardinal);
-
-begin
-  FAnimationDuration := Value;
-  if FAnimationDuration = 0 then
-    Exclude(FOptions.FAnimationOptions, toAnimatedToggle)
-  else
-    Include(FOptions.FAnimationOptions, toAnimatedToggle);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetBackground(const Value: TPicture);
-
-begin
-  FBackground.Assign(Value);
-  Invalidate;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetBackgroundOffset(const Index, Value: Integer);
-
-begin
-  case Index of
-    0:
-      if FBackgroundOffsetX <> Value then
-      begin
-        FBackgroundOffsetX := Value;
-        Invalidate;
-      end;
-    1:
-      if FBackgroundOffsetY <> Value then
-      begin
-        FBackgroundOffsetY := Value;
-        Invalidate;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-{
-procedure TBaseVirtualTree.SetBorderStyle(Value: TBorderStyle);
-
-begin
-  if FBorderStyle <> Value then
-  begin
-    FBorderStyle := Value;
-    RecreateWnd;
-  end;
-end;
-}
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetBottomNode(Node: PVirtualNode);
-
-var
-  Run: PVirtualNode;
-  R: TRect;
-
-begin
-  if Assigned(Node) then
-  begin
-    // make sure all parents of the node are expanded
-    Run := Node.Parent;
-    while Run <> FRoot do
-    begin
-      if not (vsExpanded in Run.States) then
-        ToggleNode(Run);
-      Run := Run.Parent;
-    end;
-    R := GetDisplayRect(Node, FHeader.MainColumn, True);
-    DoSetOffsetXY(Point(FOffsetX, FOffsetY + ClientHeight - R.Top - Integer(NodeHeight[Node])),
-      [suoRepaintScrollbars, suoUpdateNCArea]);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetBottomSpace(const Value: Cardinal);
-
-begin
-  if FBottomSpace <> Value then
-  begin
-    FBottomSpace := Value;
-    UpdateVerticalScrollbar(True);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetButtonFillMode(const Value: TVTButtonFillMode);
-
-begin
-  if FButtonFillMode <> Value then
-  begin
-    FButtonFillMode := Value;
-    if not (csLoading in ComponentState) then
-    begin
-      PrepareBitmaps(True, False);
-      if HandleAllocated then
-        Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetButtonStyle(const Value: TVTButtonStyle);
-
-begin
-  if FButtonStyle <> Value then
-  begin
-    FButtonStyle := Value;
-    if not (csLoading in ComponentState) then
-    begin
-      PrepareBitmaps(True, False);
-      if HandleAllocated then
-        Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetCheckImageKind(Value: TCheckImageKind);
-
-begin
-  if FCheckImageKind <> Value then
-  begin
-    FCheckImageKind := Value;
-    if toCheckSupport in FOptions.FMiscOptions then
-      UpdateCheckImageList;
-    if HandleAllocated and (FUpdateCount = 0) and not (csLoading in ComponentState) then
-      InvalidateRect(Handle, nil, False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetCheckState(Node: PVirtualNode; Value: TCheckState);
-
-begin
-  if (Node.CheckState <> Value) and not (vsDisabled in Node.States) and DoChecking(Node, Value) then
-    DoCheckClick(Node, Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetCheckType(Node: PVirtualNode; Value: TCheckType);
-
-begin
-  if (Node.CheckType <> Value) and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    Node.CheckType := Value;
-    Node.CheckState := csUncheckedNormal;
-    // For check boxes with tri-state check box parents we have to initialize differently.
-    if (toAutoTriStateTracking in FOptions.FAutoOptions) and (Value in [ctCheckBox, ctTriStateCheckBox]) and
-      (Node.Parent <> FRoot) then
-    begin
-      if not (vsInitialized in Node.Parent.States) then
-        InitNode(Node.Parent);
-      if (Node.Parent.CheckType = ctTriStateCheckBox) and
-        (Node.Parent.CheckState in [csUncheckedNormal, csCheckedNormal]) then
-        CheckState[Node] := Node.Parent.CheckState;
-    end;
-    InvalidateNode(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetChildCount(Node: PVirtualNode; NewChildCount: Cardinal);
-
-// Changes a node's child structure to accomodate the new child count. This is used to add or delete
-// child nodes to/from the end of the node's child list. To insert or delete a specific node a separate
-// routine is used.
-
-var
-  Remaining: Cardinal;
-  Index: Cardinal;
-  Child: PVirtualNode;
-  Count: Integer;
-  NewHeight: Integer;
-
-begin
-  if not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    if Node = nil then
-      Node := FRoot;
-
-    if NewChildCount = 0 then
-      DeleteChildren(Node)
-    else
-    begin
-      // If nothing changed then do nothing.
-      if NewChildCount <> Node.ChildCount then
-      begin
-        InterruptValidation;
-        NewHeight := 0;
-
-        if NewChildCount > Node.ChildCount then
-        begin
-          Remaining := NewChildCount - Node.ChildCount;
-          Count := Remaining;
-          
-          // New nodes to add.
-          if Assigned(Node.LastChild) then
-            Index := Node.LastChild.Index + 1
-          else
-          begin
-            Index := 0;
-            Include(Node.States, vsHasChildren);
-          end;
-          Node.States := Node.States - [vsAllChildrenHidden, vsHeightMeasured];
-
-          // New nodes are by default always visible, so we don't need to check the visibility.
-          while Remaining > 0 do
-          begin
-            Child := MakeNewNode;
-            Child.Index := Index;
-            Child.PrevSibling := Node.LastChild;
-            if Assigned(Node.LastChild) then
-              Node.LastChild.NextSibling := Child;
-            Child.Parent := Node;
-            Node.LastChild := Child;
-            if Node.FirstChild = nil then
-              Node.FirstChild := Child;
-            Dec(Remaining);
-            Inc(Index);
-
-            // The actual node height will later be computed once it is clear
-            // whether this node has a variable node height or not.
-            Inc(NewHeight, Child.NodeHeight);
-          end;
-
-          if vsExpanded in Node.States then
-          begin
-            AdjustTotalHeight(Node, NewHeight, True);
-            if FullyVisible[Node] then
-              Inc(Integer(FVisibleCount), Count);
-          end;
-
-          AdjustTotalCount(Node, Count, True);
-          Node.ChildCount := NewChildCount;
-          if (FUpdateCount = 0) and (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then
-            Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, True);
-
-          InvalidateCache;
-        end
-        else
-        begin
-          // Nodes have to be deleted.
-          Remaining := Node.ChildCount - NewChildCount;
-          while Remaining > 0 do
-          begin
-            DeleteNode(Node.LastChild);
-            Dec(Remaining);
-          end;
-        end;
-
-        if FUpdateCount = 0 then
-        begin
-          ValidateCache;
-          UpdateScrollBars(True);
-          Invalidate;
-        end;
-
-        if Node = FRoot then
-          StructureChange(nil, crChildAdded)
-        else
-          StructureChange(Node, crChildAdded);
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetClipboardFormats(const Value: TClipboardFormats);
-
-var
-  I: Integer;
-
-begin
-  // Add string by string instead doing an Assign or AddStrings because the list may return -1 for
-  // invalid entries which cause trouble for the standard implementation.
-  FClipboardFormats.Clear;
-  for I := 0 to Value.Count - 1 do
-    FClipboardFormats.Add(Value[I]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetColors(const Value: TVTColors);
-
-begin
-  FColors.Assign(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetCustomCheckImages(const Value: TBitmap);
-
-begin
-  if FCustomCheckImages <> Value then
-  begin
-    if Assigned(FCustomCheckImages) then
-    begin
-      // Reset the internal check image list reference too, if necessary.
-      if FCheckImages = FCustomCheckImages then
-        FCheckImages := nil;
-    end;
-    FCustomCheckImages := Value;
-    // Check if currently custom check images are active.
-    if FCheckImageKind = ckCustom then
-      FCheckImages := Value;
-    if not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetDefaultNodeHeight(Value: Cardinal);
-
-begin
-  if Value = 0 then
-    Value := 18;
-  if FDefaultNodeHeight <> Value then
-  begin
-    DoStateChange([tsNeedScale]);
-    Inc(Integer(FRoot.TotalHeight), Integer(Value) - Integer(FDefaultNodeHeight));
-    Inc(SmallInt(FRoot.NodeHeight), Integer(Value) - Integer(FDefaultNodeHeight));
-    FDefaultNodeHeight := Value;
-    InvalidateCache;
-    if (FUpdateCount = 0) and HandleAllocated and not (csLoading in ComponentState) then
-    begin
-      ValidateCache;
-      UpdateScrollBars(True);
-      ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, True);
-      Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetDisabled(Node: PVirtualNode; Value: Boolean);
-
-begin
-  if Assigned(Node) and (Value xor (vsDisabled in Node.States)) then
-  begin
-    if Value then
-      Include(Node.States, vsDisabled)
-    else
-      Exclude(Node.States, vsDisabled);
-
-    if FUpdateCount = 0 then
-      InvalidateNode(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetExpanded(Node: PVirtualNode; Value: Boolean);
-
-begin
-  if Assigned(Node) and (Node <> FRoot) and (Value xor (vsExpanded in Node.States)) then
-    ToggleNode(Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetFocusedColumn(Value: TColumnIndex);
-
-begin
-  if (FFocusedColumn <> Value) and
-     DoFocusChanging(FFocusedNode, FFocusedNode, FFocusedColumn, Value) then
-  begin
-    CancelEditNode;
-    InvalidateColumn(FFocusedColumn);
-    InvalidateColumn(Value);
-    FFocusedColumn := Value;
-    if Assigned(FFocusedNode) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then
-    begin
-      if ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)) then
-        InvalidateNode(FFocusedNode);
-    end;
-
-    if Assigned(FDropTargetNode) then
-      InvalidateNode(FDropTargetNode);
-
-    DoFocusChange(FFocusedNode, FFocusedColumn);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetFocusedNode(Value: PVirtualNode);
-
-var
-  WasDifferent: Boolean;
-
-begin
-  WasDifferent := Value <> FFocusedNode;
-  DoFocusNode(Value, True);
-  // Do change event only if there was actually a change.
-  if WasDifferent and (FFocusedNode = Value) then
-    DoFocusChange(FFocusedNode, FFocusedColumn);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetFullyVisible(Node: PVirtualNode; Value: Boolean);
-
-// This method ensures that a node is visible and all its parent nodes are expanded and also visible
-// if Value is True. Otherwise the visibility flag of the node is reset but the expand state
-// of the parent nodes stays untouched.
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter');
-
-  IsVisible[Node] := Value;
-  if Value then
-  begin
-    repeat
-      Node := Node.Parent;
-      if Node = FRoot then
-        Break;
-      if not (vsExpanded in Node.States) then
-        ToggleNode(Node);
-      if not (vsVisible in Node.States) then
-        IsVisible[Node] := True;
-    until False;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetHasChildren(Node: PVirtualNode; Value: Boolean);
-
-begin
-  if Assigned(Node) and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    if Value then
-      Include(Node.States, vsHasChildren)
-    else
-    begin
-      Exclude(Node.States, vsHasChildren);
-      DeleteChildren(Node);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetHeader(const Value: TVTHeader);
-
-begin
-  FHeader.Assign(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-procedure TBaseVirtualTree.SetImages(const Value: TCustomImageList);
-
-begin
-  if FImages <> Value then
-  begin
-    if Assigned(FImages) then
-    begin
-      FImages.UnRegisterChanges(FImageChangeLink);
-      FImages.RemoveFreeNotification(Self);
-    end;
-    FImages := Value;
-    if Assigned(FImages) then
-    begin
-      FImages.RegisterChanges(FImageChangeLink);
-      FImages.FreeNotification(Self);
-    end;
-    if not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetIndent(Value: Cardinal);
-
-begin
-  if FIndent <> Value then
-  begin
-    FIndent := Value;
-    if not (csLoading in ComponentState) and (FUpdateCount = 0) and HandleAllocated then
-    begin
-      UpdateScrollBars(True);
-      Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetLineMode(const Value: TVTLineMode);
-
-begin
-  if FLineMode <> Value then
-  begin
-    FLineMode := Value;
-    if HandleAllocated and not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetLineStyle(const Value: TVTLineStyle);
-
-begin
-  if FLineStyle <> Value then
-  begin
-    FLineStyle := Value;
-    if not (csLoading in ComponentState) then
-    begin
-      PrepareBitmaps(False, True);
-      if HandleAllocated then
-        Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetMargin(Value: Integer);
-
-begin
-  if FMargin <> Value then
-  begin
-    FMargin := Value;
-    if HandleAllocated and not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetMultiline(Node: PVirtualNode; const Value: Boolean);
-
-begin
-  if Assigned(Node) and (Node <> FRoot) then
-    if Value <> (vsMultiline in Node.States) then
-    begin
-      if Value then
-        Include(Node.States, vsMultiline)
-      else
-        Exclude(Node.States, vsMultiline);
-
-      if FUpdateCount = 0 then
-        InvalidateNode(Node);
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetNodeAlignment(const Value: TVTNodeAlignment);
-
-begin
-  if FNodeAlignment <> Value then
-  begin
-    FNodeAlignment := Value;
-    if HandleAllocated and not (csReading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetNodeDataSize(Value: Integer);
-
-var
-  LastRootCount: Cardinal;
-
-begin
-  if Value < -1 then
-    Value := -1;
-  if FNodeDataSize <> Value then
-  begin
-    FNodeDataSize := Value;
-    if not (csLoading in ComponentState) and not (csDesigning in ComponentState) then
-    begin
-      LastRootCount := FRoot.ChildCount;
-      Clear;
-      SetRootNodeCount(LastRootCount);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetNodeHeight(Node: PVirtualNode; Value: Cardinal);
-
-var
-  Difference: Integer;
-
-begin
-  if Assigned(Node) and (Node <> FRoot) and (Node.NodeHeight <> Value) and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    Difference := Integer(Value) - Integer(Node.NodeHeight);
-    Node.NodeHeight := Value;
-    AdjustTotalHeight(Node, Difference, True);
-
-    // If an edit operation is currently active then update the editors boundaries as well.
-    UpdateEditBounds;
-
-    // Stay away from touching the node cache while it is being validated.
-    if not (tsValidating in FStates) and FullyVisible[Node] then
-    begin
-      InvalidateCache;
-      if FUpdateCount = 0 then
-      begin
-        ValidateCache;
-        InvalidateToBottom(Node);
-        UpdateScrollBars(True);
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetNodeParent(Node: PVirtualNode; const Value: PVirtualNode);
-
-begin
-  if Assigned(Node) and Assigned(Value) and (Node.Parent <> Value) then
-    MoveTo(Node, Value, amAddChildLast, False);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetOffsetX(const Value: Integer);
-
-begin
-  DoSetOffsetXY(Point(Value, FOffsetY), DefaultScrollUpdateFlags);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetOffsetXY(const Value: TPoint);
-
-begin
-  DoSetOffsetXY(Value, DefaultScrollUpdateFlags);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetOffsetY(const Value: Integer);
-
-begin
-  DoSetOffsetXY(Point(FOffsetX, Value), DefaultScrollUpdateFlags);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetOptions(const Value: TCustomVirtualTreeOptions);
-
-begin
-  FOptions.Assign(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetRootNodeCount(Value: Cardinal);
-
-begin
-  // Don't set the root node count until all other properties (in particular the OnInitNode event) have been set.
-  if csLoading in ComponentState then
-  begin
-    FRoot.ChildCount := Value;
-    DoStateChange([tsNeedRootCountUpdate]);
-  end
-  else
-    if FRoot.ChildCount <> Value then
-    begin
-      BeginUpdate;
-      InterruptValidation;
-      SetChildCount(FRoot, Value);
-      EndUpdate;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetScrollBarOptions(Value: TScrollBarOptions);
-
-begin
-  FScrollBarOptions.Assign(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetSearchOption(const Value: TVTIncrementalSearch);
-
-begin
-  if FIncrementalSearch <> Value then
-  begin
-    FIncrementalSearch := Value;
-    if FIncrementalSearch = isNone then
-    begin
-      KillTimer(Handle, SearchTimer);
-      FSearchBuffer := '';
-      FLastSearchNode := nil;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetSelected(Node: PVirtualNode; Value: Boolean);
-
-begin
-  if not FSelectionLocked and Assigned(Node) and (Node <> FRoot) and (Value xor (vsSelected in Node.States)) then
-  begin
-    if Value then
-    begin
-      if FSelectionCount = 0 then
-        FRangeAnchor := Node
-      else
-        if not (toMultiSelect in FOptions.FSelectionOptions) then
-          ClearSelection;
-
-      AddToSelection(Node);
-
-      // Make sure there is a valid column selected (if there are columns at all).
-      if ((FFocusedColumn < 0) or not (coVisible in FHeader.Columns[FFocusedColumn].Options)) and
-        (FHeader.MainColumn > NoColumn) then
-        if ([coVisible, coAllowFocus] *  FHeader.Columns[FHeader.MainColumn].Options = [coVisible, coAllowFocus]) then
-          FFocusedColumn := FHeader.MainColumn
-        else
-          FFocusedColumn := FHeader.Columns.GetFirstVisibleColumn(True);
-      if FRangeAnchor = nil then
-        FRangeAnchor := Node;
-    end
-    else
-    begin
-      RemoveFromSelection(Node);
-      if FSelectionCount = 0 then
-        ResetRangeAnchor;
-    end;
-    if FullyVisible[Node] then
-      InvalidateNode(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetSelectionCurveRadius(const Value: Cardinal);
-
-begin
-  if FSelectionCurveRadius <> Value then
-  begin
-    FSelectionCurveRadius := Value;
-    if HandleAllocated and not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetStateImages(const Value: TCustomImageList);
-
-begin
-  if FStateImages <> Value then
-  begin
-    if Assigned(FStateImages) then
-    begin
-      FStateImages.UnRegisterChanges(FStateChangeLink);
-      FStateImages.RemoveFreeNotification(Self);
-    end;
-    FStateImages := Value;
-    if Assigned(FStateImages) then
-    begin
-      FStateImages.RegisterChanges(FStateChangeLink);
-      FStateImages.FreeNotification(Self);
-    end;
-    if HandleAllocated and not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetTextMargin(Value: Integer);
-
-begin
-  if FTextMargin <> Value then
-  begin
-    FTextMargin := Value;
-    if not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetTopNode(Node: PVirtualNode);
-
-var
-  R: TRect;
-  Run: PVirtualNode;
-
-begin
-  if Assigned(Node) then
-  begin
-    // make sure all parents of the node are expanded
-    Run := Node.Parent;
-    while Run <> FRoot do
-    begin
-      if not (vsExpanded in Run.States) then
-        ToggleNode(Run);
-      Run := Run.Parent;
-    end;
-    R := GetDisplayRect(Node, FHeader.MainColumn, True);
-    //lclheader
-    if hoVisible in FHeader.Options then
-      Dec(R.Top, FHeader.Height);
-    SetOffsetY(FOffsetY - R.Top);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetUpdateState(Updating: Boolean);
-
-begin
-  // The check for visibility is necessary otherwise the tree is automatically shown when
-  // updating is allowed. As this happens internally the VCL does not get notified and
-  // still assumes the control is hidden. This results in weird "cannot focus invisible control" errors.
-  //lcl todo
-  if Visible and HandleAllocated and (FUpdateCount = 0) then
-    SendMessage(Handle, WM_SETREDRAW, Ord(not Updating), 0);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetVerticalAlignment(Node: PVirtualNode; Value: Byte);
-
-begin
-  if Value > 100 then
-    Value := 100;
-  if Node.Align <> Value then
-  begin
-    Node.Align := Value;
-    if FullyVisible[Node] then
-      InvalidateNode(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetVisible(Node: PVirtualNode; Value: Boolean);
-
-// Sets the visibility style of the given node according to Value.
-
-var
-  NeedUpdate: Boolean;
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.');
-
-  if Value <> (vsVisible in Node.States) then
-  begin
-    InterruptValidation;
-    NeedUpdate := False;
-    if Value then
-    begin
-      Include(Node.States, vsVisible);
-      if vsExpanded in Node.Parent.States then
-        AdjustTotalHeight(Node.Parent, Node.TotalHeight, True);
-      if VisiblePath[Node] then
-      begin
-        Inc(FVisibleCount, 1 + CountVisibleChildren(Node));
-        NeedUpdate := True;
-      end;
-
-      // Update the hidden children flag of the parent.
-      // Since this node is now visible we simply have to remove the flag.
-      Exclude(Node.Parent.States, vsAllChildrenHidden);
-    end
-    else
-    begin
-      Exclude(Node.States, vsVisible);
-      if vsExpanded in Node.Parent.States then
-        AdjustTotalHeight(Node.Parent, -Integer(Node.TotalHeight), True);
-      if VisiblePath[Node] then
-      begin
-        Dec(FVisibleCount, 1 + CountVisibleChildren(Node));
-        NeedUpdate := True;
-      end;
-
-      if FUpdateCount = 0 then
-        DetermineHiddenChildrenFlag(Node.Parent)
-      else
-        Include(FStates, tsUpdateHiddenChildrenNeeded)
-    end;
-
-    InvalidateCache;
-    if NeedUpdate and (FUpdateCount = 0) then
-    begin
-      ValidateCache;
-      UpdateScrollBars(True);
-      Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetVisiblePath(Node: PVirtualNode; Value: Boolean);
-
-// If Value is True then all parent nodes of Node are expanded.
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.');
-
-  if Value then
-  begin
-    repeat
-      Node := Node.Parent;
-      if Node = FRoot then
-        Break;
-      if not (vsExpanded in Node.States) then
-        ToggleNode(Node);
-    until False;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.StaticBackground(Source: TBitmap; Target: TCanvas; const Offset: TPoint; const R: TRect);
-
-// Draws the given source graphic so that it stays static in the given rectangle which is relative to the target bitmap.
-// The graphic is aligned so that it always starts at the upper left corner of the target canvas.
-// Offset gives the position of the target window as a possible superordinated surface.
-
-const
-  DST = $00AA0029; // Ternary Raster Operation - Destination unchanged
-
-var
-  PicRect: TRect;
-  AreaRect: TRect;
-  DrawRect: TRect;
-
-begin
-  // clear background
-  Target.Brush.Color := Brush.Color;
-  Target.FillRect(R);
-
-  // Picture rect in relation to client viewscreen.
-  PicRect := Rect(FBackgroundOffsetX, FBackgroundOffsetY, FBackgroundOffsetX + Source.Width, FBackgroundOffsetY + Source.Height);
-
-  // Area to be draw in relation to client viewscreen.
-  AreaRect := Rect(Offset.X + R.Left, Offset.Y + R.Top, Offset.X + R.Right, Offset.Y + R.Bottom);
-
-  // If picture falls in AreaRect, return intersection (DrawRect).
-  if IntersectRect(DrawRect, PicRect, AreaRect) then
-  begin
-    // Draw portion of image which falls in canvas area.
-    if Source.Transparent then
-    begin
-      // Leave transparent area as destination unchanged (DST), copy non-transparent areas to canvas (SRCCOPY).
-      with DrawRect do
-        MaskBlt(Target.Handle, Left - Offset.X, Top - Offset.Y, (Right - Offset.X) - (Left - Offset.X),
-          (Bottom - Offset.Y) - (Top - Offset.Y), Source.Canvas.Handle, Left - PicRect.Left, DrawRect.Top - PicRect.Top,
-          Source.MaskHandle, Left - PicRect.Left, Top - PicRect.Top, MakeROP4(DST, SRCCOPY));
-    end
-    else
-    begin
-      // copy image to destination
-      with DrawRect do
-        BitBlt(Target.Handle, Left - Offset.X, Top - Offset.Y, (Right - Offset.X) - (Left - Offset.X),
-          (Bottom - Offset.Y) - (Top - Offset.Y) + R.Top, Source.Canvas.Handle, Left - PicRect.Left, DrawRect.Top - PicRect.Top,
-          SRCCOPY);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.TileBackground(Source: TBitmap; Target: TCanvas; const Offset: TPoint; R: TRect);
-
-// Draws the given source graphic so that it tiles into the given rectangle which is relative to the target bitmap.
-// The graphic is aligned so that it always starts at the upper left corner of the target canvas.
-// Offset gives the position of the target window in an possible superordinated surface.
-
-var
-  SourceX,
-  SourceY,
-  TargetX,
-
-  DeltaY: Integer;
-
-begin
-  with Target do
-  begin
-    SourceY := (R.Top + Offset.Y + FBackgroundOffsetY) mod Source.Height;
-    // Always wrap the source coordinates into positive range.
-    if SourceY < 0 then
-      SourceY := Source.Height + SourceY;
-
-    // Tile image vertically until target rect is filled.
-    while R.Top < R.Bottom do
-    begin
-      SourceX := (R.Left + Offset.X + FBackgroundOffsetX) mod Source.Width;
-      // always wrap the source coordinates into positive range
-      if SourceX < 0 then
-        SourceX := Source.Width + SourceX;
-
-      TargetX := R.Left;
-      // height of strip to draw
-      DeltaY := Min(R.Bottom - R.Top, Source.Height - SourceY);
-
-      // tile the image horizontally
-      while TargetX < R.Right do
-      begin
-        BitBlt(Handle, TargetX, R.Top, Min(R.Right - TargetX, Source.Width - SourceX), DeltaY,
-          Source.Canvas.Handle, SourceX, SourceY, SRCCOPY);
-        Inc(TargetX, Source.Width - SourceX);
-        SourceX := 0;
-      end;
-      Inc(R.Top, Source.Height - SourceY);
-      SourceY := 0;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ToggleCallback(Step, StepSize: Integer; Data: Pointer): Boolean;
-
-var
-  Column: TColumnIndex;
-  Run: TRect;
-  SecondaryStepSize: Integer;
-
-  //--------------- local functions -------------------------------------------
-
-  procedure EraseLine;
-
-  var
-    LocalBrush: HBRUSH;
-
-  begin
-    with TToggleAnimationData(Data^), FHeader.FColumns do
-    begin
-      // Iterate through all columns and erase background in their local color.
-      // LocalBrush is a brush in the color of the particular column.
-      Column := GetFirstVisibleColumn;
-      while (Column > InvalidColumn) and (Run.Left < ClientWidth) do
-      begin
-        GetColumnBounds(Column, Run.Left, Run.Right);
-        if coParentColor in Items[Column].FOptions then
-          FillRect(DC, Run, Brush)
-        else
-        begin
-          LocalBrush := CreateSolidBrush(ColorToRGB(Items[Column].Color));
-          FillRect(DC, Run, LocalBrush);
-          DeleteObject(LocalBrush);
-        end;
-        Column := GetNextVisibleColumn(Column);
-      end;
-    end;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  procedure DoScrollUp(DC: HDC; Brush: HBRUSH; Area: TRect; Steps: Integer);
-
-begin
-    {$ifndef INCOMPLETE_WINAPI}
-    ScrollDC(DC, 0, -Steps, Area, Area, 0, nil);
-    {$endif}
-
-    if Step = 0 then
-      if not FHeader.UseColumns then
-        FillRect(DC, Rect(Area.Left, Area.Bottom - Steps - 1, Area.Right, Area.Bottom), Brush)
-      else
-      begin
-        Run := Rect(Area.Left, Area.Bottom - Steps - 1, Area.Right, Area.Bottom);
-        EraseLine;
-      end;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  procedure DoScrollDown(DC: HDC; Brush: HBRUSH; Area: TRect; Steps: Integer);
-
-      begin
-      {$ifndef INCOMPLETE_WINAPI}
-      ScrollDC(DC, 0, Steps, Area, Area, 0, nil);
-      {$endif}
-
-        if Step = 0 then
-          if not FHeader.UseColumns then
-        FillRect(DC, Rect(Area.Left, Area.Top, Area.Right, Area.Top + Steps + 1), Brush)
-          else
-          begin
-        Run := Rect(Area.Left, Area.Top, Area.Right, Area.Top + Steps + 1);
-            EraseLine;
-          end;
-      end;
-
-  //--------------- end local functions ---------------------------------------
-
-begin
-  Result := True;
-  if StepSize > 0 then
-  begin
-    SecondaryStepSize := 0;
-    with TToggleAnimationData(Data^) do
-    begin
-      if Mode1 <> tamNoScroll then
-      begin
-        if Mode1 = tamScrollUp then
-          DoScrollUp(DC, Brush, R1, StepSize)
-          else
-          DoScrollDown(DC, Brush, R1, StepSize);
-
-        if (Mode2 <> tamNoScroll) and (ScaleFactor > 0) then
-          begin
-          // As this routine is able to scroll two independent areas at once, the missing StepSize is
-          // computed in that case. To ensure the maximal accuracy the rounding error is accumulated.
-          SecondaryStepSize := Round((StepSize + MissedSteps) * ScaleFactor);
-          MissedSteps := MissedSteps + StepSize * ScaleFactor - SecondaryStepSize;
-      end;
-      end
-      else
-        SecondaryStepSize := StepSize;
-
-      if Mode2 <> tamNoScroll then
-        if Mode2 = tamScrollUp then
-          DoScrollUp(DC, Brush, R2, SecondaryStepSize)
-        else
-          DoScrollDown(DC, Brush, R2, SecondaryStepSize);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CMColorChange(var Message: TLMessage);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'CMColorChange');{$endif}
-  if not (csLoading in ComponentState) then
-  begin
-    PrepareBitmaps(True, False);
-    if HandleAllocated then
-      Invalidate;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'CMColorChange');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CMBiDiModeChanged(var Message: TLMessage);
-
-begin
-  inherited;
-
-  if UseRightToLeftAlignment then
-    FEffectiveOffsetX := Integer(FRangeX) - ClientWidth + FOffsetX
-  else
-    FEffectiveOffsetX := -FOffsetX;
-  if FEffectiveOffsetX < 0 then
-    FEffectiveOffsetX := 0;
-    
-  if toAutoBidiColumnOrdering in FOptions.FAutoOptions then
-    FHeader.FColumns.ReorderColumns(UseRightToLeftAlignment);
-  FHeader.Invalidate(nil);
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FEffectiveOffsetX after CMBidiModeChanged',FEffectiveOffsetX);{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CMDenySubclassing(var Message: TLMessage);
-
-// If a Windows XP Theme Manager component is used in the application it will try to subclass all controls which do not
-// explicitly deny this. Virtual Treeview knows how to handle XP themes so it does not need subclassing.
-
-begin
-  Message.Result := 1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoDragMsg(ADragMessage: TDragMessage; APosition: TPoint;
-  ADragObject: TDragObject; ATarget: TControl; ADocking: Boolean): LRESULT;
-
-var
-  S: TObject;
-  KeyState: LongWord;
-  P: TPoint;
-  Formats: TFormatArray;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DoDragMsg');{$endif}
-  S := ADragObject;
-  Formats := nil;
-
-  // Let the ancestor handle dock operations.
-  if S is TDragDockObject then
-    inherited
-  else
-  begin
-    // We need an extra check for the control drag object as there might be other objects not derived from
-    // this class (e.g. TActionDragObject).
-    if not (tsUserDragObject in FStates) and (S is TDragControlObject) then
-      S := (S as TDragControlObject).Control;
-    case ADragMessage of
-      dmDragEnter, dmDragLeave, dmDragMove:
-        begin
-          if ADragMessage = dmDragEnter then
-            DoStateChange([tsVCLDragging]);
-          if ADragMessage = dmDragLeave then
-            DoStateChange([], [tsVCLDragging]);
-
-          if ADragMessage = dmDragMove then
-            with ScreenToClient(APosition) do
-              DoAutoScroll(X, Y);
-
-          KeyState := 0;
-          // Alt key will be queried by the KeysToShiftState function in DragOver.
-          if GetKeyState(VK_SHIFT) < 0 then
-            KeyState := KeyState or MK_SHIFT;
-          if GetKeyState(VK_CONTROL) < 0 then
-            KeyState := KeyState or MK_CONTROL;
-
-          // Allowed drop effects are simulated for VCL dd.
-          FVCLDragEffect := DROPEFFECT_MOVE or DROPEFFECT_COPY;
-          DragOver(S, KeyState, TDragState(ADragMessage), APosition, FVCLDragEffect);
-          Result := LRESULT(FVCLDragEffect);
-          FLastVCLDragTarget := FDropTargetNode;
-          if (ADragMessage = dmDragLeave) and Assigned(FDropTargetNode) then
-          begin
-            InvalidateNode(FDropTargetNode);
-            FDropTargetNode := nil;
-          end;
-        end;
-      dmDragDrop:
-        begin
-          KeyState := 0;
-          // Alt key will be queried by the KeysToShiftState function in DragOver
-          if GetKeyState(VK_SHIFT) < 0 then
-            KeyState := KeyState or MK_SHIFT;
-          if GetKeyState(VK_CONTROL) < 0 then
-            KeyState := KeyState or MK_CONTROL;
-
-          // allowed drop effects are simulated for VCL dd,
-          // replace target node with cached node from other VCL dd messages
-          if Assigned(FDropTargetNode) then
-            InvalidateNode(FDropTargetNode);
-          FDropTargetNode := FLastVCLDragTarget;
-          P := ScreenToClient(APosition);
-          DoDragDrop(S, nil, Formats, KeysToShiftState(KeyState), P, FVCLDragEffect, FLastDropMode);
-          if Assigned(FDropTargetNode) then
-          begin
-            InvalidateNode(FDropTargetNode);
-            FDropTargetNode := nil;
-          end;
-        end;
-      dmFindTarget:
-        begin
-          Result := LRESULT(ControlAtPos(ScreenToClient(APosition), False));
-          if Result = 0 then
-            Result := LRESULT(Self);
-
-          // This is a reliable place to check whether VCL drag has
-          // really begun.
-          if tsVCLDragPending in FStates then
-            DoStateChange([tsVCLDragging], [tsVCLDragPending, tsEditPending, tsClearPending]);
-        end;
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DoDragMsg');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CMFontChanged(var Message: TLMessage);
-
-var
-  HeaderMessage: TLMessage;
-
-begin
-  inherited;
-
-  if not (csLoading in ComponentState) then
-    PrepareBitmaps(True, False);
-
-  HeaderMessage.Msg := CM_PARENTFONTCHANGED;
-  HeaderMessage.WParam := 0;
-  HeaderMessage.LParam := 0;
-  HeaderMessage.Result := 0;
-  FHeader.HandleMessage(HeaderMessage);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CMHintShow(var Message: TCMHintShow);
-
-// Determines hint message (tooltip) and out-of-hint rect.
-// Note: A special handling is needed here because we cannot pass wide strings back to the caller.
-//       I had to introduce the hint data record anyway so we can use this to pass the hint string.
-//       We still need to set a dummy hint string in the message to make the VCL showing the hint window.
-
-var
-  NodeRect: TRect;
-  SpanColumn,
-  Dummy,
-  ColLeft,
-  ColRight: Integer;
-  HitInfo: THitInfo;
-  ShowOwnHint: Boolean;
-  IsFocusedOrEditing: Boolean;
-  ParentForm: TCustomForm;
-  BottomRightCellContentMargin: TPoint;
-  LineBreakStyle: TVTTooltipLineBreakStyle;
-begin
-  with Message do
-  begin
-    Result := 1;
-
-    if PtInRect(FLastHintRect, HintInfo.CursorPos) then
-      Exit;
-
-    // Determine node for which to show hint/tooltip.
-    with HintInfo^ do
-      GetHitTestInfoAt(CursorPos.X, CursorPos.Y, True, HitInfo);
-
-    // Make sure a hint is only shown if the tree or at least its parent form is active.
-    // Active editing is ok too as long as we don't want the hint for the current edit node.
-    if IsEditing then
-      IsFocusedOrEditing := HitInfo.HitNode <> FFocusedNode
-    else
-    begin
-      IsFocusedOrEditing := Focused;
-      ParentForm := GetParentForm(Self);
-      if Assigned(ParentForm) then
-        IsFocusedOrEditing := ParentForm.Focused or Application.Active;
-    end;
-
-    if (GetCapture = 0) and ShowHint and not (Dragging or IsMouseSelecting) and ([tsScrolling] * FStates = []) and
-      (FHeader.States = []) and IsFocusedOrEditing then
-    begin
-      with HintInfo^ do
-      begin
-        Result := 0;
-        ShowOwnHint := False;
-
-        // First check whether there is a header hint to show.
-        if FHeader.UseColumns and (hoShowHint in FHeader.FOptions) and FHeader.InHeader(CursorPos) then
-        begin
-          CursorRect := FHeaderRect;
-          // Convert the cursor rectangle into real client coordinates.
-          OffsetRect(CursorRect, 0, -Integer(FHeader.FHeight));
-          HitInfo.HitColumn := FHeader.FColumns.GetColumnAndBounds(CursorPos, CursorRect.Left, CursorRect.Right);
-          // align the vertical hint position on the bottom bound of the header, but
-          // avoid overlapping of mouse cursor and hint
-          HintPos.Y := Max(HintPos.Y, ClientToScreen(Point(0, CursorRect.Bottom)).Y);
-          // Note: the test for the left mouse button in ControlState might cause problems whenever the VCL does not
-          //       realize when the button is released. This, for instance, happens when doing OLE drag'n drop and
-          //       cancel this with ESC.
-          if (HitInfo.HitColumn > -1) and not (csLButtonDown in ControlState) then
-          begin
-            FHintData.DefaultHint := FHeader.FColumns[HitInfo.HitColumn].FHint;
-            if FHintData.DefaultHint <> '' then
-              ShowOwnHint := True
-            else
-              Result := 1;
-          end
-          else
-            Result := 1;
-        end
-        else
-        begin
-          // Default mode is handled as would the tree be a usual VCL control (no own hint window necessary).
-          if FHintMode = hmDefault then
-            HintStr := GetShortHint(Hint)
-          else
-          begin
-            if Assigned(HitInfo.HitNode) and (HitInfo.HitColumn > InvalidColumn) then
-            begin
-              // A draw tree should only display a hint when at least its OnGetHintSize
-              // event handler is assigned.
-              if Self is TCustomVirtualDrawTree then
-              begin
-                FHintData.HintRect := Rect(0, 0, 0, 0);
-                with Self as TCustomVirtualDrawTree do
-                  DoGetHintSize(HitInfo.HitNode, HitInfo.HitColumn, FHintData.HintRect);
-                ShowOwnHint := not IsRectEmpty(FHintData.HintRect);
-              end
-              else
-                // For string trees a decision about showing the hint or not is based
-                // on the hint string (if it is empty then no hint is shown).
-                ShowOwnHint := True;
-
-              if ShowOwnHint then
-              begin
-                if HitInfo.HitColumn > NoColumn then
-                begin
-                  FHeader.FColumns.GetColumnBounds(HitInfo.HitColumn, ColLeft, ColRight);
-                  // The right column border might be extended if column spanning is enabled.
-                  if toAutoSpanColumns in FOptions.FAutoOptions then
-                  begin
-                    SpanColumn := HitInfo.HitColumn;
-                    repeat
-                      Dummy := FHeader.FColumns.GetNextVisibleColumn(SpanColumn);
-                      if (Dummy = InvalidColumn) or not ColumnIsEmpty(HitInfo.HitNode, Dummy) then
-                        Break;
-                      SpanColumn := Dummy;
-                    until False;
-                    if SpanColumn <> HitInfo.HitColumn then
-                      FHeader.FColumns.GetColumnBounds(SpanColumn, Dummy, ColRight);
-                  end;
-                end
-                else
-                begin
-                  ColLeft := 0;
-                  ColRight := ClientWidth;
-                end;
-
-                FHintData.DefaultHint :=  '';
-                if FHintMode <> hmTooltip then
-                begin
-                  // Node specific hint text.
-                  CursorRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, False);
-                  CursorRect.Left := ColLeft;
-                  CursorRect.Right := ColRight;
-                  // Align the vertical hint position on the bottom bound of the node, but
-                  // avoid overlapping of mouse cursor and hint.
-                  HintPos.Y := Max(HintPos.Y, ClientToScreen(CursorRect.BottomRight).Y) + 2;
-                end
-                else
-                begin
-                  // Tool tip to show. This means the full caption of the node must be displayed.
-                  if vsMultiline in HitInfo.HitNode.States then
-                  begin
-                    if hiOnItemLabel in HitInfo.HitPositions then
-                    begin
-                      ShowOwnHint := True;
-                      NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, True, False);
-                    end;
-                  end
-                  else
-                  begin
-                    NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, True, True, True);
-                    BottomRightCellContentMargin := DoGetCellContentMargin(HitInfo.HitNode, HitInfo.HitColumn, ccmtBottomRightOnly);
-
-                    ShowOwnHint := (HitInfo.HitColumn > InvalidColumn) and PtInRect(NodeRect, CursorPos) and
-                      (CursorPos.X <= ColRight) and (CursorPos.X >= ColLeft) and
-                      (
-                        // Show hint also if the node text is partially out of the client area.
-                        // "ColRight - 1", since the right column border is not part of this cell.
-                        ( (NodeRect.Right + BottomRightCellContentMargin.X) > Min(ColRight - 1, ClientWidth) ) or
-                        (NodeRect.Left < Max(ColLeft, 0)) or
-                        ( (NodeRect.Bottom + BottomRightCellContentMargin.Y) > ClientHeight ) or
-                        (NodeRect.Top < 0)
-                      );
-                  end;
-
-                  if ShowOwnHint then
-                  begin
-                    // Node specific hint text given will be retrieved when needed.
-                    FHintData.DefaultHint := '';
-                    HintPos := ClientToScreen(Point(NodeRect.Left, NodeRect.Top));
-                    CursorRect := NodeRect;
-                  end
-                  else
-                    // nothing to show
-                    Result := 1;
-                end;
-              end
-              else
-                Result := 1; // Avoid hint if this is a draw tree returning an empty hint rectangle.
-            end
-            else
-            begin
-              // No node so fall back to control's hint (if indicated) or show nothing.
-              if FHintMode = hmHintAndDefault then
-                HintStr := GetShortHint(Hint)
-              else
-                Result := 1;
-            end;
-          end;
-        end;
-
-        {$ifdef DEBUG_VTV}Logger.Send([lcHint], 'ShowOwnHint: %s Result: %d', [BoolToStr(ShowOwnHint, True), Result]);{$endif}
-        {$ifdef DEBUG_VTV}Logger.Send([lcHint], 'CursorRect', CursorRect);{$endif}
-        {$ifdef DEBUG_VTV}Logger.Send([lcHint], 'CursorPos', CursorPos);{$endif}
-        {$ifdef DEBUG_VTV}Logger.Send([lcHint], 'HintMaxWidth', HintMaxWidth);{$endif}
-        // If hint must be show and is not the control's hint then get the hint
-        // from the node or from the DefaultHint
-        if ShowOwnHint and (Result = 0) then
-        begin
-          LineBreakStyle := hlbDefault;
-          FLastHintRect := CursorRect;
-          if Length(FHintData.DefaultHint) > 0 then
-            HintStr := FHintData.DefaultHint
-          else
-            if FHintMode = hmToolTip then
-              HintStr := DoGetNodeToolTip(HitInfo.HitNode, HitInfo.HitColumn, LineBreakStyle)
-            else
-              HintStr := DoGetNodeHint(HitInfo.HitNode, HitInfo.HitColumn, LineBreakStyle);
-          // Determine actual line break style depending on what was returned by the methods and what's in the node.
-          if (LineBreakStyle = hlbDefault) and Assigned(HitInfo.HitNode)
-            and (vsMultiline in HitInfo.HitNode.States) then
-            LineBreakStyle := hlbForceMultiLine;
-          if LineBreakStyle = hlbForceMultiLine then
-          begin
-            // NodeRect is already calculated for ToolTip
-            if FHintMode <> hmTooltip then
-              NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, True, False);
-            HintMaxWidth := NodeRect.Right - NodeRect.Left;
-          end;
-
-          HintWindowClass := GetHintWindowClass;
-          FHintData.Tree := Self;
-          FHintData.Column := HitInfo.HitColumn;
-          FHintData.Node := HitInfo.HitNode;
-          FHintData.HintInfo := HintInfo;
-          HintData := @FHintData;
-        end
-        else
-          FLastHintRect := Rect(0, 0, 0, 0);
-      end;
-
-      // Remind that a hint is about to show.
-      if Result = 0 then
-        DoStateChange([tsHint])
-      else
-        DoStateChange([], [tsHint]);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CMMouseLeave(var Message: TLMessage);
-
-var
-  LeaveStates: TVirtualTreeStates;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'CMMouseLeave');{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send([lcMessages],'FCurrentHotNode',hexStr(FCurrentHotNode));{$endif}
-  // Reset the last used hint rectangle in case the mouse enters the window within the bounds
-  if Assigned(FHintData.Tree) then
-    FHintData.Tree.FLastHintRect := Rect(0, 0, 0, 0);
-
-  LeaveStates := [tsHint];
-  if [tsWheelPanning, tsWheelScrolling] * FStates = [] then
-  begin
-    if HandleAllocated then
-      KillTimer(Handle, ScrollTimer);
-    LeaveStates := LeaveStates + [tsScrollPending, tsScrolling];
-  end;
-  DoStateChange([], LeaveStates);
-  if Assigned(FCurrentHotNode) then
-  begin
-    DoHotChange(FCurrentHotNode, nil);
-    if (toHotTrack in FOptions.PaintOptions) or (toCheckSupport in FOptions.FMiscOptions) then
-      InvalidateNode(FCurrentHotNode);
-    FCurrentHotNode := nil;
-  end;
-
-  Header.FColumns.FDownIndex := NoColumn;
-  Header.FColumns.FHoverIndex := NoColumn;
-
-  inherited CMMouseLeave(Message);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'CMMouseLeave');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CMMouseWheel(var Message: TLMMouseEvent);
-
-var
-  ScrollAmount: Integer;
-  ScrollLines: DWORD;
-  RTLFactor: Integer;
-  WheelFactor: Double;
-
-begin
-  //todo: rename to WM*
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcScroll],'CMMouseWheel');{$endif}
-  StopWheelPanning;
-
-  inherited WMMouseWheel(Message);
-
-  if Message.Result = 0  then
-  begin
-    with Message do
-    begin
-      Result := 1;
-      WheelFactor := WheelDelta / WHEEL_DELTA;
-      if (FRangeY > Cardinal(ClientHeight)) and (not (ssShift in State)) then
-      begin
-        {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'Scroll Vertical - WheelDelta', WheelDelta);{$endif}
-        // Scroll vertically if there's something to scroll...
-        if ssCtrlOS in State then
-          ScrollAmount := Trunc(WheelFactor * ClientHeight)
-        else
-        begin
-          SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, @ScrollLines, 0);
-          if ScrollLines = WHEEL_PAGESCROLL then
-            ScrollAmount := Integer(Trunc(WheelFactor * ClientHeight))
-          else
-            ScrollAmount := Integer(Trunc(WheelFactor * ScrollLines * FDefaultNodeHeight));
-        end;
-        SetOffsetY(FOffsetY + ScrollAmount);
-      end
-      else
-      begin
-        // ...else scroll horizontally if there's something to scroll.
-        if UseRightToLeftAlignment then
-          RTLFactor := -1
-        else
-          RTLFactor := 1;
-
-        if ssCtrlOS in State then
-          ScrollAmount := Trunc(WheelFactor * (ClientWidth - FHeader.Columns.GetVisibleFixedWidth))
-        else
-        begin
-          SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, @ScrollLines, 0);
-          ScrollAmount := Trunc(WheelFactor * ScrollLines * FHeader.Columns.GetScrollWidth);
-        end;
-        SetOffsetX(FOffsetX + RTLFactor * ScrollAmount);
-      end;
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcScroll],'CMMouseWheel');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$ifdef EnableNativeTVM}
-
-procedure TBaseVirtualTree.TVMGetItem(var Message: TLMessage);
-
-// Screen reader support function. The method returns information about a particular node.
-
-const
-  StateMask = TVIS_STATEIMAGEMASK or TVIS_OVERLAYMASK or TVIS_EXPANDED or TVIS_DROPHILITED or TVIS_CUT or
-    TVIS_SELECTED or TVIS_FOCUSED;
-
-var
-  Item: PTVItemEx;
-  Node: PVirtualNode;
-  Ghosted: Boolean;
-  ImageIndex: Integer;
-  R: TRect;
-  Text: String;
-  {$ifndef UNICODE}
-    ANSIText: ANSIString;
-  {$endif}
-
-begin
-  // We can only return valid data if a nodes reference is given.
-  Item := Pointer(Message.LParam);
-  Message.Result := Ord(((Item.mask and TVIF_HANDLE) <> 0) and Assigned(Item.hItem));
-  if Message.Result = 1 then
-  begin
-    Node := Pointer(Item.hItem);
-    // Child count requested?
-    if (Item.mask and TVIF_CHILDREN) <> 0 then
-      Item.cChildren := Node.ChildCount;
-    // Index for normal image requested?
-    if (Item.mask and TVIF_IMAGE) <> 0 then
-    begin
-      Item.iImage := -1;
-      DoGetImageIndex(Node, ikNormal, -1, Ghosted, Item.iImage);
-    end;
-    // Index for selected image requested?
-    if (Item.mask and TVIF_SELECTEDIMAGE) <> 0 then
-    begin
-      Item.iSelectedImage := -1;
-      DoGetImageIndex(Node, ikSelected, -1, Ghosted, Item.iSelectedImage);
-    end;
-    // State info requested?
-    if (Item.mask and TVIF_STATE) <> 0 then
-    begin
-      // Everything, which is possible is returned.
-      Item.stateMask := StateMask;
-      Item.state := 0;
-      if Node = FFocusedNode then
-        Item.state := Item.state or TVIS_FOCUSED;
-      if vsSelected in Node.States then
-        Item.state := Item.state or TVIS_SELECTED;
-      if vsCutOrCopy in Node.States then
-        Item.state := Item.state or TVIS_CUT;
-      if Node = FDropTargetNode then
-        Item.state := Item.state or TVIS_DROPHILITED;
-      if vsExpanded in Node.States then
-        Item.state := Item.state or TVIS_EXPANDED;
-
-      // Construct state image and overlay image indices. They are one based, btw.
-      // and zero means there is no image.
-      ImageIndex := -1;
-      DoGetImageIndex(Node, ikState, -1, Ghosted, ImageIndex);
-      Item.state := Item.state or Byte(IndexToStateImageMask(ImageIndex + 1));
-      ImageIndex := -1;
-      DoGetImageIndex(Node, ikOverlay, -1, Ghosted, ImageIndex);
-      Item.state := Item.state or Byte(IndexToOverlayMask(ImageIndex + 1));
-    end;
-    // Node caption requested?
-    if (Item.mask and TVIF_TEXT) <> 0 then
-    begin
-      GetTextInfo(Node, -1, Font, R, Text);
-
-      {$ifdef UNICODE}
-        StrLCopy(Item.pszText, PChar(Text), Item.cchTextMax - 1);
-        Item.pszText[Length(Text)] := #0;
-      {$else}
-        // Convert the Unicode implicitely to ANSI using the current locale.
-        ANSIText := Text;
-        StrLCopy(Item.pszText, PChar(ANSIText), Item.cchTextMax - 1);
-        Item.pszText[Length(ANSIText)] := #0;
-      {$endif}
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.TVMGetItemRect(var Message: TLMessage);
-
-// Screen read support function. This method returns a node's display rectangle.
-
-var
-  TextOnly: Boolean;
-  Node: PVirtualNode;
-
-begin
-  // The lparam member is used two-way. On enter it contains a pointer to the item (node).
-  // On exit it is to be considered as pointer to a rectangle structure.
-  Node := Pointer(Pointer(Message.LParam)^);
-  Message.Result := Ord(IsVisible[Node]);
-  if Message.Result <> 0 then
-  begin
-    TextOnly := Message.WParam <> 0;
-    PRect(Message.LParam)^ := GetDisplayRect(Node, -1, TextOnly);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.TVMGetNextItem(var Message: TLMessage);
-
-// Screen read support function. This method returns a node depending on the requested case.
-
-var
-  Node: PVirtualNode;
-
-begin
-  // Start with a nil result.
-  Message.Result := 0;
-  Node := Pointer(Message.LParam);
-  case Message.WParam of
-    TVGN_CARET:
-      Message.Result := Integer(FFocusedNode);
-    TVGN_CHILD:
-      if Assigned(Node) then
-        Message.Result := Integer(GetFirstChild(Node));
-    TVGN_DROPHILITE:
-      Message.Result := Integer(FDropTargetNode);
-    TVGN_FIRSTVISIBLE:
-      Message.Result := Integer(GetFirstVisible(nil, True));
-    TVGN_LASTVISIBLE:
-      Message.Result := Integer(GetLastVisible(nil, True));
-    TVGN_NEXT:
-      if Assigned(Node) then
-        Message.Result := Integer(GetNextSibling(Node));
-    TVGN_NEXTVISIBLE:
-      if Assigned(Node) then
-        Message.Result := Integer(GetNextVisible(Node, True));
-    TVGN_PARENT:
-      if Assigned(Node) and (Node <> FRoot) and (Node.Parent <> FRoot) then
-        Message.Result := Integer(Node.Parent);
-    TVGN_PREVIOUS:
-      if Assigned(Node) then
-        Message.Result := Integer(GetPreviousSibling(Node));
-    TVGN_PREVIOUSVISIBLE:
-      if Assigned(Node) then
-        Message.Result := Integer(GetPreviousVisible(Node, True));
-    TVGN_ROOT:
-      Message.Result := Integer(GetFirst);
-  end;
-end;
-
-{$endif}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMCancelMode(var Message: TLMNoParams);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMCancelMode');{$endif}
-  // Clear any transient state.
-  KillTimer(Handle, ExpandTimer);
-  KillTimer(Handle, EditTimer);
-  KillTimer(Handle, ScrollTimer);
-  KillTimer(Handle, SearchTimer);
-  FSearchBuffer := '';
-  FLastSearchNode := nil;
-
-  DoStateChange([], [tsClearPending, tsEditPending, tsOLEDragPending, tsVCLDragPending, tsDrawSelecting,
-    tsDrawSelPending, tsIncrementalSearching]);
-  //lcl does not has a inherited procedure
-  //inherited WMCancelMode(Message);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMCancelMode');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMChangeState(var Message: TLMessage);
-
-var
-  EnterStates,
-  LeaveStates: TVirtualTreeStates;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMChangeState');{$endif}
-  EnterStates := [];
-  if csStopValidation in TChangeStates(Byte(Message.WParam)) then
-    Include(EnterStates, tsStopValidation);
-  if csUseCache in TChangeStates(Byte(Message.WParam)) then
-    Include(EnterStates, tsUseCache);
-  if csValidating in TChangeStates(Byte(Message.WParam)) then
-    Include(EnterStates, tsValidating);
-  if csValidationNeeded in TChangeStates(Byte(Message.WParam)) then
-    Include(EnterStates, tsValidationNeeded);
-
-  LeaveStates := [];
-  if csStopValidation in TChangeStates(Byte(Message.LParam)) then
-    Include(LeaveStates, tsStopValidation);
-  if csUseCache in TChangeStates(Byte(Message.LParam)) then
-    Include(LeaveStates, tsUseCache);
-  if csValidating in TChangeStates(Byte(Message.LParam)) then
-    Include(LeaveStates, tsValidating);
-  if csValidationNeeded in TChangeStates(Byte(Message.LParam)) then
-    Include(LeaveStates, tsValidationNeeded);
-
-  DoStateChange(EnterStates, LeaveStates);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMChangeState');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMChar(var Message: TLMChar);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMChar');{$endif}
-  if tsIncrementalSearchPending in FStates then
-  begin
-    HandleIncrementalSearch(Message.CharCode);
-    DoStateChange([], [tsIncrementalSearchPending]);
-  end;
-
-  inherited WMChar(Message);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMChar');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMContextMenu(var Message: TLMContextMenu);
-
-// This method is called when a popup menu is about to be displayed.
-// We have to cancel some pending states here to avoid interferences.
-//lcl: handle mouse up here because MouseUp is not called when popup is show
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMContextMenu');{$endif}
-  DoStateChange([], [tsClearPending, tsEditPending, tsOLEDragPending, tsVCLDragPending]);
-  {$ifdef ContextMenuBeforeMouseUp}
-  if Assigned(PopupMenu) then
-  begin
-    if FHeader.FStates = [] then
-    begin
-      Application.CancelHint;
-      if IsMouseSelecting then
-      begin
-        // Reset selection state already here, before the inherited handler opens the default menu.
-        DoStateChange([], [tsDrawSelecting, tsDrawSelPending]);
-        Invalidate;
-      end;
-      inherited WMContextMenu(Message);
-      if (toRightClickSelect in FOptions.FSelectionOptions) then
-      begin
-        // get information about the hit
-        GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-        HandleMouseUp(0, HitInfo);
-      end;
-    end;
-  end
-  else
-    inherited WMContextMenu(Message);
-  {$else}
-  if not (tsPopupMenuShown in FStates) then
-    inherited WMContextMenu(Message);
-  {$endif}
-
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMContextMenu');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMCopy(var Message: TLMNoParams);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMCopy');{$endif}
-  CopyToClipboard;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMCopy');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMCut(var Message: TLMNoParams);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMCut');{$endif}
-  CutToClipboard;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMCut');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMEnable(var Message: TLMNoParams);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMEnable');{$endif}
-  //LCL does not has inherited WMEnable
-  //inherited WMEnable(Message);
-  RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_NOERASE or RDW_NOCHILDREN);
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMEnable');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMEraseBkgnd(var Message: TLMEraseBkgnd);
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcEraseBkgnd],'WMEraseBkgnd');{$endif}
-  Message.Result := 1;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcEraseBkgnd],'WMEraseBkgnd');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMGetDlgCode(var Message: TLMNoParams);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.Send([lcMessages],'WMGetDlgCode');{$endif}
-  Message.Result := DLGC_WANTCHARS or DLGC_WANTARROWS;
-  if FWantTabs then
-    Message.Result := Message.Result or DLGC_WANTTAB;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$ifdef EnableAccessible}
-procedure TBaseVirtualTree.WMGetObject(var Message: TLMessage);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMGetObject');{$endif}
-  if GetAccessibilityFactory <> nil then
-  begin
-    // Create the IAccessibles for the tree view and tree view items, if necessary.
-    if FAccessible = nil then
-      FAccessible := GetAccessibilityFactory.CreateIAccessible(Self);
-    if FAccessibleItem = nil then
-      FAccessibleItem := GetAccessibilityFactory.CreateIAccessible(Self);
-  if Cardinal(Message.LParam) = OBJID_CLIENT then
-    if Assigned(Accessible) then
-      Message.Result := LresultFromObject(IID_IAccessible, Message.WParam, FAccessible)
-    else
-      Message.Result := 0;
-
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMGetObject');{$endif}
-end;
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMHScroll(var Message: TLMHScroll);
-
-  //--------------- local functions -------------------------------------------
-
-  function GetRealScrollPosition: Integer;
-
-  var
-    SI: TScrollInfo;
-    Code: Integer;
-
-  begin
-    SI.cbSize := SizeOf(TScrollInfo);
-    SI.fMask := SIF_TRACKPOS;
-    Code := SB_HORZ;
-    {$ifdef UseFlatScrollbars}
-      FlatSB_GetScrollInfo(Handle, Code, SI);
-    {$else}
-      GetScrollInfo(Handle, Code, SI);
-    {$endif UseFlatScrollbars}
-    Result := SI.nTrackPos;
-  end;
-
-  //--------------- end local functions ---------------------------------------
-
-var
-  RTLFactor: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMHScroll');{$endif}
-  if UseRightToLeftAlignment then
-    RTLFactor := -1
-  else
-    RTLFactor := 1;
-    
-  case Message.ScrollCode of
-    SB_BOTTOM:
-      SetOffsetX(-Integer(FRangeX));
-    SB_ENDSCROLL:
-      begin
-        DoStateChange([], [tsThumbTracking]);
-        // avoiding to adjust the vertical scroll position while tracking makes it much smoother
-        // but we need to adjust the final position here then
-        UpdateHorizontalScrollBar(False);
-      end;
-    SB_LINELEFT:
-      SetOffsetX(FOffsetX + RTLFactor * FScrollBarOptions.FIncrementX);
-    SB_LINERIGHT:
-      SetOffsetX(FOffsetX - RTLFactor * FScrollBarOptions.FIncrementX);
-    SB_PAGELEFT:
-      SetOffsetX(FOffsetX + RTLFactor * (ClientWidth - FHeader.Columns.GetVisibleFixedWidth));
-    SB_PAGERIGHT:
-      SetOffsetX(FOffsetX - RTLFactor * (ClientWidth - FHeader.Columns.GetVisibleFixedWidth));
-    SB_THUMBPOSITION,
-    SB_THUMBTRACK:
-      begin
-        DoStateChange([tsThumbTracking]);
-        {$if DEFINED(LCLQt) OR DEFINED(LCLCarbon)}
-        if UseRightToLeftAlignment then
-          SetOffsetX(-Integer(FRangeX) + ClientWidth + Message.Pos)
-        else
-          SetOffsetX(-Message.Pos);
-        {$else}
-        if UseRightToLeftAlignment then
-          SetOffsetX(-Integer(FRangeX) + ClientWidth + GetRealScrollPosition)
-        else
-          SetOffsetX(-GetRealScrollPosition);
-        {$endif}
-      end;
-    SB_TOP:
-      SetOffsetX(0);
-  end;
-
-  Message.Result := 0;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMHScroll');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMKeyDown(var Message: TLMKeyDown);
-
-// Keyboard event handling for node focus, selection, node specific popup menus and help invokation.
-// For a detailed description of every action done here read the help.
-
-var
-  Shift: TShiftState;
-  Node, Temp,
-  LastFocused: PVirtualNode;
-  Offset: Integer;
-  ClearPending,
-  NeedInvalidate,
-  DoRangeSelect,
-  HandleMultiSelect: Boolean;
-  Context: Integer;
-  ParentControl: TWinControl;
-  R: TRect;
-  NewCheckState: TCheckState;
-  TempColumn,
-  NewColumn: TColumnIndex;
-  ActAsGrid: Boolean;
-  ForceSelection: Boolean;
-  NewWidth,
-  NewHeight: Integer;
-  RTLFactor: Integer;
-
-  // for tabulator handling
-  GetStartColumn: function(ConsiderAllowFocus: Boolean = False): TColumnIndex of object;
-  GetNextColumn: function(Column: TColumnIndex; ConsiderAllowFocus: Boolean = False): TColumnIndex of object;
-  GetNextNode: TGetNextNodeProc;
-
-  KeyState: TKeyboardState;
-  Buffer: array[0..1] of Char;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMKeyDown');{$endif}
-  // Make form key preview work and let application modify the key if it wants this.
-  inherited WMKeyDown(Message);
-
-  with Message do
-  begin
-    Shift := KeyDataToShiftState(KeyData);
-    // Ask the application if the default key handling is desired.
-    if DoKeyAction(CharCode, Shift) then
-    begin
-      if (tsKeyCheckPending in FStates) and (CharCode <> VK_SPACE) then
-      begin
-        DoStateChange([], [tskeyCheckPending]);
-        FCheckNode.CheckState := UnpressedState[FCheckNode.CheckState];
-        RepaintNode(FCheckNode);
-        FCheckNode := nil;
-      end;
-
-      if CharCode in [VK_HOME, VK_END, VK_PRIOR, VK_NEXT, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_BACK, VK_TAB] then
-      begin
-        HandleMultiSelect := (ssShift in Shift) and (toMultiSelect in FOptions.FSelectionOptions) and not IsEditing;
-
-        // Flag to avoid range selection in case of single node advance.
-        DoRangeSelect := (CharCode in [VK_HOME, VK_END, VK_PRIOR, VK_NEXT]) and HandleMultiSelect and not IsEditing;
-
-        NeedInvalidate := DoRangeSelect or (FSelectionCount > 1);
-        ActAsGrid := toGridExtensions in FOptions.FMiscOptions;
-        ClearPending := (Shift = []) or (ActAsGrid and not (ssShift in Shift)) or
-          not (toMultiSelect in FOptions.FSelectionOptions) or (CharCode in [VK_TAB, VK_BACK]);
-
-        // Keep old focused node for range selection. Use a default node if none was focused until now.
-        LastFocused := FFocusedNode;
-        if (LastFocused = nil) and (Shift <> []) then
-          LastFocused := GetFirstVisible(nil, True);
-
-        // Set an initial range anchor if there is not yet one.
-        if FRangeAnchor = nil then
-          FRangeAnchor := GetFirstSelected;
-        if FRangeAnchor = nil then
-          FRangeAnchor := GetFirst;
-
-        if UseRightToLeftAlignment then
-          RTLFactor := -1
-        else
-          RTLFactor := 1;
-          
-        // Determine new focused node.
-        case CharCode of
-          VK_HOME, VK_END:
-            begin
-              if (CharCode = VK_END) xor UseRightToLeftAlignment then
-              begin
-                GetStartColumn := FHeader.FColumns.GetLastVisibleColumn;
-                GetNextColumn := FHeader.FColumns.GetPreviousVisibleColumn;
-                GetNextNode := GetPreviousVisible;
-                Node := GetLastVisible(nil, True);
-              end
-              else
-              begin
-                GetStartColumn := FHeader.FColumns.GetFirstVisibleColumn;
-                GetNextColumn := FHeader.FColumns.GetNextVisibleColumn;
-                GetNextNode := GetNextVisible;
-                Node := GetFirstVisible(nil, True);
-              end;
-
-              // Advance to next/previous visible column.
-              if FHeader.UseColumns then
-                NewColumn := GetStartColumn
-              else
-                NewColumn := NoColumn;
-              // Find a column for the new/current node which can be focused.
-              // Make the 'DoFocusChanging' for finding a valid column
-              // identifiable from the 'DoFocusChanging' raised later on by
-              // "FocusedNode := Node;"
-              while (NewColumn > NoColumn) and not DoFocusChanging(FFocusedNode, FFocusedNode, FFocusedColumn, NewColumn) do
-                NewColumn := GetNextColumn(NewColumn);
-              if NewColumn > InvalidColumn then
-              begin
-                if (Shift = [ssCtrlOS]) and not ActAsGrid then
-                begin
-                  ScrollIntoView(Node, toCenterScrollIntoView in FOptions.SelectionOptions,
-                    not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions));
-                  if (CharCode = VK_HOME) and not UseRightToLeftAlignment then
-                    SetOffsetX(0)
-                  else
-                    SetOffsetX(-MaxInt);
-                end
-                else
-                begin
-                  if not ActAsGrid or (ssCtrlOS in Shift) then
-                    FocusedNode := Node;
-                  if ActAsGrid and not (toFullRowSelect in FOptions.FSelectionOptions) then
-                    FocusedColumn := NewColumn;
-                end;
-              end;
-            end;
-          VK_PRIOR:
-            if ssCtrlOS in Shift then
-              SetOffsetY(FOffsetY + ClientHeight)
-            else
-            begin
-              Offset := 0;
-              // If there's no focused node then just take the very first visible one.
-              if FFocusedNode = nil then
-                Node := GetFirstVisible(nil, True)
-              else
-              begin
-                // Go up as many nodes as comprise together a size of ClientHeight.
-                Node := FFocusedNode;
-                while True do
-                begin
-                  Temp := GetPreviousVisible(Node, True);
-                  NewHeight := NodeHeight[Node];
-                  if (Temp = nil) or (Offset + NewHeight >= ClientHeight) then
-                    Break;
-                  Node := Temp;
-                  Inc(Offset, NodeHeight[Node]);
-                end;
-              end;
-              FocusedNode := Node;
-            end;
-          VK_NEXT:
-            if ssCtrlOS in Shift then
-              SetOffsetY(FOffsetY - ClientHeight)
-            else
-            begin
-              Offset := 0;
-              // If there's no focused node then just take the very last one.
-              if FFocusedNode = nil then
-                Node := GetLastVisible(nil, True)
-              else
-              begin
-                // Go up as many nodes as comprise together a size of ClientHeight.
-                Node := FFocusedNode;
-                while True do
-                begin
-                  Temp := GetNextVisible(Node, True);
-                  NewHeight := NodeHeight[Node];
-                  if (Temp = nil) or (Offset + NewHeight >= ClientHeight) then
-                    Break;
-                  Node := Temp;
-                  Inc(Offset, NewHeight);
-                end;
-              end;
-              FocusedNode := Node;
-            end;
-          VK_UP:
-            begin
-              // scrolling without selection change
-              if ssCtrlOS in Shift then
-                SetOffsetY(FOffsetY + Integer(FDefaultNodeHeight))
-              else
-              begin
-                if FFocusedNode = nil then
-                  Node := GetLastVisible(nil, True)
-                else
-                  Node := GetPreviousVisible(FFocusedNode, True);
-
-                if Assigned(Node) then
-                begin
-                  EndEditNode;
-                  if HandleMultiSelect and (CompareNodePositions(LastFocused, FRangeAnchor) > 0) and
-                    Assigned(FFocusedNode) then
-                    RemoveFromSelection(FFocusedNode);
-                  if FFocusedColumn <= NoColumn then
-                    FFocusedColumn := FHeader.MainColumn;
-                  FocusedNode := Node;
-                end
-                else
-                  if Assigned(FFocusedNode) then
-                    InvalidateNode(FFocusedNode);
-              end;
-            end;
-          VK_DOWN:
-            begin
-              // scrolling without selection change
-              if ssCtrlOS in Shift then
-                SetOffsetY(FOffsetY - Integer(FDefaultNodeHeight))
-              else
-              begin
-                if FFocusedNode = nil then
-                  Node := GetFirstVisible(nil, True)
-                else
-                  Node := GetNextVisible(FFocusedNode, True);
-
-                if Assigned(Node) then
-                begin
-                  EndEditNode;
-                  if HandleMultiSelect and (CompareNodePositions(LastFocused, FRangeAnchor) < 0) and
-                    Assigned(FFocusedNode) then
-                    RemoveFromSelection(FFocusedNode);
-                  if FFocusedColumn <= NoColumn then
-                    FFocusedColumn := FHeader.MainColumn;
-                  FocusedNode := Node;
-                end
-                else
-                  if Assigned(FFocusedNode) then
-                    InvalidateNode(FFocusedNode);
-              end;
-            end;
-          VK_LEFT:
-            begin
-              // special handling
-              if ssCtrlOS in Shift then
-                SetOffsetX(FOffsetX + RTLFactor * FHeader.Columns.GetScrollWidth)
-              else
-              begin
-                // other special cases
-                Context := NoColumn;
-                if (toExtendedFocus in FOptions.FSelectionOptions) and (toGridExtensions in FOptions.FMiscOptions) then
-                begin
-                  Context := FHeader.Columns.GetPreviousVisibleColumn(FFocusedColumn, True);
-                  if Context > -1 then
-                    FocusedColumn := Context
-                end
-                else
-                  if Assigned(FFocusedNode) and (vsExpanded in FFocusedNode.States) and
-                     (Shift = []) and (vsHasChildren in FFocusedNode.States) then
-                    ToggleNode(FFocusedNode)
-                  else
-                  begin
-                    if FFocusedNode = nil then
-                      FocusedNode := GetFirstVisible(nil, True)
-                    else
-                    begin
-                      if FFocusedNode.Parent <> FRoot then
-                        Node := FFocusedNode.Parent
-                      else
-                        Node := nil;
-                      if Assigned(Node) then
-                      begin
-                        if HandleMultiSelect then
-                        begin
-                          // and a third special case
-                          if FFocusedNode.Index > 0 then
-                            DoRangeSelect := True
-                          else
-                           if CompareNodePositions(Node, FRangeAnchor) > 0 then
-                             RemoveFromSelection(FFocusedNode);
-                        end;
-                        FocusedNode := Node;
-                      end;
-                    end;
-                  end;
-              end;
-            end;
-          VK_RIGHT:
-            begin
-              // special handling
-              if ssCtrlOS in Shift then
-                SetOffsetX(FOffsetX - RTLFactor * FHeader.Columns.GetScrollWidth)
-              else
-              begin
-                // other special cases
-                Context := NoColumn;
-                if (toExtendedFocus in FOptions.FSelectionOptions) and (toGridExtensions in FOptions.FMiscOptions) then
-                begin
-                  Context := FHeader.Columns.GetNextVisibleColumn(FFocusedColumn, True);
-                  if Context > -1 then
-                    FocusedColumn := Context;
-                end
-                else
-                  if Assigned(FFocusedNode) and not (vsExpanded in FFocusedNode.States) and
-                     (Shift = []) and (vsHasChildren in FFocusedNode.States) then
-                    ToggleNode(FFocusedNode)
-                  else
-                  begin
-                    if FFocusedNode = nil then
-                      FocusedNode := GetFirstVisible(nil, True)
-                    else
-                    begin
-                      Node := GetFirstVisibleChild(FFocusedNode);
-                      if Assigned(Node) then
-                      begin
-                        if HandleMultiSelect and (CompareNodePositions(Node, FRangeAnchor) < 0) then
-                          RemoveFromSelection(FFocusedNode);
-                        FocusedNode := Node;
-                      end;
-                    end;
-                  end;
-              end;
-            end;
-          VK_BACK:
-            if tsIncrementalSearching in FStates then
-              DoStateChange([tsIncrementalSearchPending])
-            else
-              if Assigned(FFocusedNode) and (FFocusedNode.Parent <> FRoot) then
-                FocusedNode := FocusedNode.Parent;
-          VK_TAB:
-            if (toExtendedFocus in FOptions.FSelectionOptions) and FHeader.UseColumns then
-            begin
-              // In order to avoid duplicating source code just to change the direction
-              // we use function variables.
-              if ssShift in Shift then
-              begin
-                GetStartColumn := FHeader.FColumns.GetLastVisibleColumn;
-                GetNextColumn := FHeader.FColumns.GetPreviousVisibleColumn;
-                GetNextNode := GetPreviousVisible;
-              end
-              else
-              begin
-                GetStartColumn := FHeader.FColumns.GetFirstVisibleColumn;
-                GetNextColumn := FHeader.FColumns.GetNextVisibleColumn;
-                GetNextNode := GetNextVisible;
-              end;
-
-              // Advance to next/previous visible column/node.
-              Node := FFocusedNode;
-              NewColumn := GetNextColumn(FFocusedColumn, True);
-              repeat
-                // Find a column for the current node which can be focused.
-                while (NewColumn > NoColumn) and not DoFocusChanging(FFocusedNode, Node, FFocusedColumn, NewColumn) do
-                  NewColumn := GetNextColumn(NewColumn, True);
-
-                if NewColumn > NoColumn then
-                begin
-                  // Set new node and column in one go.
-                  SetFocusedNodeAndColumn(Node, NewColumn);
-                  Break;
-                end;
-
-                // No next column was accepted for the current node. So advance to next node and try again.
-                Node := GetNextNode(Node);
-                NewColumn := GetStartColumn;
-              until Node = nil;
-            end;
-        end;
-
-        // Clear old selection if required but take care to select the new focused node if it was not selected before.
-        ForceSelection := False;
-        if ClearPending and ((LastFocused <> FFocusedNode) or (FSelectionCount <> 1)) then
-        begin
-          ClearSelection;
-          ForceSelection := True;
-        end;
-
-        // Determine new selection anchor.
-        if Shift = [] then
-        begin
-          FRangeAnchor := FFocusedNode;
-          FLastSelectionLevel := GetNodeLevel(FFocusedNode);
-        end;
-        // Finally change the selection for a specific range of nodes.
-        if DoRangeSelect then
-          ToggleSelection(LastFocused, FFocusedNode);
-
-        // Make sure the new focused node is also selected.
-        if Assigned(FFocusedNode) and ((LastFocused <> FFocusedNode) or ForceSelection) then
-          AddToSelection(FFocusedNode);
-
-        // If a repaint is needed then paint the entire tree because of the ClearSelection call,
-        if NeedInvalidate then
-          Invalidate;
-        {$ifdef LCLGtk2}
-        //workaround for changing focus bug
-        if CharCode <> VK_TAB then
-          CharCode := 0;
-        {$endif}
-      end
-      else
-      begin
-        // Second chance for keys not directly concerned with selection changes.
-
-        // For +, -, /, * keys on the main keyboard (not numpad) there is no virtual key code defined.
-        // We have to do special processing to get them working too.
-        //todo: reimplement
-        {$ifndef INCOMPLETE_WINAPI}
-        GetKeyboardState(KeyState);
-        // Avoid conversion to control characters. We have captured the control key state already in Shift.
-        KeyState[VK_CONTROL] := 0;
-        if ToASCII(Message.CharCode, (Message.KeyData shr 16) and 7, KeyState, @Buffer, 0) > 0 then
-        begin
-          case Buffer[0] of
-            '*':
-              CharCode := VK_MULTIPLY;
-            '+':
-              CharCode := VK_ADD;
-            '/':
-              CharCode := VK_DIVIDE;
-            '-':
-              CharCode := VK_SUBTRACT;
-          end;
-        end;
-
-        // According to http://www.it-faq.pl/mskb/99/337.HTM there is a problem with ToASCII when used in conjunction
-        // with dead chars. The article recommends to call ToASCII twice to restore a deleted flag in the key message
-        // structure under certain circumstances. It turned out it is best to always call ToASCII twice.
-        ToASCII(Message.CharCode, (Message.KeyData shr 16) and 7, KeyState, @Buffer, 0);
-        {$endif}
-        case CharCode of
-          VK_F2:
-            if (Shift = []) and Assigned(FFocusedNode) and CanEdit(FFocusedNode, FFocusedColumn) then
-            begin
-              FEditColumn := FFocusedColumn;
-              DoEdit;
-            end;
-          VK_ADD:
-            if not (tsIncrementalSearching in FStates) then
-            begin
-              if ssCtrlOS in Shift then
-                if {$ifdef ReverseFullExpandHotKey} not {$endif ReverseFullExpandHotKey} (ssShift in Shift) then
-                  FullExpand
-                else
-                  FHeader.AutoFitColumns
-              else
-                if Assigned(FFocusedNode) and not (vsExpanded in FFocusedNode.States) then
-                  ToggleNode(FFocusedNode);
-            end
-            else
-              DoStateChange([tsIncrementalSearchPending]);
-          VK_SUBTRACT:
-            if not (tsIncrementalSearching in FStates) then
-            begin
-              if ssCtrlOS in Shift then
-                if {$ifdef ReverseFullExpandHotKey} not {$endif ReverseFullExpandHotKey} (ssShift in Shift) then
-                  FullCollapse
-                else
-                  FHeader.RestoreColumns
-              else
-                if Assigned(FFocusedNode) and (vsExpanded in FFocusedNode.States) then
-                  ToggleNode(FFocusedNode);
-            end
-            else
-              DoStateChange([tsIncrementalSearchPending]);
-          VK_MULTIPLY:
-            if not (tsIncrementalSearching in FStates) then
-            begin
-              if Assigned(FFocusedNode) then
-                FullExpand(FFocusedNode);
-            end
-            else
-              DoStateChange([tsIncrementalSearchPending]);
-          VK_DIVIDE:
-            if not (tsIncrementalSearching in FStates) then
-            begin
-              if Assigned(FFocusedNode) then
-                FullCollapse(FFocusedNode);
-            end
-            else
-              DoStateChange([tsIncrementalSearchPending]);
-          VK_ESCAPE: // cancel actions currently in progress
-            begin
-              if IsMouseSelecting then
-              begin
-                DoStateChange([], [tsDrawSelecting, tsDrawSelPending]);
-                Invalidate;
-              end
-              //gtk1 does not like to free a component in KeyDown
-              {$ifndef LCLGtk}
-              else
-                if IsEditing then
-                  CancelEditNode;
-              {$endif}
-            end;
-          VK_SPACE:
-            if (toCheckSupport in FOptions.FMiscOptions) and Assigned(FFocusedNode) and
-              (FFocusedNode.CheckType <> ctNone) then
-            begin
-              if (FStates * [tsKeyCheckPending, tsMouseCheckPending] = []) and Assigned(FFocusedNode) and
-                not (vsDisabled in FFocusedNode.States) then
-              begin
-                with FFocusedNode^ do
-                  NewCheckState := DetermineNextCheckState(CheckType, CheckState);
-                if DoChecking(FFocusedNode, NewCheckState) then
-                begin
-                  DoStateChange([tsKeyCheckPending]);
-                  FCheckNode := FFocusedNode;
-                  FPendingCheckState := NewCheckState;
-                  FCheckNode.CheckState := PressedState[FCheckNode.CheckState];
-                  RepaintNode(FCheckNode);
-                end;
-              end;
-            end
-            else
-              DoStateChange([tsIncrementalSearchPending]);
-          VK_F1:
-            if Assigned(FOnGetHelpContext) then
-            begin
-              Context := 0;
-              if Assigned(FFocusedNode) then
-              begin
-                Node := FFocusedNode;
-                // Traverse the tree structure up to the root.
-                repeat
-                  FOnGetHelpContext(Self, Node, 0, Context);
-                  Node := Node.Parent;
-                until (Node = FRoot) or (Context <> 0);
-              end;
-
-              // If no help context could be found try the tree's one or its parent's contexts.
-              ParentControl := Self;
-              while Assigned(ParentControl) and (Context = 0) do
-              begin
-                Context := ParentControl.HelpContext;
-                ParentControl := ParentControl.Parent;
-              end;
-              if Context <> 0 then
-                Application.HelpContext(Context);
-            end;
-          VK_APPS:
-            if Assigned(FFocusedNode) then
-            begin
-              R := GetDisplayRect(FFocusedNode, FFocusedColumn, True);
-              Offset := DoGetNodeWidth(FFocusedNode, FFocusedColumn);
-              if FFocusedColumn >= 0 then
-              begin
-                if Offset > FHeader.Columns[FFocusedColumn].Width then
-                  Offset := FHeader.Columns[FFocusedColumn].Width;
-              end
-              else
-              begin
-                if Offset > ClientWidth then
-                  Offset := ClientWidth;
-              end;
-              DoPopupMenu(FFocusedNode, FFocusedColumn, Point(R.Left + Offset div 2, (R.Top + R.Bottom) div 2));
-            end;
-          Ord('a'), Ord('A'):
-            if ssCtrlOS in Shift then
-              SelectAll(True)
-            else
-              DoStateChange([tsIncrementalSearchPending]);
-        else
-        begin
-          // Use the key for incremental search.
-          // Since we are dealing with Unicode all the time there should be a more sophisticated way
-          // of checking for valid characters for incremental search.
-          // This is available but would require to include a significant amount of Unicode character
-          // properties, so we stick with the simple space check.
-          if (Shift * [ssCtrlOS, ssAlt] = []) and (CharCode >= 32) then
-            DoStateChange([tsIncrementalSearchPending]);
-          end;
-        end;
-      end;
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMKeyDown');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMKeyUp(var Message: TLMKeyUp);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMKeyUp');{$endif}
-  inherited WMKeyUp(Message);
-
-  case Message.CharCode of
-    VK_SPACE:
-      if tsKeyCheckPending in FStates then
-      begin
-        DoStateChange([], [tskeyCheckPending]);
-        if FCheckNode = FFocusedNode then
-          DoCheckClick(FCheckNode, FPendingCheckState);
-        InvalidateNode(FCheckNode);
-        FCheckNode := nil;
-      end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMKeyUp');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMKillFocus(var Msg: TLMKillFocus);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMKillFocus');{$endif}
-  inherited WMKillFocus(Msg);
-
-  // Remove hint if shown currently.
-  Application.CancelHint;
-
-  // Stop wheel panning if active.
-  StopWheelPanning;
-
-  // Don't let any timer continue if the tree is no longer the active control (except change timers).
-  KillTimer(Handle, ExpandTimer);
-  KillTimer(Handle, EditTimer);
-  KillTimer(Handle, ScrollTimer);
-  KillTimer(Handle, SearchTimer);
-  FSearchBuffer := '';
-  FLastSearchNode := nil;
-
-  DoStateChange([], [tsScrollPending, tsScrolling, tsEditPending, tsLeftButtonDown, tsRightButtonDown,
-    tsMiddleButtonDown, tsOLEDragPending, tsVCLDragPending, tsIncrementalSearching, tsNodeHeightTrackPending,
-    tsNodeHeightTracking]);
-
-  if (FSelectionCount > 0) or not (toGhostedIfUnfocused in FOptions.FPaintOptions) then
-    Invalidate
-  else
-    if Assigned(FFocusedNode) then
-      InvalidateNode(FFocusedNode);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMKillFocus');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMLButtonDblClk(var Message: TLMLButtonDblClk);
-
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMLButtonDblClk');{$endif}
-  DoStateChange([tsLeftDblClick]);
-
-  inherited WMLButtonDblClk(Message);
-
-  // get information about the hit
-  GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-  HandleMouseDblClick(Message, HitInfo);
-  DoStateChange([], [tsLeftDblClick]);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMLButtonDblClk');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMLButtonDown(var Message: TLMLButtonDown);
-
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMLButtonDown');{$endif}
-  DoStateChange([tsLeftButtonDown]);
-  inherited WMLButtonDown(Message);
-
-  // get information about the hit
-  GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-  {$ifdef DEBUG_VTV}
-  if HitInfo.HitNode <> nil then
-    Logger.Send([lcPaintHeader, lcMouseEvent],'WMLButtonDown - HitNode.Index', HitInfo.HitNode^.Index);
-  {$endif}
-  HandleMouseDown(Message, HitInfo);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMLButtonDown');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMLButtonUp(var Message: TLMLButtonUp);
-
-var
-  HitInfo: THitInfo;
-
-begin
-  DoStateChange([], [tsLeftButtonDown, tsNodeHeightTracking, tsNodeHeightTrackPending]);
-
-  // get information about the hit
-  GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-  HandleMouseUp(Message.Keys, HitInfo);
-
-  inherited WMLButtonUp(Message);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMLButtonUp');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMMButtonDblClk(var Message: TLMMButtonDblClk);
-
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMMButtonDblClk');{$endif}
-  DoStateChange([tsMiddleDblClick]);
-  inherited WMMButtonDblClk(Message);
-
-  // get information about the hit
-  if toMiddleClickSelect in FOptions.FSelectionOptions then
-  begin
-    GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-    HandleMouseDblClick(Message, HitInfo);
-  end;
-  DoStateChange([], [tsMiddleDblClick]);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMMButtonDblClk');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMMButtonDown(var Message: TLMMButtonDown);
-
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMMButtonDown');{$endif}
-  DoStateChange([tsMiddleButtonDown]);
-
-  if FHeader.FStates = [] then
-  begin
-    inherited WMMButtonDown(Message);
-
-    // Start wheel panning or scrolling if not already active, allowed and scrolling is useful at all.
-    if (toWheelPanning in FOptions.FMiscOptions) and ([tsWheelScrolling, tsWheelPanning] * FStates = []) and
-      ((Integer(FRangeX) > ClientWidth) or (Integer(FRangeY) > ClientHeight)) then
-    begin
-      FLastClickPos := SmallPointToPoint(Message.Pos);
-      StartWheelPanning(FLastClickPos);
-    end
-    else
-    begin
-      StopWheelPanning;
-
-      // Get information about the hit.
-      if toMiddleClickSelect in FOptions.FSelectionOptions then
-      begin
-        GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-        HandleMouseDown(Message, HitInfo);
-      end;
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMMButtonDown');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMMButtonUp(var Message: TLMMButtonUp);
-
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMMButtonUp');{$endif}
-  DoStateChange([], [tsMiddleButtonDown]);
-
-  // If wheel panning/scrolling is active and the mouse has not yet been moved then the user starts wheel auto scrolling.
-  // Indicate this by removing the panning flag. Otherwise (the mouse has moved meanwhile) stop panning.
-  if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then
-  begin
-    if tsWheelScrolling in FStates then
-      DoStateChange([], [tsWheelPanning])
-    else
-      StopWheelPanning;
-  end
-  else
-    if FHeader.FStates = [] then
-    begin
-      inherited WMMButtonUp(Message);
-
-      // get information about the hit
-      if toMiddleClickSelect in FOptions.FSelectionOptions then
-      begin
-        GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-        HandleMouseUp(Message.Keys, HitInfo);
-      end;
-    end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod('WMMButtonUp');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$ifdef EnableNCFunctions}
-
-procedure TBaseVirtualTree.WMNCCalcSize(var Message: TLMNCCalcSize);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMNCCalcSize');{$endif}
-  inherited WMNCCalcSize(Message);
-
-  with FHeader do
-    if hoVisible in FHeader.FOptions then
-      with Message.CalcSize_Params^ do
-        Inc(rgrc[0].Top, FHeight);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMNCCalcSize');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMNCHitTest(var Message: TWMNCHitTest);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMNCHitTest');{$endif}
-  inherited WMNCHitTest(Message);
-  if not (csDesigning in ComponentState) and (hoVisible in FHeader.FOptions) and
-    FHeader.InHeader(ScreenToClient(SmallPointToPoint(Message.Pos))) then
-    Message.Result := HTBORDER;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMNCHitTest');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMNCPaint(var Message: TRealWMNCPaint);
-
-var
-  DC: HDC;
-  R: TRect;
-  Flags: DWORD;
-  {$ifdef ThemeSupport}
-    ExStyle: Integer;
-    TempRgn: HRGN;
-    BorderWidth,
-    BorderHeight: Integer;
-  {$endif ThemeSupport}
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMNCPaint');{$endif}
-  {$ifdef ThemeSupport}
-    if tsUseThemes in FStates then
-    begin
-      // If theming is enabled and the client edge border is set for the window then prevent the default window proc
-      // from painting the old border to avoid flickering.
-      ExStyle := GetWindowLong(Handle, GWL_EXSTYLE);
-      if (ExStyle and WS_EX_CLIENTEDGE) <> 0 then
-      begin
-        GetWindowRect(Handle, R);
-        // Determine width of the client edge.
-        BorderWidth := GetSystemMetrics(SM_CXEDGE);
-        BorderHeight := GetSystemMetrics(SM_CYEDGE);
-        InflateRect(R, -BorderWidth, -BorderHeight);
-        TempRgn := CreateRectRgnIndirect(R);
-        // Exclude the border from the message region if there is one. Otherwise just use the inflated
-        // window area region.
-        if Message.Rgn <> 1 then
-          CombineRgn(TempRgn, Message.Rgn, TempRgn, RGN_AND);
-        DefWindowProc(Handle, Message.Msg, Integer(TempRgn), 0);
-        DeleteObject(TempRgn);
-      end
-      else
-        DefaultHandler(Message);
-    end
-    else
-  {$endif ThemeSupport}
-    DefaultHandler(Message);
-
-  Flags := DCX_CACHE or DCX_CLIPSIBLINGS or DCX_WINDOW or DCX_VALIDATE;
-
-  if (Message.Rgn = 1) or not IsWinNT then
-    DC := GetDCEx(Handle, 0, Flags)
-  else
-    DC := GetDCEx(Handle, Message.Rgn, Flags or DCX_INTERSECTRGN);
-
-  if DC <> 0 then
-  begin
-    if hoVisible in FHeader.FOptions then
-    begin
-      R := FHeaderRect;
-      FHeader.FColumns.PaintHeader(DC, R, -FEffectiveOffsetX);
-    end;
-    OriginalWMNCPaint(DC);
-    ReleaseDC(Handle, DC);
-  end;
-  {$ifdef ThemeSupport}
-    if tsUseThemes in FStates then
-      ThemeServices.PaintBorder(Self, False);
-  {$endif ThemeSupport}
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMNCPaint');{$endif}
-end;
-
-{$endif}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMPaint(var Message: TLMPaint);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMPaint');{$endif}
-  //todo:
-  //Windows.GetUpdateRect is always empty because BeginPaint was called
-  //see if PaintStruct has the same rect
-  {$ifndef INCOMPLETE_WINAPI}
-  if tsVCLDragging in FStates then
-    ImageList_DragShowNolock(False);
-  {$endif}
-
-  if csPaintCopy in ControlState then
-    FUpdateRect := ClientRect
-  else
-    FUpdateRect := Message.PaintStruct^.rcPaint;
-
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaint],'FUpdateRect', FUpdateRect);{$endif}
-
-  inherited WMPaint(Message);
-
-  {$ifndef INCOMPLETE_WINAPI}
-  if tsVCLDragging in FStates then
-    ImageList_DragShowNolock(True);
-  {$endif}
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMPaint');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMPaste(var Message: TLMNoParams);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMPaste');{$endif}
-  PasteFromClipboard;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMPaste');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$ifdef EnablePrintFunctions}
-
-procedure TBaseVirtualTree.WMPrint(var Message: TWMPrint);
-
-// This message is sent to request that the tree draws itself to a given device context. This includes not only
-// the client area but also the non-client area (header!).
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMPrint');{$endif}
-  // Draw only if the window is visible or visibility is not required.
-  if ((Message.Flags and PRF_CHECKVISIBLE) = 0) or IsWindowVisible(Handle) then
-    Header.Columns.PaintHeader(Message.DC, FHeaderRect, -FEffectiveOffsetX);
-
-  inherited WMPrint(Message);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMPrint');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMPrintClient(var Message: TWMPrintClient);
-
-var
-  Window: TRect;
-  Target: TPoint;
-  Canvas: TCanvas;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMPrintClient');{$endif}
-  // Draw only if the window is visible or visibility is not required.
-  if ((Message.Flags and PRF_CHECKVISIBLE) = 0) or IsWindowVisible(Handle) then
-  begin
-    // Determine area of the entire tree to be displayed in the control.
-    Window := ClientRect;
-    Target := Window.TopLeft;
-
-    // The Window rectangle is given in client coordinates. We have to convert it into
-    // a sliding window of the tree image.
-    OffsetRect(Window, FEffectiveOffsetX, -FOffsetY);
-
-    Canvas := TCanvas.Create;
-    try
-      Canvas.Handle := Message.DC;
-      PaintTree(Canvas, Window, Target, [poBackground, poDrawFocusRect, poDrawDropMark, poDrawSelection, poGridLines]);
-    finally
-      Canvas.Handle := 0;
-      Canvas.Free;
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMPrintClient');{$endif}
-end;
-
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMRButtonDblClk(var Message: TLMRButtonDblClk);
-
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMRButtonDblClk');{$endif}
-  DoStateChange([tsRightDblClick]);
-  inherited WMRButtonDblClk(Message);
-
-  // get information about the hit
-  if toMiddleClickSelect in FOptions.FSelectionOptions then
-  begin
-    GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-    HandleMouseDblClick(Message, HitInfo);
-  end;
-  DoStateChange([], [tsRightDblClick]);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMRButtonDblClk');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMRButtonDown(var Message: TLMRButtonDown);
-
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMRButtonDown');{$endif}
-  DoStateChange([tsRightButtonDown]);
-
-  if FHeader.FStates = [] then
-  begin
-    inherited WMRButtonDown(Message);
-
-    // get information about the hit
-    if toRightClickSelect in FOptions.FSelectionOptions then
-    begin
-      GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-      HandleMouseDown(Message, HitInfo);
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMRButtonDown');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMRButtonUp(var Message: TLMRButtonUp);
-
-// handle right click selection and node specific popup menu
-
-var
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMRButtonUp');{$endif}
-  DoStateChange([], [tsPopupMenuShown, tsRightButtonDown]);
-
-  if FHeader.FStates = [] then
-  begin
-    Application.CancelHint;
-
-    if IsMouseSelecting and Assigned(PopupMenu) then
-    begin
-      // Reset selection state already here, before the inherited handler opens the default menu.
-      DoStateChange([], [tsDrawSelecting, tsDrawSelPending]);
-      Invalidate;
-    end;
-
-    inherited WMRButtonUp(Message);
-
-    // get information about the hit
-    GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-
-    if toRightClickSelect in FOptions.FSelectionOptions then
-      HandleMouseUp(Message.Keys, HitInfo);
-
-    if not Assigned(PopupMenu) then
-      DoPopupMenu(HitInfo.HitNode, HitInfo.HitColumn, Point(Message.XPos, Message.YPos));
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMRButtonUp');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMSetFocus(var Msg: TLMSetFocus);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMSetFocus') ;{$endif}
-  inherited WMSetFocus(Msg);
-  if (FSelectionCount > 0) or not (toGhostedIfUnfocused in FOptions.FPaintOptions) then
-    Invalidate;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMSetFocus');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMSize(var Message: TLMSize);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'WMSize');{$endif}
-  inherited WMSize(Message);
-
-  // Need to update scroll bars here. This will cause a recursion because of the change of the client area
-  // when changing a scrollbar. Usually this is no problem since with the second level recursion no change of the
-  // window size happens (the same values for the scrollbars are set, which shouldn't cause a window size change).
-  // Appearently, this applies not to all systems, however.
-  if HandleAllocated and ([tsSizing, tsWindowCreating] * FStates = []) and (ClientHeight > 0) then
-  try
-    DoStateChange([tsSizing]);
-    // This call will invalidate the entire non-client area which needs recalculation on resize.
-    FHeader.RescaleHeader;
-    FHeader.UpdateSpringColumns;
-    UpdateScrollBars(True);
-
-    if (tsEditing in FStates) and not FHeader.UseColumns then
-      UpdateEditBounds;
-  finally
-    DoStateChange([], [tsSizing]);
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'WMSize');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$ifdef ThemeSupport}
-{$ifdef Windows}
-//todo
-  procedure TBaseVirtualTree.WMThemeChanged(var Message: TLMessage);
-
-  begin
-    inherited;
-    ThemeServices.UpdateThemes;
-    if ThemeServices.ThemesEnabled and (toThemeAware in TreeOptions.PaintOptions) then
-      DoStateChange([tsUseThemes])
-    else
-      DoStateChange([], [tsUseThemes]);
-    RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_VALIDATE or RDW_FRAME);
-  end;
-{$endif}
-{$endif ThemeSupport}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMTimer(var Message: TLMTimer);
-
-// centralized timer handling happens here
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages,lcTimer],'WMTimer');{$endif}
-  with Message do
-  begin
-    {$ifdef DEBUG_VTV}Logger.Send([lcTimer],'TimerId',TimerId);{$endif}
-    case TimerID of
-      ExpandTimer:
-        DoDragExpand;
-      EditTimer:
-        DoEdit;
-      ScrollTimer:
-        begin
-          if tsScrollPending in FStates then
-          begin
-            Application.CancelHint;
-            // Scroll delay has elapsed, set to normal scroll interval now.
-            SetTimer(Handle, ScrollTimer, FAutoScrollInterval, nil);
-            DoStateChange([tsScrolling], [tsScrollPending]);
-          end;
-          DoTimerScroll;
-        end;
-      ChangeTimer:
-        DoChange(FLastChangedNode);
-      StructureChangeTimer:
-        DoStructureChange(FLastStructureChangeNode, FLastStructureChangeReason);
-      SearchTimer:
-        begin
-          // When this event triggers then the user did not pressed any key for the specified timeout period.
-          // Hence incremental searching is stopped.
-          DoStateChange([], [tsIncrementalSearching]);
-          KillTimer(Handle, SearchTimer);
-          FSearchBuffer := '';
-          FLastSearchNode := nil;
-        end;
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages,lcTimer],'WMTimer');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WMVScroll(var Message: TLMVScroll);
-
-  //--------------- local functions -------------------------------------------
-
-  function GetRealScrollPosition: Integer;
-
-  var
-    SI: TScrollInfo;
-    Code: Integer;
-
-  begin
-    SI.cbSize := SizeOf(TScrollInfo);
-    SI.fMask := SIF_TRACKPOS;
-    Code := SB_VERT;
-    {$ifdef UseFlatScrollbars}
-      FlatSB_GetScrollInfo(Handle, Code, SI);
-    {$else}
-      GetScrollInfo(Handle, Code, SI);
-    {$endif UseFlatScrollbars}
-    Result := SI.nTrackPos;
-    {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'GetRealScrollPosition',Result);{$endif}
-  end;
-
-  //--------------- end local functions ---------------------------------------
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcScroll],'WMVScroll');{$endif}
-  //{$ifdef DEBUG_VTV}Logger.SendCallStack([lcScroll],'CallStack');{$endif}
-  case Message.ScrollCode of
-    SB_BOTTOM:
-      SetOffsetY(-Integer(FRoot.TotalHeight));
-    SB_ENDSCROLL:
-      begin
-        DoStateChange([], [tsThumbTracking]);
-        // Avoiding to adjust the horizontal scroll position while tracking makes scrolling much smoother
-        // but we need to adjust the final position here then.
-        UpdateScrollBars(True);
-        // Really weird invalidation needed here (and I do it only because it happens so rarely), because
-        // when showing the horizontal scrollbar while scrolling down using the down arrow button,
-        // the button will be repainted on mouse up (at the wrong place in the far right lower corner)...
-        RedrawWindow(Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_NOERASE or RDW_NOCHILDREN);
-      end;
-    SB_LINEUP:
-      SetOffsetY(FOffsetY + FScrollBarOptions.FIncrementY);
-    SB_LINEDOWN:
-      SetOffsetY(FOffsetY - FScrollBarOptions.FIncrementY);
-    SB_PAGEUP:
-      SetOffsetY(FOffsetY + ClientHeight);
-    SB_PAGEDOWN:
-      SetOffsetY(FOffsetY - ClientHeight);
-
-    SB_THUMBPOSITION,
-    SB_THUMBTRACK:
-      begin
-        DoStateChange([tsThumbTracking]);
-        {$if DEFINED(LCLQt) OR DEFINED(LCLCarbon)}
-        SetOffsetY(-Message.Pos);
-        {$else}
-        SetOffsetY(-GetRealScrollPosition);
-        {$endif}
-      end;
-    SB_TOP:
-      SetOffsetY(0);
-  end;
-  Message.Result := 0;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcScroll],'WMVScroll');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AddToSelection(Node: PVirtualNode);
-
-var
-  Changed: Boolean;
-
-begin
-  if not FSelectionLocked then
-  begin
-    Assert(Assigned(Node), 'Node must not be nil!');
-    FSingletonNodeArray[0] := Node;
-    Changed := InternalAddToSelection(FSingletonNodeArray, 1, False);
-    if Changed then
-    begin
-      InvalidateNode(Node);
-      Change(Node);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AddToSelection(const NewItems: TNodeArray; NewLength: Integer; ForceInsert: Boolean = False);
-
-// Adds the given items all at once into the current selection array. NewLength is the amount of
-// nodes to add (necessary to allow NewItems to be larger than the actual used entries).
-// ForceInsert is True if nodes must be inserted without consideration of level select constraint or
-// already set selected flags (e.g. when loading from stream).
-// Note: In the case ForceInsert is True the caller is responsible for making sure the new nodes aren't already in the
-//       selection array!
-
-var
-  Changed: Boolean;
-
-begin
-  Changed := InternalAddToSelection(NewItems, NewLength, ForceInsert);
-  if Changed then
-  begin
-    if NewLength = 1 then
-    begin
-      InvalidateNode(NewItems[0]);
-      Change(NewItems[0]);
-    end
-    else
-    begin
-      Invalidate;
-      Change(nil);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex);
-
-// Used in descendants to modify the paint rectangle of the current column while painting a certain node.
-
-begin
-  // Since cells are always drawn from left to right the next column index is independent of the
-  // bidi mode, but not the column borders, which might change depending on the cell's content.
-  NextNonEmpty := FHeader.FColumns.GetNextVisibleColumn(PaintInfo.Column);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AdjustPanningCursor(X, Y: Integer);
-
-// Triggered by a mouse move when wheel panning/scrolling is active.
-// Loads the proper cursor which indicates into which direction scrolling is done.
-
-var
-  NewCursor: HCURSOR;
-  ScrollHorizontal,
-  ScrollVertical: Boolean;
-
-begin
-  ScrollHorizontal := Integer(FRangeX) > ClientWidth;
-  ScrollVertical := Integer(FRangeY) > ClientHeight;
-
-  if (Abs(X - FLastClickPos.X) < 8) and (Abs(Y - FLastClickPos.Y) < 8) then
-  begin
-    // Mouse is in the neutral zone.
-    if ScrollHorizontal then
-    begin
-      if ScrollVertical then
-        NewCursor := crVT_MOVEALL
-      else
-        NewCursor := crVT_MOVEEW
-    end
-    else
-      NewCursor := crVT_MOVENS;
-  end
-  else
-  begin
-    // One of 8 directions applies: north, north-east, east, south-east, south, south-west, west and north-west.
-    // Check also if scrolling in the particular direction is possible.
-    if ScrollVertical and ScrollHorizontal then
-    begin
-      // All directions allowed.
-      if X - FlastClickPos.X < -8 then
-      begin
-        // Left hand side.
-        if Y - FLastClickPos.Y < -8 then
-          NewCursor := crVT_MOVENW
-        else
-          if Y - FLastClickPos.Y > 8 then
-            NewCursor := crVT_MOVESW
-          else
-            NewCursor := crVT_MOVEW;
-      end
-      else
-        if X - FLastClickPos.X > 8 then
-        begin
-          // Right hand side.
-          if Y - FLastClickPos.Y < -8 then
-            NewCursor := crVT_MOVENE
-          else
-            if Y - FLastClickPos.Y > 8 then
-              NewCursor := crVT_MOVESE
-            else
-              NewCursor := crVT_MOVEE;
-        end
-        else
-        begin
-          // Up or down.
-          if Y < FLastClickPos.Y then
-            NewCursor := crVT_MOVEN
-          else
-            NewCursor := crVT_MOVES;
-        end;
-    end
-    else
-      if ScrollHorizontal then
-      begin
-        // Only horizontal movement allowed.
-        if X < FlastClickPos.X then
-          NewCursor := crVT_MOVEW
-        else
-          NewCursor := crVT_MOVEE;
-      end
-      else
-      begin
-        // Only vertical movement allowed.
-        if Y < FlastClickPos.Y then
-          NewCursor := crVT_MOVEN
-        else
-          NewCursor := crVT_MOVES;
-      end;
-  end;
-
-  // Now load the cursor and apply it.
-  {$ifdef Windows}
-  LCLIntf.SetCursor(Screen.Cursors[NewCursor]);
-  {$else}
-  Cursor := NewCursor;
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AdviseChangeEvent(StructureChange: Boolean; Node: PVirtualNode; Reason: TChangeReason);
-
-// Used to register a delayed change event. If StructureChange is False then we have a selection change event (without
-// a specific reason) otherwise it is a structure change.
-
-begin
-  if StructureChange then
-  begin
-    if tsStructureChangePending in FStates then
-    begin
-      if HandleAllocated then
-        KillTimer(Handle,StructureChangeTimer);
-    end
-    else
-      DoStateChange([tsStructureChangePending]);
-
-    FLastStructureChangeNode := Node;
-    if FLastStructureChangeReason = crIgnore then
-      FLastStructureChangeReason := Reason
-    else
-      if Reason <> crIgnore then
-        FLastStructureChangeReason := crAccumulated;
-  end
-  else
-  begin
-    if tsChangePending in FStates then
-      KillTimer(Handle, ChangeTimer)
-    else
-      DoStateChange([tsChangePending]);
-
-    FLastChangedNode := Node;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.AllocateInternalDataArea(Size: Cardinal): Cardinal;
-
-// Simple registration method to be called by each descendant to claim their internal data area.
-// Result is the offset from the begin of the node to the internal data area of the calling tree class.
-
-begin
-  Assert((FRoot = nil) or (FRoot.ChildCount = 0), 'Internal data allocation must be done before any node is created.');
-  {$ifdef DEBUG_VTV}Logger.Send('FTotalInternalDataSize BEFORE',FTotalInternalDataSize);{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send('Size',Size);{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send('TreeNodeSize',TreeNodeSize);{$endif}
-  Result := TreeNodeSize + FTotalInternalDataSize;
-  {$ifdef DEBUG_VTV}Logger.Send('Result',Result);{$endif}
-  Inc(FTotalInternalDataSize, (Size + 3) and not 3);
-  {$ifdef DEBUG_VTV}Logger.Send('FTotalInternalDataSize AFTER', FTotalInternalDataSize);{$endif}
-  InitRootNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.Animate(Steps, Duration: Cardinal; Callback: TVTAnimationCallback; Data: Pointer);
-
-// This method does the calculation part of an animation as used for node toggling and hint animations.
-// Steps is the maximum amount of animation steps to do and Duration determines the milliseconds the animation
-// has to run. Callback is a task specific method which is called in the loop for every step and Data is simply
-// something to pass on to the callback.
-// The callback is called with the current step, the current step size and the Data parameter. Since the step amount
-// as well as the step size are possibly adjusted during the animation, it is impossible to determine if the current
-// step is the last step, even if the original step amount is known. To solve this problem the callback will be
-// called after the loop has finished with a step size of 0 indicating so to execute any post processing.
-
-var
-  StepSize,
-  RemainingTime,
-  RemainingSteps,
-  NextTimeStep,
-  CurrentStep,
-  StartTime,
-  CurrentTime: Cardinal;
-
-begin
-  {$ifndef Windows}
-  //Is necessary to properly implement timeGetTime in non Windows
-  Exit;
-  {$endif}
-  if not (tsInAnimation in FStates) and (Duration > 0) then
-  begin
-    DoStateChange([tsInAnimation]);
-    try
-      RemainingTime := Duration;
-      RemainingSteps := Steps;
-
-      // Determine the initial step size which is either 1 if the needed steps are less than the number of
-      // steps possible given by the duration or > 1 otherwise.
-      StepSize := Round(Max(1, RemainingSteps / Duration));
-      RemainingSteps := RemainingSteps div StepSize;
-      CurrentStep := 0;
-
-      while (RemainingSteps > 0) and (RemainingTime > 0) and not Application.Terminated do
-      begin
-        StartTime := timeGetTime;
-        NextTimeStep := StartTime + RemainingTime div RemainingSteps;
-        if not Callback(CurrentStep, StepSize, Data) then
-          Break;
-
-        // Keep duration for this step for rest calculation.
-        CurrentTime := timeGetTime;
-        // Wait until the calculated time has been reached.
-        while CurrentTime < NextTimeStep do
-          CurrentTime := timeGetTime;
-
-        // Subtract the time this step really needed.
-        if RemainingTime >= CurrentTime - StartTime then
-        begin
-          Dec(RemainingTime, CurrentTime - StartTime);
-          Dec(RemainingSteps);
-        end
-        else
-        begin
-          RemainingTime := 0;
-          RemainingSteps := 0;
-        end;
-        // If the remaining time per step is less than one time step then we have to decrease the
-        // step count and increase the step size.
-        if (RemainingSteps > 0) and ((RemainingTime div RemainingSteps) < 1) then
-        begin
-          repeat
-            Inc(StepSize);
-            RemainingSteps := RemainingTime div StepSize;
-          until (RemainingSteps <= 0) or ((RemainingTime div RemainingSteps) >= 1);
-        end;
-        CurrentStep := Cardinal(Steps) - RemainingSteps;
-      end;
-
-      if not Application.Terminated then
-        Callback(0, 0, Data);
-    finally
-      DoStateChange([], [tsCancelHintAnimation, tsInAnimation]);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.BeginOperation;
-
-// Called to indicate that a long-running operation has been started.
-
-begin
-  Inc(FOperationCount);
-  if FOperationCount = 1 then
-    FOperationCanceled := False;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CalculateSelectionRect(X, Y: Integer): Boolean;
-
-// Recalculates old and new selection rectangle given that X, Y are new mouse coordinates.
-// Returns True if there was a change since the last call.
-
-var
-  MaxValue: Integer;
-
-begin
-  //lclheader
-  if hoVisible in FHeader.Options then
-    Dec(Y, FHeader.Height);
-  if tsDrawSelecting in FStates then
-    FLastSelRect := FNewSelRect;
-  FNewSelRect.BottomRight := Point(X + FEffectiveOffsetX, Y - FOffsetY);
-  if FNewSelRect.Right < 0 then
-    FNewSelRect.Right := 0;
-  if FNewSelRect.Bottom < 0 then
-    FNewSelRect.Bottom := 0;
-  MaxValue := ClientWidth;
-  if FRangeX > Cardinal(MaxValue) then
-    MaxValue := FRangeX;
-  if FNewSelRect.Right > MaxValue then
-    FNewSelRect.Right := MaxValue;
-  MaxValue := ClientHeight;
-  if FRangeY > Cardinal(MaxValue) then
-    MaxValue := FRangeY;
-  if FNewSelRect.Bottom > MaxValue then
-    FNewSelRect.Bottom := MaxValue;
-
-  Result := not CompareMem(@FLastSelRect, @FNewSelRect, SizeOf(FNewSelRect));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CanAutoScroll: Boolean;
-
-// Determines if auto scrolling is currently allowed.
-
-var
-  IsDropTarget: Boolean;
-  IsDrawSelecting: Boolean;
-  IsWheelPanning: Boolean;
-
-begin
-  // Don't scroll the client area if the header is currently doing tracking or dragging.
-  // Do auto scroll only if there is a draw selection in progress or the tree is the current drop target or
-  // wheel panning/scrolling is active.
-  IsDropTarget := Assigned(FDragManager) and VTVDragManager.IsDropTarget;
-  IsDrawSelecting := [tsDrawSelPending, tsDrawSelecting] * FStates <> [];
-  IsWheelPanning := [tsWheelPanning, tsWheelScrolling] * FStates <> [];
-  Result := ((toAutoScroll in FOptions.FAutoOptions) or IsWheelPanning) and
-    (FHeader.FStates = []) and (IsDrawSelecting or IsDropTarget or (tsVCLDragging in FStates) or IsWheelPanning);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CanShowDragImage: Boolean;
-
-// Determines whether a drag image should be shown.
-
-begin
-  Result := FDragImageKind <> diNoImage;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.Change(Node: PVirtualNode);
-
-begin
-  AdviseChangeEvent(False, Node, crIgnore);
-
-  if FUpdateCount = 0 then
-  begin
-    if (FChangeDelay > 0) and not (tsSynchMode in FStates) then
-      SetTimer(Handle, ChangeTimer, FChangeDelay, nil)
-    else
-      DoChange(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ChangeScale(M, D: Integer);
-
-var
-  DoScale: Boolean;
-
-begin
-  inherited;
-
-  if (M <> D) and (toAutoChangeScale in FOptions.FAutoOptions) then
-  begin
-    if (csLoading in ComponentState) then
-      DoScale := tsNeedScale in FStates
-    else
-      DoScale := True;
-    if DoScale then
-    begin
-      FDefaultNodeHeight := MulDiv(FDefaultNodeHeight, M, D);
-      FHeader.ChangeScale(M, D);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CheckParentCheckState(Node: PVirtualNode; NewCheckState: TCheckState): Boolean;
-
-// Checks all siblings of node to determine which check state Node's parent must get.
-
-var
-  CheckCount,
-  BoxCount: Cardinal;
-  PartialCheck: Boolean;
-  Run: PVirtualNode;
-
-begin
-  CheckCount := 0;
-  BoxCount := 0;
-  PartialCheck := False;
-  Run := Node.Parent.FirstChild;
-  while Assigned(Run) do
-  begin
-    if Run = Node then
-    begin
-      // The given node cannot be checked because it does not yet have its new check state (as this depends
-      // on the outcome of this method). Instead NewCheckState is used as this contains the new state the node
-      // will get if this method returns True.
-      if Run.CheckType in [ctCheckBox, ctTriStateCheckBox] then
-      begin
-        Inc(BoxCount);
-        if NewCheckState in [csCheckedNormal, csCheckedPressed] then
-          Inc(CheckCount);
-        PartialCheck := PartialCheck or (NewCheckState = csMixedNormal);
-      end;
-    end
-    else
-      if Run.CheckType in [ctCheckBox, ctTriStateCheckBox] then
-      begin
-        Inc(BoxCount);
-        if Run.CheckState in [csCheckedNormal, csCheckedPressed] then
-          Inc(CheckCount);
-        PartialCheck := PartialCheck or (Run.CheckState = csMixedNormal);
-      end;
-    Run := Run.NextSibling;
-  end;
-
-  if (CheckCount = 0) and not PartialCheck then
-    NewCheckState := csUncheckedNormal
-  else
-    if CheckCount < BoxCount then
-      NewCheckState := csMixedNormal
-    else
-      NewCheckState := csCheckedNormal;
-
-  Node := Node.Parent;
-  Result := DoChecking(Node, NewCheckState);
-  if Result then
-  begin
-    DoCheckClick(Node, NewCheckState);
-    // Recursively adjust parent of parent.
-    with Node^ do
-    begin
-      if not (vsInitialized in Parent.States) then
-        InitNode(Parent);
-      if ([vsChecking, vsDisabled] * Parent.States = []) and (Parent <> FRoot) and
-        (Parent.CheckType = ctTriStateCheckBox) then
-        Result := CheckParentCheckState(Node, NewCheckState);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ClearTempCache;
-
-// make sure the temporary node cache is in a reliable state
-
-begin
-  FTempNodeCache := nil;
-  FTempNodeCount := 0;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean;
-
-// Returns True if the given column is to be considered as being empty. This will usually be determined by
-// descendants as the base tree implementation has not enough information to decide.
-
-begin
-  Result := True;
-  if Assigned(FOnGetCellIsEmpty) then
-    FOnGetCellIsEmpty(Self, Node, Column, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ComputeRTLOffset(ExcludeScrollbar: Boolean): Integer;
-
-// Computes the horizontal offset needed when all columns are automatically right aligned (in RTL bidi mode).
-// ExcludeScrollbar determines if the left-hand vertical scrollbar is to be included (if visible) or not.
-
-var
-  HeaderWidth: Integer;
-  ScrollbarVisible: Boolean;
-begin
-  ScrollbarVisible := (Integer(FRangeY) > ClientHeight) and (ScrollbarOptions.Scrollbars in [ssVertical, ssBoth]);
-  if ScrollbarVisible then
-    Result := GetSystemMetrics(SM_CXVSCROLL)
-  else
-    Result := 0;
-
-  // Make everything right aligned.
-  HeaderWidth := FHeaderRect.Right - FHeaderRect.Left;
-  if Integer(FRangeX) + Result <= HeaderWidth then
-    Result := HeaderWidth - Integer(FRangeX);
-  // Otherwise take only left-hand vertical scrollbar into account.
-
-  if ScrollbarVisible and ExcludeScrollbar then
-    Dec(Result, GetSystemMetrics(SM_CXVSCROLL));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CountLevelDifference(Node1, Node2: PVirtualNode): Integer;
-
-// This method counts how many indentation levels the given nodes are apart. If both nodes have the same parent then the
-// difference is 0 otherwise the result is basically GetNodeLevel(Node2) - GetNodeLevel(Node1), but with sign.
-// If the result is negative then Node2 is less intended than Node1.
-
-var
-  Level1, Level2: Integer;
-
-begin
-  Assert(Assigned(Node1) and Assigned(Node2), 'Both nodes must be Assigned.');
-
-  Level1 := 0;
-  while Node1.Parent <> FRoot do
-  begin
-    Inc(Level1);
-    Node1 := Node1.Parent;
-  end;
-
-  Level2 := 0;
-  while Node2.Parent <> FRoot do
-  begin
-    Inc(Level2);
-    Node2 := Node2.Parent;
-  end;
-
-  Result := Level2 - Level1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CountVisibleChildren(Node: PVirtualNode): Cardinal;
-
-// Returns the number of visible child nodes of the given node.
-
-begin
-  Result := 0;
-
-  // The node's direct children...
-  if vsExpanded in Node.States then
-  begin
-    // ...and their children.
-    Node := Node.FirstChild;
-    while Assigned(Node) do
-    begin
-      if vsVisible in Node.States then
-        Inc(Result, CountVisibleChildren(Node) + 1);
-      Node := Node.NextSibling;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CreateParams(var Params: TCreateParams);
-
-const
-  ScrollBar: array[TScrollStyle] of Cardinal = (0, WS_HSCROLL, WS_VSCROLL, WS_HSCROLL or WS_VSCROLL,
-    0,0,0);
-
-begin
-  //todo_lcl
-
-  inherited CreateParams(Params);
-
-  with Params do
-  begin
-    Style := Style or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or ScrollBar[ScrollBarOptions.FScrollBars];
-    if toFullRepaintOnResize in FOptions.FMiscOptions then
-      WindowClass.style := WindowClass.style or CS_HREDRAW or CS_VREDRAW
-    else
-      WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
-    //lcl: Ctl3D is not used in LCL. Has the same meaning of BorderStyle = bsSingle
-    {
-    if BorderStyle = bsSingle then
-    begin
-      if Ctl3D then
-      begin
-        ExStyle := ExStyle or WS_EX_CLIENTEDGE;
-        Style := Style and not WS_BORDER;
-      end
-      else
-        Style := Style or WS_BORDER;
-    end
-    else
-      Style := Style and not WS_BORDER;
-    }
-    //todo_lcl_low
-    //AddBiDiModeExStyle(ExStyle);
-  end;
-
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CreateWnd;
-
-// Initializes data which depends on a valid window handle.
-
-begin
-  DoStateChange([tsWindowCreating]);
-  inherited;
-  {$ifdef DEBUG_VTV}Logger.Send([lcInfo],'Handle (CreateWnd)',Handle);{$endif}
-  DoStateChange([], [tsWindowCreating]);
-
-  {$ifdef ThemeSupport}
-    if ThemeServices.ThemesEnabled and (toThemeAware in TreeOptions.PaintOptions) then
-    begin
-      DoStateChange([tsUseThemes]);
-      //todo
-      //if (toUseExplorerTheme in FOptions.FPaintOptions) and IsWinVistaOrAbove then
-      //  SetWindowTheme(Handle, 'explorer', nil);
-    end
-    else
-  {$endif ThemeSupport}
-    DoStateChange([], [tsUseThemes]);
-
-  // Because of the special recursion and update stopper when creating the window (or resizing it)
-  // we have to manually trigger the auto size calculation here.
-  if hsNeedScaling in FHeader.FStates then
-    FHeader.RescaleHeader;
-  //lcl: Call with Force argument to true since AdjustAutoSize is not called in Loaded
-  if hoAutoResize in FHeader.FOptions then
-    FHeader.FColumns.AdjustAutoSize(InvalidColumn, True);
-
-  // Initialize flat scroll bar library if required.
-  {$ifdef UseFlatScrollbars}
-    if FScrollBarOptions.FScrollBarStyle <> sbmRegular then
-    begin
-      InitializeFlatSB(Handle);
-      FlatSB_SetScrollProp(Handle, WSB_PROP_HSTYLE, ScrollBarProp[FScrollBarOptions.ScrollBarStyle], False);
-      FlatSB_SetScrollProp(Handle, WSB_PROP_VSTYLE, ScrollBarProp[FScrollBarOptions.ScrollBarStyle], False);
-    end;
-  {$endif UseFlatScrollbars}
-
-  PrepareBitmaps(True, True);
-
-  {$ifdef Windows}
-  // Register tree as OLE drop target.
-  if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.FMiscOptions) then
-     RegisterDragDrop(Handle, VTVDragManager as IDropTarget);
-  {$endif}
-
-  if toCheckSupport in FOptions.FMiscOptions then
-    CheckImageListNeeded;
-  UpdateScrollBars(True);
-  UpdateHeaderRect;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DestroyHandle;
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcMessages],'DestroyHandle');{$endif}
-  //lcl: this code was  originally called is response to WM_NCDESTROY
-  //  see if there will be issues calling here
-  InterruptValidation;
-
-  KillTimer(Handle, ChangeTimer);
-  KillTimer(Handle, StructureChangeTimer);
-
-  {$ifdef Windows}
-  if not (csDesigning in ComponentState) and (toAcceptOLEDrop in FOptions.FMiscOptions) then
-    RevokeDragDrop(Handle);
-  {$endif}
-
-  // Clean up other stuff.
-  DeleteObject(FDottedBrush);
-  FDottedBrush := 0;
-
-  CancelEditNode;
-  inherited;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcMessages],'DestroyHandle');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DetermineHiddenChildrenFlag(Node: PVirtualNode);
-
-// Update the hidden children flag of the given node.
-
-var
-  Run: PVirtualNode;
-
-begin
-  if Node.ChildCount = 0 then
-  begin
-    if vsHasChildren in Node.States then
-      Exclude(Node.States, vsAllChildrenHidden)
-    else
-      Include(Node.States, vsAllChildrenHidden);
-  end
-  else
-  begin
-    // Iterate through all siblings and stop when one visible is found.
-    Run := Node.FirstChild;
-    while Assigned(Run) do
-      Run := Run.NextSibling;
-    if Assigned(Run) then
-      Exclude(Node.States, vsAllChildrenHidden)
-    else
-      Include(Node.States, vsAllChildrenHidden);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DetermineHiddenChildrenFlagAllNodes;
-
-var
-  Run: PVirtualNode;
-
-begin
-  Run := GetFirstNoInit(False);
-  while Assigned(Run) do
-  begin
-    DetermineHiddenChildrenFlag(Run);
-    Run := GetNextNoInit(Run);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DetermineHitPositionLTR(var HitInfo: THitInfo; Offset, Right: Integer;
-  Alignment: TAlignment);
-
-// This method determines the hit position within a node with left-to-right orientation.
-
-var
-  MainColumnHit: Boolean;
-  Run: PVirtualNode;
-  Indent,
-  TextWidth,
-  ImageOffset: Integer;
-
-begin
-  MainColumnHit := HitInfo.HitColumn = FHeader.MainColumn;
-  Indent := 0;
-
-  // If columns are not used or the main column is hit then the tree indentation must be considered too.
-  if MainColumnHit then
-  begin
-    if toFixedIndent in FOptions.FPaintOptions then
-      Indent := FIndent
-    else
-    begin
-    Run := HitInfo.HitNode;
-    while (Run.Parent <> FRoot) do
-    begin
-      Inc(Indent, FIndent);
-      Run := Run.Parent;
-    end;
-    if toShowRoot in FOptions.FPaintOptions then
-      Inc(Indent, FIndent);
-  end;
-  end;
-
-  if Offset < Indent then
-  begin
-    // Position is to the left of calculated indentation which can only happen for the main column.
-    // Check whether it corresponds to a button/checkbox.
-    if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in HitInfo.HitNode.States) then
-    begin
-      // Position of button is interpreted very generously to avoid forcing the user
-      // to click exactly into the 9x9 pixels area. The entire node height and one full
-      // indentation level is accepted as button hit.
-      if Offset >= Indent - Integer(FIndent) then
-        Include(HitInfo.HitPositions, hiOnItemButton);
-      if Offset >= Indent - FPlusBM.Width then
-        Include(HitInfo.HitPositions, hiOnItemButtonExact);
-    end;
-    // no button hit so position is on indent
-    if HitInfo.HitPositions = [] then
-      Include(HitInfo.HitPositions, hiOnItemIndent);
-  end
-  else
-  begin
-    // The next hit positions can be:
-    //   - on the check box
-    //   - on the state image
-    //   - on the normal image
-    //   - to the left of the text area
-    //   - on the label or
-    //   - to the right of the text area
-    // (in this order).
-
-    // In report mode no hit other than in the main column is possible.
-    if MainColumnHit or not (toReportMode in FOptions.FMiscOptions) then
-    begin
-      ImageOffset := Indent +  FMargin;
-
-      // Check support is only available for the main column.
-      if MainColumnHit and (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and
-        (HitInfo.HitNode.CheckType <> ctNone) then
-        Inc(ImageOffset, FCheckImages.Height + 2);
-
-      if MainColumnHit and (Offset < ImageOffset) then
-      begin
-        HitInfo.HitPositions := [hiOnItem];
-        if (HitInfo.HitNode.CheckType <> ctNone) then
-          Include(HitInfo.HitPositions, hiOnItemCheckBox);
-      end
-      else
-      begin
-        if Assigned(FStateImages) and HasImage(HitInfo.HitNode, ikState, HitInfo.HitColumn) then
-          Inc(ImageOffset, FStateImages.Width + 2);
-        if Offset < ImageOffset then
-          Include(HitInfo.HitPositions, hiOnStateIcon)
-        else
-        begin
-          if Assigned(FImages) and HasImage(HitInfo.HitNode, ikNormal, HitInfo.HitColumn) then
-            Inc(ImageOffset, FImages.Width + 2);
-          if Offset < ImageOffset then
-            Include(HitInfo.HitPositions, hiOnNormalIcon)
-          else
-          begin
-            // ImageOffset contains now the left border of the node label area. This is used to calculate the
-            // correct alignment in the column.
-            TextWidth := DoGetNodeWidth(HitInfo.HitNode, HitInfo.HitColumn);
-
-            // Check if the text can be aligned at all. This is only possible if there is enough room
-            // in the remaining text rectangle.
-            if TextWidth > Right - ImageOffset then
-              Include(HitInfo.HitPositions, hiOnItemLabel)
-            else
-            begin
-              case Alignment of
-                taCenter:
-                  begin
-                    Indent := (ImageOffset + Right - TextWidth) div 2;
-                    if Offset < Indent then
-                      Include(HitInfo.HitPositions, hiOnItemLeft)
-                    else
-                      if Offset < Indent + TextWidth then
-                        Include(HitInfo.HitPositions, hiOnItemLabel)
-                      else
-                        Include(HitInfo.HitPositions, hiOnItemRight)
-                  end;
-                taRightJustify:
-                  begin
-                    Indent := Right - TextWidth;
-                    if Offset < Indent then
-                      Include(HitInfo.HitPositions, hiOnItemLeft)
-                    else
-                      Include(HitInfo.HitPositions, hiOnItemLabel);
-                  end;
-              else // taLeftJustify
-                if Offset < ImageOffset + TextWidth then
-                  Include(HitInfo.HitPositions, hiOnItemLabel)
-                else
-                  Include(HitInfo.HitPositions, hiOnItemRight);
-              end;
-            end;
-          end;
-        end;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DetermineHitPositionRTL(var HitInfo: THitInfo; Offset, Right: Integer; Alignment: TAlignment);
-
-// This method determines the hit position within a node with right-to-left orientation.
-
-var
-  MainColumnHit: Boolean;
-  Run: PVirtualNode;
-  Indent,
-  TextWidth,
-  ImageOffset: Integer;
-
-begin
-  MainColumnHit := HitInfo.HitColumn = FHeader.MainColumn;
-
-  // If columns are not used or the main column is hit then the tree indentation must be considered too.
-  if MainColumnHit then
-  begin
-    if toFixedIndent in FOptions.FPaintOptions then
-      Dec(Right, FIndent)
-    else
-    begin
-    Run := HitInfo.HitNode;
-    while (Run.Parent <> FRoot) do
-    begin
-      Dec(Right, FIndent);
-      Run := Run.Parent;
-    end;
-    if toShowRoot in FOptions.FPaintOptions then
-      Dec(Right, FIndent);
-  end;
-  end;
-
-  if Offset >= Right then
-  begin
-    // Position is to the right of calculated indentation which can only happen for the main column.
-    // Check whether it corresponds to a button/checkbox.
-    if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in HitInfo.HitNode.States) then
-    begin
-      // Position of button is interpreted very generously to avoid forcing the user
-      // to click exactly into the 9x9 pixels area. The entire node height and one full
-      // indentation level is accepted as button hit.
-      if Offset <= Right + Integer(FIndent) then
-        Include(HitInfo.HitPositions, hiOnItemButton);
-      if Offset <= Right + FPlusBM.Width then
-        Include(HitInfo.HitPositions, hiOnItemButtonExact);
-    end;
-    // no button hit so position is on indent
-    if HitInfo.HitPositions = [] then
-      Include(HitInfo.HitPositions, hiOnItemIndent);
-  end
-  else
-  begin
-    // The next hit positions can be:
-    //   - on the check box
-    //   - on the state image
-    //   - on the normal image
-    //   - to the left of the text area
-    //   - on the label or
-    //   - to the right of the text area
-    // (in this order).
-
-    // In report mode no hit other than in the main column is possible.
-    if MainColumnHit or not (toReportMode in FOptions.FMiscOptions) then
-    begin
-      ImageOffset := Right - FMargin;
-
-      // Check support is only available for the main column.
-      if MainColumnHit and (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and
-        (HitInfo.HitNode.CheckType <> ctNone) then
-        Dec(ImageOffset, FCheckImages.Height + 2);
-
-      if MainColumnHit and (Offset > ImageOffset) then
-      begin
-        HitInfo.HitPositions := [hiOnItem];
-        if (HitInfo.HitNode.CheckType <> ctNone) then
-          Include(HitInfo.HitPositions, hiOnItemCheckBox);
-      end
-      else
-      begin
-        if Assigned(FStateImages) and HasImage(HitInfo.HitNode, ikState, HitInfo.HitColumn) then
-          Dec(ImageOffset, FStateImages.Width + 2);
-        if Offset > ImageOffset then
-          Include(HitInfo.HitPositions, hiOnStateIcon)
-        else
-        begin
-          if Assigned(FImages) and HasImage(HitInfo.HitNode, ikNormal, HitInfo.HitColumn) then
-            Dec(ImageOffset, FImages.Width + 2);
-          if Offset > ImageOffset then
-            Include(HitInfo.HitPositions, hiOnNormalIcon)
-          else
-          begin
-            // ImageOffset contains now the right border of the node label area. This is used to calculate the
-            // correct alignment in the column.
-            TextWidth := DoGetNodeWidth(HitInfo.HitNode, HitInfo.HitColumn);
-
-            // Check if the text can be aligned at all. This is only possible if there is enough room
-            // in the remaining text rectangle.
-            if TextWidth > ImageOffset then
-              Include(HitInfo.HitPositions, hiOnItemLabel)
-            else
-            begin
-              // Consider bidi mode here. In RTL context does left alignment actually mean right alignment
-              // and vice versa.
-              ChangeBiDiModeAlignment(Alignment);
-
-              case Alignment of
-                taCenter:
-                  begin
-                    Indent := (ImageOffset - TextWidth) div 2;
-                    if Offset < Indent then
-                      Include(HitInfo.HitPositions, hiOnItemLeft)
-                    else
-                      if Offset < Indent + TextWidth then
-                        Include(HitInfo.HitPositions, hiOnItemLabel)
-                      else
-                        Include(HitInfo.HitPositions, hiOnItemRight)
-                  end;
-                taRightJustify:
-                  begin
-                    Indent := ImageOffset - TextWidth;
-                    if Offset < Indent then
-                      Include(HitInfo.HitPositions, hiOnItemLeft)
-                    else
-                      Include(HitInfo.HitPositions, hiOnItemLabel);
-                  end;
-              else // taLeftJustify
-                if Offset > TextWidth then
-                  Include(HitInfo.HitPositions, hiOnItemRight)
-                else
-                  Include(HitInfo.HitPositions, hiOnItemLabel);
-              end;
-            end;
-          end;
-        end;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DetermineNextCheckState(CheckType: TCheckType; CheckState: TCheckState): TCheckState;
-
-// Determines the next check state in case the user click the check image or pressed the space key.
-
-begin
-  case CheckType of
-    ctTriStateCheckBox,
-    ctCheckBox:
-      if CheckState = csCheckedNormal then
-        Result := csUncheckedNormal
-      else
-        Result := csCheckedNormal;
-    ctRadioButton:
-      Result := csCheckedNormal;
-    ctButton:
-      Result := csUncheckedNormal;
-  else
-    Result := csMixedNormal;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DetermineScrollDirections(X, Y: Integer): TScrollDirections;
-
-// Determines which direction the client area must be scrolled depending on the given position.
-
-begin
-  Result:= [];
-
-  if CanAutoScroll then
-  begin
-    // Calculation for wheel panning/scrolling is a bit different to normal auto scroll.
-    if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then
-    begin
-      if (X - FLastClickPos.X) < -8 then
-        Include(Result, sdLeft);
-      if (X - FLastClickPos.X) > 8 then
-        Include(Result, sdRight);
-
-      if (Y - FLastClickPos.Y) < -8 then
-        Include(Result, sdUp);
-      if (Y - FLastClickPos.Y) > 8 then
-        Include(Result, sdDown);
-    end
-    else
-    begin
-      if (X < Integer(FDefaultNodeHeight)) and (FEffectiveOffsetX <> 0) then
-        Include(Result, sdLeft);
-      if (ClientWidth + FEffectiveOffsetX < Integer(FRangeX)) and (X > ClientWidth - Integer(FDefaultNodeHeight)) then
-        Include(Result, sdRight);
-      //lclheader
-      if (ClientHeight - FOffsetY < Integer(FRangeY)) and (Y > inherited GetClientRect.Bottom - Integer(FDefaultNodeHeight)) then
-        Include(Result, sdDown);
-      if hoVisible in FHeader.FOptions then
-        Dec(Y, FHeader.Height);
-
-      if (Y < Integer(FDefaultNodeHeight)) and (FOffsetY <> 0) then
-        Include(Result, sdUp);
-
-      //todo: probably the code below is bug due to poor timeGetTime implementation
-      // 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.
-      if (Result <> []) and
-        ((Assigned(FDragManager) and VTVDragManager.IsDropTarget) or
-        (FindDragTarget(Point(X, Y), False) = Self)) then
-      begin
-        if FDragScrollStart = 0 then
-          FDragScrollStart := timeGetTime;
-        // Reset any scroll direction to avoid scroll in the case the user is dragging and the auto scroll time has not
-        // yet elapsed.
-        if ((timeGetTime - FDragScrollStart) < FAutoScrollDelay) then
-          Result := [];
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoAdvancedHeaderDraw(var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements);
-
-begin
-  if Assigned(FOnAdvancedHeaderDraw) then
-    FOnAdvancedHeaderDraw(FHeader, PaintInfo, Elements);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoAfterCellPaint(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const CellRect: TRect);
-
-begin
-  if Assigned(FOnAfterCellPaint) then
-    FOnAfterCellPaint(Self, Canvas, Node, Column, CellRect);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoAfterItemErase(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect);
-
-begin
-  if Assigned(FOnAfterItemErase) then
-    FOnAfterItemErase(Self, Canvas, Node, ItemRect);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoAfterItemPaint(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect);
-
-begin
-  if Assigned(FOnAfterItemPaint) then
-    FOnAfterItemPaint(Self, Canvas, Node, ItemRect);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoAfterPaint(Canvas: TCanvas);
-
-begin
-  if Assigned(FOnAfterPaint) then
-    FOnAfterPaint(Self, Canvas);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoAutoScroll(X, Y: Integer);
-
-begin
-  FScrollDirections := DetermineScrollDirections(X, Y);
-
-  if FStates * [tsWheelPanning, tsWheelScrolling] = [] then
-  begin
-    if FScrollDirections = [] then
-    begin
-      if ((FStates * [tsScrollPending, tsScrolling]) <> []) then
-      begin
-        KillTimer(Handle, ScrollTimer);
-        DoStateChange([], [tsScrollPending, tsScrolling]);
-      end;
-    end
-    else
-    begin
-      // start auto scroll if not yet done
-      if (FStates * [tsScrollPending, tsScrolling]) = [] then
-      begin
-        DoStateChange([tsScrollPending]);
-        SetTimer(Handle, ScrollTimer, FAutoScrollDelay, nil);
-      end;
-    end;
-  end;
-end;
-
-
-procedure TBaseVirtualTree.DoAutoSize;
-begin
-  //The default DoAutoSize makes the editors be placed wrongly when scrolling
-end;
-
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoBeforeDrag(Node: PVirtualNode; Column: TColumnIndex): Boolean;
-
-begin
-  Result := False;
-  if Assigned(FOnDragAllowed) then
-    FOnDragAllowed(Self, Node, Column, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoBeforeCellPaint(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
-  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
-
-{$ifdef LCLWin32}
-var
-  UpdateRect: TRect;
-{$endif}
-
-begin
-  //todo: implement under non win32
-  if Assigned(FOnBeforeCellPaint) then
-  begin
-    {$ifdef LCLWin32}
-    if CellPaintMode = cpmGetContentMargin then
-    begin
-      // Prevent drawing if we are only about to get the margin. As this also clears the update rect we need to save it.
-      GetUpdateRect(Handle, UpdateRect, False);
-      SetUpdateState(True);
-    end;
-    {$endif}
-
-    FOnBeforeCellPaint(Self, Canvas, Node, Column, CellPaintMode, CellRect, ContentRect);
-
-    {$ifdef LCLWin32}
-    if CellPaintMode = cpmGetContentMargin then
-    begin
-      SetUpdateState(False);
-      InvalidateRect(Handle, @UpdateRect, False);
-    end;
-    {$endif}
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoBeforeItemErase(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect; var Color: TColor;
-  var EraseAction: TItemEraseAction);
-
-begin
-  if Assigned(FOnBeforeItemErase) then
-    FOnBeforeItemErase(Self, Canvas, Node, ItemRect, Color, EraseAction);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoBeforeItemPaint(Canvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect): Boolean;
-
-begin
-  // By default custom draw will not be used, so the tree handles drawing the node.
-  Result := False;
-  if Assigned(FOnBeforeItemPaint) then
-    FOnBeforeItemPaint(Self, Canvas, Node, ItemRect, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoBeforePaint(Canvas: TCanvas);
-
-begin
-  if Assigned(FOnBeforePaint) then
-    FOnBeforePaint(Self, Canvas);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoCancelEdit: Boolean;
-
-// Called when the current edit action or a pending edit must be cancelled.
-
-begin
-  KillTimer(Handle, EditTimer);
-  DoStateChange([], [tsEditPending]);
-  Result := (tsEditing in FStates) and FEditLink.CancelEdit;
-  if Result then
-  begin
-    DoStateChange([], [tsEditing]);
-    if Assigned(FOnEditCancelled) then
-      FOnEditCancelled(Self, FEditColumn);
-    FEditLink := nil;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoCanEdit(Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
-
-begin
-  if Assigned(FOnEditing) then
-    FOnEditing(Self, Node, Column, Allowed);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoChange(Node: PVirtualNode);
-
-begin
-  KillTimer(Handle, ChangeTimer);
-  if Assigned(FOnChange) then
-    FOnChange(Self, Node);
-
-  // This is a good place to reset the cached node. This is the same as the node passed in here.
-  // This is necessary to allow descendants to override this method and get the node then.
-  DoStateChange([], [tsChangePending]);
-  FLastChangedNode := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoCheckClick(Node: PVirtualNode; NewCheckState: TCheckState);
-
-begin
-  if ChangeCheckState(Node, NewCheckState) then
-    DoChecked(Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoChecked(Node: PVirtualNode);
-
-begin
-  if Assigned(FOnChecked) then
-    FOnChecked(Self, Node);
-
-  {$ifdef EnableAccessible}
-  NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF);
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoChecking(Node: PVirtualNode; var NewCheckState: TCheckState): Boolean;
-
-// Determines if a node is allowed to change its check state to NewCheckState.
-
-begin
-  if toReadOnly in FOptions.FMiscOptions then
-    Result := False
-  else
-  begin
-    Result := True;
-    if Assigned(FOnChecking) then
-      FOnChecking(Self, Node, NewCheckState, Result);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoCollapsed(Node: PVirtualNode);
-
-begin
-  if Assigned(FOnCollapsed) then
-    FOnCollapsed(Self, Node);
-  {$ifdef EnableAccessible}
-  NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF);
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoCollapsing(Node: PVirtualNode): Boolean;
-
-begin
-  Result := True;
-  if Assigned(FOnCollapsing) then
-    FOnCollapsing(Self, Node, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoColumnClick(Column: TColumnIndex; Shift: TShiftState);
-
-begin
-  if Assigned(FOnColumnClick) then
-    FOnColumnClick(Self, Column, Shift);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoColumnDblClick(Column: TColumnIndex; Shift: TShiftState);
-
-begin
-  if Assigned(FOnColumnDblClick) then
-    FOnColumnDblClick(Self, Column, Shift);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoColumnResize(Column: TColumnIndex);
-
-var
-  R: TRect;
-  Run: PVirtualNode;
-
-begin
-  if not (csLoading in ComponentState) and HandleAllocated then
-  begin
-    // Reset all vsHeightMeasured flags if we are in multiline mode.
-    Run := GetFirstInitialized;
-    while Assigned(Run) do
-    begin
-      if vsMultiline in Run.States then
-        Exclude(Run.States, vsHeightMeasured);
-      Run := GetNextInitialized(Run);
-    end;
-
-    UpdateHorizontalScrollBar(True);
-    if Column > NoColumn then
-    begin
-      // Invalidate client area from the current column all to the right (or left in RTL mode).
-      R := ClientRect;
-      //lclheader
-      if hoVisible in FHeader.FOptions then
-        Inc(R.Bottom, FHeader.Height);
-      if not (toAutoSpanColumns in FOptions.FAutoOptions) then
-        if UseRightToLeftAlignment then
-          R.Right := FHeader.Columns[Column].Left + FHeader.Columns[Column].Width + ComputeRTLOffset
-        else
-          R.Left := FHeader.Columns[Column].Left;
-      InvalidateRect(Handle, @R, False);
-      FHeader.Invalidate(FHeader.Columns[Column], True);
-    end;
-    if [hsColumnWidthTracking, hsResizing] * FHeader.States = [hsColumnWidthTracking] then
-      UpdateWindow(Handle);
-
-    if not (tsUpdating in FStates) then
-      UpdateDesigner; // design time only
-
-    if Assigned(FOnColumnResize) and not (hsResizing in FHeader.States) then
-      FOnColumnResize(FHeader, Column);
-
-    // If the tree is currently in edit state then notify edit link.
-    if tsEditing in FStates then
-      UpdateEditBounds;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoCompare(Node1, Node2: PVirtualNode; Column: TColumnIndex): Integer;
-
-begin
-  Result := 0;
-  if Assigned(FOnCompareNodes) then
-    FOnCompareNodes(Self, Node1, Node2, Column, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoCreateDataObject: IDataObject;
-
-begin
-  Result := nil;
-  if Assigned(FOnCreateDataObject) then
-    FOnCreateDataObject(Self, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoCreateDragManager: IVTDragManager;
-
-begin
-  Result := nil;
-  if Assigned(FOnCreateDragManager) then
-    FOnCreateDragManager(Self, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoCreateEditor(Node: PVirtualNode; Column: TColumnIndex): IVTEditLink;
-
-begin
-  Result := nil;
-  if Assigned(FOnCreateEditor) then
-  begin
-    FOnCreateEditor(Self, Node, Column, Result);
-    if Result = nil then
-      ShowError(SEditLinkIsNil, hcTFEditLinkIsNil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoDragging(P: TPoint);
-
-// Initiates finally the drag'n drop operation and returns after DD is finished.
-
-  //--------------- local function --------------------------------------------
-
-  function GetDragOperations: LongWord;
-
-  begin
-    if FDragOperations = [] then
-      Result := DROPEFFECT_COPY or DROPEFFECT_MOVE or DROPEFFECT_LINK
-    else
-    begin
-      Result := 0;
-      if doCopy in FDragOperations then
-        Result := Result or DROPEFFECT_COPY;
-      if doLink in FDragOperations then
-        Result := Result or DROPEFFECT_LINK;
-      if doMove in FDragOperations then
-        Result := Result or DROPEFFECT_MOVE;
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-var
-  DragEffect, AllowedEffects: LongWord;
-  I: Integer;
-  DragObject: TDragObject;
-
-  DataObject: IDataObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DoDragging');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcDrag],'Stack');{$endif}
-  DataObject := nil;
-  // Dragging is dragging, nothing else.
-  DoCancelEdit;
-
-  if Assigned(FCurrentHotNode) then
-  begin
-    InvalidateNode(FCurrentHotNode);
-    FCurrentHotNode := nil;
-  end;
-  // Select the focused node if not already done.
-  if Assigned(FFocusedNode) and not (vsSelected in FFocusedNode.States) then
-  begin
-    InternalAddToSelection(FFocusedNode, False);
-    InvalidateNode(FFocusedNode);
-  end;
-
-  UpdateWindow(Handle);
-
-  // Keep a list of all currently selected nodes as this list might change,
-  // but we have probably to delete currently selected nodes.
-  FDragSelection := GetSortedSelection(True);
-  try
-    DoStateChange([tsOLEDragging], [tsOLEDragPending, tsClearPending]);
-
-    // An application might create a drag object like used during VCL dd. This is not required for OLE dd but
-    // required as parameter.
-    DragObject := nil;
-    DoStartDrag(DragObject);
-    DragObject.Free;
-
-    DataObject := VTVDragManager.DataObject;
-    PrepareDragImage(P, DataObject);
-
-    FLastDropMode := dmOnNode;
-    // Don't forget to initialize the result. It might never be touched.
-    DragEffect := DROPEFFECT_NONE;
-    AllowedEffects := GetDragOperations;
-    try
-      DragAndDrop(AllowedEffects, DataObject, DragEffect);
-      VTVDragManager.ForceDragLeave;
-    finally
-      GetCursorPos(P);
-      P := ScreenToClient(P);
-      DoEndDrag(Self, P.X, P.Y);
-
-      FDragImage.EndDrag;
-
-      // Finish the operation.
-      if (DragEffect = DROPEFFECT_MOVE) and (toAutoDeleteMovedNodes in TreeOptions.AutoOptions) then
-      begin
-        // The operation was a move so delete the previously selected nodes.
-        BeginUpdate;
-        try
-          // The list of selected nodes was retrieved in resolved state. That means there can never be a node
-          // in the list whose parent (or its parent etc.) is also selected.
-          for I := 0 to High(FDragSelection) do
-            DeleteNode(FDragSelection[I]);
-        finally
-          EndUpdate;
-        end;
-      end;
-
-      DoStateChange([], [tsOLEDragging]);
-    end;
-  finally
-    FDragSelection := nil;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DoDragging');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoDragExpand;
-
-var
-  SourceTree: TBaseVirtualTree;
-
-begin
-  KillTimer(Handle, ExpandTimer);
-  if Assigned(FDropTargetNode) and (vsHasChildren in FDropTargetNode.States) and
-    not (vsExpanded in FDropTargetNode.States) then
-  begin
-    if Assigned(FDragManager) then
-      SourceTree := TBaseVirtualTree(VTVDragManager.DragSource)
-    else
-      SourceTree := nil;
-
-    if not VTVDragManager.DropTargetHelperSupported and Assigned(SourceTree) then
-      SourceTree.FDragImage.HideDragImage;
-    ToggleNode(FDropTargetNode);
-    UpdateWindow(Handle);
-    if not VTVDragManager.DropTargetHelperSupported and Assigned(SourceTree) then
-      SourceTree.FDragImage.ShowDragImage;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoDragOver(Source: TObject; Shift: TShiftState; State: TDragState; const Pt: TPoint; Mode: TDropMode;
-  var Effect: LongWord): Boolean;
-
-begin
-  Result := False;
-  if Assigned(FOnDragOver) then
-    FOnDragOver(Self, Source, Shift, State, Pt, Mode, Effect, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoDragDrop(Source: TObject; DataObject: IDataObject; Formats: TFormatArray;
-  Shift: TShiftState; const Pt: TPoint; var Effect: LongWord; Mode: TDropMode);
-
-begin
-  if Assigned(FOnDragDrop) then
-    FOnDragDrop(Self, Source, {DataObject, }Formats, Shift, Pt, Effect, Mode);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoEdit;
-
-begin
-  Application.CancelHint;
-  KillTimer(Handle, ScrollTimer);
-  KillTimer(Handle, EditTimer);
-  DoStateChange([], [tsEditPending]);
-  if Assigned(FFocusedNode) and not (vsDisabled in FFocusedNode.States) and
-    not (toReadOnly in FOptions.FMiscOptions) and (FEditLink = nil) then
-  begin
-    FEditLink := DoCreateEditor(FFocusedNode, FEditColumn);
-    if Assigned(FEditLink) then
-    begin
-      DoStateChange([tsEditing], [tsDrawSelecting, tsDrawSelPending, tsToggleFocusedSelection, tsOLEDragPending,
-        tsOLEDragging, tsClearPending, tsScrollPending, tsScrolling, tsMouseCheckPending]);
-      ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions,
-        not (toDisableAutoscrollOnEdit in FOptions.AutoOptions));
-      if FEditLink.PrepareEdit(Self, FFocusedNode, FEditColumn) then
-      begin
-        UpdateEditBounds;
-        // Node needs repaint because the selection rectangle and static text must disappear.
-        InvalidateNode(FFocusedNode);
-        if not FEditLink.BeginEdit then
-          DoStateChange([], [tsEditing]);
-      end
-      else
-        DoStateChange([], [tsEditing]);
-      if not (tsEditing in FStates) then
-        FEditLink := nil;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoEndDrag(Target: TObject; X, Y: Integer);
-
-// Does some housekeeping for VCL drag'n drop;
-
-begin
-  inherited;
-
-  DragFinished;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoEndEdit: Boolean;
-
-begin
-  KillTimer(Handle, EditTimer);
-  Result := (tsEditing in FStates) and FEditLink.EndEdit;
-  if Result then
-  begin
-    DoStateChange([], [tsEditing]);
-    FEditLink := nil;
-    if Assigned(FOnEdited) then
-      FOnEdited(Self, FFocusedNode, FEditColumn);
-  end;
-  DoStateChange([], [tsEditPending]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoExpanded(Node: PVirtualNode);
-
-begin
-  if Assigned(FOnExpanded) then
-    FOnExpanded(Self, Node);
-  {$ifdef EnableAccessible}
-  NotifyWinEvent(EVENT_OBJECT_STATECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF);
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoExpanding(Node: PVirtualNode): Boolean;
-
-begin
-  Result := True;
-  if Assigned(FOnExpanding) then
-    FOnExpanding(Self, Node, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoFocusChange(Node: PVirtualNode; Column: TColumnIndex);
-
-begin
-  if Assigned(FOnFocusChanged) then
-    FOnFocusChanged(Self, Node, Column);
-  {$ifdef EnableAccessible}
-  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);
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoFocusChanging(OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex): Boolean;
-
-begin
-  Result := (OldColumn = NewColumn) or FHeader.AllowFocus(NewColumn);
-  if Assigned(FOnFocusChanging) then
-    FOnFocusChanging(Self, OldNode, NewNode, OldColumn, NewColumn, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoFocusNode(Node: PVirtualNode; Ask: Boolean);
-
-begin
-  if not (tsEditing in FStates) or EndEditNode then
-  begin
-    if Node = FRoot then
-      Node := nil;
-    if (FFocusedNode <> Node) and (not Ask or DoFocusChanging(FFocusedNode, Node, FFocusedColumn, FFocusedColumn)) then
-    begin
-      if Assigned(FFocusedNode) then
-      begin
-        // Do automatic collapsing of last focused node if enabled. This is however only done if
-        // old and new focused node have a common parent node.
-        if (toAutoExpand in FOptions.FAutoOptions) and Assigned(Node) and (Node.Parent = FFocusedNode.Parent) and
-          (vsExpanded in FFocusedNode.States) then
-          ToggleNode(FFocusedNode)
-        else
-          InvalidateNode(FFocusedNode);
-      end;
-      FFocusedNode := Node;
-    end;
-
-    // Have to scroll the node into view, even it is the same node as before.
-    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.FColumns.IsValidColumn(FFocusedColumn)) then
-        FFocusedColumn := FHeader.MainColumn;
-      // Do automatic expansion of the newly focused node if enabled.
-      if (toAutoExpand in FOptions.FAutoOptions) and not (vsExpanded in FFocusedNode.States) then
-        ToggleNode(FFocusedNode);
-      InvalidateNode(FFocusedNode);
-      if (FUpdateCount = 0) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then
-        ScrollIntoView(FFocusedNode, (toCenterScrollIntoView in FOptions.SelectionOptions) and
-          (MouseButtonDown * FStates = []), not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions));
-    end;
-
-    // Reset range anchor if necessary.
-    if FSelectionCount = 0 then
-      ResetRangeAnchor;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoFreeNode(Node: PVirtualNode);
-
-begin
-  if Node = FLastChangedNode then
-    FLastChangedNode := nil;
-  if Node = FCurrentHotNode then
-    FCurrentHotNode := nil;
-  if Node = FDropTargetNode then
-    FDropTargetNode := nil;
-  if Assigned(FOnFreeNode) and ([vsInitialized, vsInitialUserData] * Node.States <> []) then
-    FOnFreeNode(Self, Node);
-  FreeMem(Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoGetCellContentMargin(Node: PVirtualNode; Column: TColumnIndex;
-  CellContentMarginType: TVTCellContentMarginType = ccmtAllSides; Canvas: TCanvas = nil): TPoint;
-
-// Determines the margins of the content rectangle caused by DoBeforeCellPaint.
-// Note that shrinking the content rectangle results in positive margins whereas enlarging the content rectangle results
-// in negative margins.
-
-var
-  CellRect,
-  ContentRect: TRect;
-
-begin
-  Result := Point(0, 0);
-
-  if Assigned(FOnBeforeCellPaint) then // Otherwise DoBeforeCellPaint has no effect.
-  begin
-    if Canvas = nil then
-      Canvas := Self.Canvas;
-
-    // Determine then node's cell rectangle and content rectangle before calling DoBeforeCellPaint.
-    CellRect := GetDisplayRect(Node, Column, True);
-    ContentRect := CellRect;
-    DoBeforeCellPaint(Canvas, Node, Column, cpmGetContentMargin, CellRect, ContentRect);
-
-    // Calculate the changes caused by DoBeforeCellPaint.
-    case CellContentMarginType of
-      ccmtAllSides:
-        // Calculate the width difference and high difference.
-        Result := Point((CellRect.Right - CellRect.Left) - (ContentRect.Right - ContentRect.Left),
-                        (CellRect.Bottom - CellRect.Top) - (ContentRect.Bottom - ContentRect.Top));
-      ccmtTopLeftOnly:
-        // Calculate the left margin and top margin only.
-        Result := Point(ContentRect.Left - CellRect.Left, ContentRect.Top - CellRect.Top);
-      ccmtBottomRightOnly:
-        // Calculate the right margin and bottom margin only.
-        Result := Point(CellRect.Right - ContentRect.Right, CellRect.Bottom - ContentRect.Bottom);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoGetCursor(var Cursor: TCursor);
-
-begin
-  if Assigned(FOnGetCursor) then
-    FOnGetCursor(Self, Cursor);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoGetHeaderCursor(var Cursor: HCURSOR);
-
-begin
-  if Assigned(FOnGetHeaderCursor) then
-    FOnGetHeaderCursor(FHeader, Cursor);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoGetImageIndex(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
-  var Ghosted: Boolean; var Index: Integer): TCustomImageList;
-
-// Queries the application/descendant about certain image properties for a node.
-// Returns a custom image list if given by the callee, otherwise nil.
-
-begin
-  Result := nil;
-
-  // First try the enhanced event to allow for custom image lists.
-  if Assigned(FOnGetImageEx) then
-    FOnGetImageEx(Self, Node, Kind, Column, Ghosted, Index, Result)
-  else
-    if Assigned(FOnGetImage) then
-      FOnGetImage(Self, Node, Kind, Column, Ghosted, Index);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoGetImageText(Node: PVirtualNode; Kind: TVTImageKind;
-  Column: TColumnIndex; var ImageText: String);
-
-// Queries the application/descendant about alternative image text for a node.
-
-begin
-  if Assigned(FOnGetImageText) then
-     FOnGetImageText(Self, Node, Kind, Column, ImageText);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoGetLineStyle(var Bits: Pointer);
-
-begin
-  if Assigned(FOnGetLineStyle) then
-    FOnGetLineStyle(Self, Bits);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoGetNodeHint(Node: PVirtualNode; Column: TColumnIndex;
-  var LineBreakStyle: TVTTooltipLineBreakStyle): String;
-
-begin
-  Result := Hint;
-  LineBreakStyle := hlbDefault;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoGetNodeTooltip(Node: PVirtualNode; Column: TColumnIndex;
-  var LineBreakStyle: TVTTooltipLineBreakStyle): String;
-
-begin
-  Result := Hint;
-  LineBreakStyle := hlbDefault;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer;
-
-begin
-  Result := 0;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoGetPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Position: TPoint): TPopupMenu;
-
-// Queries the application whether there is a node specific popup menu.
-
-var
-  Run: PVirtualNode;
-  AskParent: Boolean;
-
-begin
-  Result := nil;
-  if Assigned(FOnGetPopupMenu) then
-  begin
-    Run := Node;
-
-    if Assigned(Run) then
-    begin
-      AskParent := True;
-      repeat
-        FOnGetPopupMenu(Self, Run, Column, Position, AskParent, Result);
-        Run := Run.Parent;
-      until (Run = FRoot) or Assigned(Result) or not AskParent;
-    end
-    else
-      FOnGetPopupMenu(Self, nil, -1, Position, AskParent, Result);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoGetUserClipboardFormats(var Formats: TFormatEtcArray);
-
-begin
-  if Assigned(FOnGetUserClipboardFormats) then
-    FOnGetUserClipboardFormats(Self, Formats);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
-
-begin
-  if Assigned(FOnHeaderClick) then
-    FOnHeaderClick(FHeader, Column, Button, Shift, X, Y);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderDblClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
-
-begin
-  if Assigned(FOnHeaderDblClick) then
-    FOnHeaderDblClick(FHeader, Column, Button, Shift, X, Y);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderImageClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState;
-  X, Y: Integer);
-
-begin
-  if Assigned(FOnHeaderImageClick) then
-    FOnHeaderImageClick(FHeader, Column, Button, Shift, X, Y)
-  else if Assigned(FOnHeaderClick) then
-    FOnHeaderClick(FHeader, Column, Button, Shift, X, Y)
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderCheckBoxClick(Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState;
-  X, Y: Integer);
-
-begin
-  if Assigned(FOnHeaderCheckBoxClick) then
-    FOnHeaderCheckBoxClick(FHeader, Column, Button, Shift, X, Y);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderDragged(Column: TColumnIndex; OldPosition: TColumnPosition);
-
-begin
-  if Assigned(FOnHeaderDragged) then
-    FOnHeaderDragged(FHeader, Column, OldPosition);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderDraggedOut(Column: TColumnIndex; const DropPosition: TPoint);
-
-begin
-  if Assigned(FOnHeaderDraggedOut) then
-    FOnHeaderDraggedOut(FHeader, Column, DropPosition);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoHeaderDragging(Column: TColumnIndex): Boolean;
-
-begin
-  Result := True;
-  if Assigned(FOnHeaderDragging) then
-    FOnHeaderDragging(FHeader, Column, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderDraw(Canvas: TCanvas; Column: TVirtualTreeColumn; const R: TRect; Hover, Pressed: Boolean;
-  DropMark: TVTDropMarkMode);
-
-begin
-  if Assigned(FOnHeaderDraw) then
-    FOnHeaderDraw(FHeader, Canvas, Column, R, Hover, Pressed, DropMark);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderDrawQueryElements(var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements);
-
-begin
-  if Assigned(FOnHeaderDrawQueryElements) then
-    FOnHeaderDrawQueryElements(FHeader, PaintInfo, Elements);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
-
-begin
-  if Assigned(FOnHeaderMouseDown) then
-    FOnHeaderMouseDown(FHeader, Button, Shift, X, Y);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderMouseMove(Shift: TShiftState; X, Y: Integer);
-
-begin
-  if Assigned(FOnHeaderMouseMove) then
-    FOnHeaderMouseMove(FHeader, Shift, X, Y);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHeaderMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
-
-begin
-  if Assigned(FOnHeaderMouseUp) then
-    FOnHeaderMouseUp(FHeader, Button, Shift, X, Y);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoHotChange(Old, New: PVirtualNode);
-
-begin
-  if Assigned(FOnHotChange) then
-    FOnHotChange(Self, Old, New);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoIncrementalSearch(Node: PVirtualNode; const Text: String): Integer;
-
-begin
-  Result := 0;
-  if Assigned(FOnIncrementalSearch) then
-    FOnIncrementalSearch(Self, Node, Text, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoInitChildren(Node: PVirtualNode; var ChildCount: Cardinal);
-
-begin
-  if Assigned(FOnInitChildren) then
-    FOnInitChildren(Self, Node, ChildCount);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoInitNode(Parent, Node: PVirtualNode; var InitStates: TVirtualNodeInitStates);
-
-begin
-  if Assigned(FOnInitNode) then
-    FOnInitNode(Self, Parent, Node, InitStates);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoKeyAction(var CharCode: Word; var Shift: TShiftState): Boolean;
-
-begin
-  Result := True;
-  if Assigned(FOnKeyAction) then
-    FOnKeyAction(Self, CharCode, Shift, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoLoadUserData(Node: PVirtualNode; Stream: TStream);
-
-begin
-  if Assigned(FOnLoadNode) then
-    if Node = FRoot then
-      FOnLoadNode(Self, nil, Stream)
-    else
-      FOnLoadNode(Self, Node, Stream);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoMeasureItem(TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer);
-
-begin
-  if Assigned(FOnMeasureItem) then
-    FOnMeasureItem(Self, TargetCanvas, Node, NodeHeight);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoNodeCopied(Node: PVirtualNode);
-
-begin
-  if Assigned(FOnNodeCopied) then
-    FOnNodeCopied(Self, Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoNodeCopying(Node, NewParent: PVirtualNode): Boolean;
-
-begin
-  Result := True;
-  if Assigned(FOnNodeCopying) then
-    FOnNodeCopying(Self, Node, NewParent, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoNodeHeightDblClickResize(Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState;
-  P: TPoint): Boolean;
-
-begin
-  Result := True;
-  if Assigned(FOnNodeHeightDblClickResize) then
-    FOnNodeHeightDblClickResize(Self, Node, Column, Shift, P, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoNodeHeightTracking(Node: PVirtualNode; Column: TColumnIndex; Shift: TShiftState;
-  var TrackPoint: TPoint; P: TPoint): Boolean;
-
-begin
-  Result := True;
-  if Assigned(FOnNodeHeightTracking) then
-    FOnNodeHeightTracking(Self, Node, Column, Shift, TrackPoint, P, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoNodeMoved(Node: PVirtualNode);
-
-begin
-  if Assigned(FOnNodeMoved) then
-    FOnNodeMoved(Self, Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoNodeMoving(Node, NewParent: PVirtualNode): Boolean;
-
-begin
-  Result := True;
-  if Assigned(FOnNodeMoving) then
-    FOnNodeMoving(Self, Node, NewParent, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoPaintBackground(Canvas: TCanvas; const R: TRect): Boolean;
-
-begin
-  Result := False;
-  if Assigned(FOnPaintBackground) then
-    FOnPaintBackground(Self, Canvas, R, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoPaintDropMark(Canvas: TCanvas; Node: PVirtualNode; const R: TRect);
-
-// draws the drop mark into the given rectangle
-// Note: Changed properties of the given canvas should be reset to their previous values.
-
-var
-  SaveBrushColor: TColor;
-  SavePenStyle: TPenStyle;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DoPaintDropMark');{$endif}
-  if FLastDropMode in [dmAbove, dmBelow] then
-    with Canvas do
-    begin
-      {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'DropMode in [dmAbove,dmBelow]');{$endif}
-      SavePenStyle := Pen.Style;
-      Pen.Style := psClear;
-      SaveBrushColor := Brush.Color;
-      Brush.Color := FColors.DropMarkColor;
-      {$ifdef DEBUG_VTV}Logger.SendColor([lcDrag],'Brush.Color',Brush.Color);{$endif}
-      {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'R',R);{$endif}
-      if FLastDropMode = dmAbove then
-      begin
-        Polygon([Point(R.Left + 2, R.Top),
-                 Point(R.Right - 2, R.Top),
-                 Point(R.Right - 2, R.Top + 6),
-                 Point(R.Right - 6, R.Top + 2),
-                 Point(R.Left + 6 , R.Top + 2),
-                 Point(R.Left + 2, R.Top + 6)
-        ]);
-      end
-      else
-        Polygon([Point(R.Left + 2, R.Bottom - 1),
-                 Point(R.Right - 2, R.Bottom - 1),
-                 Point(R.Right - 2, R.Bottom - 8),
-                 Point(R.Right - 7, R.Bottom - 3),
-                 Point(R.Left + 7 , R.Bottom - 3),
-                 Point(R.Left + 2, R.Bottom - 8)
-        ]);
-      Brush.Color := SaveBrushColor;
-      Pen.Style := SavePenStyle;
-    end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DoPaintDropMark');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoPaintNode(var PaintInfo: TVTPaintInfo);
-
-begin
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Position: TPoint);
-
-// Support for node dependent popup menus.
-
-var
-  Menu: TPopupMenu;
-
-begin
-  Menu := DoGetPopupMenu(Node, Column, Position);
-
-  if Assigned(Menu) then
-  begin
-    DoStateChange([tsPopupMenuShown]);
-    KillTimer(Handle, EditTimer);
-    Menu.PopupComponent := Self;
-    with ClientToScreen(Position) do
-      Menu.Popup(X, Y);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-  ForClipboard: Boolean): HRESULT;
-
-begin
-  Result := E_FAIL;
-  if Assigned(FOnRenderOLEData) then
-    FOnRenderOLEData(Self, FormatEtcIn, Medium, ForClipboard, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoReset(Node: PVirtualNode);
-
-begin
-  if Assigned(FOnResetNode) then
-    FOnResetNode(Self, Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoSaveUserData(Node: PVirtualNode; Stream: TStream);
-
-begin
-  if Assigned(FOnSaveNode) then
-    if Node = FRoot then
-      FOnSaveNode(Self, nil, Stream)
-    else
-      FOnSaveNode(Self, Node, Stream);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoScroll(DeltaX, DeltaY: Integer);
-
-begin
-  if Assigned(FOnScroll) then
-    FOnScroll(Self, DeltaX, DeltaY);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoSetOffsetXY(Value: TPoint; Options: TScrollUpdateOptions; ClipRect: PRect = nil): Boolean;
-
-// Actual offset setter used to scroll the client area, update scroll bars and invalidating the header (all optional).
-// Returns True if the offset really changed otherwise False is returned.
-
-var
-  DeltaX: Integer;
-  DeltaY: Integer;
-  DWPStructure: THandle;//HDWP;
-  I: Integer;
-  P: TPoint;
-  R: TRect;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcScroll],'DoSetOffsetXY');{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'Value',Value);{$endif}
-  //{$ifdef DEBUG_VTV}Logger.SendCallStack([lcScroll],'CallStack');{$endif}
-  // Range check, order is important here.
-  if Value.X < (ClientWidth - Integer(FRangeX)) then
-    Value.X := ClientWidth - Integer(FRangeX);
-  if Value.X > 0 then
-    Value.X := 0;
-  DeltaX := Value.X - FOffsetX;
-  if UseRightToLeftAlignment then
-    DeltaX := -DeltaX;
-  if Value.Y < (ClientHeight - Integer(FRangeY)) then
-    Value.Y := ClientHeight - Integer(FRangeY);
-  if Value.Y > 0 then
-    Value.Y := 0;
-  DeltaY := Value.Y - FOffsetY;
-  {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'FOffsetX: %d FOffsetY: %d',[FOffsetX,FOffsetY]);{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send([lcScroll],'DeltaX: %d DeltaY: %d',[DeltaX,DeltaY]);{$endif}
-  Result := (DeltaX <> 0) or (DeltaY <> 0);
-  if Result then
-  begin
-    FOffsetX := Value.X;
-    FOffsetY := Value.Y;
-
-    Application.CancelHint;
-    if FUpdateCount = 0 then
-    begin
-      // The drag image from VCL controls need special consideration.
-      {$ifndef INCOMPLETE_WINAPI}
-      if tsVCLDragging in FStates then
-        ImageList_DragShowNolock(False);
-      {$endif}
-
-      if (suoScrollClientArea in Options) and not (tsToggling in FStates) then
-      begin
-        // Have to invalidate the entire window if there's a background.
-        if (toShowBackground in FOptions.FPaintOptions) and (FBackground.Graphic is TBitmap) then
-        begin
-          //todo: reimplement
-          {$ifndef INCOMPLETE_WINAPI}
-          // Since we don't use ScrollWindow here we have to move all client windows ourselves.
-          DWPStructure := BeginDeferWindowPos(ControlCount);
-          for I := 0 to ControlCount - 1 do
-            if Controls[I] is TWinControl then
-            begin
-              with Controls[I] as TWinControl do
-                DWPStructure := DeferWindowPos(DWPStructure, Handle, 0, Left + DeltaX, Top + DeltaY, 0, 0,
-                  SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOSIZE);
-              if DWPStructure = 0 then
-                Break;
-            end;
-          if DWPStructure <> 0 then
-            EndDeferWindowPos(DWPStructure);
-          InvalidateRect(Handle, nil, False);
-          {$endif}
-        end
-        else
-        begin
-          if (DeltaX <> 0) and (Header.Columns.GetVisibleFixedWidth > 0) then
-          begin
-            // When fixed columns exists we have to scroll separately horizontally and vertically.
-            // Horizontally is scroll only the client area not occupied by fixed columns and
-            // vertically entire client area (or clipping area if one exists).
-            R := ClientRect;
-            R.Left := Header.Columns.GetVisibleFixedWidth;
-            //lclheader
-            if hoVisible in FHeader.FOptions then
-            begin
-              Inc(R.Top,FHeader.Height);
-              Inc(R.Bottom,FHeader.Height);
-            end;
-            //scrollwindow implementation under gtk is broken
-            {$ifdef Gtk}
-            InvalidateRect(Handle, nil, True);
-            {$else}
-            ScrollWindow(Handle, DeltaX, 0, @R, @R);
-            if DeltaY <> 0 then
-              ScrollWindow(Handle, 0, DeltaY, @R, @R);
-            {$endif}
-          end
-          else
-          begin
-            //lclheader
-            if ClipRect <> nil then
-            begin
-              {$ifdef DEBUG_VTV}Logger.SendWarning([lcWarning], 'DoSetOffsetXY called with a non nil ClipRect');{$endif}
-              R := ClipRect^;
-            end
-            else
-              R := ClientRect;
-            if hoVisible in FHeader.FOptions then
-            begin
-              Inc(R.Top, FHeader.Height);
-              Inc(R.Bottom, FHeader.Height);
-            end;
-            {$ifdef DEBUG_VTV}Logger.Send([lcScroll], 'Rect to Scroll', R);{$endif}
-            //todo: temporary hack to avoid some drawing problems.
-            //Will be removed when scrollwindowex is properly implemented in all widgets
-            {$ifdef LCLQt}
-            ScrollWindow(Handle, DeltaX, DeltaY, @R, @R);
-            {$else}
-            {$ifdef Gtk}
-            InvalidateRect(Handle, nil, True);
-            {$else}
-            ScrollWindowEx(Handle, DeltaX, DeltaY, @R, @R,0, nil, SW_INVALIDATE or SW_SCROLLCHILDREN);
-            {$endif}
-            {$endif}
-          end;
-        end;
-      end;
-
-      if suoUpdateNCArea in Options then
-      begin
-        if DeltaX <> 0 then
-        begin
-          if (suoRepaintHeader in Options) and (hoVisible in FHeader.FOptions) then
-            FHeader.Invalidate(nil);
-          if not (tsSizing in FStates) and (FScrollBarOptions.ScrollBars in [ssHorizontal, ssBoth]) then
-            UpdateHorizontalScrollBar(suoRepaintScrollbars in Options);
-        end;
-
-        if (DeltaY <> 0) and ([tsThumbTracking, tsSizing] * FStates = []) then
-        begin
-          UpdateVerticalScrollBar(suoRepaintScrollbars in Options);
-          if not (FHeader.UseColumns or IsMouseSelecting) and
-            (FScrollBarOptions.ScrollBars in [ssHorizontal, ssBoth]) then
-            UpdateHorizontalScrollBar(suoRepaintScrollbars in Options);
-        end;
-      end;
-      {$ifndef INCOMPLETE_WINAPI}
-      if tsVCLDragging in FStates then
-        ImageList_DragShowNolock(True);
-      {$endif}
-    end;
-
-    // Finally update "hot" node if hot tracking is activated
-    GetCursorPos(P);
-    P := ScreenToClient(P);
-    if PtInRect(ClientRect, P) then
-      HandleHotTrack(P.X, P.Y);
-
-    DoScroll(DeltaX, DeltaY);
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcScroll],'DoSetOffsetXY');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoShowScrollbar(Bar: Integer; Show: Boolean);
-
-begin
-  {$ifdef UseFlatScrollbars}
-    FlatSB_ShowScrollBar(Handle, Bar, Show);
-  {$else}
-    ShowScrollBar(Handle, Bar, Show);
-  {$endif UseFlatScrollbars};
-
-  if Assigned(FOnShowScrollbar) then
-    FOnShowScrollbar(Self, Bar, Show);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoStartDrag(var DragObject: TDragObject);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DoStartDrag');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcDrag],'Stack');{$endif}
-
-  inherited;
-
-  // Check if the application created an own drag object. This is needed to pass the correct source in
-  // OnDragOver and OnDragDrop.
-  if Assigned(DragObject) then
-    DoStateChange([tsUserDragObject]);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DoStartDrag');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoStateChange(Enter: TVirtualTreeStates; Leave: TVirtualTreeStates = []);
-
-var
-  ActualEnter,
-  ActualLeave: TVirtualTreeStates;
-
-begin
-  if Assigned(FOnStateChange) then
-  begin
-    ActualEnter := Enter - FStates;
-    ActualLeave := FStates * Leave;
-    if (ActualEnter + ActualLeave) <> [] then
-      FOnStateChange(Self, Enter, Leave);
-  end;
-  FStates := FStates + Enter - Leave;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoStructureChange(Node: PVirtualNode; Reason: TChangeReason);
-
-begin
-  if HandleAllocated then
-    KillTimer(Handle, StructureChangeTimer);
-  if Assigned(FOnStructureChange) then
-    FOnStructureChange(Self, Node, Reason);
-
-  // This is a good place to reset the cached node and reason. These are the same as the values passed in here.
-  // This is necessary to allow descendants to override this method and get them.
-  DoStateChange([], [tsStructureChangePending]);
-  FLastStructureChangeNode := nil;
-  FLastStructureChangeReason := crIgnore;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoTimerScroll;
-
-var
-  P,
-  ClientP: TPoint;
-  InRect,
-  Panning: Boolean;
-  R,
-  ClipRect: TRect;
-  DeltaX,
-  DeltaY: Integer;
-
-begin
-  GetCursorPos(P);
-  //lclheader
-  R := inherited GetClientRect;
-  ClipRect := R;
-  {$ifndef INCOMPLETE_WINAPI}
-  MapWindowPoints(Handle, 0, R, 2);
-  {$endif}
-  InRect := PtInRect(R, P);
-  ClientP := ScreenToClient(P);
-  Panning := [tsWheelPanning, tsWheelScrolling] * FStates <> [];
-
-  if IsMouseSelecting or InRect or Panning or CanScroll(ClientP) then
-  begin
-    DeltaX := 0;
-    DeltaY := 0;
-    if sdUp in FScrollDirections then
-    begin
-      if Panning then
-        DeltaY := FLastClickPos.Y - ClientP.Y - 8
-      else
-        if InRect then
-          DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight)
-        else
-          DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight) * Abs(R.Top - P.Y);
-      if FOffsetY = 0 then
-        Exclude(FScrollDirections, sdUp);
-    end;
-
-    if sdDown in FScrollDirections then
-    begin
-      if Panning then
-        DeltaY := FLastClickPos.Y - ClientP.Y + 8
-      else
-        if InRect then
-          DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight)
-        else
-          DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight) * Abs(P.Y - R.Bottom);
-      if (ClientHeight - FOffsetY) = Integer(FRangeY) then
-        Exclude(FScrollDirections, sdDown);
-    end;
-
-    if sdLeft in FScrollDirections then
-    begin
-      if Panning then
-        DeltaX := FLastClickPos.X - ClientP.X - 8
-      else
-        if InRect then
-          DeltaX := FScrollBarOptions.FIncrementX
-        else
-          DeltaX := FScrollBarOptions.FIncrementX * Abs(R.Left - P.X);
-      if FEffectiveOffsetX = 0 then
-        Exclude(FScrollDirections, sdleft);
-    end;
-
-    if sdRight in FScrollDirections then
-    begin
-      if Panning then
-        DeltaX := FLastClickPos.X - ClientP.X + 8
-      else
-        if InRect then
-          DeltaX := -FScrollBarOptions.FIncrementX
-        else
-          DeltaX := -FScrollBarOptions.FIncrementX * Abs(P.X - R.Right);
-
-      if (ClientWidth + FEffectiveOffsetX) = Integer(FRangeX) then
-        Exclude(FScrollDirections, sdRight);
-    end;
-
-    if UseRightToLeftAlignment then
-      DeltaX := - DeltaX;
-      
-    if IsMouseSelecting then
-    begin
-      // In order to avoid scrolling the area which needs a repaint due to the changed selection rectangle
-      // we limit the scroll area explicitely.
-      OffsetRect(ClipRect, DeltaX, DeltaY);
-      DoSetOffsetXY(Point(FOffsetX + DeltaX, FOffsetY + DeltaY), DefaultScrollUpdateFlags, @ClipRect);
-      // When selecting with the mouse then either update only the parts of the window which have been uncovered
-      // by the scroll operation if no change in the selection happend or invalidate and redraw the entire
-      // client area otherwise (to avoid the time consuming task of determining the display rectangles of every
-      // changed node).
-      if CalculateSelectionRect(ClientP.X, ClientP.Y) and HandleDrawSelection(ClientP.X, ClientP.Y) then
-        InvalidateRect(Handle, nil, False)
-      else
-      begin
-        // The selection did not change so invalidate only the part of the window which really needs an update.
-        // 1) Invalidate the parts uncovered by the scroll operation. Add another offset range, we have to
-        //    scroll only one stripe but have to update two.
-        OffsetRect(ClipRect, DeltaX, DeltaY);
-        SubtractRect(ClipRect, ClientRect, ClipRect);
-        InvalidateRect(Handle, @ClipRect, False);
-
-        // 2) Invalidate the selection rectangles.
-        UnionRect(ClipRect, OrderRect(FNewSelRect), OrderRect(FLastSelRect));
-        OffsetRect(ClipRect, FOffsetX, FOffsetY);
-        InvalidateRect(Handle, @ClipRect, False);
-      end;
-    end
-    else
-    begin
-      // Scroll only if there is no drag'n drop in progress. Drag'n drop scrolling is handled in DragOver.
-      if ((FDragManager = nil) or not VTVDragManager.IsDropTarget) and ((DeltaX <> 0) or (DeltaY <> 0)) then
-        DoSetOffsetXY(Point(FOffsetX + DeltaX, FOffsetY + DeltaY), DefaultScrollUpdateFlags, nil);
-    end;
-    UpdateWindow(Handle);
-
-    if (FScrollDirections = []) and ([tsWheelPanning, tsWheelScrolling] * FStates = []) then
-    begin
-      KillTimer(Handle, ScrollTimer);
-      DoStateChange([], [tsScrollPending, tsScrolling]);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DoUpdating(State: TVTUpdateState);
-
-begin
-  if Assigned(FOnUpdating) then
-    FOnUpdating(Self, State);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DoValidateCache: Boolean;
-
-// This method fills the cache, which is used to speed up searching for nodes.
-// The strategy is simple: Take the current number of visible nodes and distribute evenly a number of marks
-// (which are stored in FPositionCache) so that iterating through the tree doesn't cost too much time.
-// If there are less than 'CacheThreshold' nodes in the tree then the cache remains empty.
-// Result is True if the cache was filled without interruption, otherwise False.
-// Note: You can adjust the maximum number of nodes between two cache entries by changing CacheThreshold.
-
-var
-  EntryCount,
-  CurrentTop,
-  Index: Cardinal;
-  CurrentNode,
-  Temp: PVirtualNode;
-
-begin
-  EntryCount := 0;
-  if not (tsStopValidation in FStates) then
-  begin
-    if FStartIndex = 0 then
-      FPositionCache := nil;
-
-    if FVisibleCount > CacheThreshold then
-    begin
-      EntryCount := CalculateCacheEntryCount;
-      SetLength(FPositionCache, EntryCount);
-      if FStartIndex > EntryCount then
-        FStartIndex := EntryCount;
-
-      // Optimize validation by starting with FStartIndex if set.
-      if (FStartIndex > 0) and Assigned(FPositionCache[FStartIndex - 1].Node) then
-      begin
-        // Index is the current entry in FPositionCache.
-        Index := FStartIndex - 1;
-        // Running term for absolute top value.
-        CurrentTop := FPositionCache[Index].AbsoluteTop;
-        // Running node pointer.
-        CurrentNode := FPositionCache[Index].Node;
-      end
-      else
-      begin
-        // Index is the current entry in FPositionCache.
-        Index := 0;
-        // Running term for absolute top value.
-        CurrentTop := 0;
-        // Running node pointer.
-        CurrentNode := GetFirstVisibleNoInit(nil, True);
-      end;
-
-      // EntryCount serves as counter for processed nodes here. This value can always start at 0 as
-      // the validation either starts also at index 0 or an index which is always a multiple of CacheThreshold
-      // and EntryCount is only used with modulo CacheThreshold.
-      EntryCount := 0;
-      if Assigned(CurrentNode) then
-      begin
-        while not (tsStopValidation in FStates) do
-        begin
-          if (EntryCount mod CacheThreshold) = 0 then
-          begin
-            // New cache entry to set up.
-            with FPositionCache[Index] do
-            begin
-              Node := CurrentNode;
-              AbsoluteTop := CurrentTop;
-            end;
-            Inc(Index);
-          end;
-
-          Inc(CurrentTop, NodeHeight[CurrentNode]);
-          // Advance to next visible node.
-          Temp := GetNextVisibleNoInit(CurrentNode, True);
-          // If there is no further node or the cache is full then stop the loop.
-          if (Temp = nil) or (Integer(Index) = Length(FPositionCache)) then
-            Break;
-
-          CurrentNode := Temp;
-          Inc(EntryCount);
-        end;
-      end;
-      // Finalize the position cache so no nil entry remains there.
-      if not (tsStopValidation in FStates) and (Integer(Index) <= High(FPositionCache)) then
-      begin
-        SetLength(FPositionCache, Index + 1);
-        with FPositionCache[Index] do
-        begin
-          Node := CurrentNode;
-          AbsoluteTop := CurrentTop;
-        end;
-      end;
-    end;
-  end;
-
-  Result := (EntryCount > 0) and not (tsStopValidation in FStates);
-
-  // In variable node height mode it might have happend that some or all of the nodes have been adjusted in their
-  // height. During validation updates of the scrollbars is disabled so let's do this here.
-  if Result and (toVariableNodeHeight in FOptions.FMiscOptions) then
-    UpdateScrollbars(True);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DragAndDrop(AllowedEffects: LongWord;
-  DataObject: IDataObject; DragEffect: LongWord);
-
-begin
-  {$ifdef Windows}
-  ActiveX.DoDragDrop(DataObject, VTVDragManager as IDropSource, AllowedEffects, @DragEffect);
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DragCanceled;
-
-// Does some housekeeping for VCL drag'n drop;
-
-begin
-  inherited;
-
-  DragFinished;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DragDrop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-var
-  Shift: TShiftState;
-  EnumFormat: IEnumFormatEtc;
-  Fetched: LongWord;
-  OLEFormat: TFormatEtc;
-  Formats: TFormatArray;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragDrop');{$endif}
-  KillTimer(Handle, ExpandTimer);
-  KillTimer(Handle, ScrollTimer);
-  DoStateChange([], [tsScrollPending, tsScrolling]);
-  Formats := nil;
-
-  // Ask explicitly again whether the action is allowed. Otherwise we may accept a drop which is intentionally not
-  // allowed but cannot be prevented by the application because when the tree was scrolling while dropping
-  // no DragOver event is created by the OLE subsystem.
-  Result := DragOver(VTVDragManager.DragSource, KeyState, dsDragMove, Pt, Effect);
-  try
-    if (Result <>  NOERROR) or ((Effect and not DROPEFFECT_SCROLL) = DROPEFFECT_NONE) then
-      Result := E_FAIL
-    else
-    begin
-      try
-        Shift := KeysToShiftState(KeyState);
-        if tsLeftButtonDown in FStates then
-          Include(Shift, ssLeft);
-        if tsMiddleButtonDown in FStates then
-          Include(Shift, ssMiddle);
-        if tsRightButtonDown in FStates then
-          Include(Shift, ssRight);
-        Pt := ScreenToClient(Pt);
-        // Determine which formats we can get and pass them along with the data object to the drop handler.
-        Result := DataObject.EnumFormatEtc(DATADIR_GET, EnumFormat);
-        if Failed(Result) then
-          Abort;
-        Result := EnumFormat.Reset;
-        if Failed(Result) then
-          Abort;
-        // create a list of available formats
-        while EnumFormat.Next(1, OLEFormat, @Fetched) = S_OK do
-        begin
-          SetLength(Formats, Length(Formats) + 1);
-          Formats[High(Formats)] := OLEFormat.cfFormat;
-        end;
-        DoDragDrop(VTVDragManager.DragSource, DataObject, Formats, Shift, Pt, Effect, FLastDropMode);
-      except
-        // An unhandled exception here leaks memory.
-        Application.HandleException(Self);
-        Result := E_UNEXPECTED;
-      end;
-    end;
-  finally
-    if Assigned(FDropTargetNode) then
-    begin
-      InvalidateNode(FDropTargetNode);
-      FDropTargetNode := nil;
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DragDrop');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DragEnter(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult;
-
-// callback routine for the drop target interface
-
-var
-  Shift: TShiftState;
-  Accept: Boolean;
-  R: TRect;
-  HitInfo: THitInfo;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragEnter');{$endif}
-  try
-    // Determine acceptance of drag operation and reset scroll start time.
-    FDragScrollStart := 0;
-
-    Shift := KeysToShiftState(KeyState);
-    if tsLeftButtonDown in FStates then
-      Include(Shift, ssLeft);
-    if tsMiddleButtonDown in FStates then
-      Include(Shift, ssMiddle);
-    if tsRightButtonDown in FStates then
-      Include(Shift, ssRight);
-    Pt := ScreenToClient(Pt);
-    Effect := SuggestDropEffect(VTVDragManager.DragSource, Shift, Pt, Effect);
-    Accept := DoDragOver(VTVDragManager.DragSource, Shift, dsDragEnter, Pt, FLastDropMode, Effect);
-    if not Accept then
-      Effect := DROPEFFECT_NONE
-    else
-    begin
-      // Set initial drop target node and drop mode.
-      GetHitTestInfoAt(Pt.X, Pt.Y, True, HitInfo);
-      if Assigned(HitInfo.HitNode) then
-      begin
-        FDropTargetNode := HitInfo.HitNode;
-        R := GetDisplayRect(HitInfo.HitNode, FHeader.MainColumn, False);
-        if hiOnItemLabel in HitInfo.HitPositions then
-          FLastDropMode := dmOnNode
-        else
-          if ((R.Top + R.Bottom) div 2) > Pt.Y then
-            FLastDropMode := dmAbove
-          else
-            FLastDropMode := dmBelow;
-      end
-      else
-        FLastDropMode := dmNowhere;
-    end;
-
-    // If the drag source is a virtual tree then we know how to control the drag image
-    // and can show it even if the source is not the target tree.
-    // This is only necessary if we cannot use the drag image helper interfaces.
-    if not VTVDragManager.DropTargetHelperSupported and Assigned(VTVDragManager.DragSource) then
-      TBaseVirtualTree(VTVDragManager.DragSource).FDragImage.ShowDragImage;
-    Result :=  NOERROR;
-  except
-    Result := E_UNEXPECTED;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DragEnter');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DragFinished;
-
-// Called by DragCancelled or EndDrag to make up for the still missing mouse button up messages.
-// These are important for such important things like popup menus.
-
-var
-  P: TPoint;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragFinished');{$endif}
-  DoStateChange([], [tsVCLDragPending, tsVCLDragging, tsUserDragObject]);
-
-  GetCursorPos(P);
-  P := ScreenToClient(P);
-  if tsRightButtonDown in FStates then
-    Perform(LM_RBUTTONUP, 0, Longint(PointToSmallPoint(P)))
-  else
-    if tsMiddleButtonDown in FStates then
-      Perform(LM_MBUTTONUP, 0, Longint(PointToSmallPoint(P)))
-    else
-      Perform(LM_LBUTTONUP, 0, Longint(PointToSmallPoint(P)));
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DragFinished');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DragLeave;
-
-var
-  Effect: LongWord;
-
-begin
-  KillTimer(Handle, ExpandTimer);
-
-  if not VTVDragManager.DropTargetHelperSupported and Assigned(VTVDragManager.DragSource) then
-    TBaseVirtualTree(VTVDragManager.DragSource).FDragImage.HideDragImage;
-
-  if Assigned(FDropTargetNode) then
-  begin
-    InvalidateNode(FDropTargetNode);
-    FDropTargetNode := nil;
-  end;
-  UpdateWindow(Handle);
-
-  Effect := 0;
-  DoDragOver(nil, [], dsDragLeave, Point(0, 0), FLastDropMode, Effect);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.DragOver(Source: TObject; KeyState: LongWord; DragState: TDragState; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-// callback routine for the drop target interface
-
-var
-  Shift: TShiftState;
-  Accept,
-  DragImageWillMove,
-  WindowScrolled: Boolean;
-  OldR, R: TRect;
-  NewDropMode: TDropMode;
-  HitInfo: THitInfo;
-  ImageHit: Boolean;
-  LabelHit: Boolean;
-  DragPos: TPoint;
-  Tree: TBaseVirtualTree;
-  LastNode: PVirtualNode;
-
-  DeltaX,
-  DeltaY: Integer;
-  ScrollOptions: TScrollUpdateOptions;
-
-begin
-  //{$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'DragOver');{$endif}
-  //todo: the check to FDragManager disable drag images in non windows.
-  //This should be reviewed as soon as drag image is implemented in non windows
-  if Assigned(FDragManager) and not VTVDragManager.DropTargetHelperSupported and (Source is TBaseVirtualTree) then
-  begin
-    Tree := Source as TBaseVirtualTree;
-    ScrollOptions := [suoUpdateNCArea];
-  end
-  else
-  begin
-    Tree := nil;
-    ScrollOptions := DefaultScrollUpdateFlags;
-  end;
-
-  try
-    DragPos := Pt;
-    Pt := ScreenToClient(Pt);
-    //{$ifdef DEBUG_VTV}Logger.Send([lcDrag],'Pt',Pt);{$endif}
-    // Check if we have to scroll the client area.
-    FScrollDirections := DetermineScrollDirections(Pt.X, Pt.Y);
-    DeltaX := 0;
-    DeltaY := 0;
-    if FScrollDirections <> [] then
-    begin
-      // Determine amount to scroll.
-      if sdUp in FScrollDirections then
-      begin
-        DeltaY := Min(FScrollBarOptions.FIncrementY, ClientHeight);
-        if FOffsetY = 0 then
-          Exclude(FScrollDirections, sdUp);
-      end;
-      if sdDown in FScrollDirections then
-      begin
-        DeltaY := -Min(FScrollBarOptions.FIncrementY, ClientHeight);
-        if (ClientHeight - FOffsetY) = Integer(FRangeY) then
-          Exclude(FScrollDirections, sdDown);
-      end;
-      if sdLeft in FScrollDirections then
-      begin
-        DeltaX := FScrollBarOptions.FIncrementX;
-        if FEffectiveOffsetX = 0 then
-          Exclude(FScrollDirections, sdleft);
-      end;
-      if sdRight in FScrollDirections then
-      begin
-        DeltaX := -FScrollBarOptions.FIncrementX;
-        if (ClientWidth + FEffectiveOffsetX) = Integer(FRangeX) then
-          Exclude(FScrollDirections, sdRight);
-      end;
-      WindowScrolled := DoSetOffsetXY(Point(FOffsetX + DeltaX, FOffsetY + DeltaY), ScrollOptions, nil);
-    end
-    else
-      WindowScrolled := False;
-
-    // Determine acceptance of drag operation as well as drag target.
-    Shift := KeysToShiftState(KeyState);
-    if tsLeftButtonDown in FStates then
-      Include(Shift, ssLeft);
-    if tsMiddleButtonDown in FStates then
-      Include(Shift, ssMiddle);
-    if tsRightButtonDown in FStates then
-      Include(Shift, ssRight);
-    GetHitTestInfoAt(Pt.X, Pt.Y, True, HitInfo);
-    ImageHit := HitInfo.HitPositions * [hiOnNormalIcon, hiOnStateIcon] <> [];
-    LabelHit := hiOnItemLabel in HitInfo.HitPositions;
-    // In report mode only direct hits of the node captions/images in the main column are accepted as hits.
-    if (toReportMode in FOptions.FMiscOptions) and not ((LabelHit or ImageHit) and
-      (HitInfo.HitColumn = FHeader.MainColumn)) then
-      HitInfo.HitNode := nil;
-
-    if Assigned(HitInfo.HitNode) then
-    begin
-      R := GetDisplayRect(HitInfo.HitNode, NoColumn, False);
-      if LabelHit or ImageHit or not (toShowDropmark in FOptions.FPaintOptions) then
-        NewDropMode := dmOnNode
-      else
-        if ((R.Top + R.Bottom) div 2) > Pt.Y then
-          NewDropMode := dmAbove
-        else
-          NewDropMode := dmBelow;
-    end
-    else
-    begin
-      NewDropMode := dmNowhere;
-      R := Rect(0, 0, 0, 0);
-    end;
-
-    if Assigned(Tree) then
-      DragImageWillMove := Tree.FDragImage.WillMove(DragPos)
-    else
-      DragImageWillMove := False;
-
-    if (HitInfo.HitNode <> FDropTargetNode) or (FLastDropMode <> NewDropMode) then
-    begin
-      // Something in the tree will change. This requires to update the screen and/or the drag image.
-      FLastDropMode := NewDropMode;
-      if HitInfo.HitNode <> FDropTargetNode then
-      begin
-        KillTimer(Handle, ExpandTimer);
-        // The last target node is needed for the rectangle determination but must already be set for
-        // the recapture call, hence it must be stored somewhere.
-        LastNode := FDropTargetNode;
-        FDropTargetNode := HitInfo.HitNode;
-        // In order to show a selection rectangle a column must be focused.
-        if FFocusedColumn <= NoColumn then
-          FFocusedColumn := FHeader.MainColumn;
-
-        if Assigned(LastNode) and Assigned(FDropTargetNode) then
-        begin
-          // Optimize the case that the selection moved between two nodes.
-          OldR := GetDisplayRect(LastNode, NoColumn, False);
-          UnionRect(R, R, OldR);
-          if Assigned(Tree) then
-          begin
-            if WindowScrolled then
-              UpdateWindowAndDragImage(Tree, ClientRect, True, not DragImageWillMove)
-            else
-              UpdateWindowAndDragImage(Tree, R, False, not DragImageWillMove);
-          end
-          else
-            InvalidateRect(Handle, @R, False);
-        end
-        else
-        begin
-          if Assigned(LastNode) then
-          begin
-            // Repaint last target node.
-            OldR := GetDisplayRect(LastNode, NoColumn, False);
-            if Assigned(Tree) then
-            begin
-              if WindowScrolled then
-                UpdateWindowAndDragImage(Tree, ClientRect, WindowScrolled, not DragImageWillMove)
-              else
-                UpdateWindowAndDragImage(Tree, OldR, False, not DragImageWillMove);
-            end
-            else
-              InvalidateRect(Handle, @OldR, False);
-          end
-          else
-          begin
-            if Assigned(Tree) then
-            begin
-              if WindowScrolled then
-                UpdateWindowAndDragImage(Tree, ClientRect, WindowScrolled, not DragImageWillMove)
-              else
-                UpdateWindowAndDragImage(Tree, R, False, not DragImageWillMove);
-            end
-            else
-              InvalidateRect(Handle, @R, False);
-          end;
-        end;
-
-        // Start auto expand timer if necessary.
-        if (toAutoDropExpand in FOptions.FAutoOptions) and Assigned(FDropTargetNode) and
-          (vsHasChildren in FDropTargetNode.States) then
-          SetTimer(Handle, ExpandTimer, FAutoExpandDelay, nil);
-      end
-      else
-      begin
-        // Only the drop mark position changed so invalidate the current drop target node.
-        if Assigned(Tree) then
-        begin
-          if WindowScrolled then
-            UpdateWindowAndDragImage(Tree, ClientRect, WindowScrolled, not DragImageWillMove)
-          else
-            UpdateWindowAndDragImage(Tree, R, False, not DragImageWillMove);
-        end
-        else
-          InvalidateRect(Handle, @R, False);
-      end;
-    end
-    else
-    begin
-      // No change in the current drop target or drop mode. This might still mean horizontal or vertical scrolling.
-      if Assigned(Tree) and ((DeltaX <> 0) or (DeltaY <> 0)) then
-        UpdateWindowAndDragImage(Tree, ClientRect, WindowScrolled, not DragImageWillMove);
-    end;
-
-    Update;
-
-    if Assigned(Tree) and DragImageWillMove then
-      Tree.FDragImage.DragTo(DragPos, False);
-
-    Effect := SuggestDropEffect(Source, Shift, Pt, Effect);
-    Accept := DoDragOver(Source, Shift, DragState, Pt, FLastDropMode, Effect);
-    if not Accept then
-      Effect := DROPEFFECT_NONE;
-    if WindowScrolled then
-      Effect := Effect or LongWord(DROPEFFECT_SCROLL);
-    Result :=  NOERROR;
-  except
-    Result := E_UNEXPECTED;
-  end;
-  //{$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'DragOver');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DrawDottedHLine(const PaintInfo: TVTPaintInfo; Left, Right, Top: Integer);
-
-// Draws a horizontal line with alternating pixels (this style is not supported for pens under Win9x).
-
-var
-  R: TRect;
-
-begin
-  with PaintInfo, Canvas do
-  begin
-    Brush.Color := Self.Brush.Color;
-    R := Rect(Min(Left, Right), Top, Max(Left, Right) + 1, Top + 1);
-    LCLIntf.FillRect(Handle, R, FDottedBrush);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DrawDottedVLine(const PaintInfo: TVTPaintInfo; Top, Bottom, Left: Integer);
-
-// Draws a vertical line with alternating pixels (this style is not supported for pens under Win9x).
-
-var
-  R: TRect;
-
-begin
-  with PaintInfo, Canvas do
-  begin
-    Brush.Color := Self.Brush.Color;
-    R := Rect(Left, Min(Top, Bottom), Left + 1, Max(Top, Bottom) + 1);
-    LCLIntf.FillRect(Handle, R, FDottedBrush);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.EndOperation;
-
-// Called to indicate that a long-running operation has finished.
-
-begin
-  Assert(FOperationCount > 0, 'EndOperation must not be called when no operation in progress.');
-  Dec(FOperationCount);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.FindNodeInSelection(P: PVirtualNode; out Index: Integer; LowBound,
-  HighBound: Integer): Boolean;
-
-// Search routine to find a specific node in the selection array.
-// LowBound and HighBound determine the range in which to search the node.
-// Either value can be -1 to denote the maximum range otherwise LowBound must be less or equal HighBound.
-
-var
-  L, H,
-  I, C: PtrInt;
-
-begin
-  Result := False;
-  L := 0;
-  if LowBound >= 0 then
-    L := LowBound;
-  H := FSelectionCount - 1;
-  if HighBound >= 0 then
-    H := HighBound;
-  while L <= H do
-  begin
-    I := (L + H) shr 1;
-    C := PtrInt(FSelection[I]) - PtrInt(P);
-    if C < 0 then
-      L := I + 1
-    else
-    begin
-      H := I - 1;
-      if C = 0 then
-      begin
-        Result := True;
-        L := I;
-      end;
-    end;
-  end;
-  Index := L;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.FinishChunkHeader(Stream: TStream; StartPos, EndPos: Integer);
-
-// used while streaming out a node to finally write out the size of the chunk
-
-var
-  Size: Integer;
-
-begin
-  // seek back to the second entry in the chunk header
-  Stream.Position := StartPos + SizeOf(Integer);
-  // determine size of chunk without the chunk header
-  Size := EndPos - StartPos - SizeOf(TChunkHeader);
-  // write the size...
-  Stream.Write(Size, SizeOf(Size));
-  // ... and seek to the last endposition
-  Stream.Position := EndPos;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.FontChanged(AFont: TObject);
-
-// Little helper function for font changes (as they are not tracked in TBitmap/TCanvas.OnChange).
-
-begin
-  FFontChanged := True;
-  FOldFontChange(AFont);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetBorderDimensions: TSize;
-
-// Returns the overall width of the current window border, depending on border styles.
-// Note: these numbers represent the system's standards not special properties, which can be set for TWinControl
-// (e.g. bevels, border width).
-
-var
-  Styles: Integer;
-
-begin
-  Result.cx := 0;
-  Result.cy := 0;
-
-  Styles := GetWindowLong(Handle, GWL_STYLE);
-  if (Styles and WS_BORDER) <> 0 then
-  begin
-    Dec(Result.cx);
-    Dec(Result.cy);
-  end;
-  if (Styles and WS_THICKFRAME) <> 0 then
-  begin
-    Dec(Result.cx, GetSystemMetrics(SM_CXFIXEDFRAME));
-    Dec(Result.cy, GetSystemMetrics(SM_CYFIXEDFRAME));
-  end;
-  Styles := GetWindowLong(Handle, GWL_EXSTYLE);
-  if (Styles and WS_EX_CLIENTEDGE) <> 0 then
-  begin
-    Dec(Result.cx, GetSystemMetrics(SM_CXEDGE));
-    Dec(Result.cy, GetSystemMetrics(SM_CYEDGE));
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetCheckImage(Node: PVirtualNode; ImgCheckType: TCheckType = ctNone; ImgCheckState:
-  TCheckState = csUncheckedNormal; ImgEnabled: Boolean = False): Integer;
-
-// Determines the index into the check image list for the given node depending on the check type
-// and enabled state.
-
-const
-  // Four dimensional array consisting of image indices for the check type, the check state, the enabled state and the
-  // hot state.
-  CheckStateToCheckImage: array[ctCheckBox..ctButton, csUncheckedNormal..csMixedPressed, Boolean, Boolean] of Integer = (
-    // ctCheckBox, ctTriStateCheckBox
-    (
-      // csUncheckedNormal (disabled [not hot, hot], enabled [not hot, hot])
-      ((ckCheckUncheckedDisabled, ckCheckUncheckedDisabled), (ckCheckUncheckedNormal, ckCheckUncheckedHot)),
-      // csUncheckedPressed (disabled [not hot, hot], enabled [not hot, hot])
-      ((ckCheckUncheckedDisabled, ckCheckUncheckedDisabled), (ckCheckUncheckedPressed, ckCheckUncheckedPressed)),
-      // csCheckedNormal
-      ((ckCheckCheckedDisabled, ckCheckCheckedDisabled), (ckCheckCheckedNormal, ckCheckCheckedHot)),
-      // csCheckedPressed
-      ((ckCheckCheckedDisabled, ckCheckCheckedDisabled), (ckCheckCheckedPressed, ckCheckCheckedPressed)),
-      // csMixedNormal
-      ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedNormal, ckCheckMixedHot)),
-      // csMixedPressed
-      ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedPressed, ckCheckMixedPressed))
-    ),
-    // ctRadioButton
-    (
-      // csUncheckedNormal (disabled [not hot, hot], enabled [not hot, hot])
-      ((ckRadioUncheckedDisabled, ckRadioUncheckedDisabled), (ckRadioUncheckedNormal, ckRadioUncheckedHot)),
-      // csUncheckedPressed (disabled [not hot, hot], enabled [not hot, hot])
-      ((ckRadioUncheckedDisabled, ckRadioUncheckedDisabled), (ckRadioUncheckedPressed, ckRadioUncheckedPressed)),
-      // csCheckedNormal
-      ((ckRadioCheckedDisabled, ckRadioCheckedDisabled), (ckRadioCheckedNormal, ckRadioCheckedHot)),
-      // csCheckedPressed
-      ((ckRadioCheckedDisabled, ckRadioCheckedDisabled), (ckRadioCheckedPressed, ckRadioCheckedPressed)),
-      // csMixedNormal (should never appear with ctRadioButton)
-      ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedNormal, ckCheckMixedHot)),
-      // csMixedPressed (should never appear with ctRadioButton)
-      ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedPressed, ckCheckMixedPressed))
-    ),
-    // ctButton
-    (
-      // csUncheckedNormal (disabled [not hot, hot], enabled [not hot, hot])
-      ((ckButtonDisabled, ckButtonDisabled), (ckButtonNormal, ckButtonHot)),
-      // csUncheckedPressed (disabled [not hot, hot], enabled [not hot, hot])
-      ((ckButtonDisabled, ckButtonDisabled), (ckButtonPressed, ckButtonPressed)),
-      // csCheckedNormal
-      ((ckButtonDisabled, ckButtonDisabled), (ckButtonNormal, ckButtonHot)),
-      // csCheckedPressed
-      ((ckButtonDisabled, ckButtonDisabled), (ckButtonPressed, ckButtonPressed)),
-      // csMixedNormal (should never appear with ctButton)
-      ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedNormal, ckCheckMixedHot)),
-      // csMixedPressed (should never appear with ctButton)
-      ((ckCheckMixedDisabled, ckCheckMixedDisabled), (ckCheckMixedPressed, ckCheckMixedPressed))
-    )
-  );
-
-var
-  AType: TCheckType;
-
-begin
-  if not Assigned(Node) then
-    Result := CheckStateToCheckImage[ImgCheckType, ImgCheckState, ImgEnabled, False]
-  else if Node.CheckType = ctNone then
-    Result := -1
-  else
-  begin
-    AType := Node.CheckType;
-    if AType = ctTriStateCheckBox then
-      AType := ctCheckBox;
-    Result := CheckStateToCheckImage[AType, Node.CheckState, not (vsDisabled in Node.States) and Enabled,
-      Node = FCurrentHotNode];
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CheckImageListNeeded;
-begin
-  if FCheckImages <> nil then
-    Exit;
-  if FCheckImageKind = ckCustom then
-    FCheckImages := FCustomCheckImages
-  else
-  begin
-    FCheckImages := TBitmap.Create;
-    FCheckImages.Transparent := True;
-    FCheckImages.LoadFromLazarusResource(CheckImagesStrings[FCheckImageKind]);
-  end;
-end;
-
-function TBaseVirtualTree.GetClientRect: TRect;
-begin
-  Result := inherited;
-  //lclheader
-  if HandleAllocated and (hoVisible in FHeader.FOptions) then
-    Dec(Result.Bottom, FHeader.Height);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetColumnClass: TVirtualTreeColumnClass;
-
-begin
-  Result := TVirtualTreeColumn;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetHeaderClass: TVTHeaderClass;
-
-begin
-  Result := TVTHeader;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-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;
-  DefaultImages: TCustomImageList);
-
-// Retrieves the image index and an eventual customized image list for drawing.
-
-var
-  CustomImages: TCustomImageList;
-
-begin
-  with Info do
-  begin
-    ImageInfo[InfoIndex].Index := -1;
-    ImageInfo[InfoIndex].Ghosted := False;
-
-    CustomImages := DoGetImageIndex(Node, Kind, Column, ImageInfo[InfoIndex].Ghosted, ImageInfo[InfoIndex].Index);
-    if Assigned(CustomImages) then
-      ImageInfo[InfoIndex].Images := CustomImages
-    else
-      ImageInfo[InfoIndex].Images := DefaultImages;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetMaxRightExtend: Cardinal;
-
-// Determines the maximum with of the currently visible part of the tree, depending on the length
-// of the node texts. This method is used for determining the horizontal scroll range if no columns are used.
-
-var
-  Node,
-  NextNode: PVirtualNode;
-  TopPosition: Integer;
-  NodeLeft,
-  CurrentWidth: Integer;
-  WithCheck: Boolean;
-  CheckOffset: Integer;
-
-begin
-  Node := InternalGetNodeAt(0, 0, True, TopPosition);
-  Result := 0;
-  if toShowRoot in FOptions.FPaintOptions then
-    NodeLeft := (GetNodeLevel(Node) + 1) * FIndent
-  else
-    NodeLeft := GetNodeLevel(Node) * FIndent;
-
-  if Assigned(FStateImages) then
-    Inc(NodeLeft, FStateImages.Width + 2);
-  if Assigned(FImages) then
-    Inc(NodeLeft, FImages.Width + 2);
-  WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages);
-  if WithCheck then
-    CheckOffset := FCheckImages.Height + 2
-  else
-    CheckOffset := 0;
-
-  while Assigned(Node) do
-  begin
-    if not (vsInitialized in Node.States) then
-      InitNode(Node);
-
-    if WithCheck and (Node.CheckType <> ctNone) then
-      Inc(NodeLeft, CheckOffset);
-    CurrentWidth := DoGetNodeWidth(Node, NoColumn);
-    if Integer(Result) < (NodeLeft + CurrentWidth) then
-      Result := NodeLeft + CurrentWidth;
-    Inc(TopPosition, NodeHeight[Node]);
-    //lclheader: Height -> ClientHeight
-    if TopPosition > ClientHeight then
-      Break;
-
-    if WithCheck and (Node.CheckType <> ctNone) then
-      Dec(NodeLeft, CheckOffset);
-
-    // Get next visible node and update left node position.
-    NextNode := GetNextVisible(Node, True);
-    if NextNode = nil then
-      Break;
-    Inc(NodeLeft, CountLevelDifference(Node, NextNode) * Integer(FIndent));
-    Node := NextNode;
-  end;
-
-  Inc(Result, FMargin);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.GetNativeClipboardFormats(var Formats: TFormatEtcArray);
-
-// Returns the supported clipboard formats of the tree.
-
-begin
-  InternalClipboardFormats.EnumerateFormats(TVirtualTreeClass(ClassType), Formats, FClipboardFormats);
-  // Ask application/descendants for self defined formats.
-  DoGetUserClipboardFormats(Formats);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetOperationCanceled;
-
-begin
-  Result := FOperationCanceled and (FOperationCount > 0);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetOptionsClass: TTreeOptionsClass;
-
-begin
-  Result := TCustomVirtualTreeOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$i olemethods.inc}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.HandleHotTrack(X, Y: Integer);
-
-// Updates the current "hot" node.
-
-var
-  HitInfo: THitInfo;
-  CheckPositions: THitPositions;
-  ButtonIsHit,
-  DoInvalidate: Boolean;
-
-begin
-  DoInvalidate := False;
-  // Get information about the hit.
-  GetHitTestInfoAt(X, Y, True, HitInfo);
-
-  // Only make the new node being "hot" if its label is hit or full row selection is enabled.
-  CheckPositions := [hiOnItemLabel, hiOnItemCheckbox];
-
-  // If running under Windows Vista using the explorer theme hitting the buttons makes the node hot, too.
-  if (IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions)) then
-    Include(CheckPositions, hiOnItemButtonExact);
-
-  if (CheckPositions * HitInfo.HitPositions = []) and not (toFullRowSelect in FOptions.FSelectionOptions) then
-    HitInfo.HitNode := nil;
-  if (HitInfo.HitNode <> FCurrentHotNode) or (HitInfo.HitColumn <> FCurrentHotColumn) then
-  begin
-    DoInvalidate := (toHotTrack in FOptions.PaintOptions) or (toCheckSupport in FOptions.FMiscOptions);
-    DoHotChange(FCurrentHotNode, HitInfo.HitNode);
-    if Assigned(FCurrentHotNode) and DoInvalidate then
-      InvalidateNode(FCurrentHotNode);
-    FCurrentHotNode := HitInfo.HitNode;
-    FCurrentHotColumn := HitInfo.HitColumn;
-  end;
-
-  ButtonIsHit := (hiOnItemButtonExact in HitInfo.HitPositions) and (toHotTrack in FOptions.FPaintOptions);
-  if Assigned(FCurrentHotNode) and ((FHotNodeButtonHit <> ButtonIsHit) or DoInvalidate) then
-  begin
-    FHotNodeButtonHit := ButtonIsHit and (toHotTrack in FOptions.FPaintOptions);
-    InvalidateNode(FCurrentHotNode);
-  end
-  else
-    if not Assigned(FCurrentHotNode) then
-      FHotNodeButtonHit := False;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.HandleIncrementalSearch(CharCode: Word);
-
-var
-  Run, Stop: PVirtualNode;
-  GetNextNode: TGetNextNodeProc;
-  NewSearchText: String;
-  SingleLetter,
-  PreviousSearch: Boolean; // True if VK_BACK was sent.
-  SearchDirection: TVTSearchDirection;
-
-  //--------------- local functions -------------------------------------------
-
-  procedure SetupNavigation;
-
-  // If the search buffer is empty then we start searching with the next node after the last one, otherwise
-  // we continue with the last one. Node navigation function is set up too here, to avoid frequent checks.
-
-  var
-    FindNextNode: Boolean;
-
-  begin
-    FindNextNode := (Length(FSearchBuffer) = 0) or (Run = nil) or SingleLetter or PreviousSearch;
-    case FIncrementalSearch of
-      isVisibleOnly:
-        if SearchDirection = sdForward then
-        begin
-          GetNextNode := GetNextVisible;
-          if FindNextNode then
-          begin
-            if Run = nil then
-              Run := GetFirstVisible(nil, True)
-            else
-            begin
-              Run := GetNextVisible(Run, True);
-              // Do wrap around.
-              if Run = nil then
-                Run := GetFirstVisible(nil, True);
-            end;
-          end;
-        end
-        else
-        begin
-          GetNextNode := GetPreviousVisible;
-          if FindNextNode then
-          begin
-            if Run = nil then
-              Run := GetLastVisible(nil, True)
-            else
-            begin
-              Run := GetPreviousVisible(Run, True);
-              // Do wrap around.
-              if Run = nil then
-                Run := GetLastVisible(nil, True);
-            end;
-          end;
-        end;
-      isInitializedOnly:
-        if SearchDirection = sdForward then
-        begin
-          GetNextNode := GetNextNoInit;
-          if FindNextNode then
-          begin
-            if Run = nil then
-              Run := GetFirstNoInit
-            else
-            begin
-              Run := GetNextNoInit(Run);
-              // Do wrap around.
-              if Run = nil then
-                Run := GetFirstNoInit;
-            end;
-          end;
-        end
-        else
-        begin
-          GetNextNode := GetPreviousNoInit;
-          if FindNextNode then
-          begin
-            if Run = nil then
-              Run := GetLastNoInit
-            else
-            begin
-              Run := GetPreviousNoInit(Run);
-              // Do wrap around.
-              if Run = nil then
-                Run := GetLastNoInit;
-            end;
-          end;
-        end;
-    else
-      // isAll
-      if SearchDirection = sdForward then
-      begin
-        GetNextNode := GetNext;
-        if FindNextNode then
-        begin
-          if Run = nil then
-            Run := GetFirst
-          else
-          begin
-            Run := GetNext(Run);
-            // Do wrap around.
-            if Run = nil then
-              Run := GetFirst;
-          end;
-        end;
-      end
-      else
-      begin
-        GetNextNode := GetPrevious;
-        if FindNextNode then
-        begin
-          if Run = nil then
-            Run := GetLast
-          else
-          begin
-            Run := GetPrevious(Run);
-            // Do wrap around.
-            if Run = nil then
-              Run := GetLast;
-          end;
-        end;
-      end;
-    end;
-  end;
-
-  //---------------------------------------------------------------------------
-  //todo: reimplement
-  {$ifndef INCOMPLETE_WINAPI}
-  function CodePageFromLocale(Language: DWord): Integer;
-
-  // Determines the code page for a given locale.
-  // Unfortunately there is no easier way than this, currently.
-
-  var
-    Buf: array[0..6] of Char;
-
-  begin
-    GetLocaleInfo(Language, LOCALE_IDEFAULTANSICODEPAGE, Buf, 6);
-    Result := StrToIntDef(Buf, GetACP);
-  end;
-
-  //---------------------------------------------------------------------------
-
-  function KeyUnicode(C: Char): WideChar;
-
-  // Converts the given character into its corresponding Unicode character
-  // depending on the active keyboard layout.
-
-  begin
-    MultiByteToWideChar(CodePageFromLocale(GetKeyboardLayout(0) and $FFFF),
-      MB_USEGLYPHCHARS, @C, 1, @Result, 1);
-  end;
-  {$endif}
-  //--------------- end local functions ---------------------------------------
-
-var
-  FoundMatch: Boolean;
-  NewChar: WideChar;
-
-begin
-  //todo: handle correctly unicode char after WideString -> String conversion
-  KillTimer(Handle, SearchTimer);
-
-  if FIncrementalSearch <> isNone then
-  begin
-    if CharCode <> 0 then
-    begin
-      DoStateChange([tsIncrementalSearching]);
-
-      // Convert the given virtual key code into a Unicode character based on the current locale.
-      //todo: reimplement
-      {$ifndef INCOMPLETE_WINAPI}
-      NewChar := KeyUnicode(Char(CharCode));
-      {$else}
-      NewChar := Char(CharCode);
-      {$endif}
-      PreviousSearch := NewChar = WideChar(VK_BACK);
-      // We cannot do a search with an empty search buffer.
-      if not PreviousSearch or (FSearchBuffer <> '') then
-      begin
-        // Determine which method to use to advance nodes and the start node to search from.
-        case FSearchStart of
-          ssAlwaysStartOver:
-            Run := nil;
-          ssFocusedNode:
-            Run := FFocusedNode;
-        else // ssLastHit
-          Run := FLastSearchNode;
-        end;
-
-        // Make sure the start node corresponds to the search criterion.
-        if Assigned(Run) then
-        begin
-          case FIncrementalSearch of
-            isInitializedOnly:
-              if not (vsInitialized in Run.States) then
-                Run := nil;
-            isVisibleOnly:
-              if not FullyVisible[Run] then
-                Run := nil;
-          end;
-        end;
-        Stop := Run;
-
-        // VK_BACK temporarily changes search direction to opposite mode.
-        if PreviousSearch then
-        begin
-          if SearchDirection = sdBackward then
-            SearchDirection := sdForward
-          else
-            SearchDirection := sdBackward
-        end
-        else
-          SearchDirection := FSearchDirection;
-        // The "single letter mode" is used to advance quickly from node to node when pressing the same key several times.
-        SingleLetter := (Length(FSearchBuffer) = 1) and not PreviousSearch and (FSearchBuffer[1] = NewChar);
-        // However if the current hit (if there is one) would fit also with a repeated character then
-        // don't use single letter mode.
-        if SingleLetter and (DoIncrementalSearch(Run, FSearchBuffer + NewChar) = 0) then
-          SingleLetter := False;
-        SetupNavigation;
-        FoundMatch := False;
-
-        if Assigned(Run) then
-        begin
-          if SingleLetter then
-            NewSearchText := FSearchBuffer
-          else
-            if PreviousSearch then
-            begin
-              SetLength(FSearchBuffer, Length(FSearchBuffer) - 1);
-              NewSearchText := FSearchBuffer;
-            end
-            else
-              NewSearchText := FSearchBuffer + NewChar;
-
-          repeat
-            if DoIncrementalSearch(Run, NewSearchText) = 0 then
-            begin
-              FoundMatch := True;
-              Break;
-            end;
-
-            // Advance to next node if we have not found a match.
-            Run := GetNextNode(Run);
-            // Do wrap around start or end of tree.
-            if (Run <> Stop) and (Run = nil) then
-              SetupNavigation;
-          until Run = Stop;
-        end;
-
-        if FoundMatch then
-        begin
-          ClearSelection;
-          FSearchBuffer := NewSearchText;
-          FLastSearchNode := Run;
-          FocusedNode := Run;
-          Selected[Run] := True;
-          FLastSearchNode := Run;
-        end
-        else
-          // Play an acoustic signal if nothing could be found but don't beep if only the currently
-          // focused node matches.
-          if Assigned(Run) and (DoIncrementalSearch(Run, NewSearchText) <> 0) then
-            Beep;
-      end;
-    end;
-
-    // Restart search timeout interval.
-    SetTimer(Handle, SearchTimer, FSearchTimeout, nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.HandleMouseDblClick(var Message: TLMMouse; const HitInfo: THitInfo);
-
-var
-  NewCheckState: TCheckState;
-  Node: PVirtualNode;
-  MayEdit: Boolean;
-
-begin
-  MayEdit := not (tsEditing in FStates) and (toEditOnDblClick in FOptions.FMiscOptions);
-  if tsEditPending in FStates then
-  begin
-    KillTimer(Handle, EditTimer);
-    DoStateChange([], [tsEditPending]);
-  end;
-
-  if not (tsEditing in FStates) or DoEndEdit then
-  begin
-    if HitInfo.HitColumn = FHeader.FColumns.FClickIndex then
-      DoColumnDblClick(HitInfo.HitColumn, KeysToShiftState(Message.Keys));
-
-    Node := nil;
-    if (hiOnItem in HitInfo.HitPositions) and (hitInfo.HitColumn > NoColumn) and
-       (coFixed in FHeader.FColumns[HitInfo.HitColumn].FOptions) then
-    begin
-      if hiUpperSplitter in HitInfo.HitPositions then
-        Node := GetPreviousVisible(HitInfo.HitNode, True)
-      else if  hiLowerSplitter in HitInfo.HitPositions then
-        Node := HitInfo.HitNode
-    end;
-
-    if Assigned(Node) and (Node <> FRoot) and (toNodeHeightDblClickResize in FOptions.FMiscOptions) then
-    begin
-      if DoNodeHeightDblClickResize(Node, HitInfo.HitColumn, KeysToShiftState(Message.Keys), Point(Message.XPos, Message.YPos)) then
-      begin
-        SetNodeHeight(Node, FDefaultNodeHeight);
-        UpdateWindow(Handle);
-        MayEdit := False;
-      end;
-    end
-    else if hiOnItemCheckBox in HitInfo.HitPositions then
-    begin
-      if (FStates * [tsMouseCheckPending, tsKeyCheckPending] = []) and not (vsDisabled in HitInfo.HitNode.States) then
-      begin
-        with HitInfo.HitNode^ do
-          NewCheckState := DetermineNextCheckState(CheckType, CheckState);
-        if DoChecking(HitInfo.HitNode, NewCheckState) then
-        begin
-          DoStateChange([tsMouseCheckPending]);
-          FCheckNode := HitInfo.HitNode;
-          FPendingCheckState := NewCheckState;
-          FCheckNode.CheckState := PressedState[FCheckNode.CheckState];
-          InvalidateNode(HitInfo.HitNode);
-          MayEdit := False;
-        end;
-      end;
-    end
-    else
-    begin
-      if hiOnItemButton in HitInfo.HitPositions then
-      begin
-        ToggleNode(HitInfo.HitNode);
-        MayEdit := False;
-      end
-      else
-      begin
-        if toToggleOnDblClick in FOptions.FMiscOptions then
-        begin
-          if ((([hiOnItemButton, hiOnItemLabel, hiOnNormalIcon, hiOnStateIcon] * HitInfo.HitPositions) <> []) or
-            ((toFullRowSelect in FOptions.FSelectionOptions) and Assigned(HitInfo.HitNode))) then
-          begin
-            ToggleNode(HitInfo.HitNode);
-            MayEdit := False;
-          end;
-        end;
-      end;
-    end;
-  end;
-
-  if MayEdit and Assigned(FFocusedNode) and (FFocusedNode = HitInfo.HitNode) and
-    (FFocusedColumn = HitInfo.HitColumn) and CanEdit(FFocusedNode, HitInfo.HitColumn) then
-  begin
-    DoStateChange([tsEditPending]);
-    FEditColumn := FFocusedcolumn;
-    SetTimer(Handle, EditTimer, FEditDelay, nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.HandleMouseDown(var Message: TLMMouse; var HitInfo: THitInfo);
-
-// centralized mouse button down handling
-
-var
-  LastFocused: PVirtualNode;
-  Column: TColumnIndex;
-  ShiftState: TShiftState;
-
-  // helper variables to shorten boolean equations/expressions
-  AutoDrag,              // automatic (or allowed) drag start
-  IsHit,                 // the node's caption or images are hit
-  IsCellHit,             // for grid extension or full row select (but not check box, button)
-  IsAnyHit,              // either IsHit or IsCellHit
-  IsHeightTracking,      // height tracking
-  MultiSelect,           // multiselection is enabled
-  ShiftEmpty,            // ShiftState = []
-  NodeSelected: Boolean; // the new node (if any) is selected
-  NewColumn: Boolean;    // column changed
-  NewNode: Boolean;      // Node changed.
-  NeedChange: Boolean;   // change event is required for selection change
-  CanClear: Boolean;
-  NewCheckState: TCheckState;
-  AltPressed: Boolean;   // Pressing the Alt key enables special processing for selection.
-  FullRowDrag: Boolean;  // Start dragging anywhere within a node's bound.
-  NodeRect: TRect;
-  FocusCanChange: Boolean;
-begin
-  if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then
-  begin
-    StopWheelPanning;
-    Exit;
-  end;
-
-  if tsEditPending in FStates then
-  begin
-    KillTimer(Handle, EditTimer);
-    DoStateChange([], [tsEditPending]);
-  end;
-
-  if not (tsEditing in FStates) or DoEndEdit then
-  begin
-    // Focus change. Don't use the SetFocus method as this does not work for MDI windows.
-    if not Focused and CanFocus then
-    begin
-      LCLIntf.SetFocus(Handle);
-      // Repeat the hit test as an OnExit event might got triggered that could modify the tree.
-      GetHitTestInfoAt(Message.XPos, Message.YPos, True, HitInfo);
-    end;
-
-    // Keep clicked column in case the application needs it.
-    FHeader.FColumns.FClickIndex := HitInfo.HitColumn;
-
-    // Change column only if we have hit the node label.
-    if (hiOnItemLabel in HitInfo.HitPositions) or
-      (toFullRowSelect in FOptions.FSelectionOptions) or
-      (toGridExtensions in FOptions.FMiscOptions) then
-    begin
-      NewColumn := FFocusedColumn <> HitInfo.HitColumn;
-      if toExtendedFocus in FOptions.FSelectionOptions then
-        Column := HitInfo.HitColumn
-      else
-        Column := FHeader.MainColumn;
-    end
-    else
-    begin
-      NewColumn := False;
-      Column := FFocusedColumn;
-    end;
-
-    if NewColumn and
-       (not FHeader.AllowFocus(Column)) then
-    begin
-      NewColumn := False;
-      Column := FFocusedColumn;
-    end;
-
-    NewNode := FFocusedNode <> HitInfo.HitNode;
-
-    // Translate keys and filter out shift and control key.
-    ShiftState := KeysToShiftState(Message.Keys) * [ssShift, ssCtrlOS, ssAlt];
-    if ssAlt in ShiftState then
-    begin
-      AltPressed := True;
-      // Remove the Alt key from the shift state. It is not meaningful there.
-      Exclude(ShiftState, ssAlt);
-    end
-    else
-      AltPressed := False;
-
-    // Various combinations determine what states the tree enters now.
-    // We initialize shorthand variables to avoid the following expressions getting too large
-    // and to avoid repeative expensive checks.
-    IsHit := not AltPressed and not (toSimpleDrawSelection in FOptions.FSelectionOptions) and
-             ((hiOnItemLabel in HitInfo.HitPositions) or (hiOnNormalIcon in HitInfo.HitPositions));
-    IsCellHit := not AltPressed and not IsHit and Assigned(HitInfo.HitNode) and
-      ([hiOnItemButton, hiOnItemCheckBox] * HitInfo.HitPositions = []) and
-      ((toFullRowSelect in FOptions.FSelectionOptions) or
-      ((toGridExtensions in FOptions.FMiscOptions) and (HitInfo.HitColumn > NoColumn)));
-    IsAnyHit := IsHit or IsCellHit;
-    MultiSelect := toMultiSelect in FOptions.FSelectionOptions;
-    ShiftEmpty := ShiftState = [];
-    NodeSelected := IsAnyHit and (vsSelected in HitInfo.HitNode.States);
-    FullRowDrag := toFullRowDrag in FOptions.FMiscOptions;
-    IsHeightTracking := (Message.Msg = LM_LBUTTONDOWN) and
-                        (toNodeHeightResize in FOptions.FMiscOptions) and (hiOnItem in HitInfo.HitPositions) and
-                        ([hiUpperSplitter, hiLowerSplitter] * HitInfo.HitPositions <> []) and
-                        ((HitInfo.HitColumn > NoColumn) and (coFixed in FHeader.FColumns[HitInfo.HitColumn].Options));
-
-    // Dragging might be started in the inherited handler manually (which is discouraged for stability reasons)
-    // the test for manual mode is done below (after the focused node is set).
-    AutoDrag := ((DragMode = dmAutomatic) or Dragging) and (not IsCellHit or FullRowDrag);
-
-    // Query the application to learn if dragging may start now (if set to dmManual).
-    if Assigned(HitInfo.HitNode) and not AutoDrag and (DragMode = dmManual) then
-      AutoDrag := DoBeforeDrag(HitInfo.HitNode, Column) and (not IsCellHit or FullRowDrag);
-
-    // handle node height tracking
-    if IsHeightTracking then
-    begin
-      if hiUpperSplitter in HitInfo.HitPositions then
-        FHeightTrackNode := GetPreviousVisible(HitInfo.HitNode, True)
-      else
-        FHeightTrackNode := HitInfo.HitNode;
-
-      if Assigned(FHeightTrackNode) and (FHeightTrackNode <> FRoot) then
-      begin
-        FHeightTrackColumn := HitInfo.HitColumn;
-        NodeRect := GetDisplayRect(FHeightTrackNode, FHeightTrackColumn, False);
-        FHeightTrackPoint := Point(NodeRect.Left, NodeRect.Top);
-        DoStateChange([tsNodeHeightTrackPending]);
-        Exit;
-      end;
-    end;
-
-    // handle button clicks
-    if (hiOnItemButton in HitInfo.HitPositions) and (vsHasChildren in HitInfo.HitNode.States) then
-    begin
-      ToggleNode(HitInfo.HitNode);
-      Exit;
-    end;
-
-    // check event
-    if hiOnItemCheckBox in HitInfo.HitPositions then
-    begin
-      if (FStates * [tsMouseCheckPending, tsKeyCheckPending] = []) and not (vsDisabled in HitInfo.HitNode.States) then
-      begin
-        with HitInfo.HitNode^ do
-          NewCheckState := DetermineNextCheckState(CheckType, CheckState);
-        if DoChecking(HitInfo.HitNode, NewCheckState) then
-        begin
-          DoStateChange([tsMouseCheckPending]);
-          FCheckNode := HitInfo.HitNode;
-          FPendingCheckState := NewCheckState;
-          FCheckNode.CheckState := PressedState[FCheckNode.CheckState];
-          InvalidateNode(HitInfo.HitNode);
-        end;
-      end;
-      Exit;
-    end;
-
-    // Keep this node's level in case we need it for constraint selection.
-    if (FRoot.ChildCount > 0) and ShiftEmpty or (FSelectionCount = 0) then
-      if Assigned(HitInfo.HitNode) then
-        FLastSelectionLevel := GetNodeLevel(HitInfo.HitNode)
-      else
-        FLastSelectionLevel := GetNodeLevel(GetLastVisibleNoInit(nil, True));
-
-    // pending clearance
-    if MultiSelect and ShiftEmpty and not (hiOnItemCheckbox in HitInfo.HitPositions) and IsAnyHit and AutoDrag and
-      NodeSelected and not FSelectionLocked then
-      DoStateChange([tsClearPending]);
-
-    // immediate clearance
-    // Determine for the right mouse button if there is a popup menu. In this case and if drag'n drop is pending
-    // the current selection has to stay as it is.
-    with HitInfo, Message do
-      CanClear := not AutoDrag and
-        (not (tsRightButtonDown in FStates) or not HasPopupMenu(HitNode, HitColumn, Point(XPos, YPos)));
-
-    //lcl
-    FocusCanChange := DoFocusChanging(FFocusedNode, HitInfo.HitNode, FFocusedColumn, Column);
-
-    if not FSelectionLocked and FocusCanChange and ((not (IsAnyHit or FullRowDrag) and MultiSelect and ShiftEmpty) or
-      (IsAnyHit and (not NodeSelected or (NodeSelected and CanClear)) and (ShiftEmpty or not MultiSelect))) then
-    begin
-      Assert(not (tsClearPending in FStates), 'Pending and direct clearance are mutual exclusive!');
-
-      // If the currently hit node was already selected then we have to reselect it again after clearing the current
-      // selection, but without a change event if it is the only selected node.
-      // The same applies if the Alt key is pressed, which allows to start drawing the selection rectangle also
-      // on node captions and images. Here the previous selection state does not matter, though.
-      if NodeSelected or (AltPressed and Assigned(HitInfo.HitNode) and (HitInfo.HitColumn = FHeader.MainColumn)) then
-      begin
-        NeedChange := FSelectionCount > 1;
-        InternalClearSelection;
-        InternalAddToSelection(HitInfo.HitNode, True);
-        if NeedChange then
-        begin
-          Invalidate;
-          Change(nil);
-        end;
-      end
-      else
-        ClearSelection;
-    end;
-
-    // pending node edit
-    if Focused and
-      ((hiOnItemLabel in HitInfo.HitPositions) or ((toGridExtensions in FOptions.FMiscOptions) and
-      (hiOnItem in HitInfo.HitPositions))) and NodeSelected and not NewColumn and ShiftEmpty then
-      DoStateChange([tsEditPending]);
-
-    // User starts a selection with a selection rectangle.
-    if not (toDisableDrawSelection in FOptions.FSelectionOptions) and not (IsHit or FullRowDrag) and MultiSelect then
-    begin
-      SetCapture(Handle);
-      DoStateChange([tsDrawSelPending]);
-      FDrawSelShiftState := ShiftState;
-      FNewSelRect := Rect(Message.XPos + FEffectiveOffsetX, Message.YPos - FOffsetY, Message.XPos + FEffectiveOffsetX,
-        Message.YPos - FOffsetY);
-      //lclheader
-      if hoVisible in FHeader.Options then
-        OffsetRect(FNewSelRect, 0, -FHeader.Height);
-      {$ifdef DEBUG_VTV}Logger.Send([lcSelection],'FNewSelRect', FNewSelRect);{$endif}
-
-      FLastSelRect := Rect(0, 0, 0, 0);
-      if not IsCellHit then
-        Exit;
-    end;
-
-    // Keep current mouse position.
-    FLastClickPos := Point(Message.XPos, Message.YPos);
-
-    // Handle selection and node focus change.
-    if IsAnyHit and FocusCanChange then
-    begin
-      if NewColumn then
-      begin
-        InvalidateColumn(FFocusedColumn);
-        InvalidateColumn(Column);
-        FFocusedColumn := Column;
-      end;
-      if DragKind = dkDock then
-      begin
-        KillTimer(Handle, ScrollTimer);
-        DoStateChange([], [tsScrollPending, tsScrolling]);
-      end;
-      // Get the currently focused node to make multiple multi-selection blocks possible.
-      LastFocused := FFocusedNode;
-      if NewNode then
-        DoFocusNode(HitInfo.HitNode, False);
-
-      if MultiSelect and not ShiftEmpty then
-        HandleClickSelection(LastFocused, HitInfo.HitNode, ShiftState, AutoDrag)
-      else
-      begin
-        if ShiftEmpty then
-          FRangeAnchor := HitInfo.HitNode;
-
-        // If the hit node is not yet selected then do it now.
-        if not NodeSelected then
-          AddToSelection(HitInfo.HitNode);
-      end;
-
-      if NewNode or NewColumn then
-      begin
-        ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions,
-                       not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions));
-        DoFocusChange(FFocusedNode, FFocusedColumn);
-      end;
-    end;
-
-    // Drag'n drop initiation
-    // If we lost focus in the interim the button states would be cleared in WM_KILLFOCUS.
-    if AutoDrag and IsAnyHit and (FStates * [tsLeftButtonDown, tsRightButtonDown, tsMiddleButtonDown] <> []) then
-      BeginDrag(False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.HandleMouseUp(Keys: PtrUInt; const HitInfo: THitInfo);
-
-// Counterpart to the mouse down handler.
-
-var
-  ReselectFocusedNode: Boolean;
-
-begin
-  ReleaseCapture;
-
-  if not (tsVCLDragPending in FStates) then
-  begin
-    // reset pending or persistent states
-    if IsMouseSelecting then
-    begin
-      DoStateChange([], [tsDrawSelecting, tsDrawSelPending, tsToggleFocusedSelection]);
-      Invalidate;
-    end;
-
-    if tsClearPending in FStates then
-    begin
-      ReselectFocusedNode := Assigned(FFocusedNode) and (vsSelected in FFocusedNode.States);
-      ClearSelection;
-      if ReselectFocusedNode then
-        AddToSelection(FFocusedNode);
-    end;
-
-    if (tsToggleFocusedSelection in FStates) and (HitInfo.HitNode = FFocusedNode) then
-    begin
-      if vsSelected in HitInfo.HitNode.States then
-        RemoveFromSelection(HitInfo.HitNode)
-      else
-        AddToSelection(HitInfo.HitNode);
-      InvalidateNode(HitInfo.HitNode);
-    end;
-
-    DoStateChange([], [tsOLEDragPending, tsOLEDragging, tsClearPending, tsDrawSelPending, tsToggleFocusedSelection,
-      tsScrollPending, tsScrolling]);
-    KillTimer(Handle, ScrollTimer);
-
-    if tsMouseCheckPending in FStates then
-    begin
-      DoStateChange([], [tsMouseCheckPending]);
-      // Is the mouse still over the same node?
-      if (HitInfo.HitNode = FCheckNode) and (hiOnItem in HitInfo.HitPositions) then
-        DoCheckClick(FCheckNode, FPendingCheckState)
-      else
-        FCheckNode.CheckState := UnpressedState[FCheckNode.CheckState];
-      InvalidateNode(FCheckNode);
-      FCheckNode := nil;
-    end;
-
-    if (FHeader.FColumns.FClickIndex > NoColumn) and (FHeader.FColumns.FClickIndex = HitInfo.HitColumn) then
-      DoColumnClick(HitInfo.HitColumn, KeysToShiftState(Keys));
-
-    // handle a pending edit event
-    if tsEditPending in FStates then
-    begin
-      // Is the mouse still over the same node?
-      if (HitInfo.HitNode = FFocusedNode) and (hiOnItem in HitInfo.HitPositions) and
-         CanEdit(FFocusedNode, HitInfo.HitColumn) and (toEditOnClick in FOptions.FMiscOptions) then
-      begin
-        FEditColumn := FFocusedColumn;
-        SetTimer(Handle, EditTimer, FEditDelay, nil);
-      end
-      else
-        DoStateChange([], [tsEditPending]);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.HasImage(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex): Boolean;
-
-// Determines whether the given node has got an image of the given kind in the given column.
-// Returns True if so, otherwise False.
-
-var
-  Ghosted: Boolean;
-  Index: Integer;
-
-begin
-  Index := -1;
-  Ghosted := False;
-  DoGetImageIndex(Node, Kind, Column, Ghosted, Index);
-  Result := Index > -1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.HasPopupMenu(Node: PVirtualNode; Column: TColumnIndex; const Pos: TPoint): Boolean;
-
-// Determines whether the tree got a popup menu, either in its PopupMenu property, via the OnGetPopupMenu event or
-// through inheritance. The latter case must be checked by the descendant which must override this method.
-
-begin
-  Result := Assigned(PopupMenu) or Assigned(DoGetPopupMenu(Node, Column, Pos));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InitChildren(Node: PVirtualNode);
-
-// Initiates the initialization of the child number of the given node.
-
-var
-  Count: Cardinal;
-
-begin
-  if Assigned(Node) and (Node <> FRoot) and (vsHasChildren in Node.States) then
-  begin
-    Count := Node.ChildCount;
-    DoInitChildren(Node, Count);
-    if Count = 0 then
-    begin
-      // Remove any child node which is already there.
-      DeleteChildren(Node);
-      Exclude(Node.States, vsHasChildren);
-    end
-    else
-      SetChildCount(Node, Count);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InitNode(Node: PVirtualNode);
-
-// Initiates the initialization of the given node to allow the application to load needed data for it.
-
-var
-  InitStates: TVirtualNodeInitStates;
-
-begin
-  with Node^ do
-  begin
-    Include(States, vsInitialized);
-    InitStates := [];
-    if Parent = FRoot then
-      DoInitNode(nil, Node, InitStates)
-    else
-      DoInitNode(Parent, Node, InitStates);
-    if ivsDisabled in InitStates then
-      Include(States, vsDisabled);
-    if ivsHasChildren in InitStates then
-      Include(States, vsHasChildren);
-    if ivsSelected in InitStates then
-    begin
-      FSingletonNodeArray[0] := Node;
-      InternalAddToSelection(FSingletonNodeArray, 1, False);
-    end;
-    if ivsMultiline in InitStates then
-      Include(States, vsMultiline);
-
-    // Expanded may already be set (when called from ReinitNode) or be set in DoInitNode, allow both.
-    if (vsExpanded in Node.States) xor (ivsExpanded in InitStates) then
-    begin
-      // Expand node if not yet done (this will automatically initialize child nodes).
-      if ivsExpanded in InitStates then
-        ToggleNode(Node)
-      else
-        // If the node already was expanded then explicitly trigger child initialization.
-        if vsHasChildren in Node.States then
-          InitChildren(Node);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InternalAddFromStream(Stream: TStream; Version: Integer; Node: PVirtualNode);
-
-// Loads all details for Node (including its children) from the given stream.
-// Because the new nodes might be selected this method also fixes the selection array.
-
-var
-  Stop: PVirtualNode;
-  Index: Integer;
-  LastTotalHeight: Cardinal;
-  WasFullyVisible: Boolean;
-
-begin
-  Assert(Node <> FRoot, 'The root node cannot be loaded from stream.');
-
-  // Keep the current total height value of Node as it has already been applied
-  // but might change in the load and fixup code. We have to adjust that afterwards.
-  LastTotalHeight := Node.TotalHeight;
-  WasFullyVisible := FullyVisible[Node];
-
-  // Read in the new nodes.
-  ReadNode(Stream, Version, Node);
-
-  // One time update of node-internal states and the global visibility counter.
-  // This is located here to ease and speed up the loading process.
-  FixupTotalCount(Node);
-  AdjustTotalCount(Node.Parent, Node.TotalCount - 1, True); // -1 because Node itself was already set.
-  FixupTotalHeight(Node);
-  AdjustTotalHeight(Node.Parent, Node.TotalHeight - LastTotalHeight, True);
-
-  // New nodes are always visible, so the visible node count has been increased already.
-  // If Node is now invisible we have to take back this increment and don't need to add any visible child node.
-  if not FullyVisible[Node] then
-  begin
-    if WasFullyVisible then
-      Dec(FVisibleCount);
-  end
-  else
-    // It can never happen that the node is now fully visible but was not before as this would require
-    // that the visibility state of one of its parents has changed, which cannot happen during loading.
-    Inc(FVisibleCount, CountVisibleChildren(Node));
-
-  // Fix selection array.
-  ClearTempCache;
-  if Node = FRoot then
-    Stop := nil
-  else
-    Stop := Node.NextSibling;
-
-  if toMultiSelect in FOptions.FSelectionOptions then
-  begin
-    // Add all nodes which were selected before to the current selection (unless they are already there).
-    while Node <> Stop do
-    begin
-      if (vsSelected in Node.States) and not FindNodeInSelection(Node, Index, 0, High(FSelection)) then
-        InternalCacheNode(Node);
-      Node := GetNextNoInit(Node);
-    end;
-    if FTempNodeCount > 0 then
-      AddToSelection(FTempNodeCache, FTempNodeCount, True);
-    ClearTempCache;
-  end
-  else // No further selected nodes allowed so delete the corresponding flag in all new nodes.
-    while Node <> Stop do
-    begin
-      Exclude(Node.States, vsSelected);
-      Node := GetNextNoInit(Node);
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.InternalAddToSelection(Node: PVirtualNode; ForceInsert: Boolean): Boolean;
-
-begin
-  Assert(Assigned(Node), 'Node must not be nil!');
-  FSingletonNodeArray[0] := Node;
-  Result := InternalAddToSelection(FSingletonNodeArray, 1, ForceInsert);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.InternalAddToSelection(const NewItems: TNodeArray; NewLength: Integer;
-  ForceInsert: Boolean): Boolean;
-
-// Internal version of method AddToSelection which does not trigger OnChange events
-
-var
-  I, J: Integer;
-  CurrentEnd: Integer;
-  Constrained,
-  SiblingConstrained: Boolean;
-
-begin
-  // The idea behind this code is to use a kind of reverse merge sort. QuickSort is quite fast
-  // and would do the job here too but has a serious problem with already sorted lists like FSelection.
-
-  // 1) Remove already selected items, mark all other as being selected.
-  if ForceInsert then
-  begin
-    for I := 0 to NewLength - 1 do
-      Include(NewItems[I].States, vsSelected);
-  end
-  else
-  begin
-    Constrained := toLevelSelectConstraint in FOptions.FSelectionOptions;
-    if Constrained and (FLastSelectionLevel = -1) then
-      FLastSelectionLevel := GetNodeLevel(NewItems[0]);
-    SiblingConstrained := toSiblingSelectConstraint in FOptions.FSelectionOptions;
-    if SiblingConstrained and (FRangeAnchor = nil) then
-      FRangeAnchor := NewItems[0];
-
-    for I := 0 to NewLength - 1 do
-      if ([vsSelected, vsDisabled] * NewItems[I].States <> []) or
-         (Constrained and (Cardinal(FLastSelectionLevel) <> GetNodeLevel(NewItems[I]))) or
-         (SiblingConstrained and (FRangeAnchor.Parent <> NewItems[I].Parent)) then
-        Inc(PtrUInt(NewItems[I]))
-      else
-        Include(NewItems[I].States, vsSelected);
-  end;
-
-  I := PackArray(NewItems, NewLength);
-  if I > -1 then
-    NewLength := I;
-
-  Result := NewLength > 0;
-  if Result then
-  begin
-    // 2) Sort the new item list so we can easily traverse it.
-    if NewLength > 1 then
-      QuickSort(NewItems, 0, NewLength - 1);
-    // 3) Make room in FSelection for the new items.
-    if FSelectionCount + NewLength >= Length(FSelection) then
-      SetLength(FSelection, FSelectionCount + NewLength);
-
-    // 4) Merge in new items
-    J := NewLength - 1;
-    CurrentEnd := FSelectionCount - 1;
-
-    while J >= 0 do
-    begin
-      // First insert all new entries which are greater than the greatest entry in the old list.
-      // If the current end marker is < 0 then there's nothing more to move in the selection
-      // array and only the remaining new items must be inserted.
-      if CurrentEnd >= 0 then
-      begin
-        while (J >= 0) and (NewItems[J] > FSelection[CurrentEnd]) do
-        begin
-          FSelection[CurrentEnd + J + 1] := NewItems[J];
-          Dec(J);
-        end;
-        // early out if nothing more needs to be copied
-        if J < 0 then
-          Break;
-      end
-      else
-      begin
-        // insert remaining new entries at position 0
-        Move(NewItems[0], FSelection[0], (J + 1) * SizeOf(Pointer));
-        // nothing more to do so exit main loop
-        Break;
-      end;
-
-      // find the last entry in the remaining selection list which is smaller then the largest
-      // entry in the remaining new items list
-      FindNodeInSelection(NewItems[J], I, 0, CurrentEnd);
-      Dec(I);
-      // move all entries which are greater than the greatest entry in the new items list up
-      // so the remaining gap travels down to where new items must be inserted
-      Move(FSelection[I + 1], FSelection[I + J + 2], (CurrentEnd - I) * SizeOf(Pointer));
-      CurrentEnd := I;
-    end;
-
-    Inc(FSelectionCount, NewLength);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InternalCacheNode(Node: PVirtualNode);
-
-// Adds the given node to the temporary node cache (used when collecting possibly large amounts of nodes).
-
-var
-  Len: Cardinal;
-
-begin
-  Len := Length(FTempNodeCache);
-  if FTempNodeCount = Len then
-  begin
-    if Len < 100 then
-      Len := 100
-    else
-      Len := Len + Len div 10;
-    SetLength(FTempNodeCache, Len);
-  end;
-  FTempNodeCache[FTempNodeCount] := Node;
-  Inc(FTempNodeCount);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InternalClearSelection;
-
-var
-  Count: Integer;
-
-begin
-  // It is possible that there are invalid node references in the selection array
-  // if the tree update is locked and changes in the structure were made.
-  // Handle this potentially dangerous situation by packing the selection array explicitely.
-  if FUpdateCount > 0 then
-  begin
-    Count := PackArray(FSelection, FSelectionCount);
-    if Count > -1 then
-    begin
-      FSelectionCount := Count;
-      SetLength(FSelection, FSelectionCount);
-    end;
-  end;
-
-  while FSelectionCount > 0 do
-  begin
-    Dec(FSelectionCount);
-    Exclude(FSelection[FSelectionCount].States, vsSelected);
-  end;
-  ResetRangeAnchor;
-  FSelection := nil;
-  DoStateChange([], [tsClearPending]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InternalConnectNode(Node, Destination: PVirtualNode; Target: TBaseVirtualTree;
-  Mode: TVTNodeAttachMode);
-
-// Connects Node with Destination depending on Mode.
-// No error checking takes place. Node as well as Destination must be valid. Node must never be a root node and
-// Destination must not be a root node if Mode is amInsertBefore or amInsertAfter.
-
-var
-  Run: PVirtualNode;
-
-begin
-  // Keep in mind that the destination node might belong to another tree.
-  with Target do
-  begin
-    case Mode of
-      amInsertBefore:
-        begin
-          Node.PrevSibling := Destination.PrevSibling;
-          Destination.PrevSibling := Node;
-          Node.NextSibling := Destination;
-          Node.Parent := Destination.Parent;
-          Node.Index := Destination.Index;
-          if Node.PrevSibling = nil then
-            Node.Parent.FirstChild := Node
-          else
-            Node.PrevSibling.NextSibling := Node;
-
-          // reindex all following nodes
-          Run := Destination;
-          while Assigned(Run) do
-          begin
-            Inc(Run.Index);
-            Run := Run.NextSibling;
-          end;
-
-          Inc(Destination.Parent.ChildCount);
-          Include(Destination.Parent.States, vsHasChildren);
-          AdjustTotalCount(Destination.Parent, Node.TotalCount, True);
-
-          // Add the new node's height only if its parent is expanded.
-          if Destination.Parent.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then
-            AdjustTotalHeight(Destination.Parent, Node.TotalHeight, True);
-          if FullyVisible[Node] then
-            Inc(FVisibleCount, CountVisibleChildren(Node) + 1);
-        end;
-      amInsertAfter:
-        begin
-          Node.NextSibling := Destination.NextSibling;
-          Destination.NextSibling := Node;
-          Node.PrevSibling := Destination;
-          Node.Parent := Destination.Parent;
-          if Node.NextSibling = nil then
-            Node.Parent.LastChild := Node
-          else
-            Node.NextSibling.PrevSibling := Node;
-          Node.Index := Destination.Index;
-
-          // reindex all following nodes
-          Run := Node;
-          while Assigned(Run) do
-          begin
-            Inc(Run.Index);
-            Run := Run.NextSibling;
-          end;
-
-          Inc(Destination.Parent.ChildCount);
-          Include(Destination.Parent.States, vsHasChildren);
-          AdjustTotalCount(Destination.Parent, Node.TotalCount, True);
-
-          // Add the new node's height only if its parent is expanded.
-          if Destination.Parent.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then
-            AdjustTotalHeight(Destination.Parent, Node.TotalHeight, True);
-          if FullyVisible[Node] then
-            Inc(FVisibleCount, CountVisibleChildren(Node) + 1);
-        end;
-      amAddChildFirst:
-        begin
-          if Assigned(Destination.FirstChild) then
-          begin
-            // If there's a first child then there must also be a last child.
-            Destination.FirstChild.PrevSibling := Node;
-            Node.NextSibling := Destination.FirstChild;
-            Destination.FirstChild := Node;
-          end
-          else
-          begin
-            // First child node at this location.
-            Destination.FirstChild := Node;
-            Destination.LastChild := Node;
-            Node.NextSibling := nil;
-          end;
-          Node.PrevSibling := nil;
-          Node.Parent := Destination;
-          Node.Index := 0;
-          // reindex all following nodes
-          Run := Node.NextSibling;
-          while Assigned(Run) do
-          begin
-            Inc(Run.Index);
-            Run := Run.NextSibling;
-          end;
-
-          Inc(Destination.ChildCount);
-          Include(Destination.States, vsHasChildren);
-          AdjustTotalCount(Destination, Node.TotalCount, True);
-          // Add the new node's height only if its parent is expanded.
-          if Destination.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then
-            AdjustTotalHeight(Destination, Node.TotalHeight, True);
-          if FullyVisible[Node] then
-            Inc(FVisibleCount, CountVisibleChildren(Node) + 1);
-        end;
-      amAddChildLast:
-        begin
-          if Assigned(Destination.LastChild) then
-          begin
-            // If there's a last child then there must also be a first child.
-            Destination.LastChild.NextSibling := Node;
-            Node.PrevSibling := Destination.LastChild;
-            Destination.LastChild := Node;
-          end
-          else
-          begin
-            // first child node at this location
-            Destination.FirstChild := Node;
-            Destination.LastChild := Node;
-            Node.PrevSibling := nil;
-          end;
-          Node.NextSibling := nil;
-          Node.Parent := Destination;
-          if Assigned(Node.PrevSibling) then
-            Node.Index := Node.PrevSibling.Index + 1
-          else
-            Node.Index := 0;
-          Inc(Destination.ChildCount);
-          Include(Destination.States, vsHasChildren);
-          AdjustTotalCount(Destination, Node.TotalCount, True);
-          // Add the new node's height only if its parent is expanded.
-          if Destination.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible] then
-            AdjustTotalHeight(Destination, Node.TotalHeight, True);
-          if FullyVisible[Node] then
-            Inc(FVisibleCount, CountVisibleChildren(Node) + 1);
-        end;
-    else
-      // amNoWhere: do nothing
-    end;
-
-    // Remove temporary states.
-    Node.States := Node.States - [vsChecking, vsCutOrCopy, vsDeleting, vsClearing];
-
-    // Update the hidden children flag of the parent.
-    if (Mode <> amNoWhere) and (Node.Parent <> FRoot) then
-    begin
-      // If we have added a visible node then simply remove the all-children-hidden flag.
-      if vsVisible in Node.States then
-        Exclude(Node.Parent.States, vsAllChildrenHidden)
-      else
-        // If we have added an invisible node and this is the only child node then
-        // make sure the all-children-hidden flag is in a determined state.
-        // If there were child nodes before then no action is needed.
-        if Node.Parent.ChildCount = 1 then
-          Include(Node.Parent.States, vsAllChildrenHidden);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.InternalData(Node: PVirtualNode): Pointer;
-
-begin
-  Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InternalDisconnectNode(Node: PVirtualNode; KeepFocus: Boolean; Reindex: Boolean = True);
-
-// Disconnects the given node from its parent and siblings. The node's pointer are not reset so they can still be used
-// after return from this method (probably a very short time only!).
-// If KeepFocus is True then the focused node is not reset. This is useful if the given node is reconnected to the tree
-// immediately after return of this method and should stay being the focused node if it was it before.
-// Note: Node must not be nil or the root node.
-
-var
-  Parent,
-  Run: PVirtualNode;
-  Index: Integer;
-  AdjustHeight: Boolean;
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Node must neither be nil nor the root node.');
-
-  if (Node = FFocusedNode) and not KeepFocus then
-  begin
-    DoFocusNode(nil, False);
-    DoFocusChange(FFocusedNode, FFocusedColumn);
-  end;
-
-  if Node = FRangeAnchor then
-    ResetRangeAnchor;
-
-  // Update the hidden children flag of the parent.
-  if (Node.Parent <> FRoot) and not (vsClearing in Node.Parent.States) then
-    if FUpdateCount = 0 then
-      DetermineHiddenChildrenFlag(Node.Parent)
-    else
-      Include(FStates, tsUpdateHiddenChildrenNeeded);
-
-  if not (vsDeleting in Node.States) then
-  begin
-    // Some states are only temporary so take them out.
-    Node.States := Node.States - [vsChecking];
-    Parent := Node.Parent;
-    Dec(Parent.ChildCount);
-    AdjustHeight := Parent.States * [vsExpanded, vsVisible] = [vsExpanded, vsVisible];
-    if Parent.ChildCount = 0 then
-    begin
-      Parent.States := Parent.States - [vsAllChildrenHidden, vsHasChildren];
-      if (Parent <> FRoot) and (vsExpanded in Parent.States) then
-        Exclude(Parent.States, vsExpanded);
-    end;
-    AdjustTotalCount(Parent, -Integer(Node.TotalCount), True);
-    if AdjustHeight then
-      AdjustTotalHeight(Parent, -Integer(Node.TotalHeight), True);
-    if FullyVisible[Node] then
-      Dec(FVisibleCount, CountVisibleChildren(Node) + 1);
-    if Assigned(Node.PrevSibling) then
-      Node.PrevSibling.NextSibling := Node.NextSibling
-    else
-      Parent.FirstChild := Node.NextSibling;
-
-    if Assigned(Node.NextSibling) then
-    begin
-      Node.NextSibling.PrevSibling := Node.PrevSibling;
-      // Reindex all following nodes.
-      if Reindex then
-      begin
-        Run := Node.NextSibling;
-        Index := Node.Index;
-        while Assigned(Run) do
-        begin
-          Run.Index := Index;
-          Inc(Index);
-          Run := Run.NextSibling;
-        end;
-      end;
-    end
-    else
-      Parent.LastChild := Node.PrevSibling;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.InternalGetNodeAt(X, Y: Integer): PVirtualNode;
-var
-  Dummy: Integer;
-begin
-  Result := InternalGetNodeAt(X, Y, True, Dummy);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.InternalGetNodeAt(X, Y: Integer; Relative: Boolean; var NodeTop: Integer): PVirtualNode;
-
-//lclheader this is the original version of GetNodeAt used internally since expects coordinates
-//  relative to the image tree. In LCL the image tree and control coordinates are different
-//  when header is visible
-
-// This method returns the node that occupies the specified point, or nil if there's none.
-// If Relative is True then X and Y are given in client coordinates otherwise they are considered as being
-// absolute values into the virtual tree image (regardless of the current offsets in the tree window).
-// NodeTop gets the absolute or relative top position of the node returned or is untouched if no node
-// could be found.
-
-var
-  AbsolutePos,
-  CurrentPos: Cardinal;
-
-begin
-  if Y < 0 then
-    Exit(nil);
-
-  AbsolutePos := Y;
-  if Relative then
-    Inc(AbsolutePos, -FOffsetY);
-
-  // CurrentPos tracks a running term of the current position to test for.
-  // It corresponds always to the top position of the currently considered node.
-  CurrentPos := 0;
-
-  // If the cache is available then use it.
-  if tsUseCache in FStates then
-    Result := FindInPositionCache(AbsolutePos, CurrentPos)
-  else
-    Result := GetFirstVisibleNoInit(nil, True);
-
-  // Determine node, of which position and height corresponds to the scroll position most closely.
-  while Assigned(Result) and (Result <> FRoot) do
-  begin
-    if AbsolutePos < (CurrentPos + NodeHeight[Result]) then
-      Break;
-    Inc(CurrentPos, NodeHeight[Result]);
-    Result := GetNextVisibleNoInit(Result, True);
-  end;
-
-  if Result = FRoot then
-    Result := nil;
-
-  // Since the given vertical position is likely not the same as the top position
-  // of the found node this top position is returned.
-  if Assigned(Result) then
-  begin
-    NodeTop := CurrentPos;
-    if Relative then
-      Inc(NodeTop, FOffsetY);
-    //{$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'GetNodeAt Result: ',Result^.Index);{$endif}
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InternalRemoveFromSelection(Node: PVirtualNode);
-
-// Special version to mark a node to be no longer in the current selection. PackArray must
-// be used to remove finally those entries.
-
-var
-  Index: Integer;
-
-begin
-  // Because pointers are always DWORD aligned we can simply increment all those
-  // which we want to have removed (see also PackArray) and still have the
-  // order in the list preserved.
-  if FindNodeInSelection(Node, Index, -1, -1) then
-  begin
-    Exclude(Node.States, vsSelected);
-    Inc(PtrUInt(FSelection[Index]));
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InvalidateCache;
-
-// Marks the cache as invalid.
-
-begin
-  DoStateChange([tsValidationNeeded], [tsUseCache]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.MarkCutCopyNodes;
-
-// Sets the vsCutOrCopy style in every currently selected but not disabled node to indicate it is
-// now part of a clipboard operation.
-
-var
-  Nodes: TNodeArray;
-  I: Integer;
-
-begin
-  Nodes := nil;
-  if FSelectionCount > 0 then
-  begin
-    // need the current selection sorted to exclude selected nodes which are children, grandchildren etc. of
-    // already selected nodes
-    Nodes := GetSortedSelection(False);
-    for I := 0 to High(Nodes) do
-      with Nodes[I]^ do
-        if not (vsDisabled in States) then
-          Include(States, vsCutOrCopy);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.Loaded;
-
-var
-  LastRootCount: Cardinal;
-  IsReadOnly: Boolean;
-
-begin
-  inherited;
-
-  // If a root node count has been set during load of the tree then update its child structure now
-  // as this hasn't been done yet in this case.
-  if (tsNeedRootCountUpdate in FStates) and (FRoot.ChildCount > 0) then
-  begin
-    DoStateChange([], [tsNeedRootCountUpdate]);
-    IsReadOnly := toReadOnly in FOptions.FMiscOptions;
-    Exclude(FOptions.FMiscOptions, toReadOnly);
-    LastRootCount := FRoot.ChildCount;
-    FRoot.ChildCount := 0;
-    BeginUpdate;
-    SetChildCount(FRoot, LastRootCount);
-    EndUpdate;
-    if IsReadOnly then
-      Include(FOptions.FMiscOptions, toReadOnly);
-  end;
-
-  // Prevent the object inspector at design time from marking the header as being modified
-  // when auto resize is enabled.
-  Updating;
-  try
-    FHeader.UpdateMainColumn;
-    FHeader.FColumns.FixPositions;
-    if toAutoBidiColumnOrdering in FOptions.FAutoOptions then
-      FHeader.FColumns.ReorderColumns(UseRightToLeftAlignment);
-    FHeader.RecalculateHeader;
-    //lclheader
-    //AdjustAutoSize is called inside CreateWnd. Don't call here
-    //Keep the commented code until we get sure of not being necessary
-    //if hoAutoResize in FHeader.FOptions then
-    //  FHeader.FColumns.AdjustAutoSize(InvalidColumn, True);
-  finally
-    Updated;
-  end;                             
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.MainColumnChanged;
-
-begin
-  DoCancelEdit;
-  {$ifdef EnableAccessible}
-  NotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Handle, OBJID_CLIENT, CHILDID_SELF);
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.MouseMove(Shift: TShiftState; X, Y: Integer);
-
-var
-  R: TRect;
-  NewCursor: TCursor;
-  HitInfo: THitInfo;
-  P: TPoint;
-  Node: PVirtualNode;  
-
-begin
-  // lcl: Adjust cursor
-  if ([tsWheelPanning, tsWheelScrolling] * FStates = []) then
-  begin
-    // Apply own cursors only if there is no global cursor set.
-    if Screen.Cursor = crDefault then
-    begin
-      NewCursor := crDefault;
-      if (toNodeHeightResize in FOptions.FMiscOptions) then
-      begin
-        GetCursorPos(P);
-        P := ScreenToClient(P);
-        GetHitTestInfoAt(P.X, P.Y, True, HitInfo);
-        if (hiOnItem in HitInfo.HitPositions) and
-           ([hiUpperSplitter, hiLowerSplitter] * HitInfo.HitPositions <> []) and
-           ((hitInfo.HitColumn > NoColumn) and (coFixed in FHeader.FColumns[HitInfo.HitColumn].FOptions)) then
-        begin
-          if hiUpperSplitter in HitInfo.HitPositions then
-            Node := GetPreviousVisible(HitInfo.HitNode, True)
-          else
-            Node := HitInfo.HitNode;
-          if Assigned(Node) and (Node <> FRoot) then
-            NewCursor := crVertSplit;
-        end;
-      end;
-      if (NewCursor = crDefault) and (toHotTrack in FOptions.PaintOptions) and Assigned(FCurrentHotNode) then
-        NewCursor := FHotCursor;
- 
-      DoGetCursor(NewCursor);
-      Cursor := NewCursor;
-    end;
-  end;
-  if tsNodeHeightTrackPending in FStates then
-  begin
-    // Remove hint if shown currently.
-    Application.CancelHint;
-
-    // Stop wheel panning if active.
-    StopWheelPanning;
-
-    // Stop timers
-    KillTimer(Handle, ExpandTimer);
-    KillTimer(Handle, EditTimer);
-    KillTimer(Handle, ScrollTimer);
-    KillTimer(Handle, SearchTimer);
-    FSearchBuffer := '';
-    FLastSearchNode := nil;
-
-    DoStateChange([tsNodeHeightTracking], [tsScrollPending, tsScrolling, tsEditPending, tsOLEDragPending, tsVCLDragPending,
-      tsIncrementalSearching, tsNodeHeightTrackPending]);
-  end;
-
-  if tsDrawSelPending in FStates then
-  begin
-    // Remove current selection in case the user clicked somewhere in the window (but not a node)
-    // and moved the mouse.
-    if CalculateSelectionRect(X, Y) then
-    begin
-      //lclheader
-      R := FNewSelRect;
-      if hoVisible in FHeader.Options then
-        OffsetRect(R, 0, FHeader.Height);
-      InvalidateRect(Handle, @R, False);
-      UpdateWindow(Handle);
-      if (Abs(FNewSelRect.Right - FNewSelRect.Left) > DragManager.DragThreshold) or
-         (Abs(FNewSelRect.Bottom - FNewSelRect.Top) > DragManager.DragThreshold) then
-      begin
-        if tsClearPending in FStates then
-        begin
-          DoStateChange([], [tsClearPending]);
-          ClearSelection;
-        end;
-        DoStateChange([tsDrawSelecting], [tsDrawSelPending]);
-
-        // Reset to main column for multiselection.
-        FocusedColumn := FHeader.MainColumn;
-
-        // The current rectangle may already include some node captions. Handle this.
-        if HandleDrawSelection(X, Y) then
-          InvalidateRect(Handle, nil, False);
-      end;
-    end;
-  end
-  else
-  begin
-    if tsNodeHeightTracking in FStates then
-    begin
-      // Handle height tracking.
-      if DoNodeHeightTracking(FHeightTrackNode, FHeightTrackColumn, FHeader.GetShiftState,
-        FHeightTrackPoint, Point(X, Y)) then
-      begin
-        // Avoid negative (or zero) node heights.
-        if FHeightTrackPoint.Y >= Y then
-          Y := FHeightTrackPoint.Y + 1;
-        SetNodeHeight(FHeightTrackNode, Y - FHeightTrackPoint.Y);
-        UpdateWindow(Handle);
-        Exit;
-      end;
-    end;
-
-    // If both wheel panning and auto scrolling are pending then the user moved the mouse while holding down the
-    // middle mouse button. This means panning is being used, hence remove the wheel scroll flag.
-    if [tsWheelPanning, tsWheelScrolling] * FStates = [tsWheelPanning, tsWheelScrolling] then
-    begin
-      if ((Abs(FLastClickPos.X - X) >= DragManager.DragThreshold) or (Abs(FLastClickPos.Y - Y) >= DragManager.DragThreshold)) then
-        DoStateChange([], [tsWheelScrolling]);
-    end;
-
-    // Really start dragging if the mouse has been moved more than the threshold.
-    if (tsOLEDragPending in FStates) and ((Abs(FLastClickPos.X - X) >= FDragThreshold) or
-       (Abs(FLastClickPos.Y - Y) >= FDragThreshold)) then
-      DoDragging(FLastClickPos)
-    else
-    begin
-      if CanAutoScroll then
-        DoAutoScroll(X, Y);
-      if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then
-        AdjustPanningCursor(X, Y);
-      if not IsMouseSelecting then
-      begin
-        HandleHotTrack(X, Y);
-        inherited MouseMove(Shift, X, Y);
-      end
-      else
-      begin
-        // Handle draw selection if required, but don't do the work twice if the
-        // auto scrolling code already cares about the selection.
-        if not (tsScrolling in FStates) and CalculateSelectionRect(X, Y) then
-        begin
-          // If something in the selection changed then invalidate the entire
-          // tree instead trying to figure out the display rects of all changed nodes.
-          if HandleDrawSelection(X, Y) then
-            InvalidateRect(Handle, nil, False)
-          else
-          begin
-            UnionRect(R, OrderRect(FNewSelRect), OrderRect(FLastSelRect));
-            OffsetRect(R, -FEffectiveOffsetX, FOffsetY);
-            if hoVisible in FHeader.Options then
-              OffsetRect(R, 0, FHeader.Height);
-            InvalidateRect(Handle, @R, False);
-          end;
-          UpdateWindow(Handle);
-        end;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.Notification(AComponent: TComponent; Operation: TOperation);
-
-begin
-  if (AComponent <> Self) and (Operation = opRemove) then
-  begin
-    // Check for components linked to the tree.
-    if AComponent = FImages then
-    begin
-      Images := nil;
-      if not (csDestroying in ComponentState) then
-        Invalidate;
-    end
-    else
-      if AComponent = FStateImages then
-      begin
-        StateImages := nil;
-        if not (csDestroying in ComponentState) then
-          Invalidate;
-      end
-      else
-        if AComponent = PopupMenu then
-          PopupMenu := nil
-        else
-          // Check for components linked to the header.
-          if AComponent = FHeader.FImages then
-            FHeader.Images := nil
-          else
-            if AComponent = FHeader.PopupMenu then
-              FHeader.PopupMenu := nil;
-  end;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-{$ifdef EnableNCFunctions}
-procedure TBaseVirtualTree.OriginalWMNCPaint(DC: HDC);
-
-// Unfortunately, the painting for the non-client area in TControl is not always correct and does also not consider
-// existing clipping regions, so it has been modified here to take this into account.
-
-const
-  InnerStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
-  OuterStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
-  EdgeStyles: array[TBevelKind] of Integer = (0, 0, BF_SOFT, BF_FLAT);
-  Ctl3DStyles: array[Boolean] of Integer = (BF_MONO, 0);
-
-var
-  RC, RW: TRect;
-  EdgeSize: Integer;
-  Size: TSize;
-
-begin
-  if (BevelKind <> bkNone) or (BorderWidth > 0) then
-  begin
-    RC := Rect(0, 0, Width, Height);
-    Size := GetBorderDimensions;
-    InflateRect(RC, Size.cx, Size.cy);
-
-    RW := RC;
-
-    if BevelKind <> bkNone then
-    begin
-      DrawEdge(DC, RC, InnerStyles[BevelInner] or OuterStyles[BevelOuter], Byte(BevelEdges) or EdgeStyles[BevelKind] or
-        Ctl3DStyles[Ctl3D]);
-
-      EdgeSize := 0;
-      if BevelInner <> bvNone then
-        Inc(EdgeSize, BevelWidth);
-      if BevelOuter <> bvNone then
-        Inc(EdgeSize, BevelWidth);
-      with RC do
-      begin
-        if beLeft in BevelEdges then
-          Inc(Left, EdgeSize);
-        if beTop in BevelEdges then
-          Inc(Top, EdgeSize);
-        if beRight in BevelEdges then
-          Dec(Right, EdgeSize);
-        if beBottom in BevelEdges then
-          Dec(Bottom, EdgeSize);
-      end;
-    end;
-
-    // Repaint only the part in the original clipping region and not yet drawn parts.
-    IntersectClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom);
-
-    // Determine inner rectangle to exclude (RC corresponds then to the client area).
-    InflateRect(RC, -BorderWidth, -BorderWidth);
-
-    // Remove the inner rectangle.
-    ExcludeClipRect(DC, RC.Left, RC.Top, RC.Right, RC.Bottom);
-
-    // Erase parts not drawn.
-    Brush.Color := FColors.BorderColor;
-    Windows.FillRect(DC, RW, Brush.Handle);
-  end;
-end;
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.Paint;
-
-// Window paint routine. Used when the tree window needs to be updated.
-
-var
-  Window: TRect;
-  Target: TPoint;
-  Temp: Integer;
-  Options: TVTInternalPaintOptions;
-  RTLOffset: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaint],'Paint');{$endif}
-  Options := [poBackground, poColumnColor, poDrawFocusRect, poDrawDropMark, poDrawSelection, poGridLines];
-  if UseRightToLeftAlignment and FHeader.UseColumns then
-    RTLOffset := ComputeRTLOffset(True)
-  else
-    RTLOffset := 0;
-  
-  // The update rect has already been filled in WMPaint, as it is the window's update rect, which gets
-  // reset when BeginPaint is called (in the ancestor).
-  // The difference to the DC's clipbox is that it is also valid with internal paint operations used
-  // e.g. by the Explorer while dragging, but show window content while dragging is disabled.
-  if not IsRectEmpty(FUpdateRect) then
-  begin
-    Temp := Header.Columns.GetVisibleFixedWidth;
-    if Temp = 0 then
-    begin
-      Window := FUpdateRect;
-      {$ifdef DEBUG_VTV}Logger.Send([lcHeaderOffset], 'FUpdateRect', FUpdateRect);{$endif}
-      Target := Window.TopLeft;
-      //lclheader
-      if hoVisible in FHeader.FOptions then
-      begin
-        if Target.Y < FHeader.Height then
-        begin
-          Window.Top := 0;
-          Target.Y := FHeader.Height;
-        end
-        else
-        begin
-          Dec(Window.Top, FHeader.Height);
-        end;
-        Dec(Window.Bottom, FHeader.Height);
-
-        if RectVisible(Canvas.Handle, FHeaderRect) then
-        begin
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'RectVisible = True');{$endif}
-          FHeader.FColumns.PaintHeader(Canvas.Handle, FHeaderRect, -FEffectiveOffsetX);
-        end;
-        with FHeaderRect do
-          ExcludeClipRect(Canvas.Handle, Left, Top, Right, Bottom);
-      end;
-      // The clipping rectangle is given in client coordinates of the window. We have to convert it into
-      // a sliding window of the tree image.
-      {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FEffectiveOffsetX: %d, RTLOffset: %d, OffsetY: %d',[FEffectiveOffsetX,RTLOffset,FOffsetY]);{$endif}
-
-      OffsetRect(Window, FEffectiveOffsetX - RTLOffset, -FOffsetY);
-      //{$ifdef DEBUG_VTV}Logger.Active:=Logger.CalledBy('DoDragging');{$endif}
-      PaintTree(Canvas, Window, Target, Options);
-      //{$ifdef DEBUG_VTV}Logger.Active:=True;{$endif}
-    end
-    else
-    begin
-      {$ifdef DEBUG_VTV}Logger.Send([lcPaint],'VisibleFixedWidth > 0');{$endif}
-      // First part, fixed columns
-      Window := ClientRect;
-      Window.Right := Temp;
-      Target := Window.TopLeft;
-      //lclheader
-      if hoVisible in FHeader.FOptions then
-      begin
-        //Target is always (0,0) due to call to ClientRect, so no need set Top to 0
-        //also no need to decrease bottom because ClientRect already computes header
-        Inc(Target.Y, FHeader.Height);
-        if  RectVisible(Canvas.Handle, FHeaderRect) then
-        begin
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader], 'RectVisible = True');{$endif}
-          FHeader.FColumns.PaintHeader(Canvas.Handle, FHeaderRect, -FEffectiveOffsetX);
-        end;
-        with FHeaderRect do
-          ExcludeClipRect(Canvas.Handle,Left,Top,Right,Bottom);
-      end;
-
-      OffsetRect(Window,  -RTLOffset, -FOffsetY);
-      PaintTree(Canvas, Window, Target, Options);
-
-      // Second part, other columns
-      Window := GetClientRect;
-
-      if Temp > Window.Right then
-      begin
-        {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaint],'Paint');{$endif}
-        Exit;
-      end;
-
-      Window.Left := Temp;
-      Target := Window.TopLeft;
-
-      //lclheader
-      if hoVisible in FHeader.FOptions then
-        Inc(Target.Y, FHeader.Height);
-      {$ifdef DEBUG_VTV}Logger.Send([lcDrag],'FEffectiveOffsetX: %d, RTLOffset: %d, OffsetY: %d',[FEffectiveOffsetX,RTLOffset,FOffsetY]);{$endif}
-      OffsetRect(Window, FEffectiveOffsetX - RTLOffset, -FOffsetY);
-      PaintTree(Canvas, Window, Target, Options);
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaint],'Paint');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PaintCheckImage(const PaintInfo: TVTPaintInfo);
-
-
-  procedure DrawCheckButton(Canvas: TCanvas; Index: Integer; const R: TRect; Flat: Boolean);
-
-  var
-    ButtonState: Cardinal;
-    ButtonType: Cardinal;
-
-  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(Canvas.Handle, R, DFC_BUTTON, ButtonType or ButtonState);
-  end;
-
-
-var
-  R: TRect;
-  {$ifdef ThemeSupport}
-  Details: TThemedElementDetails;
-  {$endif}
-  UseThemes: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcCheck],'PaintCheckImage');{$endif}
-  with PaintInfo, ImageInfo[iiCheck] do
-  begin
-    {$ifdef ThemeSupport}
-    UseThemes := (tsUseThemes in FStates) and (FCheckImageKind = ckSystemDefault);
-    {$else}
-    UseThemes := False;
-    {$endif}
-    if UseThemes or ((FCheckImageKind in [ckSystemFlat, ckSystemDefault]) and not (Index in [21..24])) then
-    begin
-      {$ifdef ThemeSupport}
-      if UseThemes then
-      begin
-        R := Rect(XPos - 1, YPos, XPos + 16, YPos + 16);
-        Details.Element := teButton;
-        case Index of
-          0..8: // radio buttons
-            begin
-              Details.Part := BP_RADIOBUTTON;
-              Details.State := Index;
-            end;
-          9..20: // check boxes
-            begin
-              Details.Part := BP_CHECKBOX;
-              Details.State := Index - 8;
-            end;
-          21..24: // buttons
-            begin
-              Details.Part := BP_PUSHBUTTON;
-              Details.State := Index - 20;
-            end;
-        else
-          Details.Part := 0;
-          Details.State := 0;
-        end;
-        ThemeServices.DrawElement(Canvas.Handle, Details, R);
-        {$ifdef USE_DELPHICOMPAT}
-        if Index in [21..24] then
-          with UtilityImages do
-            DirectMaskBlt(PaintInfo.Canvas.Handle, XPos - 1, YPos, Height, Height,
-              Canvas.Handle, 4 * Height, 0, MaskHandle);
-        {$else}
-        if Index in [21..24] then
-          with UtilityImages do
-            StretchMaskBlt(PaintInfo.Canvas.Handle, XPos - 1, YPos, Height, Height,
-              Canvas.Handle, 4 * Height, 0, Height, Height, MaskHandle,  4 * Height, 0, SRCCOPY);
-        {$endif}
-      end
-      else
-      {$endif}
-      begin
-        R := Rect(XPos + 1, YPos + 1, XPos + 14, YPos + 14);
-        DrawCheckButton(Canvas, Index - 1, R, FCheckImageKind = ckSystemFlat);
-      end;
-    end
-    else
-    with FCheckImages do
-    begin
-      {$ifdef USE_DELPHICOMPAT}
-      DirectMaskBlt(PaintInfo.Canvas.Handle, XPos, YPos, Height, Height, Canvas.Handle,
-        Index * Height, 0, MaskHandle);
-      {$else}
-      StretchMaskBlt(PaintInfo.Canvas.Handle, XPos, YPos, Height, Height, Canvas.Handle,
-        Index * Height, 0, Height, Height, MaskHandle, Index * Height, 0, SRCCOPY);
-      {$endif}
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcCheck],'PaintCheckImage');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean);
-
-var
-  CutNode: Boolean;
-  PaintFocused: Boolean;
-  DrawEffect: TGraphicsDrawEffect;
-
-begin
-  with PaintInfo do
-  begin
-    CutNode := (vsCutOrCopy in Node.States) and (tsCutPending in FStates);
-    PaintFocused := Focused or (toGhostedIfUnfocused in FOptions.FPaintOptions);
-
-    // Since the overlay image must be specified together with the image to draw
-    // it is meaningfull to retrieve it in advance.
-    if DoOverlay then
-      GetImageIndex(PaintInfo, ikOverlay, iiOverlay, Images)
-    else
-      PaintInfo.ImageInfo[iiOverlay].Index := -1;
-
-    with ImageInfo[ImageInfoIndex] do
-    begin
-      if (vsSelected in Node.States) and not (Ghosted or CutNode) then
-      begin
-        if PaintFocused or (toPopupMode in FOptions.FPaintOptions) then
-          Images.BlendColor := FColors.FocusedSelectionColor
-        else
-          Images.BlendColor := FColors.UnfocusedSelectionColor;
-      end
-      else
-        Images.BlendColor := Color;
-
-      if (vsDisabled in Node.States) or not Enabled then
-        DrawEffect := gdeDisabled
-      else
-      // Blend image if enabled and the tree has the focus (or ghosted images must be drawn also if unfocused) ...
-      if (toUseBlendedImages in FOptions.FPaintOptions) and PaintFocused
-        // ... and the image is ghosted...
-        and (Ghosted or
-        // ... or it is not the check image and the node is selected (but selection is not for the entire row)...
-        ((vsSelected in Node.States) and
-        not (toFullRowSelect in FOptions.FSelectionOptions) and
-        not (toGridExtensions in FOptions.FMiscOptions)) or
-        // ... or the node must be shown in cut mode.
-        CutNode) then
-          DrawEffect := gdeShadowed
-        else
-          DrawEffect := gdeNormal;
-
-      if (vsSelected in Node.States) and not Ghosted then
-        Images.BlendColor := clDefault;
-
-      Images.Draw(Canvas, XPos, YPos, Index, DrawEffect);
-
-      // Now, draw the overlay.
-      // Delphi version has the ability to use the built in overlay indices of windows system image lists
-      // Since this is system dependent the LCL version will support only custom overlays
-
-      // Note: XPos and YPos are those of the normal images.
-      if PaintInfo.ImageInfo[iiOverlay].Index >= 0 then
-        ImageInfo[iiOverlay].Images.Draw(Canvas, XPos, YPos, ImageInfo[iiOverlay].Index);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PaintNodeButton(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const R: TRect;
-  ButtonX, ButtonY: Integer; BidiMode: TBiDiMode);
-
-var
-  Bitmap: TBitmap;
-  XPos: Integer;
-  IsHot: Boolean;
-
-begin
-  IsHot := (toHotTrack in FOptions.FPaintOptions) and (FCurrentHotNode = Node) and FHotNodeButtonHit;
-
-  if vsExpanded in Node.States then
-  begin
-    if IsHot then
-      Bitmap := FHotMinusBM
-    else
-      Bitmap := FMinusBM;
-  end
-  else
-  begin
-    if IsHot then
-      Bitmap := FHotPlusBM
-    else
-      Bitmap := FPlusBM;
-  end;
-
-  // Draw the node's plus/minus button according to the directionality.
-  if BidiMode = bdLeftToRight then
-    XPos := R.Left + ButtonX
-  else
-    XPos := R.Right - ButtonX - Bitmap.Width;
-
-  // Need to draw this masked.
-  Canvas.Draw(XPos, R.Top + ButtonY, Bitmap);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PaintTreeLines(const PaintInfo: TVTPaintInfo; VAlignment, IndentSize: Integer;
-  LineImage: TLineImage);
-
-var
-  I: Integer;
-  XPos,
-  Offset: Integer;
-  NewStyles: TLineImage;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'PaintTreeLines');{$endif}
-  NewStyles := nil;
-
-  with PaintInfo do
-  begin
-    if BidiMode = bdLeftToRight then
-    begin
-      XPos := CellRect.Left;
-      Offset := FIndent;
-    end
-    else
-    begin
-      Offset := -Integer(FIndent);
-      XPos := CellRect.Right + Offset;
-    end;
-
-    case FLineMode of
-      lmBands:
-        if poGridLines in PaintInfo.PaintOptions then
-        begin
-          // Convert the line images in correct bands.
-          SetLength(NewStyles, Length(LineImage));
-          for I := IndentSize - 1 downto 0 do
-          begin
-            {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FLineMode = lmBands');{$endif}
-            if (vsExpanded in Node.States) and not (vsAllChildrenHidden in Node.States) then
-              NewStyles[I] := ltLeft
-            else
-              case LineImage[I] of
-                ltRight,
-                ltBottomRight,
-                ltTopDownRight,
-                ltTopRight:
-                  NewStyles[I] := ltLeftBottom;
-                ltNone:
-                  // Have to take over the image to the right of this one. A no line entry can never appear as
-                  // last entry so I don't need an end check here.
-                  if LineImage[I + 1] in [ltNone, ltTopRight] then
-                    NewStyles[I] := NewStyles[I + 1]
-                  else
-                    NewStyles[I] := ltLeft;
-                ltTopDown:
-                  // Have to check the image to the right of this one. A top down line can never appear as
-                  // last entry so I don't need an end check here.
-                  if LineImage[I + 1] in [ltNone, ltTopRight] then
-                    NewStyles[I] := NewStyles[I + 1]
-                  else
-                    NewStyles[I] := ltLeft;
-              end;
-          end;
-
-          PaintInfo.Canvas.Font.Color := FColors.GridLineColor;
-          for I := 0 to IndentSize - 1 do
-          begin
-            DrawLineImage(PaintInfo, XPos, CellRect.Top, NodeHeight[Node] - 1, VAlignment, NewStyles[I],
-              BidiMode <> bdLeftToRight);
-            Inc(XPos, Offset);
-          end;
-        end;
-    else // lmNormal
-      {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FLineMode = lmNormal');{$endif}
-      {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif}
-      PaintInfo.Canvas.Font.Color := FColors.TreeLineColor;
-      {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Font.Color);{$endif}
-      for I := 0 to IndentSize - 1 do
-      begin
-        DrawLineImage(PaintInfo, XPos, CellRect.Top, NodeHeight[Node], VAlignment, LineImage[I],
-          BidiMode <> bdLeftToRight);
-        Inc(XPos, Offset);
-      end;
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintTreeLines');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PaintSelectionRectangle(Target: TCanvas; WindowOrgX: Integer; const SelectionRect: TRect;
-  TargetRect: TRect);
-
-// Helper routine to draw a selection rectangle in the mode determined by DrawSelectionMode.
-
-var
-  BlendRect: TRect;
-  TextColorBackup,
-  BackColorBackup: COLORREF;   // used to restore forground and background colors when drawing a selection rectangle
-
-begin
-  {$ifdef DEBUG_VTV}Logger.Send([lcSelection], 'SelectionRect at PaintSelection', SelectionRect);{$endif}
-  if ((FDrawSelectionMode = smDottedRectangle) and not (tsUseThemes in FStates)) or
-    not MMXAvailable then
-  begin
-    // Classical selection rectangle using dotted borderlines.
-    TextColorBackup := GetTextColor(Target.Handle);
-    SetTextColor(Target.Handle, $FFFFFF);
-    BackColorBackup := GetBkColor(Target.Handle);
-    SetBkColor(Target.Handle, 0);
-    Target.DrawFocusRect(SelectionRect);
-    SetTextColor(Target.Handle, TextColorBackup);
-    SetBkColor(Target.Handle, BackColorBackup);
-  end
-  else
-  begin
-    // Modern alpha blended style.
-    OffsetRect(TargetRect, WindowOrgX, 0);
-    if IntersectRect(BlendRect, OrderRect(SelectionRect), TargetRect) then
-    begin
-      OffsetRect(BlendRect, -WindowOrgX, 0);
-      AlphaBlend(0, Target.Handle, BlendRect, Point(0, 0), bmConstantAlphaAndColor, FSelectionBlendFactor,
-        ColorToRGB(FColors.SelectionRectangleBlendColor));
-
-      Target.Brush.Color := FColors.SelectionRectangleBorderColor;
-      Target.FrameRect(SelectionRect);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PrepareCell(var PaintInfo: TVTPaintInfo; WindowOrgX, MaxWidth: Integer);
-
-// This method is called immediately before a cell's content is drawn und is responsible to paint selection colors etc.
-
-var
-  TextColorBackup,
-  BackColorBackup: COLORREF;
-  FocusRect,
-  InnerRect: TRect;
-  {$ifdef ThemeSupport}
-    RowRect: TRect;
-    //Theme: HTHEME;
-  {$endif ThemeSupport}
-
-  //--------------- local functions -------------------------------------------
-
-  procedure AlphaBlendSelection(Color: TColor);
-
-  var
-    R: TRect;
-
-  begin
-    // Take into account any window offset and size limitations in the target bitmap, as this is only as large
-    // as necessary and might not cover the whole node. For normal painting this does not matter (because of
-    // clipping) but for the MMX code there is no such check and it will crash badly when bitmap boundaries are
-    // crossed.
-    R := InnerRect;
-    OffsetRect(R, -WindowOrgX, 0);
-    if R.Left < 0 then
-      R.Left := 0;
-    if R.Right > MaxWidth then
-      R.Right := MaxWidth;
-    AlphaBlend(0, PaintInfo.Canvas.Handle, R, Point(0, 0), bmConstantAlphaAndColor,
-      FSelectionBlendFactor, ColorToRGB(Color));
-  end;
-
-  //---------------------------------------------------------------------------
-
-  {$ifdef ThemeSupport}
-  //todo
-  {
-    procedure DrawBackground(State: Integer);
-    begin
-      with PaintInfo do
-        if (toGridExtensions in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions) then
-          DrawThemeBackground(Theme, Canvas.Handle, TVP_TREEITEM, State, RowRect, @CellRect)
-        else
-          DrawThemeBackground(Theme, Canvas.Handle, TVP_TREEITEM, State, InnerRect, nil);
-    end;
-    }
-  {$endif ThemeSupport}
-
-  //--------------- end local functions ---------------------------------------
-
-begin
-  {$ifdef ThemeSupport}
-    //todo
-    {
-    if IsWinVistaOrAbove and (tsUseThemes in FStates) and (toUseExplorerTheme in FOptions.FPaintOptions) then
-    begin
-      RowRect := Rect(0, PaintInfo.CellRect.Top, FRangeX, PaintInfo.CellRect.Bottom);
-      if toShowVertGridLines in FOptions.PaintOptions then
-        Dec(RowRect.Right);
-      Theme := OpenThemeData(Handle, 'TREEVIEW');
-    end
-    else
-      Theme := 0;
-    }
-  {$endif ThemeSupport}
-
-  with PaintInfo, Canvas do
-  begin
-    // Fill cell background if its color differs from tree background.
-    with FHeader.FColumns do
-      if poColumnColor in PaintOptions then
-      begin
-        Brush.Color := Items[Column].Color;
-        FillRect(CellRect);
-      end;
-
-    // Let the application customize the cell background and the content rectangle.
-    DoBeforeCellPaint(Canvas, Node, Column, cpmPaint, CellRect, ContentRect);
-
-    InnerRect := ContentRect;
-
-    // The selection rectangle depends on alignment.
-    if not (toGridExtensions in FOptions.FMiscOptions) then
-    begin
-      case Alignment of
-        taLeftJustify:
-          with InnerRect do
-            if Left + NodeWidth < Right then
-              Right := Left + NodeWidth;
-        taCenter:
-          with InnerRect do
-            if (Right - Left) > NodeWidth then
-            begin
-              Left := (Left + Right - NodeWidth) div 2;
-              Right := Left + NodeWidth;
-            end;
-        taRightJustify:
-          with InnerRect do
-            if (Right - Left) > NodeWidth then
-              Left := Right - NodeWidth;
-      end;
-    end;
-
-    if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then
-    begin
-      // Fill the selection rectangle.
-      if poDrawSelection in PaintOptions then
-      begin
-        if Node = FDropTargetNode then
-        begin
-          if (FLastDropMode = dmOnNode) or (vsSelected in Node.States) then
-          begin
-            Brush.Color := FColors.DropTargetColor;
-            Pen.Color := FColors.DropTargetBorderColor;
-
-            if (toGridExtensions in FOptions.FMiscOptions) or
-              (toFullRowSelect in FOptions.FSelectionOptions) then
-              InnerRect := CellRect;
-            if not IsRectEmpty(InnerRect) then
-              if MMXAvailable and (toUseBlendedSelection in FOptions.PaintOptions) then
-                AlphaBlendSelection(Brush.Color)
-              else
-                with InnerRect do
-                  RoundRect(Left, Top, Right, Bottom, FSelectionCurveRadius, FSelectionCurveRadius);
-          end
-          else
-          begin
-            //lcl: Is not necessary to set the style here
-            //Brush.Style := bsClear;
-          end;
-        end
-        else
-          if vsSelected in Node.States then
-          begin
-            if Focused or (toPopupMode in FOptions.FPaintOptions) then
-            begin
-              Brush.Color := FColors.FocusedSelectionColor;
-              Pen.Color := FColors.FocusedSelectionBorderColor;
-            end
-            else
-            begin
-              Brush.Color := FColors.UnfocusedSelectionColor;
-              Pen.Color := FColors.UnfocusedSelectionBorderColor;
-            end;
-
-            if (toGridExtensions in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions) then
-              InnerRect := CellRect;
-            if not IsRectEmpty(InnerRect) then
-              {$ifdef ThemeSupport}
-                //todo
-                {
-                if Theme <> 0 then
-                begin
-                  // If the node is also hot, its background will be drawn later.
-                  if not (toHotTrack in FOptions.FPaintOptions) or (Node <> FCurrentHotNode) or
-                     ((Column <> FCurrentHotColumn) and not (toFullRowSelect in FOptions.FSelectionOptions)) then
-                    DrawBackground(IfThen(Self.Focused, TREIS_SELECTED, TREIS_SELECTEDNOTFOCUS));
-                end
-                else
-                }
-              {$endif ThemeSupport}
-              if MMXAvailable and (toUseBlendedSelection in FOptions.PaintOptions) then
-                AlphaBlendSelection(Brush.Color)
-              else
-                with InnerRect do
-                  RoundRect(Left, Top, Right, Bottom, FSelectionCurveRadius, FSelectionCurveRadius);
-          end;
-      end;
-    end;
-
-    {$ifdef ThemeSupport}
-    //todo
-    {
-      if (Theme <> 0) and (toHotTrack in FOptions.FPaintOptions) and (Node = FCurrentHotNode) and
-         ((Column = FCurrentHotColumn) or (toFullRowSelect in FOptions.FSelectionOptions)) then
-        DrawBackground(IfThen((vsSelected in Node.States) and not (toAlwaysHideSelection in FOptions.FPaintOptions),
-                              TREIS_HOTSELECTED, TREIS_HOT));
-    }
-    {$endif ThemeSupport}
-
-    if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then
-    begin
-      // draw focus rect
-      if (poDrawFocusRect in PaintOptions) and
-         (Focused or (toPopupMode in FOptions.FPaintOptions)) and (FFocusedNode = Node) and
-         ( (Column = FFocusedColumn)
-           {$ifdef ThemeSupport}
-             //todo
-             { or
-             (not (toExtendedFocus in FOptions.FSelectionOptions) and
-             (toFullRowSelect in FOptions.FSelectionOptions) and
-             (Theme <> 0) )
-             }
-          {$endif ThemeSupport}
-         ) then
-      begin
-        TextColorBackup := GetTextColor(Handle);
-        SetTextColor(Handle, $FFFFFF);
-        BackColorBackup := GetBkColor(Handle);
-        SetBkColor(Handle, 0);
-
-        {$ifdef ThemeSupport}
-        //todo
-        {
-          if not (toExtendedFocus in FOptions.FSelectionOptions) and (toFullRowSelect in FOptions.FSelectionOptions) and
-            (Theme <> 0) then
-            FocusRect := RowRect
-          else
-        }
-        {$endif ThemeSupport}
-        if toGridExtensions in FOptions.FMiscOptions then
-          FocusRect := CellRect
-        else
-          FocusRect := InnerRect;
-
-        {$ifdef ThemeSupport}
-        //todo
-        {
-          if Theme <> 0 then
-            InflateRect(FocusRect, -1, -1);
-         }
-        {$endif ThemeSupport}
-
-        LCLIntf.DrawFocusRect(Handle, FocusRect);
-        SetTextColor(Handle, TextColorBackup);
-        SetBkColor(Handle, BackColorBackup);
-      end;
-    end;
-  end;
-  {$ifdef ThemeSupport}
-  //todo
-  {
-  if Theme <> 0 then
-    CloseThemeData(Theme);
-  }
-  {$endif ThemeSupport}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType,
-  ChunkSize: Integer): Boolean;
-
-// Called while loading a tree structure, Node is already valid (allocated) at this point.
-// The function handles the base and user chunks, any other chunk is marked as being unknown (result becomes False)
-// and skipped. descendants may handle them by overriding this method.
-// Returns True if the chunk could be handled, otherwise False.
-
-var
-  ChunkBody: TBaseChunkBody;
-  Run: PVirtualNode;
-  LastPosition: Integer;
-
-begin
-  case ChunkType of
-    BaseChunk:
-      begin
-        // Load base chunk's body (chunk header has already been consumed).
-        Stream.Read(ChunkBody, SizeOf(ChunkBody));
-        with Node^ do
-        begin
-          // Set states first, in case the node is invisible.
-          States := ChunkBody.States;
-          NodeHeight := ChunkBody.NodeHeight;
-          TotalHeight := NodeHeight;
-          Align := ChunkBody.Align;
-          CheckState := ChunkBody.CheckState;
-          CheckType := ChunkBody.CheckType;
-          ChildCount := ChunkBody.ChildCount;
-
-          // Create and read child nodes.
-          while ChunkBody.ChildCount > 0 do
-          begin
-            Run := MakeNewNode;
-
-            Run.PrevSibling := Node.LastChild;
-            if Assigned(Run.PrevSibling) then
-              Run.Index := Run.PrevSibling.Index + 1;
-            if Assigned(Node.LastChild) then
-              Node.LastChild.NextSibling := Run
-            else
-              Node.FirstChild := Run;
-            Node.LastChild := Run;
-            Run.Parent := Node;
-
-            ReadNode(Stream, Version, Run);
-            Dec(ChunkBody.ChildCount);
-          end;
-        end;
-        Result := True;
-      end;
-    UserChunk:
-      if ChunkSize > 0 then
-      begin
-        // need to know whether the data was read
-        LastPosition := Stream.Position;
-        DoLoadUserData(Node, Stream);
-        // compare stream position to learn whether the data was read
-        Result := Stream.Position > LastPosition;
-        // Improve stability by advancing the stream to the chunk's real end if
-        // the application did not read what has been written.
-        if not Result or (Stream.Position <> (LastPosition + ChunkSize)) then
-          Stream.Position := LastPosition + ChunkSize;
-      end
-      else
-        Result := True;
-  else
-    // unknown chunk, skip it
-    Stream.Position := Stream.Position + ChunkSize;
-    Result := False;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ReadNode(Stream: TStream; Version: Integer; Node: PVirtualNode);
-
-// Reads the anchor chunk of each node and initiates reading the sub chunks for this node
-
-var
-  Header: TChunkHeader;
-  EndPosition: Integer;
-
-begin
-  with Stream do
-  begin
-    // Read anchor chunk of the node.
-    Stream.Read(Header, SizeOf(Header));
-    if Header.ChunkType = NodeChunk then
-    begin
-      EndPosition := Stream.Position + Header.ChunkSize;
-      // Read all subchunks until the indicated chunk end position is reached in the stream.
-      while Position < EndPosition do
-      begin
-        // Read new chunk header.
-        Stream.Read(Header, SizeOf(Header));
-        ReadChunk(Stream, Version, Node, Header.ChunkType, Header.ChunkSize);
-      end;
-      // If the last chunk does not end at the given end position then there is something wrong.
-      if Position <> EndPosition then
-        ShowError(SCorruptStream2, hcTFCorruptStream2);
-    end
-    else
-      ShowError(SCorruptStream1, hcTFCorruptStream1);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.RedirectFontChangeEvent(Canvas: TCanvas);
-
-begin
-  if @Canvas.Font.OnChange <> @FOldFontChange then
-  begin
-    FOldFontChange := Canvas.Font.OnChange;
-    Canvas.Font.OnChange := FontChanged;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.RemoveFromSelection(Node: PVirtualNode);
-
-var
-  Index: Integer;
-
-begin
-  if not FSelectionLocked then
-  begin
-    Assert(Assigned(Node), 'Node must not be nil!');
-    if vsSelected in Node.States then
-    begin
-      Exclude(Node.States, vsSelected);
-      if FindNodeInSelection(Node, Index, -1, -1) and (Index < FSelectionCount - 1) then
-        Move(FSelection[Index + 1], FSelection[Index], (FSelectionCount - Index - 1) * 4);
-      if FSelectionCount > 0 then
-        Dec(FSelectionCount);
-      SetLength(FSelection, FSelectionCount);
-
-      if FSelectionCount = 0 then
-        ResetRangeAnchor;
-
-      Change(Node);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ResetRangeAnchor;
-
-// Called when there is no selected node anymore and the selection range anchor needs a new value.
-
-begin
-  FRangeAnchor := FFocusedNode;
-  FLastSelectionLevel := -1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.RestoreFontChangeEvent(Canvas: TCanvas);
-
-begin
-  Canvas.Font.OnChange := FOldFontChange;
-  FOldFontChange := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SelectNodes(StartNode, EndNode: PVirtualNode; AddOnly: Boolean);
-
-// Selects a range of nodes and unselects all other eventually selected nodes which are not in this range if
-// AddOnly is False.
-// EndNode must be visible while StartNode does not necessarily as in the case where the last focused node is the start
-// node but it is a child of a node which has been collapsed previously. In this case the first visible parent node
-// is used as start node. StartNode can be nil in which case the very first node in the tree is used.
-
-var
-  NodeFrom,
-  NodeTo,
-  LastAnchor: PVirtualNode;
-  Index: Integer;
-
-begin
-  Assert(Assigned(EndNode), 'EndNode must not be nil!');
-  if not FSelectionLocked then
-  begin
-    ClearTempCache;
-    if StartNode = nil then
-      StartNode := GetFirstVisibleNoInit(nil, True)
-    else
-      if not FullyVisible[StartNode] then
-      begin
-        StartNode := GetPreviousVisible(StartNode, True);
-        if StartNode = nil then
-          StartNode := GetFirstVisibleNoInit(nil, True)
-      end;
-
-    if CompareNodePositions(StartNode, EndNode, True) < 0 then
-    begin
-      NodeFrom := StartNode;
-      NodeTo := EndNode;
-    end
-    else
-    begin
-      NodeFrom := EndNode;
-      NodeTo := StartNode;
-    end;
-
-    // The range anchor will be reset by the following call.
-    LastAnchor := FRangeAnchor;
-    if not AddOnly then
-      InternalClearSelection;
-
-    while NodeFrom <> NodeTo do
-    begin
-      InternalCacheNode(NodeFrom);
-      NodeFrom := GetNextVisible(NodeFrom, True);
-    end;
-    // select last node too
-    InternalCacheNode(NodeFrom);
-    // now add them all in "one" step
-    AddToSelection(FTempNodeCache, FTempNodeCount);
-    ClearTempCache;
-    if Assigned(LastAnchor) and FindNodeInSelection(LastAnchor, Index, -1, -1) then
-     FRangeAnchor := LastAnchor;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SetFocusedNodeAndColumn(Node: PVirtualNode; Column: TColumnIndex);
-
-var
-  OldColumn: TColumnIndex;
-  WasDifferent: Boolean;
-
-begin
-  if not FHeader.AllowFocus(Column) then
-    Column := FFocusedColumn;
-
-  WasDifferent := (Node <> FFocusedNode) or (Column <> FFocusedColumn);
-
-  OldColumn := FFocusedColumn;
-  FFocusedColumn := Column;
-
-  DoFocusNode(Node, True);
-
-  // Check if the change was accepted.
-  if FFocusedNode = Node then
-  begin
-    CancelEditNode;
-    if WasDifferent then
-      DoFocusChange(FFocusedNode, FFocusedColumn);
-  end
-  else
-    // If the user did not accept the new cell to focus then set also the focused column back
-    // to its original state.
-    FFocusedColumn := OldColumn;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SkipNode(Stream: TStream);
-
-// Skips the data for the next node in the given stream (including the child nodes).
-
-var
-  Header: TChunkHeader;
-
-begin
-  with Stream do
-  begin
-    // read achor chunk of the node
-    Stream.Read(Header, SizeOf(Header));
-    if Header.ChunkType = NodeChunk then
-      Stream.Position := Stream.Position + Header.ChunkSize
-    else
-      ShowError(SCorruptStream1, hcTFCorruptStream1);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-procedure TBaseVirtualTree.StartWheelPanning(const Position: TPoint);
-
-// Called when wheel panning should start. A little helper window is created to indicate the reference position,
-// which determines in which direction and how far wheel panning/scrolling will happen.
-
-  //--------------- local function --------------------------------------------
-
-  function CreateClipRegion: HRGN;
-
-  // In order to avoid doing all the transparent drawing ourselves we use a
-  // window region for the wheel window.
-  // Since we only work on a very small image (32x32 pixels) this is acceptable.
-
-  var
-    Start, X, Y, ImageHeight, ImageWidth: Integer;
-    Temp: HRGN;
-
-  begin
-    Assert(not FPanningWindow.Image.Empty, 'Invalid wheel panning image.');
-    ImageWidth := FPanningWindow.Image.Width;
-    ImageHeight := FPanningWindow.Image.Height;
-    // Create an initial region on which we operate.
-    Result := CreateRectRgn(0, 0, 0, 0);
-    with FPanningWindow.Image.Canvas do
-    begin
-      for Y := 0 to ImageHeight - 1 do
-      begin
-        Start := -1;
-        for X := 0 to ImageWidth - 1 do
-        begin
-          // Start a new span if we found a non-transparent pixel and no span is currently started.
-          if (Start = -1) and (Pixels[X, Y] <> clFuchsia) then
-            Start := X
-          else
-            if (Start > -1) and (Pixels[X, Y] = clFuchsia) then
-            begin
-              // A non-transparent span is finished. Add it to the result region.
-              Temp := CreateRectRgn(Start, Y, X, Y + 1);
-              CombineRgn(Result, Result, Temp, RGN_OR);
-              DeleteObject(Temp);
-              Start := -1;
-            end;
-        end;
-        // If there is an open span then add this also to the result region.
-        if Start > -1 then
-        begin
-          Temp := CreateRectRgn(Start, Y, ImageWidth, Y + 1);
-          CombineRgn(Result, Result, Temp, RGN_OR);
-          DeleteObject(Temp);
-        end;
-      end;
-    end;
-    // The resulting region is used as window region so we must not delete it.
-    // Windows will own it after the assignment below.
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-var
-  ImageName: string;
-
-begin
-  // Set both panning and scrolling flag. One will be removed shortly depending on whether the middle mouse button is
-  // released before the mouse is moved or vice versa. The first case is referred to as wheel scrolling while the
-  // latter is called wheel panning.
-  KillTimer(Handle, ScrollTimer);
-  DoStateChange([tsWheelPanning, tsWheelScrolling]);
-
-  if FPanningWindow = nil then
-  begin
-    FPanningWindow := TVirtualPanningWindow.Create;
-    LoadPanningCursors;
-  end;
-
-  FPanningWindow.Start(Handle, ClientToScreen(Position));
-
-  if Integer(FRangeX) > ClientWidth then
-  begin
-    if Integer(FRangeY) > ClientHeight then
-      ImageName := 'VT_MOVEALL_BMP'
-    else
-      ImageName := 'VT_MOVEEW_BMP'
-  end
-  else
-    ImageName := 'VT_MOVENS_BMP';
-
-  FPanningWindow.Image.LoadFromLazarusResource(ImageName);
-
-  FPanningWindow.Show(CreateClipRegion);
-
-  // Setup the panscroll timer and capture all mouse input.
-  SetFocus;
-  SetCapture(Handle);
-  AdjustPanningCursor(Position.X, Position.Y);
-  SetTimer(Handle, ScrollTimer, 20, nil);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.StopWheelPanning;
-
-// Stops panning if currently active and destroys the helper window.
-
-begin
-  if [tsWheelPanning, tsWheelScrolling] * FStates <> [] then
-  begin
-    // Release the mouse capture and stop the panscroll timer.
-    KillTimer(Handle, ScrollTimer);
-    ReleaseCapture;
-    DoStateChange([], [tsWheelPanning, tsWheelScrolling]);
-
-    FPanningWindow.Stop;
-    {$ifndef Windows}
-    Cursor := crDefault;
-    {$endif}
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.StructureChange(Node: PVirtualNode; Reason: TChangeReason);
-
-begin
-  AdviseChangeEvent(True, Node, Reason);
-
-  if FUpdateCount = 0 then
-  begin
-    if (FChangeDelay > 0) and not (tsSynchMode in FStates) then
-      SetTimer(Handle, StructureChangeTimer, FChangeDelay, nil)
-    else
-      DoStructureChange(Node, Reason);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.SuggestDropEffect(Source: TObject; Shift: TShiftState; const Pt: TPoint;
-  AllowedEffects: LongWord): LongWord;
-
-// determines the drop action to take if the drag'n drop operation ends on this tree
-// Note: Source can be any Delphi object not just a virtual tree
-
-begin
-  Result := AllowedEffects;
-
-  // prefer MOVE if source and target are the same control, otherwise whatever is allowed as initial value
-  if Assigned(Source) and (Source = Self) then
-    if (AllowedEffects and DROPEFFECT_MOVE) <> 0 then
-      Result := DROPEFFECT_MOVE
-    else // no change
-  else
-    // drag between different applicatons
-    if (AllowedEffects and DROPEFFECT_COPY) <> 0 then
-      Result := DROPEFFECT_COPY;
-
-  // consider modifier keys and what is allowed at the moment, if none of the following conditions apply then
-  // the initial value just set is used
-  if ssCtrlOS in Shift then
-  begin
-    // copy or link
-    if ssShift in Shift then
-    begin
-      // link
-      if (AllowedEffects and DROPEFFECT_LINK) <> 0 then
-        Result := DROPEFFECT_LINK;
-    end
-    else
-    begin
-      // copy
-      if (AllowedEffects and DROPEFFECT_COPY) <> 0 then
-        Result := DROPEFFECT_COPY;
-    end;
-  end
-  else
-  begin
-    // move, link or default
-    if ssShift in Shift then
-    begin
-      // move
-      if (AllowedEffects and DROPEFFECT_MOVE) <> 0 then
-        Result := DROPEFFECT_MOVE;
-    end
-    else
-    begin
-      // link or default
-      if ssAlt in Shift then
-      begin
-        // link
-        if (AllowedEffects and DROPEFFECT_LINK) <> 0 then
-          Result := DROPEFFECT_LINK;
-      end;
-      // else default
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ToggleSelection(StartNode, EndNode: PVirtualNode);
-
-// Switchs the selection state of a range of nodes.
-// Note: This method is specifically designed to help selecting ranges with the keyboard and considers therefore
-//       the range anchor.
-
-var
-  NodeFrom,
-  NodeTo: PVirtualNode;
-  NewSize: Integer;
-  Position: Integer;
-
-begin
-  if not FSelectionLocked then
-  begin
-    Assert(Assigned(EndNode), 'EndNode must not be nil!');
-    if StartNode = nil then
-      StartNode := FRoot.FirstChild
-    else
-      if not FullyVisible[StartNode] then
-        StartNode := GetPreviousVisible(StartNode, True);
-
-    Position := CompareNodePositions(StartNode, EndNode);
-    // nothing to do if start and end node are the same
-    if Position <> 0 then
-    begin
-      if Position < 0 then
-      begin
-        NodeFrom := StartNode;
-        NodeTo := EndNode;
-      end
-      else
-      begin
-        NodeFrom := EndNode;
-        NodeTo := StartNode;
-      end;
-
-      ClearTempCache;
-
-      // 1) toggle the start node if it is before the range anchor
-      if CompareNodePositions(NodeFrom, FRangeAnchor) < 0 then
-        if not (vsSelected in NodeFrom.States) then
-          InternalCacheNode(NodeFrom)
-        else
-          InternalRemoveFromSelection(NodeFrom);
-
-      // 2) toggle all nodes within the range
-      NodeFrom := GetNextVisible(NodeFrom, True);
-      while NodeFrom <> NodeTo do
-      begin
-        if not (vsSelected in NodeFrom.States) then
-          InternalCacheNode(NodeFrom)
-        else
-          InternalRemoveFromSelection(NodeFrom);
-        NodeFrom := GetNextVisible(NodeFrom, True);
-      end;
-
-      // 3) toggle end node if it is after the range anchor
-      if CompareNodePositions(NodeFrom, FRangeAnchor) > 0 then
-        if not (vsSelected in NodeFrom.States) then
-          InternalCacheNode(NodeFrom)
-        else
-          InternalRemoveFromSelection(NodeFrom);
-
-      // Do some housekeeping if there was a change.
-      NewSize := PackArray(FSelection, FSelectionCount);
-      if NewSize > -1 then
-      begin
-        FSelectionCount := NewSize;
-        SetLength(FSelection, FSelectionCount);
-      end;
-      // If the range went over the anchor then we need to reselect it.
-      if not (vsSelected in FRangeAnchor.States) then
-        InternalCacheNode(FRangeAnchor);
-      if FTempNodeCount > 0 then
-        AddToSelection(FTempNodeCache, FTempNodeCount);
-      ClearTempCache;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UnselectNodes(StartNode, EndNode: PVirtualNode);
-
-// Deselects a range of nodes.
-// EndNode must be visible while StartNode must not as in the case where the last focused node is the start node
-// but it is a child of a node which has been collapsed previously. In this case the first visible parent node
-// is used as start node. StartNode can be nil in which case the very first node in the tree is used.
-
-var
-  NodeFrom,
-  NodeTo: PVirtualNode;
-  NewSize: Integer;
-
-begin
-  if not FSelectionLocked then
-  begin
-    Assert(Assigned(EndNode), 'EndNode must not be nil!');
-
-    if StartNode = nil then
-      StartNode := FRoot.FirstChild
-    else
-      if not FullyVisible[StartNode] then
-      begin
-        StartNode := GetPreviousVisible(StartNode, True);
-        if StartNode = nil then
-          StartNode := FRoot.FirstChild
-      end;
-
-    if CompareNodePositions(StartNode, EndNode) < 0 then
-    begin
-      NodeFrom := StartNode;
-      NodeTo := EndNode;
-    end
-    else
-    begin
-      NodeFrom := EndNode;
-      NodeTo := StartNode;
-    end;
-
-    while NodeFrom <> NodeTo do
-    begin
-      InternalRemoveFromSelection(NodeFrom);
-      NodeFrom := GetNextVisible(NodeFrom, True);
-    end;
-    // Deselect last node too.
-    InternalRemoveFromSelection(NodeFrom);
-
-    // Do some housekeeping.
-    NewSize := PackArray(FSelection, FSelectionCount);
-    if NewSize > -1 then
-    begin
-      FSelectionCount := NewSize;
-      SetLength(FSelection, FSelectionCount);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UpdateCheckImageList;
-begin
-  if FCheckImages <> FCustomCheckImages then
-    FCheckImages.Free;
-  FCheckImages := nil;
-  CheckImageListNeeded;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UpdateColumnCheckState(Col: TVirtualTreeColumn);
-
-begin
-  Col.CheckState := DetermineNextCheckState(Col.CheckType, Col.CheckState);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UpdateDesigner;
-
-var
-  ParentForm: TCustomForm;
-
-begin
-  if (csDesigning in ComponentState) and not (csUpdating in ComponentState) then
-  begin
-    ParentForm := GetParentForm(Self);
-    if Assigned(ParentForm) and Assigned(ParentForm.Designer) then
-      ParentForm.Designer.Modified;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UpdateHeaderRect;
-
-// Calculates the rectangle the header occupies in non-client area.
-// These coordinates are in window rectangle.
-
-var
-  OffsetX,
-  OffsetY: Integer;
-  //EdgeSize: Integer;
-  Size: TSize;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintHeader],'UpdateHeaderRect');{$endif}
-  FHeaderRect := Rect(0, 0, Width, Height);
-
-  // Consider borders...
-  Size := GetBorderDimensions;
-  //lclheader
-  //Adjust rect size
-  Inc(FHeaderRect.Right,Size.cx*2);
-
-  // ... and bevels.
-  OffsetX := BorderWidth;
-  OffsetY := BorderWidth;
-  //todo_lcl
-  {
-  if BevelKind <> bkNone then
-  begin
-    EdgeSize := 0;
-    if BevelInner <> bvNone then
-      Inc(EdgeSize, BevelWidth);
-    if BevelOuter <> bvNone then
-      Inc(EdgeSize, BevelWidth);
-    if beLeft in BevelEdges then
-      Inc(OffsetX, EdgeSize);
-    if beTop in BevelEdges then
-      Inc(OffsetY, EdgeSize);
-  end;
-  }
-  InflateRect(FHeaderRect, -OffsetX, -OffsetY);
-
-  if hoVisible in FHeader.FOptions then
-  begin
-    if FHeaderRect.Left <= FHeaderRect.Right then
-      FHeaderRect.Bottom := FHeaderRect.Top + Integer(FHeader.FHeight)
-    else
-      FHeaderRect := Rect(0, 0, 0, 0);
-  end
-  else
-    FHeaderRect.Bottom := FHeaderRect.Top;
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'FHeaderRect',FHeaderRect);{$endif}
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintHeader],'UpdateHeaderRect');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UpdateEditBounds;
-
-// Used to update the bounds of the current node editor if editing is currently active.
-
-var
-  R: TRect;
-  Dummy: Integer;
-  CurrentAlignment: TAlignment;
-  CurrentBidiMode: TBidiMode;
-
-begin
-  if tsEditing in FStates then
-  begin
-    if vsMultiline in FFocusedNode.States then
-      R := GetDisplayRect(FFocusedNode, FEditColumn, True, False)
-    else
-      R := GetDisplayRect(FFocusedNode, FEditColumn, True, True);
-    if (toGridExtensions in FOptions.FMiscOptions) then
-    begin
-      // Adjust edit bounds depending on alignment and bidi mode.
-      if FEditColumn <= NoColumn then
-      begin
-        CurrentAlignment := Alignment;
-        CurrentBidiMode := BiDiMode;
-      end
-      else
-      begin
-        CurrentAlignment := FHeader.Columns[FEditColumn].FAlignment;
-        CurrentBidiMode := FHeader.Columns[FEditColumn].FBidiMode;
-      end;
-      // Consider bidi mode here. In RTL context does left alignment actually mean right alignment and vice versa.
-      if CurrentBidiMode <> bdLeftToRight then
-        ChangeBiDiModeAlignment(CurrentAlignment);
-      if CurrentAlignment = taLeftJustify then
-        FHeader.Columns.GetColumnBounds(FEditColumn, Dummy, R.Right)
-      else
-        FHeader.Columns.GetColumnBounds(FEditColumn, R.Left, Dummy);
-    end;
-    if toShowHorzGridLines in TreeOptions.PaintOptions then
-      Dec(R.Bottom);
-    FEditLink.SetBounds(R);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-const
-  ScrollMasks: array[Boolean] of Cardinal = (0, SIF_DISABLENOSCROLL);
-
-const // Region identifiers for GetRandomRgn
-  {
-  CLIPRGN = 1;
-  METARGN = 2;
-  APIRGN = 3;
-  }
-  SYSRGN = 4;
-
-procedure TBaseVirtualTree.UpdateWindowAndDragImage(const Tree: TBaseVirtualTree; TreeRect: TRect; UpdateNCArea,
-  ReshowDragImage: Boolean);
-
-// Method to repaint part of the window area which is not covered by the drag image and to initiate a recapture
-// of the drag image.
-// Note: This method must only be called during a drag operation and the tree passed in is the one managing the current
-// drag image (so it is the actual drag source).
-{$ifndef INCOMPLETE_WINAPI}
-var
-  DragRegion,          // the region representing the drag image
-  UpdateRegion,        // the unclipped region within the tree to be updated
-  NCRegion: HRGN;      // the region representing the non-client area of the tree
-  DragRect,
-  NCRect: TRect;
-  RedrawFlags: Cardinal;
-
-  VisibleTreeRegion: HRGN;
-
-  DC: HDC;
-{$endif}
-
-begin
-  //todo: reimplement
-  {$ifndef INCOMPLETE_WINAPI}
-  if IntersectRect(TreeRect, TreeRect, ClientRect) then
-  begin
-    // Retrieve the visible region of the window. This is important to avoid overpainting parts of other windows
-    // which overlap this one.
-    VisibleTreeRegion := CreateRectRgn(0, 0, 1, 1);
-    DC := GetDCEx(Handle, 0, DCX_CACHE or DCX_WINDOW or DCX_CLIPSIBLINGS or DCX_CLIPCHILDREN);
-    GetRandomRgn(DC, VisibleTreeRegion, SYSRGN);
-    ReleaseDC(Handle, DC);
-
-    // In Win9x the returned visible region is given in client coordinates. We need it in screen coordinates, though.
-    if not IsWinNT then
-      with ClientToScreen(Point(0, 0)) do
-        OffsetRgn(VisibleTreeRegion, X, Y);
-
-    // The drag image will figure out itself what part of the rectangle can be recaptured.
-    // Recapturing is not done by taking a snapshot of the screen, but by letting the tree draw itself
-    // into the back bitmap of the drag image. So the order here is unimportant.
-    Tree.FDragImage.RecaptureBackground(Self, TreeRect, VisibleTreeRegion, UpdateNCArea, ReshowDragImage);
-
-    // Calculate the screen area not covered by the drag image and which needs an update.
-    DragRect := Tree.FDragImage.GetDragImageRect;
-    MapWindowPoints(0, Handle, DragRect, 2);
-    DragRegion := CreateRectRgnIndirect(DragRect);
-
-    // Start with non-client area if requested.
-    if UpdateNCArea then
-    begin
-      // Compute the part of the non-client area which must be updated.
-
-      // Determine the outer rectangle of the entire tree window.
-      GetWindowRect(Handle, NCRect);
-      // Express the tree window rectangle in client coordinates (because RedrawWindow wants them so).
-      MapWindowPoints(0, Handle, NCRect, 2);
-      NCRegion := CreateRectRgnIndirect(NCRect);
-      // Determine client rect in screen coordinates and create another region for it.
-      UpdateRegion := CreateRectRgnIndirect(ClientRect);
-      // Create a region which only contains the NC part by subtracting out the client area.
-      CombineRgn(NCRegion, NCRegion, UpdateRegion, RGN_DIFF);
-      // Subtract also out what is hidden by the drag image.
-      CombineRgn(NCRegion, NCRegion, DragRegion, RGN_DIFF);
-      RedrawWindow(Handle, nil, NCRegion, RDW_FRAME or RDW_NOERASE or RDW_NOCHILDREN or RDW_INVALIDATE or RDW_VALIDATE or
-        RDW_UPDATENOW);
-      DeleteObject(NCRegion);
-      DeleteObject(UpdateRegion);
-    end;
-
-    UpdateRegion := CreateRectRgnIndirect(TreeRect);
-    RedrawFlags := RDW_INVALIDATE or RDW_VALIDATE or RDW_UPDATENOW or RDW_NOERASE or RDW_NOCHILDREN;
-    // Remove the part of the update region which is covered by the drag image.
-    CombineRgn(UpdateRegion, UpdateRegion, DragRegion, RGN_DIFF);
-    RedrawWindow(Handle, nil, UpdateRegion, RedrawFlags);
-    DeleteObject(UpdateRegion);
-    DeleteObject(DragRegion);
-    DeleteObject(VisibleTreeRegion);
-  end;
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ValidateCache;
-
-// Starts cache validation if not already done by adding this instance to the worker thread's waiter list
-// (if not already there) and signalling the thread it can start validating.
-
-begin
-  // Wait for thread to stop validation if it is currently validating this tree's cache.
-  InterruptValidation;
-
-  FStartIndex := 0;
-  {$ifdef EnableThreadSupport}
-  if tsValidationNeeded in FStates then
-  begin
-    // Tell the thread this tree needs actually something to do.
-    WorkerThread.AddTree(Self);
-    WorkEvent.SetEvent;
-  end;
-  {$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ValidateNodeDataSize(var Size: Integer);
-
-begin
-  Size := 0;
-  if Assigned(FOnGetNodeDataSize) then
-    FOnGetNodeDataSize(Self, Size);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WndProc(var Message: TLMessage);
-
-var
-  Handled: Boolean;
-
-begin
-  Handled := False;
-
-  // Try the header whether it needs to take this message.
-  if Assigned(FHeader) and (FHeader.FStates <> []) then
-    Handled := FHeader.HandleMessage(Message);
-  if not Handled then
-  begin
-    // For auto drag mode, let tree handle itself, instead of TControl.
-    if not (csDesigning in ComponentState) and
-       ((Message.Msg = LM_LBUTTONDOWN) or (Message.Msg = LM_LBUTTONDBLCLK)) then
-    begin
-      Handled := (DragMode = dmAutomatic) and (DragKind = dkDrag);
-      if Handled then
-      begin
-        if not IsControlMouseMsg(TLMMouse(Message)) then
-        begin
-          //lclheader
-          //let the header handle the message here
-          //otherwise no header click event will be fired
-          FHeader.HandleMessage(Message);
-          ControlState := ControlState + [csLButtonDown];
-          Dispatch(Message);  // overrides TControl's BeginDrag
-        end;
-      end;
-    end;
-
-    if not Handled and Assigned(FHeader) then
-      Handled := FHeader.HandleMessage(Message);
-
-    if not Handled then
-      inherited;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WriteChunks(Stream: TStream; Node: PVirtualNode);
-
-// Writes the core chunks for Node into the stream.
-// Note: descendants can optionally override this method to add other node specific chunks.
-//       Keep in mind that this method is also called for the root node. Using this fact in descendants you can
-//       create a kind of "global" chunks not directly bound to a specific node.
-
-var
-  Header: TChunkHeader;
-  LastPosition,
-  ChunkSize: Integer;
-  Chunk: TBaseChunk;
-  Run: PVirtualNode;
-
-begin
-  with Stream do
-  begin
-    // 1. The base chunk...
-    LastPosition := Position;
-    Chunk.Header.ChunkType := BaseChunk;
-    with Node^, Chunk do
-    begin
-      Body.ChildCount := ChildCount;
-      Body.NodeHeight := NodeHeight;
-      // Some states are only temporary so take them out as they make no sense at the new location.
-      Body.States := States - [vsChecking, vsCutOrCopy, vsDeleting, vsInitialUserData, vsHeightMeasured];
-      Body.Align := Align;
-      Body.CheckState := CheckState;
-      Body.CheckType := CheckType;
-      Body.Reserved := 0;
-    end;
-    // write the base chunk
-    Write(Chunk, SizeOf(Chunk));
-
-    // 2. ... directly followed by the child node chunks (actually they are child chunks of
-    //   the base chunk)
-    if vsInitialized in Node.States then
-    begin
-      Run := Node.FirstChild;
-      while Assigned(Run) do
-      begin
-        WriteNode(Stream, Run);
-        Run := Run.NextSibling;
-      end;
-    end;
-
-    FinishChunkHeader(Stream, LastPosition, Position);
-
-    // 3. write user data
-    LastPosition := Position;
-    Header.ChunkType := UserChunk;
-    Write(Header, SizeOf(Header));
-    DoSaveUserData(Node, Stream);
-    // check if the application actually wrote data
-    ChunkSize := Position - LastPosition - SizeOf(TChunkHeader);
-    // seek back to start of chunk if nothing has been written
-    if ChunkSize = 0 then
-    begin
-      Position := LastPosition;
-      Size := Size - SizeOf(Header);
-    end
-    else
-      FinishChunkHeader(Stream, LastPosition, Position);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.WriteNode(Stream: TStream; Node: PVirtualNode);
-
-// Writes the "cover" chunk for Node to Stream and initiates writing child nodes and chunks.
-
-var
-  LastPosition: Integer;
-  Header: TChunkHeader;
-
-begin
-  // Initialize the node first if necessary and wanted.
-  if toInitOnSave in FOptions.FMiscOptions then
-  begin
-    if not (vsInitialized in Node.States) then
-      InitNode(Node);
-    if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then
-      InitChildren(Node);
-  end;
-
-  with Stream do
-  begin
-    LastPosition := Position;
-    // Emit the anchor chunk.
-    Header.ChunkType := NodeChunk;
-    Write(Header, SizeOf(Header));
-    // Write other chunks to stream taking their size into this chunk's size.
-    WriteChunks(Stream, Node);
-
-    // Update chunk size.
-    FinishChunkHeader(Stream, LastPosition, Position);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.AbsoluteIndex(Node: PVirtualNode): Cardinal;
-
-begin
-  Result := 0;
-  while Assigned(Node) and (Node <> FRoot) do
-  begin
-    if not (vsInitialized in Node.States) then
-      InitNode(Node);
-    if Assigned(Node.PrevSibling) then
-    begin
-      // if there's a previous sibling then add its total count to the result
-      Node := Node.PrevSibling;
-      Inc(Result, Node.TotalCount);
-    end
-    else
-    begin
-      Node := Node.Parent;
-      if Node <> FRoot then
-        Inc(Result);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode;
-
-// Adds a new node to the given parent node. This is simply done by increasing the child count of the
-// parent node. If Parent is nil then the new node is added as (last) top level node.
-// UserData can be used to set the first 4 bytes of the user data area to an initial value which can be used
-// in OnInitNode and will also cause to trigger the OnFreeNode event (if <> nil) even if the node is not yet
-// "officially" initialized.
-// AddChild is a compatibility method and will implicitly validate the parent node. This is however
-// against the virtual paradigm and hence I dissuade from its usage.
-
-var
-  NodeData: ^Pointer;
-
-begin
-  if not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    CancelEditNode;
-
-    if Parent = nil then
-      Parent := FRoot;
-    if not (vsInitialized in Parent.States) then
-      InitNode(Parent);
-
-    // Locally stop updates of the tree in order to avoid usage of the new node before it is correctly set up.
-    // If the update count was 0 on enter then there will be a correct update at the end of this method.
-    Inc(FUpdateCount);
-    try
-      SetChildCount(Parent, Parent.ChildCount + 1);
-      // Update the hidden children flag of the parent. Nodes are added as being visible by default.
-      Exclude(Parent.States, vsAllChildrenHidden);
-    finally
-      Dec(FUpdateCount);
-    end;
-    Result := Parent.LastChild;
-
-    // Check if there is initial user data and there is also enough user data space allocated.
-    if Assigned(UserData) then
-      if FNodeDataSize >= 4 then
-      begin
-        NodeData := Pointer(PByte(@Result.Data) + FTotalInternalDataSize);
-        NodeData^ := UserData;
-        Include(Result.States, vsInitialUserData);
-      end
-      else
-        ShowError(SCannotSetUserData, hcTFCannotSetUserData);
-
-    InvalidateCache;
-    if FUpdateCount = 0 then
-    begin
-      ValidateCache;
-      if tsStructureChangePending in FStates then
-      begin
-        if Parent = FRoot then
-          StructureChange(nil, crChildAdded)
-        else
-          StructureChange(Parent, crChildAdded);
-      end;
-
-      if (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then
-        Sort(Parent, FHeader.FSortColumn, FHeader.FSortDirection, True);
-
-      InvalidateToBottom(Parent);
-      //lcl 
-      //Calling UpdateHorizontalScrollBar without a header leads to a
-      //wrong NodeWidth because the node is not initialized at this time.
-      //As result the horizontal scrollbar is not correctly
-      //sized and the node can not be selected by a click.
-      if HandleAllocated then
-        UpdateVerticalScrollBar(True)
-    end;
-  end
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AddFromStream(Stream: TStream; TargetNode: PVirtualNode);
-
-// loads nodes from the given stream and adds them to TargetNode
-// the current content is not cleared before the load process starts (see also LoadFromStream)
-
-var
-  ThisID: TMagicID;
-  Version,
-  Count: Cardinal;
-  Node: PVirtualNode;
-
-begin
-  if not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    // check first whether this is a stream we can read
-    Stream.ReadBuffer(ThisID, SizeOf(TMagicID));
-    if (ThisID[0] = MagicID[0]) and
-       (ThisID[1] = MagicID[1]) and
-       (ThisID[2] = MagicID[2]) and
-       (ThisID[5] = MagicID[5]) then
-    begin
-      Version := Word(ThisID[3]);
-      if Version <= VTTreeStreamVersion  then
-      begin
-        BeginUpdate;
-        try
-          if Version < 2 then
-            Count := MaxInt
-          else
-            Stream.ReadBuffer(Count, SizeOf(Count));
-
-          while (Stream.Position < Stream.Size) and (Count > 0) do
-          begin
-            Dec(Count);
-            Node := MakeNewNode;
-            InternalConnectNode(Node, TargetNode, Self, amAddChildLast);
-            InternalAddFromStream(Stream, Version, Node);
-          end;
-          if TargetNode = FRoot then
-            DoNodeCopied(nil)
-          else
-            DoNodeCopied(TargetNode);
-        finally
-          EndUpdate;
-        end;
-      end
-      else
-        ShowError(SWrongStreamVersion, hcTFWrongStreamVersion);
-    end
-    else
-      ShowError(SWrongStreamVersion, hcTFWrongStreamVersion);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.AfterConstruction;
-
-begin
-  inherited;
-
-  if FRoot = nil then
-    InitRootNode;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.Assign(Source: TPersistent);
-
-begin
-  if (Source is TBaseVirtualTree) and not (toReadOnly in FOptions.FMiscOptions) then
-    with Source as TBaseVirtualTree do
-    begin
-      Self.Align := Align;
-      Self.Anchors := Anchors;
-      Self.AutoScrollDelay := AutoScrollDelay;
-      Self.AutoScrollInterval := AutoScrollInterval;
-      Self.AutoSize := AutoSize;
-      Self.Background := Background;
-      //todo_lcl
-      {
-      Self.BevelEdges := BevelEdges;
-      Self.BevelInner := BevelInner;
-      Self.BevelKind := BevelKind;
-      Self.BevelOuter := BevelOuter;
-      Self.BevelWidth := BevelWidth;
-      }
-      Self.BiDiMode := BiDiMode;
-      Self.BorderStyle := BorderStyle;
-      Self.BorderWidth := BorderWidth;
-      Self.ChangeDelay := ChangeDelay;
-      Self.CheckImageKind := CheckImageKind;
-      Self.Color := Color;
-      Self.Colors.Assign(Colors);
-      Self.Constraints.Assign(Constraints);
-      Self.DefaultNodeHeight := DefaultNodeHeight;
-      Self.DefaultPasteMode := DefaultPasteMode;
-      Self.DragCursor := DragCursor;
-      Self.DragImageKind := DragImageKind;
-      Self.DragKind := DragKind;
-      Self.DragMode := DragMode;
-      Self.Enabled := Enabled;
-      Self.Font := Font;
-      Self.Header := Header;
-      Self.HintMode := HintMode;
-      Self.HotCursor := HotCursor;
-      Self.Images := Images;
-      //Self.ImeMode := ImeMode;
-      //Self.ImeName := ImeName;
-      Self.Indent := Indent;
-      Self.Margin := Margin;
-      Self.NodeAlignment := NodeAlignment;
-      Self.NodeDataSize := NodeDataSize;
-      Self.TreeOptions := TreeOptions;
-      //Self.ParentBiDiMode := ParentBiDiMode;
-      Self.ParentColor := ParentColor;
-      Self.ParentFont := ParentFont;
-      Self.ParentShowHint := ParentShowHint;
-      Self.PopupMenu := PopupMenu;
-      Self.RootNodeCount := RootNodeCount;
-      Self.ScrollBarOptions := ScrollBarOptions;
-      Self.ShowHint := ShowHint;
-      Self.StateImages := StateImages;
-      Self.TabOrder := TabOrder;
-      Self.TabStop := TabStop;
-      Self.Visible := Visible;
-      Self.SelectionCurveRadius := SelectionCurveRadius;
-      Self.SelectionBlendFactor := SelectionBlendFactor;
-    end
-    else
-      inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.BeginDrag(Immediate: Boolean; Threshold: Integer);
-
-// Reintroduced method to allow to start OLE drag'n drop as well as VCL drag'n drop.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcDrag],'BeginDrag');{$endif}
-  if FDragType = dtVCL then
-  begin
-    DoStateChange([tsVCLDragPending]);
-    inherited;
-  end
-  else
-    if (FStates * [tsOLEDragPending, tsOLEDragging]) = [] then
-    begin
-      // Drag start position has already been recorded in WMMouseDown.
-      if Threshold < 0 then
-        FDragThreshold := DragManager.DragThreshold
-      else
-        FDragThreshold := Threshold;
-      if Immediate then
-        DoDragging(FLastClickPos)
-      else
-        DoStateChange([tsOLEDragPending]);
-    end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcDrag],'BeginDrag');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.BeginSynch;
-
-// Starts the synchronous update mode (if not already active).
-
-begin
-  if not (csDestroying in ComponentState) then
-  begin
-    if FSynchUpdateCount = 0 then
-    begin
-      DoUpdating(usBeginSynch);
-
-      // Stop all timers...
-      KillTimer(Handle, ChangeTimer);
-      KillTimer(Handle, StructureChangeTimer);
-      KillTimer(Handle, ExpandTimer);
-      KillTimer(Handle, EditTimer);
-      KillTimer(Handle, ScrollTimer);
-      KillTimer(Handle, SearchTimer);
-      FSearchBuffer := '';
-      FLastSearchNode := nil;
-      DoStateChange([], [tsEditPending, tsScrollPending, tsScrolling, tsIncrementalSearching]);
-
-      // ...and trigger pending update states.
-      if tsStructureChangePending in FStates then
-        DoStructureChange(FLastStructureChangeNode, FLastStructureChangeReason);
-      if tsChangePending in FStates then
-        DoChange(FLastChangedNode);
-    end
-    else
-      DoUpdating(usSynch);
-  end;
-  Inc(FSynchUpdateCount);
-  DoStateChange([tsSynchMode]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.BeginUpdate;
-
-begin
-  if not (csDestroying in ComponentState) then
-  begin
-    if FUpdateCount = 0 then
-    begin
-      DoUpdating(usBegin);
-      SetUpdateState(True);
-    end
-    else
-      DoUpdating(usUpdate);
-  end;
-  Inc(FUpdateCount);
-  DoStateChange([tsUpdating]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CancelCutOrCopy;
-
-// Resets nodes which are marked as being cut.
-
-var
-  Run: PVirtualNode;
-
-begin
-  if ([tsCutPending, tsCopyPending] * FStates) <> [] then
-  begin
-    Run := FRoot.FirstChild;
-    while Assigned(Run) do
-    begin
-      if vsCutOrCopy in Run.States then
-        Exclude(Run.States, vsCutOrCopy);
-      Run := GetNextNoInit(Run);
-    end;
-  end;
-  DoStateChange([], [tsCutPending, tsCopyPending]);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CancelEditNode: Boolean;
-
-// Called by the application or the current edit link to cancel the edit action.
-
-begin
-  if HandleAllocated and ([tsEditing, tsEditPending] * FStates <> []) then
-    Result := DoCancelEdit
-  else
-    Result := True;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CancelOperation;
-
-// Called by the application to cancel a long-running operation.
-
-begin
-  if FOperationCount > 0 then
-    FOperationCanceled := True;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CanEdit(Node: PVirtualNode; Column: TColumnIndex): Boolean;
-
-// Returns True if the given node can be edited.
-
-begin
-  Result := (toEditable in FOptions.FMiscOptions) and Enabled and not (toReadOnly in FOptions.FMiscOptions);
-  DoCanEdit(Node, Column, Result);
-end;
-
-function TBaseVirtualTree.CanScroll(const ClientMousePos: TPoint): Boolean;
-// Determines whether auto scrolling can occur based on current mouse cursor position.
-begin
-  Result := False;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.Clear;
-
-begin
-  if not (toReadOnly in FOptions.FMiscOptions) or (csDestroying in ComponentState) then
-  begin
-    BeginUpdate;
-    try
-      InterruptValidation;
-      if IsEditing then
-        CancelEditNode;
-
-      if ClipboardStates * FStates <> [] then
-      begin
-        OleSetClipBoard(nil);
-        DoStateChange([], ClipboardStates);
-      end;
-      ClearSelection;
-      FFocusedNode := nil;
-      FLastSelected := nil;
-      FCurrentHotNode := nil;
-      FDropTargetNode := nil;
-      FLastChangedNode := nil;
-      FRangeAnchor := nil;
-      FCheckNode := nil;
-      FLastVCLDragTarget := nil;
-      FLastSearchNode := nil;
-      DeleteChildren(FRoot, True);
-      FOffsetX := 0;
-      FOffsetY := 0;
-    finally
-      EndUpdate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ClearChecked;
-
-var
-  Node: PVirtualNode;
-
-begin
-  Node := RootNode.FirstChild;
-  while Assigned(Node) do
-  begin
-    if Node.CheckState <> csUncheckedNormal then
-      CheckState[Node] := csUncheckedNormal;
-    Node := GetNextNoInit(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ClearSelection;
-
-var
-  Node: PVirtualNode;
-  R: TRect;
-  Counter: Integer;
-
-begin
-  if not FSelectionLocked and (FSelectionCount > 0) and not (csDestroying in ComponentState) then
-  begin
-    if (FUpdateCount = 0) and HandleAllocated and (FVisibleCount > 0) then
-    begin
-      // Iterate through nodes currently visible in the client area and invalidate them.
-      Node := TopNode;
-      if Assigned(Node) then
-        R := GetDisplayRect(Node, NoColumn, False);
-      Counter := FSelectionCount;
-
-      while Assigned(Node) do
-      begin
-        R.Bottom := R.Top + Integer(NodeHeight[Node]);
-        if vsSelected in Node.States then
-        begin
-          InvalidateRect(Handle, @R, False);
-          Dec(Counter);
-          // Only try as many nodes as are selected.
-          if Counter = 0 then
-            Break;
-        end;
-        R.Top := R.Bottom;
-        if R.Top > ClientHeight then
-          Break;
-        Node := GetNextVisibleNoInit(Node, True);
-      end;
-    end;
-
-    InternalClearSelection;
-    Change(nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CopyTo(Source: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode;
-  ChildrenOnly: Boolean): PVirtualNode;
-
-// A simplified CopyTo method to allow to copy nodes to the root of another tree.
-
-begin
-  Result := CopyTo(Source, Tree.FRoot, Mode, ChildrenOnly);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.CopyTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode;
-  ChildrenOnly: Boolean): PVirtualNode;
-
-// Copies Source and all its child nodes to Target.
-// Mode is used to specify further where to add the new node actually (as sibling of Target or as child of Target).
-// Result is the newly created node to which source has been copied if ChildrenOnly is False or just contains Target
-// in the other case.
-// ChildrenOnly determines whether to copy also the source node or only its child nodes.
-
-var
-  TargetTree: TBaseVirtualTree;
-  Stream: TMemoryStream;
-
-begin
-  Assert(TreeFromNode(Source) = Self, 'The source tree must contain the source node.');
-
-  Result := nil;
-  if (Mode <> amNoWhere) and Assigned(Source) and (Source <> FRoot) then
-  begin
-    // Assume that an empty destination means the root in this (the source) tree.
-    if Target = nil then
-    begin
-      TargetTree := Self;
-      Target := FRoot;
-      Mode := amAddChildFirst;
-    end
-    else
-      TargetTree := TreeFromNode(Target);
-
-    if not (toReadOnly in TargetTree.FOptions.FMiscOptions) then
-    begin
-      if Target = TargetTree.FRoot then
-      begin
-        case Mode of
-          amInsertBefore:
-            Mode := amAddChildFirst;
-          amInsertAfter:
-            Mode := amAddChildLast;
-        end;
-      end;
-
-      Stream := TMemoryStream.Create;
-      try
-        // Write all nodes into a temprary stream depending on the ChildrenOnly flag.
-        if not ChildrenOnly then
-          WriteNode(Stream, Source)
-        else
-        begin
-          Source := Source.FirstChild;
-          while Assigned(Source) do
-          begin
-            WriteNode(Stream, Source);
-            Source := Source.NextSibling;
-          end;
-        end;
-        // Now load the serialized nodes into the target node (tree).
-        TargetTree.BeginUpdate;
-        try
-          Stream.Position := 0;
-          while Stream.Position < Stream.Size do
-          begin
-            Result := TargetTree.MakeNewNode;
-            InternalConnectNode(Result, Target, TargetTree, Mode);
-            TargetTree.InternalAddFromStream(Stream, VTTreeStreamVersion, Result);
-            if not DoNodeCopying(Result, Target) then
-            begin
-              TargetTree.DeleteNode(Result);
-              Result := nil;
-            end
-            else
-              DoNodeCopied(Result);
-          end;
-          if ChildrenOnly then
-            Result := Target;
-        finally
-          TargetTree.EndUpdate;
-        end;
-      finally
-        Stream.Free;
-      end;
-
-      with TargetTree do
-      begin
-        InvalidateCache;
-        if FUpdateCount = 0 then
-        begin
-          ValidateCache;
-          UpdateScrollBars(True);
-          Invalidate;
-        end;
-        StructureChange(Source, crNodeCopied);
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CopyToClipBoard;
-
-var
-  DataObject: IDataObject;
-
-begin
-  if FSelectionCount > 0 then
-  begin
-    DataObject := TVTDataObject.Create(Self, True) as IDataObject;
-    if OleSetClipBoard(DataObject) = S_OK then
-    begin
-      MarkCutCopyNodes;
-      DoStateChange([tsCopyPending]);
-      Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.CutToClipBoard;
-
-var
-  DataObject: IDataObject;
-
-begin
-  if (FSelectionCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    DataObject := TVTDataObject.Create(Self, True) as IDataObject;
-    if OleSetClipBoard(DataObject) = S_OK then
-    begin
-      MarkCutCopyNodes;
-      DoStateChange([tsCutPending], [tsCopyPending]);
-      Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DefaultHandler(var AMessage);
-begin
-  //used to avoid default handler of LM_MOUSEWHEEL
-end;
-
-
-procedure TBaseVirtualTree.DeleteChildren(Node: PVirtualNode; ResetHasChildren: Boolean = False);
-
-// Removes all children and their children from memory without changing the vsHasChildren style by default.
-
-var
-  Run,
-  Mark: PVirtualNode;
-  LastTop,
-  LastLeft,
-  NewSize: Integer;
-  ParentVisible: Boolean;
-
-begin
-  if (Node.ChildCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    Assert(not (tsIterating in FStates), 'Deleting nodes during tree iteration leads to invalid pointers.');
-
-    // The code below uses some flags for speed improvements which may cause invalid pointers if updates of
-    // the tree happen. Hence switch updates off until we have finished the operation.
-    Inc(FUpdateCount);
-    try
-      InterruptValidation;
-      LastLeft := -FEffectiveOffsetX;
-      LastTop := FOffsetY;
-
-      // Make a local copy of the visibility state of this node to speed up
-      // adjusting the visible nodes count.
-      ParentVisible := Node = FRoot;
-      if not ParentVisible then
-        ParentVisible := FullyVisible[Node] and (vsExpanded in Node.States);
-
-      // Show that we are clearing the child list, to avoid registering structure change events.
-      Include(Node.States, vsClearing);
-      Run := Node.LastChild;
-      while Assigned(Run) do
-      begin
-        if ParentVisible and (vsVisible in Run.States) then
-          Dec(FVisibleCount);
-
-        Include(Run.States, vsDeleting);
-        Mark := Run;
-        Run := Run.PrevSibling;
-        // Important, to avoid exchange of invalid pointers while disconnecting the node.
-        if Assigned(Run) then
-          Run.NextSibling := nil;
-        DeleteNode(Mark);
-      end;
-      Exclude(Node.States, vsClearing);
-      if ResetHasChildren then
-        Exclude(Node.States, vsHasChildren);
-      if Node <> FRoot then
-        Exclude(Node.States, vsExpanded);
-      Node.ChildCount := 0;
-      if (Node = FRoot) or (vsDeleting in Node.States) then
-      begin
-        Node.TotalHeight := FDefaultNodeHeight + NodeHeight[Node];
-        Node.TotalCount := 1;
-      end
-      else
-      begin
-        AdjustTotalHeight(Node, NodeHeight[Node]);
-        AdjustTotalCount(Node, 1);
-      end;
-      Node.FirstChild := nil;
-      Node.LastChild := nil;
-    finally
-      Dec(FUpdateCount);
-    end;
-
-    InvalidateCache;
-    if FUpdateCount = 0 then
-    begin
-      NewSize := PackArray(FSelection, FSelectionCount);
-      if NewSize > -1 then
-      begin
-        FSelectionCount := NewSize;
-        SetLength(FSelection, FSelectionCount);
-      end;
-
-      ValidateCache;
-      UpdateScrollbars(True);
-      // Invalidate entire tree if it scrolled e.g. to make the last node also the
-      // bottom node in the treeview.
-      if (LastLeft <> FOffsetX) or (LastTop <> FOffsetY) then
-        Invalidate
-      else
-        InvalidateToBottom(Node);
-    end;
-    StructureChange(Node, crChildDeleted);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DeleteNode(Node: PVirtualNode; Reindex: Boolean = True);
-
-var
-  LastTop,
-  LastLeft: Integer;
-  LastParent: PVirtualNode;
-  WasInSynchMode: Boolean;
-  ParentClearing: Boolean;
-
-begin
-  if Assigned(Node) and (Node <> FRoot) and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    Assert(not (tsIterating in FStates), 'Deleting nodes during tree iteration leads to invalid pointers.');
-
-    // Determine parent node for structure change notification.
-    ParentClearing := vsClearing in Node.Parent.States;
-    LastParent := Node.Parent;
-
-    if not ParentClearing then
-    begin
-      if LastParent = FRoot then
-        StructureChange(nil, crChildDeleted)
-      else
-        StructureChange(LastParent, crChildDeleted);
-    end;
-
-    LastLeft := -FEffectiveOffsetX;
-    LastTop := FOffsetY;
-
-    if vsSelected in Node.States then
-    begin
-      if FUpdateCount = 0 then
-      begin
-        // Go temporarily into sync mode to avoid a delayed change event for the node
-        // when unselecting.
-        WasInSynchMode := tsSynchMode in FStates;
-        Include(FStates, tsSynchMode);
-        RemoveFromSelection(Node);
-        if not WasInSynchMode then
-          Exclude(FStates, tsSynchMode);
-        InvalidateToBottom(LastParent);
-      end
-      else
-        InternalRemoveFromSelection(Node);
-    end
-    else
-      InvalidateToBottom(LastParent);
-
-    if tsHint in FStates then
-    begin
-      Application.CancelHint;
-      DoStateChange([], [tsHint]);
-    end;
-
-    DeleteChildren(Node);
-    InternalDisconnectNode(Node, False, Reindex);
-    DoFreeNode(Node);
-
-    if not ParentClearing then
-    begin
-      DetermineHiddenChildrenFlag(LastParent);
-      InvalidateCache;
-      if FUpdateCount = 0 then
-      begin
-        ValidateCache;
-        UpdateScrollbars(True);
-        // Invalidate entire tree if it scrolled e.g. to make the last node also the
-        // bottom node in the treeview.
-        if (LastLeft <> FOffsetX) or (LastTop <> FOffsetY) then
-          Invalidate;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.DeleteSelectedNodes;
-
-// Deletes all currently selected nodes (including their child nodes).
-
-var
-  Nodes: TNodeArray;
-  I: Integer;
-  LevelChange: Boolean;
-
-begin
-  Nodes := nil;
-  if (FSelectionCount > 0) and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    BeginUpdate;
-    try
-      Nodes := GetSortedSelection(True);
-      for I := High(Nodes) downto 1 do
-      begin
-        LevelChange := Nodes[I].Parent <> Nodes[I - 1].Parent;
-        DeleteNode(Nodes[I], LevelChange);
-      end;
-      DeleteNode(Nodes[0]);
-    finally
-      EndUpdate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.Dragging: Boolean;
-
-begin
-  // Check for both OLE drag'n drop as well as VCL drag'n drop.
-  Result := ([tsOLEDragPending, tsOLEDragging] * FStates <> []) or inherited Dragging;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.EditNode(Node: PVirtualNode; Column: TColumnIndex): Boolean;
-
-// Application triggered edit event for the given node.
-// Returns True if the tree started editing otherwise False.
-
-begin
-  Assert(Assigned(Node), 'Node must not be nil.');
-  Assert((Column > InvalidColumn) and (Column < FHeader.Columns.Count),
-    'Column must be a valid column index (-1 if no header is shown).');
-
-  Result := tsEditing in FStates;
-  // If the tree is already editing then we don't disrupt this.
-  if not Result and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    FocusedNode := Node;
-    if Assigned(FFocusedNode) and (Node = FFocusedNode) and CanEdit(FFocusedNode, Column) then
-    begin
-      FEditColumn := Column;
-      if not (vsInitialized in Node.States) then
-        InitNode(Node);
-      DoEdit;
-      Result := tsEditing in FStates;
-    end
-    else
-      Result := False;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.EndEditNode: Boolean;
-
-// Called to finish a current edit action or stop the edit timer if an edit operation is pending.
-
-begin
-  if [tsEditing, tsEditPending] * FStates <> [] then
-    Result := DoEndEdit
-  else
-    Result := True;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.EndSynch;
-
-begin
-  if FSynchUpdateCount > 0 then
-    Dec(FSynchUpdateCount);
-
-  if not (csDestroying in ComponentState) then
-  begin
-    if FSynchUpdateCount = 0 then
-    begin
-      DoStateChange([], [tsSynchMode]);
-      DoUpdating(usEndSynch);
-    end
-    else
-      DoUpdating(usSynch);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.EndUpdate;
-
-var
-  NewSize: Integer;
-
-begin
-  if FUpdateCount > 0 then
-    Dec(FUpdateCount);
-
-  if not (csDestroying in ComponentState) then
-  begin
-    if (FUpdateCount = 0) and (tsUpdating in FStates) then
-    begin
-      if tsUpdateHiddenChildrenNeeded in FStates then
-      begin
-        DetermineHiddenChildrenFlagAllNodes;
-        Exclude(FStates, tsUpdateHiddenChildrenNeeded);
-      end;
-
-      DoStateChange([], [tsUpdating]);
-
-      NewSize := PackArray(FSelection, FSelectionCount);
-      if NewSize > -1 then
-      begin
-        FSelectionCount := NewSize;
-        SetLength(FSelection, FSelectionCount);
-      end;
-
-      InvalidateCache;
-      ValidateCache;
-      if HandleAllocated then
-        UpdateScrollBars(False);
-
-      if tsStructureChangePending in FStates then
-        DoStructureChange(FLastStructureChangeNode, FLastStructureChangeReason);
-      try
-        if tsChangePending in FStates then
-          DoChange(FLastChangedNode);
-      finally
-        if toAutoSort in FOptions.FAutoOptions then
-          SortTree(FHeader.FSortColumn, FHeader.FSortDirection, True);
-
-        SetUpdateState(False);
-        if HandleAllocated then
-          Invalidate;
-        UpdateDesigner;
-      end;
-    end;
-
-    if FUpdateCount = 0 then
-      DoUpdating(usEnd)
-    else
-      DoUpdating(usUpdate);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ExecuteAction(Action: TBasicAction): Boolean;
-
-// Some support for standard actions.
-
-begin
-  Result := inherited ExecuteAction(Action);
-
-  if not Result then
-  begin
-      Result := Action is TEditSelectAll;
-      if Result then
-        SelectAll(False)
-      else
-        begin
-        Result := Action is TEditCopy;
-        if Result then
-          CopyToClipboard
-        else
-          if not (toReadOnly in FOptions.FMiscOptions) then
-          begin
-            Result := Action is TEditCut;
-            if Result then
-              CutToClipBoard
-            else
-            begin
-              Result := Action is TEditPaste;
-              if Result then
-                PasteFromClipboard
-                else
-                begin
-                  Result := Action is TEditDelete;
-                  if Result then
-                    DeleteSelectedNodes
-                end;
-            end;
-          end;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.FinishCutOrCopy;
-
-// Deletes nodes which are marked as being cutted.
-
-var
-  Run, ToDelete: PVirtualNode;
-
-begin
-
-  if tsCutPending in FStates then
-  begin
-    Run := FRoot.FirstChild;
-    while Assigned(Run) do
-    begin
-      if vsCutOrCopy in Run.States then
-      begin
-        ToDelete := Run;
-        Run := GetNextNoInit(Run);
-        DeleteNode(ToDelete);
-      end
-      else
-        Run := GetNextNoInit(Run);
-    end;
-    DoStateChange([], [tsCutPending]);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.FlushClipboard;
-
-// Used to render the data which is currently on the clipboard (finishes delayed rendering).
-
-begin
-  if ClipboardStates * FStates <> [] then
-  begin
-    DoStateChange([tsClipboardFlushing]);
-    OleFlushClipboard;
-    CancelCutOrCopy;
-    DoStateChange([], [tsClipboardFlushing]);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.FullCollapse(Node: PVirtualNode = nil);
-
-// This routine collapses all expanded nodes in the subtree given by Node or the whole tree if Node is FRoot or nil.
-// Only nodes which are expanded will be collapsed. This excludes uninitialized nodes but nodes marked as visible
-// will still be collapsed if they are expanded.
-
-var
-  Stop: PVirtualNode;
-
-begin
-  if FRoot.TotalCount > 1 then
-  begin
-    if Node = FRoot then
-      Node := nil;
-
-    DoStateChange([tsCollapsing]);
-    BeginUpdate;
-    try
-      Stop := Node;
-      Node := GetLastVisibleNoInit(Node, True);
-
-      if Assigned(Node) then
-      begin
-        repeat
-          if [vsHasChildren, vsExpanded] * Node.States = [vsHasChildren, vsExpanded] then
-            ToggleNode(Node);
-          Node := GetPreviousNoInit(Node);
-        until Node = Stop;
-
-        // Collapse the start node too.
-        if Assigned(Node) and ([vsHasChildren, vsExpanded] * Node.States = [vsHasChildren, vsExpanded]) then
-          ToggleNode(Node);
-      end;
-    finally
-      EndUpdate;
-      DoStateChange([], [tsCollapsing]);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.FullExpand(Node: PVirtualNode = nil);
-
-// This routine expands all collapsed nodes in the subtree given by Node or the whole tree if Node is FRoot or nil.
-// All nodes on the way down are initialized so this procedure might take a long time.
-// Since all nodes are validated, the tree cannot make use of optimatizations. Hence it is counter productive and you
-// should consider avoiding its use.
-
-var
-  Stop: PVirtualNode;
-
-begin
-  if FRoot.TotalCount > 1 then
-  begin
-    DoStateChange([tsExpanding]);
-    BeginUpdate;
-    try
-      if Node = nil then
-      begin
-        Node := FRoot.FirstChild;
-        Stop := nil;
-      end
-      else
-      begin
-        Stop := Node.NextSibling;
-        if Stop = nil then
-        begin
-          Stop := Node;
-          repeat
-            Stop := Stop.Parent;
-          until (Stop = FRoot) or Assigned(Stop.NextSibling);
-          if Stop = FRoot then
-            Stop := nil
-          else
-            Stop := Stop.NextSibling;
-        end;
-      end;
-
-      // Initialize the start node. Others will be initialized in GetNext.
-      if not (vsInitialized in Node.States) then
-        InitNode(Node);
-
-      repeat
-        if not (vsExpanded in Node.States) then
-          ToggleNode(Node);
-        Node := GetNext(Node);
-      until Node = Stop;
-    finally
-      EndUpdate;
-      DoStateChange([], [tsExpanding]);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$ifndef fpc}
-
-function TBaseVirtualTree.GetControlsAlignment: TAlignment;
-
-begin
-  Result := FAlignment;
-end;
-
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetDisplayRect(Node: PVirtualNode; Column: TColumnIndex; TextOnly: Boolean;
-  Unclipped: Boolean = False; ApplyCellContentMargin: Boolean = False): TRect;
-
-// Determines the client coordinates the given node covers, depending on scrolling, expand state etc.
-// If the given node cannot be found (because one of its parents is collapsed or it is invisible) then an empty
-// rectangle is returned.
-// If TextOnly is True then only the text bounds are returned, that is, the resulting rectangle's left and right border
-// are updated according to bidi mode, alignment and text width of the node.
-// If Unclipped is True (which only makes sense if also TextOnly is True) then the calculated text rectangle is
-// not clipped if the text does not entirely fit into the text space. This is special handling needed for hints.
-// If ApplyCellContentMargin is True (which only makes sense if also TextOnly is True) then the calculated text
-// rectangle respects the cell content margin.
-// If Column is -1 then the entire client width is used before determining the node's width otherwise the bounds of the
-// particular column are used.
-// Note: Column must be a valid column and is used independent of whether the header is visible or not.
-
-var
-  Temp: PVirtualNode;
-  Offset: Cardinal;
-  Indent,
-  TextWidth: Integer;
-  MainColumnHit: Boolean;
-  CurrentBidiMode: TBidiMode;
-  CurrentAlignment: TAlignment;
-  MaxUnclippedHeight: Integer;
-  TM: TTextMetric;
-  ExtraVerticalMargin: Integer;
-
-begin
-  //{$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintHeader],'GetDisplayRect');{$endif}
-  Assert(Assigned(Node), 'Node must not be nil.');
-  Assert(Node <> FRoot, 'Node must not be the hidden root node.');
-
-  MainColumnHit := (Column + 1) in [0, FHeader.MainColumn + 1];
-  if not (vsInitialized in Node.States) then
-    InitNode(Node);
-
-  Result := Rect(0, 0, 0, 0);
-
-  // Check whether the node is visible (determine indentation level btw.).
-  Temp := Node;
-  if not (vsVisible in Temp.States) then
-    Exit;
-  Indent := 0;
-  while Temp <> FRoot do
-  begin
-    if not (vsVisible in Temp.States) or not (vsExpanded in Temp.Parent.States) then
-      Exit;
-    Temp := Temp.Parent;
-    if MainColumnHit and (Temp <> FRoot) then
-      Inc(Indent, FIndent);
-  end;
-
-  // Here we know the node is visible.
-  Offset := 0;
-  if tsUseCache in FStates then
-  begin
-    // If we can use the position cache then do a binary search to find a cached node which is as close as possible
-    // to the current node. Iterate then through all following and visible nodes and sum up their heights.
-    Temp := FindInPositionCache(Node, Offset);
-    while Assigned(Temp) and (Temp <> Node) do
-    begin
-      Inc(Offset, NodeHeight[Temp]);
-      Temp := GetNextVisibleNoInit(Temp, True);
-    end;
-  end
-  else
-  begin
-    // If the cache is not available then go straight through all nodes up to the root and sum up their heights.
-    Temp := Node;
-    repeat
-      Temp := GetPreviousVisibleNoInit(Temp, True);
-      if Temp = nil then
-        Break;
-      Inc(Offset, NodeHeight[Temp]);
-    until False;
-  end;
-
-  Result := Rect(0, Offset, Max(FRangeX, ClientWidth), Offset + NodeHeight[Node]);
-
-  // Limit left and right bounds to the given column (if any) and move bounds according to current scroll state.
-  if Column > NoColumn then
-  begin
-    FHeader.FColumns.GetColumnBounds(Column, Result.Left, Result.Right);
-    // The right column border is not part of this cell.
-    Dec(Result.Right);
-    OffsetRect(Result, 0, FOffsetY);
-  end
-  else
-    OffsetRect(Result, -FEffectiveOffsetX, FOffsetY);
-
-  // Limit left and right bounds further if only the text area is required.
-  if TextOnly then
-  begin
-    // Start with the offset of the text in the column and consider the indentation level too.
-    Offset := FMargin + Indent;
-    // If the text of a node is involved then we have to consider directionality and alignment too.
-    if Column <= NoColumn then
-    begin
-      CurrentBidiMode := BidiMode;
-      CurrentAlignment := Alignment;
-    end
-    else
-    begin
-      CurrentBidiMode := FHeader.FColumns[Column].BidiMode;
-      CurrentAlignment := FHeader.FColumns[Column].Alignment;
-    end;
-
-    if MainColumnHit then
-    begin
-      if toShowRoot in FOptions.FPaintOptions then
-        Inc(Offset, FIndent);
-      if (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages) and (Node.CheckType <> ctNone) then
-        Inc(Offset, FCheckImages.Height + 2);
-    end;
-    // Consider associated images.
-    if Assigned(FStateImages) and HasImage(Node, ikState, Column) then
-      Inc(Offset, FStateImages.Width + 2);
-    if Assigned(FImages) and HasImage(Node, ikNormal, Column) then
-      Inc(Offset, FImages.Width + 2);
-
-    // Offset contains now the distance from the left or right border of the rectangle (depending on bidi mode).
-    // Now consider the alignment too and calculate the final result.
-    if CurrentBidiMode = bdLeftToRight then
-    begin
-      Inc(Result.Left, Offset);
-      // Left-to-right reading does not need any special adjustment of the alignment.
-    end
-    else
-    begin
-      Dec(Result.Right, Offset);
-
-      // Consider bidi mode here. In RTL context does left alignment actually mean right alignment and vice versa.
-      ChangeBiDiModeAlignment(CurrentAlignment);
-    end;
-
-    TextWidth := DoGetNodeWidth(Node, Column);
-
-    // Keep cell height before applying cell content margin in order to increase cell height if text does not fit
-    // and Unclipped it true (see below).
-    MaxUnclippedHeight := Result.Bottom - Result.Top;
-
-    if ApplyCellContentMargin then
-      DoBeforeCellPaint(Self.Canvas, Node, Column, cpmGetContentMargin, Result, Result);
-
-    if Unclipped then
-    begin
-      // The caller requested the text coordinates unclipped. This means they must be calculated so as would
-      // there be enough space, regardless of column bounds etc.
-      // The layout still depends on the available space too, because this determines the position
-      // of the unclipped text rectangle.
-      if Result.Right - Result.Left < TextWidth - 1 then
-        if CurrentBidiMode = bdLeftToRight then
-          CurrentAlignment := taLeftJustify
-        else
-          CurrentAlignment := taRightJustify;
-
-      // Increase cell height (up to MaxUnclippedHeight determined above) if text does not fit.
-      GetTextMetrics(Self.Canvas.Handle, TM);
-      ExtraVerticalMargin := Math.Min(TM.tmHeight, MaxUnclippedHeight) - (Result.Bottom - Result.Top);
-      if ExtraVerticalMargin > 0 then
-        InflateRect(Result, 0, (ExtraVerticalMargin + 1) div 2);
-
-      case CurrentAlignment of
-        taCenter:
-          begin
-            Result.Left := (Result.Left + Result.Right - TextWidth) div 2;
-            Result.Right := Result.Left + TextWidth;
-          end;
-        taRightJustify:
-          Result.Left := Result.Right - TextWidth;
-      else // taLeftJustify
-        Result.Right := Result.Left + TextWidth - 1;
-      end;
-    end
-    else
-      // Modify rectangle only if the text fits entirely into the given room.
-      if Result.Right - Result.Left > TextWidth then
-        case CurrentAlignment of
-          taCenter:
-            begin
-              Result.Left := (Result.Left + Result.Right - TextWidth) div 2;
-              Result.Right := Result.Left + TextWidth;
-            end;
-          taRightJustify:
-            Result.Left := Result.Right - TextWidth;
-        else // taLeftJustify
-          Result.Right := Result.Left + TextWidth;
-        end;
-  end;
-  //lclheader
-  //todo: add a parameter to decide if the result must be returned as
-  //a tree offset or a control offset
-  if hoVisible in FHeader.FOptions then
-    OffsetRect(Result, 0, FHeader.Height);
-  //{$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'DisplayRect for Node '+IntToStr(Node^.Index),Result);{$endif}
-  //{$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintHeader],'GetDisplayRect');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirst(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the first node in the tree while optionally considering toChildrenAbove.
-
-begin
-  if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-  begin
-    if vsHasChildren in FRoot.States then
-    begin
-      Result := FRoot;
-
-      // Child nodes are the first choice if possible.
-      if Assigned(Result.FirstChild) then
-      begin
-        while Assigned(Result.FirstChild) do
-begin
-          Result := Result.FirstChild;
-          if not (vsInitialized in Result.States) then
-            InitNode(Result);
-
-          if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then
-            InitChildren(Result);
-        end;
-      end
-      else
-        Result := nil;
-    end
-    else
-      Result := nil;
-  end
-  else
-  Result := FRoot.FirstChild;
-
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstChecked(State: TCheckState = csCheckedNormal;
-  ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the first node in the tree with the given check state.
-
-begin
-  Result := GetNextChecked(nil, State, ConsiderChildrenAbove);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstChild(Node: PVirtualNode): PVirtualNode;
-
-// Returns the first child of the given node. The result node is initialized before exit.
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := FRoot.FirstChild
-  else
-  begin
-    if not (vsInitialized in Node.States) then
-      InitNode(Node);
-    if vsHasChildren in Node.States then
-    begin
-      if Node.ChildCount = 0 then
-        InitChildren(Node);
-      Result := Node.FirstChild;
-    end
-    else
-      Result := nil;
-  end;
-
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstCutCopy(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the first node in the tree which is currently marked for a clipboard operation.
-// See also GetNextCutCopy for comments on initialization.
-
-begin
-  Result := GetNextCutCopy(nil, ConsiderChildrenAbove);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstInitialized(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the first node which is already initialized.
-
-begin
-  Result := GetFirstNoInit(ConsiderChildrenAbove);
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    Result := GetNextInitialized(Result, ConsiderChildrenAbove);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstLeaf: PVirtualNode;
-
-// Returns the first node in the tree which has currently no children.
-// The result is initialized if necessary.
-
-begin
-  Result := GetNextLeaf(nil);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstLevel(NodeLevel: Cardinal): PVirtualNode;
-
-// Returns the first node in the tree on a specific level.
-// The result is initialized if necessary.
-
-begin
-  Result := GetFirstNoInit(True);
-  while Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) do
-    Result := GetNextNoInit(Result, True);
-
-  if Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) then // i.e. there is no node with the desired level in the tree
-    Result := nil;
-    
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstNoInit(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the first node in the tree while optionally considering toChildrenAbove.
-// No initialization is performed.
-
-begin
-  if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-  begin
-    if vsHasChildren in FRoot.States then
-    begin
-      Result := FRoot;
-
-      // Child nodes are the first choice if possible.
-      if Assigned(Result.FirstChild) then
-begin
-        while Assigned(Result.FirstChild) do
-          Result := Result.FirstChild;
-      end
-      else
-        Result := nil;
-    end
-    else
-      Result := nil;
-  end
-  else
-  Result := FRoot.FirstChild;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstSelected(ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the first node in the current selection while optionally considering toChildrenAbove.
-
-begin
-  Result := GetNextSelected(nil, ConsiderChildrenAbove);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-
-// Returns the first visible node in the tree while optionally considering toChildrenAbove.
-// If necessary nodes are initialized on demand.
-
-begin
-  Result := Node;
-  if not Assigned(Result) then
-    Result := FRoot;
-
-  if vsHasChildren in Result.States then
-  begin
-    if Result.ChildCount = 0 then
-      InitChildren(Result);
-
-    // Child nodes are the first choice if possible.
-    if Assigned(Result.FirstChild) then
-    begin
-      Result := GetFirstChild(Result);
-
-      if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-      begin
-        repeat
-          // Search the first visible sibling.
-          while Assigned(Result.NextSibling) and not (vsVisible in Result.States) do
-          begin
-            Result := Result.NextSibling;
-            // Init node on demand as this might change the visibility.
-            if not (vsInitialized in Result.States) then
-              InitNode(Result);
-          end;
-
-          // If there a no visible siblings take the parent.
-          if not (vsVisible in Result.States) then
-          begin
-            Result := Result.Parent;
-            if Result = FRoot then
-              Result := nil;
-            Break;
-          end
-          else
-          begin
-            if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then
-              InitChildren(Result);
-            if (not Assigned(Result.FirstChild)) or (not (vsExpanded in Result.States)) then
-            Break;
-          end;
-
-          Result := Result.FirstChild;
-          if not (vsInitialized in Result.States) then
-            InitNode(Result);
-        until False;
-      end
-      else
-      begin
-        // If there are no children or the first child is not visible then search the sibling nodes or traverse parents.
-        if not (vsVisible in Result.States) then
-        begin
-          repeat
-            // Is there a next sibling?
-            if Assigned(Result.NextSibling) then
-            begin
-              Result := Result.NextSibling;
-              // The visible state can be removed during initialization so init the node first.
-              if not (vsInitialized in Result.States) then
-                InitNode(Result);
-              if vsVisible in Result.States then
-                Break;
-            end
-            else
-            begin
-              // No sibling anymore, so use the parent's next sibling.
-              if Result.Parent <> FRoot then
-                Result := Result.Parent
-              else
-              begin
-                // There are no further nodes to examine, hence there is no further visible node.
-                Result := nil;
-                Break;
-              end;
-            end;
-          until False;
-        end;
-      end;
-    end
-    else
-      Result := nil;
-  end
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstVisibleChild(Node: PVirtualNode): PVirtualNode;
-
-// Returns the first visible child node of Node. If necessary nodes are initialized on demand.
-
-begin
-  if Node = nil then
-    Node := FRoot;
-  Result := GetFirstChild(Node);
-
-  if Assigned(Result) and not (vsVisible in Result.States) then
-    Result := GetNextVisibleSibling(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstVisibleChildNoInit(Node: PVirtualNode): PVirtualNode;
-
-// Returns the first visible child node of Node.
-
-begin
-  if Node = nil then
-    Node := FRoot;
-  Result := Node.FirstChild;
-  if Assigned(Result) and not (vsVisible in Result.States) then
-    Result := GetNextVisibleSiblingNoInit(ResulT);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetFirstVisibleNoInit(Node: PVirtualNode = nil;
-  ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-
-// Returns the first visible node in the tree or given subtree while optionally considering toChildrenAbove.
-// No initialization is performed.
-
-begin
-  Result := Node;
-  if not Assigned(Result) then
-    Result := FRoot;
-
-  if vsHasChildren in Result.States then
-  begin
-    // Child nodes are the first choice if possible.
-    if Assigned(Result.FirstChild) then
-    begin
-      Result := Result.FirstChild;
-
-      if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-      begin
-        repeat
-          // Search the first visible sibling.
-          while Assigned(Result.NextSibling) and not (vsVisible in Result.States) do
-            Result := Result.NextSibling;
-
-          // If there a no visible siblings take the parent.
-          if not (vsVisible in Result.States) then
-          begin
-            Result := Result.Parent;
-            if Result = FRoot then
-              Result := nil;
-            Break;
-          end
-          else if (not Assigned(Result.FirstChild)) or (not (vsExpanded in Result.States))then
-            Break;
-
-          Result := Result.FirstChild;
-        until False;
-      end
-      else
-      begin
-        // If there are no children or the first child is not visible then search the sibling nodes or traverse parents.
-        if not (vsVisible in Result.States) then
-        begin
-          repeat
-            // Is there a next sibling?
-            if Assigned(Result.NextSibling) then
-            begin
-              Result := Result.NextSibling;
-              if vsVisible in Result.States then
-                Break;
-            end
-            else
-            begin
-              // No sibling anymore, so use the parent's next sibling.
-              if Result.Parent <> FRoot then
-                Result := Result.Parent
-              else
-              begin
-                // There are no further nodes to examine, hence there is no further visible node.
-                Result := nil;
-                Break;
-              end;
-            end;
-          until False;
-        end;
-      end;
-    end
-    else
-      Result := nil;
-  end
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.GetHitTestInfoAt(X, Y: Integer; Relative: Boolean; var HitInfo: THitInfo);
-
-// Determines the node that occupies the specified point or nil if there's none. The parameter Relative determines
-// whether to consider X and Y as being client coordinates (if True) or as being absolute tree coordinates.
-// HitInfo is filled with flags describing the hit further.
-
-var
-  ColLeft,
-  ColRight: Integer;
-  NodeTop: Integer;
-  InitialColumn,
-  NextColumn: TColumnIndex;
-  CurrentBidiMode: TBidiMode;
-  CurrentAlignment: TAlignment;
-  NodeRect: TRect;
-
-begin
-  HitInfo.HitNode := nil;
-  HitInfo.HitPositions := [];
-  HitInfo.HitColumn := NoColumn;
-
-  // Determine if point lies in the tree's client area.
-  if X < 0 then
-    Include(HitInfo.HitPositions, hiToLeft)
-  else
-    if X > Max(FRangeX, ClientWidth) then
-      Include(HitInfo.HitPositions, hiToRight);
-
-  //lclheader
-  if Y < IfThen(hoVisible in FHeader.Options, FHeader.Height) then
-    Include(HitInfo.HitPositions, hiAbove)
-  else
-    if Y > Max(FRangeY, inherited GetClientRect.Bottom) then
-      Include(HitInfo.HitPositions, hiBelow);
-
-  // If the point is in the tree area then check the nodes.
-  if HitInfo.HitPositions = [] then
-  begin
-    // Convert position into absolute coordinate if necessary.
-    if Relative then
-    begin
-      if X > Header.Columns.GetVisibleFixedWidth then
-        Inc(X, FEffectiveOffsetX);
-      //lclheader
-      if hoVisible in FHeader.Options then
-        Dec(Y, FHeader.Height);
-      Dec(Y, FOffsetY);
-    end;
-
-    HitInfo.HitNode := InternalGetNodeAt(X, Y, False, NodeTop);
-    if HitInfo.HitNode = nil then
-      Include(HitInfo.HitPositions, hiNowhere)
-    else
-    begin
-      // At this point we need some info about the node, so it must be initialized.
-      if not (vsInitialized in HitInfo.HitNode.States) then
-        InitNode(HitInfo.HitNode);
-
-      if FHeader.UseColumns then
-      begin
-        HitInfo.HitColumn := FHeader.Columns.GetColumnAndBounds(Point(X, Y), ColLeft, ColRight, False);
-        // If auto column spanning is enabled then look for the last non empty column.
-        if toAutoSpanColumns in FOptions.FAutoOptions then
-        begin
-          InitialColumn := HitInfo.HitColumn;
-          // Search to the left of the hit column for empty columns.
-          while (HitInfo.HitColumn > NoColumn) and ColumnIsEmpty(HitInfo.HitNode, HitInfo.HitColumn) do
-          begin
-            NextColumn := FHeader.FColumns.GetPreviousVisibleColumn(HitInfo.HitColumn);
-            if NextColumn = InvalidColumn then
-              Break;
-            HitInfo.HitColumn := NextColumn;
-            Dec(ColLeft, FHeader.FColumns[NextColumn].Width);
-          end;
-          // Search to the right of the hit column for empty columns.
-          repeat
-            InitialColumn := FHeader.FColumns.GetNextVisibleColumn(InitialColumn);
-            if (InitialColumn = InvalidColumn) or not ColumnIsEmpty(HitInfo.HitNode, InitialColumn) then
-              Break;
-            Inc(ColRight, FHeader.FColumns[InitialColumn].Width);
-          until False;
-        end;
-        // Make the X position and the right border relative to the start of the column.
-        Dec(X, ColLeft);
-        Dec(ColRight, ColLeft);
-      end
-      else
-      begin
-        HitInfo.HitColumn := NoColumn;
-        ColRight := Max(FRangeX, ClientWidth);
-      end;
-      ColLeft := 0;
-
-      if HitInfo.HitColumn = InvalidColumn then
-        Include(HitInfo.HitPositions, hiNowhere)
-      else
-      begin
-        // From now on X is in "column" coordinates (relative to the left column border).
-        HitInfo.HitPositions := [hiOnItem];
-
-        // Avoid getting the display rect if this is not necessary.
-        if toNodeHeightResize in FOptions.FMiscOptions then
-        begin
-          NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, False);
-          if Y <= (NodeRect.Top - FOffsetY + 1) then
-            Include(HitInfo.HitPositions, hiUpperSplitter)
-          else
-          if Y >= (NodeRect.Bottom - FOffsetY - 3) then
-            Include(HitInfo.HitPositions, hiLowerSplitter);
-        end;
-
-        if HitInfo.HitColumn <= NoColumn then
-        begin
-          CurrentBidiMode := BidiMode;
-          CurrentAlignment := Alignment;
-        end
-        else
-        begin
-          CurrentBidiMode := FHeader.FColumns[HitInfo.HitColumn].BidiMode;
-          CurrentAlignment := FHeader.FColumns[HitInfo.HitColumn].Alignment;
-        end;
-
-        if CurrentBidiMode = bdLeftToRight then
-          DetermineHitPositionLTR(HitInfo, X, ColRight, CurrentAlignment)
-        else
-          DetermineHitPositionRTL(HitInfo, X, ColRight, CurrentAlignment);
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLast(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the very last node in the tree branch given by Node and initializes the nodes all the way down including the
-// result. toChildrenAbove is optionally considered. By using Node = nil the very last node in the tree is returned.
-
-var
-  Next: PVirtualNode;
-
-begin
-  Result := GetLastChild(Node);
-  if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then
-  while Assigned(Result) do
-  begin
-    // Test if there is a next last child. If not keep the node from the last run.
-    // Otherwise use the next last child.
-    Next := GetLastChild(Result);
-    if Next = nil then
-      Break;
-    Result := Next;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLastInitialized(Node: PVirtualNode = nil;
-  ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the very last initialized child node in the tree branch given by Node.
-
-begin
-  Result := GetLastNoInit(Node, ConsiderChildrenAbove);
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    Result := GetPreviousInitialized(Result, ConsiderChildrenAbove);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLastNoInit(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the very last node in the tree branch given by Node without initialization.
-
-var
-  Next: PVirtualNode;
-
-begin
-  Result := GetLastChildNoInit(Node);
-  if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then
-  while Assigned(Result) do
-  begin
-    // Test if there is a next last child. If not keep the node from the last run.
-    // Otherwise use the next last child.
-    Next := GetLastChildNoInit(Result);
-    if Next = nil then
-      Break;
-    Result := Next;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLastChild(Node: PVirtualNode): PVirtualNode;
-
-// Determines the last child of the given node and initializes it if there is one.
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := FRoot.LastChild
-  else
-  begin
-    if not (vsInitialized in Node.States) then
-      InitNode(Node);
-    if vsHasChildren in Node.States then
-    begin
-      if Node.ChildCount = 0 then
-        InitChildren(Node);
-      Result := Node.LastChild;
-    end
-    else
-      Result := nil;
-  end;
-
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLastChildNoInit(Node: PVirtualNode): PVirtualNode;
-
-// Determines the last child of the given node but does not initialize it.
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := FRoot.LastChild
-  else
-  begin
-    if vsHasChildren in Node.States then
-      Result := Node.LastChild
-    else
-      Result := nil;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLastVisible(Node: PVirtualNode = nil; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-
-// Returns the very last visible node in the tree while optionally considering toChildrenAbove.
-// The nodes are intialized all the way down including the result node.
-
-var
-  Next: PVirtualNode;
-
-begin
-  Result := GetLastVisibleChild(Node);
-  if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then
-    while Assigned(Result) do
-    begin
-      // Test if there is a next last visible child. If not keep the node from the last run.
-      // Otherwise use the next last visible child.
-      Next := GetLastVisibleChild(Result);
-      if Next = nil then
-        Break;
-      Result := Next;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLastVisibleChild(Node: PVirtualNode): PVirtualNode;
-
-// Determines the last visible child of the given node and initializes it if necessary.
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := GetLastChild(FRoot)
-  else
-    if FullyVisible[Node] and (vsExpanded in Node.States) then
-      Result := GetLastChild(Node)
-    else
-      Result := nil;
-
-  if Assigned(Result) and not (vsVisible in Result.States) then
-    Result := GetPreviousVisibleSibling(Result);
-
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLastVisibleChildNoInit(Node: PVirtualNode): PVirtualNode;
-
-// Determines the last visible child of the given node without initialization.
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := GetLastChildNoInit(FRoot)
-  else
-    if FullyVisible[Node] and (vsExpanded in Node.States) then
-      Result := GetLastChildNoInit(Node)
-    else
-      Result := nil;
-
-  if Assigned(Result) and not (vsVisible in Result.States) then
-    Result := GetPreviousVisibleSiblingNoInit(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetLastVisibleNoInit(Node: PVirtualNode = nil;
-  ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-
-// Returns the very last visible node in the tree while optionally considering toChildrenAbove.
-// No initialization is performed.
-
-var
-  Next: PVirtualNode;
-
-begin
-  Result := GetLastVisibleChildNoInit(Node);
-  if not ConsiderChildrenAbove or not (toChildrenAbove in FOptions.FPaintOptions) then
-    while Assigned(Result) do
-    begin
-      // Test if there is a next last visible child. If not keep the node from the last run.
-      // Otherwise use the next last visible child.
-      Next := GetLastVisibleChildNoInit(Result);
-      if Next = nil then
-        Break;
-      Result := Next;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetMaxColumnWidth(Column: TColumnIndex; UseSmartColumnWidth: Boolean = False): Integer;
-
-// This method determines the width of the largest node in the given column.
-// If UseSmartColumnWidth is True then only the visible nodes which are in view will be considered
-// Note: If UseSmartColumnWidth is False then every visible node in the tree will be initialized contradicting so
-//       the virtual paradigm.
-
-var
-  Run,
-  LastNode,
-  NextNode: PVirtualNode;
-  NodeLeft,
-  TextLeft,
-  CurrentWidth: Integer;
-  WithCheck,
-  WithImages,
-  WithStateImages: Boolean;
-  CheckOffset,
-  ImageOffset,
-  StateImageOffset: Integer;
-
-begin
-  if OperationCanceled then
-  begin
-    // Behave non-destructive.
-    Result := FHeader.FColumns[Column].Width;
-    Exit;
-  end
-  else
-    Result := 0;
-
-  BeginOperation;
-  if Assigned(FOnBeforeGetMaxColumnWidth) then
-    FOnBeforeGetMaxColumnWidth(FHeader, Column, UseSmartColumnWidth);
-
-  // Don't check the event here as descendant trees might have overriden the DoGetImageIndex method.
-  WithImages := Assigned(FImages);
-  if WithImages then
-    ImageOffset := FImages.Width + 2
-  else
-    ImageOffset := 0;
-  WithStateImages := Assigned(FStateImages);
-  if WithStateImages then
-    StateImageOffset := FStateImages.Width + 2
-  else
-    StateImageOffset := 0;
-  if Assigned(FCheckImages) then
-    CheckOffset := FCheckImages.Height + 2
-  else
-    CheckOffset := 0;
-
-  if UseSmartColumnWidth then // Get first visible node which is in view.
-    Run := GetTopNode
-  else
-    Run := GetFirstVisible(nil, True);
-
-  if Column = FHeader.MainColumn then
-  begin
-    if toFixedIndent in FOptions.FPaintOptions then
-      NodeLeft := FIndent
-    else
-    begin
-    if toShowRoot in FOptions.FPaintOptions then
-      NodeLeft := Integer((GetNodeLevel(Run) + 1) * FIndent)
-    else
-      NodeLeft := Integer(GetNodeLevel(Run) * FIndent);
-    end;
-
-    WithCheck := (toCheckSupport in FOptions.FMiscOptions) and Assigned(FCheckImages);
-  end
-  else
-  begin
-    NodeLeft := 0;
-    WithCheck := False;
-  end;
-
-  // Consider node margin at the left of the nodes.
-  Inc(NodeLeft, FMargin);
-
-  // Decide where to stop.
-  if UseSmartColumnWidth then
-    LastNode := GetNextVisible(BottomNode)
-  else
-    LastNode := nil;
-
-  while Assigned(Run) and not OperationCanceled do
-  begin
-    TextLeft := NodeLeft;
-    if WithCheck and (Run.CheckType <> ctNone) then
-      Inc(TextLeft, CheckOffset);
-    if WithImages and HasImage(Run, ikNormal, Column) then
-      Inc(TextLeft, ImageOffset);
-    if WithStateImages and HasImage(Run, ikState, Column) then
-      Inc(TextLeft, StateImageOffset);
-
-    CurrentWidth := DoGetNodeWidth(Run, Column);
-    Inc(CurrentWidth, DoGetCellContentMargin(Run, Column).X);
-
-    if Result < (TextLeft + CurrentWidth) then
-      Result := TextLeft + CurrentWidth;
-
-    // Get next visible node and update left node position if needed.
-    NextNode := GetNextVisible(Run, True);
-    if NextNode = LastNode then
-      Break;
-    if (Column = Header.MainColumn) and not (toFixedIndent in FOptions.FPaintOptions) then
-      Inc(NodeLeft, CountLevelDifference(Run, NextNode) * Integer(FIndent));
-    Run := NextNode;
-  end;
-  if toShowVertGridLines in FOptions.FPaintOptions then
-    Inc(Result);
-
-  if Assigned(FOnAfterGetMaxColumnWidth) then
-    FOnAfterGetMaxColumnWidth(FHeader, Column, Result);
-  EndOperation;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNext(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns next node in tree while optionally considering toChildrenAbove. The Result will be initialized if needed. 
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-    begin
-      // If this node has no siblings use the parent.
-      if not Assigned(Result.NextSibling) then
-      begin
-        Result := Result.Parent;
-        if Result = FRoot then
-        begin
-          Result := nil;
-        end;
-      end
-      else
-      begin
-        // There is at least one sibling so take it.
-        Result := Result.NextSibling;
-
-        // Has this node got children? Initialize them if necessary.
-        if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then
-          InitChildren(Result);
-
-        // Now take a look at the children.
-        while Assigned(Result.FirstChild) do
-        begin
-          Result := Result.FirstChild;
-          if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then
-            InitChildren(Result);
-        end;
-      end;
-    end
-    else
-    begin
-    // Has this node got children?
-    if vsHasChildren in Result.States then
-    begin
-      // Yes, there are child nodes. Initialize them if necessary.
-      if Result.ChildCount = 0 then
-        InitChildren(Result);
-    end;
-
-    // if there is no child node try siblings
-    if Assigned(Result.FirstChild) then
-      Result := Result.FirstChild
-    else
-    begin
-      repeat
-        // Is there a next sibling?
-        if Assigned(Result.NextSibling) then
-        begin
-          Result := Result.NextSibling;
-          Break;
-        end
-        else
-        begin
-          // No sibling anymore, so use the parent's next sibling.
-          if Result.Parent <> FRoot then
-            Result := Result.Parent
-          else
-          begin
-            // There are no further nodes to examine, hence there is no further visible node.
-            Result := nil;
-            Break;
-          end;
-        end;
-      until False;
-    end;
-  end;
-    end;
-
-    if Assigned(Result) and not (vsInitialized in Result.States) then
-      InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal;
-  ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := GetFirstNoInit(ConsiderChildrenAbove)
-  else
-    Result := GetNextNoInit(Node, ConsiderChildrenAbove);
-
-  while Assigned(Result) and (Result.CheckState <> State) do
-    Result := GetNextNoInit(Result, ConsiderChildrenAbove);
-
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the next node in the tree which is currently marked for a clipboard operation. Since only visible nodes can
-// be marked (or they are hidden after they have been marked) it is not necessary to initialize nodes to check for
-// child nodes. The result, however, is initialized if necessary.
-
-begin
-  if ClipboardStates * FStates <> [] then
-  begin
-    if (Node = nil) or (Node = FRoot) then
-      Result := GetFirstNoInit(ConsiderChildrenAbove)
-    else
-      Result := GetNextNoInit(Node, ConsiderChildrenAbove);
-    while Assigned(Result) and not (vsCutOrCopy in Result.States) do
-      Result := GetNextNoInit(Result, ConsiderChildrenAbove);
-    if Assigned(Result) and not (vsInitialized in Result.States) then
-      InitNode(Result);
-  end
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the next node in tree which is initialized.
-
-begin
-  Result := Node;
-  repeat
-    Result := GetNextNoInit(Result, ConsiderChildrenAbove);
-  until (Result = nil) or (vsInitialized in Result.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextLeaf(Node: PVirtualNode): PVirtualNode;
-
-// Returns the next node in the tree which has currently no children.
-// The result is initialized if necessary.
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := FRoot.FirstChild
-  else
-    Result := GetNext(Node);
-  while Assigned(Result) and (vsHasChildren in Result.States) do
-    Result := GetNext(Result);
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
-
-// Returns the next node in the tree on a specific level.
-// The result is initialized if necessary.
-
-var
-  StartNodeLevel: Cardinal;
-
-begin
-  Result := nil;
-
-  if Assigned(Node) and (Node <> FRoot) then
-  begin
-    StartNodeLevel := GetNodeLevel(Node);
-
-    if StartNodeLevel < NodeLevel then
-    begin
-      Result := GetNext(Node);
-      if Assigned(Result) and (GetNodeLevel(Result) <> NodeLevel) then
-        Result := GetNextLevel(Result, NodeLevel);
-    end
-    else if StartNodeLevel = NodeLevel then
-    begin
-      Result := Node.NextSibling;
-      if not Assigned(Result) then // i.e. start node was a last sibling
-      begin
-        Result := Node.Parent;
-        if Assigned(Result) then
-        begin
-          // go to next anchestor of the start node which has a next sibling (if exists)
-          while Assigned(Result) and not Assigned(Result.NextSibling) do
-            Result := Result.Parent;
-          if Assigned(Result) then
-            Result := GetNextLevel(Result.NextSibling, NodeLevel);
-        end;
-      end;
-    end
-    else // i.e. StartNodeLevel > NodeLevel
-      Result := GetNextLevel(Node.Parent, NodeLevel);
-  end;
-
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean): PVirtualNode;
-
-// Optimized version of GetNext performing no initialization, but optionally considering toChildrenAbove.
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-    begin
-      // If this node has no siblings use the parent.
-      if not Assigned(Result.NextSibling) then
-      begin
-        Result := Result.Parent;
-        if Result = FRoot then
-        begin
-          Result := nil;
-        end;
-      end
-      else
-      begin
-        // There is at least one sibling so take it.
-        Result := Result.NextSibling;
-
-        // Now take a look at the children.
-        while Assigned(Result.FirstChild) do
-        begin
-          Result := Result.FirstChild;
-        end;
-      end;
-    end
-    else
-    begin
-    // If there is no child node try siblings.
-    if Assigned(Result.FirstChild) then
-      Result := Result.FirstChild
-    else
-    begin
-      repeat
-        // Is there a next sibling?
-        if Assigned(Result.NextSibling) then
-        begin
-          Result := Result.NextSibling;
-          Break;
-        end
-        else
-        begin
-          // No sibling anymore, so use the parent's next sibling.
-          if Result.Parent <> FRoot then
-            Result := Result.Parent
-          else
-          begin
-            // There are no further nodes to examine, hence there is no further visible node.
-            Result := nil;
-            Break;
-          end;
-        end;
-      until False;
-    end;
-  end;
-end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the next node in the tree which is currently selected. Since children of unitialized nodes cannot be
-// in the current selection (because they simply do not exist yet) it is not necessary to initialize nodes here.
-// The result however is initialized if necessary.
-
-begin
-  if FSelectionCount > 0 then
-  begin
-    if (Node = nil) or (Node = FRoot) then
-      Result := GetFirstNoInit(ConsiderChildrenAbove)
-    else
-      Result := GetNextNoInit(Node, ConsiderChildrenAbove);
-    while Assigned(Result) and not (vsSelected in Result.States) do
-      Result := GetNextNoInit(Result, ConsiderChildrenAbove);
-    if Assigned(Result) and not (vsInitialized in Result.States) then
-      InitNode(Result);
-  end
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextSibling(Node: PVirtualNode): PVirtualNode;
-
-// Returns the next sibling of Node and initializes it if necessary.
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    Result := Result.NextSibling;
-    if Assigned(Result) and not (vsInitialized in Result.States) then
-      InitNode(Result);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-
-// Returns the next sibling of Node performing no initialization.
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    Result := Result.NextSibling;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-
-// Returns next node in tree, with regard to Node, which is visible.
-// Nodes which need an initialization (including the result) are initialized.
-// toChildrenAbove is optionally considered which is the default here.
-
-var
-  ForceSearch: Boolean;
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    // If the given node is not visible then look for a parent node which is visible, otherwise we will
-    // likely go unnecessarily through a whole bunch of invisible nodes.
-    if not FullyVisible[Result] then
-      Result := GetVisibleParent(Result);
-
-    if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-    begin
-      repeat
-        // If there a no siblings anymore, go up one level.
-        if not Assigned(Result.NextSibling) then
-        begin
-          Result := Result.Parent;
-          if Result = FRoot then
-          begin
-            Result := nil;
-            Break;
-          end;
-
-          if not (vsInitialized in Result.States) then
-            InitNode(Result);
-          if vsVisible in Result.States then
-            Break;
-        end
-        else
-        begin
-          // There is at least one sibling so take it.
-          Result := Result.NextSibling;
-          if not (vsInitialized in Result.States) then
-            InitNode(Result);
-          if not (vsVisible in Result.States) then
-            Continue;
-
-          // Now take a look at the children.
-          // As the children are initialized while toggling, we don't need to do this here.
-          while (vsExpanded in Result.States) and Assigned(Result.FirstChild) do
-          begin
-            Result := Result.FirstChild;
-            if not (vsInitialized in Result.States) then
-              InitNode(Result);
-            if not (vsVisible in Result.States) then
-              Break;
-          end;
-
-          // If we found a visible node we don't need to search any longer.
-          if vsVisible in Result.States then
-            Break;
-        end;
-      until False;
-    end
-    else
-    begin
-      // Has this node got children?
-      if [vsHasChildren, vsExpanded] * Result.States = [vsHasChildren, vsExpanded] then
-      begin
-        // Yes, there are child nodes. Initialize them if necessary.
-        if Result.ChildCount = 0 then
-          InitChildren(Result);
-      end;
-
-      // Child nodes are the first choice if possible.
-      if (vsExpanded in Result.States) and Assigned(Result.FirstChild) then
-      begin
-        Result := GetFirstChild(Result);
-        ForceSearch := False;
-      end
-      else
-        ForceSearch := True;
-
-      // If there are no children or the first child is not visible then search the sibling nodes or traverse parents.
-      if Assigned(Result) and (ForceSearch or not (vsVisible in Result.States)) then
-      begin
-        repeat
-          // Is there a next sibling?
-          if Assigned(Result.NextSibling) then
-          begin
-            Result := Result.NextSibling;
-            if not (vsInitialized in Result.States) then
-              InitNode(Result);
-            if vsVisible in Result.States then
-              Break;
-          end
-          else
-          begin
-            // No sibling anymore, so use the parent's next sibling.
-            if Result.Parent <> FRoot then
-              Result := Result.Parent
-            else
-            begin
-              // There are no further nodes to examine, hence there is no further visible node.
-              Result := nil;
-              Break;
-            end;
-          end;
-        until False;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-
-// Returns the next node in tree, with regard to Node, which is visible.
-// toChildrenAbove is optionally considered (which is the default). No initialization is done.
-
-var
-  ForceSearch: Boolean;
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-    begin
-      repeat
-        // If there a no siblings anymore, go up one level.
-        if not Assigned(Result.NextSibling) then
-        begin
-          Result := Result.Parent;
-          if Result = FRoot then
-          begin
-            Result := nil;
-            Break;
-          end;
-          if vsVisible in Result.States then
-            Break;
-        end
-        else
-        begin
-          // There is at least one sibling so take it.
-          Result := Result.NextSibling;
-          if not (vsVisible in Result.States) then
-            Continue;
-
-          // Now take a look at the children.
-          while (vsExpanded in Result.States) and Assigned(Result.FirstChild) do
-          begin
-            Result := Result.FirstChild;
-            if not (vsVisible in Result.States) then
-              Break;
-          end;
-
-          // If we found a visible node we don't need to search any longer.
-          if vsVisible in Result.States then
-            Break;
-        end;
-      until False;
-    end
-    else
-    begin
-      // If the given node is not visible then look for a parent node which is visible, otherwise we will
-      // likely go unnecessarily through a whole bunch of invisible nodes.
-      if not FullyVisible[Result] then
-        Result := GetVisibleParent(Result);
-
-      // Child nodes are the first choice if possible.
-      if (vsExpanded in Result.States) and Assigned(Result.FirstChild) then
-      begin
-        Result := Result.FirstChild;
-        ForceSearch := False;
-      end
-      else
-        ForceSearch := True;
-
-      // If there are no children or the first child is not visible then search the sibling nodes or traverse parents.
-      if ForceSearch or not (vsVisible in Result.States) then
-      begin
-        repeat
-          // Is there a next sibling?
-          if Assigned(Result.NextSibling) then
-          begin
-            Result := Result.NextSibling;
-            if vsVisible in Result.States then
-              Break;
-          end
-          else
-          begin
-            // No sibling anymore, so use the parent's next sibling.
-            if Result.Parent <> FRoot then
-              Result := Result.Parent
-            else
-            begin
-              // There are no further nodes to examine, hence there is no further visible node.
-              Result := nil;
-              Break;
-            end;
-          end;
-        until False;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextVisibleSibling(Node: PVirtualNode): PVirtualNode;
-
-// Returns the next visible sibling after Node. Initialization is done implicitly.
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.');
-
-  Result := Node;
-  repeat
-    Result := GetNextSibling(Result);
-  until not Assigned(Result) or (vsVisible in Result.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNextVisibleSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-
-// Returns the next visible sibling after Node.
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.');
-
-  Result := Node;
-  repeat
-    Result := Result.NextSibling;
-  until not Assigned(Result) or (vsVisible in Result.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNodeAt(X, Y: Integer): PVirtualNode;
-
-// Overloaded variant of GetNodeAt to easy life of application developers which do not need to have the exact
-// top position returned and always use client coordinates.
-
-var
-  Dummy: Integer;
-
-begin
-  Result := GetNodeAt(X, Y, True, Dummy);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNodeAt(X, Y: Integer; Relative: Boolean; var NodeTop: Integer): PVirtualNode;
-var
-  OffsetByHeader: Boolean;
-begin
-  //lclheader
-  OffsetByHeader := Relative and (hoVisible in FHeader.Options);
-  if OffsetByHeader then
-    Dec(Y, FHeader.Height);
-  Result := InternalGetNodeAt(X, Y, Relative, NodeTop);
-  //lclheader
-  if OffsetByHeader then
-    Inc(NodeTop, FHeader.Height);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNodeData(Node: PVirtualNode): Pointer;
-
-// Returns the address of the user defined data area in the node.
-
-begin
-  Assert(FNodeDataSize > 0, 'NodeDataSize not initialized.');
-
-  if (FNodeDataSize <= 0) or (Node = nil) or (Node = FRoot) then
-    Result := nil
-  else
-    Result := PByte(@Node.Data) + FTotalInternalDataSize;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetNodeLevel(Node: PVirtualNode): Cardinal;
-
-// returns the level of the given node
-
-var
-  Run: PVirtualNode;
-
-begin
-  Result := 0;
-  if Assigned(Node) and (Node <> FRoot) then
-  begin
-    Run := Node.Parent;
-    while Run <> FRoot do
-    begin
-      Run := Run.Parent;
-      Inc(Result);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPrevious(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns previous node in tree. If ConsiderChildrenAbove is True the function considers
-// whether toChildrenAbove is currently set, otherwise the result will always be the previous
-// node in top-down order regardless of the current PaintOptions.
-// The Result will be initialized if needed.
-
-var
-  Run: PVirtualNode;
-
-begin
-    Result := Node;
-    if Assigned(Result) then
-    begin
-      Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-    begin
-      // Has this node got children? Initialize them if necessary.
-      if (vsHasChildren in Result.States) and (Result.ChildCount = 0) then
-        InitChildren(Result);
-
-        // If there is a last child, take it; if not try the previous sibling.
-        if Assigned(Result.LastChild) then
-          Result := Result.LastChild
-        else if Assigned(Result.PrevSibling) then
-           Result := Result.PrevSibling
-        else
-        begin
-          // If neither a last child nor a previous sibling exist, go the tree upwards and
-          // look, wether one of the parent nodes have a previous sibling. If not the result
-          // will ne nil.
-          repeat
-            Result := Result.Parent;
-            Run    := nil;
-            if Result <> FRoot then
-              Run := Result.PrevSibling
-            else
-              Result := nil;
-          until Assigned(Run) or (Result = nil);
-
-          if Assigned(Run) then
-            Result := Run;
-        end;
-    end
-    else
-    begin
-      // Is there a previous sibling?
-      if Assigned(Node.PrevSibling) then
-      begin
-        // Go down and find the last child node.
-        Result := GetLast(Node.PrevSibling);
-        if Result = nil then
-          Result := Node.PrevSibling;
-      end
-      else
-        // no previous sibling so the parent of the node is the previous visible node
-        if Node.Parent <> FRoot then
-          Result := Node.Parent
-        else
-          Result := nil;
-    end;
-  end;
-
-      if Assigned(Result) and not (vsInitialized in Result.States) then
-        InitNode(Result);
-    end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousChecked(Node: PVirtualNode; State: TCheckState = csCheckedNormal;
-  ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := GetLastNoInit(nil, ConsiderChildrenAbove)
-  else
-    Result := GetPreviousNoInit(Node, ConsiderChildrenAbove);
-
-  while Assigned(Result) and (Result.CheckState <> State) do
-    Result := GetPreviousNoInit(Result, ConsiderChildrenAbove);
-
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousCutCopy(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the previous node in the tree which is currently marked for a clipboard operation. Since only visible nodes can
-// be marked (or they are hidden after they have been marked) it is not necessary to initialize nodes to check for
-// child nodes. The result, however, is initialized if necessary.
-
-begin
-  if ClipboardStates * FStates <> [] then
-  begin
-    if (Node = nil) or (Node = FRoot) then
-      Result := GetLastNoInit(nil, ConsiderChildrenAbove)
-    else
-      Result := GetPreviousNoInit(Node, ConsiderChildrenAbove);
-    while Assigned(Result) and not (vsCutOrCopy in Result.States) do
-      Result := GetPreviousNoInit(Result, ConsiderChildrenAbove);
-    if Assigned(Result) and not (vsInitialized in Result.States) then
-      InitNode(Result);
-  end
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousInitialized(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the previous node in tree which is initialized.
-
-begin
-  Result := Node;
-  repeat
-    Result := GetPreviousNoInit(Result, ConsiderChildrenAbove);
-  until (Result = nil) or (vsInitialized in Result.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousLeaf(Node: PVirtualNode): PVirtualNode;
-
-// Returns the previous node in the tree which has currently no children.
-// The result is initialized if necessary.
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := FRoot.LastChild
-  else
-    Result := GetPrevious(Node);
-  while Assigned(Result) and (vsHasChildren in Result.States) do
-    Result := GetPrevious(Result);
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousLevel(Node: PVirtualNode; NodeLevel: Cardinal): PVirtualNode;
-
-// Returns the previous node in the tree on a specific level.
-// The result is initialized if necessary.
-
-var
-  StartNodeLevel: Cardinal;
-  Run: PVirtualNode;
-
-begin
-  Result := nil;
-
-  if Assigned(Node) and (Node <> FRoot) then
-  begin
-    StartNodeLevel := GetNodeLevel(Node);
-
-    if StartNodeLevel < NodeLevel then
-    begin
-      Result := Node.PrevSibling;
-      if Assigned(Result) then
-      begin
-        // go to last descendant of previous sibling with desired node level (if exists)
-        Run := Result;
-        while Assigned(Run) and (GetNodeLevel(Run) < NodeLevel) do
-        begin
-          Result := Run;
-          Run := GetLastChild(Run);
-        end;
-        if Assigned(Run) and (GetNodeLevel(Run) = NodeLevel) then
-          Result := Run
-        else
-        begin
-          if Assigned(Result.PrevSibling) then
-            Result := GetPreviousLevel(Result, NodeLevel)
-          else if Assigned(Result) and (Result.Parent <> FRoot) then
-            Result := GetPreviousLevel(Result.Parent, NodeLevel)
-          else
-            Result := nil;
-        end;
-      end
-      else
-        Result := GetPreviousLevel(Node.Parent, NodeLevel);
-    end
-    else if StartNodeLevel = NodeLevel then
-    begin
-      Result := Node.PrevSibling;
-      if not Assigned(Result) then // i.e. start node was a first sibling
-      begin
-        Result := Node.Parent;
-        if Assigned(Result) then
-          Result := GetPreviousLevel(Result, NodeLevel);
-      end;
-    end
-    else // i.e. StartNodeLevel > NodeLevel
-      Result := GetPreviousLevel(Node.Parent, NodeLevel);
-  end;
-
-  if Assigned(Result) and not (vsInitialized in Result.States) then
-    InitNode(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns previous node in tree, optionally considering toChildrenAbove. No initialization is performed.
-
-var
-  Run: PVirtualNode;
-
-begin
-    Result := Node;
-    if Assigned(Result) then
-    begin
-      Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-    begin
-      // If there is a last child, take it; if not try the previous sibling.
-      if Assigned(Result.LastChild) then
-        Result := Result.LastChild
-      else if Assigned(Result.PrevSibling) then
-         Result := Result.PrevSibling
-      else
-      begin
-        // If neither a last child nor a previous sibling exist, go the tree upwards and
-        // look, wether one of the parent nodes have a previous sibling. If not the result
-        // will ne nil.
-        repeat
-          Result := Result.Parent;
-          Run    := nil;
-          if Result <> FRoot then
-            Run := Result.PrevSibling
-          else
-            Result := nil;
-        until Assigned(Run) or (Result = nil);
-
-        if Assigned(Run) then
-          Result := Run;
-      end;
-  end
-  else
-    begin
-      // Is there a previous sibling?
-      if Assigned(Node.PrevSibling) then
-      begin
-        // Go down and find the last child node.
-        Result := GetLastNoInit(Node.PrevSibling);
-        if Result = nil then
-          Result := Node.PrevSibling;
-      end
-      else
-        // No previous sibling so the parent of the node is the previous node.
-        if Node.Parent <> FRoot then
-          Result := Node.Parent
-        else
-          Result := nil
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-
-// Returns the previous node in the tree which is currently selected. Since children of unitialized nodes cannot be
-// in the current selection (because they simply do not exist yet) it is not necessary to initialize nodes here.
-// The result however is initialized if necessary.
-
-begin
-  if FSelectionCount > 0 then
-  begin
-    if (Node = nil) or (Node = FRoot) then
-      Result := FRoot.LastChild
-    else
-      Result := GetPreviousNoInit(Node, ConsiderChildrenAbove);
-    while Assigned(Result) and not (vsSelected in Result.States) do
-      Result := GetPreviousNoInit(Result, ConsiderChildrenAbove);
-    if Assigned(Result) and not (vsInitialized in Result.States) then
-      InitNode(Result);
-  end
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousSibling(Node: PVirtualNode): PVirtualNode;
-
-// Get next sibling of Node, initialize it if necessary.
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    Result := Result.PrevSibling;
-    if Assigned(Result) and not (vsInitialized in Result.States) then
-      InitNode(Result);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-
-// Get next sibling of Node, performes no initialization.
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    Result := Result.PrevSibling;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-
-// Returns the previous node in tree, with regard to Node, which is visible.
-// Nodes which need an initialization (including the result) are initialized.
-// toChildrenAbove is optionally considered which is the default here.
-
-var
-  Marker: PVirtualNode;
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    repeat
-      // If the given node is not visible then look for a parent node which is visible and use its last visible
-      // child or the parent node (if there is no visible child) as result.
-      if not FullyVisible[Result] then
-      begin
-        Result := GetVisibleParent(Result);
-        if Result = FRoot then
-          Result := nil;
-        Marker := GetLastVisible(Result, True);
-        if Assigned(Marker) then
-          Result := Marker;
-      end
-      else
-      begin
-        if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-        begin
-          repeat
-            if Assigned(Result.LastChild) and (vsExpanded in Result.States) then
-            begin
-              Result := Result.LastChild;
-              if not (vsInitialized in Result.States) then
-                InitNode(Result);
-
-              if vsVisible in Result.States then
-                Break;
-            end
-            else if Assigned(Result.PrevSibling) then
-            begin
-              if not (vsInitialized in Result.PrevSibling.States) then
-                InitNode(Result.PrevSibling);
-
-              if vsVisible in Result.PrevSibling.States then
-              begin
-                Result := Result.PrevSibling;
-                Break;
-              end;
-            end
-            else
-            begin
-              Marker := nil;
-              repeat
-                Result := Result.Parent;
-                if Result <> FRoot then
-                  Marker := GetPreviousVisibleSibling(Result)
-                else
-                  Result := nil;
-              until Assigned(Marker) or (Result = nil);
-              if Assigned(Marker) then
-                Result := Marker;
-
-              Break;
-            end;
-          until False;
-        end
-        else
-        begin
-          repeat
-            // Is there a previous sibling node?
-            if Assigned(Result.PrevSibling) then
-            begin
-              Result := Result.PrevSibling;
-              // Initialize the new node and check its visibility.
-              if not (vsInitialized in Result.States) then
-                InitNode(Result);
-              if vsVisible in Result.States then
-              begin
-                // If there are visible child nodes then use the last one.
-                Marker := GetLastVisible(Result, True);
-                if Assigned(Marker) then
-                  Result := Marker;
-                Break;
-              end;
-            end
-            else
-            begin
-              // No previous sibling there so the parent node is the nearest previous node.
-              Result := Result.Parent;
-              if Result = FRoot then
-                Result := nil;
-              Break;
-            end;
-          until False;
-        end;
-
-        if Assigned(Result) and not (vsInitialized in Result.States) then
-          InitNode(Result);
-      end;
-    until not Assigned(Result) or (vsVisible in Result.States);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousVisibleNoInit(Node: PVirtualNode;
-  ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-
-// Returns the previous node in tree, with regard to Node, which is visible.
-// toChildrenAbove is optionally considered which is the default here.
-
-var
-  Marker: PVirtualNode;
-
-begin
-  Result := Node;
-  if Assigned(Result) then
-  begin
-    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-
-    repeat
-      // If the given node is not visible then look for a parent node which is visible and use its last visible
-      // child or the parent node (if there is no visible child) as result.
-      if not FullyVisible[Result] then
-      begin
-        Result := GetVisibleParent(Result);
-        if Result = FRoot then
-          Result := nil;
-        Marker := GetLastVisibleNoInit(Result, True);
-        if Assigned(Marker) then
-          Result := Marker;
-      end
-      else
-      begin
-        if ConsiderChildrenAbove and (toChildrenAbove in FOptions.FPaintOptions) then
-        begin
-          repeat
-            // Is the current node expanded and has children?
-            if (vsExpanded in Result.States) and Assigned(Result.LastChild) then
-            begin
-              Result := Result.LastChild;
-              if vsVisible in Result.States then
-                Break;
-            end
-            else if Assigned(Result.PrevSibling) then
-            begin
-              // No children anymore, so take the previous sibling.
-              if vsVisible in Result.PrevSibling.States then
-              begin
-                Result := Result.PrevSibling;
-                Break;
-              end;
-            end
-            else
-            begin
-              // No children and no previous siblings, so walk up the tree and look wether
-              // a parent has a previous visible sibling. If that is the case take it,
-              // otherwise there is no previous visible node.
-              Marker := nil;
-              repeat
-                Result := Result.Parent;
-                if Result <> FRoot then
-                  Marker := GetPreviousVisibleSiblingNoInit(Result)
-                else
-                  Result := nil;
-              until Assigned(Marker) or (Result = nil);
-              if Assigned(Marker) then
-                Result := Marker;
-              Break;
-            end;
-          until False;
-        end
-        else
-        begin
-          repeat
-            // Is there a previous sibling node?
-            if Assigned(Result.PrevSibling) then
-            begin
-              Result := Result.PrevSibling;
-              if vsVisible in Result.States then
-              begin
-                // If there are visible child nodes then use the last one.
-                Marker := GetLastVisibleNoInit(Result, True);
-                if Assigned(Marker) then
-                  Result := Marker;
-                Break;
-              end;
-            end
-            else
-            begin
-              // No previous sibling there so the parent node is the nearest previous node.
-              Result := Result.Parent;
-              if Result = FRoot then
-                Result := nil;
-              Break;
-            end;
-          until False;
-        end;
-      end;
-    until not Assigned(Result) or (vsVisible in Result.States);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousVisibleSibling(Node: PVirtualNode): PVirtualNode;
-
-// Returns the previous visible sibling before Node. Initialization is done implicitly.
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.');
-
-  Result := Node;
-  repeat
-    Result := GetPreviousSibling(Result);
-  until not Assigned(Result) or (vsVisible in Result.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetPreviousVisibleSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-
-// Returns the previous visible sibling before Node.
-
-begin
-  Assert(Assigned(Node) and (Node <> FRoot), 'Invalid parameter.');
-
-  Result := Node;
-  repeat
-    Result := Result.PrevSibling;
-  until not Assigned(Result) or (vsVisible in Result.States);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetSortedCutCopySet(Resolve: Boolean): TNodeArray;
-
-// Same as GetSortedSelection but with nodes marked as being part in the current cut/copy set (e.g. for clipboard).
-
-var
-  Run: PVirtualNode;
-  Counter: Cardinal;
-
-  //--------------- local function --------------------------------------------
-
-  procedure IncludeThisNode(Node: PVirtualNode);
-
-  // adds the given node to the result
-
-  var
-    Len: Cardinal;
-
-  begin
-    Len := Length(Result);
-    if Counter = Len then
-    begin
-      if Len < 100 then
-        Len := 100
-      else
-        Len := Len + Len div 10;
-      SetLength(Result, Len);
-    end;
-    Result[Counter] := Node;
-    Inc(Counter);
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-begin
-  Run := FRoot.FirstChild;
-  Counter := 0;
-  if Resolve then
-  begin
-    // Resolving is actually easy: just find the first cutted node in logical order
-    // and then never go deeper in level than this node as long as there's a sibling node.
-    // Restart the search for a cutted node (at any level) if there are no further siblings.
-    while Assigned(Run) do
-    begin
-      if vsCutOrCopy in Run.States then
-      begin
-        IncludeThisNode(Run);
-        if Assigned(Run.NextSibling) then
-          Run := Run.NextSibling
-        else
-        begin
-          // If there are no further siblings then go up one or more levels until a node is
-          // found or all nodes have been processed. Although we consider here only initialized
-          // nodes we don't need to make any special checks as only initialized nodes can also be selected.
-          repeat
-            Run := Run.Parent;
-          until (Run = FRoot) or Assigned(Run.NextSibling);
-          if Run = FRoot then
-            Break
-          else
-            Run := Run.NextSibling;
-        end;
-      end
-      else
-        Run := GetNextNoInit(Run);
-    end;
-  end
-  else
-    while Assigned(Run) do
-    begin
-      if vsCutOrCopy in Run.States then
-        IncludeThisNode(Run);
-      Run := GetNextNoInit(Run);
-    end;
-
-  // set the resulting array to its real length
-  SetLength(Result, Counter);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetSortedSelection(Resolve: Boolean): TNodeArray;
-
-// Returns a list of selected nodes sorted in logical order, that is, as they appear in the tree.
-// If Resolve is True then nodes which are children of other selected nodes are not put into the new array.
-// This feature is in particuar important when doing drag'n drop as in this case all selected node plus their children
-// need to be considered. A selected node which is child (grand child etc.) of another selected node is then
-// automatically included and doesn't need to be explicitely mentioned in the returned selection array.
-//
-// Note: The caller is responsible for freeing the array. Allocation is done here. Usually, though, freeing the array
-//       doesn't need additional attention as it is automatically freed by Delphi when it gets out of scope.
-
-var
-  Run: PVirtualNode;
-  Counter: Cardinal;
-
-begin
-  SetLength(Result, FSelectionCount);
-  if FSelectionCount > 0 then
-  begin
-    Run := FRoot.FirstChild;
-    Counter := 0;
-    if Resolve then
-    begin
-      // Resolving is actually easy: just find the first selected node in logical order
-      // and then never go deeper in level than this node as long as there's a sibling node.
-      // Restart the search for a selected node (at any level) if there are no further siblings.
-      while Assigned(Run) do
-      begin
-        if vsSelected in Run.States then
-        begin
-          Result[Counter] := Run;
-          Inc(Counter);
-          if Assigned(Run.NextSibling) then
-            Run := Run.NextSibling
-          else
-          begin
-            // If there are no further siblings then go up one or more levels until a node is
-            // found or all nodes have been processed. Although we consider here only initialized
-            // nodes we don't need to make any special checks as only initialized nodes can also be selected.
-            repeat
-              Run := Run.Parent;
-            until (Run = FRoot) or Assigned(Run.NextSibling);
-            if Run = FRoot then
-              Break
-            else
-              Run := Run.NextSibling;
-          end;
-        end
-        else
-          Run := GetNextNoInit(Run);
-      end;
-    end
-    else
-      while Assigned(Run) do
-      begin
-        if vsSelected in Run.States then
-        begin
-          Result[Counter] := Run;
-          Inc(Counter);
-        end;
-        Run := GetNextNoInit(Run);
-      end;
-
-    // Since we may have skipped some nodes the result array is likely to be smaller than the
-    // selection array, hence shorten the result to true length.
-    if Integer(Counter) < Length(Result) then
-      SetLength(Result, Counter);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect;
-  out Text: String);
-
-// Generic base method for editors, hint windows etc. to get some info about a node.
-
-begin
-  R := Rect(0, 0, 0, 0);
-  Text := '';
-  AFont.Assign(Font);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetTreeRect: TRect;
-
-// Returns the true size of the tree in pixels. This size is at least ClientHeight x ClientWidth and depends on
-// the expand state, header size etc.
-// Note: if no columns are used then the width of the tree is determined by the largest node which is currently in the
-//       client area. This might however not be the largest node in the entire tree.
-
-begin
-  Result := Rect(0, 0, Max(FRangeX, ClientWidth), Max(FRangeY, ClientHeight));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.GetVisibleParent(Node: PVirtualNode): PVirtualNode;
-
-// Returns the first (nearest) parent node of Node which is visible.
-// This method is one of the seldom cases where the hidden root node could be returned.
-
-begin
-  Assert(Assigned(Node), 'Node must not be nil.');
-  Assert(Node <> FRoot, 'Node must not be the hidden root node.');
-
-  Result := Node.Parent;
-  while (Result <> FRoot) and not FullyVisible[Result] do
-    Result := Result.Parent;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.HasAsParent(Node, PotentialParent: PVirtualNode): Boolean;
-
-// Determines whether Node has got PotentialParent as one of its parents.
-
-var
-  Run: PVirtualNode;
-
-begin
-  Result := Assigned(Node) and Assigned(PotentialParent) and (Node <> PotentialParent);
-  if Result then
-  begin
-    Run := Node;
-    while (Run <> FRoot) and (Run <> PotentialParent) do
-      Run := Run.Parent;
-    Result := Run = PotentialParent;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.InsertNode(Node: PVirtualNode; Mode: TVTNodeAttachMode; UserData: Pointer = nil): PVirtualNode;
-
-// Adds a new node relative to Node. The final position is determined by Mode.
-// UserData can be used to set the first 4 bytes of the user data area to an initial value which can be used
-// in OnInitNode and will also cause to trigger the OnFreeNode event (if <> nil) even if the node is not yet
-// "officially" initialized.
-// InsertNode is a compatibility method and will implicitly validate the given node if the new node
-// is to be added as child node. This is however against the virtual paradigm and hence I dissuade from its usage.
-
-var
-  NodeData: ^Pointer;
-
-begin
-  if Mode <> amNoWhere then
-  begin
-    CancelEditNode;
-
-    if Node = nil then
-      Node := FRoot;
-    // we need a new node...
-    Result := MakeNewNode;
-    // avoid erronous attach modes
-    if Node = FRoot then
-    begin
-      case Mode of
-        amInsertBefore:
-          Mode := amAddChildFirst;
-        amInsertAfter:
-          Mode := amAddChildLast;
-      end;
-    end;
-
-    // Validate given node in case the new node becomes its child.
-    if (Mode in [amAddChildFirst, amAddChildLast]) and not (vsInitialized in Node.States) then
-      InitNode(Node);
-    InternalConnectNode(Result, Node, Self, Mode);
-
-    // Check if there is initial user data and there is also enough user data space allocated.
-    if Assigned(UserData) then
-      if FNodeDataSize >= 4 then
-      begin
-        NodeData := Pointer(PByte(@Result.Data) + FTotalInternalDataSize);
-        NodeData^ := UserData;
-        Include(Result.States, vsInitialUserData);
-      end
-      else
-        ShowError(SCannotSetUserData, hcTFCannotSetUserData);
-
-    if FUpdateCount = 0 then
-    begin
-      // If auto sort is enabled then sort the node or its parent (depending on the insert mode).
-      if (toAutoSort in FOptions.FAutoOptions) and (FHeader.FSortColumn > InvalidColumn) then
-        case Mode of
-          amInsertBefore,
-          amInsertAfter:
-            // Here no initialization is necessary because *if* a node has already got children then it
-            // must also be initialized.
-            // Note: Node can never be FRoot at this point.
-            Sort(Node.Parent, FHeader.FSortColumn, FHeader.FSortDirection, True);
-          amAddChildFirst,
-          amAddChildLast:
-            Sort(Node, FHeader.FSortColumn, FHeader.FSortDirection, True);
-        end;
-
-      UpdateScrollbars(True);
-      if Mode = amInsertBefore then
-        InvalidateToBottom(Result)
-      else
-        InvalidateToBottom(Node);
-    end;
-    StructureChange(Result, crNodeAdded);
-  end
-  else
-    Result := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InvalidateChildren(Node: PVirtualNode; Recursive: Boolean);
-
-// Invalidates Node and its immediate children.
-// If Recursive is True then all grandchildren are invalidated as well.
-// The node itself is initialized if necessary and its child nodes are created (and initialized too if
-// Recursive is True).
-
-var
-  Run: PVirtualNode;
-
-begin
-  if Assigned(Node) then
-  begin
-    if not (vsInitialized in Node.States) then
-      InitNode(Node);
-    InvalidateNode(Node);
-    if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then
-      InitChildren(Node);
-    Run := Node.FirstChild;
-  end
-  else
-    Run := FRoot.FirstChild;
-
-  while Assigned(Run) do
-  begin
-    InvalidateNode(Run);
-    if Recursive then
-      InvalidateChildren(Run, True);
-    Run := Run.NextSibling;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InvalidateColumn(Column: TColumnIndex);
-
-// Invalidates the client area part of a column.
-
-var
-  R: TRect;
-
-begin
-  if (FUpdateCount = 0) and HandleAllocated and FHeader.FColumns.IsValidColumn(Column) then
-  begin
-    R := ClientRect;
-    //lclheader
-    if hoVisible in FHeader.FOptions then
-      OffsetRect(R, 0, FHeader.Height);
-    FHeader.Columns.GetColumnBounds(Column, R.Left, R.Right);
-    InvalidateRect(Handle, @R, False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.InvalidateNode(Node: PVirtualNode): TRect;
-
-// Initiates repaint of the given node and returns the just invalidated rectangle.
-
-begin
-  if (FUpdateCount = 0) and HandleAllocated then
-  begin
-    Result := GetDisplayRect(Node, NoColumn, False);
-    InvalidateRect(Handle, @Result, False);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InvalidateToBottom(Node: PVirtualNode);
-
-// Initiates repaint of client area starting at given node. If this node is not visible or not yet initialized
-// then nothing happens.
-
-var
-  R: TRect;
-
-begin
-  if FUpdateCount = 0 then
-  begin
-    if (Node = nil) or (Node = FRoot) then
-      Invalidate
-    else
-      if (vsInitialized in Node.States) and (vsVisible in Node.States) then
-      begin
-        R := GetDisplayRect(Node, -1, False);
-        if R.Top < ClientHeight then
-        begin
-          if (toChildrenAbove in FOptions.FPaintOptions) and (vsExpanded in Node.States) then
-            Dec(R.Top, Node.TotalHeight + NodeHeight[Node]);
-          R.Bottom := ClientHeight;
-          //lclheader
-          if hoVisible in FHeader.FOptions then
-            Inc(R.Bottom, FHeader.Height);
-          InvalidateRect(Handle, @R, False);
-        end;
-      end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.InvertSelection(VisibleOnly: Boolean);
-
-// Inverts the current selection (so nodes which are selected become unselected and vice versa).
-// If VisibleOnly is True then only visible nodes are considered.
-
-var
-  Run: PVirtualNode;
-  NewSize: Integer;
-  NextFunction: TGetNextNodeProc;
-  TriggerChange: Boolean;
-
-begin
-  if not FSelectionLocked and (toMultiSelect in FOptions.FSelectionOptions) then
-  begin
-    Run := FRoot.FirstChild;
-    ClearTempCache;
-    if VisibleOnly then
-      NextFunction := GetNextVisibleNoInit
-    else
-      NextFunction := GetNextNoInit;
-    while Assigned(Run) do
-    begin
-      if vsSelected in Run.States then
-        InternalRemoveFromSelection(Run)
-      else
-        InternalCacheNode(Run);
-      Run := NextFunction(Run);
-    end;
-
-    // do some housekeeping
-    // Need to trigger the OnChange event from here if nodes were only deleted but not added.
-    TriggerChange := False;
-    NewSize := PackArray(FSelection, FSelectionCount);
-    if NewSize > -1 then
-    begin
-      FSelectionCount := NewSize;
-      SetLength(FSelection, FSelectionCount);
-      TriggerChange := True;
-    end;
-    if FTempNodeCount > 0 then
-    begin
-      AddToSelection(FTempNodeCache, FTempNodeCount);
-      ClearTempCache;
-      TriggerChange := False;
-    end;
-    Invalidate;
-    if TriggerChange then
-      Change(nil);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.IsEditing: Boolean;
-
-begin
-  Result := tsEditing in FStates;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.IsMouseSelecting: Boolean;
-
-begin
-  Result := (tsDrawSelPending in FStates) or (tsDrawSelecting in FStates);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.IterateSubtree(Node: PVirtualNode; Callback: TVTGetNodeProc; Data: Pointer;
-  Filter: TVirtualNodeStates = []; DoInit: Boolean = False; ChildNodesOnly: Boolean = False): PVirtualNode;
-
-// Iterates through the all children and grandchildren etc. of Node (or the entire tree if Node = nil)
-// and calls for each node the provided callback method (which must not be empty).
-// Filter determines which nodes to consider (an empty set denotes all nodes).
-// If DoInit is True then nodes which aren't initialized yet will be initialized.
-// Note: During execution of the callback the application can set Abort to True. In this case the iteration is stopped
-//       and the last accessed node (the one on which the callback set Abort to True) is returned to the caller.
-//       Otherwise (no abort) nil is returned.
-
-var
-  Stop: PVirtualNode;
-  Abort: Boolean;
-  GetNextNode: TGetNextNodeProc;
-  WasIterating: Boolean;
-
-begin
-  Assert(Node <> FRoot, 'Node must not be the hidden root node.');
-
-  WasIterating := tsIterating in FStates;
-  DoStateChange([tsIterating]);
-  try
-    // prepare function to be used when advancing
-    if DoInit then
-      GetNextNode := GetNext
-    else
-      GetNextNode := GetNextNoInit;
-
-    Abort := False;
-    if Node = nil then
-      Stop := nil
-    else
-    begin
-      if not (vsInitialized in Node.States) and DoInit then
-        InitNode(Node);
-
-      // The stopper does not need to be initialized since it is not taken into the enumeration.
-      Stop := Node.NextSibling;
-      if Stop = nil then
-      begin
-        Stop := Node;
-        repeat
-          Stop := Stop.Parent;
-        until (Stop = FRoot) or Assigned(Stop.NextSibling);
-        if Stop = FRoot then
-          Stop := nil
-        else
-          Stop := Stop.NextSibling;
-      end;
-    end;
-
-    // Use first node if we start with the root.
-    if Node = nil then
-      Node := GetFirstNoInit;
-
-    if Assigned(Node) then
-    begin
-      if not (vsInitialized in Node.States) and DoInit then
-        InitNode(Node);
-
-      // Skip given node if only the child nodes are requested.
-      if ChildNodesOnly then
-      begin
-        if Node.ChildCount = 0 then
-          Node := nil
-        else
-          Node := GetNextNode(Node);
-      end;
-
-      if Filter = [] then
-      begin
-        // unfiltered loop
-        while Assigned(Node) and (Node <> Stop) do
-        begin
-          Callback(Self, Node, Data, Abort);
-          if Abort then
-            Break;
-          Node := GetNextNode(Node);
-        end;
-      end
-      else
-      begin
-        // filtered loop
-        while Assigned(Node) and (Node <> Stop) do
-        begin
-          if Node.States * Filter = Filter then
-            Callback(Self, Node, Data, Abort);
-          if Abort then
-            Break;
-          Node := GetNextNode(Node)
-        end;
-      end;
-    end;
-
-    if Abort then
-      Result := Node
-    else
-      Result := nil;
-  finally
-    if not WasIterating then
-      DoStateChange([], [tsIterating]);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.LoadFromFile(const FileName: TFileName);
-
-var
-  FileStream: TFileStream;
-
-begin
-  FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
-  try
-    LoadFromStream(FileStream);
-  finally
-    FileStream.Free;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.LoadFromStream(Stream: TStream);
-
-// Clears the current content of the tree and loads a new structure from the given stream.
-
-var
-  ThisID: TMagicID;
-  Version,
-  Count: Cardinal;
-  Node: PVirtualNode;
-
-begin
-  if not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    Clear;
-    // Check first whether this is a stream we can read.
-    if Stream.Read(ThisID, SizeOf(TMagicID)) < SizeOf(TMagicID) then
-      ShowError(SStreamTooSmall, hcTFStreamTooSmall);
-
-    if (ThisID[0] = MagicID[0]) and
-       (ThisID[1] = MagicID[1]) and
-       (ThisID[2] = MagicID[2]) and
-       (ThisID[5] = MagicID[5]) then
-    begin
-      Version := Word(ThisID[3]);
-      if Version <= VTTreeStreamVersion then
-      begin
-        BeginUpdate;
-        try
-          // LCL port started with tree stream version 2 so no need to do the check here
-          Stream.ReadBuffer(Count, SizeOf(Count));
-
-          while (Stream.Position < Stream.Size) and (Count > 0) do
-          begin
-            Dec(Count);
-            Node := MakeNewNode;
-            InternalConnectNode(Node, FRoot, Self, amAddChildLast);
-            InternalAddFromStream(Stream, Version, Node);
-          end;
-          DoNodeCopied(nil);
-        finally
-          EndUpdate;
-        end;
-      end
-      else
-        ShowError(SWrongStreamVersion, hcTFWrongStreamVersion);
-    end
-    else
-      ShowError(SWrongStreamFormat, hcTFWrongStreamFormat);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.MeasureItemHeight(const Canvas: TCanvas; Node: PVirtualNode);
-
-// If the height of the given node has not yet been measured then do it now.
-
-var
-  NewNodeHeight: Integer;
-
-begin
-  if not (vsHeightMeasured in Node.States) then
-  begin
-    Include(Node.States, vsHeightMeasured);
-    NewNodeHeight := Node.NodeHeight;
-    DoMeasureItem(Canvas, Node, NewNodeHeight);
-    if NewNodeHeight <> Node.NodeHeight then
-      SetNodeHeight(Node, NewNodeHeight);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.MoveTo(Node: PVirtualNode; Tree: TBaseVirtualTree; Mode: TVTNodeAttachMode;
-  ChildrenOnly: Boolean);
-
-// A simplified method to allow to move nodes to the root of another tree.
-
-begin
-  MoveTo(Node, Tree.FRoot, Mode, ChildrenOnly);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.MoveTo(Source, Target: PVirtualNode; Mode: TVTNodeAttachMode; ChildrenOnly: Boolean);
-
-// Moves the given node (and all its children) to Target. Source must belong to the tree instance which calls this
-// MoveTo method. Mode determines how to connect Source to Target.
-// This method might involve a change of the tree if Target belongs to a different tree than Source.
-
-var
-  TargetTree: TBaseVirtualTree;
-  Allowed: Boolean;
-  NewNode: PVirtualNode;
-  Stream: TMemoryStream;
-
-begin
-  Assert(TreeFromNode(Source) = Self, 'The source tree must contain the source node.');
-
-  // When moving nodes then source and target must not be the same node unless only the source's children are
-  // moved and they are inserted before or after the node itself.
-  Allowed := (Source <> Target) or ((Mode in [amInsertBefore, amInsertAfter]) and ChildrenOnly);
-
-  if Allowed and (Mode <> amNoWhere) and Assigned(Source) and (Source <> FRoot) and
-    not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    // Assume that an empty destination means the root in this (the source) tree.
-    if Target = nil then
-    begin
-      TargetTree := Self;
-      Target := FRoot;
-      Mode := amAddChildFirst;
-    end
-    else
-      TargetTree := TreeFromNode(Target);
-
-    if Target = TargetTree.FRoot then
-    begin
-      case Mode of
-        amInsertBefore:
-          Mode := amAddChildFirst;
-        amInsertAfter:
-          Mode := amAddChildLast;
-      end;
-    end;
-
-    // Make sure the target node is initialized.
-    if not (vsInitialized in Target.States) then
-      InitNode(Target)
-    else
-      if (vsHasChildren in Target.States) and (Target.ChildCount = 0) then
-        InitChildren(Target);
-
-    if TargetTree = Self then
-    begin
-      // Simple case: move node(s) within the same tree.
-      if Target = FRoot then
-        Allowed := DoNodeMoving(Source, nil)
-      else
-        Allowed := DoNodeMoving(Source, Target);
-      if Allowed then
-      begin
-        // Check first that Source is not added as new child to a target node which
-        // is already a child of Source.
-        // Consider the case Source and Target are the same node, but only child nodes are moved.
-        if (Source <> Target) and HasAsParent(Target, Source) then
-            ShowError(SWrongMoveError, hcTFWrongMoveError);
-
-        if not ChildrenOnly then
-        begin
-          // Disconnect from old location.
-          InternalDisconnectNode(Source, True);
-          // Connect to new location.
-          InternalConnectNode(Source, Target, Self, Mode);
-          DoNodeMoved(Source);
-        end
-        else
-        begin
-          // Only child nodes should be moved. Insertion order depends on move mode.
-          if Mode = amAddChildFirst then
-          begin
-            Source := Source.LastChild;
-            while Assigned(Source) do
-            begin
-              NewNode := Source.PrevSibling;
-              // Disconnect from old location.
-              InternalDisconnectNode(Source, True, False);
-              // Connect to new location.
-              InternalConnectNode(Source, Target, Self, Mode);
-              DoNodeMoved(Source);
-              Source := NewNode;
-            end;
-          end
-          else
-          begin
-            Source := Source.FirstChild;
-            while Assigned(Source) do
-            begin
-              NewNode := Source.NextSibling;
-              // Disconnect from old location.
-              InternalDisconnectNode(Source, True, False);
-              // Connect to new location.
-              InternalConnectNode(Source, Target, Self, Mode);
-              DoNodeMoved(Source);
-              Source := NewNode;
-            end;
-          end;
-        end;
-      end;
-    end
-    else
-    begin
-      // Difficult case: move node(s) to another tree.
-      // In opposition to node copying we ask only once if moving is allowed because
-      // we cannot take back a move once done.
-      if Target = TargetTree.FRoot then
-        Allowed := DoNodeMoving(Source, nil)
-      else
-        Allowed := DoNodeMoving(Source, Target);
-
-      if Allowed then
-      begin
-        Stream := TMemoryStream.Create;
-        try
-          // Write all nodes into a temporary stream depending on the ChildrenOnly flag.
-          if not ChildrenOnly then
-            WriteNode(Stream, Source)
-          else
-          begin
-            Source := Source.FirstChild;
-            while Assigned(Source) do
-            begin
-              WriteNode(Stream, Source);
-              Source := Source.NextSibling;
-            end;
-          end;
-          // Now load the serialized nodes into the target node (tree).
-          TargetTree.BeginUpdate;
-          try
-            Stream.Position := 0;
-            while Stream.Position < Stream.Size do
-            begin
-              NewNode := TargetTree.MakeNewNode;
-              InternalConnectNode(NewNode, Target, TargetTree, Mode);
-              TargetTree.InternalAddFromStream(Stream, VTTreeStreamVersion, NewNode);
-              DoNodeMoved(NewNode);
-            end;
-          finally
-            TargetTree.EndUpdate;
-          end;
-        finally
-          Stream.Free;
-        end;
-        // finally delete original nodes
-        BeginUpdate;
-        try
-          if ChildrenOnly then
-            DeleteChildren(Source)
-          else
-            DeleteNode(Source);
-        finally
-          EndUpdate;
-        end;
-      end;
-    end;
-
-    InvalidateCache;
-    if (FUpdateCount = 0) and Allowed then
-    begin
-      ValidateCache;
-      UpdateScrollBars(True);
-      Invalidate;
-      if TargetTree <> Self then
-        TargetTree.Invalidate;
-    end;
-    StructureChange(Source, crNodeMoved);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PaintTree(TargetCanvas: TCanvas; const Window: TRect; Target: TPoint;
-  PaintOptions: TVTInternalPaintOptions; PixelFormat: TPixelFormat);
-
-// This is the core paint routine of the tree. It is responsible for maintaining the paint cycles per node as well
-// as coordinating drawing of the various parts of the tree image.
-// TargetCanvas is the canvas to which to draw the tree image. This is usually the tree window itself but could well
-// be a bitmap or printer canvas.
-// Window determines which part of the entire tree image to draw. The full size of the virtual image is determined
-// by GetTreeRect.
-// Target is the position in TargetCanvas where to draw the tree part specified by Window.
-// PaintOptions determines what of the tree to draw. For different tasks usually different parts need to be drawn, with
-// a full image in the window, selected only nodes for a drag image etc.
-
-const
-  ImageKind: array[Boolean] of TVTImageKind = (ikNormal, ikSelected);
-
-var
-  DrawSelectionRect,
-  UseBackground,
-  ShowImages,
-  ShowStateImages,
-  ShowCheckImages,
-  UseColumns,
-  IsMainColumn: Boolean;
-  {$ifdef ManualClipNeeded}
-  YCorrect,
-  {$endif}
-  VAlign,
-  IndentSize,
-  ButtonX,
-  ButtonY: Integer;
-  LineImage: TLineImage;
-  PaintInfo: TVTPaintInfo;     // all necessary information about a node to pass to the paint routines
-
-  R,                           // the area of an entire node in its local coordinate
-  TargetRect,                  // the area of a node (part) in the target canvas
-  SelectionRect: TRect;        // ordered rectangle used for drawing the selection focus rect
-  NextColumn: TColumnIndex;
-  BaseOffset: Integer;         // top position of the top node to draw given in absolute tree coordinates
-  NodeBitmap: TBitmap;         // small buffer to draw flicker free
-  MaximumRight,                // maximum horizontal target position
-  MaximumBottom: Integer;      // maximum vertical target position
-  SelectLevel: Integer;        // > 0 if current node is selected or child/grandchild etc. of a selected node
-  FirstColumn: TColumnIndex;   // index of first column which is at least partially visible in the given window
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaint],'PaintTree');{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaint, lcHeaderOffset],'Window',Window);{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaint, lcHeaderOffset],'Target',Target);{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'ClientRect',ClientRect);{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'TreeRect',GetTreeRect);{$endif}
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader],'OffsetX: %d  OffsetY: %d',[OffsetX,OffsetY]);{$endif}
-  //lcl changes to 24bit color depth when screen depth is 32 bit
-  //todo: remove when this limitation is removed
-  {$ifdef Windows}
-  if (PixelFormat = pfDevice) and (ScreenInfo.ColorDepth = 32) then
-    PixelFormat := pf32bit;
-  {$endif}
-  if not (tsPainting in FStates) then
-  begin
-    DoStateChange([tsPainting]);
-    try
-      DoBeforePaint(TargetCanvas);
-
-      // Create small bitmaps and initialize default values.
-      // The bitmaps are used to paint one node at a time and to draw the result to the target (e.g. screen) in one step,
-      // to prevent flickering.
-      NodeBitmap := TBitmap.Create;
-      // For alpha blending we need the 32 bit pixel format. For other targets there might be a need for a certain
-      // pixel format (e.g. printing).
-      if MMXAvailable and ((FDrawSelectionMode = smBlendedRectangle) or (tsUseThemes in FStates) or
-        (toUseBlendedSelection in FOptions.PaintOptions)) then
-        NodeBitmap.PixelFormat := pf32Bit
-      else
-        NodeBitmap.PixelFormat := PixelFormat;
-
-      // Prepare paint info structure and lock the back bitmap canvas to avoid that it gets freed on the way.
-      FillChar(PaintInfo, SizeOf(PaintInfo), 0);
-      PaintInfo.Canvas := NodeBitmap.Canvas;
-      NodeBitmap.Canvas.Lock;
-      try
-        {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FNewSelRect', FNewSelRect);{$endif}
-        // Prepare the current selection rectangle once. The corner points are absolute tree coordinates.
-        SelectionRect := OrderRect(FNewSelRect);
-        {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails, lcSelection],'SelectionRect', SelectionRect);{$endif}
-        DrawSelectionRect := IsMouseSelecting and not IsRectEmpty(SelectionRect);
-        {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'DrawSelectionRect',DrawSelectionRect);{$endif}
-        // R represents an entire node (all columns), but is a bit unprecise when it comes to
-        // trees without any column defined, because FRangeX only represents the maximum width of all
-        // nodes in the client area (not all defined nodes). There might be, however, wider nodes somewhere. Without full
-        // validation I cannot better determine the width, though. By using at least the control's width it is ensured
-        // that the tree is fully displayed on screen.
-        R := Rect(0, 0, Max(FRangeX, ClientWidth), 0);
-        NodeBitmap.Width := Window.Right - Window.Left;
-
-        // For quick checks some intermediate variables are used.
-        UseBackground := (toShowBackground in FOptions.FPaintOptions) and (FBackground.Graphic is TBitmap) and
-          (poBackground in PaintOptions);
-        ShowImages := Assigned(FImages);
-        ShowStateImages := Assigned(FStateImages);
-        ShowCheckImages := Assigned(FCheckImages) and (toCheckSupport in FOptions.FMiscOptions);
-        {$ifdef DEBUG_VTV}Logger.Send([lcCheck],'ShowCheckImages',ShowCheckImages);{$endif}
-        UseColumns := FHeader.UseColumns;
-
-        // Adjust paint options to tree settings. Hide selection if told so or the tree is unfocused.
-        if (toAlwaysHideSelection in FOptions.FPaintOptions) or
-          (not Focused and (toHideSelection in FOptions.FPaintOptions)) then
-          Exclude(PaintOptions, poDrawSelection);
-        if toHideFocusRect in FOptions.FPaintOptions then
-          Exclude(PaintOptions, poDrawFocusRect);
-
-        // Determine node to start drawing with.
-        BaseOffset := 0;
-        PaintInfo.Node := InternalGetNodeAt(0, Window.Top, False, BaseOffset);
-        if PaintInfo.Node = nil then
-          BaseOffset := Window.Top;
-        {$ifdef DEBUG_VTV}Logger.Send([lcPaint, lcHeaderOffset],'BaseOffset',BaseOffset);{$endif}
-
-        // Transform selection rectangle into node bitmap coordinates.
-        if DrawSelectionRect then
-          OffsetRect(SelectionRect, 0, -BaseOffset);
-
-        {$ifdef DEBUG_VTV}Logger.Send([lcSelection], 'SelectionRect fixed by BaseOffset', SelectionRect);{$endif}
-        // The target rectangle holds the coordinates of the exact area to blit in target canvas coordinates.
-        // It is usually smaller than an entire node and wanders while the paint loop advances.
-        MaximumRight := Target.X + (Window.Right - Window.Left);
-        MaximumBottom := Target.Y + (Window.Bottom - Window.Top);
-
-        {$ifdef DEBUG_VTV}Logger.Send([lcPaintHeader, lcHeaderOffset],'MaximumRight: %d MaximumBottom: %d',[MaximumRight,MaximumBottom]);{$endif}
-        TargetRect := Rect(Target.X, Target.Y - (Window.Top - BaseOffset), MaximumRight, 0);
-        TargetRect.Bottom := TargetRect.Top;
-
-        // This marker gets the index of the first column which is visible in the given window.
-        // This is needed for column based background colors.
-        FirstColumn := InvalidColumn;
-
-        if Assigned(PaintInfo.Node) then
-        begin
-          ButtonX := Round((Integer(FIndent) - FPlusBM.Width) / 2);
-
-          // ----- main node paint loop
-          while Assigned(PaintInfo.Node) do
-          begin
-            {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'PaintNode');{$endif}
-            {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeIndex',PaintInfo.Node^.Index);{$endif}
-            {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'BaseOffset',BaseOffset);{$endif}
-            {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif}
-            // Determine LineImage, SelectionLevel and IndentSize
-            SelectLevel := DetermineLineImageAndSelectLevel(PaintInfo.Node, LineImage);
-            IndentSize := Length(LineImage);
-            if not (toFixedIndent in FOptions.FPaintOptions) then
-              ButtonX := (IndentSize - 1) * FIndent + Round((FIndent - FPlusBM.Width) / 2);
-
-            // Initialize node if not already done.
-            if not (vsInitialized in PaintInfo.Node.States) then
-              InitNode(PaintInfo.Node);
-            if (vsSelected in PaintInfo.Node.States) and not (toChildrenAbove in FOptions.FPaintOptions) then
-              Inc(SelectLevel);
-
-            // Ensure the node's height is determined.
-            MeasureItemHeight(PaintInfo.Canvas, PaintInfo.Node);
-
-            // Adjust the brush origin for dotted lines depending on the current source position.
-            // It is applied some lines later, as the canvas might get reallocated, when changing the node bitmap.
-            PaintInfo.BrushOrigin := Point(Window.Left and 1, BaseOffset and 1);
-            Inc(BaseOffset, PaintInfo.Node.NodeHeight);
-
-            TargetRect.Bottom := TargetRect.Top + PaintInfo.Node.NodeHeight;
-
-            {$ifdef DEBUG_VTV}Logger.Send([lcHeaderOffset], 'TargetRect for Node ' + IntToStr(PaintInfo.Node.Index), TargetRect);{$endif}
-
-            // If poSelectedOnly is active then do the following stuff only for selected nodes or nodes
-            // which are children of selected nodes.
-            if (SelectLevel > 0) or not (poSelectedOnly in PaintOptions) then
-            begin
-              // Adjust height of temporary node bitmap.
-              with NodeBitmap do
-              begin
-                if Height <> PaintInfo.Node.NodeHeight then
-                begin
-                  {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Setting the Node Height');{$endif}
-                  Height := PaintInfo.Node.NodeHeight;
-                  // Make sure the buffer bitmap and target bitmap use the same transformation mode.
-                  {$ifndef Gtk}
-                  SetMapMode(Canvas.Handle, GetMapMode(TargetCanvas.Handle));
-                  {$endif}
-                  SetWindowOrgEx(Canvas.Handle, Window.Left, 0, nil);
-                  R.Bottom := PaintInfo.Node.NodeHeight;
-                end;
-                // Set the origin of the canvas' brush. This depends on the node heights.
-                //todo: see if is necessary. According to docs is only necessary when HALFTONE is set
-                {$ifndef INCOMPLETE_WINAPI}
-                with PaintInfo do
-                  SetBrushOrgEx(Canvas.Handle, BrushOrigin.X, BrushOrigin.Y, nil);
-                {$endif}
-              end;
-              CalculateVerticalAlignments(ShowImages, ShowStateImages, PaintInfo.Node, VAlign, ButtonY);
-
-              // Let application decide whether the node should normally be drawn or by the application itself.
-              if not DoBeforeItemPaint(PaintInfo.Canvas, PaintInfo.Node, R) then
-              begin
-                // Init paint options for the background painting.
-                PaintInfo.PaintOptions := PaintOptions;
-                {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif}
-                // The node background can contain a single color, a bitmap or can be drawn by the application.
-                ClearNodeBackground(PaintInfo, UseBackground, True, Rect(Window.Left, TargetRect.Top, Window.Right,
-                  TargetRect.Bottom));
-                {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPaintBitmap],'After Clear BackGround',NodeBitmap);{$endif}
-                {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif}
-                // Prepare column, position and node clipping rectangle.
-                PaintInfo.CellRect := R;
-                {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'PaintInfo.CellRect',PaintInfo.CellRect);{$endif}
-                if UseColumns then
-                  InitializeFirstColumnValues(PaintInfo);
-
-                // Now go through all visible columns (there's still one run if columns aren't used).
-                with FHeader.FColumns do
-                begin
-                  while ((PaintInfo.Column > InvalidColumn) or not UseColumns)
-                    and (PaintInfo.CellRect.Left < Window.Right) do
-                  begin
-                    if UseColumns then
-                    begin
-                      PaintInfo.Column := FPositionToIndex[PaintInfo.Position];
-                      if FirstColumn = InvalidColumn then
-                        FirstColumn := PaintInfo.Column;
-                      PaintInfo.BidiMode := Items[PaintInfo.Column].FBiDiMode;
-                      PaintInfo.Alignment := Items[PaintInfo.Column].FAlignment;
-                    end
-                    else
-                    begin
-                      PaintInfo.Column := NoColumn;
-                      PaintInfo.BidiMode := BidiMode;
-                      PaintInfo.Alignment := FAlignment;
-                    end;
-                    {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],
-                      'Column Paint - PaintInfo.Position: %d PaintInfo.Column: %d',[PaintInfo.Position,PaintInfo.Column]);{$endif}
-                    PaintInfo.PaintOptions := PaintOptions;
-                    with PaintInfo do
-                    begin
-                      if (tsEditing in FStates) and (Node = FFocusedNode) and
-                        ((Column = FEditColumn) or not UseColumns) then
-                        Exclude(PaintOptions, poDrawSelection);
-                      if not UseColumns or
-                        ((vsSelected in Node.States) and (toFullRowSelect in FOptions.FSelectionOptions) and
-                         (poDrawSelection in PaintOptions)) or
-                        (coParentColor in Items[PaintInfo.Column].Options) then
-                        Exclude(PaintOptions, poColumnColor);
-                    end;
-                    IsMainColumn := PaintInfo.Column = FHeader.MainColumn;
-
-                    // Consider bidi mode here. In RTL context means left alignment actually right alignment and vice versa.
-                    if PaintInfo.BidiMode <> bdLeftToRight then
-                      ChangeBiDiModeAlignment(PaintInfo.Alignment);
-
-                    // Paint the current cell if it is marked as being visible or columns aren't used and
-                    // if this cell belongs to the main column if only the main column should be drawn.
-                    if (not UseColumns or (coVisible in Items[PaintInfo.Column].FOptions)) and
-                      (not (poMainOnly in PaintOptions) or IsMainColumn) then
-                    begin
-                      AdjustPaintCellRect(PaintInfo, NextColumn);
-
-                      // Paint the cell only if it is in the current window.
-                      if PaintInfo.CellRect.Right > Window.Left then
-                      begin
-                        with PaintInfo do
-                        begin
-                          // Fill in remaining values in the paint info structure.
-                          NodeWidth := DoGetNodeWidth(Node, Column, Canvas);
-                          // Not the entire cell is covered by text. Hence we need a running rectangle to follow up.
-                          ContentRect := CellRect;
-                          // Set up the distance from column border (margin).
-                          if BidiMode <> bdLeftToRight then
-                            Dec(ContentRect.Right, FMargin)
-                          else
-                            Inc(ContentRect.Left, FMargin);
-
-                          if ShowCheckImages and IsMainColumn then
-                          begin
-                            ImageInfo[iiCheck].Index := GetCheckImage(Node);
-                            if ImageInfo[iiCheck].Index > -1 then
-                            begin
-                              AdjustImageBorder(FCheckImages.Height, FCheckImages.Height, BidiMode, VAlign, ContentRect, ImageInfo[iiCheck]);
-                              ImageInfo[iiCheck].Ghosted := False;
-                            end;
-                          end
-                          else
-                            ImageInfo[iiCheck].Index := -1;
-                          if ShowStateImages then
-                          begin
-                            GetImageIndex(PaintInfo, ikState, iiState, FStateImages);
-                            if ImageInfo[iiState].Index > -1 then
-                              AdjustImageBorder(FStateImages.Width, FStateImages.Height, BidiMode, VAlign, ContentRect, ImageInfo[iiState]);
-                          end
-                          else
-                            ImageInfo[iiState].Index := -1;
-                          if ShowImages then
-                          begin
-                            GetImageIndex(PaintInfo, ImageKind[vsSelected in Node.States], iiNormal, FImages);
-                            if ImageInfo[iiNormal].Index > -1 then
-                              AdjustImageBorder(FImages.Width, FImages.Height, BidiMode, VAlign, ContentRect, ImageInfo[iiNormal]);
-                          end
-                          else
-                            ImageInfo[iiNormal].Index := -1;
-
-                          // Take the space for the tree lines into account.
-                          if IsMainColumn then
-                            AdjustCoordinatesByIndent(PaintInfo, IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize));
-
-                          if UseColumns then
-                            LimitPaintingToArea(Canvas, CellRect);
-
-                          // Paint the horizontal grid line.
-                          if (poGridLines in PaintOptions) and (toShowHorzGridLines in FOptions.FPaintOptions) then
-                          begin
-                            Canvas.Font.Color := FColors.GridLineColor;
-                            if IsMainColumn and (FLineMode = lmBands) then
-                            begin
-                              if BidiMode = bdLeftToRight then
-                              begin
-                                DrawDottedHLine(PaintInfo, CellRect.Left + IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize) * Integer(FIndent), CellRect.Right - 1,
-                                  CellRect.Bottom - 1);
-                              end
-                              else
-                              begin
-                                DrawDottedHLine(PaintInfo, CellRect.Left, CellRect.Right - IfThen(toFixedIndent in FOptions.FPaintOptions, 1, IndentSize) * Integer(FIndent) - 1,
-                                  CellRect.Bottom - 1);
-                              end;
-                            end
-                            else
-                              DrawDottedHLine(PaintInfo, CellRect.Left, CellRect.Right, CellRect.Bottom - 1);
-                            Dec(CellRect.Bottom);
-                            Dec(ContentRect.Bottom);
-                          end;
-
-                          if UseColumns then
-                          begin
-                            // Paint vertical grid line.
-                            // Don't draw if this is the last column and the header is in autosize mode.
-                            if (poGridLines in PaintOptions) and (toShowVertGridLines in FOptions.FPaintOptions) and
-                              (not (hoAutoResize in FHeader.FOptions) or (Position < TColumnPosition(Count - 1))) then
-                            begin
-                              if (BidiMode = bdLeftToRight) or not ColumnIsEmpty(Node, Column) then
-                              begin
-                                Canvas.Font.Color := FColors.GridLineColor;
-                                DrawDottedVLine(PaintInfo, CellRect.Top, CellRect.Bottom, CellRect.Right - 1);
-                              end;
-                              Dec(CellRect.Right);
-                              Dec(ContentRect.Right);
-                            end;
-                          end;
-
-                          // Prepare background and focus rect for the current cell.
-                          PrepareCell(PaintInfo, Window.Left, NodeBitmap.Width);
-                          {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif}
-                          // Some parts are only drawn for the main column.
-                          if IsMainColumn then
-                          begin
-                            if toShowTreeLines in FOptions.FPaintOptions then
-                              PaintTreeLines(PaintInfo, VAlign, IfThen(toFixedIndent in FOptions.FPaintOptions, 1,
-                                             IndentSize), LineImage);
-                            // Show node button if allowed, if there child nodes and at least one of the child
-                            // nodes is visible or auto button hiding is disabled.
-                            if (toShowButtons in FOptions.FPaintOptions) and (vsHasChildren in Node.States) and
-                              not ((vsAllChildrenHidden in Node.States) and
-                              (toAutoHideButtons in TreeOptions.FAutoOptions)) then
-                              PaintNodeButton(Canvas, Node, Column, CellRect, ButtonX, ButtonY, BidiMode);
-
-                            if ImageInfo[iiCheck].Index > -1 then
-                              PaintCheckImage(PaintInfo);
-                          end;
-                          {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif}
-                          if ImageInfo[iiState].Index > -1 then
-                            PaintImage(PaintInfo, iiState, False);
-                          if ImageInfo[iiNormal].Index > -1 then
-                            PaintImage(PaintInfo, iiNormal, True);
-                          {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif}
-                          // Now let descendants or applications draw whatever they want,
-                          // but don't draw the node if it is currently being edited.
-                          if not ((tsEditing in FStates) and (Node = FFocusedNode) and
-                            ((Column = FEditColumn) or not UseColumns)) then
-                            DoPaintNode(PaintInfo);
-                          {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'Brush.Color',PaintInfo.Canvas.Brush.Color);{$endif}
-                          DoAfterCellPaint(Canvas, Node, Column, CellRect);
-                        end;
-                      end;
-
-                      // leave after first run if columns aren't used
-                      if not UseColumns then
-                        Break;
-                    end
-                    else
-                      NextColumn := GetNextVisibleColumn(PaintInfo.Column);
-
-                    SelectClipRgn(PaintInfo.Canvas.Handle, 0);
-                    // Stop column loop if there are no further columns in the given window.
-                    if (PaintInfo.CellRect.Left >= Window.Right) or (NextColumn = InvalidColumn) then
-                      Break;
-
-                    // Move on to next column which might not be the one immediately following the current one
-                    // because of auto span feature.
-                    PaintInfo.Position := Items[NextColumn].Position;
-
-                    // Move clip rectangle and continue.
-                    if coVisible in Items[NextColumn].FOptions then
-                      with PaintInfo do
-                      begin
-                        Items[NextColumn].GetAbsoluteBounds(CellRect.Left, CellRect.Right);
-                        CellRect.Bottom := Node.NodeHeight;
-                        ContentRect.Bottom := Node.NodeHeight;
-                      end;
-                  end;
-                end;
-
-                // This node is finished, notify descendants/application.
-                with PaintInfo do
-                begin
-                  DoAfterItemPaint(Canvas, Node, R);
-
-                  // Final touch for this node: mark it if it is the current drop target node.
-                  if (Node = FDropTargetNode) and (toShowDropmark in FOptions.FPaintOptions) and
-                    (poDrawDropMark in PaintOptions) then
-                    DoPaintDropMark(Canvas, Node, R);
-                end;
-              end;
-
-              with PaintInfo.Canvas do
-              begin
-                if DrawSelectionRect then
-                begin
-                  PaintSelectionRectangle(PaintInfo.Canvas, Window.Left, SelectionRect, Rect(0, 0, NodeBitmap.Width,
-                    NodeBitmap.Height));
-                end;
-                {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPaintBitmap],'NodeBitmap ' + IntToStr(PaintInfo.Node^.Index), NodeBitmap);{$endif}
-                {$ifdef DEBUG_VTV}Logger.SendIf([lcPaintDetails, lcHeaderOffset],'TargetRect.Top < Target.Y '+ Logger.RectToStr(TargetRect)
-                  +'  '+Logger.PointToStr(Target),TargetRect.Top < Target.Y);{$endif}
-                {$ifdef Gtk}
-                //lclheader
-                // This is a brute force fix AKA hack to prevent the header being cleared
-                // when the tree is scrolled (YOffset < 0) and the mouse is over the header
-                // Other widgetsets are not affected because excludecliprect works different (better?)
-                // this must be removed when/if the paint coordinate is modified to be header aware
-                YCorrect := 0;
-                if hoVisible in FHeader.Options then
-                begin
-                  if TargetRect.Top < FHeader.Height then
-                    YCorrect := FHeader.Height - TargetRect.Top;
-                end;
-                {$ifdef DEBUG_VTV}Logger.SendIf([lcPaintDetails],'YCorrect ' + IntToStr(YCorrect), YCorrect > 0);{$endif}
-                {$endif}
-                // Put the constructed node image onto the target canvas.
-                with TargetRect, NodeBitmap do
-                  BitBlt(TargetCanvas.Handle, Left,
-                    Top {$ifdef ManualClipNeeded} + YCorrect{$endif}, Width, Height, Canvas.Handle, Window.Left,
-                    {$ifdef ManualClipNeeded}YCorrect{$else}0{$endif}, SRCCOPY);
-              end;
-            end;
-
-            Inc(TargetRect.Top, PaintInfo.Node.NodeHeight);
-            {$ifdef DEBUG_VTV}Logger.SendIf([lcPaintHeader,lcDrag],'Last Node to be painted: '+ IntToStr(PaintInfo.Node^.Index)
-              +' (TargetRect.Top >= MaximumBottom)',TargetRect.Top >= MaximumBottom);{$endif}
-            if TargetRect.Top >= MaximumBottom then
-            begin
-              {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintNode');{$endif}
-              Break;
-            end;
-
-            // Keep selection rectangle coordinates in sync.
-            if DrawSelectionRect then
-              OffsetRect(SelectionRect, 0, -PaintInfo.Node.NodeHeight);
-
-            // Advance to next visible node.
-            PaintInfo.Node := GetNextVisible(PaintInfo.Node, True);
-            {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintNode');{$endif}
-          end;
-        end;
-
-        // Erase rest of window not covered by a node.
-        if TargetRect.Top < MaximumBottom then
-        begin
-          {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'UseBackground',UseBackground);{$endif}
-          {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'UseColumns',UseColumns);{$endif}
-          // Keep the horizontal target position to determine the selection rectangle offset later (if necessary).
-          BaseOffset := Target.X;
-          Target := TargetRect.TopLeft;
-          R := Rect(TargetRect.Left, 0, TargetRect.Left, MaximumBottom - Target.Y);
-          TargetRect := Rect(0, 0, MaximumRight - Target.X, MaximumBottom - Target.Y);
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap.Handle',NodeBitmap.Handle);{$endif}
-
-          NodeBitmap.PixelFormat := pf32Bit;
-          NodeBitmap.Width := TargetRect.Right - TargetRect.Left;
-          NodeBitmap.Height := TargetRect.Bottom - TargetRect.Top;
-          // Make sure the buffer bitmap and target bitmap use the same transformation mode.
-          {$ifndef Gtk}
-          SetMapMode(NodeBitmap.Canvas.Handle, GetMapMode(TargetCanvas.Handle));
-          {$endif}
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap.Handle after changing height to background',NodeBitmap.Handle);{$endif}
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'TargetRect',TargetRect);{$endif}
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap Width: %d Height: %d',[NodeBitmap.Width,NodeBitmap.Height]);{$endif}
-          // Call back application/descendants whether they want to erase this area.
-          SetWindowOrgEx(NodeBitmap.Canvas.Handle, Target.X, 0, nil);
-          if not DoPaintBackground(NodeBitmap.Canvas, TargetRect) then
-          begin
-            if UseBackground then
-            begin
-              SetWindowOrgEx(NodeBitmap.Canvas.Handle, 0, 0, nil);
-              if toStaticBackground in TreeOptions.PaintOptions then
-                StaticBackground(FBackground.Bitmap, NodeBitmap.Canvas, Target, TargetRect)
-              else
-                TileBackground(FBackground.Bitmap, NodeBitmap.Canvas, Target, TargetRect);
-            end
-            else
-            begin
-              // Consider here also colors of the columns.
-              if UseColumns then
-              begin
-                with FHeader.FColumns do
-                begin
-                  // If there is no content in the tree then the first column has not yet been determined.
-                  if FirstColumn = InvalidColumn then
-                  begin
-                    FirstColumn := GetFirstVisibleColumn;
-                    repeat
-                      if FirstColumn <> InvalidColumn then
-                      begin
-                        R.Left := Items[FirstColumn].Left;
-                        R.Right := R.Left +  Items[FirstColumn].FWidth;
-                        if R.Right > TargetRect.Left then
-                          Break;
-                        FirstColumn := GetNextVisibleColumn(FirstColumn);
-                      end;
-                    until FirstColumn = InvalidColumn;
-                  end
-                  else
-                  begin
-                    R.Left := Items[FirstColumn].Left;
-                    R.Right := R.Left +  Items[FirstColumn].FWidth;
-                  end;
-
-                  NodeBitmap.Canvas.Font.Color := FColors.GridLineColor;
-                  while (FirstColumn <> InvalidColumn) and (R.Left < TargetRect.Right + Target.X) do
-                  begin
-                    if (poGridLines in PaintOptions) and
-                       (toFullVertGridLines in FOptions.FPaintOptions) and
-                       (toShowVertGridLines in FOptions.FPaintOptions) and
-                       (not (hoAutoResize in FHeader.FOptions) or (Cardinal(FirstColumn) < TColumnPosition(Count - 1))) then
-                    begin
-                      DrawDottedVLine(PaintInfo, R.Top, R.Bottom, R.Right - 1);
-                      Dec(R.Right);
-                    end;
-
-                    if not (coParentColor in Items[FirstColumn].FOptions) then
-                      NodeBitmap.Canvas.Brush.Color := Items[FirstColumn].FColor
-                    else
-                      NodeBitmap.Canvas.Brush.Color := Brush.Color;
-
-                    NodeBitmap.Canvas.FillRect(R);
-                    FirstColumn := GetNextVisibleColumn(FirstColumn);
-                    if FirstColumn <> InvalidColumn then
-                    begin
-                      R.Left := Items[FirstColumn].Left;
-                      R.Right := R.Left + Items[FirstColumn].FWidth;
-                    end;
-                  end;
-
-                  // Erase also the part of the tree not covert by a column.
-                  if R.Right < TargetRect.Right + Target.X then
-                  begin
-                    R.Left := R.Right;
-                    R.Right := TargetRect.Right + Target.X;
-                    // Prevent erasing the last vertical grid line.
-                    if (poGridLines in PaintOptions) and
-                       (toFullVertGridLines in FOptions.FPaintOptions) and (toShowVertGridLines in FOptions.FPaintOptions) and
-                       (not (hoAutoResize in FHeader.FOptions)) then
-                      Inc(R.Left);
-                    NodeBitmap.Canvas.Brush.Color := Brush.Color;
-                    NodeBitmap.Canvas.FillRect(R);
-                  end;
-                end;
-                SetWindowOrgEx(NodeBitmap.Canvas.Handle, 0, 0, nil);
-              end
-              else
-              begin
-                {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'ErasingBackGround');{$endif}
-                {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'TargetRect',TargetRect);{$endif}
-                // No columns nor bitmap background. Simply erase it with the tree color.
-                SetWindowOrgEx(NodeBitmap.Canvas.Handle, 0, 0, nil);
-                NodeBitmap.Canvas.Brush.Color := Brush.Color;
-                NodeBitmap.Canvas.FillRect(TargetRect);
-              end;
-            end;
-          end;
-          SetWindowOrgEx(NodeBitmap.Canvas.Handle, 0, 0, nil);
-          {$ifdef DEBUG_VTV}Logger.Watch([lcPaintDetails],'DrawSelectionRect',DrawSelectionRect);{$endif}
-          if DrawSelectionRect then
-          begin
-            R := OrderRect(FNewSelRect);
-            // Remap the selection rectangle to the current window of the tree.
-            // Since Target has been used for other tasks BaseOffset got the left extent of the target position here.
-            OffsetRect(R, -Target.X + BaseOffset - Window.Left, -Target.Y + FOffsetY);
-            //todo: see if is necessary
-            {$ifndef INCOMPLETE_WINAPI}
-            SetBrushOrgEx(NodeBitmap.Canvas.Handle, 0, Target.X and 1, nil);
-            {$endif}
-            PaintSelectionRectangle(NodeBitmap.Canvas, 0, R, TargetRect);
-          end;
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap.Canvas.Height',NodeBitmap.Canvas.Height);{$endif}
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'NodeBitmap.Canvas.ClipRect',NodeBitmap.Canvas.ClipRect);{$endif}
-          {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Target',Target);{$endif}
-          {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPaintBitmap],'BackGroundBitmap',NodeBitmap);{$endif}
-          with Target, NodeBitmap do
-            BitBlt(TargetCanvas.Handle, X, Y, Width, Height, Canvas.Handle, 0, 0, SRCCOPY);
-        end;
-      finally
-        NodeBitmap.Canvas.Unlock;
-        NodeBitmap.Free;
-      end;
-      DoAfterPaint(TargetCanvas);
-    finally
-      DoStateChange([], [tsPainting]);
-    end;
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaint],'PaintTree');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.PasteFromClipboard: Boolean;
-
-// Reads what is currently on the clipboard into the tree (if the format is supported).
-// Note: If the application wants to have text or special formats to be inserted then it must implement
-//       its own code (OLE). Here only the native tree format is accepted.
-
-var
-  Data: IDataObject;
-  Source: TBaseVirtualTree;
-
-begin
-  Result := False;
-  if not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    if OleGetClipboard(Data) <> S_OK then
-      ShowError(SClipboardFailed, hcTFClipboardFailed)
-    else
-    try
-      // Try to get the source tree of the operation to optimize the operation.
-      Source := GetTreeFromDataObject(Data);
-      Result := ProcessOLEData(Source, Data, FFocusedNode, FDefaultPasteMode, Assigned(Source) and
-        (tsCutPending in Source.FStates));
-      if Assigned(Source) then
-        if Source <> Self then
-          Source.FinishCutOrCopy
-        else
-          DoStateChange([], [tsCutPending]);
-    finally
-      Data := nil;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.PrepareDragImage(Hotspot: TPoint; const DataObject: IDataObject);
-
-// Initiates an image drag operation. Hotspot is the position of the mouse in client coordinates.
-
-var
-  PaintOptions: TVTInternalPaintOptions;
-  TreeRect,
-  PaintRect: TRect;
-  LocalSpot,
-  ImagePos,
-  PaintTarget: TPoint;
-  Image: TBitmap;
-
-begin
-  if CanShowDragImage then
-  begin
-    // Determine the drag rectangle which is a square around the hot spot. Operate in virtual tree space.
-    LocalSpot := HotSpot;
-    Dec(LocalSpot.X, -FEffectiveOffsetX);
-    Dec(LocalSpot.Y, FOffsetY);
-    TreeRect := Rect(LocalSpot.X - FDragWidth div 2, LocalSpot.Y - FDragHeight div 2, LocalSpot.X + FDragWidth div 2,
-      LocalSpot.Y + FDragHeight div 2);
-
-    // Check that we have a valid rectangle.
-    with TreeRect do
-    begin
-      PaintRect := TreeRect;
-      //lclheader
-      if hoVisible in FHeader.Options then
-        OffsetRect(PaintRect, 0, -FHeader.Height);
-      if Left < 0 then
-      begin
-        PaintTarget.X := -Left;
-        PaintRect.Left := 0;
-      end
-      else
-        PaintTarget.X := 0;
-      if Top < 0 then
-      begin
-        PaintTarget.Y := -PaintRect.Top;
-        PaintRect.Top := 0;
-      end
-      else
-        PaintTarget.Y := 0;
-    end;
-
-    Image := TBitmap.Create;
-    with Image do
-    try
-      PixelFormat := pf32Bit;
-      Width := TreeRect.Right - TreeRect.Left;
-      Height := TreeRect.Bottom - TreeRect.Top;
-      // Erase the entire image with the color key value, for the case not everything
-      // in the image is covered by the tree image.
-      Canvas.Brush.Color := Brush.Color;
-      Canvas.FillRect(Rect(0, 0, Width, Height));
-
-      PaintOptions := [poDrawSelection, poSelectedOnly];
-      if FDragImageKind = diMainColumnOnly then
-        Include(PaintOptions, poMainOnly);
-      PaintTree(Image.Canvas, PaintRect, PaintTarget, PaintOptions);
-
-      // Once we have got the drag image we can convert all necessary coordinates into screen space.
-      OffsetRect(TreeRect, -FEffectiveOffsetX, FOffsetY);
-      ImagePos := ClientToScreen(TreeRect.TopLeft);
-      HotSpot := ClientToScreen(HotSpot);
-
-      FDragImage.ColorKey := Brush.Color;
-      FDragImage.PrepareDrag(Image, ImagePos, HotSpot, DataObject);
-    finally
-      Image.Free;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-{$ifdef EnablePrint}
-procedure TBaseVirtualTree.Print(Printer: TPrinter; PrintHeader: Boolean);
-
-var
-  SaveTreeFont: TFont;                 // Remembers the tree's current font.
-  SaveHeaderFont: TFont;               // Remembers the header's current font.
-  ImgRect,                             // Describes the dimensions of Image.
-  TreeRect,                            // The total VTree dimensions.
-  DestRect,                            // Dimensions of PrinterImage.
-  SrcRect: TRect;                      // Clip dimensions from Image -> PrinterImage
-  P: TPoint;                           // Used by PaintTree.
-  Options: TVTInternalPaintOptions;    // Used by PaintTree.
-  Image,                               // Complete Tree is drawn to this image.
-  PrinterImage: TBitmap;               // This is the image that gets printed.
-  SaveColor: TColor;                   // Remembers the VTree Color.
-  pTxtHeight,                          // Height of font in the TPrinter.Canvas
-  vTxtHeight,                          // Height of font in the VTree Canvas
-  vPageWidth,
-  vPageHeight,                         // Printer height in VTree resolution
-  xPageNum, yPageNum,                  // # of pages (except the occasional last one)
-  xPage, yPage: Integer;               // Loop counter
-  Scale: Extended;                     // Scale factor between Printer Canvas and VTree Canvas
-  LogFont: TLogFont;
-
-begin
-  if Assigned(Printer) then
-  begin
-    BeginUpdate;
-
-    // Grid lines are the only parts which are desirable when printing.
-    Options := [poGridLines];
-
-    // Remember the tree font.
-    SaveTreeFont := TFont.Create;
-    SaveTreeFont.Assign(Font);
-    // Create a new font for printing which does not use clear type output (but is antialiased, if possible)
-    // and which has the highest possible quality.
-    GetObject(Font.Handle, SizeOf(TLogFont), @LogFont);
-    LogFont.lfQuality := ANTIALIASED_QUALITY;
-    Font.Handle := CreateFontIndirect(LogFont);
-
-    // Create an image that will hold the complete VTree
-    Image := TBitmap.Create;
-    Image.PixelFormat := pf32Bit;
-    PrinterImage := nil;
-    try
-      TreeRect := GetTreeRect;
-
-      Image.Width := TreeRect.Right - TreeRect.Left;
-      P := Point(0, 0);
-      if (hoVisible in FHeader.Options) and PrintHeader then
-      begin
-        Inc(TreeRect.Bottom, FHeader.Height);
-        Inc(P.Y, FHeader.Height);
-      end;
-      Image.Height := TreeRect.Bottom - TreeRect.Top;
-
-      ImgRect.Left := 0;
-      ImgRect.Top := 0;
-      ImgRect.Right := Image.Width;
-
-      // Force the background to white color during the rendering.
-      SaveColor := Color;
-      Color := clWhite;
-      // Print header if it is visible.
-      if (hoVisible in FHeader.Options) and PrintHeader then
-      begin
-        SaveHeaderFont := TFont.Create;
-        try
-          SaveHeaderFont.Assign(FHeader.Font);
-          // Create a new font for printing which does not use clear type output (but is antialiased, if possible)
-          // and which has the highest possible quality.
-          GetObject(FHeader.Font.Handle, SizeOf(TLogFont), @LogFont);
-          LogFont.lfQuality := ANTIALIASED_QUALITY;
-          FHeader.Font.Handle := CreateFontIndirect(LogFont);
-          ImgRect.Bottom := FHeader.Height;
-          FHeader.FColumns.PaintHeader(Image.Canvas.Handle, ImgRect, 0);
-          FHeader.Font := SaveHeaderFont;
-        finally
-          SaveHeaderFont.Free;
-        end;
-      end;
-      // The image's height is already adjusted for the header if it is visible.
-      ImgRect.Bottom := Image.Height;
-
-      PaintTree(Image.Canvas, ImgRect, P, Options, pf32Bit);
-      Color := SaveColor;
-
-      // Activate the printer
-      Printer.BeginDoc;
-      Printer.Canvas.Font := Font;
-
-      // Now we can calculate the scaling :
-      pTxtHeight := Printer.Canvas.TextHeight('Tj');
-      vTxtHeight := Canvas.TextHeight('Tj');
-
-      Scale := pTxtHeight / vTxtHeight;
-
-      // Create an Image that has the same dimensions as the printer canvas but
-      // scaled to the VTree resolution:
-      PrinterImage := TBitmap.Create;
-
-      vPageHeight := Round(Printer.PageHeight / Scale);
-      vPageWidth := Round(Printer.PageWidth / Scale);
-
-      // We do a minumum of one page.
-      xPageNum := Trunc(Image.Width / vPageWidth);
-      yPageNum := Trunc(Image.Height / vPageHeight);
-
-      PrinterImage.Width := vPageWidth;
-      PrinterImage.Height := vPageHeight;
-
-      // Split vertically:
-      for yPage := 0 to yPageNum do
-      begin
-        DestRect.Left := 0;
-        DestRect.Top := 0;
-        DestRect.Right := PrinterImage.Width;
-        DestRect.Bottom := PrinterImage.Height;
-
-        // Split horizontally:
-        for xPage := 0 to xPageNum do
-          begin
-            SrcRect.Left := vPageWidth * xPage;
-            SrcRect.Top := vPageHeight * yPage;
-            SrcRect.Right := vPageWidth * xPage + PrinterImage.Width;
-            SrcRect.Bottom := SrcRect.Top + vPageHeight;
-
-            // Clear the image
-            PrinterImage.Canvas.Brush.Color := clWhite;
-            PrinterImage.Canvas.FillRect(Rect(0, 0, PrinterImage.Width, PrinterImage.Height));
-            PrinterImage.Canvas.CopyRect(DestRect, Image.Canvas, SrcRect);
-            PrtStretchDrawDIB(Printer.Canvas, Rect(0, 0, Printer.PageWidth, Printer.PageHeight - 1), PrinterImage);
-            if xPage <> xPageNum then
-              Printer.NewPage;
-          end;
-        if yPage <> yPageNum then
-          Printer.NewPage;
-      end;
-
-      // Restore tree font.
-      Font := SaveTreeFont;
-      SaveTreeFont.Free;
-      Printer.EndDoc;
-    finally
-      PrinterImage.Free;
-      Image.Free;
-      EndUpdate;
-    end;
-  end;
-end;
-{$endif}
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ProcessDrop(DataObject: IDataObject; TargetNode: PVirtualNode; var Effect: LongWord;
-  Mode: TVTNodeAttachMode): Boolean;
-
-// Recreates the (sub) tree structure serialized into memory and provided by DataObject. The new nodes are attached to
-// the passed node or FRoot if TargetNode is nil.
-// Returns True on success, i.e. the CF_VIRTUALTREE format is supported by the data object and the structure could be
-// recreated, otherwise False.
-
-var
-  Source: TBaseVirtualTree;
-
-begin
-  Result := False;
-  if Mode = amNoWhere then
-    Effect := DROPEFFECT_NONE
-  else
-  begin
-    BeginUpdate;
-    // try to get the source tree of the operation
-    Source := GetTreeFromDataObject(DataObject);
-    if Assigned(Source) then
-      Source.BeginUpdate;
-    try
-      try
-        // Before adding the new nodes try to optimize the operation if source and target tree reside in
-        // the same application and operation is a move.
-        if ((Effect and DROPEFFECT_MOVE) <> 0) and Assigned(Source) then
-        begin
-          // If both copy and move are specified then prefer a copy because this is not destructing.
-          Result := ProcessOLEData(Source, DataObject, TargetNode, Mode, (Effect and DROPEFFECT_COPY) = 0);
-          // Since we made an optimized move or a copy there's no reason to act further after DoDragging returns.
-          Effect := DROPEFFECT_NONE;
-        end
-        else
-          // Act only if move or copy operation is requested.
-          if (Effect and (DROPEFFECT_MOVE or DROPEFFECT_COPY)) <> 0 then
-            Result := ProcessOLEData(Source, DataObject, TargetNode, Mode, False)
-          else
-            Result := False;
-      except
-        Effect := DROPEFFECT_NONE;
-      end;
-    finally
-      if Assigned(Source) then
-        Source.EndUpdate;
-      EndUpdate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ReinitChildren(Node: PVirtualNode; Recursive: Boolean);
-
-// Forces all child nodes of Node to be reinitialized.
-// If Recursive is True then also the grandchildren are reinitialized.
-
-var
-  Run: PVirtualNode;
-
-begin
-  if Assigned(Node) then
-  begin
-    InitChildren(Node);
-    Run := Node.FirstChild;
-  end
-  else
-  begin
-    InitChildren(FRoot);
-    Run := FRoot.FirstChild;
-  end;
-
-  while Assigned(Run) do
-  begin
-    ReinitNode(Run, Recursive);
-    Run := Run.NextSibling;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ReinitNode(Node: PVirtualNode; Recursive: Boolean);
-
-// Forces the given node and all its children (if recursive is True) to be initialized again without
-// modifying any data in the nodes nor deleting children (unless the application requests a different amount).
-
-begin
-  if Assigned(Node) and (Node <> FRoot) then
-  begin
-    // Remove dynamic styles.
-    Node.States := Node.States - [vsChecking, vsCutOrCopy, vsDeleting, vsHeightMeasured];
-    InitNode(Node);
-  end;
-
-  if Recursive then
-    ReinitChildren(Node, True);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.RepaintNode(Node: PVirtualNode);
-
-// Causes an immediate repaint of the given node.
-
-var
-  R: Trect;
-
-begin
-  if Assigned(Node) and (Node <> FRoot) then
-  begin
-    R := GetDisplayRect(Node, -1, False);
-    RedrawWindow(Handle, @R, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_NOERASE or RDW_VALIDATE or RDW_NOCHILDREN);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ResetNode(Node: PVirtualNode);
-
-// Deletes all children of the given node and marks it as being uninitialized.
-
-begin
-  DoCancelEdit;
-  if (Node = nil) or (Node = FRoot) then
-    Clear
-  else
-  begin
-    DoReset(Node);
-    DeleteChildren(Node);
-    // Remove initialized and other dynamic styles, keep persistent styles.
-    Node.States := Node.States - [vsInitialized, vsChecking, vsCutOrCopy, vsDeleting, vsHasChildren, vsExpanded,
-      vsHeightMeasured];
-    InvalidateNode(Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SaveToFile(const FileName: TFileName);
-
-// Saves the entire content of the tree into a file (see further notes in SaveToStream).
-
-var
-  FileStream: TFileStream;
-
-begin
-  FileStream := TFileStream.Create(FileName, fmCreate);
-  try
-    SaveToStream(FileStream);
-  finally
-    FileStream.Free;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SaveToStream(Stream: TStream; Node: PVirtualNode = nil);
-
-// Saves Node and all its children to Stream. If Node is nil then all top level nodes will be stored.
-// Note: You should be careful about assuming what is actually saved. The problem here is that we are dealing with
-//       virtual data. The tree can so not know what it has to save. The only fact we reliably know is the tree's
-//       structure. To be flexible for future enhancements as well as unknown content (unknown to the tree class which
-//       is saving/loading the stream) a chunk based approach is used here. Every tree class handles only those
-//       chunks which are not handled by an anchestor class and are known by the class.
-//
-// The base tree class saves only the structure of the tree along with application provided data. descendants may
-// optionally add their own chunks to store additional information. See: WriteChunks.
-
-var
-  Count: Cardinal;
-
-begin
-  Stream.Write(MagicID, SizeOf(MagicID));
-  if Node = nil then
-  begin
-    // Keep number of top level nodes for easy restauration.
-    Count := FRoot.ChildCount;
-    Stream.WriteBuffer(Count, SizeOf(Count));
-
-    // Save entire tree here.
-    Node := FRoot.FirstChild;
-    while Assigned(Node) do
-    begin
-      WriteNode(Stream, Node);
-      Node := Node.NextSibling;
-    end;
-  end
-  else
-  begin
-    Count := 1;
-    Stream.WriteBuffer(Count, SizeOf(Count));
-    WriteNode(Stream, Node);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ScrollIntoView(Node: PVirtualNode; Center: Boolean; Horizontally: Boolean = False): Boolean;
-
-// Scrolls the tree so that the given node is in the client area and returns True if the tree really has been
-// scrolled (e.g. to avoid further updates) else returns False. If extened focus is enabled then the tree will also
-// be horizontally scrolled if needed.
-// Note: All collapsed parents of the node are expanded.
-
-var
-  R: TRect;
-  Run: PVirtualNode;
-  UseColumns,
-  HScrollBarVisible: Boolean;
-  ScrolledVertically,
-  ScrolledHorizontally: Boolean;
-  OffY, OffYM: Integer;
-
-begin
-  //todo: minimize calls to ClientHeight and ClientWidth
-  ScrolledVertically   := False;
-  ScrolledHorizontally := False;
-
-  if Assigned(Node) and (Node <> FRoot) then
-  begin
-    // Make sure all parents of the node are expanded.
-    Run := Node.Parent;
-    while Run <> FRoot do
-    begin
-      if not (vsExpanded in Run.States) then
-        ToggleNode(Run);
-      Run := Run.Parent;
-    end;
-    UseColumns := FHeader.UseColumns;
-    if UseColumns and FHeader.FColumns.IsValidColumn(FFocusedColumn) then
-      R := GetDisplayRect(Node, FFocusedColumn, not (toGridExtensions in FOptions.FMiscOptions))
-    else
-      R := GetDisplayRect(Node, NoColumn, not (toGridExtensions in FOptions.FMiscOptions));
-
-    // The returned rectangle can never be empty after the expand code above.
-    // 1) scroll vertically
-    //lclheader
-    if hoVisible in FHeader.FOptions then
-      OffsetRect(R, 0, -FHeader.Height);
-
-    if R.Top < 0 then
-    begin
-      if Center then
-        SetOffsetY(FOffsetY - R.Top + ClientHeight div 2)
-      else
-        SetOffsetY(FOffsetY - R.Top);
-      ScrolledVertically := True;
-    end
-    else
-      if (R.Bottom > ClientHeight) or Center then
-      begin
-        HScrollBarVisible := (ScrollBarOptions.ScrollBars in [ssBoth, ssHorizontal]) and
-          (ScrollBarOptions.AlwaysVisible or (Integer(FRangeX) > ClientWidth));
-        if Center then
-          SetOffsetY(FOffsetY - R.Bottom + ClientHeight div 2)
-        else
-        begin
-          // Leave additional space at the bottom to have scrollrect start with full row.
-          OffY  := FOffsetY - R.Bottom + ClientHeight;
-          OffYM := OffY mod DefaultNodeHeight;
-          if OffYM <> 0 then
-            OffY := OffY - (DefaultNodeHeight + OffYM);
-          SetOffsetY(OffY);
-        end;
-        // When scrolling up and the horizontal scroll appears because of the operation
-        // then we have to move up the node the horizontal scrollbar's height too
-        // in order to avoid that the scroll bar hides the node which we wanted to have in view.
-        if not UseColumns and not HScrollBarVisible and (Integer(FRangeX) > ClientWidth) then
-          SetOffsetY(FOffsetY - GetSystemMetrics(SM_CYHSCROLL));
-        ScrolledVertically := True;
-      end;
-
-    if Horizontally then
-      // 2) scroll horizontally
-      ScrolledHorizontally := ScrollIntoView(FFocusedColumn, Center);
-
-  end;
-
-  Result := ScrolledVertically or ScrolledHorizontally;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ScrollIntoView(Column: TColumnIndex; Center: Boolean): Boolean;
-
-// Scrolls the columns so that the given column is in the client area and returns True if the columns really have been
-// scrolled (e.g. to avoid further updates) else returns False.
-
-var
-  ColumnLeft,
-  ColumnRight: Integer;
-  NewOffset: Integer;
-
-begin
-  Result := False;
-
-  if not FHeader.UseColumns then exit;
-  if not FHeader.Columns.IsValidColumn(Column) then exit; // Just in case.
-
-  ColumnLeft := Header.Columns.Items[Column].Left;
-  ColumnRight := ColumnLeft + Header.Columns.Items[Column].Width;
-
-  NewOffset := FEffectiveOffsetX;
-  if Center then
-  begin
-    NewOffset := FEffectiveOffsetX + ColumnLeft - (Header.Columns.GetVisibleFixedWidth div 2) - (ClientWidth div 2) + ((ColumnRight - ColumnLeft) div 2);
-    if NewOffset <> FEffectiveOffsetX then
-    begin
-      if UseRightToLeftAlignment then
-        SetOffsetX(-Integer(FRangeX) + ClientWidth + NewOffset)
-      else
-        SetOffsetX(-NewOffset);
-    end;
-    Result := True;
-  end
-  else
-  begin
-    if FHeader.Columns.Count > 1 then
-    begin
-      if ColumnRight > ClientWidth then
-        NewOffset := FEffectiveOffsetX + (ColumnRight - ClientWidth)
-      else if ColumnLeft < Header.Columns.GetVisibleFixedWidth then
-        NewOffset := FEffectiveOffsetX - (Header.Columns.GetVisibleFixedWidth - ColumnLeft);
-    end;
-    if NewOffset <> FEffectiveOffsetX then
-    begin
-      if UseRightToLeftAlignment then
-        SetOffsetX(-Integer(FRangeX) + ClientWidth + NewOffset)
-      else
-        SetOffsetX(-NewOffset);
-    end;
-    Result := True;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SelectAll(VisibleOnly: Boolean);
-
-// Select all nodes in the tree.
-// If VisibleOnly is True then only visible nodes are selected.
-
-var
-  Run: PVirtualNode;
-  NextFunction: TGetNextNodeProc;
-
-begin
-  if not FSelectionLocked and (toMultiSelect in FOptions.FSelectionOptions) then
-  begin
-    ClearTempCache;
-    if VisibleOnly then
-    begin
-      Run := GetFirstVisible(nil, True);
-      NextFunction := GetNextVisible;
-    end
-    else
-    begin
-      Run := GetFirst;
-      NextFunction := GetNext;
-    end;
-
-    while Assigned(Run) do
-    begin
-      if not(vsSelected in Run.States) then
-        InternalCacheNode(Run);
-      Run := NextFunction(Run);
-    end;
-    if FTempNodeCount > 0 then
-      AddToSelection(FTempNodeCache, FTempNodeCount);
-    ClearTempCache;
-    Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.Sort(Node: PVirtualNode; Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True);
-
-// Sorts the given node. The application is queried about how to sort via the OnCompareNodes event.
-// Column is simply passed to the the compare function so the application can also sort in a particular column.
-// In order to free the application from taking care about the sort direction the parameter Direction is used.
-// This way the application can always sort in increasing order, while this method reorders nodes according to this flag.
-
-  //--------------- local functions -------------------------------------------
-
-  function MergeAscending(A, B: PVirtualNode): PVirtualNode;
-
-  // Merges A and B (which both must be sorted via Compare) into one list.
-
-  var
-    Dummy: TVirtualNode;
-
-  begin
-    // This avoids checking for Result = nil in the loops.
-    Result := @Dummy;
-    while Assigned(A) and Assigned(B) do
-    begin
-      if DoCompare(A, B, Column) <= 0 then
-      begin
-        Result.NextSibling := A;
-        Result := A;
-        A := A.NextSibling;
-      end
-      else
-      begin
-        Result.NextSibling := B;
-        Result := B;
-        B := B.NextSibling;
-      end;
-    end;
-
-    // Just append the list which is not nil (or set end of result list to nil if both lists are nil).
-    if Assigned(A) then
-      Result.NextSibling := A
-    else
-      Result.NextSibling := B;
-    // return start of the new merged list
-    Result := Dummy.NextSibling;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  function MergeDescending(A, B: PVirtualNode): PVirtualNode;
-
-  // Merges A and B (which both must be sorted via Compare) into one list.
-
-  var
-    Dummy: TVirtualNode;
-
-  begin
-    // this avoids checking for Result = nil in the loops
-    Result := @Dummy;
-    while Assigned(A) and Assigned(B) do
-    begin
-      if DoCompare(A, B, Column) >= 0 then
-      begin
-        Result.NextSibling := A;
-        Result := A;
-        A := A.NextSibling;
-      end
-      else
-      begin
-        Result.NextSibling := B;
-        Result := B;
-        B := B.NextSibling;
-      end;
-    end;
-
-    // Just append the list which is not nil (or set end of result list to nil if both lists are nil).
-    if Assigned(A) then
-      Result.NextSibling := A
-    else
-      Result.NextSibling := B;
-    // Return start of the newly merged list.
-    Result := Dummy.NextSibling;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  function MergeSortAscending(var Node: PVirtualNode; N: Cardinal): PVirtualNode;
-
-  // Sorts the list of nodes given by Node (which must not be nil).
-
-  var
-    A, B: PVirtualNode;
-
-  begin
-    if N > 1 then
-    begin
-      A := MergeSortAscending(Node, N div 2);
-      B := MergeSortAscending(Node, (N + 1) div 2);
-      Result := MergeAscending(A, B);
-    end
-    else
-    begin
-      Result := Node;
-      Node := Node.NextSibling;
-      Result.NextSibling := nil;
-    end;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  function MergeSortDescending(var Node: PVirtualNode; N: Cardinal): PVirtualNode;
-
-  // Sorts the list of nodes given by Node (which must not be nil).
-
-  var
-    A, B: PVirtualNode;
-
-  begin
-    if N > 1 then
-    begin
-      A := MergeSortDescending(Node, N div 2);
-      B := MergeSortDescending(Node, (N + 1) div 2);
-      Result := MergeDescending(A, B);
-    end
-    else
-    begin
-      Result := Node;
-      Node := Node.NextSibling;
-      Result.NextSibling := nil;
-    end;
-  end;
-
-  //--------------- end local functions ---------------------------------------
-
-var
-  Run: PVirtualNode;
-  Index: Cardinal;
-
-begin
-  InterruptValidation;
-  if tsEditPending in FStates then
-  begin
-    KillTimer(Handle, EditTimer);
-    DoStateChange([], [tsEditPending]);
-  end;
-
-  if not (tsEditing in FStates) or DoEndEdit then
-  begin
-    if Node = nil then
-      Node := FRoot;
-    if vsHasChildren in Node.States then
-    begin
-      if (Node.ChildCount = 0) and DoInit then
-        InitChildren(Node);
-      // Make sure the children are valid, so they can be sorted at all.
-      if DoInit and (Node.ChildCount > 0) then
-        ValidateChildren(Node, False);
-      // Child count might have changed.
-      if Node.ChildCount > 1 then
-      begin
-        // Sort the linked list, check direction flag only once.
-        if Direction = sdAscending then
-          Node.FirstChild := MergeSortAscending(Node.FirstChild, Node.ChildCount)
-        else
-          Node.FirstChild := MergeSortDescending(Node.FirstChild, Node.ChildCount);
-        // Consolidate the child list finally.
-        Run := Node.FirstChild;
-        Run.PrevSibling := nil;
-        Index := 0;
-        repeat
-          Run.Index := Index;
-          Inc(Index);
-          if Run.NextSibling = nil then
-            Break;
-          Run.NextSibling.PrevSibling := Run;
-          Run := Run.NextSibling;
-        until False;
-        Node.LastChild := Run;
-
-        InvalidateCache;
-      end;
-      if FUpdateCount = 0 then
-      begin
-        ValidateCache;
-        Invalidate;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.SortTree(Column: TColumnIndex; Direction: TSortDirection; DoInit: Boolean = True);
-
-  //--------------- local function --------------------------------------------
-
-  procedure DoSort(Node: PVirtualNode);
-
-  // Recursively sorts Node and its child nodes.
-
-  var
-    Run: PVirtualNode;
-
-  begin
-    Sort(Node, Column, Direction, DoInit);
-
-    Run := Node.FirstChild;
-    while Assigned(Run) do
-    begin
-      if DoInit and not (vsInitialized in Run.States) then
-        InitNode(Run);
-      if vsInitialized in Run.States then
-        DoSort(Run);
-      Run := Run.NextSibling;
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-begin
-  // Instead of wrapping the sort using BeginUpdate/EndUpdate simply the update counter
-  // is modified. Otherwise the EndUpdate call will recurse here.
-  Inc(FUpdateCount);
-  try
-    if Column > InvalidColumn then
-      DoSort(FRoot);
-    InvalidateCache;
-  finally
-    if FUpdateCount > 0 then
-      Dec(FUpdateCount);
-    if FUpdateCount = 0 then
-    begin
-      ValidateCache;
-      Invalidate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ToggleNode(Node: PVirtualNode);
-
-// Changes a node's expand state to the opposite state.
-
-var
-  Child: PVirtualNode;
-  HeightDelta,
-  StepsR1,
-  StepsR2,
-  Steps: Integer;
-  TogglingTree,
-  ChildrenInView,
-  NeedFullInvalidate,
-  NeedUpdate,
-  NodeInView,
-  PosHoldable,
-  TotalFit: Boolean;
-  ToggleData: TToggleAnimationData;
-
-  //--------------- local functions -------------------------------------------
-
-  procedure UpdateRanges;
-
-  // This function is used to adjust FRangeX/FRangeY in order to correctly
-  // reflect the tree's state after a toggle, because it is essential that
-  // these values are correct if we need to scroll afterwards. To avoid a
-  // useless call to UpdateScrollbars we do it right here.
-
-  begin
-    if FRoot.TotalHeight < FDefaultNodeHeight then
-      FRoot.TotalHeight := FDefaultNodeHeight;
-    FRangeY := FRoot.TotalHeight - FRoot.NodeHeight + FBottomSpace;
-
-    if FHeader.UseColumns then
-      FRangeX := FHeader.FColumns.TotalWidth
-    else
-      FRangeX := GetMaxRightExtend;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  procedure PrepareAnimation;
-
-  // Prepares ToggleData.
-
-  var
-    R: TRect;
-    S: Integer;
-    M: TToggleAnimationMode;
-
-  begin
-    with ToggleData do
-    begin
-      Window := Handle;
-      DC := GetDC(Handle);
-      //lcl: setting Color to Brush seems not necessary
-      //Self.Brush.Color := Color;
-      Brush := Self.Brush.Reference.Handle;
-
-      if (Mode1 <> tamNoScroll) and (Mode2 <> tamNoScroll) then
-      begin
-        if StepsR1 < StepsR2 then
-        begin
-          // As the primary rectangle is always R1 we will get a much smoother
-          // animation if R1 is the one that will be scrolled more.
-          R := R2;
-          R2 := R1;
-          R1 := R;
-
-          M := Mode2;
-          Mode2 := Mode1;
-          Mode1 := M;
-
-          S := StepsR2;
-          StepsR2 := StepsR1;
-          StepsR1 := S;
-        end;
-        ScaleFactor := StepsR2 / StepsR1;
-        MissedSteps := 0;
-      end;
-
-      if Mode1 <> tamNoScroll then
-        Steps := StepsR1
-      else
-        Steps := StepsR2;
-    end;
-  end;
-
-  //--------------- end local functions ---------------------------------------
-
-begin
-  Assert(Assigned(Node), 'Node must not be nil.');
-
-  TogglingTree := tsToggling in FStates;
-  ChildrenInView := False;
-  HeightDelta := 0;
-  NeedFullInvalidate := False;
-  NeedUpdate := False;
-  NodeInView := False;
-  PosHoldable := False;
-  TotalFit := False;
-
-  // We don't need to switch the expand state if the node is being deleted otherwise some
-  // updates (e.g. visible node count) are done twice with disasterous results).
-  if [vsDeleting, vsToggling] * Node.States = [] then
-  begin
-    try
-      DoStateChange([tsToggling]);
-      Include(Node.States, vsToggling);
-
-      if vsExpanded in Node.States then
-      begin
-        if DoCollapsing(Node) then
-        begin
-          NeedUpdate := True;
-
-          if (FUpdateCount = 0) and (toAnimatedToggle in FOptions.FAnimationOptions) and not
-             (tsCollapsing in FStates) then
-          begin
-            Application.CancelHint;
-            UpdateWindow(Handle);
-
-            // animated collapsing
-            with ToggleData do
-            begin
-              // Determine the animation behaviour and rectangle. If toChildrenAbove is set, the behaviour is depending
-              // on the position of the node to be collapsed.
-              R1 := GetDisplayRect(Node, NoColumn, False);
-              Mode2 := tamNoScroll;
-              HeightDelta := -Node.TotalHeight + NodeHeight[Node];
-              if toChildrenAbove in FOptions.FPaintOptions then
-              begin
-                PosHoldable := (FOffsetY + (Integer(Node.TotalHeight - NodeHeight[Node]))) <= 0;
-                NodeInView := R1.Top < ClientHeight;
-
-                StepsR1 := 0;
-                if NodeInView then
-                begin
-                  if PosHoldable or not (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) then
-                  begin
-                    // Scroll the child nodes down.
-                    Mode1 := tamScrollDown;
-                    R1.Bottom := R1.Top;
-                    R1.Top := 0;
-                    StepsR1 := Min(R1.Bottom - R1.Top + 1, Node.TotalHeight - NodeHeight[Node]);
-                  end
-                  else
-                  begin
-                    // The position cannot be kept. So scroll the node up to its future position.
-                    Mode1 := tamScrollUp;
-                    R1.Top := Max(0, R1.Top + HeightDelta);
-                    R1.Bottom := ClientHeight;
-                    StepsR1 := FOffsetY - HeightDelta;
-                  end;
-                end;
-              end
-              else
-              begin
-                if (Integer(FRangeY) + FOffsetY - R1.Bottom + HeightDelta >= ClientHeight - R1.Bottom) or
-                   (Integer(FRangeY) <= ClientHeight) or (FOffsetY = 0) or not
-                   (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) then
-                begin
-                  // Do a simple scroll up over the child nodes.
-                  Mode1 := tamScrollUp;
-                  Inc(R1.Top, NodeHeight[Node]);
-                  R1.Bottom := ClientHeight;
-                  StepsR1 := Min(R1.Bottom - R1.Top + 1, -HeightDelta);
-                end
-                else
-                begin
-                  // Scroll the node down to its future position. As FOffsetY will change we need to invalidate the
-                  // whole tree.
-                  Mode1 := tamScrollDown;
-                  StepsR1 := Min(-FOffsetY, ClientHeight - Integer(FRangeY) -FOffsetY - HeightDelta);
-                  R1.Top := 0;
-                  R1.Bottom := Min(ClientHeight, R1.Bottom + Steps);
-                  NeedFullInvalidate := True;
-                end;
-              end;
-
-              // No animation necessary if the node is below the current client height.
-              if R1.Top < ClientHeight then
-              begin
-                PrepareAnimation;
-                try
-                  Animate(Steps, FAnimationDuration, ToggleCallback, @ToggleData);
-                finally
-                  ReleaseDC(Window, DC);
-                end;
-              end;
-            end;
-          end;
-
-          // collapse the node
-          AdjustTotalHeight(Node, NodeHeight[Node]);
-          if FullyVisible[Node] then
-            Dec(FVisibleCount, CountVisibleChildren(Node));
-          Exclude(Node.States, vsExpanded);
-          DoCollapsed(Node);
-
-          // Remove child nodes now, if enabled.
-          if (toAutoFreeOnCollapse in FOptions.FAutoOptions) and (Node.ChildCount > 0) then
-          begin
-            DeleteChildren(Node);
-            Include(Node.States, vsHasChildren);
-          end;
-        end;
-      end
-      else
-        if DoExpanding(Node) then
-        begin
-          NeedUpdate := True;
-          // expand the node, need to adjust the height
-          if not (vsInitialized in Node.States) then
-            InitNode(Node);
-          if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then
-            InitChildren(Node);
-
-          // Avoid setting the vsExpanded style if there are no child nodes.
-          if Node.ChildCount > 0 then
-          begin
-            // Iterate through the child nodes without initializing them. We have to determine the entire height.
-            Child := Node.FirstChild;
-            repeat
-              if vsVisible in Child.States then
-                Inc(HeightDelta, Child.TotalHeight);
-              Child := Child.NextSibling;
-            until Child = nil;
-
-            // Getting the display rectangle is already done here as it is needed for toChildrenAbove in any case.
-            if (toChildrenAbove in FOptions.FPaintOptions) or (FUpdateCount = 0) then
-            begin
-              with ToggleData do
-              begin
-                R1 := GetDisplayRect(Node, NoColumn, False);
-                Mode2 := tamNoScroll;
-                TotalFit := HeightDelta + Integer(NodeHeight[Node]) <= ClientHeight;
-
-                if toChildrenAbove in FOptions.FPaintOptions then
-                begin
-                  // The main goal with toChildrenAbove being set is to keep the nodes visual position so the user does
-                  // not get confused. Therefore we need to scroll the view when the expanding is done.
-                  PosHoldable := TotalFit and (Integer(FRangeY) - ClientHeight >= 0) ;
-                  ChildrenInView := (R1.Top - HeightDelta) >= 0;
-                  NodeInView := R1.Bottom <= ClientHeight;
-                end
-                else
-                begin
-                  PosHoldable := TotalFit;
-                  ChildrenInView := R1.Bottom + HeightDelta <= ClientHeight;
-                end;
-
-                R1.Bottom := ClientHeight;
-              end;
-            end;
-
-            if FUpdateCount = 0 then
-            begin
-              // Do animated expanding if enabled.
-              if (ToggleData.R1.Top < ClientHeight) and ([tsPainting, tsExpanding] * FStates = []) and
-                (toAnimatedToggle in FOptions.FAnimationOptions)then
-              begin
-                Application.CancelHint;
-                UpdateWindow(Handle);
-                // animated expanding
-                with ToggleData do
-                begin
-                  if toChildrenAbove in FOptions.FPaintOptions then
-                  begin
-                    // At first check if we hold the position, which is the most common case.
-                    if not (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) or
-                       (PosHoldable and ( (NodeInView and ChildrenInView) or not
-                                          (toAutoScrollOnExpand in FOptions.FAutoOptions) )) then
-                    begin
-                      Mode1 := tamScrollUp;
-                      R1 := Rect(R1.Left, 0, R1.Right, R1.Top);
-                      StepsR1 := Min(HeightDelta, R1.Bottom);
-                    end
-                    else
-                    begin
-                      // If we will not hold the node's visual position we mostly scroll in both directions.
-                      Mode1 := tamScrollDown;
-                      Mode2 := tamScrollUp;
-                      R2 := Rect(R1.Left, 0, R1.Right, R1.Top);
-                      if not (toAutoScrollOnExpand in FOptions.FAutoOptions) then
-                      begin
-                        // If we shall not or cannot scroll to the desired extent we calculate the new position (with
-                        // max FOffsetY applied) and animate it that way.
-                        StepsR1 := -FOffsetY - Max(Integer(FRangeY) + HeightDelta - ClientHeight, 0) + HeightDelta;
-                        if (Integer(FRangeY) + HeightDelta - ClientHeight) <= 0 then
-                          Mode2 := tamNoScroll
-                        else
-                          StepsR2 := Min(Integer(FRangeY) + HeightDelta - ClientHeight, R2.Bottom);
-                      end
-                      else
-                      begin
-                        if TotalFit and NodeInView and (Integer(FRangeY) + HeightDelta > ClientHeight) then
-                        begin
-                          // If the whole subtree will fit into the client area and the node is currently fully visible,
-                          // the first child will be made the top node if possible.
-                          if HeightDelta >= R1.Top then
-                            StepsR1 := Abs(R1.Top - HeightDelta)
-                          else
-                            StepsR1 := ClientHeight - Integer(FRangeY);
-                        end
-                        else if Integer(FRangeY) + HeightDelta <= ClientHeight then
-                        begin
-                          // We cannot make the first child the top node as we cannot scroll to that extent,
-                          // so we do a simple scroll down.
-                          Mode2 := tamNoScroll;
-                          StepsR1 := HeightDelta;
-                        end
-                        else
-                          // If the subtree does not fit into the client area at once, the expanded node will
-                          // be made the bottom node.
-                          StepsR1 := ClientHeight - R1.Top - Integer(NodeHeight[Node]);
-
-                        if Mode2 <> tamNoScroll then
-                        begin
-                          if StepsR1 > 0 then
-                            StepsR2 := Min(R1.Top, HeightDelta - StepsR1)
-                          else
-                          begin
-                            // If the node is already at the bottom scrolling is needed.
-                            Mode1 := tamNoScroll;
-                            StepsR2 := Min(HeightDelta, R1.Bottom);
-                          end;
-                        end;
-                      end;
-                    end;
-                  end
-                  else
-                  begin
-                    // toChildrenAbove is not set.
-                    if (PosHoldable and ChildrenInView) or not (toAutoScrollOnExpand in FOptions.FAutoOptions) or not
-                       (toAdvancedAnimatedToggle in FOptions.FAnimationOptions) or (R1.Top <= 0) then
-                    begin
-                      // If the node will stay at its visual position, do a simple down-scroll.
-                      Mode1 := tamScrollDown;
-                      Inc(R1.Top, NodeHeight[Node]);
-                      StepsR1 := Min(R1.Bottom - R1.Top, HeightDelta);
-                    end
-                    else
-                    begin
-                      // We will not hold the nodes visual position so perform a double scroll.
-                      Mode1 := tamScrollUp;
-                      Mode2 := tamScrollDown;
-
-                      R1.Bottom := R1.Top + Integer(NodeHeight[Node]) + 1;
-                      R1.Top := 0;
-                      R2 := Rect(R1.Left, R1.Bottom, R1.Right, ClientHeight);
-
-                      StepsR1 := Min(HeightDelta - (ClientHeight - R2.Top), R1.Bottom - Integer(NodeHeight[Node]));
-                      StepsR2 := ClientHeight - R2.Top;
-                    end;
-                  end;
-
-                  if ClientHeight >= R1.Top then
-                  begin
-                    PrepareAnimation;
-                    try
-                      Animate(Steps, FAnimationDuration, ToggleCallback, @ToggleData);
-                    finally
-                      ReleaseDC(Window, DC);
-                    end;
-                  end;
-                end;
-              end;
-            end;
-
-            Include(Node.States, vsExpanded);
-            AdjustTotalHeight(Node, HeightDelta, True);
-            if FullyVisible[Node] then
-              Inc(FVisibleCount, CountVisibleChildren(Node));
-
-            DoExpanded(Node);
-          end;
-        end;
-
-      if NeedUpdate then
-      begin
-        InvalidateCache;
-        if FUpdateCount = 0 then
-        begin
-          ValidateCache;
-          if Node.ChildCount > 0 then
-          begin
-            UpdateRanges;
-
-            if [tsPainting, tsExpanding] * FStates = [] then
-            begin
-              if (vsExpanded in Node.States) and ((toAutoScrollOnExpand in FOptions.FAutoOptions) or
-                 (toChildrenAbove in FOptions.FPaintOptions)) then
-              begin
-                if toChildrenAbove in FOptions.FPaintOptions then
-                begin
-                  NeedFullInvalidate := True;
-                  if (PosHoldable and ChildrenInView and NodeInView) or not
-                     (toAutoScrollOnExpand in FOptions.FAutoOptions) then
-                    SetOffsetY(FOffsetY - Integer(HeightDelta))
-                  else if TotalFit and NodeInView then
-                    SetOffsetY(FOffsetY - GetDisplayRect(GetFirstVisible(Node, True), NoColumn, False).Top)
-                  else
-                    BottomNode := Node;
-                end
-                else
-                begin
-                  // Scroll as much child nodes into view as possible if the node has been expanded.
-                  if PosHoldable then
-                    NeedFullInvalidate := ScrollIntoView(GetLastVisible(Node, True), False)
-                  else
-                  begin
-                    TopNode := Node;
-                    NeedFullInvalidate := True;
-                  end;
-                end;
-              end
-              else
-              begin
-                // If we have collapsed the node or toAutoScrollOnExpand is not set, we try to keep the nodes
-                // visual position.
-                if toChildrenAbove in FOptions.FPaintOptions then
-                  SetOffsetY(FOffsetY - Integer(HeightDelta));
-                NeedFullInvalidate := True;
-              end;
-            end;
-
-            UpdateScrollbars(True);
-
-            // Check for automatically scrolled tree.
-            if NeedFullInvalidate then
-              Invalidate
-            else
-              InvalidateToBottom(Node);
-          end
-          else
-            InvalidateNode(Node);
-        end
-        else
-          UpdateRanges;
-      end;
-
-    finally
-      Exclude(Node.States, vsToggling);
-      if not TogglingTree then
-        DoStateChange([], [tsToggling]);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.UpdateAction(Action: TBasicAction): Boolean;
-
-// Support for standard actions.
-
-begin
-  if not Focused then
-    Result := inherited UpdateAction(Action)
-  else
-  begin
-    Result := (Action is TEditCut) or (Action is TEditCopy)
-       or (Action is TEditDelete);
-
-    if Result then
-      TAction(Action).Enabled := (FSelectionCount > 0) and
-        ((Action is TEditDelete) or (FClipboardFormats.Count > 0))
-    else
-    begin
-      Result := Action is TEditPaste;
-      if Result then
-        TAction(Action).Enabled := True
-      else
-      begin
-          Result := Action is TEditSelectAll;
-          if Result then
-            TAction(Action).Enabled := (toMultiSelect in FOptions.FSelectionOptions) and (FVisibleCount > 0)
-          else
-            Result := inherited UpdateAction(Action);
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UpdateHorizontalScrollBar(DoRepaint: Boolean);
-
-var
-  ScrollInfo: TScrollInfo;
-
-begin
-  if FHeader.UseColumns then
-    FRangeX := FHeader.FColumns.TotalWidth
-  else
-    FRangeX := GetMaxRightExtend;
-
-  if tsUpdating in FStates then
-    exit;
-
-  // Adjust effect scroll offset depending on bidi mode.
-  if UseRightToLeftAlignment then
-    FEffectiveOffsetX := Integer(FRangeX) - ClientWidth + FOffsetX
-  else
-    FEffectiveOffsetX := -FOffsetX;
-
-  if FScrollBarOptions.ScrollBars in [ssHorizontal, ssBoth] then
-  begin
-    FillChar(ScrollInfo, SizeOf(ScrollInfo), 0);
-    //LCL automatically set cbSize field
-    //ScrollInfo.cbSize := SizeOf(ScrollInfo);
-    ScrollInfo.fMask := SIF_ALL;
-    {$ifdef UseFlatScrollbars}
-      FlatSB_GetScrollInfo(Handle, SB_HORZ, ScrollInfo);
-    {$else}
-      GetScrollInfo(Handle, SB_HORZ, ScrollInfo);
-    {$endif UseFlatScrollbars}
-
-    if (Integer(FRangeX) > ClientWidth) or FScrollBarOptions.AlwaysVisible then
-    begin
-      DoShowScrollBar(SB_HORZ, True);
-
-      ScrollInfo.nMin := 0;
-      ScrollInfo.nMax := FRangeX;
-      ScrollInfo.nPos := FEffectiveOffsetX;
-      ScrollInfo.nPage := Max(0, ClientWidth);
-
-      ScrollInfo.fMask := SIF_ALL or ScrollMasks[FScrollBarOptions.AlwaysVisible];
-      {$ifdef UseFlatScrollbars}
-        FlatSB_SetScrollInfo(Handle, SB_HORZ, ScrollInfo, DoRepaint);
-      {$else}
-        SetScrollInfo(Handle, SB_HORZ, ScrollInfo, DoRepaint);
-      {$endif UseFlatScrollbars}
-    end
-    else
-    begin
-      ScrollInfo.nMin := 0;
-      ScrollInfo.nMax := 0;
-      ScrollInfo.nPos := 0;
-      ScrollInfo.nPage := 0;
-      DoShowScrollBar(SB_HORZ, False);
-      {$ifdef UseFlatScrollbars}
-        FlatSB_SetScrollInfo(Handle, SB_HORZ, ScrollInfo, False);
-      {$else}
-        SetScrollInfo(Handle, SB_HORZ, ScrollInfo, False);
-      {$endif UseFlatScrollbars}
-    end;
-
-    // Since the position is automatically changed if it doesn't meet the range
-    // we better read the current position back to stay synchronized.
-    {$ifdef UseFlatScrollbars}
-      FEffectiveOffsetX := FlatSB_GetScrollPos(Handle, SB_HORZ);
-    {$else}
-      //todo: Use get scrollinfo instead of GetScrollPos??
-      FEffectiveOffsetX := GetScrollPos(Handle, SB_HORZ);
-    {$endif UseFlatScrollbars}
-    if UseRightToLeftAlignment then
-      SetOffsetX(-Integer(FRangeX) + ClientWidth + FEffectiveOffsetX)
-    else
-      SetOffsetX(-FEffectiveOffsetX);
-  end
-  else
-  begin
-    DoShowScrollBar(SB_HORZ, False);
-
-    // Reset the current horizontal offset to account for window resize etc.
-    SetOffsetX(FOffsetX);
-  end;
-  {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'FEffectiveOffsetX after UpdateHScrollbar',FEffectiveOffsetX);{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UpdateScrollBars(DoRepaint: Boolean);
-
-// adjusts scrollbars to reflect current size and paint offset of the tree
-
-begin
-  if HandleAllocated then
-  begin
-    UpdateVerticalScrollBar(DoRepaint);
-    UpdateHorizontalScrollBar(DoRepaint);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.UpdateVerticalScrollBar(DoRepaint: Boolean);
-
-var
-  ScrollInfo: TScrollInfo;
-
-begin
-  // Total node height includes the height of the invisible root node.
-  if FRoot.TotalHeight < FDefaultNodeHeight then
-    FRoot.TotalHeight := FDefaultNodeHeight;
-  FRangeY := FRoot.TotalHeight - FRoot.NodeHeight + FBottomSpace;
-
-  if tsUpdating in FStates then
-    exit;
-
-  if FScrollBarOptions.ScrollBars in [ssVertical, ssBoth] then
-  begin
-    //LCL automatically set cbSize field
-    //ScrollInfo.cbSize := SizeOf(ScrollInfo);
-    ScrollInfo.fMask := SIF_ALL;
-    {$ifdef UseFlatScrollbars}
-      FlatSB_GetScrollInfo(Handle, SB_VERT, ScrollInfo);
-    {$else}
-      GetScrollInfo(Handle, SB_VERT, ScrollInfo);
-    {$endif UseFlatScrollbars}
-
-    if (Integer(FRangeY) > ClientHeight) or FScrollBarOptions.AlwaysVisible then
-    begin
-      DoShowScrollBar(SB_VERT, True);
-
-      ScrollInfo.nMin := 0;
-      ScrollInfo.nMax := FRangeY;
-      ScrollInfo.nPos := -FOffsetY;
-      ScrollInfo.nPage := Max(0, ClientHeight);
-
-      ScrollInfo.fMask := SIF_ALL or ScrollMasks[FScrollBarOptions.AlwaysVisible];
-      {$ifdef UseFlatScrollbars}
-        FlatSB_SetScrollInfo(Handle, SB_VERT, ScrollInfo, DoRepaint);
-      {$else}
-        SetScrollInfo(Handle, SB_VERT, ScrollInfo, DoRepaint);
-      {$endif UseFlatScrollbars}
-    end
-    else
-    begin
-      ScrollInfo.nMin := 0;
-      ScrollInfo.nMax := 0;
-      ScrollInfo.nPos := 0;
-      ScrollInfo.nPage := 0;
-      DoShowScrollBar(SB_VERT, False);
-      {$ifdef UseFlatScrollbars}
-        FlatSB_SetScrollInfo(Handle, SB_VERT, ScrollInfo, False);
-      {$else}
-        SetScrollInfo(Handle, SB_VERT, ScrollInfo, False);
-      {$endif UseFlatScrollbars}
-    end;
-
-    // Since the position is automatically changed if it doesn't meet the range
-    // we better read the current position back to stay synchronized.
-    {$ifdef UseFlatScrollbars}
-      SetOffsetY(-FlatSB_GetScrollPos(Handle, SB_VERT));
-    {$else}
-      SetOffsetY(-GetScrollPos(Handle, SB_VERT));
-    {$endif UseFlatScrollBars}
-  end
-  else
-  begin
-    DoShowScrollbar(SB_VERT, False);
-
-    // Reset the current vertical offset to account for window resize etc.
-    SetOffsetY(FOffsetY);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-//lcl: the current implementation in TControl is exactly equal to this.
-//     disable for now and reenable in the case the TControl implementation change
-{
-function TBaseVirtualTree.UseRightToLeftReading: Boolean;
-
-// The tree can handle right-to-left reading also on non-middle-east systems, so we cannot use the same function as
-// it is implemented in TControl.
-
-begin
-  Result := BiDiMode <> bdLeftToRight;
-end;
-}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ValidateChildren(Node: PVirtualNode; Recursive: Boolean);
-
-// Ensures that the children of the given node (and all their children, if Recursive is True) are initialized.
-// Node must already be initialized
-
-var
-  Child: PVirtualNode;
-
-begin
-  if Node = nil then
-    Node := FRoot;
-
-  if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then
-    InitChildren(Node);
-  Child := Node.FirstChild;
-  while Assigned(Child) do
-  begin
-    ValidateNode(Child, Recursive);
-    Child := Child.NextSibling;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TBaseVirtualTree.ValidateNode(Node: PVirtualNode; Recursive: Boolean);
-
-// Ensures that the given node (and all its children, if Recursive is True) are initialized.
-
-var
-  Child: PVirtualNode;
-
-begin
-  if Node = nil then
-    Node := FRoot
-  else
-    if not (vsInitialized in Node.States) then
-      InitNode(Node);
-
-  if Recursive then
-  begin
-    if (vsHasChildren in Node.States) and (Node.ChildCount = 0) then
-      InitChildren(Node);
-    Child := Node.FirstChild;
-    while Assigned(Child) do
-    begin
-      ValidateNode(Child, recursive);
-      Child := Child.NextSibling;
-    end;
-  end;
-end;
-
-//----------------- TCustomStringTreeOptions ---------------------------------------------------------------------------
-
-constructor TCustomStringTreeOptions.Create(AOwner: TBaseVirtualTree);
-
-begin
-  inherited;
-
-  FStringOptions := DefaultStringOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomStringTreeOptions.SetStringOptions(const Value: TVTStringOptions);
-
-var
-  ChangedOptions: TVTStringOptions;
-
-begin
-  if FStringOptions <> Value then
-  begin
-    // Exclusive ORing to get all entries wich are in either set but not in both.
-    ChangedOptions := FStringOptions + Value - (FStringOptions * Value);
-    FStringOptions := Value;
-    with FOwner do
-      if (toShowStaticText in ChangedOptions) and not (csLoading in ComponentState) and HandleAllocated then
-        Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomStringTreeOptions.AssignTo(Dest: TPersistent);
-
-begin
-  if Dest is TCustomStringTreeOptions then
-  begin
-    with TCustomStringTreeOptions(Dest) do
-      StringOptions := Self.StringOptions;
-  end;
-
-  // Let ancestors assign their options to the destination class.
-  inherited;
-end;
-
-//----------------- TVTEdit --------------------------------------------------------------------------------------------
-
-// Implementation of a generic node caption editor.
-
-constructor TVTEdit.Create(Link: TStringEditLink);
-
-begin
-  inherited Create(nil);
-  ShowHint := False;
-  ParentShowHint := False;
-  // This assignment increases the reference count for the interface.
-  FRefLink := Link;
-  // This reference is used to access the link.
-  FLink := Link;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.CMAutoAdjust(var Message: TLMessage);
-
-begin
-  AutoAdjustSize;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.CMExit(var Message: TLMessage);
-
-begin
-  if Assigned(FLink) and not FLink.FStopping then
-    with FLink, FTree do
-    begin
-      if (toAutoAcceptEditChange in TreeOptions.StringOptions) then
-        DoEndEdit
-      else
-        DoCancelEdit;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.CNCommand(var Message: TLMCommand);
-
-begin
-  if Assigned(FLink) and Assigned(FLink.FTree) and (Message.NotifyCode = EN_UPDATE) and
-    not (toGridExtensions in FLink.FTree.FOptions.FMiscOptions) and
-    not (vsMultiline in FLink.FNode.States) then
-    // Instead directly calling AutoAdjustSize it is necessary on Win9x/Me to decouple this notification message
-    // and eventual resizing. Hence we use a message to accomplish that.
-    if IsWinNT then
-      AutoAdjustSize
-    else
-      PostMessage(Handle, CM_AUTOADJUST, 0, 0);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.DoRelease(Data: PtrInt);
-begin
-  Free;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.WMChar(var Message: TLMChar);
-
-begin
-  if not (Message.CharCode in [VK_ESCAPE, VK_TAB]) then
-    inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.WMDestroy(var Message: TLMDestroy);
-
-begin
-  // If editing stopped by other means than accept or cancel then we have to do default processing for
-  // pending changes.
-  if Assigned(FLink) and not FLink.FStopping then
-  begin
-    with FLink, FTree do
-    begin
-      if (toAutoAcceptEditChange in TreeOptions.StringOptions) and Modified then
-        Text[FNode, FColumn] := FEdit.Text;
-    end;
-    FLink := nil;
-    FRefLink := nil;
-  end;
-
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.WMGetDlgCode(var Message: TLMNoParams);
-
-begin
-  inherited;
-
-  Message.Result := Message.Result or DLGC_WANTALLKEYS or DLGC_WANTTAB or DLGC_WANTARROWS;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.WMKeyDown(var Message: TLMKeyDown);
-
-// Handles some control keys.
-
-var
-  Shift: TShiftState;
-  EndEdit: Boolean;
-  Tree: TBaseVirtualTree;
-
-begin
-  case Message.CharCode of
-    VK_ESCAPE:
-      begin
-        Tree := FLink.FTree;
-        FLink.FTree.DoCancelEdit;
-        Tree.SetFocus;
-      end;
-    VK_RETURN:
-      begin
-        EndEdit := not (vsMultiline in FLink.FNode.States);
-        if not EndEdit then
-        begin
-          // If a multiline node is being edited the finish editing only if Ctrl+Enter was pressed,
-          // otherwise allow to insert line breaks into the text.
-          Shift := KeyDataToShiftState(Message.KeyData);
-          EndEdit := ssCtrlOS in Shift;
-        end;
-        if EndEdit then
-        begin
-          Tree := FLink.FTree;
-          FLink.FTree.InvalidateNode(FLink.FNode);
-          FLink.FTree.DoEndEdit;
-          Tree.SetFocus;
-        end;
-      end;
-    VK_UP:
-      begin
-        if not (vsMultiline in FLink.FNode.States) then
-          Message.CharCode := VK_LEFT;
-        inherited;
-      end;
-    VK_DOWN:
-      begin
-        if not (vsMultiline in FLink.FNode.States) then
-          Message.CharCode := VK_RIGHT;
-        inherited;
-      end;
-  else
-    inherited;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.AutoAdjustSize;
-
-// Changes the size of the edit to accomodate as much as possible of its text within its container window.
-// NewChar describes the next character which will be added to the edit's text.
-
-var
-  DC: HDC;
-  Size: TSize;
-  LastFont: THandle;
-
-begin
-  if not (vsMultiline in FLink.FNode.States) then
-  begin
-    DC := GetDC(Handle);
-    LastFont := SelectObject(DC, Font.Reference.Handle);
-    try
-      // Read needed space for the current text.
-      GetTextExtentPoint32(DC, PChar(Text), Length(Text), Size);
-      Inc(Size.cx, 2 * FLink.FTree.FTextMargin);
-
-      // Repaint associated node if the edit becomes smaller.
-      if Size.cx < Width then
-        FLink.FTree.InvalidateNode(FLink.FNode);
-
-      if FLink.FAlignment = taRightJustify then
-        FLink.SetBounds(Rect(Left + Width - Size.cx, Top, Left + Width, Top + Height))
-      else
-        FLink.SetBounds(Rect(Left, Top, Left + Size.cx, Top + Height));
-    finally
-      SelectObject(DC, LastFont);
-      ReleaseDC(Handle, DC);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.CreateParams(var Params: TCreateParams);
-
-begin
-  inherited;
-
-  // Only with multiline style we can use the text formatting rectangle.
-  // This does not harm formatting as single line control, if we don't use word wrapping.
-  with Params do
-  begin
-    //todo: delphi uses Multiline for all
-    //Style := Style or ES_MULTILINE;
-    if vsMultiline in FLink.FNode.States then
-    begin
-      Style := Style and not (ES_AUTOHSCROLL or WS_HSCROLL) or WS_VSCROLL or ES_AUTOVSCROLL;
-      Style := Style or ES_MULTILINE;
-    end;
-    if tsUseThemes in FLink.FTree.FStates then
-    begin
-      Style := Style and not WS_BORDER;
-      ExStyle := ExStyle or WS_EX_CLIENTEDGE;
-    end
-    else
-    begin
-      Style := Style or WS_BORDER;
-      ExStyle := ExStyle and not WS_EX_CLIENTEDGE;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTEdit.Release;
-
-begin
-  if HandleAllocated then
-    Application.QueueAsyncCall(DoRelease, 0);
-end;
-
-//----------------- TStringEditLink ------------------------------------------------------------------------------------
-
-constructor TStringEditLink.Create;
-
-begin
-  inherited;
-  FEdit := TVTEdit.Create(Self);
-  with FEdit do
-  begin
-    Visible := False;
-    BorderStyle := bsSingle;
-    AutoSize := False;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TStringEditLink.Destroy;
-
-begin
-  FEdit.Release;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TStringEditLink.BeginEdit: Boolean;
-
-// Notifies the edit link that editing can start now. descendants may cancel node edit
-// by returning False.
-
-begin
-  Result := not FStopping;
-  if Result then
-  begin
-    FEdit.Show;
-    FEdit.SelectAll;
-    FEdit.SetFocus;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TStringEditLink.SetEdit(const Value: TVTEdit);
-
-begin
-  if Assigned(FEdit) then
-    FEdit.Free;
-  FEdit := Value;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TStringEditLink.CancelEdit: Boolean;
-
-begin
-  Result := not FStopping;
-  if Result then
-  begin
-    FStopping := True;
-    FEdit.Hide;
-    FTree.CancelEditNode;
-    FEdit.FLink := nil;
-    FEdit.FRefLink := nil;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TStringEditLink.EndEdit: Boolean;
-
-begin
-  Result := not FStopping;
-  if Result then
-  try
-    FStopping := True;
-    if FEdit.Modified then
-      FTree.Text[FNode, FColumn] := FEdit.Text;
-    FEdit.Hide;
-    FEdit.FLink := nil;
-    FEdit.FRefLink := nil;
-  except
-    FStopping := False;
-    raise;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TStringEditLink.GetBounds: TRect;
-
-begin
-  Result := FEdit.BoundsRect;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TStringEditLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
-
-// Retrieves the true text bounds from the owner tree.
-
-var
-  Text: String;
-
-begin
-  Result := Tree is TCustomVirtualStringTree;
-  if Result then
-  begin
-    FTree := Tree as TCustomVirtualStringTree;
-    FNode := Node;
-    FColumn := Column;
-    // Initial size, font and text of the node.
-    FTree.GetTextInfo(Node, Column, FEdit.Font, FTextBounds, Text);
-    FEdit.Font.Color := clWindowText;
-    FEdit.Parent := Tree;
-    FEdit.HandleNeeded;
-    FEdit.Text := Text;
-
-    if Column <= NoColumn then
-    begin
-      FEdit.BidiMode := FTree.BidiMode;
-      FAlignment := FTree.Alignment;
-    end
-    else
-    begin
-      FEdit.BidiMode := FTree.Header.Columns[Column].BidiMode;
-      FAlignment := FTree.Header.Columns[Column].Alignment;
-    end;
-
-    if FEdit.BidiMode <> bdLeftToRight then
-      ChangeBidiModeAlignment(FAlignment);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TStringEditLink.ProcessMessage(var Message: TLMessage);
-
-begin
-  FEdit.WindowProc(Message);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TStringEditLink.SetBounds(R: TRect);
-
-// Sets the outer bounds of the edit control and the actual edit area in the control.
-
-var
-  Offset: Integer;
-
-begin
-  if not FStopping then
-  begin
-    with R do
-    begin
-      // Set the edit's bounds but make sure there's a minimum width and the right border does not
-      // extend beyond the parent's left/right border.
-      if Left < 0 then
-        Left := 0;
-      if Right - Left < 30 then
-      begin
-        if FAlignment = taRightJustify then
-          Left := Right - 30
-        else
-          Right := Left + 30;
-      end;
-      if Right > FTree.ClientWidth then
-        Right := FTree.ClientWidth;
-      FEdit.BoundsRect := R;
-
-      // The selected text shall exclude the text margins and be centered vertically.
-      // We have to take out the two pixel border of the edit control as well as a one pixel "edit border" the
-      // control leaves around the (selected) text.
-      R := FEdit.ClientRect;
-      Offset := 2;
-      if tsUseThemes in FTree.FStates then
-        Inc(Offset);
-      InflateRect(R, -FTree.FTextMargin + Offset, Offset);
-      if not (vsMultiline in FNode.States) then
-        OffsetRect(R, 0, FTextBounds.Top - FEdit.Top);
-
-      SendMessage(FEdit.Handle, EM_SETRECTNP, 0, PtrUInt(@R));
-    end;
-  end;
-end;
-
-//----------------- TCustomVirtualString -------------------------------------------------------------------------------
-
-constructor TCustomVirtualStringTree.Create(AOwner: TComponent);
-
-begin
-  inherited;
-  if (Owner = nil) or (([csReading, csDesigning] * Owner.ComponentState) = [csDesigning]) then
-    FDefaultText := 'Node';
-  FInternalDataOffset := AllocateInternalDataArea(SizeOf(Cardinal));
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.GetRenderStartValues(Source: TVSTTextSourceType; out Node: PVirtualNode;
-  out NextNodeProc: TGetNextNodeProc);
-
-begin
-  case Source of
-    tstInitialized:
-      begin
-        Node := GetFirstInitialized;
-        NextNodeProc := GetNextInitialized;
-      end;
-    tstSelected:
-      begin
-        Node := GetFirstSelected;
-        NextNodeProc := GetNextSelected;
-      end;
-    tstCutCopySet:
-      begin
-        Node := GetFirstCutCopy;
-        NextNodeProc := GetNextCutCopy;
-      end;
-    tstVisible:
-      begin
-        Node := GetFirstVisible(nil, True);
-        NextNodeProc := GetNextVisible;
-      end;
-  else // tstAll
-    Node := GetFirst;
-    NextNodeProc := GetNext;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.GetImageText(Node: PVirtualNode;
-  Kind: TVTImageKind; Column: TColumnIndex): String;
-begin
-  Assert(Assigned(Node), 'Node must not be nil.');
-
-  if not (vsInitialized in Node.States) then
-    InitNode(Node);
-  Result := '';
-
-  DoGetImageText(Node, Kind, Column, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.GetOptions: TCustomStringTreeOptions;
-
-begin
-  Result := FOptions as TCustomStringTreeOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.GetText(Node: PVirtualNode; Column: TColumnIndex): String;
-
-begin
-  Assert(Assigned(Node), 'Node must not be nil.');
-
-  if not (vsInitialized in Node.States) then
-    InitNode(Node);
-  Result := FDefaultText;
-
-  DoGetText(Node, Column, ttNormal, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.InitializeTextProperties(var PaintInfo: TVTPaintInfo);
-
-// Initializes default values for customization in PaintNormalText.
-
-begin
-  with PaintInfo do
-  begin
-    // Set default font values first.
-    Canvas.Font := Font;
-
-    if (toHotTrack in FOptions.FPaintOptions) and (Node = FCurrentHotNode) then
-    begin
-      if not IsWinVistaOrAbove or not (tsUseThemes in FStates) or
-         not (toUseExplorerTheme in FOptions.FPaintOptions) then
-        Canvas.Font.Style := Canvas.Font.Style + [fsUnderline];
-      Canvas.Font.Color := FColors.HotColor;
-    end;
-
-    // Change the font color only if the node also is drawn in selected style.
-    if poDrawSelection in PaintOptions then
-    begin
-      if (Column = FFocusedColumn) or (toFullRowSelect in FOptions.FSelectionOptions) then
-      begin
-        if Node = FDropTargetNode then
-        begin
-          if (FLastDropMode = dmOnNode) or (vsSelected in Node.States) and
-             (not IsWinVistaOrAbove or not (tsUseThemes in FStates) or
-              not (toUseExplorerTheme in FOptions.FPaintOptions)) then
-            Canvas.Font.Color := clHighlightText;
-        end
-        else
-          if vsSelected in Node.States then
-          begin
-            if (Focused or (toPopupMode in FOptions.FPaintOptions)) and
-               (not IsWinVistaOrAbove or not (tsUseThemes in FStates) or
-                not (toUseExplorerTheme in FOptions.FPaintOptions)) then
-              Canvas.Font.Color := clHighlightText;
-          end;
-      end;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.PaintNormalText(var PaintInfo: TVTPaintInfo; TextOutFlags: Integer;
-  Text: String);
-
-// This method is responsible for painting the given text to target canvas (under consideration of the given rectangles).
-// The text drawn here is considered as the normal text in a node.
-// Note: NodeWidth is the actual width of the text to be drawn. This does not necessarily correspond to the width of
-//       the node rectangle. The clipping rectangle comprises the entire node (including tree lines, buttons etc.).
-
-var
-  TripleWidth: Integer;
-  R: TRect;
-  DrawFormat: Cardinal;
-  Size: TSize;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'PaintNormalText') ;{$endif}
-  InitializeTextProperties(PaintInfo);
-  with PaintInfo do
-  begin
-    R := ContentRect;
-    //todo_lcl See how TextStyle should be set
-    //Canvas.TextFlags := 0;
-
-    // Multiline nodes don't need special font handling or text manipulation.
-    // Note: multiline support requires the Unicode version of DrawText, which is able to do word breaking.
-    //       The emulation in this unit does not support this so we have to use the OS version. However
-    //       DrawTextW is only available on NT/2000/XP and up. Hence there is only partial multiline support
-    //       for 9x/Me.
-    if vsMultiline in Node.States then
-    begin
-      InflateRect(R, -FTextMargin, 0);
-      DoPaintText(Node, Canvas, Column, ttNormal);
-      // Disabled node color overrides all other variants.
-      if (vsDisabled in Node.States) or not Enabled then
-        Canvas.Font.Color := FColors.DisabledColor;
-
-      // The edit control flag will ensure that no partial line is displayed, that is, only lines
-      // which are (vertically) fully visible are drawn.
-      DrawFormat := DT_NOPREFIX or DT_WORDBREAK or DT_END_ELLIPSIS or DT_EDITCONTROL or AlignmentToDrawFlag[Alignment];
-      if BidiMode <> bdLeftToRight then
-        DrawFormat := DrawFormat or DT_RTLREADING;
-    end
-    else
-    begin
-      InflateRect(R, -FTextMargin, 0);
-      FFontChanged := False;
-      TripleWidth := FEllipsisWidth;
-      DoPaintText(Node, Canvas, Column, ttNormal);
-      if FFontChanged then
-      begin
-        // If the font has been changed then the ellipsis width must be recalculated.
-        TripleWidth := 0;
-        // Recalculate also the width of the normal text.
-        GetTextExtentPoint32(Canvas.Handle, PChar(Text), Length(Text), Size);
-        NodeWidth := Size.cx + 2 * FTextMargin;
-      end;
-
-      // Disabled node color overrides all other variants.
-      if (vsDisabled in Node.States) or not Enabled then
-        Canvas.Font.Color := FColors.DisabledColor;
-
-      DrawFormat := DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE;
-      if BidiMode <> bdLeftToRight then
-        DrawFormat := DrawFormat or DT_RTLREADING;
-      // Check if the text must be shortend.
-      if (Column > -1) and ((NodeWidth - 2 * FTextMargin) > R.Right - R.Left) then
-      begin
-        Text := DoShortenString(Canvas, Node, Column, Text, R.Right - R.Left, TripleWidth);
-        if Alignment = taRightJustify then
-          DrawFormat := DrawFormat or DT_RIGHT
-        else
-          DrawFormat := DrawFormat or DT_LEFT;
-      end
-      else
-        DrawFormat := DrawFormat or AlignmentToDrawFlag[Alignment];
-    end;
-    //todo_lcl_check
-    if not Canvas.TextStyle.Opaque then
-      SetBkMode(Canvas.Handle, TRANSPARENT)
-    else
-      SetBkMode(Canvas.Handle, OPAQUE);
-    {$ifdef DEBUG_VTV}Logger.Send([lcPaintDetails],'Canvas.Brush.Color',Canvas.Brush.Color);{$endif}
-    DoTextDrawing(PaintInfo, Text, R, DrawFormat);
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintNormalText');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.PaintStaticText(const PaintInfo: TVTPaintInfo; TextOutFlags: Integer;
-  const Text: String);
-
-// This method retrives and draws the static text bound to a particular node.
-
-var
-  R: TRect;
-  DrawFormat: Cardinal;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'PaintStaticText');{$endif}
-  with PaintInfo do
-  begin
-    Canvas.Font := Font;
-    if toFullRowSelect in FOptions.FSelectionOptions then
-    begin
-      if Node = FDropTargetNode then
-      begin
-        if (FLastDropMode = dmOnNode) or (vsSelected in Node.States)then
-          Canvas.Font.Color := clHighlightText
-        else
-          Canvas.Font.Color := Font.Color;
-      end
-      else
-        if vsSelected in Node.States then
-        begin
-          if Focused or (toPopupMode in FOptions.FPaintOptions) then
-            Canvas.Font.Color := clHighlightText
-          else
-            Canvas.Font.Color := Font.Color;
-        end;
-    end;
-
-    DrawFormat := DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE;
-    //todo_lcl See how Canvas.TextStyle should be
-    //Canvas.TextFlags := 0;
-    DoPaintText(Node, Canvas, Column, ttStatic);
-
-    // Disabled node color overrides all other variants.
-    if (vsDisabled in Node.States) or not Enabled then
-      Canvas.Font.Color := FColors.DisabledColor;
-
-    R := ContentRect;
-    if Alignment = taRightJustify then
-      Dec(R.Right, NodeWidth + FTextMargin)
-    else
-      Inc(R.Left, NodeWidth + FTextMargin);
-    //todo_lcl_check
-    if not Canvas.TextStyle.Opaque then
-      SetBkMode(Canvas.Handle, TRANSPARENT)
-    else
-      SetBkMode(Canvas.Handle, OPAQUE);
-    DrawText(Canvas.Handle, PChar(Text), Length(Text), R, DrawFormat)
-  end;
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'PaintStaticText');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.SetDefaultText(const Value: String);
-
-begin
-  if FDefaultText <> Value then
-  begin
-    FDefaultText := Value;
-    if not (csLoading in ComponentState) then
-      Invalidate;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.SetOptions(const Value: TCustomStringTreeOptions);
-
-begin
-  FOptions.Assign(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.SetText(Node: PVirtualNode; Column: TColumnIndex; const Value: String);
-
-begin
-  DoNewText(Node, Column, Value);
-  InvalidateNode(Node);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.CMFontChanged(var Msg: TLMessage);
-
-// Whenever a new font is applied to the tree some default values are determined to avoid frequent
-// determination of the same value.
-
-var
-  MemDC: HDC;
-  Run: PVirtualNode;
-  TM: TTextMetric;
-  Size: TSize;
-  Data: PInteger;
-
-begin
-  inherited;
-  MemDC := CreateCompatibleDC(0);
-  try
-    SelectObject(MemDC, Font.Reference.Handle);
-    GetTextMetrics(MemDC, TM);
-    FTextHeight := TM.tmHeight;
-
-    GetTextExtentPoint32(MemDC, '...', 3, Size);
-    FEllipsisWidth := Size.cx;
-  finally
-    DeleteDC(MemDC);
-  end;
-
-  // Have to reset all node widths.
-  Run := FRoot.FirstChild;
-  while Assigned(Run) do
-  begin
-    Data := InternalData(Run);
-    if Assigned(Data) then
-      Data^ := 0;
-    Run := GetNextNoInit(Run);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.AdjustPaintCellRect(var PaintInfo: TVTPaintInfo; out NextNonEmpty: TColumnIndex);
-
-// In the case a node spans several columns (if enabled) we need to determine how many columns.
-// Note: the autospan feature can only be used with left-to-right layout.
-
-begin
-  if (toAutoSpanColumns in FOptions.FAutoOptions) and FHeader.UseColumns and (PaintInfo.BidiMode = bdLeftToRight) then
-    with FHeader.FColumns, PaintInfo do
-    begin
-      // Start with the directly following column.
-      NextNonEmpty := GetNextVisibleColumn(Column);
-
-      // Auto spanning columns can only be used for left-to-right directionality because the tree is drawn
-      // from left to right. For RTL directionality it would be necessary to draw it from right to left.
-      // While this could be managed, it becomes impossible when directionality is mixed.
-      repeat
-        if (NextNonEmpty = InvalidColumn) or not ColumnIsEmpty(Node, NextNonEmpty) or
-          (Items[NextNonEmpty].BidiMode <> bdLeftToRight) then
-          Break;
-        Inc(CellRect.Right, Items[NextNonEmpty].Width);
-        NextNonEmpty := GetNextVisibleColumn(NextNonEmpty);
-      until False;
-    end
-    else
-      inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.CalculateTextWidth(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: String): Integer;
-
-// Determines the width of the given text.
-
-begin
-  Result := 2 * FTextMargin;
-  if Length(Text) > 0 then
-  begin
-    Canvas.Font := Font;
-    DoPaintText(Node, Canvas, Column, ttNormal);
-
-    Inc(Result, DoTextMeasuring(Canvas, Node, Column, Text));
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ColumnIsEmpty(Node: PVirtualNode; Column: TColumnIndex): Boolean;
-
-// For hit tests it is necessary to consider cases where columns are empty and automatic column spanning is enabled.
-// This method simply checks the given column's text and if this is empty then the column is considered as being empty.
-
-begin
-  Result := Length(Text[Node, Column]) = 0;
-  // If there is no text then let the ancestor decide if the column is to be considered as being empty
-  // (e.g. by asking the application). If there is text then the column is never be considered as being empty.
-  if Result then
-    Result := inherited ColumnIsEmpty(Node, Column);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-{$ifndef LCLWin32}
-procedure TCustomVirtualStringTree.CopyToClipBoard;
-begin
-  if FSelectionCount > 0 then
-  begin
-    MarkCutCopyNodes;
-    DoStateChange([tsCopyPending]);
-    Clipboard.AsText := ContentToUTF8(tstCutCopySet, #9);
-    DoStateChange([], [tsCopyPending]);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.CutToClipBoard;
-begin
-  //todo: currently there's no way in LCL to know when the clipboard was used
-  CopyToClipBoard;
-end;
-{$endif}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.DoCreateEditor(Node: PVirtualNode; Column: TColumnIndex): IVTEditLink;
-
-begin
-  Result := inherited DoCreateEditor(Node, Column);
-  // Enable generic label editing support if the application does not have own editors.
-  if Result = nil then
-    Result := TStringEditLink.Create;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.DoGetNodeHint(Node: PVirtualNode; Column: TColumnIndex;
-  var LineBreakStyle: TVTTooltipLineBreakStyle): String;
-
-begin
-  Result := inherited DoGetNodeHint(Node, Column, LineBreakStyle);
-  if Assigned(FOnGetHint) then
-    FOnGetHint(Self, Node, Column, LineBreakStyle, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.DoGetNodeTooltip(Node: PVirtualNode; Column: TColumnIndex;
-  var LineBreakStyle: TVTTooltipLineBreakStyle): String;
-
-begin
-  Result := inherited DoGetNodeToolTip(Node, Column, LineBreakStyle);
-  if Assigned(FOnGetHint) then
-    FOnGetHint(Self, Node, Column, LineBreakStyle, Result)
-  else
-    Result := Text[Node, Column];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer;
-
-// Returns the text width of the given node in pixels.
-// This width is stored in the node's data member to increase access speed.
-
-var
-  Data: PInteger;
-
-begin
-  if (Column > NoColumn) and (vsMultiline in Node.States) then
-    Result := FHeader.Columns[Column].Width
-  else
-  begin
-    if Canvas = nil then
-      Canvas := Self.Canvas;
-
-    if Column = FHeader.MainColumn then
-    begin
-      // Primary column or no columns.
-      Data := InternalData(Node);
-      if Assigned(Data) then
-      begin
-        Result := Data^;
-        if Result = 0 then
-        begin
-          Data^ := CalculateTextWidth(Canvas, Node, Column, Text[Node, Column]);
-          Result := Data^;
-        end;
-      end
-      else
-        Result := 0;
-    end
-    else
-      // any other column
-      Result := CalculateTextWidth(Canvas, Node, Column, Text[Node, Column]);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.DoGetText(Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
-  var Text: String);
-
-begin
-  if Assigned(FOnGetText) then
-    FOnGetText(Self, Node, Column, TextType, Text);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.DoIncrementalSearch(Node: PVirtualNode; const Text: String): Integer;
-
-// Since the string tree has access to node text it can do incremental search on its own. Use the event to
-// override the default behavior.
-
-begin
-  Result := 0;
-  if Assigned(FOnIncrementalSearch) then
-    FOnIncrementalSearch(Self, Node, Text, Result)
-  else
-    // Default behavior is to match the search string with the start of the node text.
-    if Pos(Text, GetText(Node, FocusedColumn)) <> 1 then
-      Result := 1;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.DoNewText(Node: PVirtualNode; Column: TColumnIndex; const Text: String);
-
-begin
-  if Assigned(FOnNewText) then
-    FOnNewText(Self, Node, Column, Text);
-
-  // The width might have changed, so update the scrollbar.
-  if FUpdateCount = 0 then
-    UpdateHorizontalScrollBar(True);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.DoPaintNode(var PaintInfo: TVTPaintInfo);
-
-// Main output routine to print the text of the given node using the space provided in PaintInfo.ContentRect.
-
-var
-  S: String;
-  TextOutFlags: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.EnterMethod([lcPaintDetails],'TCustomVirtualStringTree.DoPaintNode');{$endif}
-  // Set a new OnChange event for the canvas' font so we know if the application changes it in the callbacks.
-  // This long winded procedure is necessary because font changes (as well as brush and pen changes) are
-  // unfortunately not announced via the Canvas.OnChange event.
-  RedirectFontChangeEvent(PaintInfo.Canvas);
-
-  // Determine main text direction as well as other text properties.
-  TextOutFlags := ETO_CLIPPED or RTLFlag[PaintInfo.BidiMode <> bdLeftToRight];
-  S := Text[PaintInfo.Node, PaintInfo.Column];
-
-  // Paint the normal text first...
-  if Length(S) > 0 then
-    PaintNormalText(PaintInfo, TextOutFlags, S);
-
-  // ... and afterwards the static text if not centered and the node is not multiline enabled.
-  if (Alignment <> taCenter) and not (vsMultiline in PaintInfo.Node.States) and (toShowStaticText in TreeOptions.FStringOptions) then
-  begin
-    S := '';
-    with PaintInfo do
-      DoGetText(Node, Column, ttStatic, S);
-    if Length(S) > 0 then
-      PaintStaticText(PaintInfo, TextOutFlags, S);
-  end;
-  RestoreFontChangeEvent(PaintInfo.Canvas);
-  {$ifdef DEBUG_VTV}Logger.ExitMethod([lcPaintDetails],'TCustomVirtualStringTree.DoPaintNode');{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.DoPaintText(Node: PVirtualNode; const Canvas: TCanvas; Column: TColumnIndex;
-  TextType: TVSTTextType);
-
-begin
-  if Assigned(FOnPaintText) then
-    FOnPaintText(Self, Canvas, Node, Column, TextType);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.DoShortenString(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
-  const S: String; Width: Integer; EllipsisWidth: Integer = 0): String;
-
-var
-  Done: Boolean;
-
-begin
-  Done := False;
-  if Assigned(FOnShortenString) then
-    FOnShortenString(Self, Canvas, Node, Column, S, Width, Result, Done);
-  if not Done then
-    Result := ShortenString(Canvas.Handle, S, Width, EllipsisWidth);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.DoTextDrawing(var PaintInfo: TVTPaintInfo; const Text: String; CellRect: TRect;
-  DrawFormat: Cardinal);
-
-var
-  DefaultDraw: Boolean;
-
-begin
-  DefaultDraw := True;
-  if Assigned(FOnDrawText) then
-    FOnDrawText(Self, PaintInfo.Canvas, PaintInfo.Node, PaintInfo.Column, Text, CellRect, DefaultDraw);
-  if DefaultDraw then
-    DrawText(PaintInfo.Canvas.Handle, PChar(Text), Length(Text), CellRect, DrawFormat);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.DoTextMeasuring(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
-  const Text: String): Integer;
-
-var
-  Size: TSize;
-  R: TRect;
-  DrawFormat: Integer;
-
-begin
-  GetTextExtentPoint32(Canvas.Handle, PChar(Text), Length(Text), Size);
-  if vsMultiLine in Node.States then
-  begin
-    DrawFormat := DT_CALCRECT or DT_NOPREFIX or DT_WORDBREAK or DT_END_ELLIPSIS or DT_EDITCONTROL or AlignmentToDrawFlag[Alignment];
-    if BidiMode <> bdLeftToRight then
-      DrawFormat := DrawFormat or DT_RTLREADING;
-
-    R := Rect(0, 0, Size.cx, MaxInt);
-    DrawText(Canvas.Handle, PChar(Text), Length(Text), R, DrawFormat);
-    Size.cx := R.Right - R.Left;
-  end;
-  Result := Size.cx;
-  if Assigned(FOnMeasureTextWidth) then
-    FOnMeasureTextWidth(Self, Canvas, Node, Column, Text, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.GetOptionsClass: TTreeOptionsClass;
-
-begin
-  Result := TCustomStringTreeOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.InternalData(Node: PVirtualNode): Pointer;
-
-begin
-  if (Node = FRoot) or (Node = nil) then
-    Result := nil
-  else
-    Result := PByte(Node) + FInternalDataOffset;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.MainColumnChanged;
-
-var
-  Run: PVirtualNode;
-  Data: PInteger;
-
-begin
-  inherited;
-
-  // Have to reset all node widths.
-  Run := FRoot.FirstChild;
-  while Assigned(Run) do
-  begin
-    Data := InternalData(Run);
-    if Assigned(Data) then
-      Data^ := 0;
-    Run := GetNextNoInit(Run);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ReadChunk(Stream: TStream; Version: Integer; Node: PVirtualNode; ChunkType,
-  ChunkSize: Integer): Boolean;
-
-// read in the caption chunk if there is one
-
-var
-  NewText: String;
-
-begin
-  case ChunkType of
-    CaptionChunk:
-      begin
-        NewText := '';
-        if ChunkSize > 0 then
-        begin
-          SetLength(NewText, ChunkSize);
-          Stream.Read(PChar(NewText)^, ChunkSize);
-        end;
-        // Do a new text event regardless of the caption content to allow removing the default string.
-        Text[Node, FHeader.MainColumn] := NewText;
-        Result := True;
-      end;
-  else
-    Result := inherited ReadChunk(Stream, Version, Node, ChunkType, ChunkSize);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.RenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-  ForClipboard: Boolean): HResult;
-
-// Returns string expressions of all currently selected nodes in the Medium structure.
-
-begin
-  Result := inherited RenderOLEData(FormatEtcIn, Medium, ForClipboard);
-  if Failed(Result) then
-  try
-    if ForClipboard then
-      Medium.hGlobal := ContentToClipboard(FormatEtcIn.cfFormat, tstCutCopySet)
-    else
-      Medium.hGlobal := ContentToClipboard(FormatEtcIn.cfFormat, tstSelected);
-
-    // Fill rest of the Medium structure if rendering went fine.
-    if Medium.hGlobal <> 0 then
-    begin
-      Medium.tymed := TYMED_HGLOBAL;
-      Medium.PunkForRelease := nil;
-
-      Result := S_OK;
-    end;
-  except
-    Result := E_FAIL;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.WriteChunks(Stream: TStream; Node: PVirtualNode);
-
-// Adds another sibling chunk for Node storing the label if the node is initialized.
-// Note: If the application stores a node's caption in the node's data member (which will be quite common) and needs to
-//       store more node specific data then it should use the OnSaveNode event rather than the caption autosave function
-//       (take out soSaveCaption from StringOptions). Otherwise the caption is unnecessarily stored twice.
-
-var
-  Header: TChunkHeader;
-  S: String;
-  Len: Integer;
-
-begin
-  inherited;
-  if (toSaveCaptions in TreeOptions.FStringOptions) and (Node <> FRoot) and
-    (vsInitialized in Node.States) then
-    with Stream do
-    begin
-      // Read the node's caption (primary column only).
-      S := Text[Node, FHeader.MainColumn];
-      Len := Length(S);
-      if Len > 0 then
-      begin
-        // Write a new sub chunk.
-        Header.ChunkType := CaptionChunk;
-        Header.ChunkSize := Len;
-        Write(Header, SizeOf(Header));
-        Write(PChar(S)^, Len);
-      end;
-    end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ComputeNodeHeight(Canvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
-  S: String): Integer;
-
-// Default node height calculation for multi line nodes. This method can be used by the application to delegate the
-// computation to the string tree.
-// Canvas is used to compute that value by using its current font settings.
-// Node and Column describe the cell to be used for the computation.
-// S is the string for which the height must be computed. If this string is empty the cell text is used instead.
-
-var
-  DrawFormat: Cardinal;
-  BidiMode: TBidiMode;
-  Alignment: TAlignment;
-  PaintInfo: TVTPaintInfo;
-  Dummy: TColumnIndex;
-  LineImage: TLineImage;
-
-begin
-  if Length(S) = 0 then
-    S := Text[Node, Column];
-  DrawFormat := DT_TOP or DT_NOPREFIX or DT_CALCRECT or DT_WORDBREAK;
-  if Column <= NoColumn then
-  begin
-    BidiMode := Self.BidiMode;
-    Alignment := Self.Alignment;
-  end
-  else
-  begin
-    BidiMode := Header.Columns[Column].BidiMode;
-    Alignment := Header.Columns[Column].Alignment;
-  end;
-
-  if BidiMode <> bdLeftToRight then
-    ChangeBidiModeAlignment(Alignment);
-
-  // Allow for autospanning.
-  PaintInfo.Node := Node;
-  PaintInfo.BidiMode := BidiMode;
-  PaintInfo.Column := Column;
-  PaintInfo.CellRect := Rect(0, 0, 0, 0);
-  if Column > NoColumn then
-	begin
-	  PaintInfo.CellRect.Right := FHeader.Columns[Column].Width - FTextMargin;
-	  PaintInfo.CellRect.Left := FTextMargin + FMargin;
-	  if Column = Header.MainColumn then
-	  begin
-	    if toFixedIndent in FOptions.FPaintOptions then
-	      SetLength(LineImage, 1)
-	    else
-	      DetermineLineImageAndSelectLevel(Node, LineImage);
-	    Inc(PaintInfo.CellRect.Left, Length(LineImage) * Integer(Indent));
-	  end;
-	end
-  else
-    PaintInfo.CellRect.Right := ClientWidth;
-  AdjustPaintCellRect(PaintInfo, Dummy);
-
-  if BidiMode <> bdLeftToRight then
-    DrawFormat := DrawFormat or DT_RIGHT or DT_RTLREADING
-  else
-    DrawFormat := DrawFormat or DT_LEFT;
-  DrawText(Canvas.Handle, PChar(S), Length(S), PaintInfo.CellRect, DrawFormat);
-  Result := PaintInfo.CellRect.Bottom - PaintInfo.CellRect.Top;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ContentToHTML(Source: TVSTTextSourceType; const Caption: String = ''): String;
-
-// Renders the current tree content (depending on Source) as HTML text encoded in UTF-8.
-// If Caption is not empty then it is used to create and fill the header for the table built here.
-// Based on ideas and code from Frank van den Bergh and Andreas H?rstemeier.
-
-var
-  Buffer: TBufferedUTF8String;
-
-  //---------------------------------------------------------------------------
-
-  procedure WriteColorAsHex(Color: TColor);
-
-  var
-    WinColor: COLORREF;
-    I: Integer;
-    Component,
-    Value: Byte;
-
-  begin
-    Buffer.Add('#');
-    WinColor := ColorToRGB(Color);
-    I := 1;
-    while I <= 6 do
-    begin
-      Component := WinColor and $FF;
-
-      Value := 48 + (Component shr 4);
-      if Value > $39 then
-        Inc(Value, 7);
-      Buffer.Add(AnsiChar(Value));
-      Inc(I);
-
-      Value := 48 + (Component and $F);
-      if Value > $39 then
-        Inc(Value, 7);
-      Buffer.Add(AnsiChar(Value));
-      Inc(I);
-
-      WinColor := WinColor shr 8;
-    end;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  procedure WriteStyle(const Name: AnsiString; Font: TFont);
-
-  // Creates a CSS style entry with the given name for the given font.
-  // If Name is empty then the entry is created as inline style.
-
-  begin
-    if Length(Name) = 0 then
-      Buffer.Add(' style="{font:')
-    else
-    begin
-      Buffer.Add('.');
-      Buffer.Add(Name);
-      Buffer.Add('{font:');
-    end;
-    if fsUnderline in Font.Style then
-      Buffer.Add(' underline');
-    if fsItalic in Font.Style then
-      Buffer.Add(' italic');
-    if fsBold in Font.Style then
-      Buffer.Add(' bold');
-    if Font.Size < 0 then
-      Buffer.Add(Format(' %dpx "%s";', [Font.Height, Font.Name]))
-    else
-      Buffer.Add(Format(' %dpt "%s";', [Font.Size, Font.Name]));
-    Buffer.Add('color:');
-    WriteColorAsHex(Font.Color);
-    Buffer.Add(';}');
-    if Length(Name) = 0 then
-      Buffer.Add('"');
-  end;
-
-  //--------------- end local functions ---------------------------------------
-
-var
-  I, J : Integer;
-  Level, MaxLevel: Cardinal;
-  AddHeader: String;
-  Save, Run: PVirtualNode;
-  GetNextNode: TGetNextNodeProc;
-  Text: String;
-
-  RenderColumns: Boolean;
-  Columns: TColumnsArray;
-  ColumnColors: array of String;
-  Index: Integer;
-  IndentWidth,
-  LineStyleText: String;
-  Alignment: TAlignment;
-  BidiMode: TBidiMode;
-
-  CellPadding: String;
-
-begin
-  Buffer := TBufferedUTF8String.Create;
-  try
-    // For customization by the application or descendants we use again the redirected font change event.
-    RedirectFontChangeEvent(Canvas);
-
-    CellPadding := Format('padding-left:%dpx;padding-right:%0:dpx;', [FMargin]);
-
-    IndentWidth := IntToStr(FIndent);
-    AddHeader := ' ';
-    // Add title if adviced so by giving a caption.
-    if Length(Caption) > 0 then
-      AddHeader := AddHeader + 'caption="' + Caption + '"';
-    if Borderstyle <> bsNone then
-      AddHeader := AddHeader + Format(' border="%d" frame=box', [BorderWidth + 1]);
-
-    Buffer.Add('<META http-equiv="Content-Type" content="text/html; charset=utf-8">');
-      
-    // Create HTML table based on the tree structure. To simplify formatting we use styles defined in a small CSS area.
-    Buffer.Add('<style type="text/css">');
-    Buffer.AddNewLine;
-    WriteStyle('default', Font);
-    Buffer.AddNewLine;
-    WriteStyle('header', FHeader.Font);
-    Buffer.AddNewLine;
-
-    // Determine grid/table lines and create CSS for it.
-    // Vertical and/or horizontal border to show.
-    if FLineStyle = lsSolid then
-      LineStyleText := 'solid;'
-    else
-      LineStyleText := 'dotted;';
-    if toShowHorzGridLines in FOptions.FPaintOptions then
-    begin
-      Buffer.Add('.noborder{border-style:');
-      Buffer.Add(LineStyleText);
-      Buffer.Add(' border-bottom:1;border-left:0;border-right:0; border-top:0;');
-      Buffer.Add(CellPadding);
-      Buffer.Add('}');
-    end
-    else
-    begin
-      Buffer.Add('.noborder{border-style:none;');
-      Buffer.Add(CellPadding);
-      Buffer.Add('}');
-    end;
-    Buffer.AddNewLine;
-
-    Buffer.Add('.normalborder {border-top:none; border-left:none; vertical-align:top;');
-    if toShowVertGridLines in FOptions.FPaintOptions then
-      Buffer.Add('border-right:1 ' + LineStyleText)
-    else
-      Buffer.Add('border-right:none;');
-    if toShowHorzGridLines in FOptions.FPaintOptions then
-      Buffer.Add('border-bottom:1 ' + LineStyleText)
-    else
-      Buffer.Add('border-bottom:none;');
-    Buffer.Add(CellPadding);
-    Buffer.Add('}');
-    Buffer.Add('</style>');
-    Buffer.AddNewLine;
-
-    // General table properties.
-    Buffer.Add('<table class="default" bgcolor=');
-    WriteColorAsHex(Color);
-    Buffer.Add(AddHeader);
-    Buffer.Add(' cellspacing="0" cellpadding=');
-    Buffer.Add(IntToStr(FMargin) + '>');
-    Buffer.AddNewLine;
-
-    Columns := nil;
-    ColumnColors := nil;
-    RenderColumns := FHeader.UseColumns;
-    if RenderColumns then
-    begin
-      Columns := FHeader.FColumns.GetVisibleColumns;
-      SetLength(ColumnColors, Length(Columns));
-    end;
-
-    GetRenderStartValues(Source, Run, GetNextNode);
-    Save := Run;
-
-    MaxLevel := 0;
-    // The table consists of visible columns and rows as used in the tree, but the main tree column is splitted
-    // into several HTML columns to accomodate the indentation.
-    while Assigned(Run) do
-    begin
-      if (CanExportNode(Run)) then
-      begin
-          Level := GetNodeLevel(Run);
-          if Level > MaxLevel then
-            MaxLevel := Level;
-      end;
-      Run := GetNextNode(Run);
-    end;
-
-    if RenderColumns then
-    begin
-      if Assigned(FOnBeforeHeaderExport) then
-        FOnBeforeHeaderExport(Self, etHTML);
-      Buffer.Add('<tr class="header" style="');
-      Buffer.Add(CellPadding);
-      Buffer.Add('">');
-      Buffer.AddNewLine;
-      // Make the first row in the HTML table an image of the tree header.
-      for I := 0 to High(Columns) do
-      begin
-        if Assigned(FOnBeforeColumnExport) then
-            FOnBeforeColumnExport(Self, etHTML, Columns[I]);
-        Buffer.Add('<th height="');
-        Buffer.Add(IntToStr(FHeader.FHeight));
-        Buffer.Add('px"');
-        Alignment := Columns[I].CaptionAlignment;
-        // Consider directionality.
-        if Columns[I].FBiDiMode <> bdLeftToRight then
-        begin
-          ChangeBidiModeAlignment(Alignment);
-          Buffer.Add(' dir="rtl"');
-        end;
-
-          // Consider aligment.
-        case Alignment of
-          taRightJustify:
-            Buffer.Add(' align=right');
-          taCenter:
-            Buffer.Add(' align=center');
-        else
-          Buffer.Add(' align=left');
-        end;
-
-        Index := Columns[I].Index;
-        // Merge cells of the header emulation in the main column.
-        if (MaxLevel > 0) and (Index = Header.MainColumn) then
-        begin
-          Buffer.Add(' colspan="');
-          Buffer.Add(IntToStr(MaxLevel + 1));
-          Buffer.Add('"');
-        end;
-
-        // The color of the header is usually clBtnFace.
-        Buffer.Add(' bgcolor=');
-        WriteColorAsHex(clBtnFace);
-
-        // Set column width in pixels.
-        Buffer.Add(' width="');
-        Buffer.Add(IntToStr(Columns[I].Width));
-        Buffer.Add('px">');
-
-        if Length(Columns[I].Text) > 0 then
-          Buffer.Add(Columns[I].Text);
-        Buffer.Add('</th>');
-        if Assigned(FOnAfterColumnExport) then
-            FOnAfterColumnExport(Self, etHTML, Columns[I]);
-      end;
-      Buffer.Add('</tr>');
-      Buffer.AddNewLine;
-      if Assigned(FOnAfterHeaderExport) then
-        FOnAfterHeaderExport(self, etHTML);
-    end;
-  
-    // Now go through the tree.
-    Run := Save;
-    while Assigned(Run) do
-    begin
-      if ((not CanExportNode(Run)) or (Assigned(FonBeforeNodeExport) and (not FOnBeforeNodeExport(Self, etHTML, Run)))) then
-      begin
-        Run := GetNextNode(Run);
-        Continue;
-      end;
-      Level := GetNodeLevel(Run);
-      Buffer.Add(' <tr class="default">');
-      Buffer.AddNewLine;
-
-      I := 0;
-      while (I < Length(Columns)) or not RenderColumns do
-      begin
-        if RenderColumns then
-          Index := Columns[I].Index
-        else
-          Index := NoColumn;
-
-        if not RenderColumns or (coVisible in Columns[I].FOptions) then
-        begin
-          // Call back the application to know about font customization.
-          Canvas.Font := Font;
-          FFontChanged := False;
-          DoPaintText(Run, Canvas, Index, ttNormal);
-
-          if Index = Header.MainColumn then
-          begin
-            // Create a cell for each indentation level.
-            if RenderColumns and not (coParentColor in Columns[I].FOptions) then
-            begin
-              for J := 1 to Level do
-              begin
-                Buffer.Add('<td class="noborder" width="');
-                Buffer.Add(IndentWidth);
-                Buffer.Add('" height="');
-                Buffer.Add(IntToStr(NodeHeight[Run]));
-                Buffer.Add('px"');
-                if not (coParentColor in Columns[I].FOptions) then
-                begin
-                  Buffer.Add(' bgcolor=');
-                  WriteColorAsHex(Columns[I].Color);
-                end;
-                Buffer.Add('>&nbsp;</td>');
-              end;
-            end
-            else
-            begin
-              for J := 1 to Level do
-                if J = 1 then
-                begin
-                  Buffer.Add(' <td height="');
-                  Buffer.Add(IntToStr(NodeHeight[Run]));
-                  Buffer.Add('px">&nbsp;</td>');
-                end
-                else
-                  Buffer.Add(' <td>&nbsp;</td>');
-            end;
-          end;
-
-          if FFontChanged then
-          begin
-            Buffer.Add(' <td class="normalborder" ');
-            WriteStyle('', Canvas.Font);
-            Buffer.Add(' height="');
-            Buffer.Add(IntToStr(NodeHeight[Run]));
-            Buffer.Add('px"');
-          end
-          else
-          begin
-            Buffer.Add(' <td class="normalborder"  height="');
-            Buffer.Add(IntToStr(NodeHeight[Run]));
-            Buffer.Add('px"');
-          end;
-
-          if RenderColumns then
-          begin
-            Alignment := Columns[I].Alignment;
-            BidiMode := Columns[I].BidiMode;
-          end
-          else
-          begin
-            Alignment := Self.Alignment;
-            BidiMode := Self.BidiMode;
-          end;
-          // Consider directionality.
-          if BiDiMode <> bdLeftToRight then
-          begin
-            ChangeBidiModeAlignment(Alignment);
-            Buffer.Add(' dir="rtl"');
-          end;
-
-          // Consider aligment.
-          case Alignment of
-            taRightJustify:
-              Buffer.Add(' align=right');
-            taCenter:
-              Buffer.Add(' align=center');
-          else
-            Buffer.Add(' align=left');
-          end;
-          // Merge cells in the main column.
-          if (MaxLevel > 0) and (Index = FHeader.MainColumn) and (Level < MaxLevel) then
-          begin
-            Buffer.Add(' colspan="');
-            Buffer.Add(IntToStr(MaxLevel - Level + 1));
-            Buffer.Add('"');
-          end;
-          if RenderColumns and not (coParentColor in Columns[I].FOptions) then
-          begin
-            Buffer.Add(' bgcolor=');
-            WriteColorAsHex(Columns[I].Color);
-          end;
-          Buffer.Add('>');
-          Text := Self.Text[Run, Index];
-          if Length(Text) > 0 then
-            Buffer.Add(Text);
-          Buffer.Add('</td>');
-        end;
-
-        if not RenderColumns then
-          Break;
-        Inc(I);
-      end;
-      if Assigned(FOnAfterNodeExport) then
-        FOnAfterNodeExport(Self, etHTML, Run);
-      Run := GetNextNode(Run);
-      Buffer.Add(' </tr>');
-      Buffer.AddNewLine;
-    end;
-    Buffer.Add('</table>');
-
-    RestoreFontChangeEvent(Canvas);
-
-    Result := Buffer.AsUTF8String;
-  finally
-    Buffer.Free;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.CanExportNode(Node: PVirtualNode ): Boolean;
-
-begin
-  Result := True;
-  case FOptions.ExportMode of
-    emChecked:
-      Result := Node.CheckState = csCheckedNormal;
-    emUnchecked:
-      Result := Node.CheckState = csUncheckedNormal;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ContentToRTF(Source: TVSTTextSourceType): AnsiString;
-
-// Renders the current tree content (depending on Source) as RTF (rich text).
-// Based on ideas and code from Frank van den Bergh and Andreas H?rstemeier.
-
-var
-  Fonts: TStringList;
-  Colors: TFpList;
-  CurrentFontIndex,
-  CurrentFontColor,
-  CurrentFontSize: Integer;
-  Buffer: TBufferedUTF8String;
-
-  //--------------- local functions -------------------------------------------
-
-  procedure SelectFont(Font: string);
-
-  var
-    I: Integer;
-
-  begin
-    I := Fonts.IndexOf(Font);
-    if I > -1 then
-    begin
-      // Font has already been used
-      if I <> CurrentFontIndex then
-      begin
-        Buffer.Add('\f');
-        Buffer.Add(IntToStr(I));
-        CurrentFontIndex := I;
-      end;
-    end
-    else
-    begin
-      I := Fonts.Add(Font);
-      Buffer.Add('\f');
-      Buffer.Add(IntToStr(I));
-      CurrentFontIndex := I;
-    end;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  procedure SelectColor(Color: TColor);
-
-  var
-    I: Integer;
-
-  begin
-    I := Colors.IndexOf(Pointer(Color));
-    if I > -1 then
-    begin
-      // Color has already been used
-      if I <> CurrentFontColor then
-      begin
-        Buffer.Add('\cf');
-        Buffer.Add(IntToStr(I + 1));
-        CurrentFontColor := I;
-      end;
-    end
-    else
-    begin
-      I := Colors.Add(Pointer(Color));
-      Buffer.Add('\cf');
-      Buffer.Add(IntToStr(I + 1));
-      CurrentFontColor := I;
-    end;
-  end;
-
-  //---------------------------------------------------------------------------
-
-  procedure TextPlusFont(const Text: String; Font: TFont);
-
-  var
-    UseUnderline,
-    UseItalic,
-    UseBold: Boolean;
-    I: Integer;
-    WText: UnicodeString;
-  begin
-    if Length(Text) > 0 then
-    begin
-      WText := UTF8Decode(Text);
-      UseUnderline := fsUnderline in Font.Style;
-      if UseUnderline then
-        Buffer.Add('\ul');
-      UseItalic := fsItalic in Font.Style;
-      if UseItalic then
-        Buffer.Add('\i');
-      UseBold := fsBold in Font.Style;
-      if UseBold then
-        Buffer.Add('\b');
-      SelectFont(Font.Name);
-      SelectColor(Font.Color);
-      if Font.Size <> CurrentFontSize then
-      begin
-        // Font size must be given in half points.
-        Buffer.Add('\fs');
-        Buffer.Add(IntToStr(2 * Font.Size));
-        CurrentFontSize := Font.Size;
-      end;
-      // Use escape sequences to note Unicode text.
-      Buffer.Add(' ');
-      // Note: Unicode values > 32767 must be expressed as negative numbers. This is implicitly done
-      //       by interpreting the wide chars (word values) as small integers.
-      for I := 1 to Length(WText) do
-      begin
-        if (Text[I] = WideLF) then
-          Buffer.Add( '{\par}' )
-        else if (Text[i] <> WideCR) then
-        begin
-          Buffer.Add(Format('\u%d\''3f', [SmallInt(WText[I])]));
-          Continue;
-        end;
-      end;
-      if UseUnderline then
-        Buffer.Add('\ul0');
-      if UseItalic then
-        Buffer.Add('\i0');
-      if UseBold then
-        Buffer.Add('\b0');
-    end;
-  end;
-
-  //--------------- end local functions ---------------------------------------
-
-var
-  Level, LastLevel: Integer;
-  I, J: Integer;
-  Save, Run: PVirtualNode;
-  GetNextNode: TGetNextNodeProc;
-  S, Tabs : String;
-  Text: String;
-  Twips: Integer;
-
-  RenderColumns: Boolean;
-  Columns: TColumnsArray;
-  Index: Integer;
-  Alignment: TAlignment;
-  BidiMode: TBidiMode;
-
-begin
-  Buffer := TBufferedUTF8String.Create;
-  try
-    // For customization by the application or descendants we use again the redirected font change event.
-    RedirectFontChangeEvent(Canvas);
-
-    Fonts := TStringList.Create;
-    Colors := TFpList.Create;
-    CurrentFontIndex := -1;
-    CurrentFontColor := -1;
-    CurrentFontSize := -1;
-
-    Columns := nil;
-    Tabs := '';
-    LastLevel := 0;
-
-    RenderColumns := FHeader.UseColumns;
-    if RenderColumns then
-      Columns := FHeader.FColumns.GetVisibleColumns;
-
-    GetRenderStartValues(Source, Run, GetNextNode);
-    Save := Run;
-
-    // First make a table structure. The \rtf and other header stuff is included
-    // when the font and color tables are created.
-    Buffer.Add('\uc1\trowd\trgaph70');
-    J := 0;
-    if RenderColumns then
-    begin
-      for I := 0 to High(Columns) do
-      begin
-        Inc(J, Columns[I].Width);
-        // This value must be expressed in twips (1 inch = 1440 twips).
-        Twips := Round(1440 * J / Screen.PixelsPerInch);
-        Buffer.Add('\cellx');
-        Buffer.Add(IntToStr(Twips));
-      end;
-    end
-    else
-    begin
-      Twips := Round(1440 * ClientWidth / Screen.PixelsPerInch);
-      Buffer.Add('\cellx');
-      Buffer.Add(IntToStr(Twips));
-    end;
-
-    // Fill table header.
-    if RenderColumns then
-    begin
-      if Assigned(FOnBeforeHeaderExport) then
-        FonBeforeHeaderExport(Self, etRTF);
-      Buffer.Add('\pard\intbl');
-      for I := 0 to High(Columns) do
-      begin
-        if Assigned(FOnBeforeColumnExport) then
-          FOnBeforeColumnExport(Self, etRTF, Columns[I]);
-        Alignment := Columns[I].CaptionAlignment;
-        BidiMode := Columns[I].BidiMode;
-
-        // Alignment is not supported with older RTF formats, however it will be ignored.
-        if BidiMode <> bdLeftToRight then
-          ChangeBidiModeAlignment(Alignment);
-        case Alignment of
-          taRightJustify:
-            Buffer.Add('\qr');
-          taCenter:
-            Buffer.Add('\qc');
-        end;
-
-        TextPlusFont(Columns[I].Text, Header.Font);
-        Buffer.Add('\cell');
-        if Assigned(FOnAfterColumnExport) then
-          FOnAfterColumnExport( self, etRTF, Columns[I] );
-      end;
-      Buffer.Add('\row');
-      if Assigned(FOnAfterHeaderExport) then
-        FOnAfterHeaderExport(Self, etRTF);
-    end;
-
-    // Now write the contents.
-    Run := Save;
-    while Assigned(Run) do
-    begin
-      if ((not CanExportNode(Run)) or
-         (Assigned(FOnBeforeNodeExport) and (not FOnBeforeNodeExport(Self, etRTF, Run)))) then
-      begin
-        Run := GetNextNode(Run);
-        Continue;
-      end;
-      I := 0;
-      while not RenderColumns or (I < Length(Columns)) do
-      begin
-        if RenderColumns then
-        begin
-          Index := Columns[I].Index;
-          Alignment := Columns[I].Alignment;
-          BidiMode := Columns[I].BidiMode;
-        end
-        else
-        begin
-          Index := NoColumn;
-          Alignment := FAlignment;
-          BidiMode := Self.BidiMode;
-        end;
-
-        if not RenderColumns or (coVisible in Columns[I].Options) then
-        begin
-          Text := Self.Text[Run, Index];
-          Buffer.Add('\pard\intbl');
-
-          // Alignment is not supported with older RTF formats, however it will be ignored.
-          if BidiMode <> bdLeftToRight then
-            ChangeBidiModeAlignment(Alignment);
-          case Alignment of
-            taRightJustify:
-              Buffer.Add('\qr');
-            taCenter:
-              Buffer.Add('\qc');
-          end;
-
-          // Call back the application to know about font customization.
-          Canvas.Font := Font;
-          FFontChanged := False;
-          DoPaintText(Run, Canvas, Index, ttNormal);
-
-          if Index = Header.MainColumn then
-          begin
-            Level := GetNodeLevel(Run);
-            if Level <> LastLevel then
-            begin
-              LastLevel := Level;
-              Tabs := '';
-              for J := 0 to Level - 1 do
-                Tabs := Tabs + '\tab';
-            end;
-            if Level > 0 then
-            begin
-              Buffer.Add(Tabs);
-              Buffer.Add(' ');
-              TextPlusFont(Text, Canvas.Font);
-              Buffer.Add('\cell');
-            end
-            else
-            begin
-              TextPlusFont(Text, Canvas.Font);
-              Buffer.Add('\cell');
-            end;
-          end
-          else
-          begin
-            TextPlusFont(Text, Canvas.Font);
-            Buffer.Add('\cell');
-          end;
-        end;
-
-        if not RenderColumns then
-          Break;
-        Inc(I);
-      end;
-      Buffer.Add('\row');
-      if (Assigned(FOnAfterNodeExport)) then
-        FOnAfterNodeExport(Self, etRTF, Run);
-      Run := GetNextNode(Run);
-    end;
-
-    Buffer.Add('\pard\par');
-
-    // Build lists with fonts and colors. They have to be at the start of the document.
-    S := '{\rtf1\ansi\ansicpg1252\deff0\deflang1043{\fonttbl';
-    for I := 0 to Fonts.Count - 1 do
-      S := S + Format('{\f%d %s;}', [I, Fonts[I]]);
-    S := S + '}';
-
-    S := S + '{\colortbl;';
-    for I := 0 to Colors.Count - 1 do
-    begin
-      J := ColorToRGB(TColor(Colors[I]));
-      S := S + Format('\red%d\green%d\blue%d;', [J and $FF, (J shr 8) and $FF, (J shr 16) and $FF]);
-    end;
-    S := S + '}';
-
-    Result := S + Buffer.AsAnsiString + '}';
-    Fonts.Free;
-    Colors.Free;
-
-    RestoreFontChangeEvent(Canvas);
-  finally
-    Buffer.Free;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.ContentToCustom(Source: TVSTTextSourceType);
-
-// Generic export procedure which polls the application at every stage of the export.
-
-var
-  I: Integer;
-  Save, Run: PVirtualNode;
-  GetNextNode: TGetNextNodeProc;
-  RenderColumns: Boolean;
-  Columns: TColumnsArray;
-
-begin
-  Columns := nil;
-  GetRenderStartValues(Source, Run, GetNextNode);
-  Save := Run;
-
-  RenderColumns := FHeader.UseColumns and ( hoVisible in FHeader.Options );
-
-  if Assigned(FOnBeforeTreeExport) then
-    FOnBeforeTreeExport(Self, etCustom);
-
-  // Fill table header.
-  if RenderColumns then
-  begin
-    if Assigned(FOnBeforeHeaderExport) then
-      FOnBeforeHeaderExport(Self, etCustom);
-
-    Columns := FHeader.FColumns.GetVisibleColumns;
-    for I := 0 to High(Columns) do
-    begin
-      if Assigned(FOnBeforeColumnExport) then
-        FOnBeforeColumnExport(Self, etCustom, Columns[I]);
-
-      if Assigned(FOnColumnExport) then
-        FOnColumnExport(Self, etCustom, Columns[I]);
-
-      if Assigned(FOnAfterColumnExport) then
-        FOnAfterColumnExport(Self, etCustom, Columns[I]);
-    end;
-
-    if Assigned(FOnAfterHeaderExport) then
-      FOnAfterHeaderExport(Self, etCustom);
-  end;
-
-  // Now write the content.
-  Run := Save;
-  while Assigned(Run) do
-  begin
-    if CanExportNode(Run) then
-    begin
-      if Assigned(FOnBeforeNodeExport) then
-        FOnBeforeNodeExport(Self, etCustom, Run);
-
-      if Assigned(FOnNodeExport) then
-        FOnNodeExport(Self, etCustom, Run);
-
-      if Assigned(FOnAfterNodeExport) then
-        FOnAfterNodeExport(Self, etCustom, Run);
-    end;
-
-    Run := GetNextNode(Run);
-  end;
-
-  if Assigned(FOnAfterTreeExport) then
-    FOnAfterTreeExport(Self, etCustom);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ContentToAnsi(Source: TVSTTextSourceType; const Separator: String): AnsiString;
-var
-  Buffer: TBufferedUTF8String;
-begin
-  Buffer := TBufferedUTF8String.Create;
-  try
-    AddContentToBuffer(Buffer, Source, Separator);
-  finally
-    Result := Buffer.AsAnsiString;
-    Buffer.Destroy;
-  end;
-end;
-
-function TCustomVirtualStringTree.ContentToText(Source: TVSTTextSourceType;
-  const Separator: String): AnsiString;
-begin
-  Result := ContentToAnsi(Source, Separator);
-end;
-
-function TCustomVirtualStringTree.ContentToUnicode(Source: TVSTTextSourceType;
-  const Separator: String): UnicodeString;
-begin
-  Result := ContentToUTF16(Source, Separator);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.AddContentToBuffer(Buffer: TBufferedUTF8String; Source: TVSTTextSourceType; const Separator: String);
-
-// Renders the current tree content (depending on Source) as UTF8 text.
-// If an entry contains the separator char or double quotes then it is wrapped with double quotes
-// and existing double quotes are duplicated.
-
-var
-  RenderColumns: Boolean;
-  Tabs: String;
-  GetNextNode: TGetNextNodeProc;
-  Run, Save: PVirtualNode;
-  Level, MaxLevel: Cardinal;
-  Columns: TColumnsArray;
-  LastColumn: TVirtualTreeColumn;
-  Index,
-  I: Integer;
-  Text: String;
-begin
-  Columns := nil;
-  RenderColumns := FHeader.UseColumns;
-  if RenderColumns then
-    Columns := FHeader.FColumns.GetVisibleColumns;
-
-  GetRenderStartValues(Source, Run, GetNextNode);
-  Save := Run;
-
-  // The text consists of visible groups representing the columns, which are separated by one or more separator
-  // characters. There are always MaxLevel separator chars in a line (main column only). Either before the caption
-  // to ident it or after the caption to make the following column aligned.
-  MaxLevel := 0;
-  while Assigned(Run) do
-  begin
-    Level := GetNodeLevel(Run);
-    If Level > MaxLevel then
-      MaxLevel := Level;
-    Run := GetNextNode(Run);
-  end;
-
-  Tabs := DupeString(Separator, MaxLevel);
-
-  // First line is always the header if used.
-  if RenderColumns then
-  begin
-    LastColumn := Columns[High(Columns)];
-    for I := 0 to High(Columns) do
-    begin
-      Buffer.Add(Columns[I].Text);
-      if Columns[I] <> LastColumn then
-      begin
-        if Columns[I].Index = Header.MainColumn then
-        begin
-          Buffer.Add(Tabs);
-          Buffer.Add(Separator);
-        end
-        else
-          Buffer.Add(Separator);
-      end;
-    end;
-    Buffer.AddNewLine;
-  end
-  else
-    LastColumn := nil;
-
-  Run := Save;
-  if RenderColumns then
-  begin
-    while Assigned(Run) do
-    begin
-      if (not CanExportNode(Run) or
-         (Assigned(FOnBeforeNodeExport) and (not FOnBeforeNodeExport(Self, etText, Run)))) then
-      begin
-        Run := GetNextNode(Run);
-        Continue;
-      end;
-      for I := 0 to High(Columns) do
-      begin
-        if coVisible in Columns[I].Options then
-        begin
-          Index := Columns[I].Index;
-          // This line implicitly converts the Unicode text to ANSI.
-          Text := Self.Text[Run, Index];
-          if Index = Header.MainColumn then
-          begin
-            Level := GetNodeLevel(Run);
-            Buffer.Add(Copy(Tabs, 1, Integer(Level) * Length(Separator)));
-            // Wrap the text with quotation marks if it contains the separator character.
-            if (Pos(Separator, Text) > 0) or (Pos('"', Text) > 0) then
-              Buffer.Add(AnsiQuotedStr(Text, '"'))
-            else
-              Buffer.Add(Text);
-            Buffer.Add(Copy(Tabs, 1, Integer(MaxLevel - Level) * Length(Separator)));
-          end
-          else
-            if (Pos(Separator, Text) > 0) or (Pos('"', Text) > 0) then
-              Buffer.Add(AnsiQuotedStr(Text, '"'))
-            else
-              Buffer.Add(Text);
-
-          if Columns[I] <> LastColumn then
-            Buffer.Add(Separator);
-        end;
-      end;
-      if Assigned(FOnAfterNodeExport) then
-        FOnAfterNodeExport(Self, etText, Run);
-      Run := GetNextNode(Run);
-      Buffer.AddNewLine;
-    end;
-  end
-  else
-  begin
-    while Assigned(Run) do
-    begin
-      if ((not CanExportNode(Run)) or
-         (Assigned(FOnBeforeNodeExport) and (not FOnBeforeNodeExport(Self, etText, Run)))) then
-      begin
-        Run := GetNextNode(Run);
-        Continue;
-      end;
-      // This line implicitly converts the Unicode text to ANSI.
-      Text := Self.Text[Run, NoColumn];
-      Level := GetNodeLevel(Run);
-      Buffer.Add(Copy(Tabs, 1, Integer(Level) * Length(Separator)));
-      Buffer.Add(Text);
-      Buffer.AddNewLine;
-
-      if Assigned(FOnAfterNodeExport) then
-        FonAfterNodeExport(Self, etText, Run);
-      Run := GetNextNode(Run);
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ContentToUTF16(Source: TVSTTextSourceType; const Separator: String): UnicodeString;
-var
-  Buffer: TBufferedUTF8String;
-begin
-  Buffer := TBufferedUTF8String.Create;
-  try
-    AddContentToBuffer(Buffer, Source, Separator);
-  finally
-    Result := Buffer.AsUTF16String;
-    Buffer.Destroy;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ContentToUTF8(Source: TVSTTextSourceType;
-  const Separator: String): String;
-var
-  Buffer: TBufferedUTF8String;
-begin
-  Buffer := TBufferedUTF8String.Create;
-  try
-    AddContentToBuffer(Buffer, Source, Separator);
-  finally
-    Result := Buffer.AsUTF8String;
-    Buffer.Destroy;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.GetTextInfo(Node: PVirtualNode; Column: TColumnIndex; const AFont: TFont; var R: TRect;
-  out Text: String);
-
-// Returns the font, the text and its bounding rectangle to the caller. R is returned as the closest
-// bounding rectangle around Text.
-
-var
-  NewHeight: Integer;
-  TM: TTextMetric;
-
-begin
-  // Get default font and initialize the other parameters.
-  //inherited GetTextInfo(Node, Column, AFont, R, Text);
-
-  Canvas.Font := AFont;
-
-  FFontChanged := False;
-  RedirectFontChangeEvent(Canvas);
-  DoPaintText(Node, Canvas, Column, ttNormal);
-  if FFontChanged then
-  begin
-    AFont.Assign(Canvas.Font);
-    GetTextMetrics(Canvas.Handle, TM);
-    NewHeight := TM.tmHeight;
-  end
-  else // Otherwise the correct font is already there and we only need to set the correct height.
-    NewHeight := FTextHeight;
-  RestoreFontChangeEvent(Canvas);
-
-  // Alignment to the actual text.
-  Text := Self.Text[Node, Column];
-  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);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.InvalidateNode(Node: PVirtualNode): TRect;
-
-var
-  Data: PInteger;
-
-begin
-  Result := inherited InvalidateNode(Node);
-  // Reset node width so changed text attributes are applied correctly.
-  if Assigned(Node) then
-  begin
-    Data := InternalData(Node);
-    if Assigned(Data) then
-      Data^ := 0;
-    // Reset height measured flag too to cause a re-issue of the OnMeasureItem event.
-    Exclude(Node.States, vsHeightMeasured);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.Path(Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
-  Delimiter: Char): String;
-
-// Constructs a string containing the node and all its parents. The last character in the returned path is always the
-// given delimiter.
-
-var
-  S: String;
-
-begin
-  if (Node = nil) or (Node = FRoot) then
-    Result := Delimiter
-  else
-  begin
-    Result := '';
-    while Node <> FRoot do
-    begin
-      DoGetText(Node, Column, TextType, S);
-      Result := S + Delimiter + Result;
-      Node := Node.Parent;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualStringTree.ReinitNode(Node: PVirtualNode; Recursive: Boolean);
-
-var
-  Data: PInteger;
-
-begin
-  inherited;
-  // Reset node width so changed text attributes are applied correctly.
-  if Assigned(Node) and (Node <> FRoot) then
-  begin
-    Data := InternalData(Node);
-    if Assigned(Data) then
-      Data^ := 0;
-    // vsHeightMeasured is already removed in the base tree.
-  end;
-end;
-
-//----------------- TVirtualStringTree ---------------------------------------------------------------------------------
-
-function TVirtualStringTree.GetOptions: TStringTreeOptions;
-
-begin
-  Result := FOptions as TStringTreeOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualStringTree.SetOptions(const Value: TStringTreeOptions);
-
-begin
-  FOptions.Assign(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualStringTree.GetOptionsClass: TTreeOptionsClass;
-
-begin
-  Result := TStringTreeOptions;
-end;
-
-//----------------- TCustomVirtualDrawTree -----------------------------------------------------------------------------
-
-procedure TCustomVirtualDrawTree.DoDrawHint(Canvas: TCanvas; Node: PVirtualNode; const R: TRect; Column: TColumnIndex);
-
-begin
-  if Assigned(FOnDrawHint) then
-    FOnDrawHint(Self, Canvas, Node, R, Column);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualDrawTree.DoGetCellContentMargin(Node: PVirtualNode; Column: TColumnIndex;
-  CellContentMarginType: TVTCellContentMarginType = ccmtAllSides; Canvas: TCanvas = nil): TPoint;
-
-begin
-  Result := Point(0, 0);
-  if Canvas = nil then
-    Canvas := Self.Canvas;
-
-  if Assigned(FOnGetCellContentMargin) then
-    FOnGetCellContentMargin(Self, Canvas, Node, Column, CellContentMarginType, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualDrawTree.DoGetHintSize(Node: PVirtualNode; Column: TColumnIndex; var R: TRect);
-
-begin
-  if Assigned(FOnGetHintSize) then
-    FOnGetHintSize(Self, Node, Column, R);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualDrawTree.DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas = nil): Integer;
-
-begin
-  Result := 2 * FTextMargin;
-  if Canvas = nil then
-    Canvas := Self.Canvas;
-
-  if Assigned(FOnGetNodeWidth) then
-    FOnGetNodeWidth(Self, Canvas, Node, Column, Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TCustomVirtualDrawTree.DoPaintNode(var PaintInfo: TVTPaintInfo);
-
-begin
-  if Assigned(FOnDrawNode) then
-    FOnDrawNode(Self, PaintInfo);
-end;
-
-//----------------- TVirtualDrawTree -----------------------------------------------------------------------------------
-
-function TVirtualDrawTree.GetOptions: TVirtualTreeOptions;
-
-begin
-  Result := FOptions as TVirtualTreeOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVirtualDrawTree.SetOptions(const Value: TVirtualTreeOptions);
-
-begin
-  FOptions.Assign(Value);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVirtualDrawTree.GetOptionsClass: TTreeOptionsClass;
-
-begin
-  Result := TVirtualTreeOptions;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-initialization
-  {$I virtualtrees.lrs}
-  // Necessary for dynamic package loading.
-  Initialized := False;
-  NeedToUnitialize := False;
-
-finalization
-  if Initialized then
-    FinalizeGlobalStructures;
-
-  InternalClipboardFormats.Free;
-  InternalClipboardFormats := nil;
-  {$ifdef EnableAccessible}
-  if VTAccessibleFactory <> nil then
-  begin
-    VTAccessibleFactory.Free;
-    VTAccessibleFactory := nil;
-  end;
-  {$endif}
-end.
-
-
-

+ 0 - 345
components/virtualtreeview/doublecmd.diff

@@ -1,345 +0,0 @@
-Index: VTConfig.inc
-===================================================================
---- VTConfig.inc	(revision 2731)
-+++ VTConfig.inc	(working copy)
-@@ -22,7 +22,7 @@
- 
- 
- //Lazarus port options
--{$define EnableOLE}
-+{.$define EnableOLE}
- {.$define EnableNativeTVM}
- {.$define EnablePrint}
- {.$define EnableNCFunctions}
-@@ -42,7 +42,7 @@
- 
- //under linux the performance is poor with threading enabled
- {$ifdef Windows}
--  {$define EnableThreadSupport}
-+  {.$define EnableThreadSupport}
- {$endif}
- {$ifdef CPU64}
-   {$define PACKARRAYPASCAL}
-Index: VirtualTrees.pas
-===================================================================
---- VirtualTrees.pas	(revision 2731)
-+++ VirtualTrees.pas	(working copy)
-@@ -745,6 +745,7 @@
-     toAutoHideButtons,          // Node buttons are hidden when there are child nodes, but all are invisible.
-     toAutoDeleteMovedNodes,     // Delete nodes which where moved in a drag operation (if not directed otherwise).
-     toDisableAutoscrollOnFocus, // Disable scrolling a node or column into view if it gets focused.
-+    toDisableAutoscrollHorizontal, // Only autoscroll on focus vertically never horizontally
-     toAutoChangeScale,          // Change default node height automatically if the system's font scale is set to big fonts.
-     toAutoFreeOnCollapse,       // Frees any child node after a node has been collapsed (HasChildren flag stays there).
-     toDisableAutoscrollOnEdit,  // Do not center a node horizontally when it is edited.
-@@ -2018,7 +2019,7 @@
-     var Allowed: Boolean) of object;
-   TVTDragOverEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState;
-     const Pt: TPoint; Mode: TDropMode; var Effect: LongWord; var Accept: Boolean) of object;
--  TVTDragDropEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject;
-+  TVTDragDropEvent = procedure(Sender: TBaseVirtualTree; Source: TObject; {DataObject: IDataObject;}
-     Formats: TFormatArray; Shift: TShiftState; const Pt: TPoint; var Effect: LongWord; Mode: TDropMode) of object;
-   TVTRenderOLEDataEvent = procedure(Sender: TBaseVirtualTree; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-     ForClipboard: Boolean; var Result: HRESULT) of object;
-@@ -2543,6 +2544,7 @@
-     procedure BeginOperation;
-     function CalculateSelectionRect(X, Y: Integer): Boolean; virtual;
-     function CanAutoScroll: Boolean; virtual;
-+    function CanScroll(const ClientMousePos: TPoint): Boolean; virtual;
-     function CanShowDragImage: Boolean; virtual;
-     procedure Change(Node: PVirtualNode); virtual;
-     procedure ChangeScale(M, D: Integer); override;
-@@ -3015,6 +3017,7 @@
-     function GetNextNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-     function GetNextSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-     function GetNextSibling(Node: PVirtualNode): PVirtualNode;
-+    function GetNextSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-     function GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-     function GetNextVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-     function GetNextVisibleSibling(Node: PVirtualNode): PVirtualNode;
-@@ -3033,6 +3036,7 @@
-     function GetPreviousNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-     function GetPreviousSelected(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = False): PVirtualNode;
-     function GetPreviousSibling(Node: PVirtualNode): PVirtualNode;
-+    function GetPreviousSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-     function GetPreviousVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-     function GetPreviousVisibleNoInit(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
-     function GetPreviousVisibleSibling(Node: PVirtualNode): PVirtualNode;
-@@ -13858,7 +13862,7 @@
-     FFocusedColumn := Value;
-     if Assigned(FFocusedNode) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then
-     begin
--      if ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, True) then
-+      if ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions, not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions)) then
-         InvalidateNode(FFocusedNode);
-     end;
- 
-@@ -15036,7 +15040,8 @@
-   LeaveStates := [tsHint];
-   if [tsWheelPanning, tsWheelScrolling] * FStates = [] then
-   begin
--    KillTimer(Handle, ScrollTimer);
-+    if HandleAllocated then
-+      KillTimer(Handle, ScrollTimer);
-     LeaveStates := LeaveStates + [tsScrollPending, tsScrolling];
-   end;
-   DoStateChange([], LeaveStates);
-@@ -15660,7 +15665,7 @@
-                 if (Shift = [ssCtrlOS]) and not ActAsGrid then
-                 begin
-                   ScrollIntoView(Node, toCenterScrollIntoView in FOptions.SelectionOptions,
--                    not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions));
-+                    not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions));
-                   if (CharCode = VK_HOME) and not UseRightToLeftAlignment then
-                     SetOffsetX(0)
-                   else
-@@ -17879,7 +17884,7 @@
-       if hoVisible in FHeader.FOptions then
-         Dec(Y, FHeader.Height);
- 
--      if (Y > 0) and (Y < Integer(FDefaultNodeHeight)) and (FOffsetY <> 0) then
-+      if (Y < Integer(FDefaultNodeHeight)) and (FOffsetY <> 0) then
-         Include(Result, sdUp);
- 
-       //todo: probably the code below is bug due to poor timeGetTime implementation
-@@ -18424,7 +18429,7 @@
- 
- begin
-   if Assigned(FOnDragDrop) then
--    FOnDragDrop(Self, Source, DataObject, Formats, Shift, Pt, Effect, Mode);
-+    FOnDragDrop(Self, Source, {DataObject, }Formats, Shift, Pt, Effect, Mode);
- end;
- 
- //----------------------------------------------------------------------------------------------------------------------
-@@ -18576,7 +18581,7 @@
-       InvalidateNode(FFocusedNode);
-       if (FUpdateCount = 0) and not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions) then
-         ScrollIntoView(FFocusedNode, (toCenterScrollIntoView in FOptions.SelectionOptions) and
--          (MouseButtonDown * FStates = []), True);
-+          (MouseButtonDown * FStates = []), not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions));
-     end;
- 
-     // Reset range anchor if necessary.
-@@ -19392,7 +19397,7 @@
-   ClientP := ScreenToClient(P);
-   Panning := [tsWheelPanning, tsWheelScrolling] * FStates <> [];
- 
--  if IsMouseSelecting or InRect or Panning then
-+  if IsMouseSelecting or InRect or Panning or CanScroll(ClientP) then
-   begin
-     DeltaX := 0;
-     DeltaY := 0;
-@@ -21111,7 +21116,7 @@
-       if NewNode or NewColumn then
-       begin
-         ScrollIntoView(FFocusedNode, toCenterScrollIntoView in FOptions.SelectionOptions,
--                       not (toDisableAutoscrollOnFocus in FOptions.FAutoOptions));
-+                       not (toDisableAutoscrollHorizontal in FOptions.FAutoOptions));
-         DoFocusChange(FFocusedNode, FFocusedColumn);
-       end;
-     end;
-@@ -21809,7 +21814,7 @@
- 
- begin
-   if Y < 0 then
--    Y := 0;
-+    Exit(nil);
- 
-   AbsolutePos := Y;
-   if Relative then
-@@ -24335,6 +24340,12 @@
-   DoCanEdit(Node, Column, Result);
- end;
- 
-+function TBaseVirtualTree.CanScroll(const ClientMousePos: TPoint): Boolean;
-+// Determines whether auto scrolling can occur based on current mouse cursor position.
-+begin
-+  Result := False;
-+end;
-+
- //----------------------------------------------------------------------------------------------------------------------
- 
- procedure TBaseVirtualTree.Clear;
-@@ -26446,6 +26457,22 @@
- 
- //----------------------------------------------------------------------------------------------------------------------
- 
-+function TBaseVirtualTree.GetNextSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-+
-+// Returns the next sibling of Node performing no initialization.
-+
-+begin
-+  Result := Node;
-+  if Assigned(Result) then
-+  begin
-+    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-+
-+    Result := Result.NextSibling;
-+  end;
-+end;
-+
-+//----------------------------------------------------------------------------------------------------------------------
-+
- function TBaseVirtualTree.GetNextVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
- 
- // Returns next node in tree, with regard to Node, which is visible.
-@@ -27064,6 +27091,22 @@
- 
- //----------------------------------------------------------------------------------------------------------------------
- 
-+function TBaseVirtualTree.GetPreviousSiblingNoInit(Node: PVirtualNode): PVirtualNode;
-+
-+// Get next sibling of Node, performes no initialization.
-+
-+begin
-+  Result := Node;
-+  if Assigned(Result) then
-+  begin
-+    Assert(Result <> FRoot, 'Node must not be the hidden root node.');
-+
-+    Result := Result.PrevSibling;
-+  end;
-+end;
-+
-+//----------------------------------------------------------------------------------------------------------------------
-+
- function TBaseVirtualTree.GetPreviousVisible(Node: PVirtualNode; ConsiderChildrenAbove: Boolean = True): PVirtualNode;
- 
- // Returns the previous node in tree, with regard to Node, which is visible.
-@@ -29252,6 +29295,7 @@
-   HScrollBarVisible: Boolean;
-   ScrolledVertically,
-   ScrolledHorizontally: Boolean;
-+  OffY, OffYM: Integer;
- 
- begin
-   //todo: minimize calls to ClientHeight and ClientWidth
-@@ -29296,7 +29340,14 @@
-         if Center then
-           SetOffsetY(FOffsetY - R.Bottom + ClientHeight div 2)
-         else
--          SetOffsetY(FOffsetY - R.Bottom + ClientHeight);
-+        begin
-+          // Leave additional space at the bottom to have scrollrect start with full row.
-+          OffY  := FOffsetY - R.Bottom + ClientHeight;
-+          OffYM := OffY mod DefaultNodeHeight;
-+          if OffYM <> 0 then
-+            OffY := OffY - (DefaultNodeHeight + OffYM);
-+          SetOffsetY(OffY);
-+        end;
-         // When scrolling up and the horizontal scroll appears because of the operation
-         // then we have to move up the node the horizontal scrollbar's height too
-         // in order to avoid that the scroll bar hides the node which we wanted to have in view.
-@@ -29350,10 +29401,13 @@
-   end
-   else
-   begin
--    if ColumnRight > ClientWidth then
--      NewOffset := FEffectiveOffsetX + (ColumnRight - ClientWidth)
--    else if ColumnLeft < Header.Columns.GetVisibleFixedWidth then
--      NewOffset := FEffectiveOffsetX - (Header.Columns.GetVisibleFixedWidth - ColumnLeft);
-+    if FHeader.Columns.Count > 1 then
-+    begin
-+      if ColumnRight > ClientWidth then
-+        NewOffset := FEffectiveOffsetX + (ColumnRight - ClientWidth)
-+      else if ColumnLeft < Header.Columns.GetVisibleFixedWidth then
-+        NewOffset := FEffectiveOffsetX - (Header.Columns.GetVisibleFixedWidth - ColumnLeft);
-+    end;
-     if NewOffset <> FEffectiveOffsetX then
-     begin
-       if UseRightToLeftAlignment then
-Index: include/intf/qt/vtgraphicsi.inc
-===================================================================
---- include/intf/qt/vtgraphicsi.inc	(revision 2731)
-+++ include/intf/qt/vtgraphicsi.inc	(working copy)
-@@ -284,7 +284,7 @@
- 
-         // Load MM4 with 128 to allow for saturated biasing.
-         MOV     EAX, 128
--        DB      $0F, $6E, AlphaBlendLineConstant$E0          /// MOVD      MM4, EAX
-+        DB      $0F, $6E, $E0          /// MOVD      MM4, EAX
-         DB      $0F, $61, $E4          /// PUNPCKLWD MM4, MM4
-         DB      $0F, $62, $E4          /// PUNPCKLDQ MM4, MM4
- 
-Index: units/carbon/fakemmsystem.pas
-===================================================================
---- units/carbon/fakemmsystem.pas	(revision 2731)
-+++ units/carbon/fakemmsystem.pas	(working copy)
-@@ -15,6 +15,9 @@
- 
- implementation
- 
-+uses
-+  LCLIntf;
-+
- function timeBeginPeriod(x1: DWord): DWord;
- begin
- 
-@@ -26,12 +29,8 @@
- end;
- 
- function timeGetTime: DWORD;
--var
--  ATime: TSystemTime;
- begin
--  //todo: properly implement
--  GetLocalTime(ATime);
--  Result := ATime.MilliSecond;
-+  Result := GetTickCount;
- end;
- 
- end.
-Index: units/qt/fakemmsystem.pas
-===================================================================
---- units/qt/fakemmsystem.pas	(revision 2731)
-+++ units/qt/fakemmsystem.pas	(working copy)
-@@ -15,6 +15,9 @@
- 
- implementation
- 
-+uses
-+  LCLIntf;
-+
- function timeBeginPeriod(x1: DWord): DWord;
- begin
- 
-@@ -26,12 +29,8 @@
- end;
- 
- function timeGetTime: DWORD;
--var
--  ATime: TSystemTime;
- begin
--  //todo: properly implement
--  GetLocalTime(ATime);
--  Result := ATime.MilliSecond;
-+  Result := GetTickCount;
- end;
- 
- end.
-Index: units/win32/virtualpanningwindow.pas
-===================================================================
---- units/win32/virtualpanningwindow.pas	(revision 2731)
-+++ units/win32/virtualpanningwindow.pas	(working copy)
-@@ -41,9 +41,10 @@
-     PanningObject:=TVirtualPanningWindow(GetWindowLongPtrW(Window,GWL_USERDATA));
-     if Assigned(PanningObject) then
-       PanningObject.HandlePaintMessage;
-+	Result := 0;
-   end
-   else
--    DefWindowProc(Window,Msg,WPara,LPara);
-+    Result := DefWindowProc(Window,Msg,WPara,LPara);
- end;
- 
- var
-@@ -87,8 +88,7 @@
-   with Position do
-     FHandle := CreateWindowEx(WS_EX_TOOLWINDOW, PanningWindowClass.lpszClassName, nil, WS_POPUP, X - 16, Y - 16,
-       32, 32, OwnerHandle, 0, HInstance, nil);
--  //todo use SetWindowLongPtr later
--  SetWindowLong(FHandle,GWL_USERDATA,PtrInt(Self));
-+  SetWindowLongPtr(FHandle,GWL_USERDATA,LONG_PTR(Self));
-   
-   FImage := TBitmap.Create;
- end;

+ 0 - 48
components/virtualtreeview/ideicons.lrs

@@ -1,48 +0,0 @@
-LazarusResources.Add('tvirtualdrawtree','XPM',[
-  '/* XPM */'#10'static char * tvirtualdrawtree_xpm[] = {'#10'"24 24 8 1",'#10
-  +'".'#9'c #000000",'#10'"+'#9'c None",'#10'"@'#9'c #808000",'#10'"#'#9'c #20A'
-  +'080",'#10'"$'#9'c #808080",'#10'"%'#9'c #C0A000",'#10'"&'#9'c #C0C0C0",'#10
-  +'"*'#9'c #FFFFFF",'#10'"++++++..++++++++++++++++",'#10'"+++++.&&............'
-  +'.+++",'#10'"++++.***&&&&&&&&&&$$@.++",'#10'"++++.************@$$$.++",'#10
-  +'"+++.************@$$$$.++",'#10'"++++...@********.$$$$.++",'#10'"+++++++...'
-  +'......$$$$@+++",'#10'"+++++++.$$$$$$$$***$.+++",'#10'"+++++++.*******%***&.'
-  +'+++",'#10'"+++++++.*.****%%%**$.+++",'#10'"+++++++.*...*%%%%%*.++++",'#10'"'
-  +'+++++++.*.**%%%%%%%.++++",'#10'"++++++.**.***####**.++++",'#10'"+++++.$**.*'
-  +'*######*.++++",'#10'"+++++.&**..*######*.++++",'#10'"+++++.******######*.++'
-  +'++",'#10'"+++++.*******####**&.+++",'#10'"+...+.***.....******.+++",'#10'"+'
-  +'.&&@....&&&&&.****$.+++",'#10'"+.&&&&&&&&&&&&&.**&.++++",'#10'"++.$&&&&&&&&'
-  +'&&&.&&&.++++",'#10'"++.$$$$$$$$$$$$$.&.+++++",'#10'"+++...............+++++'
-  +'+",'#10'"++++++++++++++++++++++++"};'#10
-]);
-LazarusResources.Add('tvirtualstringtree','XPM',[
-  '/* XPM */'#10'static char * tvirtualstringtree_xpm[] = {'#10'"24 24 8 1",'#10
-  +'".'#9'c #000000",'#10'"+'#9'c None",'#10'"@'#9'c #808000",'#10'"#'#9'c #20A'
-  +'080",'#10'"$'#9'c #808080",'#10'"%'#9'c #C0A000",'#10'"&'#9'c #C0C0C0",'#10
-  +'"*'#9'c #FFFFFF",'#10'"++++++..++++++++++++++++",'#10'"+++++.&&............'
-  +'.+++",'#10'"++++.***&&&&&&&&&&$$@.++",'#10'"++++.************@$$$.++",'#10
-  +'"+++.************@$$$$.++",'#10'"++++...@********.$$$$.++",'#10'"+++++++...'
-  +'......$$$$@+++",'#10'"+++++++.$$$$$$$$***$.+++",'#10'"+++++++.***********&.'
-  +'+++",'#10'"+++++++.*.**......*$.+++",'#10'"+++++++.*....%%%%.*.++++",'#10'"'
-  +'+++++++.*.**......*.++++",'#10'"++++++.**.*********.++++",'#10'"+++++.$**.*'
-  +'*......*.++++",'#10'"+++++.&**....####.*.++++",'#10'"+++++.******......*.++'
-  +'++",'#10'"+++++.*************&.+++",'#10'"+...+.***.....******.+++",'#10'"+'
-  +'.&&@....&&&&&.****$.+++",'#10'"+.&&&&&&&&&&&&&.**&.++++",'#10'"++.$&&&&&&&&'
-  +'&&&.&&&.++++",'#10'"++.$$$$$$$$$$$$$.&.+++++",'#10'"+++...............+++++'
-  +'+",'#10'"++++++++++++++++++++++++"};'#10
-]);
-LazarusResources.Add('tvtheaderpopupmenu','XPM',[
-  '/* XPM */'#10'static char * tvtheaderpopupmenu_xpm[] = {'#10'"24 24 7 1",'#10
-  +'".'#9'c #000000",'#10'"+'#9'c #000080",'#10'"@'#9'c None",'#10'"#'#9'c #808'
-  +'000",'#10'"$'#9'c #808080",'#10'"%'#9'c #C0C0C0",'#10'"&'#9'c #FFFFFF",'#10
-  +'"@@@@@@..@@@@@@@@@@@@@@@@",'#10'"@@@@@.%%.............@@@",'#10'"@@@@.&&&%%'
-  +'%%%%%%%%$$#.@@",'#10'"@@@@.&&&&&&&&&&&&#$$$.@@",'#10'"@@@.&&&&&&&&&&&&#$$$$'
-  +'.@@",'#10'"@@@@...#&&&&&&&&.$$$$.@@",'#10'"@@@@@@@.........$$$$#@@@",'#10'"'
-  +'@@@@@@@.$$$$$$$$&&&$.@@@",'#10'"@@@@@@@.$&&&&&&.&&&%.@@@",'#10'"@@@@@@@.$&+'
-  +'++&&.&&&$.@@@",'#10'"@@@@@@@.$&&&&&&.&&&.@@@@",'#10'"@@@@@@@.$&+++++.&&&.@@'
-  +'@@",'#10'"@@@@@@.&$+&&&+&+&&&.@@@@",'#10'"@@@@@.$&$&++++&&+&&.@@@@",'#10'"@'
-  +'@@@@.%&$&&&&+&&&+&.@@@@",'#10'"@@@@@.&&$....+&&&&+.@@@@",'#10'"@@@@@.&&&&&&'
-  +'&+&&&++++@@@",'#10'"@...@.&&&....+&&&&+&.@@@",'#10'"@.%%#....%%%%+&++&&+.@@'
-  +'@",'#10'"@.%%%%%%%%%%%++$+&&+@@@@",'#10'"@@.$%%%%%%%%%+%.%+&&+@@@",'#10'"@@'
-  +'.$$$$$$$$$$$$$.+&&+@@@",'#10'"@@@...............++@@@@",'#10'"@@@@@@@@@@@@@'
-  +'@@@@@@@@@@@"};'#10
-]);

+ 0 - 2
components/virtualtreeview/include/intf/carbon/olemethods.inc

@@ -1,2 +0,0 @@
-
-{$i ../dummyolemethods.inc}

+ 0 - 23
components/virtualtreeview/include/intf/carbon/vtgraphicsi.inc

@@ -1,23 +0,0 @@
-//todo: properly implement
-procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer);
-begin
-  case Mode of
-    bmConstantAlpha,
-    bmPerPixelAlpha,
-    bmMasterAlpha,
-    bmConstantAlphaAndColor:
-      begin
-	    BitBlt(Destination, Target.X, Target.Y, R.Right - R.Left, R.Bottom - R.Top, Source, R.Left, R.Right, SRCCOPY); 
-      end;
-  end;
-end;
-
-function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer;
-begin
-  Result := nil;
-end;
-
-function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer;
-begin
-  Result := nil;
-end;

+ 0 - 2
components/virtualtreeview/include/intf/carbon/vtvdragmanager.inc

@@ -1,2 +0,0 @@
-
-{$i ../dummydragmanager.inc}

+ 0 - 790
components/virtualtreeview/include/intf/dummydragmanager.inc

@@ -1,790 +0,0 @@
-
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// OLE drag and drop support classes
-// This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs
-// of DD'ing various kinds of virtual data and works also between applications.
-
-//----------------- TEnumFormatEtc -------------------------------------------------------------------------------------
-
-constructor TEnumFormatEtc.Create(Tree: TBaseVirtualTree; AFormatEtcArray: TFormatEtcArray);
-
-var
-  I: Integer;
-
-begin
-  inherited Create;
-
-  {
-  FTree := Tree;
-  // Make a local copy of the format data.
-  SetLength(FFormatEtcArray, Length(AFormatEtcArray));
-  for I := 0 to High(AFormatEtcArray) do
-    FFormatEtcArray[I] := AFormatEtcArray[I];
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
-
-{
-var
-  AClone: TEnumFormatEtc;
-}
-begin
-  {
-  Result := S_OK;
-  try
-    AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray);
-    AClone.FCurrentIndex := FCurrentIndex;
-    Enum := AClone as IEnumFormatEtc;
-  except
-    Result := E_FAIL;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc;pceltFetched:pULong=nil): HResult;
-{
-var
-  CopyCount: LongWord;
-}
-begin
-  {
-  Result := S_FALSE;
-  CopyCount := Length(FFormatEtcArray) - FCurrentIndex;
-  if celt < CopyCount then
-    CopyCount := celt;
-  if CopyCount > 0 then
-  begin
-    Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc));
-    Inc(FCurrentIndex, CopyCount);
-    Result := S_OK;
-  end;
-  //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with
-  // a C Program call with a NULL in pCeltFetcjed??
-  //Answer: Yes. Is necessary a check here
-  if @pceltFetched <> nil then
-    pceltFetched := CopyCount;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Reset: HResult;
-
-begin
-  {
-  FCurrentIndex := 0;
-  Result := S_OK;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Skip(celt: LongWord): HResult;
-
-begin
-  {
-  if FCurrentIndex + celt < High(FFormatEtcArray) then
-  begin
-    Inc(FCurrentIndex, celt);
-    Result := S_Ok;
-  end
-  else
-    Result := S_FALSE;
-  }
-end;
-
-
-
-//----------------- TVTDataObject --------------------------------------------------------------------------------------
-
-constructor TVTDataObject.Create(AOwner: TBaseVirtualTree; ForClipboard: Boolean);
-
-begin
-  inherited Create;
-  {
-
-  FOwner := AOwner;
-  FForClipboard := ForClipboard;
-  FOwner.GetNativeClipboardFormats(FFormatEtcArray);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDataObject.Destroy;
-
-var
-  I: Integer;
-  StgMedium: PStgMedium;
-
-begin
-  {
-  // Cancel a pending clipboard operation if this data object was created for the clipboard and
-  // is freed because something else is placed there.
-  if FForClipboard and not (tsClipboardFlushing in FOwner.FStates) then
-    FOwner.CancelCutOrCopy;
-
-  // Release any internal clipboard formats
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat);
-    if Assigned(StgMedium) then
-      ReleaseStgMedium(StgMedium);
-  end;
-
-  FormatEtcArray := nil;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-
-// Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown
-// interface, will always return the same pointer.
-
-begin
-  {
-  if Assigned(TestUnknown) then
-  begin
-    if TestUnknown.QueryInterface(IUnknown, Result) = 0 then
-      Result._Release // Don't actually need it just need the pointer value
-    else
-      Result := TestUnknown
-  end
-  else
-    Result := TestUnknown
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-
-begin
-  {
-  Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and
-    (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and
-    (FormatEtc1.tymed and FormatEtc2.tymed <> 0);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer;
-
-var
-  I: integer;
-
-begin
-  {
-  Result := -1;
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then
-    begin
-      Result := I;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium;
-{
-var
-  I: integer;
-}
-begin
-  {
-  Result := nil;
-  for I := 0 to High(InternalStgMediumArray) do
-  begin
-    if Format = InternalStgMediumArray[I].Format then
-    begin
-      Result := @InternalStgMediumArray[I].Medium;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle;
-
-// Returns a global memory block that is a copy of the passed memory block.
-
-{
-var
-  Size: Cardinal;
-  Data,
-  NewData: PChar;
-}
-begin
-  {
-   Size := GlobalSize(HGlobal);
-  Result := GlobalAlloc(GPTR, Size);
-  Data := GlobalLock(hGlobal);
-  try
-    NewData := GlobalLock(Result);
-    try
-      Move(Data^, NewData^, Size);
-    finally
-      GlobalUnLock(Result);
-    end
-  finally
-    GlobalUnLock(hGlobal);
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium;
-  var OLEResult: HResult): Boolean;
-
-// Tries to render one of the formats which have been stored via the SetData method.
-// Since this data is already there it is just copied or its reference count is increased (depending on storage medium).
-
-{
-var
-  InternalMedium: PStgMedium;
-}
-begin
-  {
-  Result := True;
-  InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat);
-  if Assigned(InternalMedium) then
-    OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject)
-  else
-    Result := False;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-  CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-// InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or
-// increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually
-// the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData.
-// If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during
-// that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make
-// copy of the data for the caller only to have them destroy it then need us to copy it again if necessary.
-// This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData.
-// 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;
-
-begin
-  {
-  Result := S_OK;
-
-  // Simply copy all fields to start with.
-  OutStgMedium := InStgMedium;
-  // The data handled here always results from a call of SetData we got. This ensures only one storage format
-  // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several
-  // storage formats).
-  case InStgMedium.tymed of
-    TYMED_HGLOBAL:
-      begin
-        if CopyInMedium then
-        begin
-          // Generate a unique copy of the data passed
-          OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal);
-          if OutStgMedium.hGlobal = 0 then
-            Result := E_OUTOFMEMORY
-        end
-        else
-          // Don't generate a copy just use ourselves and the copy previously saved.
-          OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount.
-      end;
-    TYMED_FILE:
-      begin
-        //todo_lcl_check
-        Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character.
-        OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len);
-        Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len);
-      end;
-    TYMED_ISTREAM:
-      IUnknown(OutStgMedium.Pstm)._AddRef;
-    TYMED_ISTORAGE:
-      IUnknown(OutStgMedium.Pstg)._AddRef;
-    TYMED_GDI:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy GDI objects right now.
-    TYMED_MFPICT:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now.
-    TYMED_ENHMF:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now.
-  else
-    Result := DV_E_TYMED;
-  end;
-
-  if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then
-    IUnknown(OutStgMedium.PunkForRelease)._AddRef;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink;
-  out dwConnection: DWord): HResult;
-
-// Advise sink management is greatly simplified by the IDataAdviseHolder interface.
-// We use this interface and forward all concerning calls to it.
-
-begin
-  {
-  Result := S_OK;
-  if FAdviseHolder = nil then
-    Result := CreateDataAdviseHolder(FAdviseHolder);
-  if Result = S_OK then
-    Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DUnadvise(dwConnection: DWord): HResult;
-
-begin
-  {
-  if FAdviseHolder = nil then
-    Result := E_NOTIMPL
-  else
-    Result := FAdviseHolder.Unadvise(dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumDAdvise(Out enumAdvise : IEnumStatData):HResult;
-
-begin
-  {
-  if FAdviseHolder = nil then
-    Result := OLE_E_ADVISENOTSUPPORTED
-  else
-    Result := FAdviseHolder.EnumAdvise(enumAdvise);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult;
-{
-var
-  NewList: TEnumFormatEtc;
-}
-begin
-  {
-  Result := E_FAIL;
-  if Direction = DATADIR_GET then
-  begin
-    NewList := TEnumFormatEtc.Create(FOwner, FormatEtcArray);
-    EnumFormatEtc := NewList as IEnumFormatEtc;
-    Result := S_OK;
-  end
-  else
-    EnumFormatEtc := nil;
-  if EnumFormatEtc = nil then
-    Result := OLE_S_USEREG;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-Function TVTDataObject.GetCanonicalFormatEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult;
-
-begin
-  //Result := DATA_S_SAMEFORMATETC;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult;
-
-// Data is requested by clipboard or drop target. This method dispatchs the call
-// depending on the data being requested.
-
-{
-var
-  I: Integer;
-  Data: PVTReference;
-}
-begin
-  {
-  // The tree reference format is always supported and returned from here.
-  if FormatEtcIn.cfFormat = CF_VTREFERENCE then
-  begin
-    // Note: this format is not used while flushing the clipboard to avoid a dangling reference
-    //       when the owner tree is destroyed before the clipboard data is replaced with something else.
-    if tsClipboardFlushing in FOwner.FStates then
-      Result := E_FAIL
-    else
-    begin
-      Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference));
-      Data := GlobalLock(Medium.hGlobal);
-      Data.Process := GetCurrentProcessID;
-      Data.Tree := FOwner;
-      GlobalUnlock(Medium.hGlobal);
-      Medium.tymed := TYMED_HGLOBAL;
-      Medium.PunkForRelease := nil;
-      Result := S_OK;
-    end;
-  end
-  else
-  begin
-    try
-      // See if we accept this type and if not get the correct return value.
-      Result := QueryGetData(FormatEtcIn);
-      if Result = S_OK then
-      begin
-        for I := 0 to High(FormatEtcArray) do
-        begin
-          if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
-          begin
-            if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
-              Result := FOwner.RenderOLEData(FormatEtcIn, Medium, FForClipboard);
-            Break;
-          end;
-        end
-      end
-    except
-      FillChar(Medium, SizeOf(Medium), #0);
-      Result := E_FAIL;
-    end;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult;
-
-begin
-  //Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult;
-
-{
-var
-  I: Integer;
-}
-
-begin
-  {
-  Result := DV_E_CLIPFORMAT;
-  for I := 0 to High(FFormatEtcArray) do
-  begin
-    if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then
-    begin
-      if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then
-      begin
-        if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then
-        begin
-          if FormatEtc.lindex = FFormatEtcArray[I].lindex then
-          begin
-            Result := S_OK;
-            Break;
-          end
-          else
-            Result := DV_E_LINDEX;
-        end
-        else
-          Result := DV_E_DVASPECT;
-      end
-      else
-        Result := DV_E_TYMED;
-    end;
-  end
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.SetData(const FormatEtc: TFormatEtc; {$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult;
-
-// 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;
-  LocalStgMedium: PStgMedium;
-}
-begin
-  {
-  // See if we already have a format of that type available.
-  Index := FindFormatEtc(FormatEtc, FormatEtcArray);
-  if Index > - 1 then
-  begin
-    // Just use the TFormatEct in the array after releasing the data.
-    LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat);
-    if Assigned(LocalStgMedium) then
-    begin
-      ReleaseStgMedium(LocalStgMedium);
-      FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-    end;
-  end
-  else
-  begin
-    // It is a new format so create a new TFormatCollectionItem, copy the
-    // FormatEtc parameter into the new object and and put it in the list.
-    SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1);
-    FormatEtcArray[High(FormatEtcArray)] := FormatEtc;
-
-    // Create a new InternalStgMedium and initialize it and associate it with the format.
-    SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1);
-    InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat;
-    LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium;
-    FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-  end;
-
-  if DoRelease then
-  begin
-    // We are simply being given the data and we take control of it.
-    LocalStgMedium^ := Medium;
-    Result := S_OK
-  end
-  else
-  begin
-    // We need to reference count or copy the data and keep our own references to it.
-    Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject);
-
-    // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium.
-    // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that
-    // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN.
-    if Assigned(LocalStgMedium.PunkForRelease) then
-    begin
-      if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then
-        IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface
-    end;
-  end;
-
-  // Tell all registered advice sinks about the data change.
-  if Assigned(FAdviseHolder) then
-    FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0);
-  }
-end;
-
-//----------------- TVTDragManager -------------------------------------------------------------------------------------
-
-constructor TVTDragManager.Create(AOwner: TBaseVirtualTree);
-
-begin
-  inherited Create;
-
-  FOwner := AOwner;
-  {
-  // Create an instance  of the drop target helper interface. This will fail but not harm on systems which do
-  // not support this interface (everything below Windows 2000);
-  CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDragManager.Destroy;
-
-begin
-  // Set the owner's reference to us to nil otherwise it will access an invalid pointer
-  // after our desctruction is complete.
-  Pointer(FOwner.FDragManager) := nil;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDataObject: IDataObject;
-
-begin
-  // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem.
-  // In this case there is no local reference to a data object and one is created (but not stored).
-  // If there is a local reference then the owner tree is currently the drop target and the stored interface is
-  // that of the drag initiator.
-  {
-  if Assigned(FDataObject) then
-    Result := FDataObject
-  else
-  begin
-    Result := FOwner.DoCreateDataObject;
-    if Result = nil then
-      Result := TVTDataObject.Create(FOwner, False) as IDataObject;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDragSource: TBaseVirtualTree;
-
-begin
-  //Result := FDragSource;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDropTargetHelperSupported: Boolean;
-
-begin
-  //Result := Assigned(FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetIsDropTarget: Boolean;
-
-begin
-  //Result := FIsDropTarget;
-  Result := True;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {
-  FDataObject := DataObject;
-  FIsDropTarget := True;
-
-  SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0);
-  // If full dragging of window contents is disabled in the system then our tree windows will be locked
-  // and cannot be updated during a drag operation. With the following call painting is again enabled.
-  if not FFullDragging then
-    LockWindowUpdate(0);
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragEnter(FOwner.Handle, DataObject, Pt, Effect);
-
-  FDragSource := FOwner.GetTreeFromDataObject(DataObject);
-  Result := FOwner.DragEnter(KeyState, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragLeave: HResult;
-
-begin
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-
-  FOwner.DragLeave;
-  FIsDropTarget := False;
-  FDragSource := nil;
-  FDataObject := nil;
-  Result := NOERROR;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult;
-
-begin
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragOver(Pt, Effect);
-
-  Result := FOwner.DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.Drop(DataObject, Pt, Effect);
-
-  Result := FOwner.DragDrop(DataObject, KeyState, Pt, Effect);
-  FIsDropTarget := False;
-  FDataObject := nil;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragManager.ForceDragLeave;
-
-// Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive
-// a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from
-// screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE).
-
-begin
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GiveFeedback(Effect: LongWord): HResult;
-
-begin
-  //Result := DRAGDROP_S_USEDEFAULTCURSORS;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult;
-
-var
-  RButton,
-  LButton: Boolean;
-
-begin
-  {
-  LButton := (KeyState and MK_LBUTTON) <> 0;
-  RButton := (KeyState and MK_RBUTTON) <> 0;
-
-  // Drag'n drop canceled by pressing both mouse buttons or Esc?
-  if (LButton and RButton) or EscapePressed then
-    Result := DRAGDROP_S_CANCEL
-  else
-    // Drag'n drop finished?
-    if not (LButton or RButton) then
-      Result := DRAGDROP_S_DROP
-    else
-      Result := S_OK;
-
-  }
-end;
-
-

+ 0 - 404
components/virtualtreeview/include/intf/dummyolemethods.inc

@@ -1,404 +0,0 @@
-function TBaseVirtualTree.GetTreeFromDataObject(const DataObject: IDataObject): 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 TBaseVirtualTree.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
-  {
-  FillChar(Medium, SizeOf(Medium), 0);
-  // 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.PunkForRelease := 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.Pstm) := 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;
-
-
-//----------------------------------------------------------------------------------------------------------------------
-
-type
-  // needed to handle OLE global memory objects
-  TOLEMemoryStream = class(TCustomMemoryStream)
-  public
-    function Write(const Buffer; Count: Integer): Longint; override;
-  end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer;
-
-begin
-  //raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError));
-  raise EStreamError.Create(SCantWriteResourceStreamError);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ProcessOLEData(Source: TBaseVirtualTree; DataObject: IDataObject; TargetNode: PVirtualNode;
-  Mode: TVTNodeAttachMode; Optimized: Boolean): Boolean;
-
-// Recreates the (sub) tree structure serialized into memory and provided by DataObject. The new nodes are attached to
-// the passed node or FRoot if TargetNode is nil according to Mode. Optimized can be set to True if the entire operation
-// happens within the same process (i.e. sender and receiver of the OLE operation are located in the same process).
-// Optimize = True makes only sense if the operation to carry out is a move hence it is also the indication of the
-// operation to be done here. Source is the source of the OLE data and only of use (and usually assigned) when
-// an OLE operation takes place in the same application.
-// Returns True on success, i.e. the CF_VIRTUALTREE format is supported by the data object and the structure could be
-// recreated, otherwise False.
-
-var
-  Medium: TStgMedium;
-  Stream: TStream;
-  Data: Pointer;
-  Node: PVirtualNode;
-  Nodes: TNodeArray;
-  I: Integer;
-  Res: HRESULT;
-  ChangeReason: TChangeReason;
-
-begin
-  {
-  Nodes := nil;
-  // Check the data format available by the data object.
-  with StandardOLEFormat do
-  begin
-    // Read best format.
-    cfFormat := CF_VIRTUALTREE;
-  end;
-  Result := DataObject.QueryGetData(StandardOLEFormat) = S_OK;
-  if Result and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    BeginUpdate;
-    Result := False;
-    try
-      if TargetNode = nil then
-        TargetNode := FRoot;
-      if TargetNode = FRoot then
-      begin
-        case Mode of
-          amInsertBefore:
-            Mode := amAddChildFirst;
-          amInsertAfter:
-            Mode := amAddChildLast;
-        end;
-      end;
-
-      // Optimized means source is known and in the same process so we can access its pointers, which avoids duplicating
-      // the data while doing a serialization. Can only be used with cut'n paste and drag'n drop with move effect.
-      if Optimized then
-      begin
-        if tsOLEDragging in Source.FStates then
-          Nodes := Source.FDragSelection
-        else
-          Nodes := Source.GetSortedCutCopySet(True);
-
-        if Mode in [amInsertBefore,amAddChildLast] then
-        begin
-          for I := 0 to High(Nodes) do
-            if not HasAsParent(TargetNode, Nodes[I]) then
-              Source.MoveTo(Nodes[I], TargetNode, Mode, False);
-        end
-        else
-        begin
-          for I := High(Nodes) downto 0 do
-            if not HasAsParent(TargetNode, Nodes[I]) then
-              Source.MoveTo(Nodes[I], TargetNode, Mode, False);
-        end;
-        Result := True;
-      end
-      else
-      begin
-        if Source = Self then
-          ChangeReason := crNodeCopied
-        else
-          ChangeReason := crNodeAdded;
-        Res := DataObject.GetData(StandardOLEFormat, Medium);
-        if Res = S_OK then
-        begin
-          case Medium.tymed of
-            TYMED_ISTREAM, // IStream interface
-            TYMED_HGLOBAL: // global memory block
-              begin
-                Stream := nil;
-                if Medium.tymed = TYMED_ISTREAM then
-                  Stream := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream)
-                else
-                begin
-                  Data := GlobalLock(Medium.hGlobal);
-                  if Assigned(Data) then
-                  begin
-                    // Get the total size of data to retrieve.
-                    I := PCardinal(Data)^;
-                    Inc(PCardinal(Data));
-                    Stream := TOLEMemoryStream.Create;
-                    TOLEMemoryStream(Stream).SetPointer(Data, I);
-                  end;
-                end;
-                if Assigned(Stream) then
-                try
-                  while Stream.Position < Stream.Size do
-                  begin
-                    Node := MakeNewNode;
-                    InternalConnectNode(Node, TargetNode, Self, Mode);
-                    InternalAddFromStream(Stream, VTTreeStreamVersion, Node);
-                    // This seems a bit strange because of the callback for granting to add the node
-                    // which actually comes after the node has been added. The reason is that the node must
-                    // contain valid data otherwise I don't see how the application can make a funded decision.
-                    if not DoNodeCopying(Node, TargetNode) then
-                      DeleteNode(Node)
-                    else
-                      DoNodeCopied(Node);
-                    StructureChange(Node, ChangeReason);
-
-                    // In order to maintain the same node order when restoring nodes in the case of amInsertAfter
-                    // we have to move the reference node continously. Othwise we would end up with reversed node order.
-                    if Mode = amInsertAfter then
-                      TargetNode := Node;
-                  end;
-                  Result := True;
-                finally
-                  Stream.Free;
-                  if Medium.tymed = TYMED_HGLOBAL then
-                    GlobalUnlock(Medium.hGlobal);
-                end;
-              end;
-          end;
-          ReleaseStgMedium(@Medium);
-        end;
-      end;
-    finally
-      EndUpdate;
-    end;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ContentToClipboard(Format: Word; Source: TVSTTextSourceType): HGLOBAL;
-
-// This method constructs a shareable memory object filled with string data in the required format. Supported are:
-// CF_TEXT - plain ANSI text (Unicode text is converted using the user's current locale)
-// CF_UNICODETEXT - plain Unicode text
-// CF_CSV - comma separated plain ANSI text
-// CF_VRTF + CF_RTFNOOBS - rich text (plain ANSI)
-// CF_HTML - HTML text encoded using UTF-8
-//
-// Result is the handle to a globally allocated memory block which can directly be used for clipboard and drag'n drop
-// transfers. The caller is responsible for freeing the memory. If for some reason the content could not be rendered
-// the Result is 0.
-
-  //--------------- local function --------------------------------------------
-{
-  procedure MakeFragment(var HTML: string);
-
-  // Helper routine to build a properly-formatted HTML fragment.
-
-  const
-    Version = 'Version:1.0'#13#10;
-    StartHTML = 'StartHTML:';
-    EndHTML = 'EndHTML:';
-    StartFragment = 'StartFragment:';
-    EndFragment = 'EndFragment:';
-    DocType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
-    HTMLIntro = '<html><head><META http-equiv=Content-Type content="text/html; charset=utf-8">' +
-      '</head><body><!--StartFragment-->';
-    HTMLExtro = '<!--EndFragment--></body></html>';
-    NumberLengthAndCR = 10;
-
-    // Let the compiler determine the description length.
-    DescriptionLength = Length(Version) + Length(StartHTML) + Length(EndHTML) + Length(StartFragment) +
-      Length(EndFragment) + 4 * NumberLengthAndCR;
-
-  var
-    Description: string;
-    StartHTMLIndex,
-    EndHTMLIndex,
-    StartFragmentIndex,
-    EndFragmentIndex: Integer;
-
-  begin
-    // The HTML clipboard format is defined by using byte positions in the entire block where HTML text and
-    // fragments start and end. These positions are written in a description. Unfortunately the positions depend on the
-    // length of the description but the description may change with varying positions.
-    // To solve this dilemma the offsets are converted into fixed length strings which makes it possible to know
-    // the description length in advance.
-    StartHTMLIndex := DescriptionLength;              // position 0 after the description
-    StartFragmentIndex := StartHTMLIndex + Length(DocType) + Length(HTMLIntro);
-    EndFragmentIndex := StartFragmentIndex + Length(HTML);
-    EndHTMLIndex := EndFragmentIndex + Length(HTMLExtro);
-
-    Description := Version +
-      SysUtils.Format('%s%.8d', [StartHTML, StartHTMLIndex]) + #13#10 +
-      SysUtils.Format('%s%.8d', [EndHTML, EndHTMLIndex]) + #13#10 +
-      SysUtils.Format('%s%.8d', [StartFragment, StartFragmentIndex]) + #13#10 +
-      SysUtils.Format('%s%.8d', [EndFragment, EndFragmentIndex]) + #13#10;
-    HTML := Description + DocType + HTMLIntro + HTML + HTMLExtro;
-  end;
- }
-  //--------------- end local function ----------------------------------------
-
-var
-  Data: Pointer;
-  DataSize: Cardinal;
-  S: string;
-  WS: WideString;
-  P: Pointer;
-
-begin
-  Result := 0;
-  {
-  case Format of
-    CF_TEXT:
-      begin
-        S := ContentToText(Source, #9) + #0;
-        Data := PChar(S);
-        DataSize := Length(S);
-      end;
-    CF_UNICODETEXT:
-      begin
-        WS := ContentToUnicode(Source, #9) + #0;
-        Data := PWideChar(WS);
-        DataSize := 2 * Length(WS);
-      end;
-  else
-    if Format = CF_CSV then
-      S := ContentToText(Source, ListSeparator) + #0
-    else
-      if (Format = CF_VRTF) or (Format = CF_VRTFNOOBJS) then
-        S := ContentToRTF(Source) + #0
-      else
-        if Format = CF_HTML then
-        begin
-          S := ContentToHTML(Source);
-          // Build a valid HTML clipboard fragment.
-          MakeFragment(S);
-          S := S + #0;
-        end;
-    Data := PChar(S);
-    DataSize := Length(S);
-  end;
-
-  if DataSize > 0 then
-  begin
-    Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize);
-    P := GlobalLock(Result);
-    Move(Data^, P^, DataSize);
-    GlobalUnlock(Result);
-  end;
-  }
-end;

+ 0 - 2
components/virtualtreeview/include/intf/gtk/olemethods.inc

@@ -1,2 +0,0 @@
-
-{$i ../dummyolemethods.inc}

+ 0 - 67
components/virtualtreeview/include/intf/gtk/vtgraphicsi.inc

@@ -1,67 +0,0 @@
-uses
-  gtkdef, gtkint, CairoXlib, gdk, Cairo, glib;
-
-//procedure gdk_drawable_get_size(drawable: PGdkDrawable; width, height: Pgint); cdecl; external gdkdll;
-
-procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer);
-
-  function CreateSurface(GtkDC: TGtkDeviceContext): Pcairo_surface_t;
-  var
-    Width, Height: gint;
-    Visual: PGdkVisual;
-  begin
-    Result := nil;
-    if (GtkDC <> nil) and (GtkDC.Drawable <> nil) then
-    begin
-      gdk_window_get_size(GtkDC.Drawable, @Width, @Height);
-      Visual := gdk_visual_get_system;
-      Result := cairo_xlib_surface_create(
-        GDK_WINDOW_XDISPLAY(PGdkWindowPrivate(GtkDC.Drawable)),
-        GDK_WINDOW_XWINDOW(PGdkWindowPrivate(GtkDC.Drawable)),
-        GDK_VISUAL_XVISUAL(PGdkVisualPrivate(Visual)),
-        Width, Height);
-    end;
-  end;
-
-var
-  SrcDC: TGtkDeviceContext absolute Source;
-  DestDC: TGtkDeviceContext absolute Destination;
-  SrcSurface, DestSurface: Pcairo_surface_t;
-  SrcContext, DestContext: Pcairo_t;
-begin
-  case Mode of
-    bmConstantAlpha:;
-    bmPerPixelAlpha:;
-    bmMasterAlpha:;
-    bmConstantAlphaAndColor:
-      begin
-        DestSurface := CreateSurface(DestDC);
-        if DestSurface <> nil then
-        begin
-          DestContext := cairo_create(DestSurface);
-          cairo_set_source_rgba(DestContext,
-            (Bias and $000000FF) / 255,
-            ((Bias shr 8) and $000000FF) / 255,
-            ((Bias shr 16) and $000000FF) / 255,
-            ConstantAlpha / 255
-            );
-          cairo_rectangle(DestContext, R.Left + Target.x, R.Top + Target.y,
-            R.Right - R.Left, R.Bottom - R.Top);
-          cairo_fill(DestContext);
-
-          cairo_destroy(DestContext);
-          cairo_surface_destroy(DestSurface);
-        end;
-      end;
-  end;
-end;
-
-function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer;
-begin
-  Result := nil;
-end;
-
-function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer;
-begin
-  Result := nil;
-end;

+ 0 - 2
components/virtualtreeview/include/intf/gtk/vtvdragmanager.inc

@@ -1,2 +0,0 @@
-
-{$i ../dummydragmanager.inc}

+ 0 - 2
components/virtualtreeview/include/intf/gtk2/olemethods.inc

@@ -1,2 +0,0 @@
-
-{$i ../dummyolemethods.inc}

+ 0 - 59
components/virtualtreeview/include/intf/gtk2/vtgraphicsi.inc

@@ -1,59 +0,0 @@
-uses
-  gtk2def, gdk2, GTK2Proc, Cairo, LCLVersion;
-
-{$MACRO ON}
-
-{$if lcl_fullversion > 1000000}
-{$define TGtk2DeviceContext:=TGtkDeviceContext}
-{$endif}
-
-function gdk_cairo_create(drawable: PGdkDrawable): Pcairo_t cdecl external gdklib;
-
-procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer);
-
-  function GetContext(GtkDC: TGtk2DeviceContext): Pcairo_t;
-  begin
-    Result := nil;
-    if (GtkDC <> nil) and (GtkDC.Drawable <> nil) then
-        Result := gdk_cairo_create(GtkDC.Drawable);
-  end;
-
-var
-  SrcDC: TGtk2DeviceContext absolute Source;
-  DestDC: TGtk2DeviceContext absolute Destination;
-  SrcContext, DestContext: Pcairo_t;
-begin
-  case Mode of
-    bmConstantAlpha:;
-    bmPerPixelAlpha:;
-    bmMasterAlpha:;
-    bmConstantAlphaAndColor:
-      begin
-        DestContext := GetContext(DestDC);
-        if DestContext <> nil then
-        begin
-          cairo_set_source_rgba(DestContext,
-            (Bias and $000000FF) / 255,
-            ((Bias shr 8) and $000000FF) / 255,
-            ((Bias shr 16) and $000000FF) / 255,
-            ConstantAlpha / 255
-            );
-          cairo_rectangle(DestContext, R.Left + Target.x, R.Top + Target.y,
-            R.Right - R.Left, R.Bottom - R.Top);
-          cairo_fill(DestContext);
-
-          cairo_destroy(DestContext);
-        end;
-      end;
-  end;
-end;
-
-function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer;
-begin
-  Result := nil;
-end;
-
-function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer;
-begin
-  Result := nil;
-end;

+ 0 - 2
components/virtualtreeview/include/intf/gtk2/vtvdragmanager.inc

@@ -1,2 +0,0 @@
-
-{$i ../dummydragmanager.inc}

+ 0 - 2
components/virtualtreeview/include/intf/qt/olemethods.inc

@@ -1,2 +0,0 @@
-
-{$i ../dummyolemethods.inc}

+ 0 - 858
components/virtualtreeview/include/intf/qt/vtgraphicsi.inc

@@ -1,858 +0,0 @@
-uses
-  qt4, qtobjects;
-
-{$ASMMODE INTEL}
-
-procedure AlphaBlendLineConstant(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer);
-
-// Blends a line of Count pixels from Source to Destination using a constant alpha value.
-// The layout of a pixel must be BGRA where A is ignored (but is calculated as the other components).
-// ConstantAlpha must be in the range 0..255 where 0 means totally transparent (destination pixel only)
-// and 255 totally opaque (source pixel only).
-// Bias is an additional value which gets added to every component and must be in the range -128..127
-
-asm
-
-{$ifdef CPU64}
-//windows
-// RCX contains Source
-// RDX contains Destination
-// R8D contains Count
-// R9D contains ConstantAlpha
-// Bias is on the stack
-
-//non windows
-// RDI contains Source
-// RSI contains Destination
-// EDX contains Count
-// ECX contains ConstantAlpha
-// R8D contains Bias
-
-        //.NOFRAME
-
-        // Load XMM3 with the constant alpha value (replicate it for every component).
-        // Expand it to word size.
-        {$ifdef windows}
-        MOVD        XMM3, R9D  // ConstantAlpha
-        {$else}
-        MOVD        XMM3, ECX  // ConstantAlpha
-        {$endif}
-        PUNPCKLWD   XMM3, XMM3
-        PUNPCKLDQ   XMM3, XMM3
-
-        // Load XMM5 with the bias value.
-        {$ifdef windows}
-        MOVD        XMM5, [Bias]
-        {$else}
-        MOVD        XMM5, R8D  //Bias
-        {$endif}
-        PUNPCKLWD   XMM5, XMM5
-        PUNPCKLDQ   XMM5, XMM5
-
-        // Load XMM4 with 128 to allow for saturated biasing.
-        MOV         R10D, 128
-        MOVD        XMM4, R10D
-        PUNPCKLWD   XMM4, XMM4
-        PUNPCKLDQ   XMM4, XMM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        {$ifdef windows}
-        MOVD        XMM1, DWORD PTR [RCX]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RDX]   // data is unaligned
-        {$else}
-        MOVD        XMM1, DWORD PTR [RDI]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RSI]   // data is unaligned
-        {$endif}
-        PXOR        XMM0, XMM0    // clear source pixel register for unpacking
-        PUNPCKLBW   XMM0, XMM1{[RCX]}    // unpack source pixel byte values into words
-        PSRLW       XMM0, 8       // move higher bytes to lower bytes
-        PXOR        XMM1, XMM1    // clear target pixel register for unpacking
-        PUNPCKLBW   XMM1, XMM2{[RDX]}    // unpack target pixel byte values into words
-        MOVQ        XMM2, XMM1    // make a copy of the shifted values, we need them again
-        PSRLW       XMM1, 8       // move higher bytes to lower bytes
-
-        // calculation is: target = (alpha * (source - target) + 256 * target) / 256
-        PSUBW       XMM0, XMM1    // source - target
-        PMULLW      XMM0, XMM3    // alpha * (source - target)
-        PADDW       XMM0, XMM2    // add target (in shifted form)
-        PSRLW       XMM0, 8       // divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        PSUBW     XMM0, XMM4
-        PADDSW    XMM0, XMM5
-        PADDW     XMM0, XMM4
-        PACKUSWB  XMM0, XMM0      // convert words to bytes with saturation
-        {$ifdef windows}
-        MOVD      DWORD PTR [RDX], XMM0     // store the result
-        {$else}
-        MOVD      DWORD PTR [RSI], XMM0     // store the result
-        {$endif}
-@3:
-        {$ifdef windows}
-        ADD       RCX, 4
-        ADD       RDX, 4
-        DEC       R8D
-        {$else}
-        ADD       RDI, 4
-        ADD       RSI, 4
-        DEC       EDX
-        {$endif}
-        JNZ       @1
-
-
-{$else}
-// EAX contains Source
-// EDX contains Destination
-// ECX contains Count
-// ConstantAlpha and Bias are on the stack
-
-
-        PUSH    ESI                    // save used registers
-        PUSH    EDI
-
-        MOV     ESI, EAX               // ESI becomes the actual source pointer
-        MOV     EDI, EDX               // EDI becomes the actual target pointer
-
-        // Load MM6 with the constant alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOV     EAX, [ConstantAlpha]
-        DB      $0F, $6E, $F0          /// MOVD      MM6, EAX
-        DB      $0F, $61, $F6          /// PUNPCKLWD MM6, MM6
-        DB      $0F, $62, $F6          /// PUNPCKLDQ MM6, MM6
-
-        // Load MM5 with the bias value.
-        MOV     EAX, [Bias]
-        DB      $0F, $6E, $E8          /// MOVD      MM5, EAX
-        DB      $0F, $61, $ED          /// PUNPCKLWD MM5, MM5
-        DB      $0F, $62, $ED          /// PUNPCKLDQ MM5, MM5
-
-        // Load MM4 with 128 to allow for saturated biasing.
-        MOV     EAX, 128
-        DB      $0F, $6E, $E0          /// MOVD      MM4, EAX
-        DB      $0F, $61, $E4          /// PUNPCKLWD MM4, MM4
-        DB      $0F, $62, $E4          /// PUNPCKLDQ MM4, MM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        DB      $0F, $EF, $C0          /// PXOR      MM0, MM0,   clear source pixel register for unpacking
-        DB      $0F, $60, $06          /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     move higher bytes to lower bytes
-        DB      $0F, $EF, $C9          /// PXOR      MM1, MM1,   clear target pixel register for unpacking
-        DB      $0F, $60, $0F          /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words
-        DB      $0F, $6F, $D1          /// MOVQ      MM2, MM1,   make a copy of the shifted values, we need them again
-        DB      $0F, $71, $D1, $08     /// PSRLW     MM1, 8,     move higher bytes to lower bytes
-
-        // calculation is: target = (alpha * (source - target) + 256 * target) / 256
-        DB      $0F, $F9, $C1          /// PSUBW     MM0, MM1,   source - target
-        DB      $0F, $D5, $C6          /// PMULLW    MM0, MM6,   alpha * (source - target)
-        DB      $0F, $FD, $C2          /// PADDW     MM0, MM2,   add target (in shifted form)
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        DB      $0F, $F9, $C4          /// PSUBW     MM0, MM4
-        DB      $0F, $ED, $C5          /// PADDSW    MM0, MM5
-        DB      $0F, $FD, $C4          /// PADDW     MM0, MM4
-        DB      $0F, $67, $C0          /// PACKUSWB  MM0, MM0,   convert words to bytes with saturation
-        DB      $0F, $7E, $07          /// MOVD      [EDI], MM0, store the result
-@3:
-        ADD     ESI, 4
-        ADD     EDI, 4
-        DEC     ECX
-        JNZ     @1
-        POP     EDI
-        POP     ESI
-{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure AlphaBlendLinePerPixel(Source, Destination: Pointer; Count, Bias: Integer);
-
-// Blends a line of Count pixels from Source to Destination using the alpha value of the source pixels.
-// The layout of a pixel must be BGRA.
-// Bias is an additional value which gets added to every component and must be in the range -128..127
-
-asm
-
-{$ifdef CPU64}
-//windows
-// RCX contains Source
-// RDX contains Destination
-// R8D contains Count
-// R9D contains Bias
-
-//non windows
-// RDI contains Source
-// RSI contains Destination
-// EDX contains Count
-// ECX contains Bias
-
-        //.NOFRAME
-
-        // Load XMM5 with the bias value.
-        {$ifdef windows}
-        MOVD        XMM5, R9D   // Bias
-        {$else}
-        MOVD        XMM5, ECX   // Bias
-        {$endif}
-        PUNPCKLWD   XMM5, XMM5
-        PUNPCKLDQ   XMM5, XMM5
-
-        // Load XMM4 with 128 to allow for saturated biasing.
-        MOV         R10D, 128
-        MOVD        XMM4, R10D
-        PUNPCKLWD   XMM4, XMM4
-        PUNPCKLDQ   XMM4, XMM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        {$ifdef windows}
-        MOVD        XMM1, DWORD PTR [RCX]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RDX]   // data is unaligned
-        {$else}
-        MOVD        XMM1, DWORD PTR [RDI]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RSI]   // data is unaligned
-        {$endif}
-        PXOR        XMM0, XMM0    // clear source pixel register for unpacking
-        PUNPCKLBW   XMM0, XMM1{[RCX]}    // unpack source pixel byte values into words
-        PSRLW       XMM0, 8       // move higher bytes to lower bytes
-        PXOR        XMM1, XMM1    // clear target pixel register for unpacking
-        PUNPCKLBW   XMM1, XMM2{[RDX]}    // unpack target pixel byte values into words
-        MOVQ        XMM2, XMM1    // make a copy of the shifted values, we need them again
-        PSRLW       XMM1, 8       // move higher bytes to lower bytes
-
-        // Load XMM3 with the source alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOVQ        XMM3, XMM0
-        PUNPCKHWD   XMM3, XMM3
-        PUNPCKHDQ   XMM3, XMM3
-
-        // calculation is: target = (alpha * (source - target) + 256 * target) / 256
-        PSUBW       XMM0, XMM1    // source - target
-        PMULLW      XMM0, XMM3    // alpha * (source - target)
-        PADDW       XMM0, XMM2    // add target (in shifted form)
-        PSRLW       XMM0, 8       // divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        PSUBW       XMM0, XMM4
-        PADDSW      XMM0, XMM5
-        PADDW       XMM0, XMM4
-        PACKUSWB    XMM0, XMM0    // convert words to bytes with saturation
-        {$ifdef windows}
-        MOVD        DWORD PTR [RDX], XMM0   // store the result
-        {$else}
-        MOVD        DWORD PTR [RSI], XMM0   // store the result
-        {$endif}
-@3:
-        {$ifdef windows}
-        ADD         RCX, 4
-        ADD         RDX, 4
-        DEC         R8D
-        {$else}
-        ADD         RDI, 4
-        ADD         RSI, 4
-        DEC         EDX
-        {$endif}
-        JNZ         @1
-
-
-{$else}
-
-// EAX contains Source
-// EDX contains Destination
-// ECX contains Count
-// Bias is on the stack
-
-        PUSH    ESI                    // save used registers
-        PUSH    EDI
-
-        MOV     ESI, EAX               // ESI becomes the actual source pointer
-        MOV     EDI, EDX               // EDI becomes the actual target pointer
-
-        // Load MM5 with the bias value.
-        MOV     EAX, [Bias]
-        DB      $0F, $6E, $E8          /// MOVD      MM5, EAX
-        DB      $0F, $61, $ED          /// PUNPCKLWD MM5, MM5
-        DB      $0F, $62, $ED          /// PUNPCKLDQ MM5, MM5
-
-        // Load MM4 with 128 to allow for saturated biasing.
-        MOV     EAX, 128
-        DB      $0F, $6E, $E0          /// MOVD      MM4, EAX
-        DB      $0F, $61, $E4          /// PUNPCKLWD MM4, MM4
-        DB      $0F, $62, $E4          /// PUNPCKLDQ MM4, MM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        DB      $0F, $EF, $C0          /// PXOR      MM0, MM0,   clear source pixel register for unpacking
-        DB      $0F, $60, $06          /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     move higher bytes to lower bytes
-        DB      $0F, $EF, $C9          /// PXOR      MM1, MM1,   clear target pixel register for unpacking
-        DB      $0F, $60, $0F          /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words
-        DB      $0F, $6F, $D1          /// MOVQ      MM2, MM1,   make a copy of the shifted values, we need them again
-        DB      $0F, $71, $D1, $08     /// PSRLW     MM1, 8,     move higher bytes to lower bytes
-
-        // Load MM6 with the source alpha value (replicate it for every component).
-        // Expand it to word size.
-        DB      $0F, $6F, $F0          /// MOVQ MM6, MM0
-        DB      $0F, $69, $F6          /// PUNPCKHWD MM6, MM6
-        DB      $0F, $6A, $F6          /// PUNPCKHDQ MM6, MM6
-
-        // calculation is: target = (alpha * (source - target) + 256 * target) / 256
-        DB      $0F, $F9, $C1          /// PSUBW     MM0, MM1,   source - target
-        DB      $0F, $D5, $C6          /// PMULLW    MM0, MM6,   alpha * (source - target)
-        DB      $0F, $FD, $C2          /// PADDW     MM0, MM2,   add target (in shifted form)
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        DB      $0F, $F9, $C4          /// PSUBW     MM0, MM4
-        DB      $0F, $ED, $C5          /// PADDSW    MM0, MM5
-        DB      $0F, $FD, $C4          /// PADDW     MM0, MM4
-        DB      $0F, $67, $C0          /// PACKUSWB  MM0, MM0,   convert words to bytes with saturation
-        DB      $0F, $7E, $07          /// MOVD      [EDI], MM0, store the result
-@3:
-        ADD     ESI, 4
-        ADD     EDI, 4
-        DEC     ECX
-        JNZ     @1
-        POP     EDI
-        POP     ESI
-{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure AlphaBlendLineMaster(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer);
-
-// Blends a line of Count pixels from Source to Destination using the source pixel and a constant alpha value.
-// The layout of a pixel must be BGRA.
-// ConstantAlpha must be in the range 0..255.
-// Bias is an additional value which gets added to every component and must be in the range -128..127
-
-asm
-
-{$ifdef CPU64}
-//windows
-// RCX contains Source
-// RDX contains Destination
-// R8D contains Count
-// R9D contains ConstantAlpha
-// Bias is on the stack
-
-//non windows
-// RDI contains Source
-// RSI contains Destination
-// EDX contains Count
-// ECX contains ConstantAlpha
-// R8D contains Bias
-
-        //.SAVENV XMM6  //todo see how implement in fpc
-
-        // Load XMM3 with the constant alpha value (replicate it for every component).
-        // Expand it to word size.
-        {$ifdef windows}
-        MOVD        XMM3, R9D    // ConstantAlpha
-        {$else}
-        MOVD        XMM3, ECX    // ConstantAlpha
-        {$endif}
-        PUNPCKLWD   XMM3, XMM3
-        PUNPCKLDQ   XMM3, XMM3
-
-        // Load XMM5 with the bias value.
-        {$ifdef windows}
-        MOV         R10D, [Bias]
-        MOVD        XMM5, R10D
-        {$else}
-        MOVD        XMM5, R8D
-        {$endif}
-        PUNPCKLWD   XMM5, XMM5
-        PUNPCKLDQ   XMM5, XMM5
-
-        // Load XMM4 with 128 to allow for saturated biasing.
-        MOV         R10D, 128
-        MOVD        XMM4, R10D
-        PUNPCKLWD   XMM4, XMM4
-        PUNPCKLDQ   XMM4, XMM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        {$ifdef windows}
-        MOVD        XMM1, DWORD PTR [RCX]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RDX]   // data is unaligned
-        {$else}
-        MOVD        XMM1, DWORD PTR [RDI]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RSI]   // data is unaligned
-        {$endif}
-        PXOR        XMM0, XMM0    // clear source pixel register for unpacking
-        PUNPCKLBW   XMM0, XMM1{[RCX]}     // unpack source pixel byte values into words
-        PSRLW       XMM0, 8       // move higher bytes to lower bytes
-        PXOR        XMM1, XMM1    // clear target pixel register for unpacking
-        PUNPCKLBW   XMM1, XMM2{[RCX]}     // unpack target pixel byte values into words
-        MOVQ        XMM2, XMM1    // make a copy of the shifted values, we need them again
-        PSRLW       XMM1, 8       // move higher bytes to lower bytes
-
-        // Load XMM6 with the source alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOVQ        XMM6, XMM0
-        PUNPCKHWD   XMM6, XMM6
-        PUNPCKHDQ   XMM6, XMM6
-        PMULLW      XMM6, XMM3    // source alpha * master alpha
-        PSRLW       XMM6, 8       // divide by 256
-
-        // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256
-        PSUBW       XMM0, XMM1    // source - target
-        PMULLW      XMM0, XMM6    // alpha * (source - target)
-        PADDW       XMM0, XMM2    // add target (in shifted form)
-        PSRLW       XMM0, 8       // divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        PSUBW       XMM0, XMM4
-        PADDSW      XMM0, XMM5
-        PADDW       XMM0, XMM4
-        PACKUSWB    XMM0, XMM0    // convert words to bytes with saturation
-        {$ifdef windows}
-        MOVD        DWORD PTR [RDX], XMM0   // store the result
-        {$else}
-        MOVD        DWORD PTR [RSI], XMM0   // store the result
-        {$endif}
-@3:
-        {$ifdef windows}
-        ADD         RCX, 4
-        ADD         RDX, 4
-        DEC         R8D
-        {$else}
-        ADD         RDI, 4
-        ADD         RSI, 4
-        DEC         EDX
-        {$endif}
-        JNZ         @1
-
-{$else}
-
-// EAX contains Source
-// EDX contains Destination
-// ECX contains Count
-// ConstantAlpha and Bias are on the stack
-
-
-        PUSH    ESI                    // save used registers
-        PUSH    EDI
-
-        MOV     ESI, EAX               // ESI becomes the actual source pointer
-        MOV     EDI, EDX               // EDI becomes the actual target pointer
-
-        // Load MM6 with the constant alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOV     EAX, [ConstantAlpha]
-        DB      $0F, $6E, $F0          /// MOVD      MM6, EAX
-        DB      $0F, $61, $F6          /// PUNPCKLWD MM6, MM6
-        DB      $0F, $62, $F6          /// PUNPCKLDQ MM6, MM6
-
-        // Load MM5 with the bias value.
-        MOV     EAX, [Bias]
-        DB      $0F, $6E, $E8          /// MOVD      MM5, EAX
-        DB      $0F, $61, $ED          /// PUNPCKLWD MM5, MM5
-        DB      $0F, $62, $ED          /// PUNPCKLDQ MM5, MM5
-
-        // Load MM4 with 128 to allow for saturated biasing.
-        MOV     EAX, 128
-        DB      $0F, $6E, $E0          /// MOVD      MM4, EAX
-        DB      $0F, $61, $E4          /// PUNPCKLWD MM4, MM4
-        DB      $0F, $62, $E4          /// PUNPCKLDQ MM4, MM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        DB      $0F, $EF, $C0          /// PXOR      MM0, MM0,   clear source pixel register for unpacking
-        DB      $0F, $60, $06          /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     move higher bytes to lower bytes
-        DB      $0F, $EF, $C9          /// PXOR      MM1, MM1,   clear target pixel register for unpacking
-        DB      $0F, $60, $0F          /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words
-        DB      $0F, $6F, $D1          /// MOVQ      MM2, MM1,   make a copy of the shifted values, we need them again
-        DB      $0F, $71, $D1, $08     /// PSRLW     MM1, 8,     move higher bytes to lower bytes
-
-        // Load MM7 with the source alpha value (replicate it for every component).
-        // Expand it to word size.
-        DB      $0F, $6F, $F8          /// MOVQ      MM7, MM0
-        DB      $0F, $69, $FF          /// PUNPCKHWD MM7, MM7
-        DB      $0F, $6A, $FF          /// PUNPCKHDQ MM7, MM7
-        DB      $0F, $D5, $FE          /// PMULLW    MM7, MM6,   source alpha * master alpha
-        DB      $0F, $71, $D7, $08     /// PSRLW     MM7, 8,     divide by 256
-
-        // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256
-        DB      $0F, $F9, $C1          /// PSUBW     MM0, MM1,   source - target
-        DB      $0F, $D5, $C7          /// PMULLW    MM0, MM7,   alpha * (source - target)
-        DB      $0F, $FD, $C2          /// PADDW     MM0, MM2,   add target (in shifted form)
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        DB      $0F, $F9, $C4          /// PSUBW     MM0, MM4
-        DB      $0F, $ED, $C5          /// PADDSW    MM0, MM5
-        DB      $0F, $FD, $C4          /// PADDW     MM0, MM4
-        DB      $0F, $67, $C0          /// PACKUSWB  MM0, MM0,   convert words to bytes with saturation
-        DB      $0F, $7E, $07          /// MOVD      [EDI], MM0, store the result
-@3:
-        ADD     ESI, 4
-        ADD     EDI, 4
-        DEC     ECX
-        JNZ     @1
-        POP     EDI
-        POP     ESI
-{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure AlphaBlendLineMasterAndColor(Destination: Pointer; Count: Integer; ConstantAlpha, Color: Integer);
-
-// Blends a line of Count pixels in Destination against the given color using a constant alpha value.
-// The layout of a pixel must be BGRA and Color must be rrggbb00 (as stored by a COLORREF).
-// ConstantAlpha must be in the range 0..255.
-
-asm
-
-{$ifdef CPU64}
-//windows
-// RCX contains Destination
-// EDX contains Count
-// R8D contains ConstantAlpha
-// R9D contains Color
-
-//non windows
-// RDI contains Destination
-// ESI contains Count
-// EDX contains ConstantAlpha
-// ECX contains Color
-
-        //.NOFRAME
-
-        // The used formula is: target = (alpha * color + (256 - alpha) * target) / 256.
-        // alpha * color (factor 1) and 256 - alpha (factor 2) are constant values which can be calculated in advance.
-        // The remaining calculation is therefore: target = (F1 + F2 * target) / 256
-
-        // Load XMM3 with the constant alpha value (replicate it for every component).
-        // Expand it to word size. (Every calculation here works on word sized operands.)
-        {$ifdef windows}
-        MOVD        XMM3, R8D   // ConstantAlpha
-        {$else}
-        MOVD        XMM3, EDX   // ConstantAlpha
-        {$endif}
-        PUNPCKLWD   XMM3, XMM3
-        PUNPCKLDQ   XMM3, XMM3
-
-        // Calculate factor 2.
-        MOV         R10D, $100
-        MOVD        XMM2, R10D
-        PUNPCKLWD   XMM2, XMM2
-        PUNPCKLDQ   XMM2, XMM2
-        PSUBW       XMM2, XMM3             // XMM2 contains now: 255 - alpha = F2
-
-        // Now calculate factor 1. Alpha is still in XMM3, but the r and b components of Color must be swapped.
-        {$ifdef windows}
-        BSWAP       R9D  // Color
-        ROR         R9D, 8
-        MOVD        XMM1, R9D              // Load the color and convert to word sized values.
-        {$else}
-        BSWAP       ECX  // Color
-        ROR         ECX, 8
-        MOVD        XMM1, ECX              // Load the color and convert to word sized values.
-        {$endif}
-        PXOR        XMM4, XMM4
-        PUNPCKLBW   XMM1, XMM4
-        PMULLW      XMM1, XMM3             // XMM1 contains now: color * alpha = F1
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        {$ifdef windows}
-        MOVD        XMM0, DWORD PTR [RCX]
-        {$else}
-        MOVD        XMM0, DWORD PTR [RDI]
-        {$endif}
-        PUNPCKLBW   XMM0, XMM4
-
-        PMULLW      XMM0, XMM2             // calculate F1 + F2 * target
-        PADDW       XMM0, XMM1
-        PSRLW       XMM0, 8                // divide by 256
-
-        PACKUSWB    XMM0, XMM0             // convert words to bytes with saturation
-        {$ifdef windows}
-        MOVD        DWORD PTR [RCX], XMM0            // store the result
-
-        ADD         RCX, 4
-        DEC         EDX
-        {$else}
-        MOVD        DWORD PTR [RDI], XMM0            // store the result
-
-        ADD         RDI, 4
-        DEC         ESI
-        {$endif}
-        JNZ         @1
-
-
-{$else}
-
-// EAX contains Destination
-// EDX contains Count
-// ECX contains ConstantAlpha
-// Color is passed on the stack
-
-
-        // The used formula is: target = (alpha * color + (256 - alpha) * target) / 256.
-        // alpha * color (factor 1) and 256 - alpha (factor 2) are constant values which can be calculated in advance.
-        // The remaining calculation is therefore: target = (F1 + F2 * target) / 256
-
-        // Load MM3 with the constant alpha value (replicate it for every component).
-        // Expand it to word size. (Every calculation here works on word sized operands.)
-        DB      $0F, $6E, $D9          /// MOVD      MM3, ECX
-        DB      $0F, $61, $DB          /// PUNPCKLWD MM3, MM3
-        DB      $0F, $62, $DB          /// PUNPCKLDQ MM3, MM3
-
-        // Calculate factor 2.
-        MOV     ECX, $100
-        DB      $0F, $6E, $D1          /// MOVD      MM2, ECX
-        DB      $0F, $61, $D2          /// PUNPCKLWD MM2, MM2
-        DB      $0F, $62, $D2          /// PUNPCKLDQ MM2, MM2
-        DB      $0F, $F9, $D3          /// PSUBW     MM2, MM3             // MM2 contains now: 255 - alpha = F2
-
-        // Now calculate factor 1. Alpha is still in MM3, but the r and b components of Color must be swapped.
-        MOV     ECX, [Color]
-        BSWAP   ECX
-        ROR     ECX, 8
-        DB      $0F, $6E, $C9          /// MOVD      MM1, ECX             // Load the color and convert to word sized values.
-        DB      $0F, $EF, $E4          /// PXOR      MM4, MM4
-        DB      $0F, $60, $CC          /// PUNPCKLBW MM1, MM4
-        DB      $0F, $D5, $CB          /// PMULLW    MM1, MM3             // MM1 contains now: color * alpha = F1
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        DB      $0F, $6E, $00          /// MOVD      MM0, [EAX]
-        DB      $0F, $60, $C4          /// PUNPCKLBW MM0, MM4
-
-        DB      $0F, $D5, $C2          /// PMULLW    MM0, MM2             // calculate F1 + F2 * target
-        DB      $0F, $FD, $C1          /// PADDW     MM0, MM1
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8               // divide by 256
-
-        DB      $0F, $67, $C0          /// PACKUSWB  MM0, MM0             // convert words to bytes with saturation
-        DB      $0F, $7E, $00          /// MOVD      [EAX], MM0           // store the result
-
-        ADD     EAX, 4
-        DEC     EDX
-        JNZ     @1
-{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure EMMS;
-
-// Reset MMX state to use the FPU for other tasks again.
-
-{$ifdef CPU64}
-  inline;
-  begin
-  end;
-
-{$else}
-
-asm
-        DB      $0F, $77               /// EMMS
-end;
-{$endif}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function GetBitmapBitsFromDeviceContext(DC: HDC; out Width, Height: Integer): Pointer;
-
-// Helper function used to retrieve the bitmap selected into the given device context. If there is a bitmap then
-// the function will return a pointer to its bits otherwise nil is returned.
-// Additionally the dimensions of the bitmap are returned.
-
-var
-  Bitmap: HBITMAP;
-  DIB: TDIBSection;
-
-begin
-  Result := nil;
-  Width := 0;
-  Height := 0;
-  Bitmap := GetCurrentObject(DC, OBJ_BITMAP);
-  if Bitmap <> 0 then
-  begin
-    if GetObject(Bitmap, SizeOf(DIB), @DIB) = SizeOf(DIB) then
-    begin
-      Assert(DIB.dsBm.bmPlanes * DIB.dsBm.bmBitsPixel = 32, 'Alpha blending error: bitmap must use 32 bpp.');
-      Result := DIB.dsBm.bmBits;
-      Width := DIB.dsBmih.biWidth;
-      Height := DIB.dsBmih.biHeight;
-    end;
-  end;
-  Assert(Result <> nil, 'Alpha blending DC error: no bitmap available.');
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer;
-var
-  DIB: TDIBSection;
-begin
-  Result := nil;
-  if Bitmap <> 0 then
-  begin
-    if GetObject(Bitmap, SizeOf(DIB), @DIB) = SizeOf(DIB) then
-    begin
-      Assert(DIB.dsBm.bmPlanes * DIB.dsBm.bmBitsPixel = 32, 'Alpha blending error: bitmap must use 32 bpp.');
-      Result := DIB.dsBm.bmBits;
-    end;
-  end;
-end;
-
-function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer;
-
-// Helper function to calculate the start address for the given row.
-
-begin
-  //todo: Height is always > 0 in LCL
-  {
-  if Height > 0 then  // bottom-up DIB
-    Row := Height - Row - 1;
-  }
-  // Return DWORD aligned address of the requested scanline.
-  Result := Bits + Row * ((Width * 32 + 31) and not 31) div 8;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer);
-
-// Optimized alpha blend procedure using MMX instructions to perform as quick as possible.
-// For this procedure to work properly it is important that both source and target bitmap use the 32 bit color format.
-// R describes the source rectangle to work on.
-// Target is the place (upper left corner) in the target bitmap where to blend to. Note that source width + X offset
-// must be less or equal to the target width. Similar for the height.
-// If Mode is bmConstantAlpha then the blend operation uses the given ConstantAlpha value for all pixels.
-// If Mode is bmPerPixelAlpha then each pixel is blended using its individual alpha value (the alpha value of the source).
-// If Mode is bmMasterAlpha then each pixel is blended using its individual alpha value multiplied by ConstantAlpha.
-// If Mode is bmConstantAlphaAndColor then each destination pixel is blended using ConstantAlpha but also a constant
-// color which will be obtained from Bias. In this case no offset value is added, otherwise Bias is used as offset.
-// Blending of a color into target only (bmConstantAlphaAndColor) ignores Source (the DC) and Target (the position).
-// CAUTION: This procedure does not check whether MMX instructions are actually available! Call it only if MMX is really
-//          usable.
-
-var
-  Y: Integer;
-  SourceRun,
-  TargetRun: PByte;
-
-  SourceBits,
-  DestBits: Pointer;
-  SourceWidth,
-  SourceHeight,
-  DestWidth,
-  DestHeight: Integer;
-
-  //BlendColor: TQColor;
-begin
-  if not IsRectEmpty(R) then
-  begin
-    {$ifdef CPU64}
-    //avoid MasterAlpha due to incomplete AlphaBlendLineMaster. See comment in procedure
-    if Mode = bmMasterAlpha then
-      Mode := bmConstantAlpha;
-    {$endif}
-    // Note: it is tempting to optimize the special cases for constant alpha 0 and 255 by just ignoring soure
-    //       (alpha = 0) or simply do a blit (alpha = 255). But this does not take the bias into account.
-    case Mode of
-      bmConstantAlpha:
-        begin
-          // Get a pointer to the bitmap bits for the source and target device contexts.
-          // Note: this supposes that both contexts do actually have bitmaps assigned!
-          SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight);
-          DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight);
-          if Assigned(SourceBits) and Assigned(DestBits) then
-          begin
-            for Y := 0 to R.Bottom - R.Top - 1 do
-            begin
-              SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top);
-              Inc(SourceRun, 4 * R.Left);
-              TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y);
-              Inc(TargetRun, 4 * Target.X);
-              AlphaBlendLineConstant(SourceRun, TargetRun, R.Right - R.Left, ConstantAlpha, Bias);
-            end;
-          end;
-          EMMS;
-        end;
-      bmPerPixelAlpha:
-        begin
-          SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight);
-          DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight);
-          if Assigned(SourceBits) and Assigned(DestBits) then
-          begin
-            for Y := 0 to R.Bottom - R.Top - 1 do
-            begin
-              SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top);
-              Inc(SourceRun, 4 * R.Left);
-              TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y);
-              Inc(TargetRun, 4 * Target.X);
-              AlphaBlendLinePerPixel(SourceRun, TargetRun, R.Right - R.Left, Bias);
-            end;
-          end;
-          EMMS;
-        end;
-      bmMasterAlpha:
-        begin
-          SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight);
-          DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight);
-          if Assigned(SourceBits) and Assigned(DestBits) then
-          begin
-            for Y := 0 to R.Bottom - R.Top - 1 do
-            begin
-              SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top);
-              Inc(SourceRun, 4 * Target.X);
-              TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y);
-              AlphaBlendLineMaster(SourceRun, TargetRun, R.Right - R.Left, ConstantAlpha, Bias);
-            end;
-          end;
-          EMMS;
-        end;
-      bmConstantAlphaAndColor:
-        begin
-          //todo: see why is not working
-          {
-          QColor_fromRgb(@BlendColor,
-            Bias and $000000FF,
-            (Bias shr 8) and $000000FF,
-            (Bias shr 16) and $000000FF,
-            ConstantAlpha);
-          QPainter_fillRect(TQTDeviceContext(Destination).Widget,
-            R.Left + Target.x, R.Top + Target.y,
-            R.Right - R.Left, R.Bottom - R.Top, @BlendColor);
-          }
-          // Source is ignored since there is a constant color value.
-
-          DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight);
-          if Assigned(DestBits) then
-          begin
-            for Y := 0 to R.Bottom - R.Top - 1 do
-            begin
-              TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + R.Top);
-              Inc(TargetRun, 4 * R.Left);
-              AlphaBlendLineMasterAndColor(TargetRun, R.Right - R.Left, ConstantAlpha, Bias);
-            end;
-          end;
-          EMMS;
-        end;
-    end;
-  end;
-end;
-
-
-

+ 0 - 2
components/virtualtreeview/include/intf/qt/vtvdragmanager.inc

@@ -1,2 +0,0 @@
-
-{$i ../dummydragmanager.inc}

+ 0 - 396
components/virtualtreeview/include/intf/win32/olemethods.inc

@@ -1,396 +0,0 @@
-function TBaseVirtualTree.GetTreeFromDataObject(const DataObject: IDataObject): 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 TBaseVirtualTree.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
-  FillChar(Medium, SizeOf(Medium), 0);
-  // 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.PunkForRelease := 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.Pstm) := 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;
-
-
-//----------------------------------------------------------------------------------------------------------------------
-
-type
-  // needed to handle OLE global memory objects
-  TOLEMemoryStream = class(TCustomMemoryStream)
-  public
-    function Write(const Buffer; Count: Integer): Longint; override;
-  end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer;
-
-begin
-  //raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError));
-  raise EStreamError.Create(SCantWriteResourceStreamError);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TBaseVirtualTree.ProcessOLEData(Source: TBaseVirtualTree; DataObject: IDataObject; TargetNode: PVirtualNode;
-  Mode: TVTNodeAttachMode; Optimized: Boolean): Boolean;
-
-// Recreates the (sub) tree structure serialized into memory and provided by DataObject. The new nodes are attached to
-// the passed node or FRoot if TargetNode is nil according to Mode. Optimized can be set to True if the entire operation
-// happens within the same process (i.e. sender and receiver of the OLE operation are located in the same process).
-// Optimize = True makes only sense if the operation to carry out is a move hence it is also the indication of the
-// operation to be done here. Source is the source of the OLE data and only of use (and usually assigned) when
-// an OLE operation takes place in the same application.
-// Returns True on success, i.e. the CF_VIRTUALTREE format is supported by the data object and the structure could be
-// recreated, otherwise False.
-
-var
-  Medium: TStgMedium;
-  Stream: TStream;
-  Data: Pointer;
-  Node: PVirtualNode;
-  Nodes: TNodeArray;
-  I: Integer;
-  Res: HRESULT;
-  ChangeReason: TChangeReason;
-
-begin
-  Nodes := nil;
-  // Check the data format available by the data object.
-  with StandardOLEFormat do
-  begin
-    // Read best format.
-    cfFormat := CF_VIRTUALTREE;
-  end;
-  Result := DataObject.QueryGetData(StandardOLEFormat) = S_OK;
-  if Result and not (toReadOnly in FOptions.FMiscOptions) then
-  begin
-    BeginUpdate;
-    Result := False;
-    try
-      if TargetNode = nil then
-        TargetNode := FRoot;
-      if TargetNode = FRoot then
-      begin
-        case Mode of
-          amInsertBefore:
-            Mode := amAddChildFirst;
-          amInsertAfter:
-            Mode := amAddChildLast;
-        end;
-      end;
-
-      // Optimized means source is known and in the same process so we can access its pointers, which avoids duplicating
-      // the data while doing a serialization. Can only be used with cut'n paste and drag'n drop with move effect.
-      if Optimized then
-      begin
-        if tsOLEDragging in Source.FStates then
-          Nodes := Source.FDragSelection
-        else
-          Nodes := Source.GetSortedCutCopySet(True);
-
-        if Mode in [amInsertBefore,amAddChildLast] then
-        begin
-          for I := 0 to High(Nodes) do
-            if not HasAsParent(TargetNode, Nodes[I]) then
-              Source.MoveTo(Nodes[I], TargetNode, Mode, False);
-        end
-        else
-        begin
-          for I := High(Nodes) downto 0 do
-            if not HasAsParent(TargetNode, Nodes[I]) then
-              Source.MoveTo(Nodes[I], TargetNode, Mode, False);
-        end;
-        Result := True;
-      end
-      else
-      begin
-        if Source = Self then
-          ChangeReason := crNodeCopied
-        else
-          ChangeReason := crNodeAdded;
-        Res := DataObject.GetData(StandardOLEFormat, Medium);
-        if Res = S_OK then
-        begin
-          case Medium.tymed of
-            TYMED_ISTREAM, // IStream interface
-            TYMED_HGLOBAL: // global memory block
-              begin
-                Stream := nil;
-                if Medium.tymed = TYMED_ISTREAM then
-                  Stream := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream)
-                else
-                begin
-                  Data := GlobalLock(Medium.hGlobal);
-                  if Assigned(Data) then
-                  begin
-                    // Get the total size of data to retrieve.
-                    I := PCardinal(Data)^;
-                    Inc(PCardinal(Data));
-                    Stream := TOLEMemoryStream.Create;
-                    TOLEMemoryStream(Stream).SetPointer(Data, I);
-                  end;
-                end;
-                if Assigned(Stream) then
-                try
-                  while Stream.Position < Stream.Size do
-                  begin
-                    Node := MakeNewNode;
-                    InternalConnectNode(Node, TargetNode, Self, Mode);
-                    InternalAddFromStream(Stream, VTTreeStreamVersion, Node);
-                    // This seems a bit strange because of the callback for granting to add the node
-                    // which actually comes after the node has been added. The reason is that the node must
-                    // contain valid data otherwise I don't see how the application can make a funded decision.
-                    if not DoNodeCopying(Node, TargetNode) then
-                      DeleteNode(Node)
-                    else
-                      DoNodeCopied(Node);
-                    StructureChange(Node, ChangeReason);
-
-                    // In order to maintain the same node order when restoring nodes in the case of amInsertAfter
-                    // we have to move the reference node continously. Othwise we would end up with reversed node order.
-                    if Mode = amInsertAfter then
-                      TargetNode := Node;
-                  end;
-                  Result := True;
-                finally
-                  Stream.Free;
-                  if Medium.tymed = TYMED_HGLOBAL then
-                    GlobalUnlock(Medium.hGlobal);
-                end;
-              end;
-          end;
-          ReleaseStgMedium(@Medium);
-        end;
-      end;
-    finally
-      EndUpdate;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TCustomVirtualStringTree.ContentToClipboard(Format: Word; Source: TVSTTextSourceType): HGLOBAL;
-
-// This method constructs a shareable memory object filled with string data in the required format. Supported are:
-// CF_TEXT - plain ANSI text (Unicode text is converted using the user's current locale)
-// CF_UNICODETEXT - plain Unicode text
-// CF_CSV - comma separated plain ANSI text
-// CF_VRTF + CF_RTFNOOBS - rich text (plain ANSI)
-// CF_HTML - HTML text encoded using UTF-8
-//
-// Result is the handle to a globally allocated memory block which can directly be used for clipboard and drag'n drop
-// transfers. The caller is responsible for freeing the memory. If for some reason the content could not be rendered
-// the Result is 0.
-
-  //--------------- local function --------------------------------------------
-
-  procedure MakeFragment(var HTML: string);
-
-  // Helper routine to build a properly-formatted HTML fragment.
-
-  const
-    Version = 'Version:1.0'#13#10;
-    StartHTML = 'StartHTML:';
-    EndHTML = 'EndHTML:';
-    StartFragment = 'StartFragment:';
-    EndFragment = 'EndFragment:';
-    DocType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
-    HTMLIntro = '<html><head><META http-equiv=Content-Type content="text/html; charset=utf-8">' +
-      '</head><body><!--StartFragment-->';
-    HTMLExtro = '<!--EndFragment--></body></html>';
-    NumberLengthAndCR = 10;
-
-    // Let the compiler determine the description length.
-    DescriptionLength = Length(Version) + Length(StartHTML) + Length(EndHTML) + Length(StartFragment) +
-      Length(EndFragment) + 4 * NumberLengthAndCR;
-
-  var
-    Description: string;
-    StartHTMLIndex,
-    EndHTMLIndex,
-    StartFragmentIndex,
-    EndFragmentIndex: Integer;
-
-  begin
-    // The HTML clipboard format is defined by using byte positions in the entire block where HTML text and
-    // fragments start and end. These positions are written in a description. Unfortunately the positions depend on the
-    // length of the description but the description may change with varying positions.
-    // To solve this dilemma the offsets are converted into fixed length strings which makes it possible to know
-    // the description length in advance.
-    StartHTMLIndex := DescriptionLength;              // position 0 after the description
-    StartFragmentIndex := StartHTMLIndex + Length(DocType) + Length(HTMLIntro);
-    EndFragmentIndex := StartFragmentIndex + Length(HTML);
-    EndHTMLIndex := EndFragmentIndex + Length(HTMLExtro);
-
-    Description := Version +
-      SysUtils.Format('%s%.8d', [StartHTML, StartHTMLIndex]) + #13#10 +
-      SysUtils.Format('%s%.8d', [EndHTML, EndHTMLIndex]) + #13#10 +
-      SysUtils.Format('%s%.8d', [StartFragment, StartFragmentIndex]) + #13#10 +
-      SysUtils.Format('%s%.8d', [EndFragment, EndFragmentIndex]) + #13#10;
-    HTML := Description + DocType + HTMLIntro + HTML + HTMLExtro;
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-var
-  Data: Pointer;
-  DataSize: Cardinal;
-  S: string;
-  WS: UnicodeString;
-  P: Pointer;
-
-begin
-  Result := 0;
-  case Format of
-    CF_TEXT:
-      begin
-        S := ContentToAnsi(Source, #9) + #0;
-        Data := PChar(S);
-        DataSize := Length(S);
-      end;
-    CF_UNICODETEXT:
-      begin
-        WS := ContentToUTF16(Source, #9) + #0;
-        Data := PWideChar(WS);
-        DataSize := 2 * Length(WS);
-      end;
-  else
-    if Format = CF_CSV then
-      S := ContentToAnsi(Source, ListSeparator) + #0
-    else
-      if (Format = CF_VRTF) or (Format = CF_VRTFNOOBJS) then
-        S := ContentToRTF(Source) + #0
-      else
-        if Format = CF_HTML then
-        begin
-          S := ContentToHTML(Source);
-          // Build a valid HTML clipboard fragment.
-          MakeFragment(S);
-          S := S + #0;
-        end;
-    Data := PChar(S);
-    DataSize := Length(S);
-  end;
-
-  if DataSize > 0 then
-  begin
-    Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize);
-    P := GlobalLock(Result);
-    Move(Data^, P^, DataSize);
-    GlobalUnlock(Result);
-  end;
-end;

+ 0 - 725
components/virtualtreeview/include/intf/win32/vtgraphicsi.inc

@@ -1,725 +0,0 @@
-
-{$ASMMODE INTEL}
-
-procedure AlphaBlendLineConstant(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer);
-
-// Blends a line of Count pixels from Source to Destination using a constant alpha value.
-// The layout of a pixel must be BGRA where A is ignored (but is calculated as the other components).
-// ConstantAlpha must be in the range 0..255 where 0 means totally transparent (destination pixel only)
-// and 255 totally opaque (source pixel only).
-// Bias is an additional value which gets added to every component and must be in the range -128..127
-
-asm
-
-{$ifdef CPU64}
-// RCX contains Source
-// RDX contains Destination
-// R8D contains Count
-// R9D contains ConstantAlpha
-// Bias is on the stack
-
-        //.NOFRAME
-
-        // Load XMM3 with the constant alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOVD        XMM3, R9D  // ConstantAlpha
-        PUNPCKLWD   XMM3, XMM3
-        PUNPCKLDQ   XMM3, XMM3
-
-        // Load XMM5 with the bias value.
-        MOVD        XMM5, [Bias]
-        PUNPCKLWD   XMM5, XMM5
-        PUNPCKLDQ   XMM5, XMM5
-
-        // Load XMM4 with 128 to allow for saturated biasing.
-        MOV         R10D, 128
-        MOVD        XMM4, R10D
-        PUNPCKLWD   XMM4, XMM4
-        PUNPCKLDQ   XMM4, XMM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        MOVD        XMM1, DWORD PTR [RCX]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RDX]   // data is unaligned
-        PXOR        XMM0, XMM0    // clear source pixel register for unpacking
-        PUNPCKLBW   XMM0, XMM1{[RCX]}    // unpack source pixel byte values into words
-        PSRLW       XMM0, 8       // move higher bytes to lower bytes
-        PXOR        XMM1, XMM1    // clear target pixel register for unpacking
-        PUNPCKLBW   XMM1, XMM2{[RDX]}    // unpack target pixel byte values into words
-        MOVQ        XMM2, XMM1    // make a copy of the shifted values, we need them again
-        PSRLW       XMM1, 8       // move higher bytes to lower bytes
-
-        // calculation is: target = (alpha * (source - target) + 256 * target) / 256
-        PSUBW       XMM0, XMM1    // source - target
-        PMULLW      XMM0, XMM3    // alpha * (source - target)
-        PADDW       XMM0, XMM2    // add target (in shifted form)
-        PSRLW       XMM0, 8       // divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        PSUBW     XMM0, XMM4
-        PADDSW    XMM0, XMM5
-        PADDW     XMM0, XMM4
-        PACKUSWB  XMM0, XMM0      // convert words to bytes with saturation
-        MOVD      DWORD PTR [RDX], XMM0     // store the result
-@3:
-        ADD       RCX, 4
-        ADD       RDX, 4
-        DEC       R8D
-        JNZ       @1
-
-
-{$else}
-// EAX contains Source
-// EDX contains Destination
-// ECX contains Count
-// ConstantAlpha and Bias are on the stack
-
-
-        PUSH    ESI                    // save used registers
-        PUSH    EDI
-
-        MOV     ESI, EAX               // ESI becomes the actual source pointer
-        MOV     EDI, EDX               // EDI becomes the actual target pointer
-
-        // Load MM6 with the constant alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOV     EAX, [ConstantAlpha]
-        DB      $0F, $6E, $F0          /// MOVD      MM6, EAX
-        DB      $0F, $61, $F6          /// PUNPCKLWD MM6, MM6
-        DB      $0F, $62, $F6          /// PUNPCKLDQ MM6, MM6
-
-        // Load MM5 with the bias value.
-        MOV     EAX, [Bias]
-        DB      $0F, $6E, $E8          /// MOVD      MM5, EAX
-        DB      $0F, $61, $ED          /// PUNPCKLWD MM5, MM5
-        DB      $0F, $62, $ED          /// PUNPCKLDQ MM5, MM5
-
-        // Load MM4 with 128 to allow for saturated biasing.
-        MOV     EAX, 128
-        DB      $0F, $6E, $E0          /// MOVD      MM4, EAX
-        DB      $0F, $61, $E4          /// PUNPCKLWD MM4, MM4
-        DB      $0F, $62, $E4          /// PUNPCKLDQ MM4, MM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        DB      $0F, $EF, $C0          /// PXOR      MM0, MM0,   clear source pixel register for unpacking
-        DB      $0F, $60, $06          /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     move higher bytes to lower bytes
-        DB      $0F, $EF, $C9          /// PXOR      MM1, MM1,   clear target pixel register for unpacking
-        DB      $0F, $60, $0F          /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words
-        DB      $0F, $6F, $D1          /// MOVQ      MM2, MM1,   make a copy of the shifted values, we need them again
-        DB      $0F, $71, $D1, $08     /// PSRLW     MM1, 8,     move higher bytes to lower bytes
-
-        // calculation is: target = (alpha * (source - target) + 256 * target) / 256
-        DB      $0F, $F9, $C1          /// PSUBW     MM0, MM1,   source - target
-        DB      $0F, $D5, $C6          /// PMULLW    MM0, MM6,   alpha * (source - target)
-        DB      $0F, $FD, $C2          /// PADDW     MM0, MM2,   add target (in shifted form)
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        DB      $0F, $F9, $C4          /// PSUBW     MM0, MM4
-        DB      $0F, $ED, $C5          /// PADDSW    MM0, MM5
-        DB      $0F, $FD, $C4          /// PADDW     MM0, MM4
-        DB      $0F, $67, $C0          /// PACKUSWB  MM0, MM0,   convert words to bytes with saturation
-        DB      $0F, $7E, $07          /// MOVD      [EDI], MM0, store the result
-@3:
-        ADD     ESI, 4
-        ADD     EDI, 4
-        DEC     ECX
-        JNZ     @1
-        POP     EDI
-        POP     ESI
-{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure AlphaBlendLinePerPixel(Source, Destination: Pointer; Count, Bias: Integer);
-
-// Blends a line of Count pixels from Source to Destination using the alpha value of the source pixels.
-// The layout of a pixel must be BGRA.
-// Bias is an additional value which gets added to every component and must be in the range -128..127
-
-asm
-
-{$ifdef CPU64}
-// RCX contains Source
-// RDX contains Destination
-// R8D contains Count
-// R9D contains Bias
-
-        //.NOFRAME
-
-        // Load XMM5 with the bias value.
-        MOVD        XMM5, R9D   // Bias
-        PUNPCKLWD   XMM5, XMM5
-        PUNPCKLDQ   XMM5, XMM5
-
-        // Load XMM4 with 128 to allow for saturated biasing.
-        MOV         R10D, 128
-        MOVD        XMM4, R10D
-        PUNPCKLWD   XMM4, XMM4
-        PUNPCKLDQ   XMM4, XMM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        MOVD        XMM1, DWORD PTR [RCX]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RDX]   // data is unaligned
-        PXOR        XMM0, XMM0    // clear source pixel register for unpacking
-        PUNPCKLBW   XMM0, XMM1{[RCX]}    // unpack source pixel byte values into words
-        PSRLW       XMM0, 8       // move higher bytes to lower bytes
-        PXOR        XMM1, XMM1    // clear target pixel register for unpacking
-        PUNPCKLBW   XMM1, XMM2{[RDX]}    // unpack target pixel byte values into words
-        MOVQ        XMM2, XMM1    // make a copy of the shifted values, we need them again
-        PSRLW       XMM1, 8       // move higher bytes to lower bytes
-
-        // Load XMM3 with the source alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOVQ        XMM3, XMM0
-        PUNPCKHWD   XMM3, XMM3
-        PUNPCKHDQ   XMM3, XMM3
-
-        // calculation is: target = (alpha * (source - target) + 256 * target) / 256
-        PSUBW       XMM0, XMM1    // source - target
-        PMULLW      XMM0, XMM3    // alpha * (source - target)
-        PADDW       XMM0, XMM2    // add target (in shifted form)
-        PSRLW       XMM0, 8       // divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        PSUBW       XMM0, XMM4
-        PADDSW      XMM0, XMM5
-        PADDW       XMM0, XMM4
-        PACKUSWB    XMM0, XMM0    // convert words to bytes with saturation
-        MOVD        DWORD PTR [RDX], XMM0   // store the result
-@3:
-        ADD         RCX, 4
-        ADD         RDX, 4
-        DEC         R8D
-        JNZ         @1
-
-
-{$else}
-
-// EAX contains Source
-// EDX contains Destination
-// ECX contains Count
-// Bias is on the stack
-
-        PUSH    ESI                    // save used registers
-        PUSH    EDI
-
-        MOV     ESI, EAX               // ESI becomes the actual source pointer
-        MOV     EDI, EDX               // EDI becomes the actual target pointer
-
-        // Load MM5 with the bias value.
-        MOV     EAX, [Bias]
-        DB      $0F, $6E, $E8          /// MOVD      MM5, EAX
-        DB      $0F, $61, $ED          /// PUNPCKLWD MM5, MM5
-        DB      $0F, $62, $ED          /// PUNPCKLDQ MM5, MM5
-
-        // Load MM4 with 128 to allow for saturated biasing.
-        MOV     EAX, 128
-        DB      $0F, $6E, $E0          /// MOVD      MM4, EAX
-        DB      $0F, $61, $E4          /// PUNPCKLWD MM4, MM4
-        DB      $0F, $62, $E4          /// PUNPCKLDQ MM4, MM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        DB      $0F, $EF, $C0          /// PXOR      MM0, MM0,   clear source pixel register for unpacking
-        DB      $0F, $60, $06          /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     move higher bytes to lower bytes
-        DB      $0F, $EF, $C9          /// PXOR      MM1, MM1,   clear target pixel register for unpacking
-        DB      $0F, $60, $0F          /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words
-        DB      $0F, $6F, $D1          /// MOVQ      MM2, MM1,   make a copy of the shifted values, we need them again
-        DB      $0F, $71, $D1, $08     /// PSRLW     MM1, 8,     move higher bytes to lower bytes
-
-        // Load MM6 with the source alpha value (replicate it for every component).
-        // Expand it to word size.
-        DB      $0F, $6F, $F0          /// MOVQ MM6, MM0
-        DB      $0F, $69, $F6          /// PUNPCKHWD MM6, MM6
-        DB      $0F, $6A, $F6          /// PUNPCKHDQ MM6, MM6
-
-        // calculation is: target = (alpha * (source - target) + 256 * target) / 256
-        DB      $0F, $F9, $C1          /// PSUBW     MM0, MM1,   source - target
-        DB      $0F, $D5, $C6          /// PMULLW    MM0, MM6,   alpha * (source - target)
-        DB      $0F, $FD, $C2          /// PADDW     MM0, MM2,   add target (in shifted form)
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        DB      $0F, $F9, $C4          /// PSUBW     MM0, MM4
-        DB      $0F, $ED, $C5          /// PADDSW    MM0, MM5
-        DB      $0F, $FD, $C4          /// PADDW     MM0, MM4
-        DB      $0F, $67, $C0          /// PACKUSWB  MM0, MM0,   convert words to bytes with saturation
-        DB      $0F, $7E, $07          /// MOVD      [EDI], MM0, store the result
-@3:
-        ADD     ESI, 4
-        ADD     EDI, 4
-        DEC     ECX
-        JNZ     @1
-        POP     EDI
-        POP     ESI
-{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure AlphaBlendLineMaster(Source, Destination: Pointer; Count: Integer; ConstantAlpha, Bias: Integer);
-
-// Blends a line of Count pixels from Source to Destination using the source pixel and a constant alpha value.
-// The layout of a pixel must be BGRA.
-// ConstantAlpha must be in the range 0..255.
-// Bias is an additional value which gets added to every component and must be in the range -128..127
-
-asm
-
-{$ifdef CPU64}
-// RCX contains Source
-// RDX contains Destination
-// R8D contains Count
-// R9D contains ConstantAlpha
-// Bias is on the stack
-
-        //.SAVENV XMM6  //todo see how implement in fpc      AlphaBlendLineMaster
-
-        // Load XMM3 with the constant alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOVD        XMM3, R9D    // ConstantAlpha
-        PUNPCKLWD   XMM3, XMM3
-        PUNPCKLDQ   XMM3, XMM3
-
-        // Load XMM5 with the bias value.
-        MOV         R10D, [Bias]
-        MOVD        XMM5, R10D
-        PUNPCKLWD   XMM5, XMM5
-        PUNPCKLDQ   XMM5, XMM5
-
-        // Load XMM4 with 128 to allow for saturated biasing.
-        MOV         R10D, 128
-        MOVD        XMM4, R10D
-        PUNPCKLWD   XMM4, XMM4
-        PUNPCKLDQ   XMM4, XMM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        MOVD        XMM1, DWORD PTR [RCX]   // data is unaligned
-        MOVD        XMM2, DWORD PTR [RDX]   // data is unaligned
-        PXOR        XMM0, XMM0    // clear source pixel register for unpacking
-        PUNPCKLBW   XMM0, XMM1{[RCX]}     // unpack source pixel byte values into words
-        PSRLW       XMM0, 8       // move higher bytes to lower bytes
-        PXOR        XMM1, XMM1    // clear target pixel register for unpacking
-        PUNPCKLBW   XMM1, XMM2{[RCX]}     // unpack target pixel byte values into words
-        MOVQ        XMM2, XMM1    // make a copy of the shifted values, we need them again
-        PSRLW       XMM1, 8       // move higher bytes to lower bytes
-
-        // Load XMM6 with the source alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOVQ        XMM6, XMM0
-        PUNPCKHWD   XMM6, XMM6
-        PUNPCKHDQ   XMM6, XMM6
-        PMULLW      XMM6, XMM3    // source alpha * master alpha
-        PSRLW       XMM6, 8       // divide by 256
-
-        // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256
-        PSUBW       XMM0, XMM1    // source - target
-        PMULLW      XMM0, XMM6    // alpha * (source - target)
-        PADDW       XMM0, XMM2    // add target (in shifted form)
-        PSRLW       XMM0, 8       // divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        PSUBW       XMM0, XMM4
-        PADDSW      XMM0, XMM5
-        PADDW       XMM0, XMM4
-        PACKUSWB    XMM0, XMM0    // convert words to bytes with saturation
-        MOVD        DWORD PTR [RDX], XMM0   // store the result
-@3:
-        ADD         RCX, 4
-        ADD         RDX, 4
-        DEC         R8D
-        JNZ         @1
-
-{$else}
-
-// EAX contains Source
-// EDX contains Destination
-// ECX contains Count
-// ConstantAlpha and Bias are on the stack
-
-
-        PUSH    ESI                    // save used registers
-        PUSH    EDI
-
-        MOV     ESI, EAX               // ESI becomes the actual source pointer
-        MOV     EDI, EDX               // EDI becomes the actual target pointer
-
-        // Load MM6 with the constant alpha value (replicate it for every component).
-        // Expand it to word size.
-        MOV     EAX, [ConstantAlpha]
-        DB      $0F, $6E, $F0          /// MOVD      MM6, EAX
-        DB      $0F, $61, $F6          /// PUNPCKLWD MM6, MM6
-        DB      $0F, $62, $F6          /// PUNPCKLDQ MM6, MM6
-
-        // Load MM5 with the bias value.
-        MOV     EAX, [Bias]
-        DB      $0F, $6E, $E8          /// MOVD      MM5, EAX
-        DB      $0F, $61, $ED          /// PUNPCKLWD MM5, MM5
-        DB      $0F, $62, $ED          /// PUNPCKLDQ MM5, MM5
-
-        // Load MM4 with 128 to allow for saturated biasing.
-        MOV     EAX, 128
-        DB      $0F, $6E, $E0          /// MOVD      MM4, EAX
-        DB      $0F, $61, $E4          /// PUNPCKLWD MM4, MM4
-        DB      $0F, $62, $E4          /// PUNPCKLDQ MM4, MM4
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        // Note: The pixel byte values are expanded into the higher bytes of a word due
-        //       to the way unpacking works. We compensate for this with an extra shift.
-        DB      $0F, $EF, $C0          /// PXOR      MM0, MM0,   clear source pixel register for unpacking
-        DB      $0F, $60, $06          /// PUNPCKLBW MM0, [ESI], unpack source pixel byte values into words
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     move higher bytes to lower bytes
-        DB      $0F, $EF, $C9          /// PXOR      MM1, MM1,   clear target pixel register for unpacking
-        DB      $0F, $60, $0F          /// PUNPCKLBW MM1, [EDI], unpack target pixel byte values into words
-        DB      $0F, $6F, $D1          /// MOVQ      MM2, MM1,   make a copy of the shifted values, we need them again
-        DB      $0F, $71, $D1, $08     /// PSRLW     MM1, 8,     move higher bytes to lower bytes
-
-        // Load MM7 with the source alpha value (replicate it for every component).
-        // Expand it to word size.
-        DB      $0F, $6F, $F8          /// MOVQ      MM7, MM0
-        DB      $0F, $69, $FF          /// PUNPCKHWD MM7, MM7
-        DB      $0F, $6A, $FF          /// PUNPCKHDQ MM7, MM7
-        DB      $0F, $D5, $FE          /// PMULLW    MM7, MM6,   source alpha * master alpha
-        DB      $0F, $71, $D7, $08     /// PSRLW     MM7, 8,     divide by 256
-
-        // calculation is: target = (alpha * master alpha * (source - target) + 256 * target) / 256
-        DB      $0F, $F9, $C1          /// PSUBW     MM0, MM1,   source - target
-        DB      $0F, $D5, $C7          /// PMULLW    MM0, MM7,   alpha * (source - target)
-        DB      $0F, $FD, $C2          /// PADDW     MM0, MM2,   add target (in shifted form)
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8,     divide by 256
-
-        // Bias is accounted for by conversion of range 0..255 to -128..127,
-        // doing a saturated add and convert back to 0..255.
-        DB      $0F, $F9, $C4          /// PSUBW     MM0, MM4
-        DB      $0F, $ED, $C5          /// PADDSW    MM0, MM5
-        DB      $0F, $FD, $C4          /// PADDW     MM0, MM4
-        DB      $0F, $67, $C0          /// PACKUSWB  MM0, MM0,   convert words to bytes with saturation
-        DB      $0F, $7E, $07          /// MOVD      [EDI], MM0, store the result
-@3:
-        ADD     ESI, 4
-        ADD     EDI, 4
-        DEC     ECX
-        JNZ     @1
-        POP     EDI
-        POP     ESI
-{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure AlphaBlendLineMasterAndColor(Destination: Pointer; Count: Integer; ConstantAlpha, Color: Integer);
-
-// Blends a line of Count pixels in Destination against the given color using a constant alpha value.
-// The layout of a pixel must be BGRA and Color must be rrggbb00 (as stored by a COLORREF).
-// ConstantAlpha must be in the range 0..255.
-
-asm
-
-{$ifdef CPU64}
-// RCX contains Destination
-// EDX contains Count
-// R8D contains ConstantAlpha
-// R9D contains Color
-        //.NOFRAME
-
-        // The used formula is: target = (alpha * color + (256 - alpha) * target) / 256.
-        // alpha * color (factor 1) and 256 - alpha (factor 2) are constant values which can be calculated in advance.
-        // The remaining calculation is therefore: target = (F1 + F2 * target) / 256
-
-        // Load XMM3 with the constant alpha value (replicate it for every component).
-        // Expand it to word size. (Every calculation here works on word sized operands.)
-        MOVD        XMM3, R8D   // ConstantAlpha
-        PUNPCKLWD   XMM3, XMM3
-        PUNPCKLDQ   XMM3, XMM3
-
-        // Calculate factor 2.
-        MOV         R10D, $100
-        MOVD        XMM2, R10D
-        PUNPCKLWD   XMM2, XMM2
-        PUNPCKLDQ   XMM2, XMM2
-        PSUBW       XMM2, XMM3             // XMM2 contains now: 255 - alpha = F2
-
-        // Now calculate factor 1. Alpha is still in XMM3, but the r and b components of Color must be swapped.
-        BSWAP       R9D  // Color
-        ROR         R9D, 8
-        MOVD        XMM1, R9D              // Load the color and convert to word sized values.
-        PXOR        XMM4, XMM4
-        PUNPCKLBW   XMM1, XMM4
-        PMULLW      XMM1, XMM3             // XMM1 contains now: color * alpha = F1
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        MOVD        XMM0, DWORD PTR [RCX]
-        PUNPCKLBW   XMM0, XMM4
-
-        PMULLW      XMM0, XMM2             // calculate F1 + F2 * target
-        PADDW       XMM0, XMM1
-        PSRLW       XMM0, 8                // divide by 256
-
-        PACKUSWB    XMM0, XMM0             // convert words to bytes with saturation
-        MOVD        DWORD PTR [RCX], XMM0            // store the result
-
-        ADD         RCX, 4
-        DEC         EDX
-        JNZ         @1
-
-
-{$else}
-
-// EAX contains Destination
-// EDX contains Count
-// ECX contains ConstantAlpha
-// Color is passed on the stack
-
-
-        // The used formula is: target = (alpha * color + (256 - alpha) * target) / 256.
-        // alpha * color (factor 1) and 256 - alpha (factor 2) are constant values which can be calculated in advance.
-        // The remaining calculation is therefore: target = (F1 + F2 * target) / 256
-
-        // Load MM3 with the constant alpha value (replicate it for every component).
-        // Expand it to word size. (Every calculation here works on word sized operands.)
-        DB      $0F, $6E, $D9          /// MOVD      MM3, ECX
-        DB      $0F, $61, $DB          /// PUNPCKLWD MM3, MM3
-        DB      $0F, $62, $DB          /// PUNPCKLDQ MM3, MM3
-
-        // Calculate factor 2.
-        MOV     ECX, $100
-        DB      $0F, $6E, $D1          /// MOVD      MM2, ECX
-        DB      $0F, $61, $D2          /// PUNPCKLWD MM2, MM2
-        DB      $0F, $62, $D2          /// PUNPCKLDQ MM2, MM2
-        DB      $0F, $F9, $D3          /// PSUBW     MM2, MM3             // MM2 contains now: 255 - alpha = F2
-
-        // Now calculate factor 1. Alpha is still in MM3, but the r and b components of Color must be swapped.
-        MOV     ECX, [Color]
-        BSWAP   ECX
-        ROR     ECX, 8
-        DB      $0F, $6E, $C9          /// MOVD      MM1, ECX             // Load the color and convert to word sized values.
-        DB      $0F, $EF, $E4          /// PXOR      MM4, MM4
-        DB      $0F, $60, $CC          /// PUNPCKLBW MM1, MM4
-        DB      $0F, $D5, $CB          /// PMULLW    MM1, MM3             // MM1 contains now: color * alpha = F1
-
-@1:     // The pixel loop calculates an entire pixel in one run.
-        DB      $0F, $6E, $00          /// MOVD      MM0, [EAX]
-        DB      $0F, $60, $C4          /// PUNPCKLBW MM0, MM4
-
-        DB      $0F, $D5, $C2          /// PMULLW    MM0, MM2             // calculate F1 + F2 * target
-        DB      $0F, $FD, $C1          /// PADDW     MM0, MM1
-        DB      $0F, $71, $D0, $08     /// PSRLW     MM0, 8               // divide by 256
-
-        DB      $0F, $67, $C0          /// PACKUSWB  MM0, MM0             // convert words to bytes with saturation
-        DB      $0F, $7E, $00          /// MOVD      [EAX], MM0           // store the result
-
-        ADD     EAX, 4
-        DEC     EDX
-        JNZ     @1
-{$endif}
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure EMMS;
-
-// Reset MMX state to use the FPU for other tasks again.
-
-{$ifdef CPU64}
-  inline;
-  begin
-  end;
-
-{$else}
-
-asm
-        DB      $0F, $77               /// EMMS
-end;
-{$endif}
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function GetBitmapBitsFromDeviceContext(DC: HDC; out Width, Height: Integer): Pointer;
-
-// Helper function used to retrieve the bitmap selected into the given device context. If there is a bitmap then
-// the function will return a pointer to its bits otherwise nil is returned.
-// Additionally the dimensions of the bitmap are returned.
-
-var
-  Bitmap: HBITMAP;
-  DIB: TDIBSection;
-
-begin
-  Result := nil;
-  Width := 0;
-  Height := 0;
-  Bitmap := GetCurrentObject(DC, OBJ_BITMAP);
-  if Bitmap <> 0 then
-  begin
-    if GetObject(Bitmap, SizeOf(DIB), @DIB) = SizeOf(DIB) then
-    begin
-      Assert(DIB.dsBm.bmPlanes * DIB.dsBm.bmBitsPixel = 32, 'Alpha blending error: bitmap must use 32 bpp.');
-      Result := DIB.dsBm.bmBits;
-      Width := DIB.dsBmih.biWidth;
-      Height := DIB.dsBmih.biHeight;
-    end;
-  end;
-  Assert(Result <> nil, 'Alpha blending DC error: no bitmap available.');
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function GetBitmapBitsFromBitmap(Bitmap: HBITMAP): Pointer;
-var
-  DIB: TDIBSection;
-begin
-  Result := nil;
-  if Bitmap <> 0 then
-  begin
-    if GetObject(Bitmap, SizeOf(DIB), @DIB) = SizeOf(DIB) then
-    begin
-      Assert(DIB.dsBm.bmPlanes * DIB.dsBm.bmBitsPixel = 32, 'Alpha blending error: bitmap must use 32 bpp.');
-      Result := DIB.dsBm.bmBits;
-    end;
-  end;
-end;
-
-function CalculateScanline(Bits: Pointer; Width, Height, Row: Integer): Pointer;
-
-// Helper function to calculate the start address for the given row.
-
-begin
-  //todo: Height is always > 0 in LCL
-  {
-  if Height > 0 then  // bottom-up DIB
-    Row := Height - Row - 1;
-  }
-  // Return DWORD aligned address of the requested scanline.
-  Result := Bits + Row * ((Width * 32 + 31) and not 31) div 8;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure AlphaBlend(Source, Destination: HDC; const R: TRect; const Target: TPoint; Mode: TBlendMode; ConstantAlpha, Bias: Integer);
-
-// Optimized alpha blend procedure using MMX instructions to perform as quick as possible.
-// For this procedure to work properly it is important that both source and target bitmap use the 32 bit color format.
-// R describes the source rectangle to work on.
-// Target is the place (upper left corner) in the target bitmap where to blend to. Note that source width + X offset
-// must be less or equal to the target width. Similar for the height.
-// If Mode is bmConstantAlpha then the blend operation uses the given ConstantAlpha value for all pixels.
-// If Mode is bmPerPixelAlpha then each pixel is blended using its individual alpha value (the alpha value of the source).
-// If Mode is bmMasterAlpha then each pixel is blended using its individual alpha value multiplied by ConstantAlpha.
-// If Mode is bmConstantAlphaAndColor then each destination pixel is blended using ConstantAlpha but also a constant
-// color which will be obtained from Bias. In this case no offset value is added, otherwise Bias is used as offset.
-// Blending of a color into target only (bmConstantAlphaAndColor) ignores Source (the DC) and Target (the position).
-// CAUTION: This procedure does not check whether MMX instructions are actually available! Call it only if MMX is really
-//          usable.
-
-var
-  Y: Integer;
-  SourceRun,
-  TargetRun: PByte;
-
-  SourceBits,
-  DestBits: Pointer;
-  SourceWidth,
-  SourceHeight,
-  DestWidth,
-  DestHeight: Integer;
-
-begin
-  if not IsRectEmpty(R) then
-  begin
-    {$ifdef CPU64}
-    //avoid MasterAlpha due to incomplete AlphaBlendLineMaster. See comment in procedure
-    if Mode = bmMasterAlpha then
-      Mode := bmConstantAlpha;
-    {$endif}
-    // Note: it is tempting to optimize the special cases for constant alpha 0 and 255 by just ignoring soure
-    //       (alpha = 0) or simply do a blit (alpha = 255). But this does not take the bias into account.
-    case Mode of
-      bmConstantAlpha:
-        begin
-          // Get a pointer to the bitmap bits for the source and target device contexts.
-          // Note: this supposes that both contexts do actually have bitmaps assigned!
-          SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight);
-          DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight);
-          if Assigned(SourceBits) and Assigned(DestBits) then
-          begin
-            for Y := 0 to R.Bottom - R.Top - 1 do
-            begin
-              SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top);
-              Inc(SourceRun, 4 * R.Left);
-              TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y);
-              Inc(TargetRun, 4 * Target.X);
-              AlphaBlendLineConstant(SourceRun, TargetRun, R.Right - R.Left, ConstantAlpha, Bias);
-            end;
-          end;
-          EMMS;
-        end;
-      bmPerPixelAlpha:
-        begin
-          SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight);
-          DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight);
-          if Assigned(SourceBits) and Assigned(DestBits) then
-          begin
-            for Y := 0 to R.Bottom - R.Top - 1 do
-            begin
-              SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top);
-              Inc(SourceRun, 4 * R.Left);
-              TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y);
-              Inc(TargetRun, 4 * Target.X);
-              AlphaBlendLinePerPixel(SourceRun, TargetRun, R.Right - R.Left, Bias);
-            end;
-          end;
-          EMMS;
-        end;
-      bmMasterAlpha:
-        begin
-          SourceBits := GetBitmapBitsFromDeviceContext(Source, SourceWidth, SourceHeight);
-          DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight);
-          if Assigned(SourceBits) and Assigned(DestBits) then
-          begin
-            for Y := 0 to R.Bottom - R.Top - 1 do
-            begin
-              SourceRun := CalculateScanline(SourceBits, SourceWidth, SourceHeight, Y + R.Top);
-              Inc(SourceRun, 4 * Target.X);
-              TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + Target.Y);
-              AlphaBlendLineMaster(SourceRun, TargetRun, R.Right - R.Left, ConstantAlpha, Bias);
-            end;
-          end;
-          EMMS;
-        end;
-      bmConstantAlphaAndColor:
-        begin
-          // Source is ignored since there is a constant color value.
-          DestBits := GetBitmapBitsFromDeviceContext(Destination, DestWidth, DestHeight);
-          if Assigned(DestBits) then
-          begin
-            for Y := 0 to R.Bottom - R.Top - 1 do
-            begin
-              TargetRun := CalculateScanline(DestBits, DestWidth, DestHeight, Y + R.Top);
-              Inc(TargetRun, 4 * R.Left);
-              AlphaBlendLineMasterAndColor(TargetRun, R.Right - R.Left, ConstantAlpha, Bias);
-            end;
-          end;
-          EMMS;
-        end;
-    end;
-  end;
-end;
-
-

+ 0 - 726
components/virtualtreeview/include/intf/win32/vtvdragmanager.inc

@@ -1,726 +0,0 @@
-
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// OLE drag and drop support classes
-// This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs
-// of DD'ing various kinds of virtual data and works also between applications.
-
-//----------------- TEnumFormatEtc -------------------------------------------------------------------------------------
-
-constructor TEnumFormatEtc.Create(Tree: TBaseVirtualTree; AFormatEtcArray: TFormatEtcArray);
-
-var
-  I: Integer;
-
-begin
-  inherited Create;
-
-  FTree := Tree;
-  // Make a local copy of the format data.
-  SetLength(FFormatEtcArray, Length(AFormatEtcArray));
-  for I := 0 to High(AFormatEtcArray) do
-    FFormatEtcArray[I] := AFormatEtcArray[I];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
-
-var
-  AClone: TEnumFormatEtc;
-
-begin
-  Result := S_OK;
-  try
-    AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray);
-    AClone.FCurrentIndex := FCurrentIndex;
-    Enum := AClone as IEnumFormatEtc;
-  except
-    Result := E_FAIL;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; pceltFetched:pULong=nil): HResult;
-var
-  CopyCount: LongWord;
-
-begin
-  Result := S_FALSE;
-  CopyCount := Length(FFormatEtcArray) - FCurrentIndex;
-  if celt < CopyCount then
-    CopyCount := celt;
-  if CopyCount > 0 then
-  begin
-    Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc));
-    Inc(FCurrentIndex, CopyCount);
-    Result := S_OK;
-  end;
-  if pceltFetched <> nil then
-    pceltFetched^ := CopyCount;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Reset: HResult;
-
-begin
-  FCurrentIndex := 0;
-  Result := S_OK;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Skip(celt: LongWord): HResult;
-
-begin
-  if FCurrentIndex + celt < High(FFormatEtcArray) then
-  begin
-    Inc(FCurrentIndex, celt);
-    Result := S_Ok;
-  end
-  else
-    Result := S_FALSE;
-end;
-
-
-
-//----------------- TVTDataObject --------------------------------------------------------------------------------------
-
-constructor TVTDataObject.Create(AOwner: TBaseVirtualTree; ForClipboard: Boolean);
-
-begin
-  inherited Create;
-
-  FOwner := AOwner;
-  FForClipboard := ForClipboard;
-  FOwner.GetNativeClipboardFormats(FFormatEtcArray);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDataObject.Destroy;
-
-var
-  I: Integer;
-  StgMedium: PStgMedium;
-
-begin
-  // Cancel a pending clipboard operation if this data object was created for the clipboard and
-  // is freed because something else is placed there.
-  if FForClipboard and not (tsClipboardFlushing in FOwner.FStates) then
-    FOwner.CancelCutOrCopy;
-
-  // Release any internal clipboard formats
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat);
-    if Assigned(StgMedium) then
-      ReleaseStgMedium(StgMedium);
-  end;
-
-  FormatEtcArray := nil;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-
-// Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown
-// interface, will always return the same pointer.
-
-begin
-  if Assigned(TestUnknown) then
-  begin
-    if TestUnknown.QueryInterface(IUnknown, Result) = 0 then
-      Result._Release // Don't actually need it just need the pointer value
-    else
-      Result := TestUnknown
-  end
-  else
-    Result := TestUnknown
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-
-begin
-  Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and
-    (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and
-    (FormatEtc1.tymed and FormatEtc2.tymed <> 0);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer;
-
-var
-  I: integer;
-
-begin
-  Result := -1;
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then
-    begin
-      Result := I;
-      Break;
-    end
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium;
-
-var
-  I: integer;
-begin
-  Result := nil;
-  for I := 0 to High(InternalStgMediumArray) do
-  begin
-    if Format = InternalStgMediumArray[I].Format then
-    begin
-      Result := @InternalStgMediumArray[I].Medium;
-      Break;
-    end
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle;
-
-// Returns a global memory block that is a copy of the passed memory block.
-
-var
-  Size: Cardinal;
-  Data,
-  NewData: PByte;
-
-begin
-  Size := GlobalSize(HGlobal);
-  Result := GlobalAlloc(GPTR, Size);
-  Data := GlobalLock(hGlobal);
-  try
-    NewData := GlobalLock(Result);
-    try
-      Move(Data^, NewData^, Size);
-    finally
-      GlobalUnLock(Result);
-    end
-  finally
-    GlobalUnLock(hGlobal);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium;
-  var OLEResult: HResult): Boolean;
-
-// Tries to render one of the formats which have been stored via the SetData method.
-// Since this data is already there it is just copied or its reference count is increased (depending on storage medium).
-
-var
-  InternalMedium: PStgMedium;
-
-begin
-  Result := True;
-  InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat);
-  if Assigned(InternalMedium) then
-    OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject)
-  else
-    Result := False;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-  CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-// InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or
-// increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually
-// the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData.
-// If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during
-// that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make
-// copy of the data for the caller only to have them destroy it then need us to copy it again if necessary.
-// This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData.
-// 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;
-
-begin
-  Result := S_OK;
-
-  // Simply copy all fields to start with.
-  OutStgMedium := InStgMedium;
-  // The data handled here always results from a call of SetData we got. This ensures only one storage format
-  // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several
-  // storage formats).
-  case InStgMedium.tymed of
-    TYMED_HGLOBAL:
-      begin
-        if CopyInMedium then
-        begin
-          // Generate a unique copy of the data passed
-          OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal);
-          if OutStgMedium.hGlobal = 0 then
-            Result := E_OUTOFMEMORY
-        end
-        else
-          // Don't generate a copy just use ourselves and the copy previously saved.
-          OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount.
-      end;
-    TYMED_FILE:
-      begin
-        //todo_lcl_check
-        Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character.
-        OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len);
-        Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len);
-      end;
-    TYMED_ISTREAM:
-      IUnknown(OutStgMedium.Pstm)._AddRef;
-    TYMED_ISTORAGE:
-      IUnknown(OutStgMedium.Pstg)._AddRef;
-    TYMED_GDI:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy GDI objects right now.
-    TYMED_MFPICT:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now.
-    TYMED_ENHMF:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now.
-  else
-    Result := DV_E_TYMED;
-  end;
-
-  if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then
-    IUnknown(OutStgMedium.PunkForRelease)._AddRef;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink;
-  out dwConnection: DWord): HResult;
-
-// Advise sink management is greatly simplified by the IDataAdviseHolder interface.
-// We use this interface and forward all concerning calls to it.
-
-begin
-  Result := S_OK;
-  if FAdviseHolder = nil then
-    Result := CreateDataAdviseHolder(FAdviseHolder);
-  if Result = S_OK then
-    Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DUnadvise(dwConnection: DWord): HResult;
-
-begin
-  if FAdviseHolder = nil then
-    Result := E_NOTIMPL
-  else
-    Result := FAdviseHolder.Unadvise(dwConnection);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumDAdvise(Out enumAdvise : IEnumStatData):HResult;
-
-begin
-  if FAdviseHolder = nil then
-    Result := OLE_E_ADVISENOTSUPPORTED
-  else
-    Result := FAdviseHolder.EnumAdvise(enumAdvise);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult;
-
-var
-  NewList: TEnumFormatEtc;
-
-begin
-  Result := E_FAIL;
-  if Direction = DATADIR_GET then
-  begin
-    NewList := TEnumFormatEtc.Create(FOwner, FormatEtcArray);
-    EnumFormatEtc := NewList as IEnumFormatEtc;
-    Result := S_OK;
-  end
-  else
-    EnumFormatEtc := nil;
-  if EnumFormatEtc = nil then
-    Result := OLE_S_USEREG;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-Function TVTDataObject.GetCanonicalFormatEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult;
-
-begin
-  Result := DATA_S_SAMEFORMATETC;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult;
-
-// Data is requested by clipboard or drop target. This method dispatchs the call
-// depending on the data being requested.
-
-var
-  I: Integer;
-  Data: PVTReference;
-
-begin
-  // The tree reference format is always supported and returned from here.
-  if FormatEtcIn.cfFormat = CF_VTREFERENCE then
-  begin
-    // Note: this format is not used while flushing the clipboard to avoid a dangling reference
-    //       when the owner tree is destroyed before the clipboard data is replaced with something else.
-    if tsClipboardFlushing in FOwner.FStates then
-      Result := E_FAIL
-    else
-    begin
-      Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference));
-      Data := GlobalLock(Medium.hGlobal);
-      Data.Process := GetCurrentProcessID;
-      Data.Tree := FOwner;
-      GlobalUnlock(Medium.hGlobal);
-      Medium.tymed := TYMED_HGLOBAL;
-      Medium.PunkForRelease := nil;
-      Result := S_OK;
-    end;
-  end
-  else
-  begin
-    try
-      // See if we accept this type and if not get the correct return value.
-      Result := QueryGetData(FormatEtcIn);
-      if Result = S_OK then
-      begin
-        for I := 0 to High(FormatEtcArray) do
-        begin
-          if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
-          begin
-            if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
-              Result := FOwner.RenderOLEData(FormatEtcIn, Medium, FForClipboard);
-            Break;
-          end;
-        end
-      end
-    except
-      FillChar(Medium, SizeOf(Medium), #0);
-      Result := E_FAIL;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult;
-
-begin
-  Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult;
-
-var
-  I: Integer;
-
-begin
-  Result := DV_E_CLIPFORMAT;
-  for I := 0 to High(FFormatEtcArray) do
-  begin
-    if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then
-    begin
-      if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then
-      begin
-        if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then
-        begin
-          if FormatEtc.lindex = FFormatEtcArray[I].lindex then
-          begin
-            Result := S_OK;
-            Break;
-          end
-          else
-            Result := DV_E_LINDEX;
-        end
-        else
-          Result := DV_E_DVASPECT;
-      end
-      else
-        Result := DV_E_TYMED;
-    end;
-  end
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.SetData(const FormatEtc: TFormatEtc; const Medium: TStgMedium; DoRelease: BOOL): HResult;
-
-// 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;
-  LocalStgMedium: PStgMedium;
-
-begin
-  // See if we already have a format of that type available.
-  Index := FindFormatEtc(FormatEtc, FormatEtcArray);
-  if Index > - 1 then
-  begin
-    // Just use the TFormatEct in the array after releasing the data.
-    LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat);
-    if Assigned(LocalStgMedium) then
-    begin
-      ReleaseStgMedium(LocalStgMedium);
-      FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-    end;
-  end
-  else
-  begin
-    // It is a new format so create a new TFormatCollectionItem, copy the
-    // FormatEtc parameter into the new object and and put it in the list.
-    SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1);
-    FormatEtcArray[High(FormatEtcArray)] := FormatEtc;
-
-    // Create a new InternalStgMedium and initialize it and associate it with the format.
-    SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1);
-    InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat;
-    LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium;
-    FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-  end;
-
-  if DoRelease then
-  begin
-    // We are simply being given the data and we take control of it.
-    LocalStgMedium^ := Medium;
-    Result := S_OK
-  end
-  else
-  begin
-    // We need to reference count or copy the data and keep our own references to it.
-    Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject);
-
-    // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium.
-    // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that
-    // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN.
-    if Assigned(LocalStgMedium.PunkForRelease) then
-    begin
-      if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then
-        IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface
-    end;
-  end;
-
-  // Tell all registered advice sinks about the data change.
-  if Assigned(FAdviseHolder) then
-    FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0);
-end;
-
-//----------------- TVTDragManager -------------------------------------------------------------------------------------
-
-constructor TVTDragManager.Create(AOwner: TBaseVirtualTree);
-
-begin
-  inherited Create;
-  FOwner := AOwner;
-
-  // Create an instance  of the drop target helper interface. This will fail but not harm on systems which do
-  // not support this interface (everything below Windows 2000);
-  CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDragManager.Destroy;
-
-begin
-  // Set the owner's reference to us to nil otherwise it will access an invalid pointer
-  // after our desctruction is complete.
-  Pointer(FOwner.FDragManager) := nil;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDataObject: IDataObject;
-
-begin
-  // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem.
-  // In this case there is no local reference to a data object and one is created (but not stored).
-  // If there is a local reference then the owner tree is currently the drop target and the stored interface is
-  // that of the drag initiator.
-  if Assigned(FDataObject) then
-    Result := FDataObject
-  else
-  begin
-    Result := FOwner.DoCreateDataObject;
-    if Result = nil then
-      Result := TVTDataObject.Create(FOwner, False) as IDataObject;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDragSource: TBaseVirtualTree;
-
-begin
-  Result := FDragSource;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDropTargetHelperSupported: Boolean;
-
-begin
-  Result := Assigned(FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetIsDropTarget: Boolean;
-
-begin
-  Result := FIsDropTarget;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  FDataObject := DataObject;
-  FIsDropTarget := True;
-
-  SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0);
-  // If full dragging of window contents is disabled in the system then our tree windows will be locked
-  // and cannot be updated during a drag operation. With the following call painting is again enabled.
-  if not FFullDragging then
-    LockWindowUpdate(0);
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragEnter(FOwner.Handle, DataObject, Pt, Effect);
-
-  FDragSource := FOwner.GetTreeFromDataObject(DataObject);
-  Result := FOwner.DragEnter(KeyState, Pt, Effect);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragLeave: HResult;
-
-begin
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-
-  FOwner.DragLeave;
-  FIsDropTarget := False;
-  FDragSource := nil;
-  FDataObject := nil;
-  Result := NOERROR;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult;
-
-begin
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragOver(Pt, Effect);
-
-  Result := FOwner.DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.Drop(DataObject, Pt, Effect);
-
-  Result := FOwner.DragDrop(DataObject, KeyState, Pt, Effect);
-  FIsDropTarget := False;
-  FDataObject := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragManager.ForceDragLeave;
-
-// Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive
-// a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from
-// screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE).
-
-begin
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$IF FPC_FULLVERSION < 020601}
-function TVTDragManager.GiveFeedback(Effect: Longint): HResult;
-{$ELSE}
-function TVTDragManager.GiveFeedback(Effect: LongWord): HResult;
-{$ENDIF}
-
-begin
-  Result := DRAGDROP_S_USEDEFAULTCURSORS;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-{$IF FPC_FULLVERSION < 020601}
-function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: Longint): HResult;
-{$ELSE}
-function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult;
-{$ENDIF}
-
-var
-  RButton,
-  LButton: Boolean;
-
-begin
-  LButton := (KeyState and MK_LBUTTON) <> 0;
-  RButton := (KeyState and MK_RBUTTON) <> 0;
-
-  // Drag'n drop canceled by pressing both mouse buttons or Esc?
-  if (LButton and RButton) or EscapePressed then
-    Result := DRAGDROP_S_CANCEL
-  else
-    // Drag'n drop finished?
-    if not (LButton or RButton) then
-      Result := DRAGDROP_S_DROP
-    else
-      Result := S_OK;
-end;
-
-

+ 0 - 161
components/virtualtreeview/lclconstants.inc

@@ -1,161 +0,0 @@
-// Message constants that are not defined in LCL
-
-  WM_APP  = $8000;
-
-// ExtTextOut Options
-
-  ETO_RTLREADING = 128;
-
-//DrawText options
-
-  DT_RTLREADING = 131072;
-
-// Clipboard constants
-
-  CF_BITMAP = 2;
-  CF_DIB = 8;
-  CF_PALETTE = 9;
-  CF_ENHMETAFILE = 14;
-  CF_METAFILEPICT = 3;
-  CF_OEMTEXT = 7;
-  CF_TEXT = 1;
-  CF_UNICODETEXT = 13;
-  CF_DIF = 5;
-  CF_DSPBITMAP = 130;
-  CF_DSPENHMETAFILE = 142;
-  CF_DSPMETAFILEPICT = 131;
-  CF_DSPTEXT = 129;
-  CF_GDIOBJFIRST = 768;
-  CF_GDIOBJLAST = 1023;
-  CF_HDROP = 15;
-  CF_LOCALE = 16;
-  CF_OWNERDISPLAY = 128;
-  CF_PENDATA = 10;
-  CF_PRIVATEFIRST = 512;
-  CF_PRIVATELAST = 767;
-  CF_RIFF = 11;
-  CF_SYLK = 4;
-  CF_WAVE = 12;
-  CF_TIFF = 6;
-  CF_MAX = 17;
-  
-// Win32 colors
-  CLR_NONE = $ffffffff;
-  CLR_DEFAULT = $ff000000;
-
-//DrawFrameControl constants
-  DFCS_HOT = $1000;
-  
-//Thread support
-  //This values is for win32, how about others??
-  INFINITE = $FFFFFFFF;
-  
-//OLE Support
-  E_OUTOFMEMORY                                = HRESULT($8007000E);
-  E_INVALIDARG                                 = HRESULT($80070057);
-  E_NOINTERFACE                                = HRESULT($80004002);
-  E_POINTER                                    = HRESULT($80004003);
-  E_HANDLE                                     = HRESULT($80070006);
-  E_ABORT                                      = HRESULT($80004004);
-  E_FAIL                                       = HRESULT($80004005);
-  E_ACCESSDENIED                               = HRESULT($80070005);
-  
-  DV_E_TYMED                                   = HRESULT($80040069);
-  DV_E_CLIPFORMAT                              = HRESULT($8004006A);
-  DV_E_LINDEX                                  = HRESULT($80040068);
-  DV_E_DVASPECT                                = HRESULT($8004006B);
-  
-  OLE_E_ADVISENOTSUPPORTED                     = HRESULT($80040003);
-  OLE_S_USEREG                                 = HRESULT($00040000);
-  
-  DATA_S_SAMEFORMATETC                         = HRESULT($00040130);
-  
-  DRAGDROP_S_DROP                              = HRESULT($00040100);
-  DRAGDROP_S_CANCEL                            = HRESULT($00040101);
-  DRAGDROP_S_USEDEFAULTCURSORS                 = HRESULT($00040102);
-  
-  NOERROR = 0;
-  
-  SPI_GETDRAGFULLWINDOWS = 38;
-  
-// windows management
-  SWP_HIDEWINDOW  = 128;
-  SWP_SHOWWINDOW = 64;
-  
-//Imagelists
-  ILD_NORMAL = 0;
-  
-// Set WindowPos
-  SWP_FRAMECHANGED = 32;
-  SWP_NOOWNERZORDER = 512;
-  SWP_NOSENDCHANGING = 1024;
-  
- { RedrawWindow  }
-  RDW_ERASE = 4;
-  RDW_FRAME = 1024;
-  RDW_INTERNALPAINT = 2;
-  RDW_INVALIDATE = 1;
-  RDW_NOERASE = 32;
-  RDW_NOFRAME = 2048;
-  RDW_NOINTERNALPAINT = 16;
-  RDW_VALIDATE = 8;
-  RDW_ERASENOW = 512;
-  RDW_UPDATENOW = 256;
-  RDW_ALLCHILDREN = 128;
-  RDW_NOCHILDREN = 64;
-  
-//SetRedraw
-  WM_SETREDRAW = 11;
-  
-//Dummy
-  CM_PARENTFONTCHANGED = 1999;
-  
-//Wheel
-  WHEEL_DELTA = 120;
-  WHEEL_PAGESCROLL = High(DWord);
-  SPI_GETWHEELSCROLLLINES = 104;
-  
-//MultiByte
-  MB_USEGLYPHCHARS = 4;
-  LOCALE_IDEFAULTANSICODEPAGE = 4100;
-  
-//Image list
-  ILD_TRANSPARENT                = $00000001;
-  ILD_MASK                       = $00000010;
-  ILD_IMAGE                      = $00000020;
-
-  ILD_ROP                        = $00000040;
-
-  ILD_BLEND25                    = $00000002;
-  ILD_BLEND50                    = $00000004;
-  ILD_OVERLAYMASK                = $00000F00;
-  
-  { GetDCEx  }
-  DCX_WINDOW = $1;
-  DCX_CACHE = $2;
-  DCX_PARENTCLIP = $20;
-  DCX_CLIPSIBLINGS = $10;
-  DCX_CLIPCHILDREN = $8;
-  DCX_NORESETATTRS = $4;
-  DCX_LOCKWINDOWUPDATE = $400;
-  DCX_EXCLUDERGN = $40;
-  DCX_INTERSECTRGN = $80;
-  DCX_VALIDATE = $200000;
-  
-  SCantWriteResourceStreamError = 'CantWriteResourceStreamError';
-  
-  //command
-  EN_UPDATE = 1024;
-  
-  ES_AUTOHSCROLL = $80;
-  ES_AUTOVSCROLL = $40;
-  ES_CENTER = $1;
-  ES_LEFT = 0;
-  ES_LOWERCASE = $10;
-  ES_MULTILINE = $4;
-  ES_NOHIDESEL = $100;
-  
-  
-  EM_SETRECTNP = 180;
-  
-  DT_END_ELLIPSIS = 32768;

+ 0 - 88
components/virtualtreeview/lclfunctions.inc

@@ -1,88 +0,0 @@
-//Used in DrawTextW
-{
-function GetTextAlign(DC: HDC): UINT;
-begin
-  Logger.AddCheckPoint(lcDummyFunctions,'GetTextAlign');
-  Result:=TA_TOP or TA_LEFT;
-end;
-}
-//Used in DrawTextW, ShortenString, TVirtualTreeColumn.ComputeHeaderLayout, TVirtualTreeColumns.DrawButtonText,
-// TVTEdit.AutoAdjustSize, TCustomVirtualStringTree.PaintNormalText, TCustomVirtualStringTree.WMSetFont
-// TCustomVirtualStringTree.DoTextMeasuring
-{
-function GetTextExtentPoint32W(DC: HDC; Str: PWideChar; Count: Integer; var Size: TSize): Boolean;
-var
- TempStr: String;
-begin
-  Logger.AddCheckPoint(lcDummyFunctions,'GetTextExtentPoint32W');
-  TempStr:=WideCharToString(Str);
-  Result:=GetTextExtentPoint(DC, PChar(TempStr), Length(TempStr), Size);
-end;
-}
-//Used in DrawTextW
-{
-function ExtTextOutW(DC: HDC; X, Y: Integer; Options: LongInt; Rect: PRect;
-  Str: PWideChar; Count: LongInt; Dx: PInteger): Boolean;
-var
- TempStr: String;
-begin
-  Logger.AddCheckPoint(lcDummyFunctions,'ExtTextOutW');
-  TempStr:=WideCharToString(Str);
-  Result:= ExtTextOut(DC, X, Y, Options, Rect, PChar(TempStr), Length(TempStr), Dx);
-end;
-}
-
-//Used in TVirtualTreeHintWindow.CalcHintRect, TVirtualTreeColumn.ComputeHeaderLayout
-//  TBaseVirtualTree.CollectSelectedNodesRTL, TBaseVirtualTree.DetermineHitPositionRTL
-// TBaseVirtualTree.UpdateEditBounds, TBaseVirtualTree.GetDisplayRect, PaintTree,
-// TStringEditLink.PrepareEdit, TCustomVirtualStringTree.ComputeNodeHeight etc
-
-function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints; cPoints: UINT): Integer;
-var
-  I:Integer;
-  XOffset, YOffset: SmallInt;
-  FromRect,ToRect: TRect;
-begin
-  GetWindowRect(hWndFrom,FromRect);
-  GetWindowRect(hWndTo,ToRect);
-  XOffset:=(FromRect.Left - ToRect.Left);
-  YOffset:=(FromRect.Top - ToRect.Top);
-  for i:=0 to cPoints - 1 do
-  begin
-    {
-    Mode Delphi does not support treating a pointer as a array
-    if ObjFpc is used than this syntax is preferred
-    PPoint(@lpPoints)[i].x:= XOffset + PPoint(@lpPoints)[i].x;
-    PPoint(@lpPoints)[i].y:= YOffset + PPoint(@lpPoints)[i].y;
-    }
-    PPoint(@lpPoints+i)^.x:= XOffset + PPoint(@lpPoints+i)^.x;
-    PPoint(@lpPoints+i)^.y:= YOffset + PPoint(@lpPoints+i)^.y;
-  end;
-  Result:=MakeLong(XOffset,YOffset);
-end;
-
-
-{$ifndef UseExternalDragManager}
-function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;external 'ole32.dll' name 'RegisterDragDrop';
-
-function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;external 'ole32.dll' name 'RevokeDragDrop';
-
-function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;stdcall;external 'ole32.dll' name 'DoDragDrop';
-
-function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleInitialize';
-
-procedure OleUninitialize;stdcall;external 'ole32.dll' name 'OleUninitialize';
-
-procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;external 'ole32.dll' name 'ReleaseStgMedium';
-
-function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleSetClipboard';
-
-function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleGetClipboard';
-
-function OleFlushClipboard:WINOLEAPI;stdcall;external 'ole32.dll' name 'OleFlushClipboard';
-
-function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleIsCurrentClipboard';
-
-function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;external 'ole32.dll' name 'CreateStreamOnHGlobal';
-
-{$endif}

+ 0 - 5
components/virtualtreeview/readme.txt

@@ -1,5 +0,0 @@
-Virtual Tree View from Lazarus CCR
-https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/components/virtualtreeview-new/branches/4.8
-Rev. 2200
-
-Some modifications done for Double Commander (see doublecmd.diff).

+ 0 - 36
components/virtualtreeview/registervirtualtreeview.pas

@@ -1,36 +0,0 @@
-unit registervirtualtreeview; 
-
-{$Mode ObjFpc}
-{$H+}
-
-interface
-
-uses 
-  Classes, SysUtils, LResources, LazarusPackageIntf,
-  VirtualTrees, VTHeaderPopup;
-  
-procedure Register;
-
-implementation
-
-procedure RegisterUnitVirtualTrees;
-begin
-  RegisterComponents('Virtual Controls', [TVirtualDrawTree, TVirtualStringTree]);
-end;  
-
-procedure RegisterUnitVTHeaderPopup;
-begin
-  RegisterComponents('Virtual Controls', [TVTHeaderPopupMenu]);
-end;
-
-procedure Register;
-
-begin
-  RegisterUnit('VirtualTrees', @RegisterUnitVirtualTrees);
-  RegisterUnit('VTHeaderPopup', @RegisterUnitVTHeaderPopup);
-end; 
-
-initialization
-{$i ideicons.lrs}
- 
-end.

+ 0 - 3
components/virtualtreeview/units/carbon/fakeactivex.pas

@@ -1,3 +0,0 @@
-unit FakeActiveX;
-
-{$i ../dummyactivex.inc}

+ 0 - 37
components/virtualtreeview/units/carbon/fakemmsystem.pas

@@ -1,37 +0,0 @@
-unit fakemmsystem;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  Classes, SysUtils, Types;
-  
-function timeBeginPeriod(x1: DWord): DWord;
-
-function timeEndPeriod(x1: DWord): DWord;
-
-function timeGetTime: DWORD;
-
-implementation
-
-uses
-  LCLIntf;
-
-function timeBeginPeriod(x1: DWord): DWord;
-begin
-
-end;
-
-function timeEndPeriod(x1: DWord): DWord;
-begin
-
-end;
-
-function timeGetTime: DWORD;
-begin
-  Result := GetTickCount;
-end;
-
-end.
-

+ 0 - 1623
components/virtualtreeview/units/carbon/virtualdragmanager.pas

@@ -1,1623 +0,0 @@
-unit virtualdragmanager;
-{fake unit just to compile - not used under non windows}
-
-{$mode delphi}
-
-interface
-
-uses
-  Classes, SysUtils, Types;
-
-const
-  // Drag image helpers for Windows 2000 and up.
-  IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
-  CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-
-  SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}';
-  SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}';
-  SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}';
-  
-  //Bridge to ActiveX constants
-  
-  TYMED_HGLOBAL = 1;
-  TYMED_ISTREAM = 4;
-  DVASPECT_CONTENT = 1;
-  CLSCTX_INPROC_SERVER = $0010;
-  DROPEFFECT_COPY = 1;
-  DROPEFFECT_LINK = 4;
-  DROPEFFECT_MOVE = 2;
-  DROPEFFECT_NONE = 0;
-  DROPEFFECT_SCROLL = dword($80000000);
-  DATADIR_GET = 1;
-  
-type
-  //types from win unit
-  Long = LongInt;
-  WinBool= LongBool;
-  Bool= WinBool;
-  ULONG  = cardinal;
-  LONGLONG  = int64;
-  LPDWORD = ^DWORD;
-  LPVOID  = pointer;
-       
-  TCOLORREF = cardinal;
-       
-  TIID = TGUID;
-  
-  LARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : LONG);
-    1: (QuadPart : LONGLONG);
-  end;
-  PLARGE_INTEGER = ^LARGE_INTEGER;
-  _LARGE_INTEGER = LARGE_INTEGER;
-
-  TLargeInteger = Int64;
-  PLargeInteger = ^TLargeInteger;
-
-  ULARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : DWORD);
-    1: (QuadPart : LONGLONG);
-  end;
-  PULARGE_INTEGER = ^ULARGE_INTEGER;
-  _ULARGE_INTEGER = ULARGE_INTEGER;
-     
-  
-  HANDLE = System.THandle;
-  HWND = HANDLE;
-  //HRESULT = System.HResult;
-  
-  HBITMAP = HANDLE;
-  HENHMETAFILE = HANDLE;
-  
-  //activex types
-  
-
-  IMoniker            = Interface;
-   
-  WINOLEAPI = HResult;
-  TLCID = DWORD;
-  
-  OleChar             = WChar;
-  LPOLESTR            = ^OLECHAR;
-  HMetaFilePict       = Pointer;
-  
-  
-  tagBIND_OPTS                 = Record
-                                  cvStruct,          //  sizeof(BIND_OPTS)
-                                  grfFlags,
-                                  grfMode,
-                                  dwTickCountDeadline : DWord;
-                                 End;
-  TBind_Opts                   = tagBIND_OPTS;
-  TCLIPFORMAT                  = Word;
-
-  tagDVTARGETDEVICE            = Record
-                                    tdSize                     : DWord;
-                                    tdDriverNameOffset,
-                                    tdDeviceNameOffset,
-                                    tdPortNameOffset,
-                                    tdExtDevmodeOffset         : Word;
-                                    Data                       : Record End;
-                                    End;
-  DVTARGETDEVICE               = TagDVTARGETDEVICE;
-  PDVTARGETDEVICE              = ^tagDVTARGETDEVICE;
-
-
-
-  tagFORMATETC                 = Record
-                                  CfFormat :  Word {TCLIPFORMAT};
-                                  Ptd      : PDVTARGETDEVICE;
-                                  dwAspect : DWORD;
-                                  lindex   : Long;
-                                  tymed    : DWORD;
-                                  End;
-  FORMATETC                    = TagFORMATETC;
-  TFORMATETC                   = FORMATETC;
-  LPFORMATETC                  = ^FORMATETC;
-  PFormatEtc                   = LPFORMATETC;
-
-  tagSTATDATA                  = Record
-                                                                // field used by:
-                                    FORMATETC   : Tformatetc;   // EnumAdvise, EnumData (cache), EnumFormats
-                                    advf        : DWord;        // EnumAdvise, EnumData (cache)
-                                    padvSink    : Pointer {IAdviseSink};  // EnumAdvise
-                                    dwConnection: DWord;        // EnumAdvise
-                                 End;
-  STATDATA                     = TagStatData;
-
-
-  TagSTGMEDIUM                 = Record
-                                    Tymed : DWord;
-                                    Case Integer Of
-                                      0 : (HBITMAP             : hBitmap;       PUnkForRelease :  Pointer {IUnknown});
-                                      1 : (HMETAFILEPICT       : hMetaFilePict );
-                                      2 : (HENHMETAFILE        : hEnhMetaFile  );
-                                      3 : (HGLOBAL             : hGlobal       );
-                                      4 : (lpszFileName        : LPOLESTR    );
-                                      5 : (pstm                : Pointer{IStream}  );
-                                      6 : (pstg                : Pointer{IStorage} );
-                                      End;
-  USTGMEDIUM                   = TagSTGMEDIUM;
-  STGMEDIUM                    = USTGMEDIUM;
-  TStgMedium                                                                           = TagSTGMEDIUM;
-  PStgMedium                   = ^TStgMedium;
-  LPSTGMEDIUM                  = ^STGMEDIUM;
-
-  IEnumString = Interface (IUnknown)
-       ['{00000101-0000-0000-C000-000000000046}']
-       Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall;
-       Function Skip (Celt:ULong):Hresult;StdCall;
-       Function Reset:HResult;StdCall;
-       Function Clone(Out penum:IEnumString):HResult;StdCall;
-       End;
-       
-
-    IEnumMoniker = Interface (IUnknown)
-       ['{00000102-0000-0000-C000-000000000046}']
-       Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall;
-       Function Skip(celt:Ulong):HResult; StdCall;
-       Function Reset:HResult; StdCall;
-       Function Close(out penum:IEnumMoniker):HResult;StdCall;
-       End;
-
-   IEnumSTATDATA = Interface (IUnknown)
-    ['{00000105-0000-0000-C000-000000000046}']
-    Function Next(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-//      Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-    Function Skip(Celt:ULong):HResult;StdCall;
-    Function Reset:HResult;StdCall;
-    Function Clone(out penum:IEnumstatdata):HResult;StdCall;
-    End;
-
-   IEnumFORMATETC = Interface (IUnknown)
-   ['{00000103-0000-0000-C000-000000000046}']
-   Function Next(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-   Function Skip(Celt:ULong):HResult;StdCall;
-   Function Reset:HResult;StdCall;
-   Function Clone(out penum:IEnumFORMATETC):HResult;StdCall;
-   End;
-   
-
-   
-    IPersist = Interface (IUnknown)
-       ['{0000010c-0000-0000-C000-000000000046}']
-       Function GetClassId(clsid:TClsId):HResult; StdCall;
-       End;
-
-    IPersistStream = Interface(IPersist)
-       ['{00000109-0000-0000-C000-000000000046}']
-       Function IsDirty:HResult; StdCall;
-       Function Load(Const stm: IStream):HResult; StdCall;
-       Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall;
-       Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall;
-       End;
-   
-   
-    IRunningObjectTable = Interface (IUnknown)
-       ['{00000010-0000-0000-C000-000000000046}']
-       Function Register  (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall;
-       Function Revoke    (dwRegister:DWord):HResult; StdCall;
-       Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall;
-       Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall;
-       Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall;
-       Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall;
-       Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall;
-       End;
-
-   
-    IBindCtx = Interface (IUnknown)
-       ['{0000000e-0000-0000-C000-000000000046}']
-       Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall;
-       Function RevokeObjectBound (Const Punk:IUnknown):HResult;  stdCall;
-       Function ReleaseBoundObjects :HResult;  StdCall;
-       Function SetBindOptions(Const bindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetBindOptions(var BindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall;
-       Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult;
-       Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall;
-       Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall;
-       Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall;
-       End;
-
-   
-    PIMoniker = ^IMoniker;
-    IMoniker = Interface (IPersistStream)
-      ['{0000000f-0000-0000-C000-000000000046}']
-      Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall;
-//    Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall;
-      Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-//    Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-      Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall;
-      Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall;
-      Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall;
-      Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall;
-      Function Hash   (Out dwHash:Dword):HResult;StdCall;
-      Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall;
-      Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall;
-      Function Inverse(out mk : IMoniker):HResult; StdCall;
-      Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall;
-      Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall;
-      Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall;
-      Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall;
-      Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall;
-      End;
-
-
-    IAdviseSink = Interface (IUnknown)
-        ['{0000010f-0000-0000-C000-000000000046}']
-    {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif}
-        Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall;
-        Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall;
-        Procedure OnRename (Const pmk : IMoniker); StdCall;
-        Procedure OnSave; StdCall;
-        Procedure OnClose; StdCall;
-     End;
-
-
-  //Fake interfaces
-  IDataObject = Interface (IUnknown)
-   ['{0000010e-0000-0000-C000-000000000046}']
-   Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL;
-   Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl;
-   Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall;
-   Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall;
-   Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall;
-   Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall;
-   Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;StdCall;
-   End;
-
- IDropTarget = interface(IUnknown)
-    ['{00000122-0000-0000-C000-000000000046}']
-    function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragLeave: HResult;StdCall;
-    function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall;
-  end;
-
-
-  IDropSource = interface(IUnknown)
-    ['{00000121-0000-0000-C000-000000000046}']
-    function QueryContinueDrag(fEscapePressed: BOOL;
-      grfKeyState: LongWord):HResult;StdCall;
-    function GiveFeedback(dwEffect: LongWord): HResult;StdCall;
-  end;
-  
-  
-  IDataAdviseHolder = Interface (IUnknown)
-       ['{00000110-0000-0000-C000-000000000046}']
-       Function Advise    (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall;
-       Function Unadvise  (dwConnection:Dword):HResult; StdCall;
-       Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall;
-       Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall;
-       End;
-
-  
-
-  // OLE drag'n drop support
-  TFormatEtcArray = array of TFormatEtc;
-  TFormatArray = array of Word;
-
-  // IDataObject.SetData support
-  TInternalStgMedium = packed record
-    Format: TClipFormat;
-    Medium: TStgMedium;
-  end;
-  TInternalStgMediumArray = array of TInternalStgMedium;
-
-  TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc)
-  private
-    FTree: TObject;
-    FFormatEtcArray: TFormatEtcArray;
-    FCurrentIndex: Integer;
-  public
-    constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-    function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
-    function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall;
-    function Reset: HResult; stdcall;
-    function Skip(celt: LongWord): HResult; stdcall;
-  end;
-
-  IDropTargetHelper = interface(IUnknown)
-    [SID_IDropTargetHelper]
-    function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function DragLeave: HRESULT; stdcall;
-    function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Show(fShow: Boolean): HRESULT; stdcall;
-  end;
-
-  PSHDragImage = ^TSHDragImage;
-  TSHDragImage = packed record
-    sizeDragImage: TSize;
-    ptOffset: TPoint;
-    hbmpDragImage: HBITMAP;
-    ColorRef: TColorRef;
-  end;
-
-  IDragSourceHelper = interface(IUnknown)
-    [SID_IDragSourceHelper]
-    function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall;
-    function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall;
-  end;
-
-
-
-  IVTDragManager = interface(IUnknown)
-    ['{C4B25559-14DA-446B-8901-0C879000EB16}']
-    procedure ForceDragLeave; stdcall;
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-
-    property DataObject: IDataObject read GetDataObject;
-    property DragSource: TObject read GetDragSource;
-    property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported;
-    property IsDropTarget: Boolean read GetIsDropTarget;
-  end;
-
-  // This data object is used in two different places. One is for clipboard operations and the other while dragging.
-  TVTDataObject = class(TInterfacedObject, IDataObject)
-  private
-    //FOwner: TBaseVirtualTree;          // The tree which provides clipboard or drag data.
-    FOwner: TObject;          // The tree which provides clipboard or drag data.
-    FForClipboard: Boolean;            // Determines which data to render with GetData.
-    FFormatEtcArray: TFormatEtcArray;
-    FInternalStgMediumArray: TInternalStgMediumArray;  // The available formats in the DataObject
-    FAdviseHolder: IDataAdviseHolder;  // Reference to an OLE supplied implementation for advising.
-  protected
-    function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-    function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-    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;
-    function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-      CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-    property ForClipboard: Boolean read FForClipboard;
-    property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray;
-    property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray;
-    property Owner: TObject read FOwner;
-  public
-    constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual;
-    destructor Destroy; override;
-
-    function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord):
-      HResult; virtual; stdcall;
-    function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall;
-    Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall;
-    function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall;
-    Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):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;
-    function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall;
-    function SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall;
-  end;
-
-  // TVTDragManager is a class to manage drag and drop in a Virtual Treeview.
-  TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget)
-  private
-    FOwner,                            // The tree which is responsible for drag management.
-    FDragSource: TObject;     // Reference to the source tree if the source was a VT, might be different than
-                                       // the owner tree.
-    FIsDropTarget: Boolean;            // True if the owner is currently the drop target.
-    FDataObject: IDataObject;          // A reference to the data object passed in by DragEnter (only used when the owner
-                                       // tree is the current drop target).
-    FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support
-    FFullDragging: BOOL;               // True, if full dragging is currently enabled in the system.
-
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-  public
-    constructor Create(AOwner: TObject); virtual;
-    destructor Destroy; override;
-
-    function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-      var Effect: LongWord): HResult; stdcall;
-    function DragLeave: HResult; stdcall;
-    function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    procedure ForceDragLeave; stdcall;
-    function GiveFeedback(Effect: LongWord): HResult; stdcall;
-    function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall;
-  end;
-  
-  //Ole helper functions
-
-  function Succeeded(Status : HRESULT) : BOOLEAN;
-
-  function Failed(Status : HRESULT) : BOOLEAN;
-  
-  //ActiveX functions that have wrong calling convention in fpc
-  
-  function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;
-
-  function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;
-
-  function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;
-
-  function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;
-
-  procedure OleUninitialize;stdcall;
-
-  procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;
-
-  function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleFlushClipboard:WINOLEAPI;stdcall;
-
-  function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;
-  
-  function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall;
-
-  //helper functions to isolate windows/OLE specific code
-  
-  function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-    ForClipboard: Boolean): HResult;
-    
-  function GetStreamFromMedium(Medium:TStgMedium):TStream;
-  
-  procedure UnlockMediumData(Medium:TStgMedium);
-  
-  function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject;
-  
-  function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL;
-
-implementation
-
-uses
-  VirtualTrees, Controls {$ifdef DEBUG_VTV}, vtlogger{$endif};
-  
-type
-  TVirtualTreeAccess = class (TBaseVirtualTree)
-  end;
-
-function Succeeded(Status : HRESULT) : BOOLEAN;
-  begin
-     Succeeded:=Status and HRESULT($80000000)=0;
-  end;
-
-function Failed(Status : HRESULT) : BOOLEAN;
-  begin
-     Failed:=Status and HRESULT($80000000)<>0;
-  end;
-
-function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function RevokeDragDrop(hwnd: HWND): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource;
-  dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleInitialize(pvReserved: LPVOID): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-procedure OleUninitialize;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-procedure ReleaseStgMedium(_para1: LPSTGMEDIUM);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleFlushClipboard: WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out
-  stm: IStream): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown;
-  _para3: DWORD; const _para4: TIID; out _para5): HRESULT;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-
-function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out
-  Medium: TStgMedium; ForClipboard: Boolean): HResult;
-{
-  //--------------- local function --------------------------------------------
-
-  procedure WriteNodes(Stream: TStream);
-
-  var
-    Selection: TNodeArray;
-    I: Integer;
-
-  begin
-    with TVirtualTreeAccess(Tree) do
-    begin
-      if ForClipboard then
-        Selection := GetSortedCutCopySet(True)
-      else
-        Selection := GetSortedSelection(True);
-      for I := 0 to High(Selection) do
-        WriteNode(Stream, Selection[I]);
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-}
-var
-  Data: PCardinal;
-  ResPointer: Pointer;
-  ResSize: Integer;
-  OLEStream: IStream;
-  VCLStream: TStream;
-  
-begin
- {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  VCLStream := nil;
-  try
-    Medium.PunkForRelease := 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.Pstm) := 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;
-
-
-type
-  // needed to handle OLE global memory objects
-  TOLEMemoryStream = class(TCustomMemoryStream)
-  public
-    function Write(const Buffer; Count: Integer): Longint; override;
-  end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-   // raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError));
-end;
-
-
-function GetStreamFromMedium(Medium: TStgMedium): TStream;
-
-var
-  Data: Pointer;
-  I: Integer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-{
-  Result := nil;
-  if Medium.tymed = TYMED_ISTREAM then
-    Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream)
-  else
-  begin
-    Data := GlobalLock(Medium.hGlobal);
-    if Assigned(Data) then
-    begin
-      // Get the total size of data to retrieve.
-      I := PCardinal(Data)^;
-      Inc(PCardinal(Data));
-      Result := TOLEMemoryStream.Create;
-      TOLEMemoryStream(Result).SetPointer(Data, I);
-    end;
-  end;
-}
-end;
-
-procedure UnlockMediumData(Medium: TStgMedium);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-{
-  if Medium.tymed = TYMED_HGLOBAL then
-    GlobalUnlock(Medium.hGlobal);
- }
-end;
-
-function GetTreeFromDataObject(const DataObject: IDataObject;
-  var Format: TFormatEtc): TObject;
-  
-var
-  Medium: TStgMedium;
-  Data: PVTReference;
-  
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := nil;
-  if Assigned(DataObject) then
-  begin
-    Format.cfFormat := CF_VTREFERENCE;
-    if DataObject.GetData(Format, 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 AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL;
-var
-  P:Pointer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize);
-  P := GlobalLock(Result);
-  Move(Data^, P^, DataSize);
-  GlobalUnlock(Result);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// OLE drag and drop support classes
-// This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs
-// of DD'ing various kinds of virtual data and works also between applications.
-
-//----------------- TEnumFormatEtc -------------------------------------------------------------------------------------
-
-constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-
-var
-  I: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-
-  FTree := Tree;
-  // Make a local copy of the format data.
-  SetLength(FFormatEtcArray, Length(AFormatEtcArray));
-  for I := 0 to High(AFormatEtcArray) do
-    FFormatEtcArray[I] := AFormatEtcArray[I];
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
-
-var
-  AClone: TEnumFormatEtc;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-   Result := S_OK;
-  try
-    AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray);
-    AClone.FCurrentIndex := FCurrentIndex;
-    Enum := AClone as IEnumFormatEtc;
-  except
-    Result := E_FAIL;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult;
-
-var
-  CopyCount: LongWord;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-   Result := S_FALSE;
-  CopyCount := Length(FFormatEtcArray) - FCurrentIndex;
-  if celt < CopyCount then
-    CopyCount := celt;
-  if CopyCount > 0 then
-  begin
-    Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc));
-    Inc(FCurrentIndex, CopyCount);
-    Result := S_OK;
-  end;
-  //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with
-  // a C Program call with a NULL in pCeltFetcjed??
-  //Answer: Yes. Is necessary a check here
-  if @pceltFetched <> nil then
-    pceltFetched := CopyCount;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Reset: HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  FCurrentIndex := 0;
-  Result := S_OK;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Skip(celt: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FCurrentIndex + celt < High(FFormatEtcArray) then
-  begin
-    Inc(FCurrentIndex, celt);
-    Result := S_Ok;
-  end
-  else
-    Result := S_FALSE;
-  }
-end;
-
-
-//----------------- TVTDataObject --------------------------------------------------------------------------------------
-
-constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-
-  FOwner := AOwner;
-  FForClipboard := ForClipboard;
-  TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDataObject.Destroy;
-
-var
-  I: Integer;
-  StgMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // Cancel a pending clipboard operation if this data object was created for the clipboard and
-  // is freed because something else is placed there.
-  if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then
-    TVirtualTreeAccess(FOwner).CancelCutOrCopy;
-
-  // Release any internal clipboard formats
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat);
-    if Assigned(StgMedium) then
-      ReleaseStgMedium(StgMedium);
-  end;
-
-  FormatEtcArray := nil;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-
-// Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown
-// interface, will always return the same pointer.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(TestUnknown) then
-  begin
-    if TestUnknown.QueryInterface(IUnknown, Result) = 0 then
-      Result._Release // Don't actually need it just need the pointer value
-    else
-      Result := TestUnknown
-  end
-  else
-    Result := TestUnknown
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and
-    (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and
-    (FormatEtc1.tymed and FormatEtc2.tymed <> 0);
-    
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer;
-
-var
-  I: integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := -1;
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then
-    begin
-      Result := I;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium;
-
-var
-  I: integer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := nil;
-  for I := 0 to High(InternalStgMediumArray) do
-  begin
-    if Format = InternalStgMediumArray[I].Format then
-    begin
-      Result := @InternalStgMediumArray[I].Medium;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle;
-
-// Returns a global memory block that is a copy of the passed memory block.
-
-var
-  Size: Cardinal;
-  Data,
-  NewData: PChar;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Size := GlobalSize(HGlobal);
-  Result := GlobalAlloc(GPTR, Size);
-  Data := GlobalLock(hGlobal);
-  try
-    NewData := GlobalLock(Result);
-    try
-      Move(Data^, NewData^, Size);
-    finally
-      GlobalUnLock(Result);
-    end
-  finally
-    GlobalUnLock(hGlobal);
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium;
-  var OLEResult: HResult): Boolean;
-
-// Tries to render one of the formats which have been stored via the SetData method.
-// Since this data is already there it is just copied or its reference count is increased (depending on storage medium).
-
-var
-  InternalMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  
-  Result := True;
-  InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat);
-  if Assigned(InternalMedium) then
-    OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject)
-  else
-    Result := False;
-   }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-  CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-// InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or
-// increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually
-// the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData.
-// If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during
-// that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make
-// copy of the data for the caller only to have them destroy it then need us to copy it again if necessary.
-// This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData.
-// 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;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := S_OK;
-
-  // Simply copy all fields to start with.
-  OutStgMedium := InStgMedium;
-  // The data handled here always results from a call of SetData we got. This ensures only one storage format
-  // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several
-  // storage formats).
-  case InStgMedium.tymed of
-    TYMED_HGLOBAL:
-      begin
-        if CopyInMedium then
-        begin
-          // Generate a unique copy of the data passed
-          OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal);
-          if OutStgMedium.hGlobal = 0 then
-            Result := E_OUTOFMEMORY
-        end
-        else
-          // Don't generate a copy just use ourselves and the copy previously saved.
-          OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount.
-      end;
-    TYMED_FILE:
-      begin
-        //todo_lcl_check
-        Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character.
-        OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len);
-        Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len);
-      end;
-    TYMED_ISTREAM:
-      IUnknown(OutStgMedium.Pstm)._AddRef;
-    TYMED_ISTORAGE:
-      IUnknown(OutStgMedium.Pstg)._AddRef;
-    TYMED_GDI:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy GDI objects right now.
-    TYMED_MFPICT:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now.
-    TYMED_ENHMF:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now.
-  else
-    Result := DV_E_TYMED;
-  end;
-
-  if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then
-    IUnknown(OutStgMedium.PunkForRelease)._AddRef;
-    }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink;
-  out dwConnection: DWord): HResult;
-
-// Advise sink management is greatly simplified by the IDataAdviseHolder interface.
-// We use this interface and forward all concerning calls to it.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := S_OK;
-  if FAdviseHolder = nil then
-    Result := CreateDataAdviseHolder(FAdviseHolder);
-  if Result = S_OK then
-    Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DUnadvise(dwConnection: DWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FAdviseHolder = nil then
-    Result := E_NOTIMPL
-  else
-    Result := FAdviseHolder.Unadvise(dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FAdviseHolder = nil then
-    Result := OLE_E_ADVISENOTSUPPORTED
-  else
-    Result := FAdviseHolder.EnumAdvise(enumAdvise);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult;
-
-var
-  NewList: TEnumFormatEtc;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := E_FAIL;
-  if Direction = DATADIR_GET then
-  begin
-    NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray);
-    EnumFormatEtc := NewList as IEnumFormatEtc;
-    Result := S_OK;
-  end
-  else
-    EnumFormatEtc := nil;
-  if EnumFormatEtc = nil then
-    Result := OLE_S_USEREG;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := DATA_S_SAMEFORMATETC;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult;
-
-// Data is requested by clipboard or drop target. This method dispatchs the call
-// depending on the data being requested.
-
-var
-  I: Integer;
-  Data: PVTReference;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  // The tree reference format is always supported and returned from here.
-  {
-  if FormatEtcIn.cfFormat = CF_VTREFERENCE then
-  begin
-    // Note: this format is not used while flushing the clipboard to avoid a dangling reference
-    //       when the owner tree is destroyed before the clipboard data is replaced with something else.
-    if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then
-      Result := E_FAIL
-    else
-    begin
-      Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference));
-      Data := GlobalLock(Medium.hGlobal);
-      Data.Process := GetCurrentProcessID;
-      Data.Tree := TBaseVirtualTree(FOwner);
-      GlobalUnlock(Medium.hGlobal);
-      Medium.tymed := TYMED_HGLOBAL;
-      Medium.PunkForRelease := nil;
-      Result := S_OK;
-    end;
-  end
-  else
-  begin
-    try
-      // See if we accept this type and if not get the correct return value.
-      Result := QueryGetData(FormatEtcIn);
-      if Result = S_OK then
-      begin
-        for I := 0 to High(FormatEtcArray) do
-        begin
-          if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
-          begin
-            if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
-              Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard);
-            Break;
-          end;
-        end
-      end
-    except
-      FillChar(Medium, SizeOf(Medium), #0);
-      Result := E_FAIL;
-    end;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult;
-
-var
-  I: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := DV_E_CLIPFORMAT;
-  for I := 0 to High(FFormatEtcArray) do
-  begin
-    if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then
-    begin
-      if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then
-      begin
-        if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then
-        begin
-          if FormatEtc.lindex = FFormatEtcArray[I].lindex then
-          begin
-            Result := S_OK;
-            Break;
-          end
-          else
-            Result := DV_E_LINDEX;
-        end
-        else
-          Result := DV_E_DVASPECT;
-      end
-      else
-        Result := DV_E_TYMED;
-    end;
-  end
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult;
-
-// 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;
-  LocalStgMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // See if we already have a format of that type available.
-  Index := FindFormatEtc(FormatEtc, FormatEtcArray);
-  if Index > - 1 then
-  begin
-    // Just use the TFormatEct in the array after releasing the data.
-    LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat);
-    if Assigned(LocalStgMedium) then
-    begin
-      ReleaseStgMedium(LocalStgMedium);
-      FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-    end;
-  end
-  else
-  begin
-    // It is a new format so create a new TFormatCollectionItem, copy the
-    // FormatEtc parameter into the new object and and put it in the list.
-    SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1);
-    FormatEtcArray[High(FormatEtcArray)] := FormatEtc;
-
-    // Create a new InternalStgMedium and initialize it and associate it with the format.
-    SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1);
-    InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat;
-    LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium;
-    FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-  end;
-
-  if DoRelease then
-  begin
-    // We are simply being given the data and we take control of it.
-    LocalStgMedium^ := Medium;
-    Result := S_OK
-  end
-  else
-  begin
-    // We need to reference count or copy the data and keep our own references to it.
-    Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject);
-
-    // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium.
-    // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that
-    // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN.
-    if Assigned(LocalStgMedium.PunkForRelease) then
-    begin
-      if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then
-        IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface
-    end;
-  end;
-
-  // Tell all registered advice sinks about the data change.
-  if Assigned(FAdviseHolder) then
-    FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0);
-  }
-end;
-
-
-//----------------- TVTDragManager -------------------------------------------------------------------------------------
-
-constructor TVTDragManager.Create(AOwner: TObject);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-  FOwner := AOwner;
-
-  // Create an instance  of the drop target helper interface. This will fail but not harm on systems which do
-  // not support this interface (everything below Windows 2000);
-  CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDragManager.Destroy;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // Set the owner's reference to us to nil otherwise it will access an invalid pointer
-  // after our desctruction is complete.
-  TVirtualTreeAccess(FOwner).FreeDragManager;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDataObject: IDataObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem.
-  // In this case there is no local reference to a data object and one is created (but not stored).
-  // If there is a local reference then the owner tree is currently the drop target and the stored interface is
-  // that of the drag initiator.
-  if Assigned(FDataObject) then
-    Result := FDataObject
-  else
-  begin
-    Result := TVirtualTreeAccess(FOwner).DoCreateDataObject;
-    if Result = nil then
-      Result := TVTDataObject.Create(FOwner, False) as IDataObject;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDragSource: TObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := FDragSource;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDropTargetHelperSupported: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := Assigned(FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetIsDropTarget: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := FIsDropTarget;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  FDataObject := DataObject;
-  FIsDropTarget := True;
-
-  SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0);
-  // If full dragging of window contents is disabled in the system then our tree windows will be locked
-  // and cannot be updated during a drag operation. With the following call painting is again enabled.
-  if not FFullDragging then
-    LockWindowUpdate(0);
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect);
-
-  FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject);
-  Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragLeave: HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-
-  TVirtualTreeAccess(FOwner).DragLeave;
-  FIsDropTarget := False;
-  FDragSource := nil;
-  FDataObject := nil;
-  Result := NOERROR;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragOver(Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.Drop(DataObject, Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect);
-  FIsDropTarget := False;
-  FDataObject := nil;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragManager.ForceDragLeave;
-
-// Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive
-// a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from
-// screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE).
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-    }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GiveFeedback(Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := DRAGDROP_S_USEDEFAULTCURSORS;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult;
-
-var
-  RButton,
-  LButton: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  LButton := (KeyState and MK_LBUTTON) <> 0;
-  RButton := (KeyState and MK_RBUTTON) <> 0;
-
-  // Drag'n drop canceled by pressing both mouse buttons or Esc?
-  if (LButton and RButton) or EscapePressed then
-    Result := DRAGDROP_S_CANCEL
-  else
-    // Drag'n drop finished?
-    if not (LButton or RButton) then
-      Result := DRAGDROP_S_DROP
-    else
-      Result := S_OK;
-  }
-end;
-
-
-end.
-

+ 0 - 58
components/virtualtreeview/units/carbon/virtualpanningwindow.pas

@@ -1,58 +0,0 @@
-unit virtualpanningwindow;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  LCLType, Graphics, Classes, SysUtils;
-  
-type
-
-  { TVirtualPanningWindow }
-
-  TVirtualPanningWindow = class
-  private
-    FHandle: THandle;
-    FOwnerHandle: THandle;
-    FImage: TBitmap;
-    procedure HandlePaintMessage;
-  public
-    procedure Start(OwnerHandle: THandle; const Position: TPoint);
-    procedure Stop;
-    procedure Show(ClipRegion: HRGN);
-    property Image: TBitmap read FImage;
-    property Handle: THandle read FHandle;
-  end;
-
-implementation
-
-{$ifdef DEBUG_VTV}
-uses
-  vtlogger;
-{$endif}
-
-{ TVirtualPanningWindow }
-
-procedure TVirtualPanningWindow.HandlePaintMessage;
-begin
-end;
-
-procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint);
-begin  
-  FImage := TBitmap.Create;
-end;
-
-procedure TVirtualPanningWindow.Stop;
-begin
-  FImage.Free;
-  FImage := nil;
-end;
-
-procedure TVirtualPanningWindow.Show(ClipRegion: HRGN);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif}
-end;
-
-end.
-

+ 0 - 420
components/virtualtreeview/units/dummyactivex.inc

@@ -1,420 +0,0 @@
-
-
-{fake unit just to compile - not used under non windows}
-
-{$mode delphi}
-
-interface
-
-uses
-  {$ifdef Windows} Windows, {$endif} Classes, SysUtils, Types;
-
-const
-  TYMED_HGLOBAL = 1;
-  TYMED_ISTREAM = 4;
-  DVASPECT_CONTENT = 1;
-  CLSCTX_INPROC_SERVER = $0010;
-  DROPEFFECT_COPY = 1;
-  DROPEFFECT_LINK = 4;
-  DROPEFFECT_MOVE = 2;
-  DROPEFFECT_NONE = 0;
-  DROPEFFECT_SCROLL = dword($80000000);
-  DATADIR_GET = 1;
-
-type
-  //types from win unit
-  Long = LongInt;
-  WinBool = LongBool;
-  Bool = WinBool;
-  ULONG  = cardinal;
-  PULONG = ^ULONG;
-  LONGLONG  = int64;
-  LPDWORD = ^DWORD;
-  LPVOID  = pointer;
-
-  TCOLORREF = cardinal;
-
-  TIID = TGUID;
-
-  LARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : LONG);
-    1: (QuadPart : LONGLONG);
-  end;
-  PLARGE_INTEGER = ^LARGE_INTEGER;
-  _LARGE_INTEGER = LARGE_INTEGER;
-
-  TLargeInteger = Int64;
-  PLargeInteger = ^TLargeInteger;
-
-  ULARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : DWORD);
-    1: (QuadPart : LONGLONG);
-  end;
-  PULARGE_INTEGER = ^ULARGE_INTEGER;
-  _ULARGE_INTEGER = ULARGE_INTEGER;
-
-
-  HANDLE = System.THandle;
-  HWND = HANDLE;
-  //HRESULT = System.HResult;
-
-  HBITMAP = HANDLE;
-  HENHMETAFILE = HANDLE;
-
-  //activex types
-
-
-  IMoniker            = Interface;
-
-  WINOLEAPI = HResult;
-  TLCID = DWORD;
-
-  OleChar             = WChar;
-  LPOLESTR            = ^OLECHAR;
-  HMetaFilePict       = Pointer;
-
-
-  tagBIND_OPTS                 = Record
-                                  cvStruct,          //  sizeof(BIND_OPTS)
-                                  grfFlags,
-                                  grfMode,
-                                  dwTickCountDeadline : DWord;
-                                 End;
-  TBind_Opts                   = tagBIND_OPTS;
-  TCLIPFORMAT                  = Word;
-
-  tagDVTARGETDEVICE            = Record
-                                    tdSize                     : DWord;
-                                    tdDriverNameOffset,
-                                    tdDeviceNameOffset,
-                                    tdPortNameOffset,
-                                    tdExtDevmodeOffset         : Word;
-                                    Data                       : Record End;
-                                    End;
-  DVTARGETDEVICE               = TagDVTARGETDEVICE;
-  PDVTARGETDEVICE              = ^tagDVTARGETDEVICE;
-
-
-
-  tagFORMATETC                 = Record
-                                  CfFormat :  Word {TCLIPFORMAT};
-                                  Ptd      : PDVTARGETDEVICE;
-                                  dwAspect : DWORD;
-                                  lindex   : Long;
-                                  tymed    : DWORD;
-                                  End;
-  FORMATETC                    = TagFORMATETC;
-  TFORMATETC                   = FORMATETC;
-  LPFORMATETC                  = ^FORMATETC;
-  PFormatEtc                   = LPFORMATETC;
-
-  tagSTATDATA                  = Record
-                                                                // field used by:
-                                    FORMATETC   : Tformatetc;   // EnumAdvise, EnumData (cache), EnumFormats
-                                    advf        : DWord;        // EnumAdvise, EnumData (cache)
-                                    padvSink    : Pointer {IAdviseSink};  // EnumAdvise
-                                    dwConnection: DWord;        // EnumAdvise
-                                 End;
-  STATDATA                     = TagStatData;
-
-
-  TagSTGMEDIUM                 = Record
-                                    Tymed : DWord;
-                                    Case Integer Of
-                                      0 : (HBITMAP             : hBitmap;       PUnkForRelease :  Pointer {IUnknown});
-                                      1 : (HMETAFILEPICT       : hMetaFilePict );
-                                      2 : (HENHMETAFILE        : hEnhMetaFile  );
-                                      3 : (HGLOBAL             : hGlobal       );
-                                      4 : (lpszFileName        : LPOLESTR    );
-                                      5 : (pstm                : Pointer{IStream}  );
-                                      6 : (pstg                : Pointer{IStorage} );
-                                      End;
-  USTGMEDIUM                   = TagSTGMEDIUM;
-  STGMEDIUM                    = USTGMEDIUM;
-  TStgMedium                                                                           = TagSTGMEDIUM;
-  PStgMedium                   = ^TStgMedium;
-  LPSTGMEDIUM                  = ^STGMEDIUM;
-
-  IEnumString = Interface (IUnknown)
-       ['{00000101-0000-0000-C000-000000000046}']
-       Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall;
-       Function Skip (Celt:ULong):Hresult;StdCall;
-       Function Reset:HResult;StdCall;
-       Function Clone(Out penum:IEnumString):HResult;StdCall;
-       End;
-
-
-    IEnumMoniker = Interface (IUnknown)
-       ['{00000102-0000-0000-C000-000000000046}']
-       Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall;
-       Function Skip(celt:Ulong):HResult; StdCall;
-       Function Reset:HResult; StdCall;
-       Function Close(out penum:IEnumMoniker):HResult;StdCall;
-       End;
-
-   IEnumSTATDATA = Interface (IUnknown)
-    ['{00000105-0000-0000-C000-000000000046}']
-    Function Next (Celt:ULong;Out xcelt;pceltfetched : PUlong):HResult; StdCall;
-//      Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-    Function Skip(Celt:ULong):HResult;StdCall;
-    Function Reset:HResult;StdCall;
-    Function Clone(out penum:IEnumstatdata):HResult;StdCall;
-    End;
-
-   IEnumFORMATETC = Interface (IUnknown)
-   ['{00000103-0000-0000-C000-000000000046}']
-   Function Next(Celt:ULong;Out Rgelt:FormatEtc;pceltFetched:pULong=nil):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-   Function Skip(Celt:ULong):HResult;StdCall;
-   Function Reset:HResult;StdCall;
-   Function Clone(out penum:IEnumFORMATETC):HResult;StdCall;
-   End;
-
-
-
-    IPersist = Interface (IUnknown)
-       ['{0000010c-0000-0000-C000-000000000046}']
-       Function GetClassId(clsid:TClsId):HResult; StdCall;
-       End;
-
-    IPersistStream = Interface(IPersist)
-       ['{00000109-0000-0000-C000-000000000046}']
-       Function IsDirty:HResult; StdCall;
-       Function Load(Const stm: IStream):HResult; StdCall;
-       Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall;
-       Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall;
-       End;
-
-
-    IRunningObjectTable = Interface (IUnknown)
-       ['{00000010-0000-0000-C000-000000000046}']
-       Function Register  (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall;
-       Function Revoke    (dwRegister:DWord):HResult; StdCall;
-       Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall;
-       Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall;
-       Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall;
-       Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall;
-       Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall;
-       End;
-
-
-    IBindCtx = Interface (IUnknown)
-       ['{0000000e-0000-0000-C000-000000000046}']
-       Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall;
-       Function RevokeObjectBound (Const Punk:IUnknown):HResult;  stdCall;
-       Function ReleaseBoundObjects :HResult;  StdCall;
-       Function SetBindOptions(Const bindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetBindOptions(var BindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall;
-       Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult;
-       Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall;
-       Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall;
-       Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall;
-       End;
-
-
-    PIMoniker = ^IMoniker;
-    IMoniker = Interface (IPersistStream)
-      ['{0000000f-0000-0000-C000-000000000046}']
-      Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall;
-//    Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall;
-      Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-//    Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-      Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall;
-      Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall;
-      Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall;
-      Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall;
-      Function Hash   (Out dwHash:Dword):HResult;StdCall;
-      Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall;
-      Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall;
-      Function Inverse(out mk : IMoniker):HResult; StdCall;
-      Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall;
-      Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall;
-      Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall;
-      Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall;
-      Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall;
-      End;
-
-
-    IAdviseSink = Interface (IUnknown)
-        ['{0000010f-0000-0000-C000-000000000046}']
-    {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif}
-        Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall;
-        Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall;
-        Procedure OnRename (Const pmk : IMoniker); StdCall;
-        Procedure OnSave; StdCall;
-        Procedure OnClose; StdCall;
-     End;
-
-
-  //Fake interfaces
-  IDataObject = Interface (IUnknown)
-   ['{0000010e-0000-0000-C000-000000000046}']
-   Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL;
-   Function GetCanonicalFormatEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl;
-   Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall;
-   Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall;
-   Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall;
-   Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall;
-   Function EnumDAdvise(Out enumAdvise : IEnumStatData):HResult;StdCall;
-   End;
-
- IDropTarget = interface(IUnknown)
-    ['{00000122-0000-0000-C000-000000000046}']
-    function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragLeave: HResult;StdCall;
-    function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall;
-  end;
-
-
-  IDropSource = interface(IUnknown)
-    ['{00000121-0000-0000-C000-000000000046}']
-    function QueryContinueDrag(fEscapePressed: BOOL;
-      grfKeyState: DWORD):HResult;StdCall;
-    function GiveFeedback(dwEffect: DWORD): HResult;StdCall;
-  end;
-
-
-  IDataAdviseHolder = Interface (IUnknown)
-       ['{00000110-0000-0000-C000-000000000046}']
-       Function Advise    (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall;
-       Function Unadvise  (dwConnection:Dword):HResult; StdCall;
-       Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall;
-       Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall;
-       End;
-
-
-
-//Ole helper functions
-
-  function Succeeded(Status : HRESULT) : BOOLEAN;
-
-  function Failed(Status : HRESULT) : BOOLEAN;
-
-  //ActiveX functions that have wrong calling convention in fpc
-
-  function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;
-
-  function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;
-
-  function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;
-
-  function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;
-
-  procedure OleUninitialize;stdcall;
-
-  procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;
-
-  function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleFlushClipboard:WINOLEAPI;stdcall;
-
-  function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;
-
-  function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall;
-
-implementation
-
-
-function Succeeded(Status : HRESULT) : BOOLEAN;
-  begin
-     Succeeded:=Status and HRESULT($80000000)=0;
-  end;
-
-function Failed(Status : HRESULT) : BOOLEAN;
-  begin
-     Failed:=Status and HRESULT($80000000)<>0;
-  end;
-  
-function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function RevokeDragDrop(hwnd: HWND): WINOLEAPI;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource;
-  dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function OleInitialize(pvReserved: LPVOID): WINOLEAPI;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-procedure OleUninitialize;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-procedure ReleaseStgMedium(_para1: LPSTGMEDIUM);
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function OleFlushClipboard: WINOLEAPI;
-begin
- // Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out
-  stm: IStream): WINOLEAPI;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-
-function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown;
-  _para3: DWORD; const _para4: TIID; out _para5): HRESULT;
-begin
-  //Logger.SendError([lcOle],'Ole function called in Linux');
-  //Logger.SendCallStack([lcOle],'Stack');
-end;
-  
-
-end.

+ 0 - 3
components/virtualtreeview/units/gtk/fakeactivex.pas

@@ -1,3 +0,0 @@
-unit FakeActiveX;
-
-{$i ../dummyactivex.inc}

+ 0 - 38
components/virtualtreeview/units/gtk/fakemmsystem.pas

@@ -1,38 +0,0 @@
-unit fakemmsystem;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  Classes, SysUtils, Types;
-  
-function timeBeginPeriod(x1: DWord): DWord;
-
-function timeEndPeriod(x1: DWord): DWord;
-
-function timeGetTime: DWORD;
-
-implementation
-
-function timeBeginPeriod(x1: DWord): DWord;
-begin
-
-end;
-
-function timeEndPeriod(x1: DWord): DWord;
-begin
-
-end;
-
-function timeGetTime: DWORD;
-var
-  ATime: TSystemTime;
-begin
-  //todo: properly implement
-  GetLocalTime(ATime);
-  Result := ATime.MilliSecond;
-end;
-
-end.
-

+ 0 - 1623
components/virtualtreeview/units/gtk/virtualdragmanager.pas

@@ -1,1623 +0,0 @@
-unit virtualdragmanager;
-{fake unit just to compile - not used under non windows}
-
-{$mode delphi}
-
-interface
-
-uses
-  Classes, SysUtils, Types;
-
-const
-  // Drag image helpers for Windows 2000 and up.
-  IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
-  CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-
-  SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}';
-  SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}';
-  SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}';
-  
-  //Bridge to ActiveX constants
-  
-  TYMED_HGLOBAL = 1;
-  TYMED_ISTREAM = 4;
-  DVASPECT_CONTENT = 1;
-  CLSCTX_INPROC_SERVER = $0010;
-  DROPEFFECT_COPY = 1;
-  DROPEFFECT_LINK = 4;
-  DROPEFFECT_MOVE = 2;
-  DROPEFFECT_NONE = 0;
-  DROPEFFECT_SCROLL = dword($80000000);
-  DATADIR_GET = 1;
-  
-type
-  //types from win unit
-  Long = LongInt;
-  WinBool= LongBool;
-  Bool= WinBool;
-  ULONG  = cardinal;
-  LONGLONG  = int64;
-  LPDWORD = ^DWORD;
-  LPVOID  = pointer;
-       
-  TCOLORREF = cardinal;
-       
-  TIID = TGUID;
-  
-  LARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : LONG);
-    1: (QuadPart : LONGLONG);
-  end;
-  PLARGE_INTEGER = ^LARGE_INTEGER;
-  _LARGE_INTEGER = LARGE_INTEGER;
-
-  TLargeInteger = Int64;
-  PLargeInteger = ^TLargeInteger;
-
-  ULARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : DWORD);
-    1: (QuadPart : LONGLONG);
-  end;
-  PULARGE_INTEGER = ^ULARGE_INTEGER;
-  _ULARGE_INTEGER = ULARGE_INTEGER;
-     
-  
-  HANDLE = System.THandle;
-  HWND = HANDLE;
-  //HRESULT = System.HResult;
-  
-  HBITMAP = HANDLE;
-  HENHMETAFILE = HANDLE;
-  
-  //activex types
-  
-
-  IMoniker            = Interface;
-   
-  WINOLEAPI = HResult;
-  TLCID = DWORD;
-  
-  OleChar             = WChar;
-  LPOLESTR            = ^OLECHAR;
-  HMetaFilePict       = Pointer;
-  
-  
-  tagBIND_OPTS                 = Record
-                                  cvStruct,          //  sizeof(BIND_OPTS)
-                                  grfFlags,
-                                  grfMode,
-                                  dwTickCountDeadline : DWord;
-                                 End;
-  TBind_Opts                   = tagBIND_OPTS;
-  TCLIPFORMAT                  = Word;
-
-  tagDVTARGETDEVICE            = Record
-                                    tdSize                     : DWord;
-                                    tdDriverNameOffset,
-                                    tdDeviceNameOffset,
-                                    tdPortNameOffset,
-                                    tdExtDevmodeOffset         : Word;
-                                    Data                       : Record End;
-                                    End;
-  DVTARGETDEVICE               = TagDVTARGETDEVICE;
-  PDVTARGETDEVICE              = ^tagDVTARGETDEVICE;
-
-
-
-  tagFORMATETC                 = Record
-                                  CfFormat :  Word {TCLIPFORMAT};
-                                  Ptd      : PDVTARGETDEVICE;
-                                  dwAspect : DWORD;
-                                  lindex   : Long;
-                                  tymed    : DWORD;
-                                  End;
-  FORMATETC                    = TagFORMATETC;
-  TFORMATETC                   = FORMATETC;
-  LPFORMATETC                  = ^FORMATETC;
-  PFormatEtc                   = LPFORMATETC;
-
-  tagSTATDATA                  = Record
-                                                                // field used by:
-                                    FORMATETC   : Tformatetc;   // EnumAdvise, EnumData (cache), EnumFormats
-                                    advf        : DWord;        // EnumAdvise, EnumData (cache)
-                                    padvSink    : Pointer {IAdviseSink};  // EnumAdvise
-                                    dwConnection: DWord;        // EnumAdvise
-                                 End;
-  STATDATA                     = TagStatData;
-
-
-  TagSTGMEDIUM                 = Record
-                                    Tymed : DWord;
-                                    Case Integer Of
-                                      0 : (HBITMAP             : hBitmap;       PUnkForRelease :  Pointer {IUnknown});
-                                      1 : (HMETAFILEPICT       : hMetaFilePict );
-                                      2 : (HENHMETAFILE        : hEnhMetaFile  );
-                                      3 : (HGLOBAL             : hGlobal       );
-                                      4 : (lpszFileName        : LPOLESTR    );
-                                      5 : (pstm                : Pointer{IStream}  );
-                                      6 : (pstg                : Pointer{IStorage} );
-                                      End;
-  USTGMEDIUM                   = TagSTGMEDIUM;
-  STGMEDIUM                    = USTGMEDIUM;
-  TStgMedium                                                                           = TagSTGMEDIUM;
-  PStgMedium                   = ^TStgMedium;
-  LPSTGMEDIUM                  = ^STGMEDIUM;
-
-  IEnumString = Interface (IUnknown)
-       ['{00000101-0000-0000-C000-000000000046}']
-       Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall;
-       Function Skip (Celt:ULong):Hresult;StdCall;
-       Function Reset:HResult;StdCall;
-       Function Clone(Out penum:IEnumString):HResult;StdCall;
-       End;
-       
-
-    IEnumMoniker = Interface (IUnknown)
-       ['{00000102-0000-0000-C000-000000000046}']
-       Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall;
-       Function Skip(celt:Ulong):HResult; StdCall;
-       Function Reset:HResult; StdCall;
-       Function Close(out penum:IEnumMoniker):HResult;StdCall;
-       End;
-
-   IEnumSTATDATA = Interface (IUnknown)
-    ['{00000105-0000-0000-C000-000000000046}']
-    Function Next(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-//      Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-    Function Skip(Celt:ULong):HResult;StdCall;
-    Function Reset:HResult;StdCall;
-    Function Clone(out penum:IEnumstatdata):HResult;StdCall;
-    End;
-
-   IEnumFORMATETC = Interface (IUnknown)
-   ['{00000103-0000-0000-C000-000000000046}']
-   Function Next(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-   Function Skip(Celt:ULong):HResult;StdCall;
-   Function Reset:HResult;StdCall;
-   Function Clone(out penum:IEnumFORMATETC):HResult;StdCall;
-   End;
-   
-
-   
-    IPersist = Interface (IUnknown)
-       ['{0000010c-0000-0000-C000-000000000046}']
-       Function GetClassId(clsid:TClsId):HResult; StdCall;
-       End;
-
-    IPersistStream = Interface(IPersist)
-       ['{00000109-0000-0000-C000-000000000046}']
-       Function IsDirty:HResult; StdCall;
-       Function Load(Const stm: IStream):HResult; StdCall;
-       Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall;
-       Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall;
-       End;
-   
-   
-    IRunningObjectTable = Interface (IUnknown)
-       ['{00000010-0000-0000-C000-000000000046}']
-       Function Register  (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall;
-       Function Revoke    (dwRegister:DWord):HResult; StdCall;
-       Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall;
-       Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall;
-       Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall;
-       Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall;
-       Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall;
-       End;
-
-   
-    IBindCtx = Interface (IUnknown)
-       ['{0000000e-0000-0000-C000-000000000046}']
-       Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall;
-       Function RevokeObjectBound (Const Punk:IUnknown):HResult;  stdCall;
-       Function ReleaseBoundObjects :HResult;  StdCall;
-       Function SetBindOptions(Const bindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetBindOptions(var BindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall;
-       Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult;
-       Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall;
-       Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall;
-       Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall;
-       End;
-
-   
-    PIMoniker = ^IMoniker;
-    IMoniker = Interface (IPersistStream)
-      ['{0000000f-0000-0000-C000-000000000046}']
-      Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall;
-//    Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall;
-      Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-//    Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-      Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall;
-      Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall;
-      Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall;
-      Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall;
-      Function Hash   (Out dwHash:Dword):HResult;StdCall;
-      Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall;
-      Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall;
-      Function Inverse(out mk : IMoniker):HResult; StdCall;
-      Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall;
-      Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall;
-      Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall;
-      Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall;
-      Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall;
-      End;
-
-
-    IAdviseSink = Interface (IUnknown)
-        ['{0000010f-0000-0000-C000-000000000046}']
-    {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif}
-        Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall;
-        Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall;
-        Procedure OnRename (Const pmk : IMoniker); StdCall;
-        Procedure OnSave; StdCall;
-        Procedure OnClose; StdCall;
-     End;
-
-
-  //Fake interfaces
-  IDataObject = Interface (IUnknown)
-   ['{0000010e-0000-0000-C000-000000000046}']
-   Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL;
-   Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl;
-   Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall;
-   Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall;
-   Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall;
-   Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall;
-   Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;StdCall;
-   End;
-
- IDropTarget = interface(IUnknown)
-    ['{00000122-0000-0000-C000-000000000046}']
-    function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragLeave: HResult;StdCall;
-    function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall;
-  end;
-
-
-  IDropSource = interface(IUnknown)
-    ['{00000121-0000-0000-C000-000000000046}']
-    function QueryContinueDrag(fEscapePressed: BOOL;
-      grfKeyState: LongWord):HResult;StdCall;
-    function GiveFeedback(dwEffect: LongWord): HResult;StdCall;
-  end;
-  
-  
-  IDataAdviseHolder = Interface (IUnknown)
-       ['{00000110-0000-0000-C000-000000000046}']
-       Function Advise    (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall;
-       Function Unadvise  (dwConnection:Dword):HResult; StdCall;
-       Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall;
-       Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall;
-       End;
-
-  
-
-  // OLE drag'n drop support
-  TFormatEtcArray = array of TFormatEtc;
-  TFormatArray = array of Word;
-
-  // IDataObject.SetData support
-  TInternalStgMedium = packed record
-    Format: TClipFormat;
-    Medium: TStgMedium;
-  end;
-  TInternalStgMediumArray = array of TInternalStgMedium;
-
-  TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc)
-  private
-    FTree: TObject;
-    FFormatEtcArray: TFormatEtcArray;
-    FCurrentIndex: Integer;
-  public
-    constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-    function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
-    function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall;
-    function Reset: HResult; stdcall;
-    function Skip(celt: LongWord): HResult; stdcall;
-  end;
-
-  IDropTargetHelper = interface(IUnknown)
-    [SID_IDropTargetHelper]
-    function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function DragLeave: HRESULT; stdcall;
-    function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Show(fShow: Boolean): HRESULT; stdcall;
-  end;
-
-  PSHDragImage = ^TSHDragImage;
-  TSHDragImage = packed record
-    sizeDragImage: TSize;
-    ptOffset: TPoint;
-    hbmpDragImage: HBITMAP;
-    ColorRef: TColorRef;
-  end;
-
-  IDragSourceHelper = interface(IUnknown)
-    [SID_IDragSourceHelper]
-    function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall;
-    function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall;
-  end;
-
-
-
-  IVTDragManager = interface(IUnknown)
-    ['{C4B25559-14DA-446B-8901-0C879000EB16}']
-    procedure ForceDragLeave; stdcall;
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-
-    property DataObject: IDataObject read GetDataObject;
-    property DragSource: TObject read GetDragSource;
-    property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported;
-    property IsDropTarget: Boolean read GetIsDropTarget;
-  end;
-
-  // This data object is used in two different places. One is for clipboard operations and the other while dragging.
-  TVTDataObject = class(TInterfacedObject, IDataObject)
-  private
-    //FOwner: TBaseVirtualTree;          // The tree which provides clipboard or drag data.
-    FOwner: TObject;          // The tree which provides clipboard or drag data.
-    FForClipboard: Boolean;            // Determines which data to render with GetData.
-    FFormatEtcArray: TFormatEtcArray;
-    FInternalStgMediumArray: TInternalStgMediumArray;  // The available formats in the DataObject
-    FAdviseHolder: IDataAdviseHolder;  // Reference to an OLE supplied implementation for advising.
-  protected
-    function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-    function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-    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;
-    function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-      CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-    property ForClipboard: Boolean read FForClipboard;
-    property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray;
-    property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray;
-    property Owner: TObject read FOwner;
-  public
-    constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual;
-    destructor Destroy; override;
-
-    function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord):
-      HResult; virtual; stdcall;
-    function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall;
-    Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall;
-    function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall;
-    Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):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;
-    function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall;
-    function SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall;
-  end;
-
-  // TVTDragManager is a class to manage drag and drop in a Virtual Treeview.
-  TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget)
-  private
-    FOwner,                            // The tree which is responsible for drag management.
-    FDragSource: TObject;     // Reference to the source tree if the source was a VT, might be different than
-                                       // the owner tree.
-    FIsDropTarget: Boolean;            // True if the owner is currently the drop target.
-    FDataObject: IDataObject;          // A reference to the data object passed in by DragEnter (only used when the owner
-                                       // tree is the current drop target).
-    FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support
-    FFullDragging: BOOL;               // True, if full dragging is currently enabled in the system.
-
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-  public
-    constructor Create(AOwner: TObject); virtual;
-    destructor Destroy; override;
-
-    function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-      var Effect: LongWord): HResult; stdcall;
-    function DragLeave: HResult; stdcall;
-    function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    procedure ForceDragLeave; stdcall;
-    function GiveFeedback(Effect: LongWord): HResult; stdcall;
-    function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall;
-  end;
-  
-  //Ole helper functions
-
-  function Succeeded(Status : HRESULT) : BOOLEAN;
-
-  function Failed(Status : HRESULT) : BOOLEAN;
-  
-  //ActiveX functions that have wrong calling convention in fpc
-  
-  function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;
-
-  function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;
-
-  function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;
-
-  function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;
-
-  procedure OleUninitialize;stdcall;
-
-  procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;
-
-  function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleFlushClipboard:WINOLEAPI;stdcall;
-
-  function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;
-  
-  function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall;
-
-  //helper functions to isolate windows/OLE specific code
-  
-  function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-    ForClipboard: Boolean): HResult;
-    
-  function GetStreamFromMedium(Medium:TStgMedium):TStream;
-  
-  procedure UnlockMediumData(Medium:TStgMedium);
-  
-  function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject;
-  
-  function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL;
-
-implementation
-
-uses
-  VirtualTrees, Controls {$ifdef DEBUG_VTV}, vtlogger{$endif};
-  
-type
-  TVirtualTreeAccess = class (TBaseVirtualTree)
-  end;
-
-function Succeeded(Status : HRESULT) : BOOLEAN;
-  begin
-     Succeeded:=Status and HRESULT($80000000)=0;
-  end;
-
-function Failed(Status : HRESULT) : BOOLEAN;
-  begin
-     Failed:=Status and HRESULT($80000000)<>0;
-  end;
-
-function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function RevokeDragDrop(hwnd: HWND): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource;
-  dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleInitialize(pvReserved: LPVOID): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-procedure OleUninitialize;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-procedure ReleaseStgMedium(_para1: LPSTGMEDIUM);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleFlushClipboard: WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out
-  stm: IStream): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown;
-  _para3: DWORD; const _para4: TIID; out _para5): HRESULT;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-
-function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out
-  Medium: TStgMedium; ForClipboard: Boolean): HResult;
-{
-  //--------------- local function --------------------------------------------
-
-  procedure WriteNodes(Stream: TStream);
-
-  var
-    Selection: TNodeArray;
-    I: Integer;
-
-  begin
-    with TVirtualTreeAccess(Tree) do
-    begin
-      if ForClipboard then
-        Selection := GetSortedCutCopySet(True)
-      else
-        Selection := GetSortedSelection(True);
-      for I := 0 to High(Selection) do
-        WriteNode(Stream, Selection[I]);
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-}
-var
-  Data: PCardinal;
-  ResPointer: Pointer;
-  ResSize: Integer;
-  OLEStream: IStream;
-  VCLStream: TStream;
-  
-begin
- {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  VCLStream := nil;
-  try
-    Medium.PunkForRelease := 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.Pstm) := 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;
-
-
-type
-  // needed to handle OLE global memory objects
-  TOLEMemoryStream = class(TCustomMemoryStream)
-  public
-    function Write(const Buffer; Count: Integer): Longint; override;
-  end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-   // raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError));
-end;
-
-
-function GetStreamFromMedium(Medium: TStgMedium): TStream;
-
-var
-  Data: Pointer;
-  I: Integer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-{
-  Result := nil;
-  if Medium.tymed = TYMED_ISTREAM then
-    Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream)
-  else
-  begin
-    Data := GlobalLock(Medium.hGlobal);
-    if Assigned(Data) then
-    begin
-      // Get the total size of data to retrieve.
-      I := PCardinal(Data)^;
-      Inc(PCardinal(Data));
-      Result := TOLEMemoryStream.Create;
-      TOLEMemoryStream(Result).SetPointer(Data, I);
-    end;
-  end;
-}
-end;
-
-procedure UnlockMediumData(Medium: TStgMedium);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-{
-  if Medium.tymed = TYMED_HGLOBAL then
-    GlobalUnlock(Medium.hGlobal);
- }
-end;
-
-function GetTreeFromDataObject(const DataObject: IDataObject;
-  var Format: TFormatEtc): TObject;
-  
-var
-  Medium: TStgMedium;
-  Data: PVTReference;
-  
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := nil;
-  if Assigned(DataObject) then
-  begin
-    Format.cfFormat := CF_VTREFERENCE;
-    if DataObject.GetData(Format, 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 AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL;
-var
-  P:Pointer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize);
-  P := GlobalLock(Result);
-  Move(Data^, P^, DataSize);
-  GlobalUnlock(Result);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// OLE drag and drop support classes
-// This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs
-// of DD'ing various kinds of virtual data and works also between applications.
-
-//----------------- TEnumFormatEtc -------------------------------------------------------------------------------------
-
-constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-
-var
-  I: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-
-  FTree := Tree;
-  // Make a local copy of the format data.
-  SetLength(FFormatEtcArray, Length(AFormatEtcArray));
-  for I := 0 to High(AFormatEtcArray) do
-    FFormatEtcArray[I] := AFormatEtcArray[I];
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
-
-var
-  AClone: TEnumFormatEtc;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-   Result := S_OK;
-  try
-    AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray);
-    AClone.FCurrentIndex := FCurrentIndex;
-    Enum := AClone as IEnumFormatEtc;
-  except
-    Result := E_FAIL;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult;
-
-var
-  CopyCount: LongWord;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-   Result := S_FALSE;
-  CopyCount := Length(FFormatEtcArray) - FCurrentIndex;
-  if celt < CopyCount then
-    CopyCount := celt;
-  if CopyCount > 0 then
-  begin
-    Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc));
-    Inc(FCurrentIndex, CopyCount);
-    Result := S_OK;
-  end;
-  //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with
-  // a C Program call with a NULL in pCeltFetcjed??
-  //Answer: Yes. Is necessary a check here
-  if @pceltFetched <> nil then
-    pceltFetched := CopyCount;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Reset: HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  FCurrentIndex := 0;
-  Result := S_OK;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Skip(celt: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FCurrentIndex + celt < High(FFormatEtcArray) then
-  begin
-    Inc(FCurrentIndex, celt);
-    Result := S_Ok;
-  end
-  else
-    Result := S_FALSE;
-  }
-end;
-
-
-//----------------- TVTDataObject --------------------------------------------------------------------------------------
-
-constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-
-  FOwner := AOwner;
-  FForClipboard := ForClipboard;
-  TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDataObject.Destroy;
-
-var
-  I: Integer;
-  StgMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // Cancel a pending clipboard operation if this data object was created for the clipboard and
-  // is freed because something else is placed there.
-  if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then
-    TVirtualTreeAccess(FOwner).CancelCutOrCopy;
-
-  // Release any internal clipboard formats
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat);
-    if Assigned(StgMedium) then
-      ReleaseStgMedium(StgMedium);
-  end;
-
-  FormatEtcArray := nil;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-
-// Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown
-// interface, will always return the same pointer.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(TestUnknown) then
-  begin
-    if TestUnknown.QueryInterface(IUnknown, Result) = 0 then
-      Result._Release // Don't actually need it just need the pointer value
-    else
-      Result := TestUnknown
-  end
-  else
-    Result := TestUnknown
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and
-    (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and
-    (FormatEtc1.tymed and FormatEtc2.tymed <> 0);
-    
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer;
-
-var
-  I: integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := -1;
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then
-    begin
-      Result := I;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium;
-
-var
-  I: integer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := nil;
-  for I := 0 to High(InternalStgMediumArray) do
-  begin
-    if Format = InternalStgMediumArray[I].Format then
-    begin
-      Result := @InternalStgMediumArray[I].Medium;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle;
-
-// Returns a global memory block that is a copy of the passed memory block.
-
-var
-  Size: Cardinal;
-  Data,
-  NewData: PChar;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Size := GlobalSize(HGlobal);
-  Result := GlobalAlloc(GPTR, Size);
-  Data := GlobalLock(hGlobal);
-  try
-    NewData := GlobalLock(Result);
-    try
-      Move(Data^, NewData^, Size);
-    finally
-      GlobalUnLock(Result);
-    end
-  finally
-    GlobalUnLock(hGlobal);
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium;
-  var OLEResult: HResult): Boolean;
-
-// Tries to render one of the formats which have been stored via the SetData method.
-// Since this data is already there it is just copied or its reference count is increased (depending on storage medium).
-
-var
-  InternalMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  
-  Result := True;
-  InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat);
-  if Assigned(InternalMedium) then
-    OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject)
-  else
-    Result := False;
-   }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-  CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-// InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or
-// increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually
-// the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData.
-// If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during
-// that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make
-// copy of the data for the caller only to have them destroy it then need us to copy it again if necessary.
-// This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData.
-// 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;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := S_OK;
-
-  // Simply copy all fields to start with.
-  OutStgMedium := InStgMedium;
-  // The data handled here always results from a call of SetData we got. This ensures only one storage format
-  // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several
-  // storage formats).
-  case InStgMedium.tymed of
-    TYMED_HGLOBAL:
-      begin
-        if CopyInMedium then
-        begin
-          // Generate a unique copy of the data passed
-          OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal);
-          if OutStgMedium.hGlobal = 0 then
-            Result := E_OUTOFMEMORY
-        end
-        else
-          // Don't generate a copy just use ourselves and the copy previously saved.
-          OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount.
-      end;
-    TYMED_FILE:
-      begin
-        //todo_lcl_check
-        Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character.
-        OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len);
-        Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len);
-      end;
-    TYMED_ISTREAM:
-      IUnknown(OutStgMedium.Pstm)._AddRef;
-    TYMED_ISTORAGE:
-      IUnknown(OutStgMedium.Pstg)._AddRef;
-    TYMED_GDI:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy GDI objects right now.
-    TYMED_MFPICT:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now.
-    TYMED_ENHMF:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now.
-  else
-    Result := DV_E_TYMED;
-  end;
-
-  if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then
-    IUnknown(OutStgMedium.PunkForRelease)._AddRef;
-    }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink;
-  out dwConnection: DWord): HResult;
-
-// Advise sink management is greatly simplified by the IDataAdviseHolder interface.
-// We use this interface and forward all concerning calls to it.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := S_OK;
-  if FAdviseHolder = nil then
-    Result := CreateDataAdviseHolder(FAdviseHolder);
-  if Result = S_OK then
-    Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DUnadvise(dwConnection: DWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FAdviseHolder = nil then
-    Result := E_NOTIMPL
-  else
-    Result := FAdviseHolder.Unadvise(dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FAdviseHolder = nil then
-    Result := OLE_E_ADVISENOTSUPPORTED
-  else
-    Result := FAdviseHolder.EnumAdvise(enumAdvise);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult;
-
-var
-  NewList: TEnumFormatEtc;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := E_FAIL;
-  if Direction = DATADIR_GET then
-  begin
-    NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray);
-    EnumFormatEtc := NewList as IEnumFormatEtc;
-    Result := S_OK;
-  end
-  else
-    EnumFormatEtc := nil;
-  if EnumFormatEtc = nil then
-    Result := OLE_S_USEREG;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := DATA_S_SAMEFORMATETC;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult;
-
-// Data is requested by clipboard or drop target. This method dispatchs the call
-// depending on the data being requested.
-
-var
-  I: Integer;
-  Data: PVTReference;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  // The tree reference format is always supported and returned from here.
-  {
-  if FormatEtcIn.cfFormat = CF_VTREFERENCE then
-  begin
-    // Note: this format is not used while flushing the clipboard to avoid a dangling reference
-    //       when the owner tree is destroyed before the clipboard data is replaced with something else.
-    if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then
-      Result := E_FAIL
-    else
-    begin
-      Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference));
-      Data := GlobalLock(Medium.hGlobal);
-      Data.Process := GetCurrentProcessID;
-      Data.Tree := TBaseVirtualTree(FOwner);
-      GlobalUnlock(Medium.hGlobal);
-      Medium.tymed := TYMED_HGLOBAL;
-      Medium.PunkForRelease := nil;
-      Result := S_OK;
-    end;
-  end
-  else
-  begin
-    try
-      // See if we accept this type and if not get the correct return value.
-      Result := QueryGetData(FormatEtcIn);
-      if Result = S_OK then
-      begin
-        for I := 0 to High(FormatEtcArray) do
-        begin
-          if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
-          begin
-            if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
-              Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard);
-            Break;
-          end;
-        end
-      end
-    except
-      FillChar(Medium, SizeOf(Medium), #0);
-      Result := E_FAIL;
-    end;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult;
-
-var
-  I: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := DV_E_CLIPFORMAT;
-  for I := 0 to High(FFormatEtcArray) do
-  begin
-    if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then
-    begin
-      if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then
-      begin
-        if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then
-        begin
-          if FormatEtc.lindex = FFormatEtcArray[I].lindex then
-          begin
-            Result := S_OK;
-            Break;
-          end
-          else
-            Result := DV_E_LINDEX;
-        end
-        else
-          Result := DV_E_DVASPECT;
-      end
-      else
-        Result := DV_E_TYMED;
-    end;
-  end
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult;
-
-// 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;
-  LocalStgMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // See if we already have a format of that type available.
-  Index := FindFormatEtc(FormatEtc, FormatEtcArray);
-  if Index > - 1 then
-  begin
-    // Just use the TFormatEct in the array after releasing the data.
-    LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat);
-    if Assigned(LocalStgMedium) then
-    begin
-      ReleaseStgMedium(LocalStgMedium);
-      FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-    end;
-  end
-  else
-  begin
-    // It is a new format so create a new TFormatCollectionItem, copy the
-    // FormatEtc parameter into the new object and and put it in the list.
-    SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1);
-    FormatEtcArray[High(FormatEtcArray)] := FormatEtc;
-
-    // Create a new InternalStgMedium and initialize it and associate it with the format.
-    SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1);
-    InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat;
-    LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium;
-    FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-  end;
-
-  if DoRelease then
-  begin
-    // We are simply being given the data and we take control of it.
-    LocalStgMedium^ := Medium;
-    Result := S_OK
-  end
-  else
-  begin
-    // We need to reference count or copy the data and keep our own references to it.
-    Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject);
-
-    // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium.
-    // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that
-    // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN.
-    if Assigned(LocalStgMedium.PunkForRelease) then
-    begin
-      if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then
-        IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface
-    end;
-  end;
-
-  // Tell all registered advice sinks about the data change.
-  if Assigned(FAdviseHolder) then
-    FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0);
-  }
-end;
-
-
-//----------------- TVTDragManager -------------------------------------------------------------------------------------
-
-constructor TVTDragManager.Create(AOwner: TObject);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-  FOwner := AOwner;
-
-  // Create an instance  of the drop target helper interface. This will fail but not harm on systems which do
-  // not support this interface (everything below Windows 2000);
-  CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDragManager.Destroy;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // Set the owner's reference to us to nil otherwise it will access an invalid pointer
-  // after our desctruction is complete.
-  TVirtualTreeAccess(FOwner).FreeDragManager;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDataObject: IDataObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem.
-  // In this case there is no local reference to a data object and one is created (but not stored).
-  // If there is a local reference then the owner tree is currently the drop target and the stored interface is
-  // that of the drag initiator.
-  if Assigned(FDataObject) then
-    Result := FDataObject
-  else
-  begin
-    Result := TVirtualTreeAccess(FOwner).DoCreateDataObject;
-    if Result = nil then
-      Result := TVTDataObject.Create(FOwner, False) as IDataObject;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDragSource: TObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := FDragSource;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDropTargetHelperSupported: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := Assigned(FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetIsDropTarget: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := FIsDropTarget;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  FDataObject := DataObject;
-  FIsDropTarget := True;
-
-  SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0);
-  // If full dragging of window contents is disabled in the system then our tree windows will be locked
-  // and cannot be updated during a drag operation. With the following call painting is again enabled.
-  if not FFullDragging then
-    LockWindowUpdate(0);
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect);
-
-  FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject);
-  Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragLeave: HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-
-  TVirtualTreeAccess(FOwner).DragLeave;
-  FIsDropTarget := False;
-  FDragSource := nil;
-  FDataObject := nil;
-  Result := NOERROR;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragOver(Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.Drop(DataObject, Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect);
-  FIsDropTarget := False;
-  FDataObject := nil;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragManager.ForceDragLeave;
-
-// Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive
-// a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from
-// screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE).
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-    }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GiveFeedback(Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := DRAGDROP_S_USEDEFAULTCURSORS;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult;
-
-var
-  RButton,
-  LButton: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  LButton := (KeyState and MK_LBUTTON) <> 0;
-  RButton := (KeyState and MK_RBUTTON) <> 0;
-
-  // Drag'n drop canceled by pressing both mouse buttons or Esc?
-  if (LButton and RButton) or EscapePressed then
-    Result := DRAGDROP_S_CANCEL
-  else
-    // Drag'n drop finished?
-    if not (LButton or RButton) then
-      Result := DRAGDROP_S_DROP
-    else
-      Result := S_OK;
-  }
-end;
-
-
-end.
-

+ 0 - 58
components/virtualtreeview/units/gtk/virtualpanningwindow.pas

@@ -1,58 +0,0 @@
-unit virtualpanningwindow;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  LCLType, Graphics, Classes, SysUtils;
-  
-type
-
-  { TVirtualPanningWindow }
-
-  TVirtualPanningWindow = class
-  private
-    FHandle: THandle;
-    FOwnerHandle: THandle;
-    FImage: TBitmap;
-    procedure HandlePaintMessage;
-  public
-    procedure Start(OwnerHandle: THandle; const Position: TPoint);
-    procedure Stop;
-    procedure Show(ClipRegion: HRGN);
-    property Image: TBitmap read FImage;
-    property Handle: THandle read FHandle;
-  end;
-
-implementation
-
-{$ifdef DEBUG_VTV}
-uses
-  vtlogger;
-{$endif}
-
-{ TVirtualPanningWindow }
-
-procedure TVirtualPanningWindow.HandlePaintMessage;
-begin
-end;
-
-procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint);
-begin  
-  FImage := TBitmap.Create;
-end;
-
-procedure TVirtualPanningWindow.Stop;
-begin
-  FImage.Free;
-  FImage := nil;
-end;
-
-procedure TVirtualPanningWindow.Show(ClipRegion: HRGN);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif}
-end;
-
-end.
-

+ 0 - 3
components/virtualtreeview/units/gtk2/fakeactivex.pas

@@ -1,3 +0,0 @@
-unit FakeActiveX;
-
-{$i ../dummyactivex.inc}

+ 0 - 34
components/virtualtreeview/units/gtk2/fakemmsystem.pas

@@ -1,34 +0,0 @@
-unit fakemmsystem;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  Classes, SysUtils, Types, LCLIntf;
-  
-function timeBeginPeriod(x1: DWord): DWord;
-
-function timeEndPeriod(x1: DWord): DWord;
-
-function timeGetTime: DWORD;
-
-implementation
-
-function timeBeginPeriod(x1: DWord): DWord;
-begin
-  //
-end;
-
-function timeEndPeriod(x1: DWord): DWord;
-begin
-  //
-end;
-
-function timeGetTime: DWORD;
-begin
-  Result := GetTickCount;
-end;
-
-end.
-

+ 0 - 1623
components/virtualtreeview/units/gtk2/virtualdragmanager.pas

@@ -1,1623 +0,0 @@
-unit virtualdragmanager;
-{fake unit just to compile - not used under non windows}
-
-{$mode delphi}
-
-interface
-
-uses
-  Classes, SysUtils, Types;
-
-const
-  // Drag image helpers for Windows 2000 and up.
-  IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
-  CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-
-  SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}';
-  SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}';
-  SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}';
-  
-  //Bridge to ActiveX constants
-  
-  TYMED_HGLOBAL = 1;
-  TYMED_ISTREAM = 4;
-  DVASPECT_CONTENT = 1;
-  CLSCTX_INPROC_SERVER = $0010;
-  DROPEFFECT_COPY = 1;
-  DROPEFFECT_LINK = 4;
-  DROPEFFECT_MOVE = 2;
-  DROPEFFECT_NONE = 0;
-  DROPEFFECT_SCROLL = dword($80000000);
-  DATADIR_GET = 1;
-  
-type
-  //types from win unit
-  Long = LongInt;
-  WinBool= LongBool;
-  Bool= WinBool;
-  ULONG  = cardinal;
-  LONGLONG  = int64;
-  LPDWORD = ^DWORD;
-  LPVOID  = pointer;
-       
-  TCOLORREF = cardinal;
-       
-  TIID = TGUID;
-  
-  LARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : LONG);
-    1: (QuadPart : LONGLONG);
-  end;
-  PLARGE_INTEGER = ^LARGE_INTEGER;
-  _LARGE_INTEGER = LARGE_INTEGER;
-
-  TLargeInteger = Int64;
-  PLargeInteger = ^TLargeInteger;
-
-  ULARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : DWORD);
-    1: (QuadPart : LONGLONG);
-  end;
-  PULARGE_INTEGER = ^ULARGE_INTEGER;
-  _ULARGE_INTEGER = ULARGE_INTEGER;
-     
-  
-  HANDLE = System.THandle;
-  HWND = HANDLE;
-  //HRESULT = System.HResult;
-  
-  HBITMAP = HANDLE;
-  HENHMETAFILE = HANDLE;
-  
-  //activex types
-  
-
-  IMoniker            = Interface;
-   
-  WINOLEAPI = HResult;
-  TLCID = DWORD;
-  
-  OleChar             = WChar;
-  LPOLESTR            = ^OLECHAR;
-  HMetaFilePict       = Pointer;
-  
-  
-  tagBIND_OPTS                 = Record
-                                  cvStruct,          //  sizeof(BIND_OPTS)
-                                  grfFlags,
-                                  grfMode,
-                                  dwTickCountDeadline : DWord;
-                                 End;
-  TBind_Opts                   = tagBIND_OPTS;
-  TCLIPFORMAT                  = Word;
-
-  tagDVTARGETDEVICE            = Record
-                                    tdSize                     : DWord;
-                                    tdDriverNameOffset,
-                                    tdDeviceNameOffset,
-                                    tdPortNameOffset,
-                                    tdExtDevmodeOffset         : Word;
-                                    Data                       : Record End;
-                                    End;
-  DVTARGETDEVICE               = TagDVTARGETDEVICE;
-  PDVTARGETDEVICE              = ^tagDVTARGETDEVICE;
-
-
-
-  tagFORMATETC                 = Record
-                                  CfFormat :  Word {TCLIPFORMAT};
-                                  Ptd      : PDVTARGETDEVICE;
-                                  dwAspect : DWORD;
-                                  lindex   : Long;
-                                  tymed    : DWORD;
-                                  End;
-  FORMATETC                    = TagFORMATETC;
-  TFORMATETC                   = FORMATETC;
-  LPFORMATETC                  = ^FORMATETC;
-  PFormatEtc                   = LPFORMATETC;
-
-  tagSTATDATA                  = Record
-                                                                // field used by:
-                                    FORMATETC   : Tformatetc;   // EnumAdvise, EnumData (cache), EnumFormats
-                                    advf        : DWord;        // EnumAdvise, EnumData (cache)
-                                    padvSink    : Pointer {IAdviseSink};  // EnumAdvise
-                                    dwConnection: DWord;        // EnumAdvise
-                                 End;
-  STATDATA                     = TagStatData;
-
-
-  TagSTGMEDIUM                 = Record
-                                    Tymed : DWord;
-                                    Case Integer Of
-                                      0 : (HBITMAP             : hBitmap;       PUnkForRelease :  Pointer {IUnknown});
-                                      1 : (HMETAFILEPICT       : hMetaFilePict );
-                                      2 : (HENHMETAFILE        : hEnhMetaFile  );
-                                      3 : (HGLOBAL             : hGlobal       );
-                                      4 : (lpszFileName        : LPOLESTR    );
-                                      5 : (pstm                : Pointer{IStream}  );
-                                      6 : (pstg                : Pointer{IStorage} );
-                                      End;
-  USTGMEDIUM                   = TagSTGMEDIUM;
-  STGMEDIUM                    = USTGMEDIUM;
-  TStgMedium                                                                           = TagSTGMEDIUM;
-  PStgMedium                   = ^TStgMedium;
-  LPSTGMEDIUM                  = ^STGMEDIUM;
-
-  IEnumString = Interface (IUnknown)
-       ['{00000101-0000-0000-C000-000000000046}']
-       Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall;
-       Function Skip (Celt:ULong):Hresult;StdCall;
-       Function Reset:HResult;StdCall;
-       Function Clone(Out penum:IEnumString):HResult;StdCall;
-       End;
-       
-
-    IEnumMoniker = Interface (IUnknown)
-       ['{00000102-0000-0000-C000-000000000046}']
-       Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall;
-       Function Skip(celt:Ulong):HResult; StdCall;
-       Function Reset:HResult; StdCall;
-       Function Close(out penum:IEnumMoniker):HResult;StdCall;
-       End;
-
-   IEnumSTATDATA = Interface (IUnknown)
-    ['{00000105-0000-0000-C000-000000000046}']
-    Function Next(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-//      Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-    Function Skip(Celt:ULong):HResult;StdCall;
-    Function Reset:HResult;StdCall;
-    Function Clone(out penum:IEnumstatdata):HResult;StdCall;
-    End;
-
-   IEnumFORMATETC = Interface (IUnknown)
-   ['{00000103-0000-0000-C000-000000000046}']
-   Function Next(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-   Function Skip(Celt:ULong):HResult;StdCall;
-   Function Reset:HResult;StdCall;
-   Function Clone(out penum:IEnumFORMATETC):HResult;StdCall;
-   End;
-   
-
-   
-    IPersist = Interface (IUnknown)
-       ['{0000010c-0000-0000-C000-000000000046}']
-       Function GetClassId(clsid:TClsId):HResult; StdCall;
-       End;
-
-    IPersistStream = Interface(IPersist)
-       ['{00000109-0000-0000-C000-000000000046}']
-       Function IsDirty:HResult; StdCall;
-       Function Load(Const stm: IStream):HResult; StdCall;
-       Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall;
-       Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall;
-       End;
-   
-   
-    IRunningObjectTable = Interface (IUnknown)
-       ['{00000010-0000-0000-C000-000000000046}']
-       Function Register  (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall;
-       Function Revoke    (dwRegister:DWord):HResult; StdCall;
-       Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall;
-       Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall;
-       Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall;
-       Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall;
-       Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall;
-       End;
-
-   
-    IBindCtx = Interface (IUnknown)
-       ['{0000000e-0000-0000-C000-000000000046}']
-       Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall;
-       Function RevokeObjectBound (Const Punk:IUnknown):HResult;  stdCall;
-       Function ReleaseBoundObjects :HResult;  StdCall;
-       Function SetBindOptions(Const bindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetBindOptions(var BindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall;
-       Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult;
-       Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall;
-       Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall;
-       Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall;
-       End;
-
-   
-    PIMoniker = ^IMoniker;
-    IMoniker = Interface (IPersistStream)
-      ['{0000000f-0000-0000-C000-000000000046}']
-      Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall;
-//    Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall;
-      Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-//    Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-      Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall;
-      Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall;
-      Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall;
-      Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall;
-      Function Hash   (Out dwHash:Dword):HResult;StdCall;
-      Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall;
-      Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall;
-      Function Inverse(out mk : IMoniker):HResult; StdCall;
-      Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall;
-      Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall;
-      Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall;
-      Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall;
-      Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall;
-      End;
-
-
-    IAdviseSink = Interface (IUnknown)
-        ['{0000010f-0000-0000-C000-000000000046}']
-    {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif}
-        Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall;
-        Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall;
-        Procedure OnRename (Const pmk : IMoniker); StdCall;
-        Procedure OnSave; StdCall;
-        Procedure OnClose; StdCall;
-     End;
-
-
-  //Fake interfaces
-  IDataObject = Interface (IUnknown)
-   ['{0000010e-0000-0000-C000-000000000046}']
-   Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL;
-   Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl;
-   Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall;
-   Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall;
-   Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall;
-   Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall;
-   Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;StdCall;
-   End;
-
- IDropTarget = interface(IUnknown)
-    ['{00000122-0000-0000-C000-000000000046}']
-    function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragLeave: HResult;StdCall;
-    function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall;
-  end;
-
-
-  IDropSource = interface(IUnknown)
-    ['{00000121-0000-0000-C000-000000000046}']
-    function QueryContinueDrag(fEscapePressed: BOOL;
-      grfKeyState: LongWord):HResult;StdCall;
-    function GiveFeedback(dwEffect: LongWord): HResult;StdCall;
-  end;
-  
-  
-  IDataAdviseHolder = Interface (IUnknown)
-       ['{00000110-0000-0000-C000-000000000046}']
-       Function Advise    (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall;
-       Function Unadvise  (dwConnection:Dword):HResult; StdCall;
-       Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall;
-       Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall;
-       End;
-
-  
-
-  // OLE drag'n drop support
-  TFormatEtcArray = array of TFormatEtc;
-  TFormatArray = array of Word;
-
-  // IDataObject.SetData support
-  TInternalStgMedium = packed record
-    Format: TClipFormat;
-    Medium: TStgMedium;
-  end;
-  TInternalStgMediumArray = array of TInternalStgMedium;
-
-  TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc)
-  private
-    FTree: TObject;
-    FFormatEtcArray: TFormatEtcArray;
-    FCurrentIndex: Integer;
-  public
-    constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-    function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
-    function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall;
-    function Reset: HResult; stdcall;
-    function Skip(celt: LongWord): HResult; stdcall;
-  end;
-
-  IDropTargetHelper = interface(IUnknown)
-    [SID_IDropTargetHelper]
-    function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function DragLeave: HRESULT; stdcall;
-    function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Show(fShow: Boolean): HRESULT; stdcall;
-  end;
-
-  PSHDragImage = ^TSHDragImage;
-  TSHDragImage = packed record
-    sizeDragImage: TSize;
-    ptOffset: TPoint;
-    hbmpDragImage: HBITMAP;
-    ColorRef: TColorRef;
-  end;
-
-  IDragSourceHelper = interface(IUnknown)
-    [SID_IDragSourceHelper]
-    function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall;
-    function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall;
-  end;
-
-
-
-  IVTDragManager = interface(IUnknown)
-    ['{C4B25559-14DA-446B-8901-0C879000EB16}']
-    procedure ForceDragLeave; stdcall;
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-
-    property DataObject: IDataObject read GetDataObject;
-    property DragSource: TObject read GetDragSource;
-    property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported;
-    property IsDropTarget: Boolean read GetIsDropTarget;
-  end;
-
-  // This data object is used in two different places. One is for clipboard operations and the other while dragging.
-  TVTDataObject = class(TInterfacedObject, IDataObject)
-  private
-    //FOwner: TBaseVirtualTree;          // The tree which provides clipboard or drag data.
-    FOwner: TObject;          // The tree which provides clipboard or drag data.
-    FForClipboard: Boolean;            // Determines which data to render with GetData.
-    FFormatEtcArray: TFormatEtcArray;
-    FInternalStgMediumArray: TInternalStgMediumArray;  // The available formats in the DataObject
-    FAdviseHolder: IDataAdviseHolder;  // Reference to an OLE supplied implementation for advising.
-  protected
-    function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-    function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-    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;
-    function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-      CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-    property ForClipboard: Boolean read FForClipboard;
-    property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray;
-    property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray;
-    property Owner: TObject read FOwner;
-  public
-    constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual;
-    destructor Destroy; override;
-
-    function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord):
-      HResult; virtual; stdcall;
-    function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall;
-    Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall;
-    function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall;
-    Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):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;
-    function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall;
-    function SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall;
-  end;
-
-  // TVTDragManager is a class to manage drag and drop in a Virtual Treeview.
-  TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget)
-  private
-    FOwner,                            // The tree which is responsible for drag management.
-    FDragSource: TObject;     // Reference to the source tree if the source was a VT, might be different than
-                                       // the owner tree.
-    FIsDropTarget: Boolean;            // True if the owner is currently the drop target.
-    FDataObject: IDataObject;          // A reference to the data object passed in by DragEnter (only used when the owner
-                                       // tree is the current drop target).
-    FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support
-    FFullDragging: BOOL;               // True, if full dragging is currently enabled in the system.
-
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-  public
-    constructor Create(AOwner: TObject); virtual;
-    destructor Destroy; override;
-
-    function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-      var Effect: LongWord): HResult; stdcall;
-    function DragLeave: HResult; stdcall;
-    function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    procedure ForceDragLeave; stdcall;
-    function GiveFeedback(Effect: LongWord): HResult; stdcall;
-    function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall;
-  end;
-  
-  //Ole helper functions
-
-  function Succeeded(Status : HRESULT) : BOOLEAN;
-
-  function Failed(Status : HRESULT) : BOOLEAN;
-  
-  //ActiveX functions that have wrong calling convention in fpc
-  
-  function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;
-
-  function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;
-
-  function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;
-
-  function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;
-
-  procedure OleUninitialize;stdcall;
-
-  procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;
-
-  function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleFlushClipboard:WINOLEAPI;stdcall;
-
-  function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;
-  
-  function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall;
-
-  //helper functions to isolate windows/OLE specific code
-  
-  function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-    ForClipboard: Boolean): HResult;
-    
-  function GetStreamFromMedium(Medium:TStgMedium):TStream;
-  
-  procedure UnlockMediumData(Medium:TStgMedium);
-  
-  function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject;
-  
-  function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL;
-
-implementation
-
-uses
-  VirtualTrees, Controls {$ifdef DEBUG_VTV}, vtlogger{$endif};
-  
-type
-  TVirtualTreeAccess = class (TBaseVirtualTree)
-  end;
-
-function Succeeded(Status : HRESULT) : BOOLEAN;
-  begin
-     Succeeded:=Status and HRESULT($80000000)=0;
-  end;
-
-function Failed(Status : HRESULT) : BOOLEAN;
-  begin
-     Failed:=Status and HRESULT($80000000)<>0;
-  end;
-
-function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function RevokeDragDrop(hwnd: HWND): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource;
-  dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleInitialize(pvReserved: LPVOID): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-procedure OleUninitialize;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-procedure ReleaseStgMedium(_para1: LPSTGMEDIUM);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleFlushClipboard: WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out
-  stm: IStream): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown;
-  _para3: DWORD; const _para4: TIID; out _para5): HRESULT;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-
-function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out
-  Medium: TStgMedium; ForClipboard: Boolean): HResult;
-{
-  //--------------- local function --------------------------------------------
-
-  procedure WriteNodes(Stream: TStream);
-
-  var
-    Selection: TNodeArray;
-    I: Integer;
-
-  begin
-    with TVirtualTreeAccess(Tree) do
-    begin
-      if ForClipboard then
-        Selection := GetSortedCutCopySet(True)
-      else
-        Selection := GetSortedSelection(True);
-      for I := 0 to High(Selection) do
-        WriteNode(Stream, Selection[I]);
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-}
-var
-  Data: PCardinal;
-  ResPointer: Pointer;
-  ResSize: Integer;
-  OLEStream: IStream;
-  VCLStream: TStream;
-  
-begin
- {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  VCLStream := nil;
-  try
-    Medium.PunkForRelease := 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.Pstm) := 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;
-
-
-type
-  // needed to handle OLE global memory objects
-  TOLEMemoryStream = class(TCustomMemoryStream)
-  public
-    function Write(const Buffer; Count: Integer): Longint; override;
-  end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-   // raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError));
-end;
-
-
-function GetStreamFromMedium(Medium: TStgMedium): TStream;
-
-var
-  Data: Pointer;
-  I: Integer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-{
-  Result := nil;
-  if Medium.tymed = TYMED_ISTREAM then
-    Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream)
-  else
-  begin
-    Data := GlobalLock(Medium.hGlobal);
-    if Assigned(Data) then
-    begin
-      // Get the total size of data to retrieve.
-      I := PCardinal(Data)^;
-      Inc(PCardinal(Data));
-      Result := TOLEMemoryStream.Create;
-      TOLEMemoryStream(Result).SetPointer(Data, I);
-    end;
-  end;
-}
-end;
-
-procedure UnlockMediumData(Medium: TStgMedium);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-{
-  if Medium.tymed = TYMED_HGLOBAL then
-    GlobalUnlock(Medium.hGlobal);
- }
-end;
-
-function GetTreeFromDataObject(const DataObject: IDataObject;
-  var Format: TFormatEtc): TObject;
-  
-var
-  Medium: TStgMedium;
-  Data: PVTReference;
-  
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := nil;
-  if Assigned(DataObject) then
-  begin
-    Format.cfFormat := CF_VTREFERENCE;
-    if DataObject.GetData(Format, 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 AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL;
-var
-  P:Pointer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize);
-  P := GlobalLock(Result);
-  Move(Data^, P^, DataSize);
-  GlobalUnlock(Result);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// OLE drag and drop support classes
-// This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs
-// of DD'ing various kinds of virtual data and works also between applications.
-
-//----------------- TEnumFormatEtc -------------------------------------------------------------------------------------
-
-constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-
-var
-  I: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-
-  FTree := Tree;
-  // Make a local copy of the format data.
-  SetLength(FFormatEtcArray, Length(AFormatEtcArray));
-  for I := 0 to High(AFormatEtcArray) do
-    FFormatEtcArray[I] := AFormatEtcArray[I];
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
-
-var
-  AClone: TEnumFormatEtc;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-   Result := S_OK;
-  try
-    AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray);
-    AClone.FCurrentIndex := FCurrentIndex;
-    Enum := AClone as IEnumFormatEtc;
-  except
-    Result := E_FAIL;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult;
-
-var
-  CopyCount: LongWord;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-   Result := S_FALSE;
-  CopyCount := Length(FFormatEtcArray) - FCurrentIndex;
-  if celt < CopyCount then
-    CopyCount := celt;
-  if CopyCount > 0 then
-  begin
-    Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc));
-    Inc(FCurrentIndex, CopyCount);
-    Result := S_OK;
-  end;
-  //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with
-  // a C Program call with a NULL in pCeltFetcjed??
-  //Answer: Yes. Is necessary a check here
-  if @pceltFetched <> nil then
-    pceltFetched := CopyCount;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Reset: HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  FCurrentIndex := 0;
-  Result := S_OK;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Skip(celt: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FCurrentIndex + celt < High(FFormatEtcArray) then
-  begin
-    Inc(FCurrentIndex, celt);
-    Result := S_Ok;
-  end
-  else
-    Result := S_FALSE;
-  }
-end;
-
-
-//----------------- TVTDataObject --------------------------------------------------------------------------------------
-
-constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-
-  FOwner := AOwner;
-  FForClipboard := ForClipboard;
-  TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDataObject.Destroy;
-
-var
-  I: Integer;
-  StgMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // Cancel a pending clipboard operation if this data object was created for the clipboard and
-  // is freed because something else is placed there.
-  if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then
-    TVirtualTreeAccess(FOwner).CancelCutOrCopy;
-
-  // Release any internal clipboard formats
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat);
-    if Assigned(StgMedium) then
-      ReleaseStgMedium(StgMedium);
-  end;
-
-  FormatEtcArray := nil;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-
-// Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown
-// interface, will always return the same pointer.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(TestUnknown) then
-  begin
-    if TestUnknown.QueryInterface(IUnknown, Result) = 0 then
-      Result._Release // Don't actually need it just need the pointer value
-    else
-      Result := TestUnknown
-  end
-  else
-    Result := TestUnknown
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and
-    (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and
-    (FormatEtc1.tymed and FormatEtc2.tymed <> 0);
-    
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer;
-
-var
-  I: integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := -1;
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then
-    begin
-      Result := I;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium;
-
-var
-  I: integer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := nil;
-  for I := 0 to High(InternalStgMediumArray) do
-  begin
-    if Format = InternalStgMediumArray[I].Format then
-    begin
-      Result := @InternalStgMediumArray[I].Medium;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle;
-
-// Returns a global memory block that is a copy of the passed memory block.
-
-var
-  Size: Cardinal;
-  Data,
-  NewData: PChar;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Size := GlobalSize(HGlobal);
-  Result := GlobalAlloc(GPTR, Size);
-  Data := GlobalLock(hGlobal);
-  try
-    NewData := GlobalLock(Result);
-    try
-      Move(Data^, NewData^, Size);
-    finally
-      GlobalUnLock(Result);
-    end
-  finally
-    GlobalUnLock(hGlobal);
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium;
-  var OLEResult: HResult): Boolean;
-
-// Tries to render one of the formats which have been stored via the SetData method.
-// Since this data is already there it is just copied or its reference count is increased (depending on storage medium).
-
-var
-  InternalMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  
-  Result := True;
-  InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat);
-  if Assigned(InternalMedium) then
-    OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject)
-  else
-    Result := False;
-   }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-  CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-// InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or
-// increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually
-// the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData.
-// If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during
-// that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make
-// copy of the data for the caller only to have them destroy it then need us to copy it again if necessary.
-// This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData.
-// 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;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := S_OK;
-
-  // Simply copy all fields to start with.
-  OutStgMedium := InStgMedium;
-  // The data handled here always results from a call of SetData we got. This ensures only one storage format
-  // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several
-  // storage formats).
-  case InStgMedium.tymed of
-    TYMED_HGLOBAL:
-      begin
-        if CopyInMedium then
-        begin
-          // Generate a unique copy of the data passed
-          OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal);
-          if OutStgMedium.hGlobal = 0 then
-            Result := E_OUTOFMEMORY
-        end
-        else
-          // Don't generate a copy just use ourselves and the copy previously saved.
-          OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount.
-      end;
-    TYMED_FILE:
-      begin
-        //todo_lcl_check
-        Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character.
-        OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len);
-        Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len);
-      end;
-    TYMED_ISTREAM:
-      IUnknown(OutStgMedium.Pstm)._AddRef;
-    TYMED_ISTORAGE:
-      IUnknown(OutStgMedium.Pstg)._AddRef;
-    TYMED_GDI:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy GDI objects right now.
-    TYMED_MFPICT:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now.
-    TYMED_ENHMF:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now.
-  else
-    Result := DV_E_TYMED;
-  end;
-
-  if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then
-    IUnknown(OutStgMedium.PunkForRelease)._AddRef;
-    }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink;
-  out dwConnection: DWord): HResult;
-
-// Advise sink management is greatly simplified by the IDataAdviseHolder interface.
-// We use this interface and forward all concerning calls to it.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := S_OK;
-  if FAdviseHolder = nil then
-    Result := CreateDataAdviseHolder(FAdviseHolder);
-  if Result = S_OK then
-    Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DUnadvise(dwConnection: DWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FAdviseHolder = nil then
-    Result := E_NOTIMPL
-  else
-    Result := FAdviseHolder.Unadvise(dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FAdviseHolder = nil then
-    Result := OLE_E_ADVISENOTSUPPORTED
-  else
-    Result := FAdviseHolder.EnumAdvise(enumAdvise);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult;
-
-var
-  NewList: TEnumFormatEtc;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := E_FAIL;
-  if Direction = DATADIR_GET then
-  begin
-    NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray);
-    EnumFormatEtc := NewList as IEnumFormatEtc;
-    Result := S_OK;
-  end
-  else
-    EnumFormatEtc := nil;
-  if EnumFormatEtc = nil then
-    Result := OLE_S_USEREG;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := DATA_S_SAMEFORMATETC;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult;
-
-// Data is requested by clipboard or drop target. This method dispatchs the call
-// depending on the data being requested.
-
-var
-  I: Integer;
-  Data: PVTReference;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  // The tree reference format is always supported and returned from here.
-  {
-  if FormatEtcIn.cfFormat = CF_VTREFERENCE then
-  begin
-    // Note: this format is not used while flushing the clipboard to avoid a dangling reference
-    //       when the owner tree is destroyed before the clipboard data is replaced with something else.
-    if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then
-      Result := E_FAIL
-    else
-    begin
-      Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference));
-      Data := GlobalLock(Medium.hGlobal);
-      Data.Process := GetCurrentProcessID;
-      Data.Tree := TBaseVirtualTree(FOwner);
-      GlobalUnlock(Medium.hGlobal);
-      Medium.tymed := TYMED_HGLOBAL;
-      Medium.PunkForRelease := nil;
-      Result := S_OK;
-    end;
-  end
-  else
-  begin
-    try
-      // See if we accept this type and if not get the correct return value.
-      Result := QueryGetData(FormatEtcIn);
-      if Result = S_OK then
-      begin
-        for I := 0 to High(FormatEtcArray) do
-        begin
-          if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
-          begin
-            if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
-              Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard);
-            Break;
-          end;
-        end
-      end
-    except
-      FillChar(Medium, SizeOf(Medium), #0);
-      Result := E_FAIL;
-    end;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult;
-
-var
-  I: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := DV_E_CLIPFORMAT;
-  for I := 0 to High(FFormatEtcArray) do
-  begin
-    if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then
-    begin
-      if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then
-      begin
-        if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then
-        begin
-          if FormatEtc.lindex = FFormatEtcArray[I].lindex then
-          begin
-            Result := S_OK;
-            Break;
-          end
-          else
-            Result := DV_E_LINDEX;
-        end
-        else
-          Result := DV_E_DVASPECT;
-      end
-      else
-        Result := DV_E_TYMED;
-    end;
-  end
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult;
-
-// 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;
-  LocalStgMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // See if we already have a format of that type available.
-  Index := FindFormatEtc(FormatEtc, FormatEtcArray);
-  if Index > - 1 then
-  begin
-    // Just use the TFormatEct in the array after releasing the data.
-    LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat);
-    if Assigned(LocalStgMedium) then
-    begin
-      ReleaseStgMedium(LocalStgMedium);
-      FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-    end;
-  end
-  else
-  begin
-    // It is a new format so create a new TFormatCollectionItem, copy the
-    // FormatEtc parameter into the new object and and put it in the list.
-    SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1);
-    FormatEtcArray[High(FormatEtcArray)] := FormatEtc;
-
-    // Create a new InternalStgMedium and initialize it and associate it with the format.
-    SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1);
-    InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat;
-    LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium;
-    FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-  end;
-
-  if DoRelease then
-  begin
-    // We are simply being given the data and we take control of it.
-    LocalStgMedium^ := Medium;
-    Result := S_OK
-  end
-  else
-  begin
-    // We need to reference count or copy the data and keep our own references to it.
-    Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject);
-
-    // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium.
-    // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that
-    // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN.
-    if Assigned(LocalStgMedium.PunkForRelease) then
-    begin
-      if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then
-        IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface
-    end;
-  end;
-
-  // Tell all registered advice sinks about the data change.
-  if Assigned(FAdviseHolder) then
-    FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0);
-  }
-end;
-
-
-//----------------- TVTDragManager -------------------------------------------------------------------------------------
-
-constructor TVTDragManager.Create(AOwner: TObject);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-  FOwner := AOwner;
-
-  // Create an instance  of the drop target helper interface. This will fail but not harm on systems which do
-  // not support this interface (everything below Windows 2000);
-  CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDragManager.Destroy;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // Set the owner's reference to us to nil otherwise it will access an invalid pointer
-  // after our desctruction is complete.
-  TVirtualTreeAccess(FOwner).FreeDragManager;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDataObject: IDataObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem.
-  // In this case there is no local reference to a data object and one is created (but not stored).
-  // If there is a local reference then the owner tree is currently the drop target and the stored interface is
-  // that of the drag initiator.
-  if Assigned(FDataObject) then
-    Result := FDataObject
-  else
-  begin
-    Result := TVirtualTreeAccess(FOwner).DoCreateDataObject;
-    if Result = nil then
-      Result := TVTDataObject.Create(FOwner, False) as IDataObject;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDragSource: TObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := FDragSource;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDropTargetHelperSupported: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := Assigned(FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetIsDropTarget: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := FIsDropTarget;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  FDataObject := DataObject;
-  FIsDropTarget := True;
-
-  SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0);
-  // If full dragging of window contents is disabled in the system then our tree windows will be locked
-  // and cannot be updated during a drag operation. With the following call painting is again enabled.
-  if not FFullDragging then
-    LockWindowUpdate(0);
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect);
-
-  FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject);
-  Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragLeave: HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-
-  TVirtualTreeAccess(FOwner).DragLeave;
-  FIsDropTarget := False;
-  FDragSource := nil;
-  FDataObject := nil;
-  Result := NOERROR;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragOver(Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.Drop(DataObject, Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect);
-  FIsDropTarget := False;
-  FDataObject := nil;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragManager.ForceDragLeave;
-
-// Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive
-// a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from
-// screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE).
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-    }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GiveFeedback(Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := DRAGDROP_S_USEDEFAULTCURSORS;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult;
-
-var
-  RButton,
-  LButton: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  LButton := (KeyState and MK_LBUTTON) <> 0;
-  RButton := (KeyState and MK_RBUTTON) <> 0;
-
-  // Drag'n drop canceled by pressing both mouse buttons or Esc?
-  if (LButton and RButton) or EscapePressed then
-    Result := DRAGDROP_S_CANCEL
-  else
-    // Drag'n drop finished?
-    if not (LButton or RButton) then
-      Result := DRAGDROP_S_DROP
-    else
-      Result := S_OK;
-  }
-end;
-
-
-end.
-

+ 0 - 58
components/virtualtreeview/units/gtk2/virtualpanningwindow.pas

@@ -1,58 +0,0 @@
-unit virtualpanningwindow;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  LCLType, Graphics, Classes, SysUtils;
-  
-type
-
-  { TVirtualPanningWindow }
-
-  TVirtualPanningWindow = class
-  private
-    FHandle: THandle;
-    FOwnerHandle: THandle;
-    FImage: TBitmap;
-    procedure HandlePaintMessage;
-  public
-    procedure Start(OwnerHandle: THandle; const Position: TPoint);
-    procedure Stop;
-    procedure Show(ClipRegion: HRGN);
-    property Image: TBitmap read FImage;
-    property Handle: THandle read FHandle;
-  end;
-
-implementation
-
-{$ifdef DEBUG_VTV}
-uses
-  vtlogger;
-{$endif}
-
-{ TVirtualPanningWindow }
-
-procedure TVirtualPanningWindow.HandlePaintMessage;
-begin
-end;
-
-procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint);
-begin  
-  FImage := TBitmap.Create;
-end;
-
-procedure TVirtualPanningWindow.Stop;
-begin
-  FImage.Free;
-  FImage := nil;
-end;
-
-procedure TVirtualPanningWindow.Show(ClipRegion: HRGN);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif}
-end;
-
-end.
-

+ 0 - 3
components/virtualtreeview/units/qt/fakeactivex.pas

@@ -1,3 +0,0 @@
-unit FakeActiveX;
-
-{$i ../dummyactivex.inc}

+ 0 - 37
components/virtualtreeview/units/qt/fakemmsystem.pas

@@ -1,37 +0,0 @@
-unit fakemmsystem;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  Classes, SysUtils, Types;
-  
-function timeBeginPeriod(x1: DWord): DWord;
-
-function timeEndPeriod(x1: DWord): DWord;
-
-function timeGetTime: DWORD;
-
-implementation
-
-uses
-  LCLIntf;
-
-function timeBeginPeriod(x1: DWord): DWord;
-begin
-
-end;
-
-function timeEndPeriod(x1: DWord): DWord;
-begin
-
-end;
-
-function timeGetTime: DWORD;
-begin
-  Result := GetTickCount;
-end;
-
-end.
-

+ 0 - 1623
components/virtualtreeview/units/qt/virtualdragmanager.pas

@@ -1,1623 +0,0 @@
-unit virtualdragmanager;
-{fake unit just to compile - not used under non windows}
-
-{$mode delphi}
-
-interface
-
-uses
-  Classes, SysUtils, Types;
-
-const
-  // Drag image helpers for Windows 2000 and up.
-  IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
-  CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-
-  SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}';
-  SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}';
-  SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}';
-  
-  //Bridge to ActiveX constants
-  
-  TYMED_HGLOBAL = 1;
-  TYMED_ISTREAM = 4;
-  DVASPECT_CONTENT = 1;
-  CLSCTX_INPROC_SERVER = $0010;
-  DROPEFFECT_COPY = 1;
-  DROPEFFECT_LINK = 4;
-  DROPEFFECT_MOVE = 2;
-  DROPEFFECT_NONE = 0;
-  DROPEFFECT_SCROLL = dword($80000000);
-  DATADIR_GET = 1;
-  
-type
-  //types from win unit
-  Long = LongInt;
-  WinBool= LongBool;
-  Bool= WinBool;
-  ULONG  = cardinal;
-  LONGLONG  = int64;
-  LPDWORD = ^DWORD;
-  LPVOID  = pointer;
-       
-  TCOLORREF = cardinal;
-       
-  TIID = TGUID;
-  
-  LARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : LONG);
-    1: (QuadPart : LONGLONG);
-  end;
-  PLARGE_INTEGER = ^LARGE_INTEGER;
-  _LARGE_INTEGER = LARGE_INTEGER;
-
-  TLargeInteger = Int64;
-  PLargeInteger = ^TLargeInteger;
-
-  ULARGE_INTEGER = record
-  case byte of
-    0: (LowPart : DWORD;
-        HighPart : DWORD);
-    1: (QuadPart : LONGLONG);
-  end;
-  PULARGE_INTEGER = ^ULARGE_INTEGER;
-  _ULARGE_INTEGER = ULARGE_INTEGER;
-     
-  
-  HANDLE = System.THandle;
-  HWND = HANDLE;
-  //HRESULT = System.HResult;
-  
-  HBITMAP = HANDLE;
-  HENHMETAFILE = HANDLE;
-  
-  //activex types
-  
-
-  IMoniker            = Interface;
-   
-  WINOLEAPI = HResult;
-  TLCID = DWORD;
-  
-  OleChar             = WChar;
-  LPOLESTR            = ^OLECHAR;
-  HMetaFilePict       = Pointer;
-  
-  
-  tagBIND_OPTS                 = Record
-                                  cvStruct,          //  sizeof(BIND_OPTS)
-                                  grfFlags,
-                                  grfMode,
-                                  dwTickCountDeadline : DWord;
-                                 End;
-  TBind_Opts                   = tagBIND_OPTS;
-  TCLIPFORMAT                  = Word;
-
-  tagDVTARGETDEVICE            = Record
-                                    tdSize                     : DWord;
-                                    tdDriverNameOffset,
-                                    tdDeviceNameOffset,
-                                    tdPortNameOffset,
-                                    tdExtDevmodeOffset         : Word;
-                                    Data                       : Record End;
-                                    End;
-  DVTARGETDEVICE               = TagDVTARGETDEVICE;
-  PDVTARGETDEVICE              = ^tagDVTARGETDEVICE;
-
-
-
-  tagFORMATETC                 = Record
-                                  CfFormat :  Word {TCLIPFORMAT};
-                                  Ptd      : PDVTARGETDEVICE;
-                                  dwAspect : DWORD;
-                                  lindex   : Long;
-                                  tymed    : DWORD;
-                                  End;
-  FORMATETC                    = TagFORMATETC;
-  TFORMATETC                   = FORMATETC;
-  LPFORMATETC                  = ^FORMATETC;
-  PFormatEtc                   = LPFORMATETC;
-
-  tagSTATDATA                  = Record
-                                                                // field used by:
-                                    FORMATETC   : Tformatetc;   // EnumAdvise, EnumData (cache), EnumFormats
-                                    advf        : DWord;        // EnumAdvise, EnumData (cache)
-                                    padvSink    : Pointer {IAdviseSink};  // EnumAdvise
-                                    dwConnection: DWord;        // EnumAdvise
-                                 End;
-  STATDATA                     = TagStatData;
-
-
-  TagSTGMEDIUM                 = Record
-                                    Tymed : DWord;
-                                    Case Integer Of
-                                      0 : (HBITMAP             : hBitmap;       PUnkForRelease :  Pointer {IUnknown});
-                                      1 : (HMETAFILEPICT       : hMetaFilePict );
-                                      2 : (HENHMETAFILE        : hEnhMetaFile  );
-                                      3 : (HGLOBAL             : hGlobal       );
-                                      4 : (lpszFileName        : LPOLESTR    );
-                                      5 : (pstm                : Pointer{IStream}  );
-                                      6 : (pstg                : Pointer{IStorage} );
-                                      End;
-  USTGMEDIUM                   = TagSTGMEDIUM;
-  STGMEDIUM                    = USTGMEDIUM;
-  TStgMedium                                                                           = TagSTGMEDIUM;
-  PStgMedium                   = ^TStgMedium;
-  LPSTGMEDIUM                  = ^STGMEDIUM;
-
-  IEnumString = Interface (IUnknown)
-       ['{00000101-0000-0000-C000-000000000046}']
-       Function Next(Celt:ULong;Out xcelt;Out Celtfetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out celt;Out Celtfetched:ULong):HResult; StdCall;
-       Function Skip (Celt:ULong):Hresult;StdCall;
-       Function Reset:HResult;StdCall;
-       Function Clone(Out penum:IEnumString):HResult;StdCall;
-       End;
-       
-
-    IEnumMoniker = Interface (IUnknown)
-       ['{00000102-0000-0000-C000-000000000046}']
-       Function Next(celt:ULong; out Elt;out celftfetched: ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong; Out rgelt;out celtfetched :ULong):Hresult; StdCall;
-       Function Skip(celt:Ulong):HResult; StdCall;
-       Function Reset:HResult; StdCall;
-       Function Close(out penum:IEnumMoniker):HResult;StdCall;
-       End;
-
-   IEnumSTATDATA = Interface (IUnknown)
-    ['{00000105-0000-0000-C000-000000000046}']
-    Function Next(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-//      Function RemoteNext(Celt:ULong;Out Rgelt:statdata;Out pceltFetched:ULong):HResult; StdCall;
-    Function Skip(Celt:ULong):HResult;StdCall;
-    Function Reset:HResult;StdCall;
-    Function Clone(out penum:IEnumstatdata):HResult;StdCall;
-    End;
-
-   IEnumFORMATETC = Interface (IUnknown)
-   ['{00000103-0000-0000-C000-000000000046}']
-   Function Next(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-//     Function RemoteNext(Celt:ULong;Out Rgelt:FormatEtc;Out pceltFetched:ULong):HResult; StdCall;
-   Function Skip(Celt:ULong):HResult;StdCall;
-   Function Reset:HResult;StdCall;
-   Function Clone(out penum:IEnumFORMATETC):HResult;StdCall;
-   End;
-   
-
-   
-    IPersist = Interface (IUnknown)
-       ['{0000010c-0000-0000-C000-000000000046}']
-       Function GetClassId(clsid:TClsId):HResult; StdCall;
-       End;
-
-    IPersistStream = Interface(IPersist)
-       ['{00000109-0000-0000-C000-000000000046}']
-       Function IsDirty:HResult; StdCall;
-       Function Load(Const stm: IStream):HResult; StdCall;
-       Function Save(Const stm: IStream;fClearDirty:Bool):HResult;StdCall;
-       Function GetSizeMax(Out cbSize:ULarge_Integer):HResult; StdCall;
-       End;
-   
-   
-    IRunningObjectTable = Interface (IUnknown)
-       ['{00000010-0000-0000-C000-000000000046}']
-       Function Register  (grfFlags :DWord;const unkobject:IUnknown;Const mkObjectName:IMoniker;Out dwregister:DWord):HResult;StdCall;
-       Function Revoke    (dwRegister:DWord):HResult; StdCall;
-       Function IsRunning (Const mkObjectName: IMoniker):HResult;StdCall;
-       Function GetObject (Const mkObjectName: IMoniker; Out punkObject:IUnknown):HResult; StdCall;
-       Function NoteChangeTime(dwRegister :DWord;Const FileTime: TFileTime):HResult;StdCall;
-       Function GetTimeOfLastChange(Const mkObjectName:IMoniker;Out filetime:TFileTime):HResult; StdCall;
-       Function EnumRunning (Out enumMoniker: IEnumMoniker):HResult; StdCall;
-       End;
-
-   
-    IBindCtx = Interface (IUnknown)
-       ['{0000000e-0000-0000-C000-000000000046}']
-       Function RegisterObjectBound(Const punk:IUnknown):HResult; stdCall;
-       Function RevokeObjectBound (Const Punk:IUnknown):HResult;  stdCall;
-       Function ReleaseBoundObjects :HResult;  StdCall;
-       Function SetBindOptions(Const bindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteSetBindOptions(Const bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetBindOptions(var BindOpts:TBind_Opts):HResult;  stdCall;
-//       Function RemoteGetBindOptions(Var bind_opts: TBind_Opts2):HResult;StdCall;
-       Function GetRunningObjectTable(Out rot : IRunningObjectTable):Hresult; StdCall;
-       Function RegisterObjectParam(Const pszkey:LPOleStr;const punk:IUnknown):HResult;
-       Function GetObjectParam(Const pszkey:LPOleStr; out punk: IUnknown):HResult; StdCall;
-       Function EnumObjectParam (out enum:IEnumString):Hresult;StdCall;
-       Function RevokeObjectParam(pszKey:LPOleStr):HResult;StdCall;
-       End;
-
-   
-    PIMoniker = ^IMoniker;
-    IMoniker = Interface (IPersistStream)
-      ['{0000000f-0000-0000-C000-000000000046}']
-      Function BindToObject (const pbc:IBindCtx;const mktoleft:IMoniker; RiidResult:TIID;Out vresult):HResult;StdCall;
-//    Function RemoteBindToObject (const pbc:IBindCtx;const mktoleft:IMoniker;RiidResult:TIID;Out vresult):HResult;StdCall;
-      Function BindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-//    Function RemoteBindToStorage(Const Pbc:IBindCtx;Const mktoLeft:IMoniker; Riid:TIID;Out vobj):HResult; StdCall;
-      Function Reduce (const pbc:IBindCtx; dwReduceHowFar:DWord; mktoLeft: PIMoniker; Out mkReduced:IMoniker):HResult; StdCall;
-      Function ComposeWith(Const MkRight:IMoniker;fOnlyIfNotGeneric:BOOL; OUT mkComposite:IMoniker):HResult; StdCall;
-      Function Enum(fForward:Bool;Out enumMoniker:IEnumMoniker):HResult;StdCall;
-      Function IsEqual(Const mkOtherMoniker:IMoniker):HResult;StdCall;
-      Function Hash   (Out dwHash:Dword):HResult;StdCall;
-      Function IsRunning(Const bc:IBindCtx;Const MkToLeft:IMoniker;Const mknewlyRunning:IMoniker):HResult;StdCall;
-      Function GetTimeOfLastChange(Const bc:IBindCtx;Const mkToLeft:IMoniker; out ft : FileTime):HResult; StdCall;
-      Function Inverse(out mk : IMoniker):HResult; StdCall;
-      Function CommonPrefixWith (Const mkOther:IMoniker):HResult; StdCall;
-      Function RelativePathTo(Const mkother:IMoniker; Out mkRelPath : IMoniker):HResult;StdCall;
-      Function GetDisplayName(Const bc:IMoniker;const mktoleft:IMoniker;Out szDisplayName: pOleStr):HResult; StdCall;
-      Function ParseDisplayName(Const bc:IBindCtx;Const mkToLeft:IMoniker;szDisplayName:POleStr;out cheaten:ULong;out mkOut:IMoniker):HResult; StdCall;
-      Function IsSystemMonitor(Out dwMkSys:DWord):HResult;StdCall;
-      End;
-
-
-    IAdviseSink = Interface (IUnknown)
-        ['{0000010f-0000-0000-C000-000000000046}']
-    {$ifdef midl500} ['{00000150-0000-0000-C000-000000000046}'] {$endif}
-        Procedure OnDataChange (Const pformatetc : Formatetc;const pstgmed : STGMEDIUM); StdCall;
-        Procedure OnViewChange (dwAspect : DWord; lindex : Long); StdCall;
-        Procedure OnRename (Const pmk : IMoniker); StdCall;
-        Procedure OnSave; StdCall;
-        Procedure OnClose; StdCall;
-     End;
-
-
-  //Fake interfaces
-  IDataObject = Interface (IUnknown)
-   ['{0000010e-0000-0000-C000-000000000046}']
-   Function GetData(Const formatetcIn : FORMATETC;Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function GetDataHere(CONST pformatetc : FormatETC; Out medium : STGMEDIUM):HRESULT; STDCALL;
-   Function QueryGetData(const pformatetc : FORMATETC):HRESULT; STDCALL;
-   Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult; STDCALl;
-   Function SetData (Const pformatetc : FORMATETC;const medium:STGMEDIUM;FRelease : BOOL):HRESULT; StdCall;
-   Function EnumFormatEtc(dwDirection : DWord; OUT enumformatetcpara : IENUMFORMATETC):HRESULT; StdCall;
-   Function DAdvise(const formatetc : FORMATETC;advf :DWORD; CONST AdvSink : IAdviseSink;OUT dwConnection:DWORD):HRESULT;StdCall;
-   Function DUnadvise(dwconnection :DWord) :HRESULT;StdCall;
-   Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;StdCall;
-   End;
-
- IDropTarget = interface(IUnknown)
-    ['{00000122-0000-0000-C000-000000000046}']
-    function DragEnter(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragOver(grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD): HResult;StdCall;
-    function DragLeave: HResult;StdCall;
-    function Drop(const dataObj: IDataObject; grfKeyState: DWORD; pt: TPoint; var dwEffect: DWORD):HResult;StdCall;
-  end;
-
-
-  IDropSource = interface(IUnknown)
-    ['{00000121-0000-0000-C000-000000000046}']
-    function QueryContinueDrag(fEscapePressed: BOOL;
-      grfKeyState: LongWord):HResult;StdCall;
-    function GiveFeedback(dwEffect: LongWord): HResult;StdCall;
-  end;
-  
-  
-  IDataAdviseHolder = Interface (IUnknown)
-       ['{00000110-0000-0000-C000-000000000046}']
-       Function Advise    (CONST pdataObject : IDataObject;CONST fetc:FORMATETC;advf : DWORD;Const pAdvise:IAdviseSink;Out DwConnection:DWord):HResult; StdCall;
-       Function Unadvise  (dwConnection:Dword):HResult; StdCall;
-       Function EnumAdvise(out penumAdvise : IEnumStatData):HResult;StdCall;
-       Function SendOnDataChange(const pDataObject :IDataObject;DwReserved,advf : DWord):HResult; StdCall;
-       End;
-
-  
-
-  // OLE drag'n drop support
-  TFormatEtcArray = array of TFormatEtc;
-  TFormatArray = array of Word;
-
-  // IDataObject.SetData support
-  TInternalStgMedium = packed record
-    Format: TClipFormat;
-    Medium: TStgMedium;
-  end;
-  TInternalStgMediumArray = array of TInternalStgMedium;
-
-  TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc)
-  private
-    FTree: TObject;
-    FFormatEtcArray: TFormatEtcArray;
-    FCurrentIndex: Integer;
-  public
-    constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-    function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
-    function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall;
-    function Reset: HResult; stdcall;
-    function Skip(celt: LongWord): HResult; stdcall;
-  end;
-
-  IDropTargetHelper = interface(IUnknown)
-    [SID_IDropTargetHelper]
-    function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function DragLeave: HRESULT; stdcall;
-    function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Show(fShow: Boolean): HRESULT; stdcall;
-  end;
-
-  PSHDragImage = ^TSHDragImage;
-  TSHDragImage = packed record
-    sizeDragImage: TSize;
-    ptOffset: TPoint;
-    hbmpDragImage: HBITMAP;
-    ColorRef: TColorRef;
-  end;
-
-  IDragSourceHelper = interface(IUnknown)
-    [SID_IDragSourceHelper]
-    function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall;
-    function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall;
-  end;
-
-
-
-  IVTDragManager = interface(IUnknown)
-    ['{C4B25559-14DA-446B-8901-0C879000EB16}']
-    procedure ForceDragLeave; stdcall;
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-
-    property DataObject: IDataObject read GetDataObject;
-    property DragSource: TObject read GetDragSource;
-    property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported;
-    property IsDropTarget: Boolean read GetIsDropTarget;
-  end;
-
-  // This data object is used in two different places. One is for clipboard operations and the other while dragging.
-  TVTDataObject = class(TInterfacedObject, IDataObject)
-  private
-    //FOwner: TBaseVirtualTree;          // The tree which provides clipboard or drag data.
-    FOwner: TObject;          // The tree which provides clipboard or drag data.
-    FForClipboard: Boolean;            // Determines which data to render with GetData.
-    FFormatEtcArray: TFormatEtcArray;
-    FInternalStgMediumArray: TInternalStgMediumArray;  // The available formats in the DataObject
-    FAdviseHolder: IDataAdviseHolder;  // Reference to an OLE supplied implementation for advising.
-  protected
-    function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-    function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-    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;
-    function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-      CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-    property ForClipboard: Boolean read FForClipboard;
-    property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray;
-    property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray;
-    property Owner: TObject read FOwner;
-  public
-    constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual;
-    destructor Destroy; override;
-
-    function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord):
-      HResult; virtual; stdcall;
-    function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall;
-    Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall;
-    function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall;
-    Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):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;
-    function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall;
-    function SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall;
-  end;
-
-  // TVTDragManager is a class to manage drag and drop in a Virtual Treeview.
-  TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget)
-  private
-    FOwner,                            // The tree which is responsible for drag management.
-    FDragSource: TObject;     // Reference to the source tree if the source was a VT, might be different than
-                                       // the owner tree.
-    FIsDropTarget: Boolean;            // True if the owner is currently the drop target.
-    FDataObject: IDataObject;          // A reference to the data object passed in by DragEnter (only used when the owner
-                                       // tree is the current drop target).
-    FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support
-    FFullDragging: BOOL;               // True, if full dragging is currently enabled in the system.
-
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-  public
-    constructor Create(AOwner: TObject); virtual;
-    destructor Destroy; override;
-
-    function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-      var Effect: LongWord): HResult; stdcall;
-    function DragLeave: HResult; stdcall;
-    function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    procedure ForceDragLeave; stdcall;
-    function GiveFeedback(Effect: LongWord): HResult; stdcall;
-    function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall;
-  end;
-  
-  //Ole helper functions
-
-  function Succeeded(Status : HRESULT) : BOOLEAN;
-
-  function Failed(Status : HRESULT) : BOOLEAN;
-  
-  //ActiveX functions that have wrong calling convention in fpc
-  
-  function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;
-
-  function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;
-
-  function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;
-
-  function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;
-
-  procedure OleUninitialize;stdcall;
-
-  procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;
-
-  function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function OleFlushClipboard:WINOLEAPI;stdcall;
-
-  function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;
-
-  function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;
-  
-  function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall;
-
-  //helper functions to isolate windows/OLE specific code
-  
-  function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-    ForClipboard: Boolean): HResult;
-    
-  function GetStreamFromMedium(Medium:TStgMedium):TStream;
-  
-  procedure UnlockMediumData(Medium:TStgMedium);
-  
-  function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject;
-  
-  function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL;
-
-implementation
-
-uses
-  VirtualTrees, Controls {$ifdef DEBUG_VTV}, vtlogger {$endif};
-  
-type
-  TVirtualTreeAccess = class (TBaseVirtualTree)
-  end;
-
-function Succeeded(Status : HRESULT) : BOOLEAN;
-  begin
-     Succeeded:=Status and HRESULT($80000000)=0;
-  end;
-
-function Failed(Status : HRESULT) : BOOLEAN;
-  begin
-     Failed:=Status and HRESULT($80000000)<>0;
-  end;
-
-function RegisterDragDrop(hwnd: HWND; pDropTarget: IDropTarget): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function RevokeDragDrop(hwnd: HWND): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource;
-  dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleInitialize(pvReserved: LPVOID): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-procedure OleUninitialize;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-procedure ReleaseStgMedium(_para1: LPSTGMEDIUM);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleSetClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleGetClipboard(out ppDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleFlushClipboard: WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function OleIsCurrentClipboard(pDataObj: IDataObject): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function CreateStreamOnHGlobal(hGlobal: HGLOBAL; fDeleteOnRelease: BOOL; out
-  stm: IStream): WINOLEAPI;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-function CoCreateInstance(const _para1: TCLSID; _para2: IUnknown;
-  _para3: DWORD; const _para4: TIID; out _para5): HRESULT;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-end;
-
-
-function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out
-  Medium: TStgMedium; ForClipboard: Boolean): HResult;
-{
-  //--------------- local function --------------------------------------------
-
-  procedure WriteNodes(Stream: TStream);
-
-  var
-    Selection: TNodeArray;
-    I: Integer;
-
-  begin
-    with TVirtualTreeAccess(Tree) do
-    begin
-      if ForClipboard then
-        Selection := GetSortedCutCopySet(True)
-      else
-        Selection := GetSortedSelection(True);
-      for I := 0 to High(Selection) do
-        WriteNode(Stream, Selection[I]);
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-}
-var
-  Data: PCardinal;
-  ResPointer: Pointer;
-  ResSize: Integer;
-  OLEStream: IStream;
-  VCLStream: TStream;
-  
-begin
- {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  VCLStream := nil;
-  try
-    Medium.PunkForRelease := 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.Pstm) := 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;
-
-
-type
-  // needed to handle OLE global memory objects
-  TOLEMemoryStream = class(TCustomMemoryStream)
-  public
-    function Write(const Buffer; Count: Integer): Longint; override;
-  end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-   // raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError));
-end;
-
-
-function GetStreamFromMedium(Medium: TStgMedium): TStream;
-
-var
-  Data: Pointer;
-  I: Integer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-{
-  Result := nil;
-  if Medium.tymed = TYMED_ISTREAM then
-    Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream)
-  else
-  begin
-    Data := GlobalLock(Medium.hGlobal);
-    if Assigned(Data) then
-    begin
-      // Get the total size of data to retrieve.
-      I := PCardinal(Data)^;
-      Inc(PCardinal(Data));
-      Result := TOLEMemoryStream.Create;
-      TOLEMemoryStream(Result).SetPointer(Data, I);
-    end;
-  end;
-}
-end;
-
-procedure UnlockMediumData(Medium: TStgMedium);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-{
-  if Medium.tymed = TYMED_HGLOBAL then
-    GlobalUnlock(Medium.hGlobal);
- }
-end;
-
-function GetTreeFromDataObject(const DataObject: IDataObject;
-  var Format: TFormatEtc): TObject;
-  
-var
-  Medium: TStgMedium;
-  Data: PVTReference;
-  
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := nil;
-  if Assigned(DataObject) then
-  begin
-    Format.cfFormat := CF_VTREFERENCE;
-    if DataObject.GetData(Format, 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 AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL;
-var
-  P:Pointer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize);
-  P := GlobalLock(Result);
-  Move(Data^, P^, DataSize);
-  GlobalUnlock(Result);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// OLE drag and drop support classes
-// This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs
-// of DD'ing various kinds of virtual data and works also between applications.
-
-//----------------- TEnumFormatEtc -------------------------------------------------------------------------------------
-
-constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-
-var
-  I: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-
-  FTree := Tree;
-  // Make a local copy of the format data.
-  SetLength(FFormatEtcArray, Length(AFormatEtcArray));
-  for I := 0 to High(AFormatEtcArray) do
-    FFormatEtcArray[I] := AFormatEtcArray[I];
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
-
-var
-  AClone: TEnumFormatEtc;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-   Result := S_OK;
-  try
-    AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray);
-    AClone.FCurrentIndex := FCurrentIndex;
-    Enum := AClone as IEnumFormatEtc;
-  except
-    Result := E_FAIL;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult;
-
-var
-  CopyCount: LongWord;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-   Result := S_FALSE;
-  CopyCount := Length(FFormatEtcArray) - FCurrentIndex;
-  if celt < CopyCount then
-    CopyCount := celt;
-  if CopyCount > 0 then
-  begin
-    Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc));
-    Inc(FCurrentIndex, CopyCount);
-    Result := S_OK;
-  end;
-  //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with
-  // a C Program call with a NULL in pCeltFetcjed??
-  //Answer: Yes. Is necessary a check here
-  if @pceltFetched <> nil then
-    pceltFetched := CopyCount;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Reset: HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  FCurrentIndex := 0;
-  Result := S_OK;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Skip(celt: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FCurrentIndex + celt < High(FFormatEtcArray) then
-  begin
-    Inc(FCurrentIndex, celt);
-    Result := S_Ok;
-  end
-  else
-    Result := S_FALSE;
-  }
-end;
-
-
-//----------------- TVTDataObject --------------------------------------------------------------------------------------
-
-constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-
-  FOwner := AOwner;
-  FForClipboard := ForClipboard;
-  TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDataObject.Destroy;
-
-var
-  I: Integer;
-  StgMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // Cancel a pending clipboard operation if this data object was created for the clipboard and
-  // is freed because something else is placed there.
-  if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then
-    TVirtualTreeAccess(FOwner).CancelCutOrCopy;
-
-  // Release any internal clipboard formats
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat);
-    if Assigned(StgMedium) then
-      ReleaseStgMedium(StgMedium);
-  end;
-
-  FormatEtcArray := nil;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-
-// Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown
-// interface, will always return the same pointer.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(TestUnknown) then
-  begin
-    if TestUnknown.QueryInterface(IUnknown, Result) = 0 then
-      Result._Release // Don't actually need it just need the pointer value
-    else
-      Result := TestUnknown
-  end
-  else
-    Result := TestUnknown
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and
-    (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and
-    (FormatEtc1.tymed and FormatEtc2.tymed <> 0);
-    
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer;
-
-var
-  I: integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := -1;
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then
-    begin
-      Result := I;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium;
-
-var
-  I: integer;
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := nil;
-  for I := 0 to High(InternalStgMediumArray) do
-  begin
-    if Format = InternalStgMediumArray[I].Format then
-    begin
-      Result := @InternalStgMediumArray[I].Medium;
-      Break;
-    end
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle;
-
-// Returns a global memory block that is a copy of the passed memory block.
-
-var
-  Size: Cardinal;
-  Data,
-  NewData: PChar;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Size := GlobalSize(HGlobal);
-  Result := GlobalAlloc(GPTR, Size);
-  Data := GlobalLock(hGlobal);
-  try
-    NewData := GlobalLock(Result);
-    try
-      Move(Data^, NewData^, Size);
-    finally
-      GlobalUnLock(Result);
-    end
-  finally
-    GlobalUnLock(hGlobal);
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium;
-  var OLEResult: HResult): Boolean;
-
-// Tries to render one of the formats which have been stored via the SetData method.
-// Since this data is already there it is just copied or its reference count is increased (depending on storage medium).
-
-var
-  InternalMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  
-  Result := True;
-  InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat);
-  if Assigned(InternalMedium) then
-    OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject)
-  else
-    Result := False;
-   }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-  CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-// InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or
-// increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually
-// the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData.
-// If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during
-// that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make
-// copy of the data for the caller only to have them destroy it then need us to copy it again if necessary.
-// This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData.
-// 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;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := S_OK;
-
-  // Simply copy all fields to start with.
-  OutStgMedium := InStgMedium;
-  // The data handled here always results from a call of SetData we got. This ensures only one storage format
-  // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several
-  // storage formats).
-  case InStgMedium.tymed of
-    TYMED_HGLOBAL:
-      begin
-        if CopyInMedium then
-        begin
-          // Generate a unique copy of the data passed
-          OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal);
-          if OutStgMedium.hGlobal = 0 then
-            Result := E_OUTOFMEMORY
-        end
-        else
-          // Don't generate a copy just use ourselves and the copy previously saved.
-          OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount.
-      end;
-    TYMED_FILE:
-      begin
-        //todo_lcl_check
-        Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character.
-        OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len);
-        Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len);
-      end;
-    TYMED_ISTREAM:
-      IUnknown(OutStgMedium.Pstm)._AddRef;
-    TYMED_ISTORAGE:
-      IUnknown(OutStgMedium.Pstg)._AddRef;
-    TYMED_GDI:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy GDI objects right now.
-    TYMED_MFPICT:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now.
-    TYMED_ENHMF:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now.
-  else
-    Result := DV_E_TYMED;
-  end;
-
-  if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then
-    IUnknown(OutStgMedium.PunkForRelease)._AddRef;
-    }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink;
-  out dwConnection: DWord): HResult;
-
-// Advise sink management is greatly simplified by the IDataAdviseHolder interface.
-// We use this interface and forward all concerning calls to it.
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := S_OK;
-  if FAdviseHolder = nil then
-    Result := CreateDataAdviseHolder(FAdviseHolder);
-  if Result = S_OK then
-    Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DUnadvise(dwConnection: DWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FAdviseHolder = nil then
-    Result := E_NOTIMPL
-  else
-    Result := FAdviseHolder.Unadvise(dwConnection);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if FAdviseHolder = nil then
-    Result := OLE_E_ADVISENOTSUPPORTED
-  else
-    Result := FAdviseHolder.EnumAdvise(enumAdvise);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult;
-
-var
-  NewList: TEnumFormatEtc;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := E_FAIL;
-  if Direction = DATADIR_GET then
-  begin
-    NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray);
-    EnumFormatEtc := NewList as IEnumFormatEtc;
-    Result := S_OK;
-  end
-  else
-    EnumFormatEtc := nil;
-  if EnumFormatEtc = nil then
-    Result := OLE_S_USEREG;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := DATA_S_SAMEFORMATETC;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult;
-
-// Data is requested by clipboard or drop target. This method dispatchs the call
-// depending on the data being requested.
-
-var
-  I: Integer;
-  Data: PVTReference;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  // The tree reference format is always supported and returned from here.
-  {
-  if FormatEtcIn.cfFormat = CF_VTREFERENCE then
-  begin
-    // Note: this format is not used while flushing the clipboard to avoid a dangling reference
-    //       when the owner tree is destroyed before the clipboard data is replaced with something else.
-    if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then
-      Result := E_FAIL
-    else
-    begin
-      Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference));
-      Data := GlobalLock(Medium.hGlobal);
-      Data.Process := GetCurrentProcessID;
-      Data.Tree := TBaseVirtualTree(FOwner);
-      GlobalUnlock(Medium.hGlobal);
-      Medium.tymed := TYMED_HGLOBAL;
-      Medium.PunkForRelease := nil;
-      Result := S_OK;
-    end;
-  end
-  else
-  begin
-    try
-      // See if we accept this type and if not get the correct return value.
-      Result := QueryGetData(FormatEtcIn);
-      if Result = S_OK then
-      begin
-        for I := 0 to High(FormatEtcArray) do
-        begin
-          if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
-          begin
-            if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
-              Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard);
-            Break;
-          end;
-        end
-      end
-    except
-      FillChar(Medium, SizeOf(Medium), #0);
-      Result := E_FAIL;
-    end;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult;
-
-var
-  I: Integer;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  Result := DV_E_CLIPFORMAT;
-  for I := 0 to High(FFormatEtcArray) do
-  begin
-    if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then
-    begin
-      if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then
-      begin
-        if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then
-        begin
-          if FormatEtc.lindex = FFormatEtcArray[I].lindex then
-          begin
-            Result := S_OK;
-            Break;
-          end
-          else
-            Result := DV_E_LINDEX;
-        end
-        else
-          Result := DV_E_DVASPECT;
-      end
-      else
-        Result := DV_E_TYMED;
-    end;
-  end
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult;
-
-// 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;
-  LocalStgMedium: PStgMedium;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // See if we already have a format of that type available.
-  Index := FindFormatEtc(FormatEtc, FormatEtcArray);
-  if Index > - 1 then
-  begin
-    // Just use the TFormatEct in the array after releasing the data.
-    LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat);
-    if Assigned(LocalStgMedium) then
-    begin
-      ReleaseStgMedium(LocalStgMedium);
-      FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-    end;
-  end
-  else
-  begin
-    // It is a new format so create a new TFormatCollectionItem, copy the
-    // FormatEtc parameter into the new object and and put it in the list.
-    SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1);
-    FormatEtcArray[High(FormatEtcArray)] := FormatEtc;
-
-    // Create a new InternalStgMedium and initialize it and associate it with the format.
-    SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1);
-    InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat;
-    LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium;
-    FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-  end;
-
-  if DoRelease then
-  begin
-    // We are simply being given the data and we take control of it.
-    LocalStgMedium^ := Medium;
-    Result := S_OK
-  end
-  else
-  begin
-    // We need to reference count or copy the data and keep our own references to it.
-    Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject);
-
-    // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium.
-    // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that
-    // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN.
-    if Assigned(LocalStgMedium.PunkForRelease) then
-    begin
-      if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then
-        IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface
-    end;
-  end;
-
-  // Tell all registered advice sinks about the data change.
-  if Assigned(FAdviseHolder) then
-    FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0);
-  }
-end;
-
-
-//----------------- TVTDragManager -------------------------------------------------------------------------------------
-
-constructor TVTDragManager.Create(AOwner: TObject);
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  inherited Create;
-  FOwner := AOwner;
-
-  // Create an instance  of the drop target helper interface. This will fail but not harm on systems which do
-  // not support this interface (everything below Windows 2000);
-  CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDragManager.Destroy;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // Set the owner's reference to us to nil otherwise it will access an invalid pointer
-  // after our desctruction is complete.
-  TVirtualTreeAccess(FOwner).FreeDragManager;
-  inherited;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDataObject: IDataObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem.
-  // In this case there is no local reference to a data object and one is created (but not stored).
-  // If there is a local reference then the owner tree is currently the drop target and the stored interface is
-  // that of the drag initiator.
-  if Assigned(FDataObject) then
-    Result := FDataObject
-  else
-  begin
-    Result := TVirtualTreeAccess(FOwner).DoCreateDataObject;
-    if Result = nil then
-      Result := TVTDataObject.Create(FOwner, False) as IDataObject;
-  end;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDragSource: TObject;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := FDragSource;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDropTargetHelperSupported: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := Assigned(FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetIsDropTarget: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := FIsDropTarget;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  FDataObject := DataObject;
-  FIsDropTarget := True;
-
-  SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0);
-  // If full dragging of window contents is disabled in the system then our tree windows will be locked
-  // and cannot be updated during a drag operation. With the following call painting is again enabled.
-  if not FFullDragging then
-    LockWindowUpdate(0);
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect);
-
-  FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject);
-  Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragLeave: HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-
-  TVirtualTreeAccess(FOwner).DragLeave;
-  FIsDropTarget := False;
-  FDragSource := nil;
-  FDataObject := nil;
-  Result := NOERROR;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragOver(Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect);
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.Drop(DataObject, Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect);
-  FIsDropTarget := False;
-  FDataObject := nil;
-  }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragManager.ForceDragLeave;
-
-// Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive
-// a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from
-// screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE).
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-    }
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GiveFeedback(Effect: LongWord): HResult;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  //Result := DRAGDROP_S_USEDEFAULTCURSORS;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult;
-
-var
-  RButton,
-  LButton: Boolean;
-
-begin
-  {$ifdef DEBUG_VTV}Logger.SendError([lcOle],'Ole function called in Linux');{$endif}
-  {$ifdef DEBUG_VTV}Logger.SendCallStack([lcOle],'Stack');{$endif}
-  {
-  LButton := (KeyState and MK_LBUTTON) <> 0;
-  RButton := (KeyState and MK_RBUTTON) <> 0;
-
-  // Drag'n drop canceled by pressing both mouse buttons or Esc?
-  if (LButton and RButton) or EscapePressed then
-    Result := DRAGDROP_S_CANCEL
-  else
-    // Drag'n drop finished?
-    if not (LButton or RButton) then
-      Result := DRAGDROP_S_DROP
-    else
-      Result := S_OK;
-  }
-end;
-
-
-end.
-

+ 0 - 58
components/virtualtreeview/units/qt/virtualpanningwindow.pas

@@ -1,58 +0,0 @@
-unit virtualpanningwindow;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  LCLType, Graphics, Classes, SysUtils;
-  
-type
-
-  { TVirtualPanningWindow }
-
-  TVirtualPanningWindow = class
-  private
-    FHandle: THandle;
-    FOwnerHandle: THandle;
-    FImage: TBitmap;
-    procedure HandlePaintMessage;
-  public
-    procedure Start(OwnerHandle: THandle; const Position: TPoint);
-    procedure Stop;
-    procedure Show(ClipRegion: HRGN);
-    property Image: TBitmap read FImage;
-    property Handle: THandle read FHandle;
-  end;
-
-implementation
-
-{$ifdef DEBUG_VTV}
-uses
-  vtlogger;
-{$endif}
-
-{ TVirtualPanningWindow }
-
-procedure TVirtualPanningWindow.HandlePaintMessage;
-begin
-end;
-
-procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint);
-begin  
-  FImage := TBitmap.Create;
-end;
-
-procedure TVirtualPanningWindow.Stop;
-begin
-  FImage.Free;
-  FImage := nil;
-end;
-
-procedure TVirtualPanningWindow.Show(ClipRegion: HRGN);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif}
-end;
-
-end.
-

+ 0 - 1134
components/virtualtreeview/units/win32/virtualdragmanager.pas

@@ -1,1134 +0,0 @@
-unit virtualdragmanager;
-
-{$mode delphi}
-
-interface
-
-uses
-  Windows, ActiveX, Classes, SysUtils;
-
-const
-  // Drag image helpers for Windows 2000 and up.
-  IID_IDropTargetHelper: TGUID = (D1: $4657278B; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDragSourceHelper: TGUID = (D1: $DE5BF786; D2: $477A; D3: $11D2; D4: ($83, $9D, $00, $C0, $4F, $D9, $18, $D0));
-  IID_IDropTarget: TGUID = (D1: $00000122; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46));
-  CLSID_DragDropHelper: TGUID = (D1: $4657278A; D2: $411B; D3: $11D2; D4: ($83, $9A, $00, $C0, $4F, $D9, $18, $D0));
-
-  SID_IDropTargetHelper = '{4657278B-411B-11D2-839A-00C04FD918D0}';
-  SID_IDragSourceHelper = '{DE5BF786-477A-11D2-839D-00C04FD918D0}';
-  SID_IDropTarget = '{00000122-0000-0000-C000-000000000046}';
-  
-  //Bridge to ActiveX constants
-  
-  TYMED_HGLOBAL = ActiveX.TYMED_HGLOBAL;
-  TYMED_ISTREAM = ActiveX.TYMED_ISTREAM;
-  DVASPECT_CONTENT = ActiveX.DVASPECT_CONTENT;
-  CLSCTX_INPROC_SERVER = ActiveX.CLSCTX_INPROC_SERVER;
-  DROPEFFECT_COPY = ActiveX.DROPEFFECT_COPY;
-  DROPEFFECT_LINK = ActiveX.DROPEFFECT_LINK;
-  DROPEFFECT_MOVE = ActiveX.DROPEFFECT_MOVE;
-  DROPEFFECT_NONE = ActiveX.DROPEFFECT_NONE;
-  DROPEFFECT_SCROLL = ActiveX.DROPEFFECT_SCROLL;
-  DATADIR_GET = ActiveX.DATADIR_GET;
-  
-type
-  //Bridge to ActiveX Types
-  IDataObject = ActiveX.IDataObject;
-  IDropTarget = ActiveX.IDropTarget;
-  IDropSource = ActiveX.IDropSource;
-  IEnumFormatEtc = ActiveX.IEnumFORMATETC;
-  
-  //WINOLEAPI = ActiveX.WINOLEAPI;
-  
-  TFormatEtc = ActiveX.TFORMATETC;
-  TStgMedium = ActiveX.TStgMedium;
-  PDVTargetDevice = ActiveX.PDVTARGETDEVICE;
-
-  // OLE drag'n drop support
-  TFormatEtcArray = array of TFormatEtc;
-  TFormatArray = array of Word;
-
-  // IDataObject.SetData support
-  TInternalStgMedium = packed record
-    Format: TClipFormat;
-    Medium: TStgMedium;
-  end;
-  TInternalStgMediumArray = array of TInternalStgMedium;
-
-  TEnumFormatEtc = class(TInterfacedObject, IEnumFormatEtc)
-  private
-    FTree: TObject;
-    FFormatEtcArray: TFormatEtcArray;
-    FCurrentIndex: Integer;
-  public
-    constructor Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-
-    function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
-    function Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult; stdcall;
-    function Reset: HResult; stdcall;
-    function Skip(celt: LongWord): HResult; stdcall;
-  end;
-
-  IDropTargetHelper = interface(IUnknown)
-    [SID_IDropTargetHelper]
-    function DragEnter(hwndTarget: HWND; pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function DragLeave: HRESULT; stdcall;
-    function DragOver(var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Drop(pDataObject: IDataObject; var ppt: TPoint; dwEffect: LongWord): HRESULT; stdcall;
-    function Show(fShow: Boolean): HRESULT; stdcall;
-  end;
-
-  PSHDragImage = ^TSHDragImage;
-  TSHDragImage = packed record
-    sizeDragImage: TSize;
-    ptOffset: TPoint;
-    hbmpDragImage: HBITMAP;
-    ColorRef: TColorRef;
-  end;
-
-  IDragSourceHelper = interface(IUnknown)
-    [SID_IDragSourceHelper]
-    function InitializeFromBitmap(var SHDragImage: TSHDragImage; pDataObject: IDataObject): HRESULT; stdcall;
-    function InitializeFromWindow(Window: HWND; var ppt: TPoint; pDataObject: IDataObject): HRESULT; stdcall;
-  end;
-
-
-
-  IVTDragManager = interface(IUnknown)
-    ['{C4B25559-14DA-446B-8901-0C879000EB16}']
-    procedure ForceDragLeave; stdcall;
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-
-    property DataObject: IDataObject read GetDataObject;
-    property DragSource: TObject read GetDragSource;
-    property DropTargetHelperSupported: Boolean read GetDropTargetHelperSupported;
-    property IsDropTarget: Boolean read GetIsDropTarget;
-  end;
-
-  // This data object is used in two different places. One is for clipboard operations and the other while dragging.
-  TVTDataObject = class(TInterfacedObject, IDataObject)
-  private
-    //FOwner: TBaseVirtualTree;          // The tree which provides clipboard or drag data.
-    FOwner: TObject;          // The tree which provides clipboard or drag data.
-    FForClipboard: Boolean;            // Determines which data to render with GetData.
-    FFormatEtcArray: TFormatEtcArray;
-    FInternalStgMediumArray: TInternalStgMediumArray;  // The available formats in the DataObject
-    FAdviseHolder: IDataAdviseHolder;  // Reference to an OLE supplied implementation for advising.
-  protected
-    function CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-    function EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-    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;
-    function StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-      CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-    property ForClipboard: Boolean read FForClipboard;
-    property FormatEtcArray: TFormatEtcArray read FFormatEtcArray write FFormatEtcArray;
-    property InternalStgMediumArray: TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray;
-    property Owner: TObject read FOwner;
-  public
-    constructor Create(AOwner: TObject; ForClipboard: Boolean); virtual;
-    destructor Destroy; override;
-
-    function DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink; out dwConnection: DWord):
-      HResult; virtual; stdcall;
-    function DUnadvise(dwConnection: DWord): HResult; virtual; stdcall;
-    Function EnumDAvise(Out enumAdvise : IEnumStatData):HResult;virtual;StdCall;
-    function EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult; virtual; stdcall;
-    Function GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):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;
-    function QueryGetData(const FormatEtc: TFormatEtc): HResult; virtual; stdcall;
-    function SetData(const FormatEtc: TFormatEtc; {$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult; virtual; stdcall;
-  end;
-
-  // TVTDragManager is a class to manage drag and drop in a Virtual Treeview.
-  TVTDragManager = class(TInterfacedObject, IVTDragManager, IDropSource, IDropTarget)
-  private
-    FOwner,                            // The tree which is responsible for drag management.
-    FDragSource: TObject;     // Reference to the source tree if the source was a VT, might be different than
-                                       // the owner tree.
-    FIsDropTarget: Boolean;            // True if the owner is currently the drop target.
-    FDataObject: IDataObject;          // A reference to the data object passed in by DragEnter (only used when the owner
-                                       // tree is the current drop target).
-    FDropTargetHelper: IDropTargetHelper; // Win2k > Drag image support
-    FFullDragging: BOOL;               // True, if full dragging is currently enabled in the system.
-
-    function GetDataObject: IDataObject; stdcall;
-    function GetDragSource: TObject; stdcall;
-    function GetDropTargetHelperSupported: Boolean; stdcall;
-    function GetIsDropTarget: Boolean; stdcall;
-  public
-    constructor Create(AOwner: TComponent); virtual;
-    destructor Destroy; override;
-
-    function DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-      var Effect: LongWord): HResult; stdcall;
-    function DragLeave: HResult; stdcall;
-    function DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    function Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult; stdcall;
-    procedure ForceDragLeave; stdcall;
-    function GiveFeedback(Effect: LongWord): HResult; stdcall;
-    function QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult; stdcall;
-  end;
-  
-  //Ole helper functions
-
-  function Succeeded(Status : HRESULT) : BOOLEAN;
-
-  function Failed(Status : HRESULT) : BOOLEAN;
-  
-  //ActiveX functions that have wrong calling convention in fpc
-  
-  function RegisterDragDrop(hwnd:HWND; pDropTarget:IDropTarget):WINOLEAPI;stdcall;external 'ole32.dll' name 'RegisterDragDrop';
-
-  function RevokeDragDrop(hwnd:HWND):WINOLEAPI;stdcall;external 'ole32.dll' name 'RevokeDragDrop';
-
-  function DoDragDrop(pDataObj:IDataObject; pDropSource:IDropSource; dwOKEffects:DWORD; pdwEffect:LPDWORD):WINOLEAPI;stdcall;external 'ole32.dll' name 'DoDragDrop';
-
-  function OleInitialize(pvReserved:LPVOID):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleInitialize';
-
-  procedure OleUninitialize;stdcall;external 'ole32.dll' name 'OleUninitialize';
-
-  procedure ReleaseStgMedium(_para1:LPSTGMEDIUM);stdcall;external 'ole32.dll' name 'ReleaseStgMedium';
-
-  function OleSetClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleSetClipboard';
-
-  function OleGetClipboard(out ppDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleGetClipboard';
-
-  function OleFlushClipboard:WINOLEAPI;stdcall;external 'ole32.dll' name 'OleFlushClipboard';
-
-  function OleIsCurrentClipboard(pDataObj:IDataObject):WINOLEAPI;stdcall;external 'ole32.dll' name 'OleIsCurrentClipboard';
-
-  function CreateStreamOnHGlobal(hGlobal:HGLOBAL; fDeleteOnRelease:BOOL;out stm:IStream):WINOLEAPI;stdcall;external 'ole32.dll' name 'CreateStreamOnHGlobal';
-  
-  function CoCreateInstance(const _para1:TCLSID; _para2:IUnknown; _para3:DWORD;const _para4:TIID;out _para5):HRESULT;stdcall; external  'ole32.dll' name 'CoCreateInstance';
-
-  //helper functions to isolate windows/OLE specific code
-  
-  function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out Medium: TStgMedium;
-    ForClipboard: Boolean): HResult;
-    
-  function GetStreamFromMedium(Medium:TStgMedium):TStream;
-  
-  procedure UnlockMediumData(Medium:TStgMedium);
-  
-  function GetTreeFromDataObject(const DataObject: IDataObject; var Format: TFormatEtc): TObject;
-  
-  function AllocateGlobal(Data: Pointer; DataSize:Cardinal): HGLOBAL;
-
-implementation
-
-uses
-  VirtualTrees, Controls, oleutils;
-  
-type
-  TVirtualTreeAccess = class (TBaseVirtualTree)
-  end;
-
-function Succeeded(Status : HRESULT) : BOOLEAN;
-  begin
-     Succeeded:=Status and HRESULT($80000000)=0;
-  end;
-
-function Failed(Status : HRESULT) : BOOLEAN;
-  begin
-     Failed:=Status and HRESULT($80000000)<>0;
-  end;
-
-
-function RenderOLEData(Tree: TObject; const FormatEtcIn: TFormatEtc; out
-  Medium: TStgMedium; ForClipboard: Boolean): HResult;
-
-  //--------------- local function --------------------------------------------
-
-  procedure WriteNodes(Stream: TStream);
-
-  var
-    Selection: TNodeArray;
-    I: Integer;
-
-  begin
-    with TVirtualTreeAccess(Tree) do
-    begin
-      if ForClipboard then
-        Selection := GetSortedCutCopySet(True)
-      else
-        Selection := GetSortedSelection(True);
-      for I := 0 to High(Selection) do
-        WriteNode(Stream, Selection[I]);
-    end;
-  end;
-
-  //--------------- end local function ----------------------------------------
-
-var
-  Data: PCardinal;
-  ResPointer: Pointer;
-  ResSize: Integer;
-  OLEStream: IStream;
-  VCLStream: TStream;
-  
-begin
-  VCLStream := nil;
-  try
-    Medium.PunkForRelease := 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.Pstm) := 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;
-
-
-type
-  // needed to handle OLE global memory objects
-  TOLEMemoryStream = class(TCustomMemoryStream)
-  public
-    function Write(const Buffer; Count: Integer): Longint; override;
-  end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TOLEMemoryStream.Write(const Buffer; Count: Integer): Integer;
-
-begin
-  {$ifdef COMPILER_5_UP}
-    raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError));
-  {$else}
-    raise EStreamError.Create(SCantWriteResourceStreamError);
-  {$endif COMPILER_5_UP}
-end;
-
-
-function GetStreamFromMedium(Medium: TStgMedium): TStream;
-var
-  Data: Pointer;
-  I: Integer;
-begin
-  Result := nil;
-  if Medium.tymed = TYMED_ISTREAM then
-    Result := TOLEStream.Create(IUnknown(Medium.Pstm) as IStream)
-  else
-  begin
-    Data := GlobalLock(Medium.hGlobal);
-    if Assigned(Data) then
-    begin
-      // Get the total size of data to retrieve.
-      I := PCardinal(Data)^;
-      Inc(PCardinal(Data));
-      Result := TOLEMemoryStream.Create;
-      TOLEMemoryStream(Result).SetPointer(Data, I);
-    end;
-  end;
-end;
-
-procedure UnlockMediumData(Medium: TStgMedium);
-begin
-  if Medium.tymed = TYMED_HGLOBAL then
-    GlobalUnlock(Medium.hGlobal);
-end;
-
-function GetTreeFromDataObject(const DataObject: IDataObject;
-  var Format: TFormatEtc): TObject;
-  
-var
-  Medium: TStgMedium;
-  Data: PVTReference;
-  
-begin
-  Result := nil;
-  if Assigned(DataObject) then
-  begin
-    Format.cfFormat := CF_VTREFERENCE;
-    if DataObject.GetData(Format, 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 AllocateGlobal(Data: Pointer; DataSize: Cardinal): HGLOBAL;
-var
-  P:Pointer;
-begin
-  Result := GlobalAlloc(GHND or GMEM_SHARE, DataSize);
-  P := GlobalLock(Result);
-  Move(Data^, P^, DataSize);
-  GlobalUnlock(Result);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-// OLE drag and drop support classes
-// This is quite heavy stuff (compared with the VCL implementation) but is much better suited to fit the needs
-// of DD'ing various kinds of virtual data and works also between applications.
-
-//----------------- TEnumFormatEtc -------------------------------------------------------------------------------------
-
-constructor TEnumFormatEtc.Create(Tree: TObject; AFormatEtcArray: TFormatEtcArray);
-
-var
-  I: Integer;
-
-begin
-  inherited Create;
-
-  FTree := Tree;
-  // Make a local copy of the format data.
-  SetLength(FFormatEtcArray, Length(AFormatEtcArray));
-  for I := 0 to High(AFormatEtcArray) do
-    FFormatEtcArray[I] := AFormatEtcArray[I];
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
-
-var
-  AClone: TEnumFormatEtc;
-
-begin
-  Result := S_OK;
-  try
-    AClone := TEnumFormatEtc.Create(nil, FFormatEtcArray);
-    AClone.FCurrentIndex := FCurrentIndex;
-    Enum := AClone as IEnumFormatEtc;
-  except
-    Result := E_FAIL;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Next(celt: LongWord; out elt: FormatEtc; out pceltFetched: LongWord): HResult;
-
-var
-  CopyCount: LongWord;
-
-begin
-  Result := S_FALSE;
-  CopyCount := Length(FFormatEtcArray) - FCurrentIndex;
-  if celt < CopyCount then
-    CopyCount := celt;
-  if CopyCount > 0 then
-  begin
-    Move(FFormatEtcArray[FCurrentIndex], elt, CopyCount * SizeOf(TFormatEtc));
-    Inc(FCurrentIndex, CopyCount);
-    Result := S_OK;
-  end;
-  //todo_lcl_check Delphi treats pceltFetched an PInteger. Implemented like in fpc.activex. What heappens with
-  // a C Program call with a NULL in pCeltFetcjed??
-  //Answer: Yes. Is necessary a check here
-  if @pceltFetched <> nil then
-    pceltFetched := CopyCount;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Reset: HResult;
-
-begin
-  FCurrentIndex := 0;
-  Result := S_OK;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TEnumFormatEtc.Skip(celt: LongWord): HResult;
-
-begin
-  if FCurrentIndex + celt < High(FFormatEtcArray) then
-  begin
-    Inc(FCurrentIndex, celt);
-    Result := S_Ok;
-  end
-  else
-    Result := S_FALSE;
-end;
-
-
-//----------------- TVTDataObject --------------------------------------------------------------------------------------
-
-constructor TVTDataObject.Create(AOwner: TObject; ForClipboard: Boolean);
-
-begin
-  inherited Create;
-
-  FOwner := AOwner;
-  FForClipboard := ForClipboard;
-  TVirtualTreeAccess(FOwner).GetNativeClipboardFormats(FFormatEtcArray);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDataObject.Destroy;
-
-var
-  I: Integer;
-  StgMedium: PStgMedium;
-
-begin
-  // Cancel a pending clipboard operation if this data object was created for the clipboard and
-  // is freed because something else is placed there.
-  if FForClipboard and not (tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates) then
-    TVirtualTreeAccess(FOwner).CancelCutOrCopy;
-
-  // Release any internal clipboard formats
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    StgMedium := FindInternalStgMedium(FormatEtcArray[I].cfFormat);
-    if Assigned(StgMedium) then
-      ReleaseStgMedium(StgMedium);
-  end;
-
-  FormatEtcArray := nil;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.CanonicalIUnknown(TestUnknown: IUnknown): IUnknown;
-
-// Uses COM object identity: An explicit call to the IUnknown::QueryInterface method, requesting the IUnknown
-// interface, will always return the same pointer.
-
-begin
-  if Assigned(TestUnknown) then
-  begin
-    if TestUnknown.QueryInterface(IUnknown, Result) = 0 then
-      Result._Release // Don't actually need it just need the pointer value
-    else
-      Result := TestUnknown
-  end
-  else
-    Result := TestUnknown
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EqualFormatEtc(FormatEtc1, FormatEtc2: TFormatEtc): Boolean;
-
-begin
-  Result := (FormatEtc1.cfFormat = FormatEtc2.cfFormat) and (FormatEtc1.ptd = FormatEtc2.ptd) and
-    (FormatEtc1.dwAspect = FormatEtc2.dwAspect) and (FormatEtc1.lindex = FormatEtc2.lindex) and
-    (FormatEtc1.tymed and FormatEtc2.tymed <> 0);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindFormatEtc(TestFormatEtc: TFormatEtc; const FormatEtcArray: TFormatEtcArray): integer;
-
-var
-  I: integer;
-
-begin
-  Result := -1;
-  for I := 0 to High(FormatEtcArray) do
-  begin
-    if EqualFormatEtc(TestFormatEtc, FormatEtcArray[I]) then
-    begin
-      Result := I;
-      Break;
-    end
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.FindInternalStgMedium(Format: TClipFormat): PStgMedium;
-
-var
-  I: integer;
-begin
-  Result := nil;
-  for I := 0 to High(InternalStgMediumArray) do
-  begin
-    if Format = InternalStgMediumArray[I].Format then
-    begin
-      Result := @InternalStgMediumArray[I].Medium;
-      Break;
-    end
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.HGlobalClone(HGlobal: THandle): THandle;
-
-// Returns a global memory block that is a copy of the passed memory block.
-
-var
-  Size: Cardinal;
-  Data,
-  NewData: PChar;
-
-begin
-  Size := GlobalSize(HGlobal);
-  Result := GlobalAlloc(GPTR, Size);
-  Data := GlobalLock(hGlobal);
-  try
-    NewData := GlobalLock(Result);
-    try
-      Move(Data^, NewData^, Size);
-    finally
-      GlobalUnLock(Result);
-    end
-  finally
-    GlobalUnLock(hGlobal);
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.RenderInternalOLEData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium;
-  var OLEResult: HResult): Boolean;
-
-// Tries to render one of the formats which have been stored via the SetData method.
-// Since this data is already there it is just copied or its reference count is increased (depending on storage medium).
-
-var
-  InternalMedium: PStgMedium;
-
-begin
-  Result := True;
-  InternalMedium := FindInternalStgMedium(FormatEtcIn.cfFormat);
-  if Assigned(InternalMedium) then
-    OLEResult := StgMediumIncRef(InternalMedium^, Medium, False, Self as IDataObject)
-  else
-    Result := False;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.StgMediumIncRef(const InStgMedium: TStgMedium; var OutStgMedium: TStgMedium;
-  CopyInMedium: Boolean; DataObject: IDataObject): HRESULT;
-
-// InStgMedium is the data that is requested, OutStgMedium is the data that we are to return either a copy of or
-// increase the IDataObject's reference and send ourselves back as the data (unkForRelease). The InStgMedium is usually
-// the result of a call to find a particular FormatEtc that has been stored locally through a call to SetData.
-// If CopyInMedium is not true we already have a local copy of the data when the SetData function was called (during
-// that call the CopyInMedium must be true). Then as the caller asks for the data through GetData we do not have to make
-// copy of the data for the caller only to have them destroy it then need us to copy it again if necessary.
-// This way we increase the reference count to ourselves and pass the STGMEDIUM structure initially stored in SetData.
-// 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;
-
-begin
-  Result := S_OK;
-
-  // Simply copy all fields to start with.
-  OutStgMedium := InStgMedium;
-  // The data handled here always results from a call of SetData we got. This ensures only one storage format
-  // is indicated and hence the case statement below is safe (IDataObject.GetData can optionally use several
-  // storage formats).
-  case InStgMedium.tymed of
-    TYMED_HGLOBAL:
-      begin
-        if CopyInMedium then
-        begin
-          // Generate a unique copy of the data passed
-          OutStgMedium.hGlobal := HGlobalClone(InStgMedium.hGlobal);
-          if OutStgMedium.hGlobal = 0 then
-            Result := E_OUTOFMEMORY
-        end
-        else
-          // Don't generate a copy just use ourselves and the copy previously saved.
-          OutStgMedium.PunkForRelease := Pointer(DataObject); // Does not increase RefCount.
-      end;
-    TYMED_FILE:
-      begin
-        //todo_lcl_check
-        Len := Length(WideString(InStgMedium.lpszFileName)) + 1; // Don't forget the terminating null character.
-        OutStgMedium.lpszFileName := CoTaskMemAlloc(2 * Len);
-        Move(InStgMedium.lpszFileName^, OutStgMedium.lpszFileName^, 2 * Len);
-      end;
-    TYMED_ISTREAM:
-      IUnknown(OutStgMedium.Pstm)._AddRef;
-    TYMED_ISTORAGE:
-      IUnknown(OutStgMedium.Pstg)._AddRef;
-    TYMED_GDI:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy GDI objects right now.
-    TYMED_MFPICT:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy MetaFile objects right now.
-    TYMED_ENHMF:
-      if not CopyInMedium then
-        // Don't generate a copy just use ourselves and the previously saved data.
-        OutStgMedium.PunkForRelease := Pointer(DataObject) // Does not increase RefCount.
-      else
-        Result := DV_E_TYMED; // Don't know how to copy enhanced metafiles objects right now.
-  else
-    Result := DV_E_TYMED;
-  end;
-
-  if (Result = S_OK) and Assigned(OutStgMedium.PunkForRelease) then
-    IUnknown(OutStgMedium.PunkForRelease)._AddRef;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DAdvise(const FormatEtc: TFormatEtc; advf: DWord; const advSink: IAdviseSink;
-  out dwConnection: DWord): HResult;
-
-// Advise sink management is greatly simplified by the IDataAdviseHolder interface.
-// We use this interface and forward all concerning calls to it.
-
-begin
-  Result := S_OK;
-  if FAdviseHolder = nil then
-    Result := CreateDataAdviseHolder(FAdviseHolder);
-  if Result = S_OK then
-    Result := FAdviseHolder.Advise(Self as IDataObject, FormatEtc, advf, advSink, dwConnection);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.DUnadvise(dwConnection: DWord): HResult;
-
-begin
-  if FAdviseHolder = nil then
-    Result := E_NOTIMPL
-  else
-    Result := FAdviseHolder.Unadvise(dwConnection);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumDAvise(Out enumAdvise : IEnumStatData):HResult;
-
-begin
-  if FAdviseHolder = nil then
-    Result := OLE_E_ADVISENOTSUPPORTED
-  else
-    Result := FAdviseHolder.EnumAdvise(enumAdvise);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.EnumFormatEtc(Direction: DWord; out EnumFormatEtc: IEnumFormatEtc): HResult;
-
-var
-  NewList: TEnumFormatEtc;
-
-begin
-  Result := E_FAIL;
-  if Direction = DATADIR_GET then
-  begin
-    NewList := TEnumFormatEtc.Create(TVirtualTreeAccess(FOwner), FormatEtcArray);
-    EnumFormatEtc := NewList as IEnumFormatEtc;
-    Result := S_OK;
-  end
-  else
-    EnumFormatEtc := nil;
-  if EnumFormatEtc = nil then
-    Result := OLE_S_USEREG;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-Function TVTDataObject.GetCanonicalFormatTEtc(const pformatetcIn : FORMATETC;Out pformatetcOut : FORMATETC):HResult;
-
-begin
-  Result := DATA_S_SAMEFORMATETC;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium): HResult;
-
-// Data is requested by clipboard or drop target. This method dispatchs the call
-// depending on the data being requested.
-
-var
-  I: Integer;
-  Data: PVTReference;
-
-begin
-  // The tree reference format is always supported and returned from here.
-  if FormatEtcIn.cfFormat = CF_VTREFERENCE then
-  begin
-    // Note: this format is not used while flushing the clipboard to avoid a dangling reference
-    //       when the owner tree is destroyed before the clipboard data is replaced with something else.
-    if tsClipboardFlushing in TVirtualTreeAccess(FOwner).TreeStates then
-      Result := E_FAIL
-    else
-    begin
-      Medium.hGlobal := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TVTReference));
-      Data := GlobalLock(Medium.hGlobal);
-      Data.Process := GetCurrentProcessID;
-      Data.Tree := TBaseVirtualTree(FOwner);
-      GlobalUnlock(Medium.hGlobal);
-      Medium.tymed := TYMED_HGLOBAL;
-      Medium.PunkForRelease := nil;
-      Result := S_OK;
-    end;
-  end
-  else
-  begin
-    try
-      // See if we accept this type and if not get the correct return value.
-      Result := QueryGetData(FormatEtcIn);
-      if Result = S_OK then
-      begin
-        for I := 0 to High(FormatEtcArray) do
-        begin
-          if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
-          begin
-            if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
-              Result := TVirtualTreeAccess(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard);
-            Break;
-          end;
-        end
-      end
-    except
-      FillChar(Medium, SizeOf(Medium), #0);
-      Result := E_FAIL;
-    end;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.GetDataHere(const FormatEtc: TFormatEtc; out Medium: TStgMedium): HResult;
-
-begin
-  Result := E_NOTIMPL;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.QueryGetData(const FormatEtc: TFormatEtc): HResult;
-
-var
-  I: Integer;
-
-begin
-  Result := DV_E_CLIPFORMAT;
-  for I := 0 to High(FFormatEtcArray) do
-  begin
-    if FormatEtc.cfFormat = FFormatEtcArray[I].cfFormat then
-    begin
-      if (FormatEtc.tymed and FFormatEtcArray[I].tymed) <> 0 then
-      begin
-        if FormatEtc.dwAspect = FFormatEtcArray[I].dwAspect then
-        begin
-          if FormatEtc.lindex = FFormatEtcArray[I].lindex then
-          begin
-            Result := S_OK;
-            Break;
-          end
-          else
-            Result := DV_E_LINDEX;
-        end
-        else
-          Result := DV_E_DVASPECT;
-      end
-      else
-        Result := DV_E_TYMED;
-    end;
-  end
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDataObject.SetData(const FormatEtc: TFormatEtc;{$ifdef VER2_0}var{$else}const{$endif} Medium: TStgMedium; DoRelease: BOOL): HResult;
-
-// 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;
-  LocalStgMedium: PStgMedium;
-
-begin
-  // See if we already have a format of that type available.
-  Index := FindFormatEtc(FormatEtc, FormatEtcArray);
-  if Index > - 1 then
-  begin
-    // Just use the TFormatEct in the array after releasing the data.
-    LocalStgMedium := FindInternalStgMedium(FormatEtcArray[Index].cfFormat);
-    if Assigned(LocalStgMedium) then
-    begin
-      ReleaseStgMedium(LocalStgMedium);
-      FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-    end;
-  end
-  else
-  begin
-    // It is a new format so create a new TFormatCollectionItem, copy the
-    // FormatEtc parameter into the new object and and put it in the list.
-    SetLength(FFormatEtcArray, Length(FormatEtcArray) + 1);
-    FormatEtcArray[High(FormatEtcArray)] := FormatEtc;
-
-    // Create a new InternalStgMedium and initialize it and associate it with the format.
-    SetLength(FInternalStgMediumArray, Length(InternalStgMediumArray) + 1);
-    InternalStgMediumArray[High(InternalStgMediumArray)].Format := FormatEtc.cfFormat;
-    LocalStgMedium := @InternalStgMediumArray[High(InternalStgMediumArray)].Medium;
-    FillChar(LocalStgMedium^, SizeOf(LocalStgMedium^), #0);
-  end;
-
-  if DoRelease then
-  begin
-    // We are simply being given the data and we take control of it.
-    LocalStgMedium^ := Medium;
-    Result := S_OK
-  end
-  else
-  begin
-    // We need to reference count or copy the data and keep our own references to it.
-    Result := StgMediumIncRef(Medium, LocalStgMedium^, True, Self as IDataObject);
-
-    // Can get a circular reference if the client calls GetData then calls SetData with the same StgMedium.
-    // Because the unkForRelease for the IDataObject can be marshalled it is necessary to get pointers that
-    // can be correctly compared. See the IDragSourceHelper article by Raymond Chen at MSDN.
-    if Assigned(LocalStgMedium.PunkForRelease) then
-    begin
-      if CanonicalIUnknown(Self) = CanonicalIUnknown(IUnknown(LocalStgMedium.PunkForRelease)) then
-        IUnknown(LocalStgMedium.PunkForRelease) := nil; // release the interface
-    end;
-  end;
-
-  // Tell all registered advice sinks about the data change.
-  if Assigned(FAdviseHolder) then
-    FAdviseHolder.SendOnDataChange(Self as IDataObject, 0, 0);
-end;
-
-
-//----------------- TVTDragManager -------------------------------------------------------------------------------------
-
-constructor TVTDragManager.Create(AOwner: TComponent);
-
-begin
-  inherited Create;
-  FOwner := AOwner;
-
-  // Create an instance  of the drop target helper interface. This will fail but not harm on systems which do
-  // not support this interface (everything below Windows 2000);
-  CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-destructor TVTDragManager.Destroy;
-
-begin
-  // Set the owner's reference to us to nil otherwise it will access an invalid pointer
-  // after our desctruction is complete.
-  TVirtualTreeAccess(FOwner).FreeDragManager;
-  inherited;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDataObject: IDataObject;
-
-begin
-  // When the owner tree starts a drag operation then it gets a data object here to pass it to the OLE subsystem.
-  // In this case there is no local reference to a data object and one is created (but not stored).
-  // If there is a local reference then the owner tree is currently the drop target and the stored interface is
-  // that of the drag initiator.
-  if Assigned(FDataObject) then
-    Result := FDataObject
-  else
-  begin
-    Result := TVirtualTreeAccess(FOwner).DoCreateDataObject;
-    if Result = nil then
-      Result := TVTDataObject.Create(FOwner, False) as IDataObject;
-  end;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDragSource: TObject;
-
-begin
-  Result := FDragSource;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetDropTargetHelperSupported: Boolean;
-
-begin
-  Result := Assigned(FDropTargetHelper);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GetIsDropTarget: Boolean;
-
-begin
-  Result := FIsDropTarget;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragEnter(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  FDataObject := DataObject;
-  FIsDropTarget := True;
-
-  SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @FFullDragging, 0);
-  // If full dragging of window contents is disabled in the system then our tree windows will be locked
-  // and cannot be updated during a drag operation. With the following call painting is again enabled.
-  if not FFullDragging then
-    LockWindowUpdate(0);
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragEnter(TBaseVirtualTree(FOwner).Handle, DataObject, Pt, Effect);
-
-  FDragSource := TVirtualTreeAccess(FOwner).GetTreeFromDataObject(DataObject);
-  Result := TVirtualTreeAccess(FOwner).DragEnter(KeyState, Pt, Effect);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragLeave: HResult;
-
-begin
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-
-  TVirtualTreeAccess(FOwner).DragLeave;
-  FIsDropTarget := False;
-  FDragSource := nil;
-  FDataObject := nil;
-  Result := NOERROR;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.DragOver(KeyState: LongWord; Pt: TPoint; var Effect: LongWord): HResult;
-
-begin
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragOver(Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragOver(FDragSource, KeyState, dsDragMove, Pt, Effect);
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.Drop(const DataObject: IDataObject; KeyState: LongWord; Pt: TPoint;
-  var Effect: LongWord): HResult;
-
-begin
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.Drop(DataObject, Pt, Effect);
-
-  Result := TVirtualTreeAccess(FOwner).DragDrop(DataObject, KeyState, Pt, Effect);
-  FIsDropTarget := False;
-  FDataObject := nil;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-procedure TVTDragManager.ForceDragLeave;
-
-// Some drop targets, e.g. Internet Explorer leave a drag image on screen instead removing it when they receive
-// a drop action. This method calls the drop target helper's DragLeave method to ensure it removes the drag image from
-// screen. Unfortunately, sometimes not even this does help (e.g. when dragging text from VT to a text field in IE).
-
-begin
-  if Assigned(FDropTargetHelper) and FFullDragging then
-    FDropTargetHelper.DragLeave;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.GiveFeedback(Effect: LongWord): HResult;
-
-begin
-  Result := DRAGDROP_S_USEDEFAULTCURSORS;
-end;
-
-//----------------------------------------------------------------------------------------------------------------------
-
-function TVTDragManager.QueryContinueDrag(EscapePressed: BOOL; KeyState: LongWord): HResult;
-
-var
-  RButton,
-  LButton: Boolean;
-
-begin
-  LButton := (KeyState and MK_LBUTTON) <> 0;
-  RButton := (KeyState and MK_RBUTTON) <> 0;
-
-  // Drag'n drop canceled by pressing both mouse buttons or Esc?
-  if (LButton and RButton) or EscapePressed then
-    Result := DRAGDROP_S_CANCEL
-  else
-    // Drag'n drop finished?
-    if not (LButton or RButton) then
-      Result := DRAGDROP_S_DROP
-    else
-      Result := S_OK;
-end;
-
-
-end.
-

+ 0 - 113
components/virtualtreeview/units/win32/virtualpanningwindow.pas

@@ -1,113 +0,0 @@
-unit virtualpanningwindow;
-
-{Adapted from VirtualTrees by Luiz Américo to work in LCL/Lazarus}
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  Windows, Graphics, Classes, SysUtils;
-  
-type
-  { TVirtualPanningWindow }
-
-  TVirtualPanningWindow = class
-  private
-    FHandle: THandle;
-    FImage: TBitmap;
-    procedure HandlePaintMessage;
-  public
-    procedure Start(OwnerHandle: THandle; const Position: TPoint);
-    procedure Stop;
-    procedure Show(ClipRegion: HRGN);
-    property Image: TBitmap read FImage;
-    property Handle: THandle read FHandle;
-  end;
-
-implementation
-
-{$ifdef DEBUG_VTV}
-uses
-  vtlogger;
-{$endif}
-
-function PanningWindowProc(Window: HWnd; Msg: UInt;WPara: WParam; LPara: LParam): LResult; stdcall;
-var
-  PanningObject: TVirtualPanningWindow;
-begin
-  if Msg = WM_PAINT then
-  begin
-    PanningObject:=TVirtualPanningWindow(GetWindowLongPtrW(Window,GWL_USERDATA));
-    if Assigned(PanningObject) then
-      PanningObject.HandlePaintMessage;
-	Result := 0;
-  end
-  else
-    Result := DefWindowProc(Window,Msg,WPara,LPara);
-end;
-
-var
-  PanningWindowClass: TWndClass = (
-    style: 0;
-    lpfnWndProc: @PanningWindowProc;
-    cbClsExtra: 0;
-    cbWndExtra: 0;
-    hInstance: 0;
-    hIcon: 0;
-    hCursor: 0;
-    hbrBackground: 0;
-    lpszMenuName: nil;
-    lpszClassName: 'VTPanningWindow'
-  );
-
-{ TVirtualPanningWindow }
-
-procedure TVirtualPanningWindow.HandlePaintMessage;
-var
-  PS: PaintStruct;
-begin
-  BeginPaint(FHandle, PS);
-  BitBlt(PS.hdc,0,0,FImage.Width,FImage.Height,FImage.Canvas.Handle,0,0,SRCCOPY);
-  EndPaint(FHandle, PS);
-end;
-
-
-procedure TVirtualPanningWindow.Start(OwnerHandle: THandle; const Position: TPoint);
-var
-  TempClass: TWndClass;
-begin
-  // Register the helper window class.
-  if not GetClassInfo(HInstance, PanningWindowClass.lpszClassName, TempClass) then
-  begin
-    PanningWindowClass.hInstance := HInstance;
-    Windows.RegisterClass(PanningWindowClass);
-  end;
-  
-  // Create the helper window and show it at the given position without activating it.
-  with Position do
-    FHandle := CreateWindowEx(WS_EX_TOOLWINDOW, PanningWindowClass.lpszClassName, nil, WS_POPUP, X - 16, Y - 16,
-      32, 32, OwnerHandle, 0, HInstance, nil);
-  SetWindowLongPtr(FHandle,GWL_USERDATA,LONG_PTR(Self));
-  
-  FImage := TBitmap.Create;
-end;
-
-procedure TVirtualPanningWindow.Stop;
-begin
-  // Destroy the helper window.
-  DestroyWindow(FHandle);
-  FImage.Free;
-  FImage := nil;
-end;
-
-procedure TVirtualPanningWindow.Show(ClipRegion: HRGN);
-begin
-  {$ifdef DEBUG_VTV}Logger.SendBitmap([lcPanning],'Panning Image',FImage);{$endif}
-  //todo: move SetWindowRgn to DelphiCompat
-  SetWindowRgn(FHandle, ClipRegion, False);
-  ShowWindow(FHandle, SW_SHOWNOACTIVATE);
-end;
-
-end.
-

+ 0 - 2108
components/virtualtreeview/virtualtrees.lrs

@@ -1,2108 +0,0 @@
-LazarusResources.Add('VT_VERTSPLIT','CUR',[
-  #0#0#2#0#1#0'  '#2#0#14#0#15#0'0'#1#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#1#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#2#0#0#0#2#0#0#0#0#0#0#0#255#255#255#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#6#0#0#0#9#0#0#0#16#128#0#0
-  +' @'#0#0#25#128#0#0#9#0#0#0#9#0#0#7#249#254#0#4#0#2#0#4#0#2#0#7#249#254#0#0#9
-  +#0#0#0#9#0#0#0#25#128#0#0' @'#0#0#16#128#0#0#9#0#0#0#6#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#249
-  +#255#255#255#240#255#255#255#224#127#255#255#192'?'#255#255#224#127#255#255
-  +#240#255#255#255#240#255#255#248#0#1#255#248#0#1#255#248#0#1#255#248#0#1#255
-  +#255#240#255#255#255#240#255#255#255#224#127#255#255#192'?'#255#255#224#127
-  +#255#255#240#255#255#255#249#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255
-]);
-LazarusResources.Add('VT_HEADERSPLIT','CUR',[
-  #0#0#2#0#1#0'  '#0#0#15#0#14#0'0'#1#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#1#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7
-  +#128#0#0#4#128#0#0#4#128#0#0#4#128#0#0#4#128#0#0'D'#136#0#0#164#148#0#1'<'
-  +#242#0#2#0#1#0#2#0#1#0#1'<'#242#0#0#164#148#0#0'D'#136#0#0#4#128#0#0#4#128#0
-  +#0#4#128#0#0#4#128#0#0#7#128#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#248#127
-  +#255#255#248#127#255#255#248#127#255#255#248#127#255#255#248#127#255#255#184
-  +'w'#255#255#24'c'#255#254#0#1#255#252#0#0#255#252#0#0#255#254#0#1#255#255#24
-  +'c'#255#255#184'w'#255#255#248#127#255#255#248#127#255#255#248#127#255#255
-  +#248#127#255#255#248#127#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVEALL','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0'0'#1#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#1#0#0#0#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#128#0#0#2'@'#0#0#4' '#0#0#8#16#0#0#16#8
-  +#0#0' '#4#0#0#127#254#0#0#160#5#0#1' '#4#128#2'!'#132'@'#4'"D '#8'$$'#16#8'$'
-  +'$'#16#4'"D '#2'!'#132'@'#1' '#4#128#0#160#5#0#0#127#254#0#0' '#4#0#0#16#8#0
-  +#0#8#16#0#0#4' '#0#0#2'@'#0#0#1#128#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254#127#255#255
-  +#252'?'#255#255#248#31#255#255#240#15#255#255#224#7#255#255#192#3#255#255#128
-  +#1#255#255#31#248#255#254#31#248#127#252#30'x?'#248#28'8'#31#240#24#24#15#240
-  +#24#24#15#248#28'8'#31#252#30'x?'#254#31#248#127#255#31#248#255#255#128#1#255
-  +#255#192#3#255#255#224#7#255#255#240#15#255#255#248#31#255#255#252'?'#255#255
-  +#254#127#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVEE','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#15#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#240#0#0#0#0#0#0#0#0#0#0#15#240
-  +#0#15#0#15#0#0#0#0#0#0#0#0#0#0#240#15#0#15#0#0#240#0#0#0#0#0#0#0#0#15#0#0#240
-  +#15#0#0#15#0#0#0#0#0#0#0#0#15#0#0#240#15#0#0#15#0#0#0#0#0#0#0#0#0#240#15#0#15
-  +#0#0#240#0#0#0#0#0#0#0#0#0#15#240#0#15#0#15#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0
-  +#240#0#0#0#0#0#0#0#0#0#0#0#0#0#15#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#251#255#255#255#249#255#255#255#248#255#255#255#248#127
-  +#255#254'x?'#255#252'8'#31#255#248#24#15#255#248#24#15#255#252'8'#31#255#254
-  +'x?'#255#255#248#127#255#255#248#255#255#255#249#255#255#255#251#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVEEW','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#15#240#0#0#0#0#0#0#0#0
-  +#240#240#0#0#0#0#15#15#0#0#0#0#0#0#0#15#0#240#0#0#0#0#15#0#240#0#0#0#0#0#0
-  +#240#0#240#0#15#240#0#15#0#15#0#0#0#0#0#15#0#0#240#0#240#15#0#15#0#0#240#0#0
-  +#0#0#240#0#0#240#15#0#0#240#15#0#0#15#0#0#0#0#240#0#0#240#15#0#0#240#15#0#0
-  +#15#0#0#0#0#15#0#0#240#0#240#15#0#15#0#0#240#0#0#0#0#0#240#0#240#0#15#240#0
-  +#15#0#15#0#0#0#0#0#0#15#0#240#0#0#0#0#15#0#240#0#0#0#0#0#0#0#240#240#0#0#0#0
-  +#15#15#0#0#0#0#0#0#0#0#15#240#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#240#0#0#0#0#15
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#223#251
-  +#255#255#159#249#255#255#31#248#255#254#31#248#127#252#30'x?'#248#28'8'#31
-  +#240#24#24#15#240#24#24#15#248#28'8'#31#252#30'x?'#254#31#248#127#255#31#248
-  +#255#255#159#249#255#255#223#251#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVEN','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0
-  +#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255
-  +#255#255#255#255#255#255#0#0#0#0#0#0#0#0#15#0#0#0#0#0#0#240#0#0#0#0#0#0#0#0#0
-  +#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240#0#0#0#0#0#0#0#0#0#0#0#240
-  +#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#254#127#255#255#252'?'#255#255#248#31#255#255#248#31#255#255#252'?'
-  +#255#255#254#127#255#255#255#255#255#255#0#0#255#255#128#1#255#255#192#3#255
-  +#255#224#7#255#255#240#15#255#255#248#31#255#255#252'?'#255#255#254#127#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVENE','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#240#15#0#0#0#240#0#0#0#0#0#0#0#0#0#15#0#0#240#0#15#240#0#0
-  +#0#0#0#0#0#0#0#15#0#0#240#0#240#240#0#0#0#0#0#0#0#0#0#0#240#15#0#15#0#240#0#0
-  +#0#0#0#0#0#0#0#0#15#240#0#240#0#240#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0
-  +#0#0#0#0#0#0#0#0#0#240#0#0#240#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#240#0#0#0#0#0#0
-  +#0#0#0#0#0#240#0#0#0#240#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240#0#0#0#0#0#0#0#0#0
-  +#0#255#255#255#255#255#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#254#127#255#255#252'?'#127#255#248#30#127#255#248#28#127#255#252
-  +'8'#127#255#254'p'#127#255#255#224#127#255#255#192#127#255#255#128#127#255
-  +#255#0#127#255#254#0#127#255#252#0#127#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVENS','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0
-  +#240#0#0#0#0#0#0#0#0#0#0#0#0#240#0#0#15#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240
-  +#0#0#0#0#0#0#0#0#0#0#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#15#255#255#255#255#255
-  +#255#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#255#255#255#255
-  +#255#255#240#0#0#0#0#0#0#0#0#0#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0
-  +#240#0#0#0#0#0#0#0#0#0#0#0#240#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#254#127#255#255#252'?'#255
-  +#255#248#31#255#255#240#15#255#255#224#7#255#255#192#3#255#255#128#1#255#255
-  +#255#255#255#255#255#255#255#255#254#127#255#255#252'?'#255#255#248#31#255
-  +#255#248#31#255#255#252'?'#255#255#254#127#255#255#255#255#255#255#255#255
-  +#255#255#128#1#255#255#192#3#255#255#224#7#255#255#240#15#255#255#248#31#255
-  +#255#252'?'#255#255#254#127#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVENW','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0
-  +#0#0#0#0#0#15#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#15#240#0#15#0#0#240#0#0#0#0#0
-  +#0#0#0#0#15#15#0#15#0#0#240#0#0#0#0#0#0#0#0#0#15#0#240#0#240#15#0#0#0#0#0#0#0
-  +#0#0#0#15#0#15#0#15#240#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0
-  +#0#15#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#240#0#0#0#0#0#0#0#0#0#0#0#15#0
-  +#0#0#15#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240#0#0#0#0#0#0#0#0#0#0#15#255#255
-  +#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#254#127#255#254#252'?'#255#254'x'#31#255#254'8'#31#255#254#28'?'#255
-  +#254#14#127#255#254#7#255#255#254#3#255#255#254#1#255#255#254#0#255#255#254#0
-  +#127#255#254#0'?'#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVES','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0
-  +#240#0#0#0#0#0#0#0#0#0#0#0#0#240#0#0#15#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240
-  +#0#0#0#0#0#0#0#0#0#0#240#0#0#0#0#15#0#0#0#0#0#0#0#0#0#15#0#0#0#0#0#0#240#0#0
-  +#0#0#0#0#0#0#255#255#255#255#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#15#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#254#127#255#255#252'?'#255#255#248#31#255#255#240#15#255
-  +#255#224#7#255#255#192#3#255#255#128#1#255#255#0#0#255#255#255#255#255#255
-  +#254#127#255#255#252'?'#255#255#248#31#255#255#248#31#255#255#252'?'#255#255
-  +#254#127#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVESE','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#240#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0
-  +#240#0#0#0#0#0#0#0#0#0#0#0#240#0#0#0#240#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#240#0
-  +#0#0#0#0#0#0#0#0#0#0#0#240#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0
-  +#0#0#0#0#0#0#15#240#0#240#0#240#0#0#0#0#0#0#0#0#0#0#240#15#0#15#0#240#0#0#0#0
-  +#0#0#0#0#0#15#0#0#240#0#240#240#0#0#0#0#0#0#0#0#0#15#0#0#240#0#15#240#0#0#0#0
-  +#0#0#0#0#0#0#240#15#0#0#0#240#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#252
-  +#0#127#255#254#0#127#255#255#0#127#255#255#128#127#255#255#192#127#255#255
-  +#224#127#255#254'p'#127#255#252'8'#127#255#248#28#127#255#248#30#127#255#252
-  +'?'#127#255#254#127#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255
-]);
-LazarusResources.Add('VT_MOVESW','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#15#255#255#255#255#255#0#0#0#0#0#0#0#0#0#0#15#0#0#0#0#240#0#0#0
-  +#0#0#0#0#0#0#0#15#0#0#0#15#0#0#0#0#0#0#0#0#0#0#0#15#0#0#0#240#0#0#0#0#0#0#0#0
-  +#0#0#0#15#0#0#15#0#0#0#0#0#0#0#0#0#0#0#0#15#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0
-  +#15#0#15#0#15#240#0#0#0#0#0#0#0#0#0#0#15#0#240#0#240#15#0#0#0#0#0#0#0#0#0#0
-  +#15#15#0#15#0#0#240#0#0#0#0#0#0#0#0#0#15#240#0#15#0#0#240#0#0#0#0#0#0#0#0#0
-  +#15#0#0#0#240#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254#0'?'#255#254
-  +#0#127#255#254#0#255#255#254#1#255#255#254#3#255#255#254#7#255#255#254#14#127
-  +#255#254#28'?'#255#254'8'#31#255#254'x'#31#255#254#252'?'#255#255#254#127#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_MOVEW','CUR',[
-  #0#0#2#0#1#0'  '#0#0#16#0#16#0#232#2#0#0#22#0#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1
-  +#0#4#0#0#0#0#0#128#2#0#0#0#0#0#0#0#0#0#0#16#0#0#0#0#0#0#0#0#0#0#0#0#0#128#0#0
-  +#128#0#0#0#128#128#0#128#0#0#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240
-  +#240#0#0#0#0#0#0#0#0#0#0#0#0#0#15#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#240#0#240#0
-  +#15#240#0#0#0#0#0#0#0#0#0#15#0#0#240#0#240#15#0#0#0#0#0#0#0#0#0#240#0#0#240
-  +#15#0#0#240#0#0#0#0#0#0#0#0#240#0#0#240#15#0#0#240#0#0#0#0#0#0#0#0#15#0#0#240
-  +#0#240#15#0#0#0#0#0#0#0#0#0#0#240#0#240#0#15#240#0#0#0#0#0#0#0#0#0#0#15#0#240
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#240#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#223#255#255#255#159#255#255#255#31#255#255#254
-  +#31#255#255#252#30#127#255#248#28'?'#255#240#24#31#255#240#24#31#255#248#28
-  +'?'#255#252#30#127#255#254#31#255#255#255#31#255#255#255#159#255#255#255#223
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-]);
-LazarusResources.Add('VT_XPBUTTONPLUS','BMP',[
-  'BM4'#1#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#9#0#0#0#9#0#0#0#1#0#24#0#0#0#0#0#0#0#0#0
-  +#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#211#194#176#181#152'x'#181#152'x'#181
-  +#152'x'#181#152'x'#181#152'x'#181#152'x'#181#152'x'#211#194#176#0#181#152'x'
-  +#191#204#210#174#190#198#168#184#194#167#184#193#167#184#193#166#183#192#170
-  +#186#195#181#152'x'#0#181#152'x'#217#225#228#207#216#220#201#211#216#0#0#0
-  +#198#209#214#192#204#210#187#200#207#181#152'x'#0#181#152'x'#238#242#242#236
-  +#240#240#231#237#237#0#0#0#227#233#234#217#224#227#204#214#219#181#152'x'#0
-  +#181#152'x'#241#245#245#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#210#219#223#181#152'x'
-  +#0#181#152'x'#245#247#247#245#247#247#244#247#247#0#0#0#244#246#246#235#240
-  +#241#218#225#229#181#152'x'#0#181#152'x'#251#252#252#251#253#253#251#253#253
-  +#0#0#0#251#252#252#250#252#252#243#246#247#181#152'x'#0#181#152'x'#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#181#152'x'#0#211#194#176#181#152'x'#181#152'x'#181#152'x'#181#152'x'#181#152
-  +'x'#181#152'x'#181#152'x'#211#194#176#0#0#0
-]);
-LazarusResources.Add('VT_XPBUTTONMINUS','BMP',[
-  'BM4'#1#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#9#0#0#0#9#0#0#0#1#0#24#0#0#0#0#0#0#0#0#0
-  +#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#211#194#176#181#152'x'#181#152'x'#181
-  +#152'x'#181#152'x'#181#152'x'#181#152'x'#181#152'x'#211#194#176#0#181#152'x'
-  +#191#204#210#174#190#198#168#184#194#167#184#193#167#184#193#166#183#192#170
-  +#186#195#181#152'x'#0#181#152'x'#217#225#228#207#216#220#201#211#216#199#210
-  +#215#198#209#214#192#204#210#187#200#207#181#152'x'#0#181#152'x'#238#242#242
-  +#236#240#240#231#237#237#230#235#236#227#233#234#217#224#227#204#214#219#181
-  +#152'x'#0#181#152'x'#241#245#245#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#210#219#223
-  +#181#152'x'#0#181#152'x'#245#247#247#245#247#247#244#247#247#244#247#247#244
-  +#246#246#235#240#241#218#225#229#181#152'x'#0#181#152'x'#251#252#252#251#253
-  +#253#251#253#253#251#253#253#251#252#252#250#252#252#243#246#247#181#152'x'#0
-  +#181#152'x'#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#181#152'x'#0#211#194#176#181#152'x'#181#152'x'#181#152
-  +'x'#181#152'x'#181#152'x'#181#152'x'#181#152'x'#211#194#176#0#0#0
-]);
-LazarusResources.Add('VT_CHECK_LIGHT','BMP',[
-  'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0
-  +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0
-  +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'""""""""""""""""""""""""""""""""""""""""""""""332"""""332"""""332"""""332""'
-  +'"""332"""""332"""""332"""""332"""#33332""#33332""#33332""#33332""#33332""#3'
-  +'3332""#33332""#33332""#33332""#33332""#33332""#33332"!DDDDDDB!DDDDDDB$'#17
-  +#17#17#17#17#17#18'!DDDDDDB""""""""""3'#17#17#19'""""3'#17#17#19'""""3333"""'
-  +'"3333""""3'#17#17#19'""""3'#17#17#19'""""3333""""3333"""4'#17#17#17#17#19'"'
-  +'"4'#17#17#17#17#19'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19
-  +'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333"!3'
-  +'33333B!333333B$333333'#18'!333333B"""""""""#A'#17#17#17'2""#A'#17#17#17'2""'
-  +'#C3332""#C3332""#A'#19'3'#17'2""#A'#19'3'#17'2""#C3332""#C3332""4'#17#17#17
-  +#17#19'""4'#17#17#17#17#19'""433333""433333""4'#20'A'#17'D'#19'""4'#20'A'#17
-  +'D'#19'""44C3D3""44C3D3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!333'
-  +'333B!333333B$333333'#18'!333333B"""""""""$'#17#17#17#17#19'""$'#17#17#17#17
-  +#19'""$33333""$33333""$'#17'DDA'#19'""$'#17'DDA'#19'""$3DDC3""$3DDC3""4'#17
-  +#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#20'D'#20'D'#19'""4'#20
-  +'D'#20'D'#19'""44D4D3""44D4D3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD'
-  +'3"!333333B!333333B$333'#3'33'#18'!333333B"""""""""4'#17#17#17#17#19'""4'#17
-  +#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43DDC3""43DDC'
-  +'3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17'DDA'#19'""'
-  +'4'#17'DDA'#19'""43DDC3""43DDC3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44D'
-  +'DD3"!330333B!330333B$330'#0'33'#18'!334333B"""""""""4'#17#17#17#17#19'""4'
-  +#17#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43DDC3""43'
-  +'DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17#20'D'#17
-  +#19'""4'#17#20'D'#17#19'""434D33""434D33""4'#20'DDD'#19'""4'#20'DDD'#19'""44'
-  +'DDD3""44DDD3"!33'#0#3'33B!33'#0#3'33B$33'#0#0#3'3'#18'!33DC33B"""""""""4'#17
-  +#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'
-  +#19'""43DDC3""43DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333'
-  +'""4'#17'DDA'#19'""4'#17'DDA'#19'""43DDC3""43DDC3""4'#20'DDD'#19'""4'#20'DDD'
-  +#19'""44DDD3""44DDD3"!30'#0#0'33B!30'#0#0'33B$30'#0#0#0'3'#18'!34DD33B""""""'
-  +'"""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17'DDA'#19'""'
-  +'4'#17'DDA'#19'""43DDC3""43DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433'
-  +'333""433333""4'#20'D'#20'D'#19'""4'#20'D'#20'D'#19'""44D4D3""44D4D3""4'#20
-  +'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!3'#0#0#0#3'3B!3'#0#0#0#3'3B$33333'
-  +'3'#18'!3DDDC3B"""""""""$1'#17#17#17'2""$1'#17#17#17'2""$33332""$33332""$1'
-  +#19'3'#17'2""$1'#19'3'#17'2""$33332""$33332""4'#17#17#17#17#19'""4'#17#17#17
-  +#17#19'""433333""433333""4'#20'A'#17'D'#19'""4'#20'A'#17'D'#19'""44C3D3""44C'
-  +'3D3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!333333B!333333B$333333'
-  +#18'!333333B"""""""""#C'#17#17#20'2""#C'#17#17#20'2""#C3342""#C3342""#C'#17
-  +#17#20'2""#C'#17#17#20'2""#C3342""#C3342""4'#17#17#17#17#19'""4'#17#17#17#17
-  +#19'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333'
-  +'""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333"!333333B!333333B$3'
-  +'33333'#18'!333333B""""""""""4DDC""""4DDC""""4DDC""""4DDC""""4DDC""""4DDC"""'
-  +'"4DDC""""4DDC"""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DD'
-  +'DDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC"!333333B!333333B$333333'#18'!333333B"""'
-  +'""""""""33""""""33""""""33""""""33""""""33""""""33""""""33""""""33""""#3333'
-  +'2""#33332""#33332""#33332""#33332""#33332""#33332""#33332""#33332""#33332""'
-  +'#33332""#33332"!'#17#17#17#17#17#17#18'!'#17#17#17#17#17#17#18'$DDDDDDB!'#17
-  +#17#17#17#17#17#18'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""'
-]);
-LazarusResources.Add('VT_CHECK_DARK','BMP',[
-  'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0
-  +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0
-  +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'""""""""""""""""""""""""""""""""""""""""""""""DDB"""""DDB"""""DDB"""""DDB""'
-  +'"""DDB"""""DDB"""""DDB"""""DDB"""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$D'
-  +'DDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB"!DDDDDDB!DDDDDDB$'#17
-  +#17#17#17#17#17#18'!DDDDDDB""""""""""D'#17#17#20'""""D'#17#17#20'""""D334"""'
-  +'"D334""""D'#17#17#20'""""D'#17#17#20'""""D334""""D334"""@'#17#17#17#17#20'"'
-  +'"@'#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20
-  +'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334"!3'
-  +'33333B!333333B$333333'#18'!333333B"""""""""$'#1#17#17#17'B""$'#1#17#17#17'B'
-  +'""$'#3'333B""$'#3'333B""$'#1#20'D'#17'B""$'#1#20'D'#17'B""$'#3'4D3B""$'#3'4'
-  +'D3B""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#16#1#17#0#20
-  +'""@'#16#1#17#0#20'""@0'#3'3'#0'4""@0'#3'3'#0'4""@'#16#0#0#0#20'""@'#16#0#0#0
-  +#20'""@0'#0#0#0'4""@4DDD4"!333333B!333333B$333333'#18'!333333B""""""""" '#17
-  +#17#17#17#20'"" '#17#17#17#17#20'"" 33334"" 33334"" '#17#0#0#1#20'"" '#17#0#0
-  +#1#20'"" 3'#0#0#3'4"" 3'#0#0#3'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@3'
-  +'3334""@33334""@'#16#0#16#0#20'""@'#16#0#16#0#20'""@0'#0'0'#0'4""@0'#0'0'#0
-  +'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!333333B!333333B$3'
-  +'33'#3'33'#18'!333333B"""""""""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@3333'
-  +'4""@33334""@'#20#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4""@4'#0#0#4'4""@'#17
-  +#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#0#0#1#20'""@'#17#0#0
-  +#1#20'""@3'#0#0#3'4""@3'#0#0#3'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0
-  +'4""@4DDD4"!330333B!330333B$330'#0'33'#18'!334333B"""""""""@'#17#17#17#17#20
-  +'""@'#17#17#17#17#20'""@33334""@33334""@'#20#0#0#4#20'""@'#20#0#0#4#20'""@4'
-  +#0#0#4'4""@4'#0#0#4'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@3333'
-  +'4""@'#17#16#0#17#20'""@'#17#16#0#17#20'""@30'#0'34""@30'#0'34""@'#16#0#0#0
-  +#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!33'#0#3'33B!33'#0#3'33B$33'#0#0#3
-  +'3'#18'!33DC33B"""""""""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@333'
-  +'34""@'#20#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4""@4'#0#0#4'4""@'#17#17#17
-  +#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#0#0#1#20'""@'#17#0#0#1#20
-  +'""@3'#0#0#3'4""@3'#0#0#3'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""'
-  +'@4DDD4"!30'#0#0'33B!30'#0#0'33B$30'#0#0#0'3'#18'!34DD33B"""""""""@'#17#17#17
-  +#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#0#0#1#20'""@'#17#0#0#1#20
-  +'""@3'#0#0#3'4""@3'#0#0#3'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334"'
-  +'"@33334""@'#16#0#16#0#20'""@'#16#0#16#0#20'""@0'#0'0'#0'4""@0'#0'0'#0'4""@'
-  +#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!3'#0#0#0#3'3B!3'#0#0#0#3
-  +'3B$333333'#18'!3DDDC3B""""""""" A'#17#17#17'B"" A'#17#17#17'B"" C333B"" C33'
-  +'3B"" A'#20'D'#17'B"" A'#20'D'#17'B"" C4D3B"" C4D3B""@'#17#17#17#17#20'""@'
-  +#17#17#17#17#20'""@33334""@33334""@'#16#1#17#0#20'""@'#16#1#17#0#20'""@0'#3
-  +'3'#0'4""@0'#3'3'#0'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4'
-  +'"!333333B!333333B$333333'#18'!333333B"""""""""$'#4#17#17#16'B""$'#4#17#17#16
-  +'B""$'#4'330B""$'#4'330B""$'#4#17#17#16'B""$'#4#17#17#16'B""$'#4'330B""$'#4
-  +'330B""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17
-  +#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17
-  +#20'""@33334""@33334"!333333B!333333B$333333'#18'!333333B""""""""""@'#0#0#4
-  +'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0
-  +#4'""""@'#0#0#4'"""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4
-  +'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4
-  +'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'"!333333B!333333B$333333'#18'!'
-  +'333333B"""""""""""DD""""""DD""""""DD""""""DD""""""DD""""""DD""""""DD""""""D'
-  +'D""""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB'
-  +'""$DDDDB""$DDDDB""$DDDDB"!'#17#17#17#17#17#17#18'!'#17#17#17#17#17#17#18'$D'
-  +'DDDDDB!'#17#17#17#17#17#17#18'"""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  ,'"""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-]);
-LazarusResources.Add('VT_FLAT','BMP',[
-  'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0
-  +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0
-  +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'""""""""""""""""""""""""""""""""""""""""""""""'#0#0'""""""'#0#0'""""""'#0#0
-  +'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'""" '#0#0#0#0#0
-  +#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0
-  +#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0
-  +#0#0#0#0#0'" '#0#0#0#0#0#0'""'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0
-  +#2'"'#0#0#0#0#0#0#2'""""""""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0
-  +#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'"" '#0#0#0#0#0#0
-  +'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0
-  +#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0
-  +#0#0#0#0'" '#0#0#0#0#0#0'""'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0'33333'#2'"'
-  +#0#0#0#0#0#0#2'""""""""" '#0#17#17#0#2'"" '#0#17#17#0#2'"" '#0'33'#0#2'"" '#0
-  +'33'#0#2'"" '#0#17#17#0#2'"" '#0#17#17#0#2'"" '#0'33'#0#2'"" '#0'33'#0#2'" '
-  +#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#17
-  +#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#17#17#17#0
-  +'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'""'#0#17#17#17#17#16#2'"'#0
-  +#17#17#17#17#16#2'"'#0#17#17#17#17#19#2'"'#0'33330'#2'""""""""" '#1#17#17#16
-  +#2'"" '#1#17#17#16#2'"" '#3'330'#2'"" '#3'330'#2'"" '#1#17#17#16#2'"" '#1#17
-  +#17#16#2'"" '#3'330'#2'"" '#3'330'#2'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0
-  +'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#1#17#17#0'" '#1#17#1#17#17#0'" '#3'3'#3
-  +'33'#0'" '#3'3'#3'33'#0'" '#1#0#0#0#1#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3
-  +'DDDC'#0'""'#0#17#17#17#17#16#2'"'#0#17#17#17#17#16#2'"'#0#17#17#17#17#19#2
-  +'"'#0'33330'#2'"""""""""'#0#17#17#17#17#0'""'#0#17#17#17#17#0'""'#0'3333'#0
-  +'""'#0'3333'#0'""'#0#17#16#1#17#0'""'#0#17#16#1#17#0'""'#0'30'#3'3'#0'""'#0
-  +'30'#3'3'#0'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'
-  +#0'" '#1#16#0#17#17#0'" '#1#16#0#17#17#0'" '#3'0'#0'33'#0'" '#3'0'#0'33'#0'"'
-  +' '#1#0#0#0#1#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0'""'#0#17#17#1
-  +#17#16#2'"'#0#17#17#1#17#16#2'"'#0#17#17#1#17#19#2'"'#0'33'#3'30'#2'""""""""'
-  +'"'#0#17#17#17#17#0'""'#0#17#17#17#17#0'""'#0'3333'#0'""'#0'3333'#0'""'#0#17
-  +#0#0#17#0'""'#0#17#0#0#17#0'""'#0'3'#0#0'3'#0'""'#0'3'#0#0'3'#0'" '#1#17#17
-  +#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#0#0#1#17#0'" '
-  +#1#0#0#1#17#0'" '#3#0#0#3'3'#0'" '#3#0#0#3'3'#0'" '#1#0#0#0#1#0'" '#1#0#0#0#1
-  +#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0'""'#0#17#16#0#17#16#2'"'#0#17#16#0#17#16#2
-  +'"'#0#17#16#0#17#19#2'"'#0'30'#0'30'#2'"""""""""'#0#17#17#17#17#0'""'#0#17#17
-  +#17#17#0'""'#0'3333'#0'""'#0'3333'#0'""'#0#17#0#0#17#0'""'#0#17#0#0#17#0'""'
-  +#0'3'#0#0'3'#0'""'#0'3'#0#0'3'#0'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '
-  +#3'3333'#0'" '#3'3333'#0'" '#1#0#16#0#17#0'" '#1#0#16#0#17#0'" '#3#0'0'#0'3'
-  +#0'" '#3#0'0'#0'3'#0'" '#1#0#0#0#1#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3'D'
-  +'DDC'#0'""'#0#17#0#0#1#16#2'"'#0#17#0#0#1#16#2'"'#0#17#0#0#1#19#2'"'#0'3'#0#0
-  +#3'0'#2'"""""""""'#0#17#17#17#17#0'""'#0#17#17#17#17#0'""'#0'3333'#0'""'#0'3'
-  +'333'#0'""'#0#17#16#1#17#0'""'#0#17#16#1#17#0'""'#0'30'#3'3'#0'""'#0'30'#3'3'
-  +#0'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1
-  +#1#17#0#1#0'" '#1#1#17#0#1#0'" '#3#3'3'#0#3#0'" '#3#3'3'#0#3#0'" '#1#0#0#0#1
-  +#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0'""'#0#16#0#0#0#16#2'"'#0#16
-  +#0#0#0#16#2'"'#0#16#0#0#0#19#2'"'#0'0'#0#0#0'0'#2'""""""""" '#1#17#17#16#2'"'
-  +'" '#1#17#17#16#2'"" '#3'330'#2'"" '#3'330'#2'"" '#1#17#17#16#2'"" '#1#17#17
-  +#16#2'"" '#3'330'#2'"" '#3'330'#2'" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '
-  +#3'3333'#0'" '#3'3333'#0'" '#1#17#17#16#1#0'" '#1#17#17#16#1#0'" '#3'330'#3#0
-  +'" '#3'330'#3#0'" '#1#0#0#0#1#0'" '#1#0#0#0#1#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0
-  +'""'#0#17#17#17#17#16#2'"'#0#17#17#17#17#16#2'"'#0#17#17#17#17#19#2'"'#0'333'
-  +'30'#2'""""""""" '#0#17#17#0#2'"" '#0#17#17#0#2'"" '#0'33'#0#2'"" '#0'33'#0#2
-  +'"" '#0#17#17#0#2'"" '#0#17#17#0#2'"" '#0'33'#0#2'"" '#0'33'#0#2'" '#1#17#17
-  +#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#17#17#1#0
-  +'" '#1#17#17#17#1#0'" '#3'333'#3#0'" '#3'333'#3#0'" '#1#0#0#0#1#0'" '#1#0#0#0
-  +#1#0'" '#3#0#0#0#3#0'" '#3'DDDC'#0'""'#0#17#17#17#17#16#2'"'#0#17#17#17#17#16
-  +#2'"'#0#17#17#17#17#19#2'"'#0'33330'#2'""""""""""'#0#0#0#0'""""'#0#0#0#0'"""'
-  ,'"'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0#0#0'""""'#0#0
-  +#0#0'"" '#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '
-  +#1#17#17#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'" '#1#17#17
-  +#17#17#0'" '#1#17#17#17#17#0'" '#3'3333'#0'" '#3'3333'#0'""'#0#17#17#17#17#16
-  +#2'"'#0#17#17#17#17#16#2'"'#0#17#17#17#17#19#2'"'#0'33330'#2'"""""""""""'#0#0
-  +'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'""""""'#0#0'"""'
-  +'"""'#0#0'""" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0
-  +'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0
-  +#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'""'#0#0#0#0#0#0#2'"'#0#0
-  +#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"""""""""""""""""""""""""""""""'
-  +'""""""""""""""""""""""""""""""""""""""""" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '
-  +#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0
-  +'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0#0#0'" '#0#0#0#0
-  +#0#0'""'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'"'#0#0#0#0#0#0#2'""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'""""""""""""""""""""""""""""""""""""""""""""""""'
-]);
-LazarusResources.Add('VT_TICK_DARK','BMP',[
-  'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0
-  +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0
-  +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'""""""""""""""""""""""""""""""""""""""""""""""DDB"""""DDB"""""DDB"""""DDB""'
-  +'"""DDB"""""DDB"""""DDB"""""DDB"""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$D'
-  +'DDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB"!DDDDDDB!DDDDDDB$'#17
-  +#17#17#17#17#17#18'!DDDDDDB""""""""""D'#17#17#20'""""D'#17#17#20'""""D334"""'
-  +'"D334""""D'#17#17#20'""""D'#17#17#20'""""D334""""D334"""@'#17#17#17#17#20'"'
-  +'"@'#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20
-  +'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334"!3'
-  +'33333B!333333B$333333'#18'!333333B"""""""""$'#1#17#17#17'B""$'#1#17#17#17'B'
-  +'""$'#3'333B""$'#3'333B""$'#1#20'D'#17'B""$'#1#20'D'#17'B""$'#3'4D3B""$'#3'4'
-  +'D3B""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17#16#17#17
-  +#20'""@'#17#16#17#17#20'""@30334""@30334""@'#16#0#0#0#20'""@'#16#0#0#0#20'""'
-  +'@0'#0#0#0'4""@4DDD4"!333333B!333333B$333333'#18'!333333B""""""""" '#17#17#17
-  +#17#20'"" '#17#17#17#17#20'"" 33334"" 33334"" '#17#0#0#1#20'"" '#17#0#0#1#20
-  +'"" 3'#0#0#3'4"" 3'#0#0#3'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334"'
-  +'"@33334""@'#17#0#1#17#20'""@'#17#0#1#17#20'""@3'#0#3'34""@3'#0#3'34""@'#16#0
-  +#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!333333B!333333B$333'#3'33'#18
-  +'!333333B"""""""""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'
-  +#20#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4""@4'#0#0#4'4""@'#17#17#17#17#20
-  +'""@'#17#17#17#17#20'""@33334""@33334""@'#16#0#0#17#20'""@'#16#0#0#17#20'""@'
-  +'0'#0#0'34""@0'#0#0'34""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD'
-  +'4"!330333B!330333B$330'#0'33'#18'!334333B"""""""""@'#17#17#17#17#20'""@'#17
-  +#17#17#17#20'""@33334""@33334""@'#20#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4'
-  +'""@4'#0#0#4'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#16
-  +#1#0#1#20'""@'#16#1#0#1#20'""@0'#3#0#3'4""@0'#3#0#3'4""@'#16#0#0#0#20'""@'#16
-  +#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!33'#0#3'33B!33'#0#3'33B$33'#0#0#3'3'#18'!33'
-  +'DC33B"""""""""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#20
-  +#0#0#4#20'""@'#20#0#0#4#20'""@4'#0#0#4'4""@4'#0#0#4'4""@'#17#17#17#17#20'""@'
-  +#17#17#17#17#20'""@33334""@33334""@'#17#17#16#0#20'""@'#17#17#16#0#20'""@330'
-  +#0'4""@330'#0'4""@'#16#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!30'#0
-  +#0'33B!30'#0#0'33B$30'#0#0#0'3'#18'!34DD33B"""""""""@'#17#17#17#17#20'""@'#17
-  +#17#17#17#20'""@33334""@33334""@'#17#0#0#1#20'""@'#17#0#0#1#20'""@3'#0#0#3'4'
-  +'""@3'#0#0#3'4""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334""@'#17
-  +#17#17#0#20'""@'#17#17#17#0#20'""@333'#0'4""@333'#0'4""@'#16#0#0#0#20'""@'#16
-  +#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!3'#0#0#0#3'3B!3'#0#0#0#3'3B$333333'#18'!3DD'
-  +'DC3B""""""""" A'#17#17#17'B"" A'#17#17#17'B"" C333B"" C333B"" A'#20'D'#17'B'
-  +'"" A'#20'D'#17'B"" C4D3B"" C4D3B""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@'
-  +'33334""@33334""@'#17#17#17#16#20'""@'#17#17#17#16#20'""@33304""@33304""@'#16
-  +#0#0#0#20'""@'#16#0#0#0#20'""@0'#0#0#0'4""@4DDD4"!333333B!333333B$333333'#18
-  +'!333333B"""""""""$'#4#17#17#16'B""$'#4#17#17#16'B""$'#4'330B""$'#4'330B""$'
-  +#4#17#17#16'B""$'#4#17#17#16'B""$'#4'330B""$'#4'330B""@'#17#17#17#17#20'""@'
-  +#17#17#17#17#20'""@33334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@3'
-  +'3334""@33334""@'#17#17#17#17#20'""@'#17#17#17#17#20'""@33334""@33334"!33333'
-  +'3B!333333B$333333'#18'!333333B""""""""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4
-  +'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'""""@'#0#0#4'"""@'#0#0#0
-  +#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0
-  +#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4'""@'#0#0#0#0#4
-  +'""@'#0#0#0#0#4'"!333333B!333333B$333333'#18'!333333B"""""""""""DD""""""DD""'
-  +'""""DD""""""DD""""""DD""""""DD""""""DD""""""DD""""$DDDDB""$DDDDB""$DDDDB""$'
-  +'DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB""$DDDDB"!'#17
-  +#17#17#17#17#17#18'!'#17#17#17#17#17#17#18'$DDDDDDB!'#17#17#17#17#17#17#18'"'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  ,'""""""""""""""""""""""""'
-]);
-LazarusResources.Add('VT_TICK_LIGHT','BMP',[
-  'BM'#246#12#0#0#0#0#0#0'v'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#4#0#0#0#0#0
-  +#128#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0#255#0#255#0
-  +#192#192#192#0#128#128#128#0#128#0#128#0#128#128#0#0#192#192#192#0#128#128
-  +#128#0#0#0#255#0#0#255#0#0#0#255#255#0#255#0#0#0#255#0#255#0#255#255#0#0#255
-  +#255#255#0'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'""""""""""""""""""""""""""""""""""""""""""""""332"""""332"""""332"""""332""'
-  +'"""332"""""332"""""332"""""332"""#33332""#33332""#33332""#33332""#33332""#3'
-  +'3332""#33332""#33332""#33332""#33332""#33332""#33332"!DDDDDDB!DDDDDDB$'#17
-  +#17#17#17#17#17#18'!DDDDDDB""""""""""3'#17#17#19'""""3'#17#17#19'""""3333"""'
-  +'"3333""""3'#17#17#19'""""3'#17#17#19'""""3333""""3333"""4'#17#17#17#17#19'"'
-  +'"4'#17#17#17#17#19'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19
-  +'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333"!3'
-  +'33333B!333333B$333333'#18'!333333B"""""""""#A'#17#17#17'2""#A'#17#17#17'2""'
-  +'#C3332""#C3332""#A'#19'3'#17'2""#A'#19'3'#17'2""#C3332""#C3332""4'#17#17#17
-  +#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17#20#17#17#19'""4'#17#20#17
-  +#17#19'""434333""434333""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!333'
-  +'333B!333333B$333333'#18'!333333B"""""""""$'#17#17#17#17#19'""$'#17#17#17#17
-  +#19'""$33333""$33333""$'#17'DDA'#19'""$'#17'DDA'#19'""$3DDC3""$3DDC3""4'#17
-  +#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17'DA'#17#19'""4'#17'D'
-  +'A'#17#19'""43DC33""43DC33""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!'
-  +'333333B!333333B$333'#3'33'#18'!333333B"""""""""4'#17#17#17#17#19'""4'#17#17
-  +#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43DDC3""43DDC3""'
-  +'4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#20'DD'#17#19'""4'
-  +#20'DD'#17#19'""44DD33""44DD33""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DD'
-  +'D3"!330333B!330333B$330'#0'33'#18'!334333B"""""""""4'#17#17#17#17#19'""4'#17
-  +#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43DDC3""43DDC'
-  +'3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#20'ADA'#19'""'
-  +'4'#20'ADA'#19'""44CDC3""44CDC3""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44D'
-  +'DD3"!33'#0#3'33B!33'#0#3'33B$33'#0#0#3'3'#18'!33DC33B"""""""""4'#17#17#17#17
-  +#19'""4'#17#17#17#17#19'""433333""433333""4'#19'DDC'#19'""4'#19'DDC'#19'""43'
-  +'DDC3""43DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17
-  +#17#20'D'#19'""4'#17#17#20'D'#19'""4334D3""4334D3""4'#20'DDD'#19'""4'#20'DDD'
-  +#19'""44DDD3""44DDD3"!30'#0#0'33B!30'#0#0'33B$30'#0#0#0'3'#18'!34DD33B""""""'
-  +'"""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333""4'#17'DDA'#19'""'
-  +'4'#17'DDA'#19'""43DDC3""43DDC3""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433'
-  +'333""433333""4'#17#17#17'D'#19'""4'#17#17#17'D'#19'""4333D3""4333D3""4'#20
-  +'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!3'#0#0#0#3'3B!3'#0#0#0#3'3B$33333'
-  +'3'#18'!3DDDC3B"""""""""$1'#17#17#17'2""$1'#17#17#17'2""$33332""$33332""$1'
-  +#19'3'#17'2""$1'#19'3'#17'2""$33332""$33332""4'#17#17#17#17#19'""4'#17#17#17
-  +#17#19'""433333""433333""4'#17#17#17#20#19'""4'#17#17#17#20#19'""433343""433'
-  +'343""4'#20'DDD'#19'""4'#20'DDD'#19'""44DDD3""44DDD3"!333333B!333333B$333333'
-  +#18'!333333B"""""""""#C'#17#17#20'2""#C'#17#17#20'2""#C3342""#C3342""#C'#17
-  +#17#20'2""#C'#17#17#20'2""#C3342""#C3342""4'#17#17#17#17#19'""4'#17#17#17#17
-  +#19'""433333""433333""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333'
-  +'""4'#17#17#17#17#19'""4'#17#17#17#17#19'""433333""433333"!333333B!333333B$3'
-  +'33333'#18'!333333B""""""""""4DDC""""4DDC""""4DDC""""4DDC""""4DDC""""4DDC"""'
-  +'"4DDC""""4DDC"""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC""4DD'
-  +'DDC""4DDDDC""4DDDDC""4DDDDC""4DDDDC"!333333B!333333B$333333'#18'!333333B"""'
-  +'""""""""33""""""33""""""33""""""33""""""33""""""33""""""33""""""33""""#3333'
-  +'2""#33332""#33332""#33332""#33332""#33332""#33332""#33332""#33332""#33332""'
-  +'#33332""#33332"!'#17#17#17#17#17#17#18'!'#17#17#17#17#17#17#18'$DDDDDDB!'#17
-  +#17#17#17#17#17#18'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'
-  +'"""""""""""""""""""""""""""""""""""""""""""'
-]);
-LazarusResources.Add('VT_UTILITIES','BMP',[
-  'BM6'#13#0#0#0#0#0#0'6'#4#0#0'('#0#0#0#144#0#0#0#16#0#0#0#1#0#8#0#0#0#0#0#0#0
-  +#0#0#19#11#0#0#19#11#0#0#0#1#0#0#0#1#0#0'www'#255'%r'#207#255'*u'#208#255#255
-  +#0#255#255#246#24#248#255#225'V'#232#255'O'#145#227#255'X'#150#227#255#134
-  +#134#134#255#140#140#140#255#147#147#147#255#154#154#154#255#190#190#190#255
-  +#184#199#203#255#197#197#197#255#204#204#204#255#195#210#213#255#221#221#221
-  +#255#240#251#255#255#255#255#255#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
-  +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
-  +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
-  +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#17#15#14#14#14#15#17#3#3#3#3#3
-  +#3#3#3#3#17#15#14#14#14#15#17#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#17#12#11#9#9#9#11#12#17#3#3#3#3#3#3
-  +#3#17#12#11#9#9#9#11#12#17#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#17#12#18#18#18#18#18#0#10#12#17#3#3#3#3#3
-  +#17#12#18#18#18#18#18#0#10#12#17#3#3#3#3#3#3#3#3#3#3#19#3#3#3#3#3#3#3#3#3#3#3
-  +#19#19#19#19#19#19#19#19#19#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#15#18#18#18#18#8#18#18#0#11#15
-  +#3#3#3#3#3#15#18#18#8#18#18#18#18#0#11#15#3#3#3#3#3#3#3#3#3#8#14#19#3#3#3#3#3
-  +#3#3#3#3#3#3#8#14#14#14#14#14#19#3#3#3#3#3#3#3#3#3#3#3#3#11#3#3#3#3#3#3#3#3#3
-  +#3#3#11#11#11#11#11#11#11#11#11#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#18#8
-  +#8#18#18#18#9#14#3#3#3#3#3#18#18#18#8#8#18#18#18#18#9#14#3#3#3#3#3#3#3#3#3#8
-  +#14#19#3#3#3#3#3#3#3#3#3#3#3#8#14#14#14#14#14#19#3#3#3#3#3#3#3#3#3#3#3#11#11
-  +#11#3#3#3#3#3#3#3#3#3#3#3#11#11#11#11#11#11#11#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  ,#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#18#18#18#8#8#8#18#18#18#9#14#3#3#3#3#3#18#18#18#8#8#8#18#18#18#9#14#3#3
-  +#3#3#3#3#3#3#8#14#14#14#19#3#3#3#3#3#3#3#3#3#3#3#8#14#14#14#19#3#3#3#3#3#3#3
-  +#3#3#3#3#11#11#11#11#11#3#3#3#3#3#3#3#3#3#3#3#11#11#11#11#11#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#18#18#8#8#8#8#18#18#18#9#14#3#3#3#3#3#18#18#18#8#8#8#8
-  +#18#18#9#14#3#3#3#3#3#3#3#3#8#14#14#14#19#3#3#3#3#3#3#3#3#3#3#3#8#14#14#14#19
-  +#3#3#3#3#3#3#3#3#3#3#11#11#11#11#11#11#11#3#3#3#3#3#3#3#3#3#3#3#11#11#11#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#8#8#8#18#18#18#11#15#3#3#3#3#3#18
-  +#18#18#8#8#8#18#18#18#11#15#3#3#3#3#3#3#3#8#14#14#14#14#14#19#3#3#3#3#3#3#3#3
-  +#3#3#3#8#14#19#3#3#3#3#3#3#3#3#3#3#11#11#11#11#11#11#11#11#11#3#3#3#3#3#3#3#3
-  +#3#3#3#11#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#18#8#8#18#18#18#12
-  +#17#3#3#3#3#3#18#18#18#8#8#18#18#18#18#12#17#3#3#3#3#3#3#3#8#14#14#14#14#14
-  +#19#3#3#3#3#3#3#3#3#3#3#3#8#14#19#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#18#8#18
-  +#18#12#17#3#3#3#3#3#3#3#18#18#8#18#18#18#18#12#17#3#3#3#3#3#3#3#8#8#8#8#8#8#8
-  +#8#19#3#3#3#3#3#3#3#3#3#3#3#19#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#18#18#18#18#18
-  +#15#17#3#3#3#3#3#3#3#3#3#18#18#18#18#18#15#17#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#4#5#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#13#13#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1
-  +#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#13#13#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#16#1#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6#6
-  +#6#6#6#6#6#6#6#6#2#16#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3
-  +#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#1#6#7#7#7#7#7#7
-  +#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7#7
-  +#6#1
-]);
-LazarusResources.Add('VT_XP','BMP',[
-  'BM8K'#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#144#1#0#0#16#0#0#0#1#0#24#0#0#0#0#0#0#0#0
-  +#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#238#231#223#233#224#214#231#221#211
-  +#233#224#214#238#231#223#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#238#231#223#233
-  +#224#214#231#221#211#233#224#214#238#231#223#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#238#231#223#233#224#214#231#221#211#233#224#214#238#231#223#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  ,#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#238#231#223#233#224#214#231#221#211#233
-  +#224#214#238#231#223#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#238#231#223#233#224
-  +#214#231#221#211#233#224#214#238#231#223#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#238#231#223#233#224#214#231#221#211#233#224#214#238#231#223#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#225#217#237'_'#140'y#oL'#6'b7'#6
-  +'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#24'iDX'#138't'#238#244#250#255
-  +#0#255#236#216#223'_'#140'y#oL'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6
-  +'b7'#6'b7'#24'iDX'#138't'#248#241#243#255#0#255#225#217#237'_'#140'y#oL'#6'b'
-  +'7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#24'iDX'#138't'#238#244
-  +#250#255#0#255#255#255#255#184#196#202#184#196#202#184#196#202#184#196#202
-  +#184#196#202#184#196#202#184#196#202#184#196#202#184#196#202#184#196#202#184
-  +#196#202#184#196#202#184#196#202#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#226#214#201#220#206#191#217#202#186#216#201#184#217#202#186#220
-  +#206#191#226#214#201#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#224#212#198#217#201#185#213#196#178#211
-  +#194#175#213#196#178#217#201#185#224#212#198#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#226#214#201#220
-  +#206#191#217#202#186#216#201#184#217#202#186#220#206#191#226#214#201#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#226#214#201#220#206#191#217#202#186#216#201#184#217#202
-  +#186#220#206#191#226#214#201#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#226#214#201#220#206#191#217#202
-  +#186#216#201#184#217#202#186#220#206#191#226#214#201#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#226#214
-  +#201#220#206#191#217#202#186#216#201#184#217#202#186#220#206#191#226#214#201
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  ,#255'V'#17#0'V'#17#0'U'#19#0'U'#16#0'V'#17#0'R'#14#1'W'#16#2'T'#18#0'U'#15#2
-  +'U'#16#0'W'#18#0'T'#18#0'V'#17#0#255#0#255#255#0#255#255#0#255'W'#19#0'W'#18
-  +#1'Y'#19#2'^'#18#0'W'#20#0'V'#18#0'W'#18#1'V'#17#0'W'#19#0'X'#17#3'U'#21#0'Z'
-  +#21#2'X'#18#1#255#0#255#255#0#255#255#0#255'V'#19#0'T'#19#4'W'#18#1'W'#18#1
-  +'Z'#18#0'X'#19#0'W'#17#0'W'#18#0'Z'#18#1'X'#19#0'V'#22#0'W'#18#0'X'#20#1#255
-  +#0#255#255#0#255#255#0#255#168#183#185#170#183#185#171#184#186#169#184#186
-  +#168#183#185#170#183#185#169#182#184#168#183#185#169#184#187#170#183#185#171
-  +#184#186#168#183#185#168#183#185#255#0#255#255#0#255#255#0#255'W'#18#0'U'#18
-  +#3'R'#19#0'V'#18#0'U'#19#0'U'#15#0'U'#19#0'T'#18#0'S'#17#0'Y'#17#0'T'#18#0'U'
-  +#16#1'V'#19#0#255#0#255#255#0#255#255#0#255'U'#17#4'Y'#20#0'W'#20#0'Y'#16#2
-  +'U'#17#0'Z'#17#3'V'#15#1'Z'#19#0'U'#19#1'U'#17#0'X'#18#1'X'#20#1'Y'#17#0#255
-  +#0#255#255#0#255#255#0#255'X'#19#0'U'#19#0'X'#18#1'W'#20#0'U'#16#1'X'#19#0'X'
-  +#18#1'U'#19#0'Y'#17#0'X'#21#0'V'#18#0'U'#19#0'Y'#20#1#255#0#255#255#0#255#255
-  +#0#255#168#183#185#170#183#185#171#183#183#170#183#185#171#184#186#169#182
-  +#184#170#183#185#169#185#184#169#182#184#170#183#185#168#183#185#167#182#184
-  +#170#183#185#255#0#255#255#0#255#255#0#255'W'#18#0'U'#18#3'R'#19#0'V'#18#0'U'
-  +#19#0'U'#15#0'U'#19#0'T'#18#0'S'#17#0'Y'#17#0'T'#18#0'U'#16#1'V'#19#0#255#0
-  +#255#255#0#255#255#0#255'U'#17#4'Y'#20#0'W'#20#0'Y'#16#2'U'#17#0'Z'#17#3'V'
-  +#15#1'Z'#19#0'U'#19#1'U'#17#0'X'#18#1'X'#20#1'Y'#17#0#255#0#255#255#0#255#255
-  +#0#255'X'#19#0'U'#19#0'X'#18#1'W'#20#0'U'#16#1'X'#19#0'X'#18#1'U'#19#0'Y'#17
-  +#0'X'#21#0'V'#18#0'U'#19#0'Y'#20#1#255#0#255#255#0#255#255#0#255#168#183#185
-  +#170#183#185#171#183#183#170#183#185#171#184#186#169#182#184#170#183#185#169
-  +#185#184#169#182#184#170#183#185#168#183#185#167#182#184#170#183#185#255#0
-  +#255#255#0#255#255#0#255'N'#131'lD}c'#152#178#199#184#209#227#184#209#227#184
-  +#209#227#184#209#227#184#209#227#184#209#227#184#209#227#183#209#226#182#208
-  +#226#164#177#201'B|aU'#136'r'#255#0#255'N'#131'ludu%r'#207'%r'#207'%r'#207'%'
-  +'r'#207'%r'#207'%r'#207'%r'#207'%r'#207'%r'#207'%r'#207'%r'#207'rbsU'#136'r'
-  +#255#0#255'N'#131'lG'#130'f'#166#203#216#226#243#246#228#244#248#228#244#248
-  +#228#244#248#228#244#248#228#244#248#228#244#248#228#245#248#229#245#248#190
-  +#218#228'H'#132'iU'#136'r'#255#0#255#184#196#202#201#211#217#221#231#235#233
-  +#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242
-  +#246#233#242#246#233#242#246#225#235#239#201#211#217#184#196#202#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#223#210#196#185#153#131#154'jN'#129'D#q,'#8#129'D#'#154
-  +'jN'#185#153#131#223#210#196#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#220#205#190#181#147'{'#151'eH'#127'A'#31'q,'#7#127
-  +'A'#31#151'eH'#181#147'{'#220#205#190#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#223#210#196#185#153#131#154'jN'#129'D#q,'#8
-  +#129'D#'#154'jN'#185#153#131#223#210#196#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#213#221#222#197#208
-  +#210#188#200#203#197#208#210#213#221#222#233#237#238#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#223#210#196#185#153
-  +#131#154'jN'#129'D#q,'#8#129'D#'#154'jN'#185#153#131#223#210#196#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#223#210#196#185
-  +#153#131#154'jN'#129'D#q,'#8#129'D#'#154'jN'#185#153#131#223#210#196#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#223#210#196
-  +#185#153#131#154'jN'#129'D#q,'#8#129'D#'#154'jN'#185#153#131#223#210#196#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#208#216#215#190#201#199#180#192#190#190#201#199#208#216#215#230
-  +#234#234#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255'V'#17#0#244#249#247#248#247#251#248#248#248#248#248#248#251#249#249#247
-  +#248#246#248#248#248#247#249#249#248#248#248#245#247#248#248#247#249'V'#17#0
-  +#255#0#255#255#0#255#255#0#255'U'#20#0#136#195#251#132#193#249#130#194#248
-  +#135#195#249#135#195#249#132#199#244#138#195#250#132#196#244#136#191#252#130
-  +#195#246#132#197#248'X'#20#0#255#0#255#255#0#255#255#0#255'Z'#18#0#201#210
-  +#213#197#211#210#198#210#210#198#210#214#196#208#208#198#212#211#198#209#213
-  +#199#211#213#198#209#213#197#211#210#200#213#211'V'#20#2#255#0#255#255#0#255
-  +#255#0#255#167#182#184#226#239#241#227#239#241#225#238#240#225#238#240#225
-  +#237#239#226#239#241#225#238#240#225#238#240#226#238#240#226#238#240#227#240
-  +#242#169#182#184#255#0#255#255#0#255#255#0#255'V'#17#0#251#249#248#250#248
-  +#247#245#247#247#244#250#245#248#249#247#250#248#248#248#247#249#247#249#250
-  +#247#246#248#250#248#247#249#247#246'V'#17#2#255#0#255#255#0#255#255#0#255'X'
-  +#18#1#133#196#246#130#194#249#132#195#245#137#196#246#138#196#248#135#198#248
-  ,#132#197#248#136#196#250#133#192#248#136#196#250#132#195#246'Z'#20#0#255#0
-  +#255#255#0#255#255#0#255'W'#18#1#197#213#212#198#210#216#197#210#208#199#210
-  +#214#199#211#213#196#208#212#200#210#210#192#210#209#197#209#211#200#211#215
-  +#199#211#213'X'#18#1#255#0#255#255#0#255#255#0#255#170#183#185#227#239#239
-  +#227#237#237#226#238#238#226#238#240#227#239#241#225#237#239#226#240#239#227
-  +#239#241#227#239#241#225#238#240#226#239#241#171#184#186#255#0#255#255#0#255
-  +#255#0#255'V'#17#0#251#249#248#250#248#247#245#247#247#244#250#245#248#249
-  +#247#250#248#248#248#247#249#247#249#250#247#246#248#250#248#247#249#247#246
-  +'V'#17#2#255#0#255#255#0#255#255#0#255'X'#18#1#133#196#246#130#194#249#132
-  +#195#245#137#196#246#138#196#248#135#198#248#132#197#248#136#196#250#133#192
-  +#248#136#196#250#132#195#246'Z'#20#0#255#0#255#255#0#255#255#0#255'W'#18#1
-  +#197#213#212#198#210#216#197#210#208#199#210#214#199#211#213#196#208#212#200
-  +#210#210#192#210#209#197#209#211#200#211#215#199#211#213'X'#18#1#255#0#255
-  +#255#0#255#255#0#255#170#183#185#227#239#239#227#237#237#226#238#238#226#238
-  +#240#227#239#241#225#237#239#226#240#239#227#239#241#227#239#241#225#238#240
-  +#226#239#241#171#184#186#255#0#255#255#0#255#255#0#255#24'iD'#179#200#215#201
-  +#225#236#200#224#234#200#224#235#201#225#236#201#225#236#201#225#236#201#225
-  +#236#201#225#236#200#224#235#198#221#234#193#216#230#170#185#205#24'iD'#255#0
-  +#255#24'iDc'#153#221'O'#145#227'O'#145#227'N'#144#227'O'#145#227'O'#145#227
-  +'O'#145#227'O'#145#227'O'#145#227'O'#145#227'O'#145#227'O'#145#227'a'#152#219
-  +#24'iD'#255#0#255#24'iD'#176#196#212#211#233#238#216#236#242#217#237#242#217
-  +#237#242#216#236#242#216#236#242#216#236#242#217#237#242#217#237#242#219#238
-  +#243#221#238#244#183#208#222#24'iD'#255#0#255#184#196#202#225#235#239#233#242
-  +#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246
-  +#233#242#246#233#242#246#233#242#246#233#242#246#225#235#239#184#196#202#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#213#195#179#162'v['#150'dH'#192#162#143#228#215#207#249#247
-  +#245#228#215#207#192#162#143#150'dH'#162'v['#213#195#179#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#210#190#173#158'pT'#129'g`~'#147#176'q'#167
-  +#223'c'#171#243'q'#167#223'~'#147#176#129'g`'#158'pT'#210#190#173#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#213#195#179#162'v['#150'kR'#180#161
-  +#147#196#192#187#200#203#203#196#192#187#180#161#147#150'kR'#162'v['#213#195
-  +#179#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#217#224#226
-  +#208#217#219#228#233#234#244#246#247#254#254#254#244#246#247#228#233#234#208
-  +#217#219#217#224#226#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#213#195#179#162'v['#150'dH'#192#162#143#228#215#207#249#247#245#228#215
-  +#207#192#162#143#150'dH'#162'v['#213#195#179#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#213#195#179#162'v['#150'dH'#192#162#143#228#215#207#249
-  +#247#245#228#215#207#192#162#143#150'dH'#162'v['#213#195#179#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#213#195#179#162'v['#150'dH'#192#162#143
-  +#228#215#207#249#247#245#228#215#207#192#162#143#150'dH'#162'v['#213#195#179
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#213#220#219#203
-  +#212#210#225#230#229#243#245#245#253#254#254#243#245#245#225#230#229#203#212
-  +#210#213#220#219#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +'V'#17#0#246#248#249#248#248#248#246#249#247#248#248#248#249#247#247#249#248
-  +#250#246#248#249#250#248#248#246#248#248#248#249#247#249#249#249'V'#17#0#255
-  +#0#255#255#0#255#255#0#255'Y'#20#1#129#195#246#248#248#248#244#249#247#245
-  +#247#247#249#248#252#249#246#248#250#249#245#244#249#248#248#247#249#250#248
-  +#248#133#196#246'W'#18#3#255#0#255#255#0#255#255#0#255'W'#18#1#197#209#213
-  +#195#208#210#196#205#209#194#204#211#194#205#209#196#205#209#193#207#206#194
-  +#206#208#195#208#210#195#207#209#199#210#214'W'#18#1#255#0#255#255#0#255#255
-  +#0#255#170#183#185#224#237#239#225#237#239#225#237#239#224#236#238#225#237
-  +#239#224#236#238#223#236#238#225#237#239#224#236#238#224#236#236#226#238#238
-  +#170#183#185#255#0#255#255#0#255#255#0#255'T'#18#0#245#247#247#248#248#248
-  +#248#248#248#245#248#252#251#247#252#248#247#249#250#248#247#246#248#248#248
-  +#249#245#246#248#248#243#248#246'V'#17#0#255#0#255#255#0#255#255#0#255'X'#19
-  +#0#134#197#248#250#249#245#245#247#247#244#249#248#244#249#247#251#247#252
-  +#246#248#248#246#250#245#246#248#248#249#247#247#132#196#250'W'#19#0#255#0
-  +#255#255#0#255#255#0#255'X'#21#0#199#210#214#195#205#212#197#209#211#202#208
-  +#207#196#209#211#203#208#211#196#205#209#194#207#209#202#205#213#194#206#210
-  +#200#213#215'Z'#18#0#255#0#255#255#0#255#255#0#255#168#183#186#224#237#239
-  +#225#237#237#225#237#237#225#237#239#227#239#241#227#239#241#225#238#240#224
-  +#236#238#224#236#238#227#239#241#226#239#241#169#182#184#255#0#255#255#0#255
-  ,#255#0#255'T'#18#0#245#247#247#248#248#248#248#248#248#245#248#252#251#247
-  +#252#248#247#249#250#248#247#246#248#248#248#249#245#246#248#248#243#248#246
-  +'V'#17#0#255#0#255#255#0#255#255#0#255'X'#19#0#134#197#248#250#249#245#245
-  +#247#247#244#249#248#244#249#247#251#247#252#246#248#248#246#250#245#246#248
-  +#248#249#247#247#132#196#250'W'#19#0#255#0#255#255#0#255#255#0#255'X'#21#0
-  +#199#210#214#195#205#212#197#209#211#202#208#207#196#209#211#203#208#211#196
-  +#205#209#194#207#209#202#205#213#194#206#210#200#213#215'Z'#18#0#255#0#255
-  +#255#0#255#255#0#255#168#183#186#224#237#239#225#237#237#225#237#237#225#237
-  +#239#227#239#241#227#239#241#225#238#240#224#236#238#224#236#238#227#239#241
-  +#226#239#241#169#182#184#255#0#255#255#0#255#255#0#255#6'b7'#225#243#246#224
-  +#243#246#224#243#246#224#243#246#224#243#246#224#243#246#224#243#246#224#243
-  +#246#224#243#246#224#243#246#222#241#246#214#235#242#204#228#238#6'b7'#255#0
-  +#255#6'b7X'#150#227'X'#150#227#224#242#245#224#242#245#224#242#245#224#242
-  +#245#224#242#245#224#242#245#224#242#245#224#242#245#222#240#245'X'#150#227
-  +'V'#149#227#6'b7'#255#0#255#6'b7'#190#213#227#197#220#231#201#225#234#202#226
-  +#234#202#226#234#202#226#234#202#226#234#202#226#234#202#226#234#202#226#234
-  +#203#227#235#206#228#236#207#229#237#6'b7'#255#0#255#184#196#202#233#242#246
-  +#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233
-  +#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#184#196
-  +#202#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#226#214#201#161'tY'#178#141'v'#249#248#245#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#249#248#245#178#141'v'#161'tY'#226
-  +#214#201#255#0#255#255#0#255#255#0#255#224#212#198#158'pT'#136#135#143'~'#180
-  +#234#179#210#240#223#235#247#250#250#251#223#235#247#179#210#240'~'#180#234
-  +#136#135#143#158'pT'#224#212#198#255#0#255#255#0#255#255#0#255#226#214#201
-  +#161'tY'#173#144'}'#207#210#209#202#206#207#202#206#207#202#206#207#202#206
-  +#207#202#206#207#207#210#209#173#144'}'#161'tY'#226#214#201#255#0#255#255#0
-  +#255#255#0#255#255#0#255#217#224#226#224#229#231#254#254#254#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#254#254#254#224#229#231#217#224
-  +#226#255#0#255#255#0#255#255#0#255#255#0#255#226#214#201#161'tY'#178#141'v'
-  +#248#245#242#247#243#240#237#230#223#233#225#215#237#230#223#247#243#240#248
-  +#245#242#178#141'v'#161'tY'#226#214#201#255#0#255#255#0#255#255#0#255#226#214
-  +#201#161'tY'#178#141'v'#248#245#242#247#243#240#237#230#223#233#225#215#237
-  +#230#223#247#243#240#248#245#242#178#141'v'#161'tY'#226#214#201#255#0#255#255
-  +#0#255#255#0#255#226#214#201#161'tY'#178#141'v'#248#245#242#247#243#240#237
-  +#230#223#233#225#215#237#230#223#247#243#240#248#245#242#178#141'v'#161'tY'
-  +#226#214#201#255#0#255#255#0#255#255#0#255#255#0#255#213#220#219#220#226#225
-  +#254#254#254#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#254
-  +#254#254#220#226#225#213#220#219#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255'V'#17#0#246#248#249#248#249#247#250#247#249#249#248#250#250#246#245
-  +#246#248#249#250#248#247#246#248#248#250#247#249#249#249#249#249#248#250'V'
-  +#17#0#255#0#255#255#0#255#255#0#255'X'#19#2#133#193#247#249#249#249#252#247
-  +#248#250#248#247#247#248#246#252#247#249#243#248#247#248#249#247#248#248#248
-  +#249#250#246#130#194#249'['#19#1#255#0#255#255#0#255#255#0#255'V'#17#0#195
-  +#210#213#195#207#207#194#204#204#193#206#204#195#206#203#197#205#204#193#204
-  +#208#194#205#209#192#204#208#196#208#208#198#209#213'Z'#19#0#255#0#255#255#0
-  +#255#255#0#255#168#183#185#224#237#239#226#238#240#224#236#238#224#236#238
-  +#224#236#238#225#237#239#223#236#238#224#236#238#225#237#239#225#237#237#225
-  +#237#239#171#184#186#255#0#255#255#0#255#255#0#255'U'#15#2#245#251#246#250
-  +#246#251#249#249#249#247#247#247#2#134#0#248#247#249#244#249#247#247#249#250
-  +#246#245#247#252#248#247#250#246#251'V'#18#0#255#0#255#255#0#255#255#0#255'X'
-  +#20#1#135#191#250#248#247#249#250#246#251#246#248#248#0#135#0#247#247#247#249
-  +#246#248#247#250#248#248#247#249#247#248#246#129#195#248'X'#19#0#255#0#255
-  +#255#0#255#255#0#255'W'#18#3#196#210#209#200#208#208#203#210#207#200#208#215
-  +#0'e'#3#205#208#216#198#207#211#198#204#209#193#206#204#194#207#215#197#211
-  +#210'Y'#20#0#255#0#255#255#0#255#255#0#255#169#184#187#227#239#241#225#237
-  +#237#226#238#238#228#240#242#161#173#175#226#238#240#227#239#241#225#238#240
-  +#225#237#239#224#237#239#224#237#239#171#184#186#255#0#255#255#0#255#255#0
-  +#255'U'#15#2#245#251#246#250#246#251#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0
-  +#0#139#0#0#139#0#252#248#247#250#246#251'V'#18#0#255#0#255#255#0#255#255#0
-  +#255'X'#20#1#135#191#250#248#247#249#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0
-  +#0#139#0#0#139#0#247#248#246#129#195#248'X'#19#0#255#0#255#255#0#255#255#0
-  +#255'W'#18#3#196#210#209#200#208#208#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0
-  ,#0#139#0#0#139#0#194#207#215#197#211#210'Y'#20#0#255#0#255#255#0#255#255#0
-  +#255#169#184#187#227#239#241#225#237#237#163#176#178#163#176#178#163#176#178
-  +#163#176#178#163#176#178#163#176#178#163#176#178#224#237#239#224#237#239#171
-  +#184#186#255#0#255#255#0#255#255#0#255#6'b7'#226#244#247#226#244#247#225#243
-  +#246#225#243#246#225#243#246#225#243#246#154#154#154#225#243#246#225#243#246
-  +#225#243#246#223#242#246#216#237#242#207#228#238#6'b7'#255#0#255#6'b7\'#153
-  +#228']'#154#229#225#242#245#225#242#245#225#242#245#225#242#245#154#154#154
-  +#225#242#245#225#242#245#225#242#245#223#241#245'\'#153#228'\'#153#228#6'b7'
-  +#255#0#255#6'b7'#189#212#226#196#219#230#201#225#234#202#226#234#202#226#234
-  +#202#226#234#154#154#154#202#226#234#202#226#234#202#226#234#203#226#234#204
-  +#228#236#206#228#236#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233
-  +#242#246#233#242#246#233#242#246#233#242#246#154#154#154#233#242#246#233#242
-  +#246#233#242#246#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#185#153#131#147'_A'#241#236#229#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#241#236#229#147'_A'#185#153#131#255
-  +#0#255#255#0#255#255#0#255#183#150#127#128'f^{'#176#228#220#228#236#254#254
-  +#253#255#255#255#255#255#255#255#255#255#254#254#253#220#228#236'{'#176#228
-  +#128'f^'#183#150#127#255#0#255#255#0#255#255#0#255#185#153#131#147'fL'#202
-  +#203#199#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206
-  +#207#202#206#207#202#203#199#147'fL'#185#153#131#255#0#255#255#0#255#255#0
-  +#255#233#237#238#208#217#219#254#254#254#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#254#254#254#208#217#219#255
-  +#0#255#255#0#255#255#0#255#255#0#255#185#153#131#147'_A'#241#236#229#247#243
-  +#240#227#216#204#214#198#181#211#194#175#214#198#181#227#216#204#247#243#240
-  +#241#236#229#147'_A'#185#153#131#255#0#255#255#0#255#255#0#255#185#153#131
-  +#147'_A'#241#236#229#247#243#240#227#216#204#214#198#181#211#194#175#214#198
-  +#181#227#216#204#247#243#240#241#236#229#147'_A'#185#153#131#255#0#255#255#0
-  +#255#255#0#255#185#153#131#147'_A'#241#236#229#247#243#240#227#216#204#214
-  +#198#181#211#194#175#214#198#181#227#216#204#247#243#240#241#236#229#147'_A'
-  +#185#153#131#255#0#255#255#0#255#255#0#255#230#234#234#203#212#210#254#254
-  +#254#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#254#254#254#203#212#210#230#234#234#255#0#255#255#0#255#255#0
-  +#255#255#0#255'V'#17#0#246#248#248#248#249#247#246#248#248#250#248#247#249
-  +#250#246#246#248#249#250#248#248#245#248#246#248#249#247#248#249#247#249#247
-  +#247'V'#17#0#255#0#255#255#0#255#255#0#255'S'#16#1#130#196#245#244#246#246
-  +#252#249#245#248#248#248#244#249#247#250#248#248#248#247#249#248#248#248#250
-  +#248#247#246#248#248#131#197#246'X'#19#0#255#0#255#255#0#255#255#0#255'W'#18
-  +#0#198#209#213#195#208#210#201#206#207#199#204#205#195#204#207#197#205#204
-  +#193#205#205#196#204#204#197#204#207#197#206#209#197#209#213'X'#20#1#255#0
-  +#255#255#0#255#255#0#255#167#182#184#224#237#239#224#236#238#224#236#238#224
-  +#237#239#223#235#237#226#238#240#223#236#238#225#237#239#224#236#238#224#237
-  +#239#228#240#242#170#183#185#255#0#255#255#0#255#255#0#255'V'#15#1#245#250
-  +#248#248#248#248#249#247#246#1#137#1#0#141#2#0#135#0#246#248#249#251#248#243
-  +#249#249#249#250#247#249#246#247#251'W'#17#0#255#0#255#255#0#255#255#0#255'Y'
-  +#17#0#130#194#248#252#247#248#251#250#246#0#135#0#1#135#0#3#134#0#248#249#247
-  +#245#247#247#245#247#248#247#249#249#134#193#249'Z'#18#0#255#0#255#255#0#255
-  +#255#0#255'Z'#19#0#198#211#213#198#208#215#202#209#212#2'e'#1#1'j'#3#2'f'#0
-  +#204#209#212#196#209#211#195#204#208#195#207#209#196#210#208'X'#18#1#255#0
-  +#255#255#0#255#255#0#255#169#184#186#224#237#239#226#238#238#227#239#239#163
-  +#175#177#165#177#179#164#176#178#227#239#241#225#238#240#226#238#240#224#236
-  +#238#227#239#241#170#183#185#255#0#255#255#0#255#255#0#255'V'#15#1#245#250
-  +#248#248#248#248#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#250
-  +#247#249#246#247#251'W'#17#0#255#0#255#255#0#255#255#0#255'Y'#17#0#130#194
-  +#248#252#247#248#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#247
-  +#249#249#134#193#249'Z'#18#0#255#0#255#255#0#255#255#0#255'Z'#19#0#198#211
-  +#213#198#208#215#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#195
-  +#207#209#196#210#208'X'#18#1#255#0#255#255#0#255#255#0#255#169#184#186#224
-  +#237#239#226#238#238#163#176#178#163#176#178#163#176#178#163#176#178#163#176
-  +#178#163#176#178#163#176#178#224#236#238#227#239#241#170#183#185#255#0#255
-  +#255#0#255#255#0#255#6'b7'#227#245#248#227#245#248#226#244#247#226#244#247
-  +#226#244#247#154#154#154#154#154#154#154#154#154#226#244#247#226#244#247#225
-  +#243#246#217#238#243#208#229#238#6'b7'#255#0#255#6'b7c'#158#229'c'#158#229
-  ,#226#243#246#226#243#246#226#243#246#154#154#154#154#154#154#154#154#154#226
-  +#243#246#226#243#246#225#242#245'c'#158#229'b'#157#229#6'b7'#255#0#255#6'b7'
-  +#189#211#227#197#219#231#202#225#234#203#226#235#203#226#235#154#154#154#154
-  +#154#154#154#154#154#203#226#235#203#226#235#204#226#235#206#227#236#206#228
-  +#237#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233#242#246#233#242
-  +#246#233#242#246#154#154#154#154#154#154#154#154#154#233#242#246#233#242#246
-  +#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#152'hK'#181#147
-  +'}'#250#247#245#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#250#247#245#181#147'}'#152'hK'#255#0#255#255#0#255
-  +#255#0#255#151'eHz'#143#170#170#196#223#250#248#246#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#250#248#246#170#196#223'z'#143#170#151
-  +'eH'#255#0#255#255#0#255#255#0#255#152'hK'#172#150#134#199#202#202#202#206
-  +#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207
-  +#199#202#202#172#150#134#152'hK'#255#0#255#255#0#255#255#0#255#213#221#222
-  +#228#233#234#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#228#233#234#213#221#222#255#0
-  +#255#255#0#255#255#0#255#152'hK'#181#147'}'#250#247#245#237#230#223#170#187
-  +#145'V'#162'K'#24#148#28'V'#162'K'#170#187#145#237#230#223#250#247#245#181
-  +#147'}'#152'hK'#255#0#255#255#0#255#255#0#255#152'hK'#181#147'}'#250#247#245
-  +#237#230#223#170#187#145'V'#162'K'#24#148#28'V'#162'K'#170#187#145#237#230
-  +#223#250#247#245#181#147'}'#152'hK'#255#0#255#255#0#255#255#0#255#152'hK'#181
-  +#147'}'#250#247#245#237#230#223#170#187#145'V'#162'K'#24#148#28'V'#162'K'#170
-  +#187#145#237#230#223#250#247#245#181#147'}'#152'hK'#255#0#255#255#0#255#255#0
-  +#255#208#216#215#225#230#229#255#255#255#255#255#255#238#241#241#207#215#214
-  +#183#195#193#207#215#214#238#241#241#255#255#255#255#255#255#225#230#229#208
-  +#216#215#255#0#255#255#0#255#255#0#255#255#0#255'V'#17#0#245#244#246#244#243
-  +#245#246#244#244#241#245#246#251#246#247#248#248#248#248#247#249#248#248#248
-  +#247#246#248#250#248#248#246#249#247'V'#17#0#255#0#255#255#0#255#255#0#255'Z'
-  +#18#0#129#193#248#247#246#248#244#246#246#246#245#249#249#249#249#243#248#247
-  +#253#248#250#246#248#249#252#247#248#247#249#249#133#194#250'V'#19#0#255#0
-  +#255#255#0#255#255#0#255'X'#18#1#195#209#208#193#205#205#194#203#206#193#205
-  +#205#194#204#204#193#206#204#196#203#206#193#206#204#195#204#208#195#206#210
-  +#198#210#212'X'#19#0#255#0#255#255#0#255#255#0#255#168#183#185#225#238#240
-  +#225#237#239#224#237#239#222#235#237#224#236#238#224#236#238#224#236#238#224
-  +#236#238#224#236#238#223#236#238#226#238#240#171#184#186#255#0#255#255#0#255
-  +#255#0#255'T'#17#2#246#248#249#254#246#246#3#136#2#0#139#0#0#137#0#0#140#0#4
-  +#136#0#247#248#246#249#248#250#251#249#249#245#249#244'W'#18#0#255#0#255#255
-  +#0#255#255#0#255'W'#18#1#132#194#248#246#250#245#0#136#1#3#138#0#0#137#0#0
-  +#141#0#0#135#0#249#247#247#251#251#245#249#246#248#134#197#248'['#20#0#255#0
-  +#255#255#0#255#255#0#255'W'#17#0#195#208#216#200#206#211#0'g'#0#0'i'#2#0'j'#0
-  +#3'k'#0#1'g'#2#203#208#217#200#206#211#197#207#207#198#207#216'X'#19#0#255#0
-  +#255#255#0#255#255#0#255#168#183#185#226#239#241#225#237#237#161#173#173#163
-  +#176#178#163#176#178#163#176#178#163#177#176#227#240#242#226#238#240#226#238
-  +#240#226#238#240#170#183#185#255#0#255#255#0#255#255#0#255'T'#17#2#246#248
-  +#249#254#246#246#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#251
-  +#249#249#245#249#244'W'#18#0#255#0#255#255#0#255#255#0#255'W'#18#1#132#194
-  +#248#246#250#245#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#249
-  +#246#248#134#197#248'['#20#0#255#0#255#255#0#255#255#0#255'W'#17#0#195#208
-  +#216#200#206#211#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#197
-  +#207#207#198#207#216'X'#19#0#255#0#255#255#0#255#255#0#255#168#183#185#226
-  +#239#241#225#237#237#163#176#178#163#176#178#163#176#178#163#176#178#163#176
-  +#178#163#176#178#163#176#178#226#238#240#226#238#240#170#183#185#255#0#255
-  +#255#0#255#255#0#255#6'b7'#228#245#248#228#245#248#227#244#247#227#244#247
-  +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#227#244#247#226
-  +#243#246#218#238#243#210#229#238#6'b7'#255#0#255#6'b7j'#162#230'j'#162#230
-  +#227#243#246#227#243#246#154#154#154#154#154#154#154#154#154#154#154#154#154
-  +#154#154#227#243#246#226#242#245'j'#162#230'j'#162#230#6'b7'#255#0#255#6'b7'
-  +#190#211#227#198#219#231#203#225#234#204#226#235#154#154#154#154#154#154#154
-  +#154#154#154#154#154#154#154#154#204#226#235#207#226#235#208#227#236#207#228
-  +#237#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233#242#246#233#242
-  +#246#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#233#242#246
-  +#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255#255#0#255#255#0
-  ,#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#127'B '#210#189
-  +#173#252#251#250#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#252#251#250#210#189#173#127'B '#255#0#255#255#0#255
-  +#255#0#255#127'A'#31'k'#159#213#207#213#218#253#252#251#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#253#252#251#207#213#218'k'#159#213
-  +#127'A'#31#255#0#255#255#0#255#255#0#255#127'B '#185#176#167#200#204#204#202
-  +#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206
-  +#207#200#204#204#185#176#167#127'B '#255#0#255#255#0#255#255#0#255#197#208
-  +#210#244#246#247#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#244#246#247#197#208#210#255
-  +#0#255#255#0#255#255#0#255#127'B '#210#189#173#252#251#250#233#225#215'W'#164
-  +'M'#13#146#19#13#146#19#13#146#19'W'#164'M'#233#225#215#252#251#250#210#189
-  +#173#127'B '#255#0#255#255#0#255#255#0#255#127'B '#210#189#173#252#251#250
-  +#233#225#215'W'#164'M'#13#146#19#13#146#19#13#146#19'W'#164'M'#233#225#215
-  +#252#251#250#210#189#173#127'B '#255#0#255#255#0#255#255#0#255#127'B '#210
-  +#189#173#252#251#250#233#225#215'W'#164'M'#13#146#19#13#146#19#13#146#19'W'
-  +#164'M'#233#225#215#252#251#250#210#189#173#127'B '#255#0#255#255#0#255#255#0
-  +#255#190#201#199#243#245#245#255#255#255#255#255#255#207#215#214#178#191#189
-  +#178#191#189#178#191#189#207#215#214#255#255#255#255#255#255#243#245#245#190
-  +#201#199#255#0#255#255#0#255#255#0#255#255#0#255'V'#17#0#242#242#242#239#241
-  +#241#241#240#244#238#244#243#244#244#244#245#246#244#245#244#246#247#246#248
-  +#248#247#249#245#248#246#248#247#249'V'#17#0#255#0#255#255#0#255#255#0#255'Z'
-  +#18#1#132#189#250#236#240#241#239#241#241#244#242#242#244#244#244#245#244#246
-  +#239#246#243#251#248#250#252#247#246#242#249#244#135#197#251'W'#19#0#255#0
-  +#255#255#0#255#255#0#255'W'#19#0#191#206#209#191#204#206#193#204#202#194#205
-  +#203#196#203#206#191#205#203#197#204#207#193#205#207#193#205#207#196#206#206
-  +#202#208#213'W'#18#0#255#0#255#255#0#255#255#0#255#169#182#184#225#239#238
-  +#225#237#239#224#236#238#225#237#239#226#237#241#225#237#239#224#236#238#225
-  +#237#239#226#238#238#224#236#238#227#239#241#167#183#182#255#0#255#255#0#255
-  +#255#0#255'W'#18#0#240#243#247#240#243#248#1#135#0#2#135#1#254#249#248#0#137
-  +#0#0#137#0#0#137#0#247#248#246#246#247#251#247#249#249'V'#16#0#255#0#255#255
-  +#0#255#255#0#255'W'#18#0#129#188#250#246#245#249#0#137#0#2#136#0#248#249#247
-  +#1#133#3#1#137#1#0#137#0#244#247#251#246#249#247#137#199#247'U'#19#0#255#0
-  +#255#255#0#255#255#0#255'W'#18#1#192#205#213#203#208#209#2'e'#1#0'g'#0#208
-  +#210#218#4'g'#0#0'i'#2#2'e'#1#204#211#214#196#209#207#200#209#212'W'#20#0#255
-  +#0#255#255#0#255#255#0#255#171#183#187#226#238#240#229#239#239#161#173#175
-  +#163#175#177#229#241#243#163#175#177#163#175#177#162#175#177#227#239#241#226
-  +#238#240#225#238#240#170#183#185#255#0#255#255#0#255#255#0#255'W'#18#0#240
-  +#243#247#240#243#248#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0
-  +#246#247#251#247#249#249'V'#16#0#255#0#255#255#0#255#255#0#255'W'#18#0#129
-  +#188#250#246#245#249#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0
-  +#246#249#247#137#199#247'U'#19#0#255#0#255#255#0#255#255#0#255'W'#18#1#192
-  +#205#213#203#208#209#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0
-  +#196#209#207#200#209#212'W'#20#0#255#0#255#255#0#255#255#0#255#171#183#187
-  +#226#238#240#229#239#239#163#176#178#163#176#178#163#176#178#163#176#178#163
-  +#176#178#163#176#178#163#176#178#226#238#240#225#238#240#170#183#185#255#0
-  +#255#255#0#255#255#0#255#6'b7'#233#249#250#233#249#250#232#250#251#154#154
-  +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154
-  +#231#249#251#224#243#247#214#235#242#6'b7'#255#0#255#6'b7'#146#187#236#139
-  +#184#235#232#249#250#154#154#154#154#154#154#154#154#154#154#154#154#154#154
-  +#154#154#154#154#154#154#154#231#248#250#139#184#235#145#186#235#6'b7'#255#0
-  +#255#6'b7'#193#215#228#200#222#234#207#228#237#154#154#154#154#154#154#154
-  +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#210#229#238#211#230
-  +#238#211#231#238#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233#242
-  +#246#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154
-  +#154#154#154#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255'q,'#8
-  +#224#211#197#250#247#245#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#250#247#245#224#211#197'q,'#8#255#0#255#255
-  +#0#255#255#0#255'q,'#7'^'#164#234#226#217#208#250#248#246#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#250#248#246#226#217#208'^'#164#234
-  +'q,'#7#255#0#255#255#0#255#255#0#255'q,'#8#187#185#178#199#202#202#202#206
-  ,#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207
-  +#199#202#202#187#185#178'q,'#8#255#0#255#255#0#255#255#0#255#188#200#203#254
-  +#254#254#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#254#254#254#188#200#203#255#0#255
-  +#255#0#255#255#0#255'q,'#8#224#211#197#250#247#245#237#230#223#25#149#29#13
-  +#146#19#13#146#19#13#146#19#25#149#29#237#230#223#250#247#245#224#211#197'q,'
-  +#8#255#0#255#255#0#255#255#0#255'q,'#8#224#211#197#250#247#245#237#230#223#25
-  +#149#29#13#146#19#13#146#19#13#146#19#25#149#29#237#230#223#250#247#245#224
-  +#211#197'q,'#8#255#0#255#255#0#255#255#0#255'q,'#8#224#211#197#250#247#245
-  +#237#230#223#25#149#29#13#146#19#13#146#19#13#146#19#25#149#29#237#230#223
-  +#250#247#245#224#211#197'q,'#8#255#0#255#255#0#255#255#0#255#180#192#190#253
-  +#254#254#255#255#255#255#255#255#183#195#193#178#191#189#178#191#189#178#191
-  +#189#183#195#193#255#255#255#255#255#255#253#254#254#180#192#190#255#0#255
-  +#255#0#255#255#0#255#255#0#255'V'#17#0#233#235#236#230#235#234#231#236#235
-  +#235#238#236#237#239#240#237#239#240#242#242#242#246#244#243#240#246#245#247
-  +#247#247#250#248#248'V'#17#0#255#0#255#255#0#255#255#0#255'U'#19#1'w'#190#240
-  +#234#233#235#235#233#233#231#236#235#233#239#238#239#238#240#237#241#242#238
-  +#245#242#243#246#244#250#246#251#134#193#249'W'#20#0#255#0#255#255#0#255#255
-  +#0#255'X'#18#1#192#204#206#192#201#204#194#202#202#189#202#200#190#202#202
-  +#193#203#203#195#202#205#196#204#203#196#203#206#192#204#208#197#208#212'Y'
-  +#20#1#255#0#255#255#0#255#255#0#255#170#183#185#224#238#237#225#237#239#224
-  +#236#238#225#237#239#223#235#237#227#239#239#224#236#238#224#236#238#224#235
-  +#239#225#237#239#225#237#237#170#183#185#255#0#255#255#0#255#255#0#255'P'#19
-  +#0#229#235#242#238#237#239#3#135#0#241#240#244#246#240#245#250#243#250#1#137
-  +#1#0#137#0#0#136#0#244#249#247#251#249#249'V'#16#0#255#0#255#255#0#255#255#0
-  +#255'W'#19#0#129#188#244#234#237#241#0#133#0#243#239#244#240#243#248#245#245
-  +#245#4#134#3#0#140#1#2#136#0#247#247#247#136#196#248'X'#19#0#255#0#255#255#0
-  +#255#255#0#255'Y'#20#0#192#205#207#193#205#205#0'f'#1#195#205#212#200#205#208
-  +#197#203#214#0'g'#0#1'h'#0#2'f'#0#201#208#211#197#208#212'Z'#19#0#255#0#255
-  +#255#0#255#255#0#255#168#183#185#225#238#240#226#238#240#161#173#175#227#239
-  +#241#226#239#241#227#238#242#163#174#178#163#175#177#160#173#175#225#238#240
-  +#227#239#241#170#183#185#255#0#255#255#0#255#255#0#255'P'#19#0#229#235#242
-  +#238#237#239#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#244#249
-  +#247#251#249#249'V'#16#0#255#0#255#255#0#255#255#0#255'W'#19#0#129#188#244
-  +#234#237#241#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#247#247
-  +#247#136#196#248'X'#19#0#255#0#255#255#0#255#255#0#255'Y'#20#0#192#205#207
-  +#193#205#205#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#201#208
-  +#211#197#208#212'Z'#19#0#255#0#255#255#0#255#255#0#255#168#183#185#225#238
-  +#240#226#238#240#163#176#178#163#176#178#163#176#178#163#176#178#163#176#178
-  +#163#176#178#163#176#178#225#238#240#227#239#241#170#183#185#255#0#255#255#0
-  +#255#255#0#255#6'b7'#235#249#250#235#249#250#154#154#154#154#154#154#154#154
-  +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154
-  +#225#243#247#215#235#242#6'b7'#255#0#255#6'b7'#150#190#237#139#184#235#154
-  +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154
-  +#154#154#154#154#154#154#154#139#184#235#150#190#237#6'b7'#255#0#255#6'b7'
-  +#193#215#228#200#222#234#154#154#154#154#154#154#154#154#154#154#154#154#154
-  +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#211#230#238#211#231
-  +#238#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#154#154#154#154#154
-  +#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154#154
-  +#154#154#154#233#242#246#233#242#246#184#196#202#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#128'C!'#205#183
-  +#165#243#238#232#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#243#238#232#205#183#165#128'C!'#255#0#255#255#0#255
-  +#255#0#255#128'B l'#160#214#199#201#203#243#238#233#254#254#253#255#255#255
-  +#255#255#255#255#255#255#254#254#253#243#238#233#199#201#203'l'#160#214#128
-  +'B '#255#0#255#255#0#255#255#0#255#128'C!'#182#173#163#196#198#195#202#206
-  +#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207#202#206#207
-  +#196#198#195#182#173#163#128'C!'#255#0#255#255#0#255#255#0#255#197#208#210
-  +#244#246#247#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#244#246#247#197#208#210#255#0
-  +#255#255#0#255#255#0#255#128'C!'#205#183#165#243#238#232#247#243#240']'#172
-  +'X'#13#146#19#13#146#19#13#146#19']'#172'X'#247#243#240#243#238#232#205#183
-  +#165#128'C!'#255#0#255#255#0#255#255#0#255#128'C!'#205#183#165#243#238#232
-  ,#247#243#240']'#172'X'#13#146#19#13#146#19#13#146#19']'#172'X'#247#243#240
-  +#243#238#232#205#183#165#128'C!'#255#0#255#255#0#255#255#0#255#128'C!'#205
-  +#183#165#243#238#232#247#243#240']'#172'X'#13#146#19#13#146#19#13#146#19']'
-  +#172'X'#247#243#240#243#238#232#205#183#165#128'C!'#255#0#255#255#0#255#255#0
-  +#255#190#201#199#243#245#245#255#255#255#255#255#255#207#215#214#178#191#189
-  +#178#191#189#178#191#189#207#215#214#255#255#255#255#255#255#243#245#245#190
-  +#201#199#255#0#255#255#0#255#255#0#255#255#0#255'V'#17#0#227#230#234#226#230
-  +#231#225#229#230#229#234#233#234#235#233#231#236#235#235#237#237#235#240#239
-  +#241#242#240#243#242#244#247#249#249'V'#17#0#255#0#255#255#0#255#255#0#255'W'
-  +#18#0'|'#181#243#225#227#228#227#226#228#222#230#230#230#232#232#229#231#231
-  +#233#235#236#233#237#238#242#237#238#241#243#243#131#194#245'W'#18#1#255#0
-  +#255#255#0#255#255#0#255'W'#18#0#189#203#202#188#200#200#185#199#198#188#202
-  +#201#188#200#202#192#201#204#191#204#202#191#204#202#190#202#204#192#204#206
-  +#196#210#209'W'#19#0#255#0#255#255#0#255#255#0#255#170#183#185#225#238#240
-  +#224#236#238#223#235#237#223#235#237#225#237#239#225#237#237#224#236#238#223
-  +#236#238#223#235#239#224#236#238#225#237#237#171#184#186#255#0#255#255#0#255
-  +#255#0#255'Z'#18#1#224#227#231#224#228#229#226#229#233#228#233#232#233#233
-  +#233#238#236#236#245#239#244#5#137#0#0#137#2#250#247#249#246#246#246'V'#17#2
-  +#255#0#255#255#0#255#255#0#255'Y'#20#1'y'#181#241#229#230#228#231#229#229#231
-  +#230#232#229#234#232#234#235#239#245#239#244#1#134#0#0#138#0#246#248#248#133
-  +#192#248'['#20#0#255#0#255#255#0#255#255#0#255'V'#17#2#188#200#206#190#202
-  +#204#195#198#206#191#203#205#192#201#204#196#203#206#201#203#213#0'f'#1#0'f'
-  +#1#195#206#210#196#209#211'W'#19#0#255#0#255#255#0#255#255#0#255#168#183#185
-  +#225#239#238#225#237#237#226#238#238#227#239#239#223#237#236#226#238#240#227
-  +#239#241#163#175#177#162#174#176#228#240#242#228#237#240#171#183#185#255#0
-  +#255#255#0#255#255#0#255'Z'#18#1#224#227#231#224#228#229#0#139#0#0#139#0#0
-  +#139#0#0#139#0#0#139#0#0#139#0#0#139#0#250#247#249#246#246#246'V'#17#2#255#0
-  +#255#255#0#255#255#0#255'Y'#20#1'y'#181#241#229#230#228#0#139#0#0#139#0#0#139
-  +#0#0#139#0#0#139#0#0#139#0#0#139#0#246#248#248#133#192#248'['#20#0#255#0#255
-  +#255#0#255#255#0#255'V'#17#2#188#200#206#190#202#204#0#139#0#0#139#0#0#139#0
-  +#0#139#0#0#139#0#0#139#0#0#139#0#195#206#210#196#209#211'W'#19#0#255#0#255
-  +#255#0#255#255#0#255#168#183#185#225#239#238#225#237#237#163#176#178#163#176
-  +#178#163#176#178#163#176#178#163#176#178#163#176#178#163#176#178#228#240#242
-  +#228#237#240#171#183#185#255#0#255#255#0#255#255#0#255#6'b7'#237#251#252#236
-  +#251#252#236#251#252#236#251#252#236#251#252#236#251#252#236#251#252#236#251
-  +#252#236#251#252#236#251#252#236#250#251#228#244#249#219#237#244#6'b7'#255#0
-  +#255#6'b7'#156#196#238#139#184#235#237#251#252#237#251#252#237#251#252#237
-  +#251#252#237#251#252#237#251#252#237#251#252#237#251#252#236#250#251#139#184
-  +#235#156#196#238#6'b7'#255#0#255#6'b7'#195#216#229#202#224#234#208#229#238
-  +#211#230#238#211#230#238#211#230#238#211#230#238#211#230#238#211#230#238#211
-  +#230#238#211#230#238#212#231#238#213#231#238#6'b7'#255#0#255#184#196#202#233
-  +#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242
-  +#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246
-  +#184#196#202#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#156'lP'#178#142'v'#233#224#214#251#250#248#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#251#250#248#233#224#214#178
-  +#142'v'#156'lP'#255#0#255#255#0#255#255#0#255#155'kO{'#143#171#161#185#208
-  +#229#218#207#243#238#233#250#248#246#253#252#251#250#248#246#243#238#233#229
-  +#218#207#161#185#208'{'#143#171#155'kO'#255#0#255#255#0#255#255#0#255#156'lP'
-  +#170#146#129#191#191#186#200#204#203#202#206#207#202#206#207#202#206#207#202
-  +#206#207#202#206#207#200#204#203#191#191#186#170#146#129#156'lP'#255#0#255
-  +#255#0#255#255#0#255#213#221#222#228#233#234#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#228#233#234#213#221#222#255#0#255#255#0#255#255#0#255#156'lP'#178#142'v'#233
-  +#224#214#250#247#245#196#222#191'`'#177'_'#26#151#31'`'#177'_'#196#222#191
-  +#250#247#245#233#224#214#178#142'v'#156'lP'#255#0#255#255#0#255#255#0#255#156
-  +'lP'#178#142'v'#233#224#214#250#247#245#196#222#191'`'#177'_'#26#151#31'`'
-  +#177'_'#196#222#191#250#247#245#233#224#214#178#142'v'#156'lP'#255#0#255#255
-  +#0#255#255#0#255#156'lP'#178#142'v'#233#224#214#250#247#245#196#222#191'`'
-  +#177'_'#26#151#31'`'#177'_'#196#222#191#250#247#245#233#224#214#178#142'v'
-  +#156'lP'#255#0#255#255#0#255#255#0#255#208#216#215#225#230#229#255#255#255
-  +#255#255#255#238#241#241#207#215#214#183#195#193#207#215#214#238#241#241#255
-  +#255#255#255#255#255#225#230#229#208#216#215#255#0#255#255#0#255#255#0#255
-  ,#255#0#255'V'#17#0#217#226#230#221#225#226#221#227#226#225#227#227#226#232
-  +#227#230#232#232#228#231#235#236#233#235#234#236#236#234#239#242#238#241#245
-  +'V'#17#0#255#0#255#255#0#255#255#0#255'['#19#1't'#177#241#217#225#218#216#222
-  +#221#220#223#221#217#225#224#226#228#228#224#229#227#233#233#227#235#234#236
-  +#234#240#239'}'#189#247'X'#18#1#255#0#255#255#0#255#255#0#255'V'#16#3#183#201
-  +#200#189#200#198#186#198#198#186#200#199#186#200#196#188#201#199#189#201#201
-  +#191#201#201#191#200#203#191#204#202#194#206#208'W'#18#0#255#0#255#255#0#255
-  +#255#0#255#170#182#186#224#237#239#226#237#241#225#237#239#224#236#238#224
-  +#235#239#224#236#238#225#237#239#224#236#238#223#237#236#225#238#240#225#238
-  +#240#168#184#183#255#0#255#255#0#255#255#0#255'Y'#17#0#212#221#224#216#220
-  +#221#215#220#221#219#224#223#218#226#225#224#229#228#227#230#234#233#234#238
-  +#1#133#2#236#240#241#240#242#242'W'#17#0#255#0#255#255#0#255#255#0#255'V'#21
-  +#0't'#178#242#217#222#221#216#221#222#217#222#223#220#225#223#224#231#228#227
-  +#231#232#236#235#239#0#133#3#237#238#242'~'#189#249'Z'#19#0#255#0#255#255#0
-  +#255#255#0#255'T'#18#0#184#203#200#189#198#201#189#198#202#186#199#201#190
-  +#198#197#189#201#201#189#201#203#200#205#208#2'f'#0#190#205#207#194#206#210
-  +'W'#18#0#255#0#255#255#0#255#255#0#255#168#181#183#225#238#240#225#237#239
-  +#223#235#237#225#237#239#225#237#239#224#236#238#226#238#240#228#240#242#159
-  +#172#174#226#238#238#225#237#239#171#184#186#255#0#255#255#0#255#255#0#255'Y'
-  +#17#0#212#221#224#216#220#221#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0
-  +#0#139#0#236#240#241#240#242#242'W'#17#0#255#0#255#255#0#255#255#0#255'V'#21
-  +#0't'#178#242#217#222#221#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0
-  +#139#0#237#238#242'~'#189#249'Z'#19#0#255#0#255#255#0#255#255#0#255'T'#18#0
-  +#184#203#200#189#198#201#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0#139#0#0
-  +#139#0#190#205#207#194#206#210'W'#18#0#255#0#255#255#0#255#255#0#255#168#181
-  +#183#225#238#240#225#237#239#163#176#178#163#176#178#163#176#178#163#176#178
-  +#163#176#178#163#176#178#163#176#178#226#238#238#225#237#239#171#184#186#255
-  +#0#255#255#0#255#255#0#255#6'b7'#240#253#254#239#253#254#239#253#254#239#253
-  +#254#239#253#254#239#253#254#239#253#254#239#253#254#239#253#254#239#253#254
-  +#238#253#254#232#247#251#224#241#246#6'b7'#255#0#255#6'b7'#161#198#238#139
-  +#184#235#240#253#254#240#253#254#240#253#254#240#253#254#240#253#254#240#253
-  +#254#240#253#254#240#253#254#239#253#254#139#184#235#161#198#238#6'b7'#255#0
-  +#255#6'b7'#195#217#229#202#224#234#210#230#238#212#233#238#213#233#238#213
-  +#233#238#213#233#238#213#233#238#213#233#238#213#233#238#213#233#238#213#233
-  +#238#214#233#238#6'b7'#255#0#255#184#196#202#233#242#246#233#242#246#233#242
-  +#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246
-  +#233#242#246#233#242#246#233#242#246#233#242#246#184#196#202#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#196
-  +#169#152#147'_B'#222#208#194#233#224#214#243#238#232#250#247#245#252#251#250
-  +#250#247#245#243#238#232#233#224#214#222#208#194#147'_B'#196#169#152#255#0
-  +#255#255#0#255#255#0#255#196#169#151#130'ibx'#171#222#197#195#192#222#209#195
-  +#229#218#207#232#222#212#229#218#207#222#209#195#197#195#192'x'#171#222#130
-  +'ib'#196#169#151#255#0#255#255#0#255#255#0#255#196#169#152#147'fM'#191#187
-  +#179#191#191#186#196#198#195#199#202#202#200#204#204#199#202#202#196#198#195
-  +#191#191#186#191#187#179#147'fM'#196#169#152#255#0#255#255#0#255#255#0#255
-  +#255#0#255#208#217#219#254#254#254#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#254#254#254#208#217#219#255#0
-  +#255#255#0#255#255#0#255#255#0#255#196#169#152#147'_B'#222#208#194#233#224
-  +#214#243#238#232#250#247#245#252#251#250#250#247#245#243#238#232#233#224#214
-  +#222#208#194#147'_B'#196#169#152#255#0#255#255#0#255#255#0#255#196#169#152
-  +#147'_B'#222#208#194#233#224#214#243#238#232#250#247#245#252#251#250#250#247
-  +#245#243#238#232#233#224#214#222#208#194#147'_B'#196#169#152#255#0#255#255#0
-  +#255#255#0#255#196#169#152#147'_B'#222#208#194#233#224#214#243#238#232#250
-  +#247#245#252#251#250#250#247#245#243#238#232#233#224#214#222#208#194#147'_B'
-  +#196#169#152#255#0#255#255#0#255#255#0#255#255#0#255#203#212#210#254#254#254
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#254#254#254#203#212#210#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255'V'#17#0#219#223#224#214#225#223#222#224#224#221#224#228#222#225#229
-  +#223#227#228#225#230#228#229#231#232#227#231#232#236#236#236#236#241#242'V'
-  +#17#0#255#0#255#255#0#255#255#0#255'Y'#20#1'p'#173#235#214#217#215#213#218
-  +#217#217#219#220#219#221#221#218#223#222#223#226#224#221#224#228#224#229#227
-  +#234#232#231'}'#185#244'['#20#0#255#0#255#255#0#255#255#0#255'Y'#20#0#187#199
-  +#199#185#198#200#185#197#197#185#197#201#184#199#202#189#198#202#188#200#200
-  ,#188#200#202#183#200#203#192#204#206#189#204#207'Y'#19#2#255#0#255#255#0#255
-  +#255#0#255#173#185#187#226#238#240#226#237#241#225#237#239#224#236#238#225
-  +#237#239#225#237#237#224#236#238#225#237#239#224#236#236#225#237#239#226#238
-  +#240#170#184#183#255#0#255#255#0#255#255#0#255'Y'#19#2#211#216#219#204#218
-  +#217#214#216#216#213#218#221#215#221#220#215#221#226#219#224#222#225#227#228
-  +#226#229#234#228#233#231#231#236#237'V'#14#2#255#0#255#255#0#255#255#0#255'W'
-  +#19#0'p'#175#235#207#218#216#213#218#217#220#220#220#221#221#221#224#221#223
-  +#221#226#225#226#228#229#230#230#230#235#236#234#128#185#246'['#19#2#255#0
-  +#255#255#0#255#255#0#255'Y'#20#1#188#200#200#185#199#198#185#198#200#186#199
-  +#201#187#197#197#184#196#200#188#200#204#193#201#201#190#199#208#194#203#206
-  +#195#204#207'T'#20#2#255#0#255#255#0#255#255#0#255#173#185#189#225#237#239
-  +#227#239#241#226#238#240#225#237#239#224#236#238#224#236#238#225#237#239#226
-  +#238#238#226#240#239#225#237#237#226#238#238#170#184#183#255#0#255#255#0#255
-  +#255#0#255'Y'#19#2#211#216#219#204#218#217#214#216#216#213#218#221#215#221
-  +#220#215#221#226#219#224#222#225#227#228#226#229#234#228#233#231#231#236#237
-  +'V'#14#2#255#0#255#255#0#255#255#0#255'W'#19#0'p'#175#235#207#218#216#213#218
-  +#217#220#220#220#221#221#221#224#221#223#221#226#225#226#228#229#230#230#230
-  +#235#236#234#128#185#246'['#19#2#255#0#255#255#0#255#255#0#255'Y'#20#1#188
-  +#200#200#185#199#198#185#198#200#186#199#201#187#197#197#184#196#200#188#200
-  +#204#193#201#201#190#199#208#194#203#206#195#204#207'T'#20#2#255#0#255#255#0
-  +#255#255#0#255#173#185#189#225#237#239#227#239#241#226#238#240#225#237#239
-  +#224#236#238#224#236#238#225#237#239#226#238#238#226#240#239#225#237#237#226
-  +#238#238#170#184#183#255#0#255#255#0#255#255#0#255'#oL'#180#221#228#245#255
-  +#255#245#255#255#245#255#255#245#255#255#245#255#255#245#255#255#245#255#255
-  +#245#255#255#245#255#255#245#255#255#244#255#255#180#221#228'#oL'#255#0#255
-  +'#oL'#149#197#252#139#184#235#150#190#237#150#190#237#150#190#237#150#190#237
-  +#150#190#237#150#190#237#150#190#237#150#190#237#150#190#237#139#184#235#149
-  +#197#252'#oL'#255#0#255'#oL'#149#175#196#185#208#227#191#212#228#194#216#230
-  +#195#217#231#195#217#231#195#217#231#195#217#231#195#217#231#195#217#231#194
-  +#216#230#196#218#231#158#189#206'#oL'#255#0#255#184#196#202#221#231#235#233
-  +#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242
-  +#246#233#242#246#233#242#246#233#242#246#233#242#246#221#231#235#184#196#202
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#167'}e'#172#133'm'#219#204#189#222#209#195#226#214#201
-  +#228#217#205#226#214#201#222#209#195#219#204#189#172#133'm'#167'}e'#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#166'}d'#138#136#145'x'#171#222#159
-  +#182#204#191#190#189#209#194#178#191#190#189#159#182#204'x'#171#222#138#136
-  +#145#166'}d'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#167'}e'#168
-  +#138'v'#189#185#176#185#183#177#187#186#180#188#187#182#187#186#180#185#183
-  +#177#189#185#176#168#138'v'#167'}e'#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#217#224#226#224#229#231#254#254#254#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#254#254#254#224#229#231#217#224#226#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#167'}e'#172#133'm'#219#204#189
-  +#222#209#195#226#214#201#228#217#205#226#214#201#222#209#195#219#204#189#172
-  +#133'm'#167'}e'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#167'}e'#172
-  +#133'm'#219#204#189#222#209#195#226#214#201#228#217#205#226#214#201#222#209
-  +#195#219#204#189#172#133'm'#167'}e'#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#167'}e'#172#133'm'#219#204#189#222#209#195#226#214#201#228#217#205
-  +#226#214#201#222#209#195#219#204#189#172#133'm'#167'}e'#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#213#220#219#220#226#225#254#254#254#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#254#254#254#220#226#225
-  +#213#220#219#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255'V'#17#0#214
-  +#226#226#218#222#227#220#223#227#221#226#229#221#227#226#223#229#228#224#230
-  +#229#222#231#228#229#232#237#230#233#237#232#238#237'V'#17#0#255#0#255#255#0
-  +#255#255#0#255'X'#19#0'l'#177#240'o'#172#236'm'#174#235'q'#176#236'r'#177#237
-  +'t'#177#239's'#182#239't'#181#236'u'#178#240'v'#181#241'y'#184#245'T'#18#0
-  +#255#0#255#255#0#255#255#0#255'V'#18#0#187#201#199#185#199#205#184#197#199
-  +#184#199#201#187#199#201#186#199#201#188#200#202#188#199#203#188#202#201#193
-  +#202#206#193#205#205'W'#19#0#255#0#255#255#0#255#255#0#255#170#182#184#227
-  +#239#239#225#237#239#227#239#239#226#238#238#225#237#239#226#238#238#226#238
-  +#240#226#238#238#225#237#239#225#237#239#227#239#239#170#182#186#255#0#255
-  +#255#0#255#255#0#255'T'#18#0#206#215#219#209#214#217#209#214#215#210#215#218
-  +#212#215#219#209#218#221#216#223#220#217#222#221#220#226#225#214#228#227#224
-  ,#230#235'T'#18#0#255#0#255#255#0#255#255#0#255'X'#19#0'n'#176#241'n'#171#235
-  +'p'#173#235'm'#179#232's'#179#237'r'#180#239'r'#180#239's'#181#240'v'#179#243
-  +'t'#183#240'u'#184#247'Y'#20#1#255#0#255#255#0#255#255#0#255'W'#19#0#188#201
-  +#203#187#199#205#183#198#200#184#198#197#186#199#201#188#201#203#189#199#199
-  +#189#200#204#189#198#208#183#201#202#192#203#211'X'#20#1#255#0#255#255#0#255
-  +#255#0#255#169#182#184#227#239#239#226#238#238#225#237#237#226#238#238#226
-  +#238#238#226#238#238#224#236#236#229#238#241#225#237#239#225#237#237#227#239
-  +#239#169#182#184#255#0#255#255#0#255#255#0#255'T'#18#0#206#215#219#209#214
-  +#217#209#214#215#210#215#218#212#215#219#209#218#221#216#223#220#217#222#221
-  +#220#226#225#214#228#227#224#230#235'T'#18#0#255#0#255#255#0#255#255#0#255'X'
-  +#19#0'n'#176#241'n'#171#235'p'#173#235'm'#179#232's'#179#237'r'#180#239'r'
-  +#180#239's'#181#240'v'#179#243't'#183#240'u'#184#247'Y'#20#1#255#0#255#255#0
-  +#255#255#0#255'W'#19#0#188#201#203#187#199#205#183#198#200#184#198#197#186
-  +#199#201#188#201#203#189#199#199#189#200#204#189#198#208#183#201#202#192#203
-  +#211'X'#20#1#255#0#255#255#0#255#255#0#255#169#182#184#227#239#239#226#238
-  +#238#225#237#237#226#238#238#226#238#238#226#238#238#224#236#236#229#238#241
-  +#225#237#239#225#237#237#227#239#239#169#182#184#255#0#255#255#0#255#255#0
-  +#255'['#137'uM'#138'm'#180#222#229#246#255#255#246#255#255#246#255#255#246
-  +#255#255#246#255#255#246#255#255#246#255#255#246#255#255#246#255#255#201#235
-  +#238'M'#138'm['#138'v'#255#0#255'['#137'u|'#140#137#149#197#252#149#197#252
-  +#149#197#252#149#197#252#149#197#252#149#197#252#149#197#252#149#197#252#149
-  +#197#252#149#197#252#149#197#252'|'#140#137'['#138'v'#255#0#255'['#137'u@z`'
-  +#145#167#192#178#204#222#179#205#223#180#205#223#180#205#223#180#205#223#180
-  +#205#223#180#205#223#180#205#223#180#205#223#164#178#201'C|b['#138'v'#255#0
-  +#255#184#196#202#201#211#217#221#231#235#233#242#246#233#242#246#233#242#246
-  +#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#233#242#246#225
-  +#235#239#201#211#217#184#196#202#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#168#127'g'#148
-  +'aC'#178#142'v'#200#177#157#214#198#180#200#177#157#178#142'v'#148'aC'#168
-  +#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#168#127'g'#131'jd|'#144#173'l'#160#214']'#164#233'l'#160#214'|'#144#173#131
-  +'jd'#168#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#168#127'g'#148'hN'#170#146#129#179#169#158#182#178#170#179#169#158
-  +#170#146#129#148'hN'#168#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#217#224#226#208#217#219#228#233#234#244#246#247#254
-  +#254#254#244#246#247#228#233#234#208#217#219#217#224#226#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#168#127'g'#148'aC'#178#142
-  +'v'#200#177#157#214#198#180#200#177#157#178#142'v'#148'aC'#168#127'g'#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#168#127'g'
-  +#148'aC'#178#142'v'#200#177#157#214#198#180#200#177#157#178#142'v'#148'aC'
-  +#168#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#168#127'g'#148'aC'#178#142'v'#200#177#157#214#198#180#200#177#157#178
-  +#142'v'#148'aC'#168#127'g'#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#213#220#219#203#212#210#225#230#229#243#245#245#253#254
-  +#254#243#245#245#225#230#229#203#212#210#213#220#219#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0
-  +'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0'V'#17#0#255#0#255
-  +#255#0#255#255#0#255'^'#17#1'W'#19#0'X'#20#1'Z'#19#0'X'#19#0'['#19#1'Y'#18#0
-  +'['#20#0'V'#21#0'X'#19#0'X'#21#0'V'#17#0'X'#21#0#255#0#255#255#0#255#255#0
-  +#255'W'#18#1'X'#20#1'V'#19#0'Y'#21#2'Z'#18#1'W'#19#0'X'#19#0'X'#19#0'Y'#17#0
-  +'V'#17#0'W'#16#2'W'#19#0'U'#19#0#255#0#255#255#0#255#255#0#255#168#183#185
-  +#170#184#183#170#183#185#170#183#185#168#183#185#169#184#186#169#185#184#170
-  +#183#185#171#184#186#168#183#186#169#184#186#169#182#184#171#183#187#255#0
-  +#255#255#0#255#255#0#255'T'#18#0'X'#19#2'S'#17#0'U'#19#1'W'#19#0'X'#19#0'Q'
-  +#19#1'T'#15#0'W'#19#0'V'#18#0'S'#17#0'W'#18#0'W'#18#1#255#0#255#255#0#255#255
-  +#0#255'_'#19#1'X'#19#0'Z'#21#2'Z'#20#0'X'#19#0'X'#17#3'U'#19#0'Z'#18#1'X'#19
-  +#0'['#20#0'Q'#20#0'Y'#20#1'W'#18#0#255#0#255#255#0#255#255#0#255'X'#19#2'W'
-  +#19#0'X'#20#1'Z'#18#0']'#18#4'X'#18#1'T'#21#0'Z'#18#0'S'#19#1'X'#19#0'U'#23#0
-  +'X'#18#1'W'#18#0#255#0#255#255#0#255#255#0#255#171#184#186#171#184#186#170
-  +#183#185#171#184#186#168#181#183#170#183#185#169#182#184#172#185#187#169#181
-  +#185#171#184#186#171#184#186#170#183#185#170#185#188#255#0#255#255#0#255#255
-  +#0#255'T'#18#0'X'#19#2'S'#17#0'U'#19#1'W'#19#0'X'#19#0'Q'#19#1'T'#15#0'W'#19
-  +#0'V'#18#0'S'#17#0'W'#18#0'W'#18#1#255#0#255#255#0#255#255#0#255'_'#19#1'X'
-  ,#19#0'Z'#21#2'Z'#20#0'X'#19#0'X'#17#3'U'#19#0'Z'#18#1'X'#19#0'['#20#0'Q'#20#0
-  +'Y'#20#1'W'#18#0#255#0#255#255#0#255#255#0#255'X'#19#2'W'#19#0'X'#20#1'Z'#18
-  +#0']'#18#4'X'#18#1'T'#21#0'Z'#18#0'S'#19#1'X'#19#0'U'#23#0'X'#18#1'W'#18#0
-  +#255#0#255#255#0#255#255#0#255#171#184#186#171#184#186#170#183#185#171#184
-  +#186#168#181#183#170#183#185#169#182#184#172#185#187#169#181#185#171#184#186
-  +#171#184#186#170#183#185#170#185#188#255#0#255#255#0#255#255#0#255#209#196
-  +#219'['#137'u#oL'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#24'i'
-  +'DO'#131'm'#213#201#223#255#0#255#222#196#200'['#137'u#oL'#6'b7'#6'b7'#6'b7'
-  +#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#24'iDO'#131'm'#226#201#205#255#0#255#209
-  +#196#219'['#137'u#oL'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'#6'b7'
-  +#24'iDO'#131'm'#213#201#223#255#0#255#255#255#255#184#196#202#184#196#202#184
-  +#196#202#184#196#202#184#196#202#184#196#202#184#196#202#184#196#202#184#196
-  +#202#184#196#202#184#196#202#184#196#202#184#196#202#255#255#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'#130'F%q-'#8#130'F%'#160's'
-  +'Y'#202#177#162#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'#130'F%q-'#8#130'F%'#160's'
-  +'Y'#202#177#162#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'#130'F%q-'#8#130'F%'#160's'
-  +'Y'#202#177#162#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#233#237#238#213#221#222#197#208#210#188#200
-  +#203#197#208#210#213#221#222#233#237#238#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'
-  +#130'F%q-'#8#130'F%'#160'sY'#202#177#162#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'
-  +#130'F%q-'#8#130'F%'#160'sY'#202#177#162#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#202#177#162#160'sY'
-  +#130'F%q-'#8#130'F%'#160'sY'#202#177#162#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#208#216#215
-  +#190#201#199#180#192#190#190#201#199#208#216#215#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  ,#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#0#0
-]);
-LazarusResources.Add('VT_MOVENS_BMP','BMP',[
-  'BM6'#12#0#0#0#0#0#0'6'#0#0#0'('#0#0#0' '#0#0#0' '#0#0#0#1#0#24#0#0#0#0#0#0#12
-  +#0#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0
-  +#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255
-  +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  ,#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0
-  +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255
-  +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  ,#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-]);
-LazarusResources.Add('VT_MOVEEW_BMP','BMP',[
-  'BM6'#12#0#0#0#0#0#0'6'#0#0#0'('#0#0#0' '#0#0#0' '#0#0#0#1#0#24#0#0#0#0#0#0#12
-  +#0#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#255
-  +#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255
-  +#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0
-  +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255
-  +#255#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255
-  +#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255
-  +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255
-  +#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0
-  ,#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0
-  +#0#255#255#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0
-  +#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255
-  +#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0
-  +#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255
-  +#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#255#255#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#255#255#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  ,#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-]);
-LazarusResources.Add('VT_MOVEALL_BMP','BMP',[
-  'BM6'#12#0#0#0#0#0#0'6'#0#0#0'('#0#0#0' '#0#0#0' '#0#0#0#1#0#24#0#0#0#0#0#0#12
-  +#0#0#18#11#0#0#18#11#0#0#0#0#0#0#0#0#0#0#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0
-  +#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255
-  +#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0
-  +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#255#255#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0
-  +#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0
-  +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0
-  +#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#255
-  +#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0
-  +#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  ,#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255
-  +#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255
-  +#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255
-  +#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#255
-  +#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0
-  +#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0
-  +#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0
-  +#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0
-  +#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255
-  +#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0
-  +#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#255#255#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0
-  +#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#255#255#0#0#0#255#255#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#255#255#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
-  +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255
-  +#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
-  +#0#0#0#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255
-  +#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#255
-  +#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#255#255#0#0#0#0#0
-  +#0#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#255#255#255#255#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  ,#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255
-  +#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0#255#255#0
-  +#255#255#0#255#255#0#255#255#0#255
-]);

+ 0 - 77
components/virtualtreeview/virtualtreeview_package.lpk

@@ -1,77 +0,0 @@
-<?xml version="1.0"?>
-<CONFIG>
-  <Package Version="4">
-    <Name Value="virtualtreeview_package"/>
-    <AddToProjectUsesSection Value="True"/>
-    <Author Value="Mike Lischke (LCL Port: Luiz Américo)"/>
-    <CompilerOptions>
-      <Version Value="11"/>
-      <SearchPaths>
-        <IncludeFiles Value="include/intf/$(LCLWidgetType);units;include/intf"/>
-        <OtherUnitFiles Value="units/$(LCLWidgetType)"/>
-        <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
-      </SearchPaths>
-      <Parsing>
-        <SyntaxOptions>
-          <UseAnsiStrings Value="False"/>
-        </SyntaxOptions>
-      </Parsing>
-      <Other>
-        <CompilerPath Value="$(CompPath)"/>
-      </Other>
-    </CompilerOptions>
-    <Description Value="Virtual Treeview is an advanced component originally created for Delphi
-"/>
-    <License Value=" Mozilla Public License 1.1 (MPL 1.1) or GNU Lesser General Public License
-"/>
-    <Version Major="4" Minor="8" Release="7" Build="3"/>
-    <Files Count="7">
-      <Item1>
-        <Filename Value="virtualtrees.lrs"/>
-        <Type Value="LRS"/>
-      </Item1>
-      <Item2>
-        <Filename Value="VirtualTrees.pas"/>
-        <UnitName Value="VirtualTrees"/>
-      </Item2>
-      <Item3>
-        <Filename Value="VTHeaderPopup.pas"/>
-        <UnitName Value="VTHeaderPopup"/>
-      </Item3>
-      <Item4>
-        <Filename Value="registervirtualtreeview.pas"/>
-        <HasRegisterProc Value="True"/>
-        <UnitName Value="registervirtualtreeview"/>
-      </Item4>
-      <Item5>
-        <Filename Value="ideicons.lrs"/>
-        <Type Value="LRS"/>
-      </Item5>
-      <Item6>
-        <Filename Value="VTConfig.inc"/>
-        <Type Value="Include"/>
-      </Item6>
-      <Item7>
-        <Filename Value="VTGraphics.pas"/>
-        <UnitName Value="VTGraphics"/>
-      </Item7>
-    </Files>
-    <Type Value="RunAndDesignTime"/>
-    <RequiredPkgs Count="2">
-      <Item1>
-        <PackageName Value="lclextensions_package"/>
-        <MinVersion Minor="5" Valid="True"/>
-      </Item1>
-      <Item2>
-        <PackageName Value="LCL"/>
-      </Item2>
-    </RequiredPkgs>
-    <UsageOptions>
-      <UnitPath Value="$(PkgOutDir)"/>
-    </UsageOptions>
-    <PublishOptions>
-      <Version Value="2"/>
-      <IgnoreBinaries Value="False"/>
-    </PublishOptions>
-  </Package>
-</CONFIG>

+ 0 - 22
components/virtualtreeview/virtualtreeview_package.pas

@@ -1,22 +0,0 @@
-{ This file was automatically created by Lazarus. Do not edit!
-  This source is only used to compile and install the package.
- }
-
-unit virtualtreeview_package; 
-
-interface
-
-uses
-  VirtualTrees, VTHeaderPopup, registervirtualtreeview, VTGraphics, 
-  LazarusPackageIntf;
-
-implementation
-
-procedure Register; 
-begin
-  RegisterUnit('registervirtualtreeview', @registervirtualtreeview.Register); 
-end; 
-
-initialization
-  RegisterPackage('virtualtreeview_package', @Register); 
-end.

+ 0 - 87
components/virtualtreeview/virtualtreeview_package_doublecmd.lpk

@@ -1,87 +0,0 @@
-<?xml version="1.0"?>
-<CONFIG>
-  <Package Version="4">
-    <Name Value="virtualtreeview_package_doublecmd"/>
-    <AddToProjectUsesSection Value="True"/>
-    <Author Value="Mike Lischke (LCL Port: Luiz Américo)"/>
-    <CompilerOptions>
-      <Version Value="11"/>
-      <SearchPaths>
-        <IncludeFiles Value="include/intf/$(LCLWidgetType);units;include/intf"/>
-        <OtherUnitFiles Value="units/$(LCLWidgetType)"/>
-        <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)"/>
-      </SearchPaths>
-      <Parsing>
-        <SyntaxOptions>
-          <UseAnsiStrings Value="False"/>
-        </SyntaxOptions>
-      </Parsing>
-      <CodeGeneration>
-        <Checks>
-          <RangeChecks Value="True"/>
-          <OverflowChecks Value="True"/>
-        </Checks>
-      </CodeGeneration>
-      <Linking>
-        <Debugging>
-          <DebugInfoType Value="dsDwarf2Set"/>
-        </Debugging>
-      </Linking>
-      <Other>
-        <CompilerPath Value="$(CompPath)"/>
-      </Other>
-    </CompilerOptions>
-    <Description Value="Virtual Treeview is an advanced component originally created for Delphi
-"/>
-    <License Value=" Mozilla Public License 1.1 (MPL 1.1) or GNU Lesser General Public License
-"/>
-    <Version Major="4" Minor="8" Release="7" Build="1"/>
-    <Files Count="7">
-      <Item1>
-        <Filename Value="virtualtrees.lrs"/>
-        <Type Value="LRS"/>
-      </Item1>
-      <Item2>
-        <Filename Value="VirtualTrees.pas"/>
-        <UnitName Value="VirtualTrees"/>
-      </Item2>
-      <Item3>
-        <Filename Value="VTHeaderPopup.pas"/>
-        <UnitName Value="VTHeaderPopup"/>
-      </Item3>
-      <Item4>
-        <Filename Value="registervirtualtreeview.pas"/>
-        <HasRegisterProc Value="True"/>
-        <UnitName Value="registervirtualtreeview"/>
-      </Item4>
-      <Item5>
-        <Filename Value="ideicons.lrs"/>
-        <Type Value="LRS"/>
-      </Item5>
-      <Item6>
-        <Filename Value="VTConfig.inc"/>
-        <Type Value="Include"/>
-      </Item6>
-      <Item7>
-        <Filename Value="VTGraphics.pas"/>
-        <UnitName Value="VTGraphics"/>
-      </Item7>
-    </Files>
-    <Type Value="RunAndDesignTime"/>
-    <RequiredPkgs Count="2">
-      <Item1>
-        <PackageName Value="lclextensions_package_doublecmd"/>
-      </Item1>
-      <Item2>
-        <PackageName Value="LCL"/>
-      </Item2>
-    </RequiredPkgs>
-    <UsageOptions>
-      <UnitPath Value="$(PkgOutDir)"/>
-    </UsageOptions>
-    <PublishOptions>
-      <Version Value="2"/>
-      <IgnoreBinaries Value="False"/>
-    </PublishOptions>
-  </Package>
-</CONFIG>

+ 0 - 22
components/virtualtreeview/virtualtreeview_package_doublecmd.pas

@@ -1,22 +0,0 @@
-{ This file was automatically created by Lazarus. Do not edit!
-  This source is only used to compile and install the package.
- }
-
-unit virtualtreeview_package_doublecmd;
-
-interface
-
-uses
-  VirtualTrees, VTHeaderPopup, registervirtualtreeview, VTGraphics, 
-  LazarusPackageIntf;
-
-implementation
-
-procedure Register;
-begin
-  RegisterUnit('registervirtualtreeview', @registervirtualtreeview.Register);
-end;
-
-initialization
-  RegisterPackage('virtualtreeview_package_doublecmd', @Register);
-end.

+ 0 - 85
components/virtualtreeview/vtlogger.pas

@@ -1,85 +0,0 @@
-unit vtlogger;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  multiloglcl, multilog;
-
-const
-  //lc stands for LogClass
-  //it's possible to define the constants to suit any need
-  lcAll = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
-  lcDebug = 0;
-  lcError = 1;
-  lcInfo = 2;
-  lcWarning = 3;
-  
-  lcEvents = 4;
-  lcPaint = 5;
-  lcPaintHeader = 6;
-  lcDummyFunctions = 7;
-  lcMessages = 8;
-  lcPaintSelection = 9;
-  lcSetCursor = 10;//it generates a lot of messages. so it will be debugged alone
-  lcPaintBitmap = 11;
-  lcScroll = 12;
-  lcPaintDetails = 13;
-  lcCheck = 14;
-  lcEditLink = 15;
-  lcEraseBkgnd = 16;
-  lcColumnPosition = 17;
-  lcTimer = 18;
-  lcDrag = 19;
-  lcOle = 20;
-  lcPanning = 21;
-  lcHeaderOffset = 22;
-  lcSelection = 23;
-  lcAlphaBlend = 24;
-  lcHint = 25;
-  lcMouseEvent = 26;
-  
-var
-  Logger: TLCLLogger;
-
-
-  function GetSelectedNodes(Sender: TLogger; Data: Pointer; var DoSend: Boolean): String;
-  
-implementation
-
-uses
-  VirtualTrees, sysutils;
-  
-type
-  TNodeData = record
-    Title: String;
-  end;
-  PNodeData = ^TNodeData;
-
-  function GetSelectedNodes(Sender: TLogger; Data: Pointer; var DoSend: Boolean): String;
-  var
-    i: Integer;
-    TempNode: PVirtualNode;
-  begin
-    with TBaseVirtualTree(Data) do
-    begin
-      Result:='SelectedCount: '+IntToStr(SelectedCount)+LineEnding;
-      TempNode:=GetFirstSelected;
-      if TempNode = nil then exit;
-      Result:=Result+PNodeData(GetNodeData(TempNode))^.Title+LineEnding;
-      for i:= 1 to SelectedCount -1 do
-      begin
-        TempNode:=GetNextSelected(TempNode);
-        Result:=Result+PNodeData(GetNodeData(TempNode))^.Title+LineEnding;
-      end;
-    end;
-  end;
-
-
-initialization
-  Logger:=TLCLLogger.Create;
-finalization
-  Logger.Free;
-end.
-

+ 0 - 2039
src/fileviews/ucolumnsfileviewvtv.pas

@@ -1,2039 +0,0 @@
-unit uColumnsFileViewVtv;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  Classes, SysUtils, Graphics, Controls, Forms, ExtCtrls, Grids,
-  LMessages, LCLIntf, LCLType, Menus, uTypes,
-  uFile,
-  uFileProperty,
-  uFileView,
-  uFileViewWithMainCtrl,
-  uFileSource,
-  uDisplayFile,
-  uColumns,
-  uFileSorting,
-  DCXmlConfig,
-  DCClassesUtf8,
-  VirtualTrees;
-
-type
-  TFunctionDime = function (AColor: TColor): TColor of object;
-
-  TColumnsSortDirections = array of uFileSorting.TSortDirection;
-  TColumnsFileViewVTV = class;
-
-  TNodeRange = record
-    First: PVirtualNode;
-    Last: PVirtualNode;
-  end;
-
-  TColumnsDrawTreeRecord = record end; // We don't need anything in it, just Node^.Index.
-  PColumnsDrawTreeRecord = ^TColumnsDrawTreeRecord;
-
-  TColumnResized = procedure (Sender: TObject; ColumnIndex: Integer; ColumnNewSize: Integer) of object;
-
-  { TColumnsDrawTree }
-
-  TColumnsDrawTree = class(TVirtualDrawTree)
-  private
-    ColumnsView: TColumnsFileViewVTV;
-
-    function GetGridHorzLine: Boolean;
-    function GetGridVertLine: Boolean;
-    procedure SetGridHorzLine(const AValue: Boolean);
-    procedure SetGridVertLine(const AValue: Boolean);
-
-    function GetNodeFile(Node: PVirtualNode): TDisplayFile;
-    function GetVisibleNodes: TNodeRange;
-    procedure SetAllRowsHeights(ARowHeight: Cardinal);
-
-  protected
-    function CanAutoScroll: Boolean; override;
-    function CanScroll(const ClientMousePos: TPoint): Boolean; override;
-    function DetermineScrollDirections(X, Y: Integer): TScrollDirections; override;
-    function DoKeyAction(var CharCode: Word; var Shift: TShiftState): Boolean; override;
-    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,Y: Integer); override;
-    procedure MouseUp(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
-    procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
-    procedure WMKeyDown(var Message: TLMKeyDown); message LM_KEYDOWN;
-
-    procedure InitializeWnd; override;
-    procedure FinalizeWnd; override;
-
-    procedure DoPaintNode(var PaintInfo: TVTPaintInfo); override;
-
-  public
-    ColumnsOwnDim: TFunctionDime;
-
-    constructor Create(AOwner: TComponent; AParent: TWinControl); reintroduce;
-    procedure AfterConstruction; override;
-
-    procedure UpdateView;
-
-    function MouseOnGrid(X, Y: LongInt): Boolean;
-
-    // Returns height of all the header rows.
-    function GetHeaderHeight: Integer;
-    function GetVisibleIndexes: TRange;
-
-    property GridVertLine: Boolean read GetGridVertLine write SetGridVertLine;
-    property GridHorzLine: Boolean read GetGridHorzLine write SetGridHorzLine;
-  end;
-
-  { TColumnsFileViewVTV }
-
-  TColumnsFileViewVTV = class(TFileViewWithMainCtrl)
-  private
-    FColumnsSortDirections: TColumnsSortDirections;
-    FFileNameColumn: Integer;
-    FExtensionColumn: Integer;
-
-    pmColumnsMenu: TPopupMenu;
-    dgPanel: TColumnsDrawTree;
-    FOnColumnResized: TColumnResized;
-
-    function GetColumnsClass: TPanelColumnsClass;
-
-    procedure SetRowCount(Count: Integer);
-    procedure SetFilesDisplayItems;
-    procedure SetColumns;
-
-    procedure MakeVisible(Node: PVirtualNode);
-    procedure DoSelectionChanged(Node: PVirtualNode); overload;
-
-    {en
-       Format and cache all columns strings for the file.
-    }
-    procedure MakeColumnsStrings(AFile: TDisplayFile);
-    procedure MakeColumnsStrings(AFile: TDisplayFile; ColumnsClass: TPanelColumnsClass);
-    procedure ClearAllColumnsStrings;
-    procedure EachViewUpdateColumns(AFileView: TFileView; UserData: Pointer);
-
-    {en
-       Translates file sorting by functions to sorting directions of columns.
-    }
-    procedure SetColumnsSortDirections;
-
-    {en
-       Checks which file properties are needed for displaying.
-    }
-    function GetFilePropertiesNeeded: TFilePropertiesTypes;
-
-    // -- Events --------------------------------------------------------------
-
-    procedure dgPanelAdvancedHeaderDraw(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
-      const Elements: THeaderPaintElements);
-    procedure dgPanelAfterItemPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect);
-    procedure dgPanelBeforeItemErase(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect; var ItemColor: TColor; var EraseAction: TItemEraseAction);
-    procedure dgPanelHeaderDrawQueryElements(Sender: TVTHeader; var PaintInfo: THeaderPaintInfo;
-      var Elements: THeaderPaintElements);
-    procedure dgPanelDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState;
-      const Pt: TPoint; Mode: TDropMode; var Effect: LongWord; var Accept: Boolean);
-    procedure dgPanelDragDrop(Sender: TBaseVirtualTree; Source: TObject;
-      Formats: TFormatArray; Shift: TShiftState; const Pt: TPoint; var Effect: LongWord; Mode: TDropMode);
-    procedure dgPanelFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
-    procedure dgPanelFocusChanging(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode; OldColumn,
-      NewColumn: TColumnIndex; var Allowed: Boolean);
-    procedure dgPanelHeaderClick(Sender: TVTHeader; Column: TColumnIndex;
-      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
-    procedure dgPanelMouseWheelUp(Sender: TObject; Shift: TShiftState;
-                                  MousePos: TPoint; var Handled: Boolean);
-    procedure dgPanelMouseWheelDown(Sender: TObject; Shift: TShiftState;
-                                  MousePos: TPoint; var Handled: Boolean);
-    procedure dgPanelScroll(Sender: TBaseVirtualTree; DeltaX, DeltaY: Integer);
-    procedure dgPanelResize(Sender: TObject);
-    procedure dgPanelColumnResize(Sender: TVTHeader; Column: TColumnIndex);
-    procedure ColumnsMenuClick(Sender: TObject);
-
-  protected
-    procedure CreateDefault(AOwner: TWinControl); override;
-
-    procedure BeforeMakeFileList; override;
-    procedure ClearAfterDragDrop; override;
-    procedure DisplayFileListChanged; override;
-    procedure DoColumnResized(Sender: TObject; ColumnIndex: Integer; ColumnNewSize: Integer);
-    procedure DoFileUpdated(AFile: TDisplayFile; UpdatedProperties: TFilePropertiesTypes = []); override;
-    procedure DoHandleKeyDown(var Key: Word; Shift: TShiftState); override;
-    procedure DoUpdateView; override;
-    function GetActiveFileIndex: PtrInt; override;
-    function GetFileIndexFromCursor(X, Y: Integer; out AtFileList: Boolean): PtrInt; override;
-    function GetFileRect(FileIndex: PtrInt): TRect; override;
-    function GetVisibleFilesIndexes: TRange; override;
-    procedure RedrawFile(FileIndex: PtrInt); override;
-    procedure RedrawFile(DisplayFile: TDisplayFile); override;
-    procedure RedrawFiles; override;
-    procedure SetActiveFile(FileIndex: PtrInt); override;
-    procedure SetSorting(const NewSortings: TFileSortings); override;
-    procedure ShowRenameFileEdit(AFile: TFile); override;
-    procedure UpdateRenameFileEditPosition; override;
-
-  public
-    ActiveColm: String;
-    ActiveColmSlave: TPanelColumnsClass;
-    isSlave:boolean;
-//---------------------
-
-    constructor Create(AOwner: TWinControl; AFileSource: IFileSource; APath: String; AFlags: TFileViewFlags = []); override;
-    constructor Create(AOwner: TWinControl; AFileView: TFileView; AFlags: TFileViewFlags = []); override;
-    constructor Create(AOwner: TWinControl; AConfig: TXmlConfig; ANode: TXmlNode; AFlags: TFileViewFlags = []); override;
-
-    destructor Destroy; override;
-
-    function Clone(NewParent: TWinControl): TColumnsFileViewVTV; override;
-    procedure CloneTo(FileView: TFileView); override;
-
-    procedure AddFileSource(aFileSource: IFileSource; aPath: String); override;
-
-    procedure LoadConfiguration(Section: String; TabIndex: Integer); override;
-    procedure LoadConfiguration(AConfig: TXmlConfig; ANode: TXmlNode); override;
-    procedure SaveConfiguration(AConfig: TXmlConfig; ANode: TXmlNode; ASaveHistory: Boolean); override;
-
-    procedure UpdateColumnsView;
-    procedure SetGridFunctionDim(ExternalDimFunction: TFunctionDime);
-
-    property OnColumnResized: TColumnResized read FOnColumnResized write FOnColumnResized;
-  published
-    procedure cm_CopyFileDetailsToClip(const Params: array of string);
-
-  end;
-
-  TColumnsFileView = TColumnsFileViewVTV;
-
-implementation
-
-uses
-  LazUTF8, Clipbrd, uLng, uGlobs, uPixmapManager, uDebug,
-  DCStrUtils, uDCUtils, math, fMain, fOptions, uClipboard,
-  uFileViewNotebook,
-  uOrderedFileView,
-  uFileSourceProperty,
-  uKeyboard,
-  uFileFunctions,
-  uFormCommands,
-  uFileViewWithGrid,
-  fOptionsCustomColumns;
-
-type
-  TEachViewCallbackReason = (evcrUpdateColumns);
-  TEachViewCallbackMsg = record
-    Reason: TEachViewCallbackReason;
-    UpdatedColumnsSetName: String;
-    NewColumnsSetName: String; // If columns name renamed
-  end;
-  PEachViewCallbackMsg = ^TEachViewCallbackMsg;
-
-procedure TColumnsFileViewVTV.SetSorting(const NewSortings: TFileSortings);
-begin
-  inherited SetSorting(NewSortings);
-  SetColumnsSortDirections;
-end;
-
-procedure TColumnsFileViewVTV.LoadConfiguration(Section: String; TabIndex: Integer);
-var
-  ColumnsClass: TPanelColumnsClass;
-  SortCount: Integer;
-  SortColumn: Integer;
-  SortDirection: uFileSorting.TSortDirection;
-  i: Integer;
-  sIndex: String;
-  NewSorting: TFileSortings = nil;
-  Column: TPanelColumn;
-  SortFunctions: TFileFunctions;
-begin
-  sIndex := IntToStr(TabIndex);
-
-  ActiveColm := gIni.ReadString(Section, sIndex + '_columnsset', 'Default');
-
-  // Load sorting options.
-  ColumnsClass := GetColumnsClass;
-  SortCount := gIni.ReadInteger(Section, sIndex + '_sortcount', 0);
-  for i := 0 to SortCount - 1 do
-  begin
-    SortColumn := gIni.ReadInteger(Section, sIndex + '_sortcolumn' + IntToStr(i), -1);
-    if (SortColumn >= 0) and (SortColumn < ColumnsClass.ColumnsCount) then
-    begin
-      Column := ColumnsClass.GetColumnItem(SortColumn);
-      if Assigned(Column) then
-      begin
-        SortFunctions := Column.GetColumnFunctions;
-        SortDirection := uFileSorting.TSortDirection(gIni.ReadInteger(Section, sIndex + '_sortdirection' + IntToStr(i), Integer(sdNone)));
-        AddSorting(NewSorting, SortFunctions, SortDirection);
-      end;
-    end;
-  end;
-  inherited SetSorting(NewSorting);
-end;
-
-procedure TColumnsFileViewVTV.LoadConfiguration(AConfig: TXmlConfig; ANode: TXmlNode);
-var
-  ColumnsClass: TPanelColumnsClass;
-  SortColumn: Integer;
-  SortDirection: uFileSorting.TSortDirection;
-  ColumnsViewNode: TXmlNode;
-  NewSorting: TFileSortings = nil;
-  Column: TPanelColumn;
-  SortFunctions: TFileFunctions;
-begin
-  inherited LoadConfiguration(AConfig, ANode);
-
-  // Try to read new view-specific node.
-  ColumnsViewNode := AConfig.FindNode(ANode, 'ColumnsView');
-  if Assigned(ColumnsViewNode) then
-    ANode := ColumnsViewNode;
-
-  ActiveColm := AConfig.GetValue(ANode, 'ColumnsSet', 'Default');
-
-  // Load sorting options.
-  ColumnsClass := GetColumnsClass;
-  ANode := ANode.FindNode('Sorting');
-  if Assigned(ANode) then
-  begin
-    ANode := ANode.FirstChild;
-    while Assigned(ANode) do
-    begin
-      if ANode.CompareName('Sort') = 0 then
-      begin
-        if AConfig.TryGetValue(ANode, 'Column', SortColumn) and
-           (SortColumn >= 0) and (SortColumn < ColumnsClass.ColumnsCount) then
-        begin
-          Column := ColumnsClass.GetColumnItem(SortColumn);
-          if Assigned(Column) then
-          begin
-            SortFunctions := Column.GetColumnFunctions;
-            SortDirection := uFileSorting.TSortDirection(AConfig.GetValue(ANode, 'Direction', Integer(sdNone)));
-            AddSorting(NewSorting, SortFunctions, SortDirection);
-          end;
-        end
-        else
-          DCDebug('Invalid entry in configuration: ' + AConfig.GetPathFromNode(ANode) + '.');
-      end;
-      ANode := ANode.NextSibling;
-    end;
-    inherited SetSorting(NewSorting);
-  end;
-end;
-
-procedure TColumnsFileViewVTV.SaveConfiguration(AConfig: TXmlConfig;
-  ANode: TXmlNode; ASaveHistory: Boolean);
-begin
-  inherited SaveConfiguration(AConfig, ANode, ASaveHistory);
-
-  AConfig.SetAttr(ANode, 'Type', 'columns');
-
-  ANode := AConfig.FindNode(ANode, 'ColumnsView', True);
-  AConfig.ClearNode(ANode);
-
-  AConfig.SetValue(ANode, 'ColumnsSet', ActiveColm);
-end;
-
-procedure TColumnsFileViewVTV.dgPanelDragOver(Sender: TBaseVirtualTree;
-  Source: TObject; Shift: TShiftState; State: TDragState;
-  const Pt: TPoint; Mode: TDropMode; var Effect: LongWord; var Accept: Boolean);
-begin
-  MainControlDragOver(Sender, Source, Pt.x, Pt.y, State, Accept);
-end;
-
-procedure TColumnsFileViewVTV.dgPanelDragDrop(Sender: TBaseVirtualTree;
-  Source: TObject;
-  Formats: TFormatArray; Shift: TShiftState;
-  const Pt: TPoint; var Effect: LongWord; Mode: TDropMode);
-begin
-  MainControlDragDrop(Sender, Source, Pt.x, Pt.y);
-end;
-
-procedure TColumnsFileViewVTV.dgPanelFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
-begin
-  dgPanel.TreeOptions.AutoOptions := dgPanel.TreeOptions.AutoOptions - [toDisableAutoscrollOnFocus];
-
-  if Assigned(Node) then
-    DoFileIndexChanged(Node^.Index);
-end;
-
-procedure TColumnsFileViewVTV.dgPanelFocusChanging(Sender: TBaseVirtualTree;
-  OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean);
-begin
-  if (OldColumn <> NewColumn) and (OldNode = NewNode) then
-    dgPanel.TreeOptions.AutoOptions := dgPanel.TreeOptions.AutoOptions + [toDisableAutoscrollOnFocus]
-  else
-    dgPanel.TreeOptions.AutoOptions := dgPanel.TreeOptions.AutoOptions - [toDisableAutoscrollOnFocus];
-end;
-
-procedure TColumnsFileViewVTV.dgPanelHeaderClick(Sender: TVTHeader; Column: TColumnIndex;
-  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
-var
-  ShiftState : TShiftState;
-  SortingDirection : uFileSorting.TSortDirection;
-  ColumnsClass: TPanelColumnsClass;
-  PanelColumn: TPanelColumn;
-  NewSorting: TFileSortings;
-  SortFunctions: TFileFunctions;
-  I : Integer;
-  Point: TPoint;
-  MI: TMenuItem;
-begin
-  case Button of
-    mbLeft:
-      begin
-        ColumnsClass := GetColumnsClass;
-        PanelColumn := ColumnsClass.GetColumnItem(Column);
-        if Assigned(PanelColumn) then
-        begin
-          NewSorting := Sorting;
-          SortFunctions := PanelColumn.GetColumnFunctions;
-          if Length(SortFunctions) = 0 then Exit;
-          ShiftState := GetKeyShiftStateEx;
-          if [ssShift, ssCtrl] * ShiftState = [] then
-          begin
-            SortingDirection := GetSortDirection(NewSorting, SortFunctions);
-            if SortingDirection = sdNone then
-            begin
-              // If there is no direction currently, sort "sdDescending" for size and date.
-    	      // Commonly, we search seek more often for most recent files then older any others.
-    	      // When sorting by size, often it is to find larger file to make room.
-    	      // Anyway, it makes DC like TC, and also, Windows Explorer do the same.
-              case SortFunctions[0] of
-                fsfSize, fsfModificationTime, fsfCreationTime, fsfLastAccessTime: SortingDirection:= uFileSorting.sdDescending;
-                else SortingDirection:= uFileSorting.sdAscending;
-              end;
-            end
-            else
-            begin
-              SortingDirection := ReverseSortDirection(SortingDirection);
-            end;
-            NewSorting := nil;
-          end
-          else
-          begin
-            // If there is no direction currently, sort "sdDescending" for size and date (see previous comment).
-            case SortFunctions[0] of
-              fsfSize, fsfModificationTime, fsfCreationTime, fsfLastAccessTime: SortingDirection:= uFileSorting.sdDescending;
-              else SortingDirection:= uFileSorting.sdAscending;
-            end;
-          end;
-
-          AddOrUpdateSorting(NewSorting, SortFunctions, SortingDirection);
-          SetSorting(NewSorting);
-        end;
-      end;
-
-    mbRight:
-      begin
-        //Load Columns into menu
-        pmColumnsMenu.Items.Clear;
-        if ColSet.Items.Count>0 then
-          begin
-            For I:=0 to ColSet.Items.Count-1 do
-              begin
-                MI:=TMenuItem.Create(pmColumnsMenu);
-                MI.Tag:=I;
-                MI.Caption:=ColSet.Items[I];
-                MI.Checked:=(ColSet.Items[I] = ActiveColm);
-                MI.OnClick:=@ColumnsMenuClick;
-                pmColumnsMenu.Items.Add(MI);
-              end;
-          end;
-
-        //-
-    	  MI:=TMenuItem.Create(pmColumnsMenu);
-    	  MI.Caption:='-';
-    	  pmColumnsMenu.Items.Add(MI);
-        //Configure custom columns
-    	  MI:=TMenuItem.Create(pmColumnsMenu);
-    	  MI.Tag:=1001;
-    	  MI.Caption:=rsMenuConfigureCustomColumns;
-    	  MI.OnClick:=@ColumnsMenuClick;
-    	  pmColumnsMenu.Items.Add(MI);
-
-        Point   := dgPanel.ClientToScreen(Classes.Point(0,0));
-        Point.X := Point.X + X - 50;
-        Point.Y := Point.Y + dgPanel.GetHeaderHeight;
-        pmColumnsMenu.PopUp(Point.X, Point.Y);
-      end;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.dgPanelAdvancedHeaderDraw(Sender: TVTHeader;
-  var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements);
-var
-  SortingDirection: uFileSorting.TSortDirection;
-  TitleX: Integer;
-  ColumnsSet: TPanelColumnsClass;
-  aCol: Integer;
-  iTextTop: Integer;
-  s: String;
-  aRect: TRect;
-begin
-  aCol  := PaintInfo.Column.Index;
-  aRect := PaintInfo.PaintRectangle;
-  // PaintRectangle is reduced by 2 pixels on each side even with owner draw,
-  // so revert this change.
-  InflateRect(aRect, 2, 2);
-
-  ColumnsSet := GetColumnsClass;
-
-  iTextTop := aRect.Top + (PaintInfo.Column.Owner.Header.Height - PaintInfo.TargetCanvas.TextHeight('Wg')) div 2;
-  TitleX   := 0;
-  s        := ColumnsSet.GetColumnTitle(ACol);
-
-  SortingDirection := FColumnsSortDirections[ACol];
-  if SortingDirection <> sdNone then
-  begin
-    TitleX := TitleX + gIconsSize;
-    PixMapManager.DrawBitmap(
-        PixMapManager.GetIconBySortingDirection(SortingDirection),
-        PaintInfo.TargetCanvas,
-        aRect.Left, aRect.Top + (PaintInfo.Column.Owner.Header.Height - gIconsSize) div 2);
-  end;
-
-  TitleX := max(TitleX, 4);
-
-  if gCutTextToColWidth then
-  begin
-    if (aRect.Right - aRect.Left) < TitleX then
-      // Column too small to display text.
-      Exit
-    else
-      while PaintInfo.TargetCanvas.TextWidth(s) - ((aRect.Right - aRect.Left) - TitleX) > 0 do
-        UTF8Delete(s, UTF8Length(s), 1);
-  end;
-
-  PaintInfo.TargetCanvas.Brush.Style := bsClear;
-  PaintInfo.TargetCanvas.TextOut(aRect.Left + TitleX, iTextTop, s);
-end;
-
-procedure TColumnsFileViewVTV.dgPanelAfterItemPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect);
-var
-  ColumnsSet: TPanelColumnsClass;
-  IsFocused: Boolean;
-
-  procedure DrawLines;
-  begin
-    // Draw focus rect.
-    if not ColumnsSet.UseFrameCursor and IsFocused and Active and ColumnsSet.UseCursorBorder then
-    begin
-      TargetCanvas.Pen.Color := ColumnsSet.CursorBorderColor;
-      TargetCanvas.Brush.Color := ColumnsSet.CursorBorderColor;
-      TargetCanvas.DrawFocusRect(ItemRect);
-    end;
-  end;
-begin
-  IsFocused := Node = dgPanel.FocusedNode;
-  ColumnsSet := GetColumnsClass;
-  DrawLines;
-end;
-
-procedure TColumnsFileViewVTV.dgPanelBeforeItemErase(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; const ItemRect: TRect; var ItemColor: TColor; var EraseAction: TItemEraseAction);
-begin
-  EraseAction := eaNone;
-end;
-
-procedure TColumnsFileViewVTV.dgPanelHeaderDrawQueryElements(Sender: TVTHeader;
-  var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements);
-begin
-  Elements := [hpeSortGlyph, hpeText];
-end;
-
-procedure TColumnsFileViewVTV.dgPanelMouseWheelUp(Sender: TObject;
-  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
-var
-  I: Integer;
-begin
-  Handled:= True;
-  if not IsLoadingFileList then
-  begin
-    case gScrollMode of
-      smLineByLine:
-        for I:= 1 to gWheelScrollLines do
-          dgPanel.Perform(LM_VSCROLL, SB_LINEUP, 0);
-      smPageByPage:
-        dgPanel.Perform(LM_VSCROLL, SB_PAGEUP, 0);
-      else
-        Handled:= False;
-    end;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.dgPanelMouseWheelDown(Sender: TObject;
-  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
-var
-  I: Integer;
-begin
-  Handled:= True;
-  if not IsLoadingFileList then
-  begin
-    case gScrollMode of
-      smLineByLine:
-        for I:= 1 to gWheelScrollLines do
-          dgPanel.Perform(LM_VSCROLL, SB_LINEDOWN, 0);
-      smPageByPage:
-        dgPanel.Perform(LM_VSCROLL, SB_PAGEDOWN, 0);
-      else
-        Handled:= False;
-    end;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.dgPanelScroll(Sender: TBaseVirtualTree; DeltaX, DeltaY: Integer);
-begin
-  if DeltaY <> 0 then
-    Notify([fvnVisibleFilePropertiesChanged]);
-end;
-
-procedure TColumnsFileViewVTV.dgPanelResize(Sender: TObject);
-begin
-  Notify([fvnVisibleFilePropertiesChanged]);
-end;
-
-procedure TColumnsFileViewVTV.dgPanelColumnResize(Sender: TVTHeader;
-  Column: TColumnIndex);
-begin
-  if Assigned(FOnColumnResized) then
-  begin
-    FOnColumnResized(Self, Column, Sender.Columns.Items[Column].Width);
-  end;
-end;
-
-procedure TColumnsFileViewVTV.ShowRenameFileEdit(AFile: TFile);
-begin
-  if FFileNameColumn <> -1 then
-  begin
-    if not edtRename.Visible then
-    begin
-      edtRename.Font.Name  := GetColumnsClass.GetColumnFontName(FFileNameColumn);
-      edtRename.Font.Size  := GetColumnsClass.GetColumnFontSize(FFileNameColumn);
-      edtRename.Font.Style := GetColumnsClass.GetColumnFontStyle(FFileNameColumn);
-
-      UpdateRenameFileEditPosition;
-    end;
-
-    inherited ShowRenameFileEdit(AFile);
-  end;
-end;
-
-procedure TColumnsFileViewVTV.UpdateRenameFileEditPosition;
-var
-  ARect: TRect;
-begin
-  ARect := dgPanel.GetDisplayRect(dgPanel.FocusedNode, FFileNameColumn, False);
-  Dec(ARect.Top, 2);
-  Inc(ARect.Bottom, 2);
-
-  if gShowIcons <> sim_none then
-    Inc(ARect.Left, gIconsSize + 2);
-
-  if Succ(FFileNameColumn) = FExtensionColumn then
-    Inc(ARect.Right, dgPanel.Header.Columns[FExtensionColumn].Width);
-
-  edtRename.SetBounds(ARect.Left, ARect.Top, ARect.Width, ARect.Height);
-end;
-
-procedure TColumnsFileViewVTV.RedrawFile(FileIndex: PtrInt);
-begin
-  dgPanel.InvalidateNode(PVirtualNode(FFiles[FileIndex].DisplayItem));
-end;
-
-procedure TColumnsFileViewVTV.RedrawFile(DisplayFile: TDisplayFile);
-begin
-  dgPanel.InvalidateNode(PVirtualNode(DisplayFile.DisplayItem));
-end;
-
-procedure TColumnsFileViewVTV.SetColumnsSortDirections;
-var
-  Columns: TPanelColumnsClass;
-
-  function SetSortDirection(ASortFunction: TFileFunction; ASortDirection: uFileSorting.TSortDirection; Overwrite: Boolean): Boolean;
-  var
-    k, l: Integer;
-    ColumnFunctions: TFileFunctions;
-  begin
-    for k := 0 to Columns.Count - 1 do
-    begin
-      ColumnFunctions := Columns.GetColumnItem(k).GetColumnFunctions;
-      for l := 0 to Length(ColumnFunctions) - 1 do
-        if ColumnFunctions[l] = ASortFunction then
-        begin
-          if Overwrite or (FColumnsSortDirections[k] = sdNone) then
-          begin
-            FColumnsSortDirections[k] := ASortDirection;
-            Exit(True);
-          end;
-        end;
-    end;
-    Result := False;
-  end;
-
-var
-  i, j: Integer;
-  ASortings: TFileSortings;
-begin
-  Columns := GetColumnsClass;
-  ASortings := Sorting;
-
-  SetLength(FColumnsSortDirections, Columns.Count);
-  for i := 0 to Length(FColumnsSortDirections) - 1 do
-    FColumnsSortDirections[i] := sdNone;
-
-  for i := 0 to Length(ASortings) - 1 do
-  begin
-    for j := 0 to Length(ASortings[i].SortFunctions) - 1 do
-    begin
-      // Search for the column containing the sort function and add sorting
-      // by that column. If function is Name and it is not found try searching
-      // for NameNoExtension + Extension and vice-versa.
-      if not SetSortDirection(ASortings[i].SortFunctions[j], ASortings[i].SortDirection, True) then
-      begin
-        if ASortings[i].SortFunctions[j] = fsfName then
-        begin
-          SetSortDirection(fsfNameNoExtension, ASortings[i].SortDirection, False);
-          SetSortDirection(fsfExtension, ASortings[i].SortDirection, False);
-        end
-        else if ASortings[i].SortFunctions[j] in [fsfNameNoExtension, fsfExtension] then
-        begin
-          SetSortDirection(fsfName, ASortings[i].SortDirection, False);
-        end;
-      end;
-    end;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.SetFilesDisplayItems;
-var
-  Node: PVirtualNode;
-  Index: Integer = 0;
-begin
-  Node := dgPanel.GetFirstNoInit;
-  while Assigned(Node) do
-  begin
-    FFiles[Index].DisplayItem := Node;
-    Inc(Index);
-    Node := Node^.NextSibling;
-  end;
-end;
-
-function TColumnsFileViewVTV.GetFilePropertiesNeeded: TFilePropertiesTypes;
-var
-  i, j: Integer;
-  ColumnsClass: TPanelColumnsClass;
-  Column: TPanelColumn;
-  FileFunctionsUsed: TFileFunctions;
-begin
-  // By default always use some properties.
-  Result := [fpName,
-             fpSize,              // For info panel (total size, selected size)
-             fpAttributes,        // For distinguishing directories
-             fpLink,              // For distinguishing directories (link to dir) and link icons
-             fpModificationTime   // For selecting/coloring files (by SearchTemplate)
-            ];
-
-  ColumnsClass := GetColumnsClass;
-  FFileNameColumn := -1;
-  FExtensionColumn := -1;
-
-  // Scan through all columns.
-  for i := 0 to ColumnsClass.Count - 1 do
-  begin
-    Column := ColumnsClass.GetColumnItem(i);
-    FileFunctionsUsed := Column.GetColumnFunctions;
-    if Length(FileFunctionsUsed) > 0 then
-    begin
-      // Scan through all functions in the column.
-      for j := Low(FileFunctionsUsed) to High(FileFunctionsUsed) do
-      begin
-        // Add file properties needed to display the function.
-        Result := Result + TFileFunctionToProperty[FileFunctionsUsed[j]];
-        if (FFileNameColumn = -1) and (FileFunctionsUsed[j] in [fsfName, fsfNameNoExtension]) then
-          FFileNameColumn := i;
-        if (FExtensionColumn = -1) and (FileFunctionsUsed[j] in [fsfExtension]) then
-          FExtensionColumn := i;
-      end;
-    end;
-  end;
-end;
-
-function TColumnsFileViewVTV.GetFileRect(FileIndex: PtrInt): TRect;
-begin
-  Result := dgPanel.GetDisplayRect(PVirtualNode(FFiles[FileIndex].DisplayItem), 0, False);
-end;
-
-function TColumnsFileViewVTV.GetVisibleFilesIndexes: TRange;
-begin
-  Result := dgPanel.GetVisibleIndexes;
-end;
-
-procedure TColumnsFileViewVTV.SetRowCount(Count: Integer);
-begin
-  if Count <> dgPanel.RootNodeCount then
-  begin
-    FUpdatingActiveFile := True;
-    dgPanel.BeginUpdate;
-    // If new node count is less then first delete all nodes and then create
-    // new ones, because deleting only some nodes is much slower then deleting all.
-    if Count < dgPanel.RootNodeCount then
-      dgPanel.RootNodeCount := 0;
-    dgPanel.RootNodeCount := Count;
-    dgPanel.EndUpdate;
-    FUpdatingActiveFile := False;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.SetColumns;
-var
-  x: Integer;
-  ColumnsClass: TPanelColumnsClass;
-  col: TVirtualTreeColumn;
-begin
-  //  setup column widths
-  ColumnsClass := GetColumnsClass;
-
-  dgPanel.Header.Columns.Clear;
-  dgPanel.Header.Columns.BeginUpdate;
-  try
-    for x:= 0 to ColumnsClass.ColumnsCount - 1 do
-    begin
-      col := dgPanel.Header.Columns.Add;
-      col.Width   := ColumnsClass.GetColumnWidth(x);
-      //col.Text    := ColumnsClass.GetColumnTitle(x); // I think not needed, as we draw text ourselves.
-      col.Margin  := 0;
-      col.Spacing := 0;
-    end;
-    if gAutoFillColumns then
-    begin
-      if (gAutoSizeColumn = 0) then
-        dgPanel.Header.AutoSizeIndex := gAutoSizeColumn
-      else
-        dgPanel.Header.AutoSizeIndex := col.Index;
-    end;
-  finally
-    dgPanel.Header.Columns.EndUpdate;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.MakeVisible(Node: PVirtualNode);
-begin
-  dgPanel.ScrollIntoView(Node, False, False);
-end;
-
-procedure TColumnsFileViewVTV.SetActiveFile(FileIndex: PtrInt);
-begin
-  dgPanel.FocusedNode := PVirtualNode(FFiles[FileIndex].DisplayItem);
-end;
-
-procedure TColumnsFileViewVTV.RedrawFiles;
-begin
-  dgPanel.Invalidate;
-end;
-
-procedure TColumnsFileViewVTV.UpdateColumnsView;
-var
-  ColumnsClass: TPanelColumnsClass;
-  OldFilePropertiesNeeded: TFilePropertiesTypes;
-begin
-  ClearAllColumnsStrings;
-
-  // If the ActiveColm set doesn't exist this will retrieve either
-  // the first set or the default set.
-  ColumnsClass := GetColumnsClass;
-  // Set name in case a different set was loaded.
-  ActiveColm := ColumnsClass.Name;
-
-  SetColumns;
-  SetColumnsSortDirections;
-
-  dgPanel.UpdateView;
-
-  OldFilePropertiesNeeded := FilePropertiesNeeded;
-  FilePropertiesNeeded := GetFilePropertiesNeeded;
-  if FilePropertiesNeeded >= OldFilePropertiesNeeded then
-  begin
-    Notify([fvnVisibleFilePropertiesChanged]);
-  end;
-end;
-
-procedure TColumnsFileViewVTV.SetGridFunctionDim(ExternalDimFunction: TFunctionDime);
-begin
-  dgPanel.ColumnsOwnDim:= ExternalDimFunction;
-end;
-
-procedure TColumnsFileViewVTV.cm_CopyFileDetailsToClip(const Params: array of string);
-var
-  I: Integer;
-  AFile: TDisplayFile;
-  sl: TStringList = nil;
-
-  procedure AddFile;
-  var
-    J: Integer;
-    S: String;
-  begin
-    if AFile.FSFile.IsNameValid then
-    begin
-      S:= EmptyStr;
-      for J:= 0 to AFile.DisplayStrings.Count - 1 do
-      begin
-        S:= S + AFile.DisplayStrings[J] + #09;
-      end;
-      J:= Length(S);
-      if J > 0 then sl.Add(Copy(S, 1, J - 1));
-    end;
-  end;
-
-begin
-  if DisplayFiles.Count > 0 then
-  begin
-    sl:= TStringList.Create;
-    try
-      for I:= 0 to FFiles.Count - 1 do
-      begin
-        AFile:= FFiles[I];
-        if AFile.Selected then AddFile;
-      end;
-
-      if sl.Count = 0 then
-      begin
-        AFile:= GetActiveDisplayFile;
-        AddFile;
-      end;
-
-      Clipboard.Clear;   // prevent multiple formats in Clipboard
-      ClipboardSetText(TrimRightLineEnding(sl.Text, sl.TextLineBreakStyle));
-    finally
-      FreeAndNil(sl);
-    end;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.ColumnsMenuClick(Sender: TObject);
-begin
-  Case (Sender as TMenuItem).Tag of
-    1001: //All columns, but current one will be selected.
-          begin
-            ShowOptions(TfrmOptionsCustomColumns);
-          end;
-  else
-    begin
-      ActiveColm:=ColSet.Items[(Sender as TMenuItem).Tag];
-      UpdateColumnsView;
-      RedrawFiles;
-    end;
-  end;
-end;
-
-constructor TColumnsFileViewVTV.Create(AOwner: TWinControl; AFileSource: IFileSource; APath: String; AFlags: TFileViewFlags = []);
-begin
-  ActiveColm := 'Default';
-  inherited Create(AOwner, AFileSource, APath, AFlags);
-end;
-
-constructor TColumnsFileViewVTV.Create(AOwner: TWinControl; AFileView: TFileView; AFlags: TFileViewFlags = []);
-begin
-  inherited Create(AOwner, AFileView, AFlags);
-end;
-
-constructor TColumnsFileViewVTV.Create(AOwner: TWinControl; AConfig: TXmlConfig; ANode: TXmlNode; AFlags: TFileViewFlags = []);
-begin
-  inherited Create(AOwner, AConfig, ANode, AFlags);
-end;
-
-procedure TColumnsFileViewVTV.CreateDefault(AOwner: TWinControl);
-begin
-  DCDebug('TColumnsFileViewVTV.Create components');
-
-  inherited CreateDefault(AOwner);
-
-  FFileNameColumn := -1;
-  FExtensionColumn := -1;
-
-  // -- other components
-
-  dgPanel:=TColumnsDrawTree.Create(Self, Self);
-  MainControl := dgPanel;
-
-  // ---
-  dgPanel.OnDragOver := @dgPanelDragOver;
-  dgPanel.OnDragDrop:= @dgPanelDragDrop;
-  dgPanel.OnAdvancedHeaderDraw:=@dgPanelAdvancedHeaderDraw;
-  dgPanel.OnAfterItemPaint := @dgPanelAfterItemPaint;
-  dgPanel.OnBeforeItemErase := @dgPanelBeforeItemErase;
-  dgPanel.OnFocusChanged:=@dgPanelFocusChanged;
-  dgPanel.OnFocusChanging:=@dgPanelFocusChanging;
-  dgPanel.OnHeaderDrawQueryElements:=@dgPanelHeaderDrawQueryElements;
-  dgPanel.OnHeaderClick:=@dgPanelHeaderClick;
-  dgPanel.OnMouseWheelUp := @dgPanelMouseWheelUp;
-  dgPanel.OnMouseWheelDown := @dgPanelMouseWheelDown;
-  dgPanel.OnScroll:= @dgPanelScroll;
-  dgpanel.OnResize:= @dgPanelResize;
-  dgPanel.OnColumnResize:= @dgPanelColumnResize;
-
-  pmColumnsMenu := TPopupMenu.Create(Self);
-  pmColumnsMenu.Parent := Self;
-
-  if Assigned(NotebookPage) then
-  begin
-    FOnColumnResized:= @DoColumnResized;
-  end;
-end;
-
-destructor TColumnsFileViewVTV.Destroy;
-begin
-  inherited Destroy;
-end;
-
-function TColumnsFileViewVTV.Clone(NewParent: TWinControl): TColumnsFileViewVTV;
-begin
-  Result := TColumnsFileViewVTV.Create(NewParent, Self);
-end;
-
-procedure TColumnsFileViewVTV.CloneTo(FileView: TFileView);
-begin
-  if Assigned(FileView) then
-  begin
-    inherited CloneTo(FileView);
-
-    if FileView is TColumnsFileViewVTV then
-    with FileView as TColumnsFileViewVTV do
-    begin
-      FColumnsSortDirections := Self.FColumnsSortDirections;
-
-      ActiveColm := Self.ActiveColm;
-      ActiveColmSlave := nil;    // set to nil because only used in preview?
-      isSlave := Self.isSlave;
-    end;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.AddFileSource(aFileSource: IFileSource; aPath: String);
-begin
-  inherited AddFileSource(aFileSource, aPath);
-end;
-
-procedure TColumnsFileViewVTV.BeforeMakeFileList;
-begin
-  inherited;
-
-  if gListFilesInThread then
-  begin
-    // Display info that file list is being loaded.
-    UpdateInfoPanel;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.ClearAfterDragDrop;
-begin
-  inherited ClearAfterDragDrop;
-
-  // Reset state. TODO: Check if this is needed on any widgetset.
-  dgPanel.TreeStates := dgPanel.TreeStates -
-    [tsLeftButtonDown, tsMiddleButtonDown, tsRightButtonDown, tsVCLDragging];
-end;
-
-procedure TColumnsFileViewVTV.DisplayFileListChanged;
-var
-  AFocused: Boolean = False;
-  Node: PVirtualNode;
-begin
-  // Update grid row count.
-  SetRowCount(FFiles.Count);
-  SetFilesDisplayItems;
-  RedrawFiles;
-
-  if SetActiveFileNow(RequestedActiveFile) then
-    RequestedActiveFile := ''
-  else
-  begin
-    // Requested file was not found, restore position to last active file.
-    if not SetActiveFileNow(LastActiveFile) then
-    begin
-      if FLastActiveFileIndex >= dgPanel.RootNodeCount then
-      begin
-        FUpdatingActiveFile := True;
-        dgPanel.FocusedNode := dgPanel.GetLastNoInit;
-        FUpdatingActiveFile := False;
-        SetLastActiveFile(FLastActiveFileIndex);
-        AFocused := True;
-      end
-      else if FLastActiveFileIndex >= 0 then
-      begin
-        Node := dgPanel.GetFirstNoInit;
-        while Assigned(Node) do
-        begin
-          if Node^.Index = FLastActiveFileIndex then
-          begin
-            FUpdatingActiveFile := True;
-            dgPanel.FocusedNode := Node;
-            FUpdatingActiveFile := False;
-            SetLastActiveFile(Node^.Index);
-            AFocused := True;
-            Break;
-          end;
-          Node := Node^.NextSibling;
-        end;
-      end;
-      if not AFocused then
-        dgPanel.FocusedNode := dgPanel.GetFirstNoInit;
-      // At creation the control has default size (100, 200).
-      // If the first column is wider than ClientWidth then VTV scrolls
-      // to the right edge of the column. So, we scroll back here.
-      // dgPanel.OffsetX := 0;
-    end;
-  end;
-
-  Notify([fvnVisibleFilePropertiesChanged]);
-
-  inherited;
-end;
-
-procedure TColumnsFileViewVTV.DoColumnResized(Sender: TObject;
-  ColumnIndex: Integer; ColumnNewSize: Integer);
-
-  procedure UpdateWidth(ANotebook: TFileViewNotebook);
-  var
-    I: Integer;
-    ColumnsView: TColumnsFileViewVTV;
-  begin
-    for I:= 0 to ANotebook.PageCount - 1 do
-    begin
-      if ANotebook.View[I] is TColumnsFileViewVTV then
-      begin
-        ColumnsView:= TColumnsFileViewVTV(ANotebook.View[I]);
-        if ColumnsView.ActiveColm = ActiveColm then
-        begin
-          with ColumnsView.dgPanel do
-          begin
-            Header.Columns.BeginUpdate;
-            Header.Columns.Items[ColumnIndex].Width:= ColumnNewSize;
-            Header.Columns.EndUpdate;
-          end;
-        end;
-      end;
-    end;
-  end;
-
-begin
-  if gColumnsAutoSaveWidth then
-  begin
-    GetColumnsClass.SetColumnWidth(ColumnIndex, ColumnNewSize);
-    UpdateWidth(frmMain.LeftTabs);
-    UpdateWidth(frmMain.RightTabs);
-  end;
-end;
-
-procedure TColumnsFileViewVTV.MakeColumnsStrings(AFile: TDisplayFile);
-begin
-  MakeColumnsStrings(AFile, GetColumnsClass);
-end;
-
-procedure TColumnsFileViewVTV.MakeColumnsStrings(AFile: TDisplayFile; ColumnsClass: TPanelColumnsClass);
-var
-  ACol: Integer;
-begin
-  AFile.DisplayStrings.Clear;
-  for ACol := 0 to ColumnsClass.Count - 1 do
-  begin
-    AFile.DisplayStrings.Add(ColumnsClass.GetColumnItemResultString(
-      ACol, AFile.FSFile, FileSource));
-  end;
-end;
-
-procedure TColumnsFileViewVTV.ClearAllColumnsStrings;
-var
-  i: Integer;
-begin
-  if Assigned(FAllDisplayFiles) then
-  begin
-    // Clear display strings in case columns have changed.
-    for i := 0 to FAllDisplayFiles.Count - 1 do
-      FAllDisplayFiles[i].DisplayStrings.Clear;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.EachViewUpdateColumns(AFileView: TFileView; UserData: Pointer);
-var
-  ColumnsView: TColumnsFileViewVTV;
-  PMsg: PEachViewCallbackMsg;
-begin
-  if AFileView is TColumnsFileViewVTV then
-  begin
-    ColumnsView := TColumnsFileViewVTV(AFileView);
-    PMsg := UserData;
-    if ColumnsView.ActiveColm = PMsg^.UpdatedColumnsSetName then
-    begin
-      ColumnsView.ActiveColm := PMsg^.NewColumnsSetName;
-      ColumnsView.UpdateColumnsView;
-      ColumnsView.RedrawFiles;
-    end;
-  end;
-end;
-
-procedure TColumnsFileViewVTV.DoUpdateView;
-begin
-  inherited DoUpdateView;
-  UpdateColumnsView;
-end;
-
-function TColumnsFileViewVTV.GetActiveFileIndex: PtrInt;
-begin
-  if Assigned(dgPanel.FocusedNode) then
-    Result := dgPanel.FocusedNode^.Index
-  else
-    Result := InvalidFileIndex;
-end;
-
-function TColumnsFileViewVTV.GetColumnsClass: TPanelColumnsClass;
-begin
-  if isSlave then
-    Result := ActiveColmSlave
-  else
-    Result := ColSet.GetColumnSet(ActiveColm);
-end;
-
-function TColumnsFileViewVTV.GetFileIndexFromCursor(X, Y: Integer; out AtFileList: Boolean): PtrInt;
-var
-  Node: PVirtualNode;
-begin
-  Node := dgPanel.GetNodeAt(X, Y);
-  if Assigned(Node) then
-    Result := Node^.Index
-  else
-    Result := InvalidFileIndex;
-  AtFileList := Y >= dgPanel.GetHeaderHeight;
-end;
-
-procedure TColumnsFileViewVTV.DoFileUpdated(AFile: TDisplayFile; UpdatedProperties: TFilePropertiesTypes);
-begin
-  MakeColumnsStrings(AFile);
-  inherited DoFileUpdated(AFile, UpdatedProperties);
-end;
-
-procedure TColumnsFileViewVTV.DoHandleKeyDown(var Key: Word; Shift: TShiftState);
-var
-  Node, NextNode: PVirtualNode;
-  aFile: TDisplayFile;
-begin
-  case Key of
-    VK_INSERT:
-      begin
-        if not IsEmpty then
-        begin
-          Node := dgPanel.FocusedNode;
-          if IsActiveItemValid then
-          begin
-            InvertFileSelection(GetActiveDisplayFile, False);
-            DoSelectionChanged(nil);
-          end;
-          NextNode := dgPanel.GetNextSiblingNoInit(Node);
-          if (Node <> NextNode) and Assigned(NextNode) then
-            dgPanel.FocusedNode := NextNode
-          else
-            dgPanel.InvalidateNode(Node);
-        end;
-        Key := 0;
-      end;
-
-    VK_LEFT:
-      if (Shift = []) then
-      begin
-        if gLynxLike then
-          ChangePathToParent(True)
-        else
-          dgPanel.OffsetX := dgPanel.OffsetX + 20;
-        Key := 0;
-      end;
-
-    VK_RIGHT:
-      if (Shift = []) then
-      begin
-        if gLynxLike then
-          ChooseFile(GetActiveDisplayFile, True)
-        else
-          dgPanel.OffsetX := dgPanel.OffsetX - 20;
-        Key := 0;
-      end;
-
-    VK_SPACE:
-      if Shift * KeyModifiersShortcut = [] then
-      begin
-        Node := dgPanel.FocusedNode;
-        if Assigned(Node) then
-        begin
-          aFile := dgPanel.GetNodeFile(Node);
-          if IsItemValid(aFile) then
-          begin
-            if (aFile.FSFile.IsDirectory or
-               aFile.FSFile.IsLinkToDirectory) and
-               not aFile.Selected then
-            begin
-              CalculateSpace(aFile);
-            end;
-
-            InvertFileSelection(aFile, False);
-            DoSelectionChanged(nil);
-          end;
-
-          if gSpaceMovesDown then
-          begin
-            NextNode := dgPanel.GetNextSiblingNoInit(Node);
-            if (Node <> NextNode) and Assigned(NextNode) then
-              dgPanel.FocusedNode := NextNode
-            else
-              dgPanel.InvalidateNode(Node);
-          end
-          else
-            dgPanel.InvalidateNode(Node);
-          Key := 0;
-        end;
-      end;
-  end;
-
-  inherited DoHandleKeyDown(Key, Shift);
-end;
-
-procedure TColumnsFileViewVTV.DoSelectionChanged(Node: PVirtualNode);
-begin
-  if Assigned(Node) then
-    DoSelectionChanged(Node^.Index)
-  else
-    DoSelectionChanged(-1);
-end;
-
-{ TColumnsDrawTree }
-
-constructor TColumnsDrawTree.Create(AOwner: TComponent; AParent: TWinControl);
-begin
-  inherited Create(AOwner);
-
-  ColumnsView := AParent as TColumnsFileViewVTV;
-  ColumnsOwnDim := @ColumnsView.DimColor;
-
-  DragType := dtVCL;
-  HintMode := hmHint;
-
-  Self.Parent := AParent;
-end;
-
-function TColumnsDrawTree.DetermineScrollDirections(X, Y: Integer): TScrollDirections;
-begin
-  Result := inherited DetermineScrollDirections(X, Y) - [sdLeft, sdRight]; // Only scroll up, down.
-end;
-
-function TColumnsDrawTree.DoKeyAction(var CharCode: Word; var Shift: TShiftState): Boolean;
-begin
-  Result := CharCode in [VK_HOME, VK_END, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT];
-end;
-
-procedure TColumnsDrawTree.AfterConstruction;
-begin
-  inherited;
-
-  RootNodeCount := 0;
-  NodeDataSize := SizeOf(TColumnsDrawTreeRecord);
-
-  Align := alClient;
-
-  TreeOptions.AutoOptions := [toAutoScroll, toDisableAutoscrollHorizontal];
-  TreeOptions.MiscOptions := [toFullRowDrag];
-  // TODO: if no mouse action for middle button: include toWheelPanning
-  TreeOptions.PaintOptions := [toShowBackground,
-    toThemeAware, toUseBlendedImages, toGhostedIfUnfocused, toStaticBackground,
-    toAlwaysHideSelection, toHideFocusRect];
-  TreeOptions.SelectionOptions := [toDisableDrawSelection, toExtendedFocus,
-    toFullRowSelect];
-
-  TabStop := False;
-  Margin := 0;
-  TextMargin := 0;
-  Indent := 0;
-  AnimationDuration := 0;
-  AutoScrollDelay := 500; // milliseconds
-  AutoScrollInterval := 100; // milliseconds
-
-  UpdateView;
-end;
-
-function TColumnsDrawTree.CanAutoScroll: Boolean;
-begin
-  Result := inherited CanAutoScroll;
-  if Header.States = [] then
-  begin
-    with ColumnsView do
-    begin
-      if IsMouseSelecting then
-        Result := True;
-    end;
-  end;
-end;
-
-function TColumnsDrawTree.CanScroll(const ClientMousePos: TPoint): Boolean;
-begin
-  Result := ColumnsView.IsMouseSelecting;
-end;
-
-procedure TColumnsDrawTree.CMHintShow(var Message: TCMHintShow);
-begin
-  // Skip CMHintShow from VTV and do what TControl.CMHintShow does.
-  DoOnShowHint(Message.HintInfo);
-end;
-
-procedure TColumnsDrawTree.UpdateView;
-
-  function CalculateDefaultRowHeight: Integer;
-  var
-    OldFont, NewFont: TFont;
-    i: Integer;
-    MaxFontHeight: Integer = 0;
-    CurrentHeight: Integer;
-    ColumnsSet: TPanelColumnsClass;
-  begin
-    // Start with height of the icons.
-    if gShowIcons <> sim_none then
-      MaxFontHeight := gIconsSize;
-
-    // Get columns settings.
-    with (Parent as TColumnsFileViewVTV) do
-    begin
-      if not isSlave then
-        ColumnsSet := ColSet.GetColumnSet(ActiveColm)
-      else
-        ColumnsSet := ActiveColmSlave;
-    end;
-
-    // Assign temporary font.
-    OldFont     := Canvas.Font;
-    NewFont     := TFont.Create;
-    Canvas.Font := NewFont;
-
-    // Search columns settings for the biggest font (in height).
-    for i := 0 to ColumnsSet.Count - 1 do
-    begin
-      Canvas.Font.Name  := ColumnsSet.GetColumnFontName(i);
-      Canvas.Font.Style := ColumnsSet.GetColumnFontStyle(i);
-      Canvas.Font.Size  := ColumnsSet.GetColumnFontSize(i);
-
-      CurrentHeight := Canvas.GetTextHeight('Wg');
-      MaxFontHeight := Max(MaxFontHeight, CurrentHeight);
-    end;
-
-    // Restore old font.
-    Canvas.Font := OldFont;
-    FreeAndNil(NewFont);
-
-    Result := MaxFontHeight;
-  end;
-
-  function CalculateTabHeaderHeight: Integer;
-  var
-    OldFont: TFont;
-  begin
-    OldFont     := Canvas.Font;
-    Canvas.Font := Font;
-    Result      := Canvas.TextHeight('Wg');
-    Canvas.Font := OldFont;
-  end;
-
-var
-  TabHeaderHeight: Integer;
-  TempRowHeight: Integer;
-  Node: PVirtualNode;
-begin
-  BeginUpdate;
-
-  try
-    if gInterfaceFlat then
-    begin
-      Header.Style := hsPlates;
-      BorderStyle := bsNone;
-      BorderWidth := 0;
-    end
-    else
-      Header.Style := hsFlatButtons;
-
-    GridVertLine:= gGridVertLine;
-    GridHorzLine:= gGridHorzLine;
-
-    // Calculate row height.
-    TempRowHeight := CalculateDefaultRowHeight;
-    if TempRowHeight > 0 then
-    begin
-      DefaultNodeHeight := TempRowHeight;
-
-      // Set each node's height if changed.
-      Node := GetFirstNoInit;
-      if Assigned(Node) and (NodeHeight[Node] <> TempRowHeight) then
-        SetAllRowsHeights(TempRowHeight);
-    end;
-
-    // Add additional space at the bottom so that the filelist doesn't jump at the end.
-    // It happens when ClientHeight is not an exact multiplication of DefaultNodeHeight.
-    BottomSpace := ClientHeight mod DefaultNodeHeight;
-
-    Header.Options := [hoColumnResize, hoDblClickResize, hoDisableAnimatedResize,
-      hoOwnerDraw, hoHotTrack];
-
-    // Set rows of header.
-    if gTabHeader then
-    begin
-      Header.Options := Header.Options + [hoVisible];
-
-      TabHeaderHeight := Max(gIconsSize, CalculateTabHeaderHeight);
-      TabHeaderHeight := TabHeaderHeight + 2; // for borders
-      if not gInterfaceFlat then
-      begin
-        TabHeaderHeight := TabHeaderHeight + 2; // additional borders if not flat
-      end;
-      Header.DefaultHeight := TabHeaderHeight;
-    end;
-
-    if gAutoFillColumns then
-      Header.Options := Header.Options + [hoAutoResize, hoAutoSpring];
-
-  finally
-    EndUpdate;
-  end;
-end;
-
-procedure TColumnsDrawTree.WMKeyDown(var Message: TLMKeyDown);
-var
-  Node, Temp: PVirtualNode;
-  Offset: Integer;
-  SavedKey: Word;
-  Shift: TShiftState;
-begin
-  Shift := KeyDataToShiftState(Message.KeyData);
-  SavedKey := Message.CharCode;
-
-  if ColumnsView.IsLoadingFileList then
-  begin
-    ColumnsView.HandleKeyDownWhenLoading(Message.CharCode, Shift);
-    Exit;
-  end;
-
-  // Set RangeSelecting before cursor is moved.
-  ColumnsView.FRangeSelecting :=
-    (ssShift in Shift) and
-    (SavedKey in [VK_HOME, VK_END, VK_PRIOR, VK_NEXT]);
-  // Special case for selection with shift key (works like VK_INSERT)
-  if (SavedKey in [VK_UP, VK_DOWN]) and (ssShift in Shift) then
-    ColumnsView.InvertActiveFile;
-
-  // Override scrolling with PageUp, PageDown because VirtualTreeView scrolls too much.
-  case SavedKey of
-    VK_PRIOR:
-      begin
-        Offset := 0;
-        // If there's no focused node then just take the very first one.
-        if FocusedNode = nil then
-          Node := GetFirstNoInit
-        else
-        begin
-          // Go up as many nodes as comprise together a size of ClientHeight.
-          Node := FocusedNode;
-          Temp := Node;
-          while Assigned(Temp) do
-          begin
-            Inc(Offset, NodeHeight[Temp]);
-            if Offset >= ClientHeight then
-              Break;
-            Node := Temp;
-            Temp := GetPreviousSiblingNoInit(Temp);
-          end;
-        end;
-        FocusedNode := Node;
-        Message.CharCode := 0;
-      end;
-
-    VK_NEXT:
-      begin
-        Offset := 0;
-        // If there's no focused node then just take the very last one.
-        if FocusedNode = nil then
-          Node := GetLastNoInit
-        else
-        begin
-          // Go down as many nodes as comprise together a size of ClientHeight.
-          Node := FocusedNode;
-          Temp := Node;
-          while Assigned(Temp) do
-          begin
-            Inc(Offset, NodeHeight[Temp]);
-            if Offset >= ClientHeight then
-              Break;
-            Node := Temp;
-            Temp := GetNextSiblingNoInit(Temp);
-          end;
-        end;
-        FocusedNode := Node;
-        //if OffsetY mod DefaultNodeHeight <> 0 then
-        //  OffsetY := OffsetY - ClientHeight mod DefaultNodeHeight;
-        Message.CharCode := 0;
-      end;
-
-{$IFDEF LCLGTK2}
-    // Workaround for GTK2 - up and down arrows moving through controls.
-    VK_UP, VK_DOWN:
-      begin
-        Node := FocusedNode;
-        if ((Node = GetLastNoInit) and (SavedKey = VK_DOWN))
-        or ((Node = GetFirstNoInit) and (SavedKey = VK_UP)) then
-          Message.CharCode := 0;
-      end;
-{$ENDIF}
-  end;
-
-  inherited WMKeyDown(Message);
-
-  if (ColumnsView.FRangeSelecting) and Assigned(FocusedNode) then
-    ColumnsView.Selection(SavedKey, FocusedNode^.Index);
-end;
-
-procedure TColumnsDrawTree.InitializeWnd;
-begin
-  inherited InitializeWnd;
-  ColumnsView.InitializeDragDropEx(Self);
-end;
-
-procedure TColumnsDrawTree.FinalizeWnd;
-begin
-  ColumnsView.FinalizeDragDropEx(Self);
-  inherited FinalizeWnd;
-end;
-
-procedure TColumnsDrawTree.DoPaintNode(var PaintInfo: TVTPaintInfo);
-var
-  //shared variables
-  s:   string;
-  iTextTop: Integer;
-  AFile: TDisplayFile;
-  FileSourceDirectAccess: Boolean;
-  ColumnsSet: TPanelColumnsClass;
-  IsFocused: Boolean;
-  aRect: TRect;
-  aCol: TColumnIndex;
-
-  //------------------------------------------------------
-  //begin subprocedures
-  //------------------------------------------------------
-
-  procedure DrawIconCell;
-  //------------------------------------------------------
-  var
-    Y: Integer;
-    IconID: PtrInt;
-    oldClipping: Boolean;
-  begin
-    if (gShowIcons <> sim_none) then
-    begin
-      IconID := AFile.IconID;
-      // Draw default icon if there is no icon for the file.
-      if IconID = -1 then
-        IconID := PixMapManager.GetDefaultIcon(AFile.FSFile);
-
-      // center icon vertically
-      Y:= aRect.Top + (PaintInfo.Node^.NodeHeight - gIconsSize) div 2;
-
-      // Draw icon for a file
-      PixMapManager.DrawBitmap(IconID,
-                               PaintInfo.Canvas,
-                               aRect.Left + 1,
-                               Y
-                               );
-
-      // Draw overlay icon for a file if needed
-      if gIconOverlays then
-      begin
-        PixMapManager.DrawBitmapOverlay(AFile,
-                                        FileSourceDirectAccess,
-                                        PaintInfo.Canvas,
-                                        aRect.Left + 1,
-                                        Y
-                                        );
-      end;
-
-    end;
-
-    s := AFile.DisplayStrings.Strings[ACol];
-
-    if gCutTextToColWidth then
-    begin
-      Y:= ((aRect.Right - aRect.Left) - PaintInfo.Canvas.TextWidth('V'));
-      if (gShowIcons <> sim_none) then Y:= Y - gIconsSize;
-      s:= FitFileName(s, PaintInfo.Canvas, AFile.FSFile, Y);
-    end;
-
-    oldClipping := PaintInfo.Canvas.Clipping;
-    //PaintInfo.Canvas.Clipping := False;
-
-    if (gShowIcons <> sim_none) then
-      PaintInfo.Canvas.TextOut(aRect.Left + gIconsSize + 4, iTextTop, s)
-    else
-      PaintInfo.Canvas.TextOut(aRect.Left + 2, iTextTop, s);
-
-//    PaintInfo.Canvas.Clipping := oldClipping;
-  end; //of DrawIconCell
-  //------------------------------------------------------
-
-  procedure DrawOtherCell;
-  //------------------------------------------------------
-  var
-    tw, cw: Integer;
-    oldClipping: Boolean;
-  begin
-    s := AFile.DisplayStrings.Strings[ACol];
-
-    if gCutTextToColWidth then
-    begin
-      while PaintInfo.Canvas.TextWidth(s) - (aRect.Right - aRect.Left) - 4 > 0 do
-        Delete(s, Length(s), 1);
-    end;
-
-    oldClipping := PaintInfo.Canvas.Clipping;
-    //PaintInfo.Canvas.Clipping := False;
-
-    case ColumnsSet.GetColumnAlign(ACol) of
-
-      taRightJustify:
-        begin
-          cw := Header.Columns.Items[ACol].Width;
-          tw := PaintInfo.Canvas.TextWidth(s);
-          PaintInfo.Canvas.TextOut(aRect.Right - tw - 3, iTextTop, s);
-        end;
-
-      taLeftJustify:
-        begin
-          PaintInfo.Canvas.TextOut(aRect.Left + 3, iTextTop, s);
-        end;
-
-      taCenter:
-        begin
-          cw := Header.Columns.Items[ACol].Width;
-          tw := PaintInfo.Canvas.TextWidth(s);
-          PaintInfo.Canvas.TextOut(aRect.Left + ((cw - tw - 3) div 2), iTextTop, s);
-        end;
-
-    end; //of case
-
-//    PaintInfo.Canvas.Clipping := oldClipping;
-  end; //of DrawOtherCell
-  //------------------------------------------------------
-
-  procedure PrepareColors;
-  //------------------------------------------------------
-  var
-    TextColor: TColor = clDefault;
-    BackgroundColor: TColor;
-    IsCursor: Boolean;
-    IsCursorInactive: Boolean;
-  //---------------------
-  begin
-    PaintInfo.Canvas.Font.Name    := ColumnsSet.GetColumnFontName(ACol);
-    PaintInfo.Canvas.Font.Size    := ColumnsSet.GetColumnFontSize(ACol);
-    PaintInfo.Canvas.Font.Style   := ColumnsSet.GetColumnFontStyle(ACol);
-    PaintInfo.Canvas.Font.Quality := ColumnsSet.GetColumnFontQuality(ACol);
-
-    IsCursor := IsFocused and ColumnsView.Active and (not ColumnsSet.UseFrameCursor);
-    IsCursorInactive := IsFocused and (not ColumnsView.Active) and (not ColumnsSet.UseFrameCursor);
-    // Set up default background color first.
-    if IsCursor then
-      begin
-        BackgroundColor := ColumnsSet.GetColumnCursorColor(ACol);
-      end
-    else
-      begin
-        if IsCursorInactive AND ColumnsSet.GetColumnUseInactiveSelColor(ACol) then
-          BackgroundColor := ColumnsSet.GetColumnInactiveCursorColor(ACol)
-        else
-        // Alternate rows background color.
-        if odd(PaintInfo.Node^.Index) then
-          BackgroundColor := ColumnsSet.GetColumnBackground(ACol)
-        else
-          BackgroundColor := ColumnsSet.GetColumnBackground2(ACol);
-      end;
-
-    // Set text color.
-    if ColumnsSet.GetColumnOvercolor(ACol) then
-      TextColor := AFile.TextColor;
-    if (TextColor = clDefault) or (TextColor = clNone) then
-      TextColor := ColumnsSet.GetColumnTextColor(ACol);
-
-    if AFile.Selected then
-    begin
-      if ColumnsSet.GetColumnUseInvertedSelection(ACol) then
-        begin
-          //------------------------------------------------------
-          if IsCursor or (IsCursorInactive and ColumnsSet.GetColumnUseInactiveSelColor(ACol)) then
-            begin
-              TextColor := InvertColor(ColumnsSet.GetColumnCursorText(ACol));
-            end
-          else
-            begin
-              if ColumnsView.Active OR (not ColumnsSet.GetColumnUseInactiveSelColor(ACol)) then
-                BackgroundColor := ColumnsSet.GetColumnMarkColor(ACol)
-              else
-                BackgroundColor := ColumnsSet.GetColumnInactiveMarkColor(ACol);
-              TextColor := ColumnsSet.GetColumnBackground(ACol);
-            end;
-          //------------------------------------------------------
-        end
-      else
-        begin
-          if ColumnsView.Active OR (not ColumnsSet.GetColumnUseInactiveSelColor(ACol)) then
-            TextColor := ColumnsSet.GetColumnMarkColor(ACol)
-          else
-            TextColor := ColumnsSet.GetColumnInactiveMarkColor(ACol);
-        end;
-    end
-    else if IsCursor then
-      begin
-        TextColor := ColumnsSet.GetColumnCursorText(ACol);
-      end;
-
-    BackgroundColor := ColumnsOwnDim(BackgroundColor);
-
-    if AFile.RecentlyUpdatedPct <> 0 then
-    begin
-      TextColor := LightColor(TextColor, AFile.RecentlyUpdatedPct);
-      BackgroundColor := LightColor(BackgroundColor, AFile.RecentlyUpdatedPct);
-    end;
-
-    // Draw background.
-    PaintInfo.Canvas.Brush.Color := BackgroundColor;
-    PaintInfo.Canvas.FillRect(aRect);
-    PaintInfo.Canvas.Font.Color := TextColor;
-  end;// of PrepareColors;
-
-  procedure DrawLines;
-  begin
-    // Draw frame cursor.
-    if ColumnsSet.UseFrameCursor and IsFocused and (ColumnsView.Active or ColumnsSet.GetColumnUseInactiveSelColor(ACol)) then
-    begin
-      if ColumnsView.Active then
-        PaintInfo.Canvas.Pen.Color := ColumnsSet.GetColumnCursorColor(ACol)
-      else
-        PaintInfo.Canvas.Pen.Color := ColumnsSet.GetColumnInactiveCursorColor(ACol);
-      PaintInfo.Canvas.Line(aRect.Left, aRect.Top, aRect.Right, aRect.Top);
-      PaintInfo.Canvas.Line(aRect.Left, aRect.Bottom - 1, aRect.Right, aRect.Bottom - 1);
-    end;
-
-    // Draw drop selection.
-    if PaintInfo.Node^.Index = ColumnsView.FDropFileIndex then
-    begin
-      PaintInfo.Canvas.Pen.Color := ColumnsSet.GetColumnTextColor(ACol);
-      PaintInfo.Canvas.Line(aRect.Left, aRect.Top + 1, aRect.Right, aRect.Top + 1);
-      PaintInfo.Canvas.Line(aRect.Left, aRect.Bottom - 1, aRect.Right, aRect.Bottom - 1);
-    end;
-  end;
-  //------------------------------------------------------
-  //end of subprocedures
-  //------------------------------------------------------
-
-begin
-  aRect := PaintInfo.ContentRect;
-  aCol := PaintInfo.Column;
-
-  AFile := GetNodeFile(PaintInfo.Node);
-  if not Assigned(AFile) then
-  begin
-    PaintInfo.Canvas.Brush.Color := Self.Color;
-    PaintInfo.Canvas.FillRect(aRect);
-    Exit;
-  end;
-
-  ColumnsSet := ColumnsView.GetColumnsClass;
-  FileSourceDirectAccess := fspDirectAccess in ColumnsView.FileSource.Properties;
-  if AFile.DisplayStrings.Count = 0 then
-    ColumnsView.MakeColumnsStrings(AFile, ColumnsSet);
-
-  IsFocused := PaintInfo.Node = FocusedNode;
-
-  PrepareColors;
-
-  // Paint on next column if it is empty.
-  {if (ColumnsSet.GetColumnAlign(ACol) = taLeftJustify) and
-     (ACol + 1 < ColumnsSet.ColumnsCount) and
-     (AFile.DisplayStrings[ACol + 1] = EmptyStr) then
-    aRect.Right := aRect.Right + Header.Columns.Items[ACol + 1].Width;
-
-  // Paint on previous column if it is empty.
-  if (ColumnsSet.GetColumnAlign(ACol) = taRightJustify) and
-     (ACol - 1 >= 0) and
-     (AFile.DisplayStrings[ACol - 1] = EmptyStr) then
-    aRect.Left := aRect.Left - Header.Columns.Items[ACol - 1].Width;
-  }
-  iTextTop := aRect.Top + (PaintInfo.Node^.NodeHeight - PaintInfo.Canvas.TextHeight('Wg')) div 2;
-
-  if PaintInfo.Column = 0 then
-    DrawIconCell  // Draw icon in the first column
-  else
-    DrawOtherCell;
-
-  DrawLines;
-end;
-
-function TColumnsDrawTree.GetNodeFile(Node: PVirtualNode): TDisplayFile;
-begin
-  if InRange(Node^.Index, 0, ColumnsView.FFiles.Count-1) then
-    Result := ColumnsView.FFiles[Node^.Index]
-  else
-    Result := nil;
-end;
-
-procedure TColumnsDrawTree.SetAllRowsHeights(ARowHeight: Cardinal);
-var
-  Node: PVirtualNode;
-begin
-  BeginUpdate;
-  try
-    Node := GetFirstNoInit;
-    while Assigned(Node) do
-    begin
-      NodeHeight[Node] := ARowHeight;
-      Node := Node^.NextSibling;
-    end;
-  finally
-    EndUpdate;
-  end;
-end;
-
-procedure TColumnsDrawTree.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
-  Y: Integer);
-var
-  BackgroundClick: Boolean;
-  Point: TPoint;
-begin
-  if ColumnsView.IsLoadingFileList then Exit;
-
-{$IFDEF LCLGTK2}
-  // Workaround for two doubleclicks being sent on GTK.
-  // MouseUp event is sent just after doubleclick, so if we drop
-  // doubleclick events we have to also drop MouseUp events that follow them.
-  if ColumnsView.TooManyDoubleClicks then Exit;
-{$ENDIF}
-
-  // Handle only if button-up was not lifted to finish drag&drop operation.
-  if not ColumnsView.FMainControlMouseDown then
-    Exit;
-
-  inherited MouseUp(Button, Shift, X, Y);
-
-  ColumnsView.FMainControlMouseDown := False;
-
-  if Button = mbRight then
-    begin
-      { If right click on file/directory }
-      if ((gMouseSelectionButton<>1) or not gMouseSelectionEnabled) then
-        begin
-          BackgroundClick:= not MouseOnGrid(X, Y);
-          Point := ClientToScreen(Classes.Point(X, Y));
-          frmMain.Commands.DoContextMenu(ColumnsView, Point.x, Point.y, BackgroundClick);
-        end
-      else if (gMouseSelectionEnabled and (gMouseSelectionButton = 1)) then
-        begin
-          ColumnsView.tmContextMenu.Enabled:= False; // stop context menu timer
-        end;
-    end
-  { Open folder in new tab on middle click }
-  else if (Button = mbMiddle) and (Y > GetHeaderHeight) then
-    begin
-      frmMain.Commands.cm_OpenDirInNewTab([]);
-    end;
-end;
-
-procedure TColumnsDrawTree.MouseDown(Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
-begin
-  if ColumnsView.IsLoadingFileList then Exit;
-
-{$IFDEF LCLGTK2}
-  // Workaround for two doubleclicks being sent on GTK.
-  // MouseDown event is sent just before doubleclick, so if we drop
-  // doubleclick events we have to also drop MouseDown events that precede them.
-  if ColumnsView.TooManyDoubleClicks then Exit;
-{$ENDIF}
-
-  ColumnsView.FMainControlMouseDown := True;
-
-  inherited MouseDown(Button, Shift, X, Y);
-end;
-
-function TColumnsDrawTree.MouseOnGrid(X, Y: LongInt): Boolean;
-begin
-  Result := Assigned(GetNodeAt(X, Y));
-end;
-
-function TColumnsDrawTree.GetHeaderHeight: Integer;
-begin
-  Result := Header.Height;
-end;
-
-function TColumnsDrawTree.GetGridHorzLine: Boolean;
-begin
-  Result := toShowHorzGridLines in TreeOptions.PaintOptions;
-end;
-
-function TColumnsDrawTree.GetGridVertLine: Boolean;
-begin
-  Result := toShowVertGridLines in TreeOptions.PaintOptions;
-end;
-
-procedure TColumnsDrawTree.SetGridHorzLine(const AValue: Boolean);
-begin
-  if AValue then
-    TreeOptions.PaintOptions := TreeOptions.PaintOptions + [toShowHorzGridLines]
-  else
-    TreeOptions.PaintOptions := TreeOptions.PaintOptions - [toShowHorzGridLines];
-end;
-
-procedure TColumnsDrawTree.SetGridVertLine(const AValue: Boolean);
-begin
-  if AValue then
-    TreeOptions.PaintOptions := TreeOptions.PaintOptions + [toShowVertGridLines]
-  else
-    TreeOptions.PaintOptions := TreeOptions.PaintOptions - [toShowVertGridLines];
-end;
-
-function TColumnsDrawTree.GetVisibleNodes: TNodeRange;
-var
-  Offset: Integer = 0;
-  Node: PVirtualNode;
-  CH: Integer;
-begin
-  Result.First := GetNodeAt(0, 0, True, Offset);
-  Result.Last := Result.First;
-  CH := ClientHeight;
-
-  // Go down as many nodes as comprise together a size of ClientHeight.
-  if Assigned(Result.Last) then
-  begin
-    while True do
-    begin
-      if Offset >= CH then
-        Break;
-      Node := GetNextSiblingNoInit(Result.Last);
-      if not Assigned(Node) then
-        Break;
-      Result.Last := Node;
-      Inc(Offset, NodeHeight[Node]);
-    end;
-  end;
-end;
-
-function TColumnsDrawTree.GetVisibleIndexes: TRange;
-begin
-  if csLoading in ComponentState then
-  begin
-    Result.First := 0;
-    Result.Last  := -1;
-  end
-  else
-  begin
-    // This assumes each row has the same height = DefaultNodeHeight.
-    Result.First := -OffsetY div DefaultNodeHeight;
-    Result.Last  := (-OffsetY + ClientHeight) div DefaultNodeHeight;
-    // Account for the fact the BottomSpace might be > 0.
-    if Result.Last >= RootNodeCount then
-      Result.Last := RootNodeCount - 1;
-  end;
-end;
-
-end.
-

+ 2 - 6
src/fmain.pas

@@ -935,12 +935,8 @@ uses
   uFileSourceOperationOptionsUI, uDebug, uHotkeyManager, uFileSourceUtil, uTempFileSystemFileSource,
   Laz2_XMLRead, DCOSUtils, DCStrUtils, fOptions, fOptionsFrame, fOptionsToolbar, uClassesEx,
   uHotDir, uFileSorting, DCBasicTypes, foptionsDirectoryHotlist, uConnectionManager,
-  fOptionsToolbarBase, fOptionsToolbarMiddle, fEditor, uColumns, StrUtils, uSysFolders
-  {$IFDEF COLUMNSFILEVIEW_VTV}
-  , uColumnsFileViewVtv
-  {$ELSE}
-  , uColumnsFileView
-  {$ENDIF}
+  fOptionsToolbarBase, fOptionsToolbarMiddle, fEditor, uColumns, StrUtils, uSysFolders,
+  uColumnsFileView
 {$IFDEF MSWINDOWS}
   , uNetworkThread
 {$ENDIF}

+ 1 - 7
src/frames/foptionscustomcolumns.pas

@@ -32,13 +32,7 @@ uses
   ComCtrls, Controls, Classes, SysUtils, StdCtrls, ExtCtrls, Forms, ColorBox,
   Buttons, Spin, Grids, Menus, Dialogs,
   //DC
-  uColumns, fOptionsFrame
-  {$IFDEF COLUMNSFILEVIEW_VTV}
-  , uColumnsFileViewVtv
-  {$ELSE}
-  , uColumnsFileView
-  {$ENDIF}
-  ;
+  uColumns, fOptionsFrame, uColumnsFileView;
 
 type
 

+ 1 - 7
src/frames/foptionsfilepanelscolors.pas

@@ -32,13 +32,7 @@ uses
   DividerBevel,
 
   //DC
-  uColumns, fOptionsFrame
-  {$IFDEF COLUMNSFILEVIEW_VTV}
-  , uColumnsFileViewVtv
-  {$ELSE}
-  , uColumnsFileView
-  {$ENDIF}
-  ;
+  uColumns, fOptionsFrame, uColumnsFileView;
 
 type
   { TfrmOptionsFilePanelsColors }

+ 2 - 6
src/umaincommands.pas

@@ -398,12 +398,8 @@ uses fOptionsPluginsBase, fOptionsPluginsDSX, fOptionsPluginsWCX,
      DCOSUtils, DCStrUtils, DCBasicTypes, uFileSourceCopyOperation, fSyncDirsDlg,
      uHotDir, DCXmlConfig, dmCommonData, fOptionsFrame, foptionsDirectoryHotlist,
      fMainCommandsDlg, uConnectionManager, fOptionsFavoriteTabs, fTreeViewMenu,
-     uArchiveFileSource, fOptionsHotKeys, fBenchmark, uAdministrator, uWcxArchiveFileSource
-     {$IFDEF COLUMNSFILEVIEW_VTV}
-     , uColumnsFileViewVtv
-     {$ELSE}
-     , uColumnsFileView
-     {$ENDIF}
+     uArchiveFileSource, fOptionsHotKeys, fBenchmark, uAdministrator, uWcxArchiveFileSource,
+     uColumnsFileView
      ;
 
 resourcestring