Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
salvadorbs committed Oct 10, 2024
2 parents 11c0b27 + 5bf755c commit 74b9db5
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 209 deletions.
6 changes: 3 additions & 3 deletions Source/VirtualTrees.AncestorLcl.pas
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ TVTAncestorLcl = class abstract(TBaseVirtualTree)

protected
function GetHintWindowClass: THintWindowClass; override;
function GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree; override;
class function GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree; deprecated 'Use class TVTDragManager.GetTreeFromDataObject() instead';
function DoRenderOLEData(const FormatEtcIn: TFormatEtc; out Medium: TStgMedium; ForClipboard: Boolean): HRESULT; override;
property OnRenderOLEData: TVTRenderOLEDataEvent read FOnRenderOLEData write FOnRenderOLEData;
public //methods
Expand Down Expand Up @@ -89,7 +89,7 @@ function TVTAncestorLcl.GetHintWindowClass: THintWindowClass;

//----------------------------------------------------------------------------------------------------------------------

function TVTAncestorLcl.GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree;
class function TVTAncestorLcl.GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree;

// Returns the owner/sender of the given data object by means of a special clipboard format
// or nil if the sender is in another process or no virtual tree at all.
Expand Down Expand Up @@ -142,7 +142,7 @@ function TVTAncestorLcl.PasteFromClipboard: Boolean;
else
begin
// Try to get the source tree of the operation to optimize the operation.
Source := GetTreeFromDataObject(Data);
Source := TVTDragManager.GetTreeFromDataObject(Data);
Result := ProcessOLEData(Source, Data, FocusedNode, DefaultPasteMode, Assigned(Source) and
(tsCutPending in Source.TreeStates));
if Assigned(Source) then
Expand Down
107 changes: 6 additions & 101 deletions Source/VirtualTrees.BaseTree.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,6 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor)
function GetOperationCanceled: Boolean;
function GetOptionsClass: TTreeOptionsClass; virtual;
function GetSelectedCount(): Integer; override;
function GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree; virtual;
procedure HandleHotTrack(X, Y: TDimension); virtual;
procedure HandleIncrementalSearch(CharCode: Word); virtual;
procedure HandleMouseDblClick(var Message: TLMMouse; const HitInfo: THitInfo); virtual;
Expand Down Expand Up @@ -1237,8 +1236,6 @@ TBaseVirtualTree = class abstract(TVTBaseAncestor)
{$ifdef DelphiStyleServices}
procedure UpdateStyleElements; override;
{$ifend}
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;
Expand Down Expand Up @@ -2220,8 +2217,9 @@ procedure InitializeGlobalStructures();

TheInstance := HINSTANCE;

// Register the tree reference clipboard format. Others will be handled in InternalClipboarFormats.
// Register the tree reference clipboard format.
CF_VTREFERENCE := RegisterClipboardFormat(CFSTR_VTREFERENCE);
CF_VTHEADERREFERENCE := RegisterClipboardFormat(CFSTR_VTHEADERREFERENCE);

UtilityImages := CreateBitmapFromResourceName(TheInstance, BuildResourceName('vt_utilities'));
UtilityImageSize := UtilityImages.Height;
Expand Down Expand Up @@ -12896,13 +12894,6 @@ function TBaseVirtualTree.GetOptionsClass: TTreeOptionsClass;

//----------------------------------------------------------------------------------------------------------------------

function TBaseVirtualTree.GetTreeFromDataObject(const DataObject: TVTDragDataObject): TBaseVirtualTree;
begin
Result:= nil;
end;

//----------------------------------------------------------------------------------------------------------------------

function TBaseVirtualTree.GetRealImagesWidth: Integer;
begin
Result := GetRealImageListWidth(FImages);
Expand Down Expand Up @@ -16596,94 +16587,7 @@ procedure TBaseVirtualTree.UpdateEditBounds;
}
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}

//This function was originally designed only for tree's drag image. But we modified
//it for reusing it with header's drag image too for solving issue 248.
useDragImage: TVTDragImage;
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);

//Take proper drag image depending on whether the drag is being done in the tree
//or in the header.
if (Tree.FHeader.DragImage <> nil) and (Tree.FHeader.DragImage.Visible) then
begin
useDragImage := Tree.FHeader.DragImage;

// 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.
useDragImage.RecaptureBackground(Self, TreeRect, VisibleTreeRegion, UpdateNCArea, ReshowDragImage);

// Calculate the screen area not covered by the drag image and which needs an update.
DragRect := useDragImage.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(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(nil, UpdateRegion, RedrawFlags);
DeleteObject(UpdateRegion);
DeleteObject(DragRegion);
DeleteObject(VisibleTreeRegion);
end;
end;
{$endif}
end;

//----------------------------------------------------------------------------------------------------------------------
function GetRandomRgn(DC: HDC; Rgn: HRGN; iNum: Integer): Integer; stdcall; external 'GDI32.DLL';

procedure TBaseVirtualTree.ValidateCache();

Expand Down Expand Up @@ -22457,7 +22361,8 @@ procedure TBaseVirtualTree.PrepareDragImage(HotSpot: TPoint; const DataObject: T
// 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);
HotSpot.X := Width div 2;
HotSpot.Y := Height div 2;

lDragImage.ColorKey := FColors.BackGroundColor;
lDragImage.PrepareDrag(Image, ImagePos, HotSpot, DataObject);
Expand Down Expand Up @@ -22643,7 +22548,7 @@ function TBaseVirtualTree.ProcessDrop(const DataObject: TVTDragDataObject; Targe
begin
BeginUpdate;
// try to get the source tree of the operation
Source := GetTreeFromDataObject(DataObject);
Source := TVTDragManager.GetTreeFromDataObject(DataObject);
if Assigned(Source) then
Source.BeginUpdate;
try
Expand Down
3 changes: 2 additions & 1 deletion Source/VirtualTrees.ClipBoard.pas
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ TClipboardFormatList = class
var
// Clipboard format IDs used in OLE drag'n drop and clipboard transfers.
CF_VIRTUALTREE,
CF_VTREFERENCE,
CF_VTREFERENCE, // Reference to a virtual tree
CF_VTHEADERREFERENCE, // A drag and drop of the column header took place
CF_VRTF,
CF_VRTFNOOBJS, // Unfortunately CF_RTF* is already defined as being
// registration strings so I have to use different identifiers.
Expand Down
67 changes: 44 additions & 23 deletions Source/VirtualTrees.DataObject.pas
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ interface
uses
Classes, Controls, Graphics, LCLType, SysUtils, Types, WSReferences,
{$ifdef Windows}
Windows,
ActiveX,
JwaWinBase,
{$endif}
Expand All @@ -30,6 +29,7 @@ interface
TVTDataObject = class(TInterfacedObject, IDataObject)
private
FOwner : TCustomControl; // The tree which provides clipboard or drag data.
FHeader : TPersistent; // 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
Expand All @@ -48,7 +48,8 @@ TVTDataObject = class(TInterfacedObject, IDataObject)
property InternalStgMediumArray : TInternalStgMediumArray read FInternalStgMediumArray write FInternalStgMediumArray;
property Owner : TCustomControl read FOwner;
public
constructor Create(AOwner : TCustomControl; ForClipboard : Boolean); virtual;
constructor Create(AOwner : TCustomControl; ForClipboard : Boolean); overload;
constructor Create(AHeader : TPersistent; AOwner : TCustomControl); overload;
destructor Destroy; override;

function DAdvise(const FormatEtc : TFormatEtc; advf : DWord; const advSink : IAdviseSink; out dwConnection : DWord) : HResult; virtual; stdcall;
Expand Down Expand Up @@ -84,12 +85,20 @@ constructor TVTDataObject.Create(AOwner : TCustomControl; ForClipboard : Boolean

FOwner := AOwner;
FForClipboard := ForClipboard;
TVTCracker(FOwner).GetNativeClipboardFormats(FFormatEtcArray);
if Assigned(FOWner) then
TVTCracker(FOwner).GetNativeClipboardFormats(FFormatEtcArray);
{$ENDIF}
end;

//----------------------------------------------------------------------------------------------------------------------

constructor TVTDataObject.Create(AHeader: TPersistent; AOwner : TCustomControl);
begin
FHeader := AHeader;
end;

//----------------------------------------------------------------------------------------------------------------------

destructor TVTDataObject.Destroy;
var
I : Integer;
Expand Down Expand Up @@ -389,8 +398,21 @@ function TVTDataObject.GetData(const FormatEtcIn : TFormatEtc; out Medium : TStg
{$ENDIF}
begin
{$IFDEF EnableWinDataObject}
if (FormatEtcIn.cfFormat = CF_VTHEADERREFERENCE) and Assigned(FHeader) then
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;
Exit(S_OK);
end; // if CF_VTHEADERREFERENCE


// The tree reference format is always supported and returned from here.
if FormatEtcIn.cfFormat = CF_VTREFERENCE then
if (FormatEtcIn.cfFormat = CF_VTREFERENCE) and Assigned(FOWner) 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.
Expand All @@ -405,31 +427,30 @@ function TVTDataObject.GetData(const FormatEtcIn : TFormatEtc; out Medium : TStg
GlobalUnLock(Medium.HGlobal);
Medium.tymed := TYMED_HGLOBAL;
Medium.PunkForRelease := nil;
Result := S_OK;
Exit(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
end; // if CF_VTREFERENCE

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
for I := 0 to High(FormatEtcArray) do
if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
begin
if EqualFormatEtc(FormatEtcIn, FormatEtcArray[I]) then
begin
if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
Result := TVTCracker(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard);
Break;
end;
if not RenderInternalOLEData(FormatEtcIn, Medium, Result) then
Result := TVTCracker(FOwner).RenderOLEData(FormatEtcIn, Medium, FForClipboard);
Break;
end;
end;
except
FillChar(Medium, SizeOf(Medium), #0);
Result := E_FAIL;
ZeroMemory(@Medium, SizeOf(Medium));
end;
end;
except
ZeroMemory(@Medium, SizeOf(Medium));
Result := E_FAIL;
end; // try..except
{$ENDIF}
end;

Expand Down
3 changes: 1 addition & 2 deletions Source/VirtualTrees.DragImage.pas
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,7 @@ procedure TVTDragImage.PrepareDrag(DragImage : TBitmap; ImagePosition, HotSpot :
// 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;
DragInfo.ptOffset := HotSpot;
//lcl
//todo: replace CopyImage. Alternatively reimplement Drag support
{$ifndef INCOMPLETE_WINAPI}
Expand Down
Loading

0 comments on commit 74b9db5

Please sign in to comment.