git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@26 05c56307-c608-d34a-929d-697000501d7a
1344 lines
40 KiB
ObjectPascal
1344 lines
40 KiB
ObjectPascal
{*******************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressPrinting System(tm) COMPONENT SUITE }
|
|
{ }
|
|
{ Copyright (C) 1998-2008 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSPRINTINGSYSTEM AND }
|
|
{ ALL ACCOMPANYING VCL CONTROLS AS PART OF AN }
|
|
{ EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{*******************************************************************}
|
|
|
|
unit dxPSXplorerTreeView;
|
|
|
|
interface
|
|
|
|
{$I cxVer.inc}
|
|
|
|
uses
|
|
Windows, Classes, Messages, CommCtrl, Graphics, Controls, ExtCtrls, ComCtrls,
|
|
Forms, dxPSCore;
|
|
|
|
type
|
|
TCustomTreeViewClass = class of TCustomTreeView;
|
|
|
|
TCustomdxPSExplorerTreeViewContainer = class(TCustomdxPSExplorerTreeContainer)
|
|
private
|
|
FFocusedNode: TTreeNode;
|
|
FStorageStream: TMemoryStream;
|
|
function GetRootNode: TTreeNode;
|
|
function GetTreeView: TCustomTreeView;
|
|
procedure TreeCancelEdit(Sender: TObject; ANode: TTreeNode);
|
|
procedure TreeChanged(Sender: TObject; ANode: TTreeNode);
|
|
procedure TreeCollapsing(Sender: TObject; Node: TTreeNode; var AllowCollapse: Boolean);
|
|
procedure TreeCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode;
|
|
State: TCustomDrawState; var DefaultDraw: Boolean);
|
|
procedure TreeDblClick(Sender: TObject);
|
|
procedure TreeDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
procedure TreeDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
procedure TreeEdited(Sender: TObject; Node: TTreeNode; var S: string);
|
|
procedure TreeEditing(Sender: TObject; Node: TTreeNode; var AllowEdit: Boolean);
|
|
procedure TreeExpanding(Sender: TObject; Node: TTreeNode; var AllowExpansion: Boolean);
|
|
procedure TreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
procedure TreeKeyPress(Sender: TObject; var Key: Char);
|
|
procedure TreeMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
|
|
procedure ReadTreeViewState;
|
|
procedure WriteTreeViewState;
|
|
protected
|
|
procedure AddItem(AParent: TdxPSExplorerFolder; AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure Clear; override;
|
|
procedure DeleteItem(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure InvalidateItem(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure MoveItem(AnItem: TCustomdxPSExplorerItem); override;
|
|
procedure RenameItem(AnItem: TCustomdxPSExplorerItem); override;
|
|
|
|
function GetCreationParent: TdxPSExplorerFolder; override;
|
|
function GetFocusedItem: TCustomdxPSExplorerItem; override;
|
|
function GetIsEditing: Boolean; override;
|
|
function GetIsFolderSelected: Boolean; override;
|
|
function GetIsItemSelected: Boolean; override;
|
|
function GetIsRootSelected: Boolean; override;
|
|
function GetSelectedFolder: TdxPSExplorerFolder; override;
|
|
function GetSelectedItem: TCustomdxPSExplorerItem; override;
|
|
function GetSelectedItemText: string; override;
|
|
procedure SetFocusedItem(Value: TCustomdxPSExplorerItem); override;
|
|
procedure SetSelectedItem(Value: TCustomdxPSExplorerItem); override;
|
|
procedure SetSelectedItemText(const Value: string); override;
|
|
|
|
procedure RestoreState; override;
|
|
procedure SaveState; override;
|
|
|
|
procedure InitializeTreeContainer; override;
|
|
|
|
function AddNode(AParent: TTreeNode; AnItem: TCustomdxPSExplorerItem): TTreeNode; virtual;
|
|
function CanDragNode(ANode: TTreeNode): Boolean; virtual;
|
|
function GetHitTestInfoAt(X, Y: Integer): THitTests;
|
|
function GetItemByNode(ANode: TTreeNode): TCustomdxPSExplorerItem;
|
|
function GetNodeByItem(AnItem: TCustomdxPSExplorerItem): TTreeNode;
|
|
|
|
property FocusedNode: TTreeNode read FFocusedNode;
|
|
property RootNode: TTreeNode read GetRootNode;
|
|
property TreeView: TCustomTreeView read GetTreeView;
|
|
public
|
|
function BeginEdit(AnImmediate: Boolean = True): Boolean; override;
|
|
procedure EndEdit(ACancel: Boolean); override;
|
|
|
|
class function ControlClass: TWinControlClass; override;
|
|
class function TreeViewClass: TCustomTreeViewClass; virtual;
|
|
|
|
procedure CollapseItem(AnItem: TCustomdxPSExplorerItem; ARecursive: Boolean = False); override;
|
|
procedure ExpandItem(AnItem: TCustomdxPSExplorerItem; ARecursive: Boolean = False); override;
|
|
procedure MakeItemVisible(AnItem: TCustomdxPSExplorerItem); override;
|
|
|
|
procedure BeginUpdate; override;
|
|
procedure EndUpdate; override;
|
|
|
|
procedure RefreshSorting(ANode: TObject); override;
|
|
procedure RefreshSorting(AFolder: TdxPSExplorerFolder); override;
|
|
|
|
function GetDropTarget(X, Y: Integer): TdxPSExplorerFolder; override;
|
|
function GetItemAt(X, Y: Integer): TCustomdxPSExplorerItem; override;
|
|
function GetItemAtMousePos: TCustomdxPSExplorerItem;
|
|
end;
|
|
|
|
{$IFDEF DELPHI5}
|
|
{$IFNDEF DELPHI6}
|
|
{$DEFINE WMCONTEXTMENU}
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
TdxPSExplorerTreeViewScrollArea = (etsaLeft, etsaTop, etsaRight, etsaBottom);
|
|
TdxPSExplorerTreeViewScrollAreas = set of TdxPSExplorerTreeViewScrollArea;
|
|
|
|
TdxPSExplorerTreeView = class(TTreeView)
|
|
private
|
|
FContainer: TCustomdxPSExplorerTreeViewContainer;
|
|
FDragImage: TDragImageList;
|
|
FExpandTimer: TTimer;
|
|
FFlat: Boolean;
|
|
FSavedDropTarget: TTreeNode;
|
|
FSavedScrollActiveAreas: TdxPSExplorerTreeViewScrollAreas;
|
|
FScrollTimer: TTimer;
|
|
{$IFNDEF DELPHI6}
|
|
FOnCancelEdit: TTVChangedEvent;
|
|
{$ENDIF}
|
|
function GetIsMouseInScrollArea: Boolean;
|
|
function GetIsMouseInScrollAreaBound(ScrollArea: TdxPSExplorerTreeViewScrollArea): Boolean;
|
|
function GetScrollActiveAreas: TdxPSExplorerTreeViewScrollAreas;
|
|
function GetScrollAreaBounds(ScrollArea: TdxPSExplorerTreeViewScrollArea): TRect;
|
|
procedure SetFlat(Value: Boolean);
|
|
procedure OnExpandTimer(Sender: TObject);
|
|
procedure OnScrollTimer(Sender: TObject);
|
|
{$IFDEF WMCONTEXTMENU}
|
|
procedure WMContextMenu(var Message: TWMContextMenu); message WM_CONTEXTMENU;
|
|
{$ENDIF}
|
|
procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
|
|
procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
|
|
protected
|
|
function CanCollapse(Node: TTreeNode): Boolean; override;
|
|
function CanEdit(Node: TTreeNode): Boolean; override;
|
|
function CanExpand(Node: TTreeNode): Boolean; override;
|
|
procedure Change(Node: TTreeNode); override;
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
procedure DblClick; override;
|
|
procedure DoEndDrag(Target: TObject; X, Y: Integer); override;
|
|
procedure DoStartDrag(var DragObject: TDragObject); override;
|
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override;
|
|
{$IFNDEF DELPHI6}
|
|
procedure Edit(const Item: TTVItem); override;
|
|
{$ENDIF}
|
|
function GetDragImages: TDragImageList; override;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure KeyPress(var Key: Char); override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure WndProc(var Message: TMessage); override;
|
|
|
|
function CanDragNode(ANode: TTreeNode): Boolean; virtual;
|
|
procedure DrawFlatEdge; virtual;
|
|
function GetInfoTip(AnItem: HTREEITEM): string;
|
|
function MakeDragBitmap(ANode: TTreeNode): Graphics.TBitmap; virtual;
|
|
procedure UpdateDragMode(ANode: TTreeNode);
|
|
|
|
property Container: TCustomdxPSExplorerTreeViewContainer read FContainer write FContainer;
|
|
property IsMouseInScrollArea: Boolean read GetIsMouseInScrollArea;
|
|
property IsMouseInScrollAreaBounds[ScrollArea: TdxPSExplorerTreeViewScrollArea]: Boolean read GetIsMouseInScrollAreaBound;
|
|
property ScrollActiveAreas: TdxPSExplorerTreeViewScrollAreas read GetScrollActiveAreas;
|
|
property ScrollAreaBounds[ScrollArea: TdxPSExplorerTreeViewScrollArea]: TRect read GetScrollAreaBounds;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
constructor CreateEx(AOwner: TComponent; AContainer: TCustomdxPSExplorerTreeViewContainer); virtual;
|
|
|
|
procedure DragDrop(Source: TObject; X, Y: Integer); override;
|
|
|
|
property Flat: Boolean read FFlat write SetFlat;
|
|
property OnCancelEdit{$IFNDEF DELPHI6} : TTVChangedEvent read FOnCancelEdit write FOnCancelEdit{$ENDIF};
|
|
end;
|
|
|
|
TdxPSExplorerTreeViewContainer = class(TCustomdxPSExplorerTreeViewContainer)
|
|
private
|
|
function GetTreeView: TdxPSExplorerTreeView;
|
|
protected
|
|
procedure InitializeTreeContainer; override;
|
|
public
|
|
class function TreeViewClass: TCustomTreeViewClass; override;
|
|
property TreeView: TdxPSExplorerTreeView read GetTreeView;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils, cxClasses, dxPSUtl, dxPSGlbl;
|
|
|
|
const
|
|
ScrollAreaHeight = 30;
|
|
ScrollAreaWidth = 30;
|
|
|
|
type
|
|
TCustomTreeViewAccess = class(TCustomTreeView);
|
|
|
|
|
|
{ TreeView Helpers }
|
|
|
|
function TreeView_GetItems(AControl: TCustomTreeView): TTreeNodes;
|
|
begin
|
|
Result := TCustomTreeViewAccess(AControl).Items;
|
|
end;
|
|
|
|
{ TCustomdxPSExplorerTreeViewContainer }
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.BeginEdit(AnImmediate: Boolean = True): Boolean;
|
|
var
|
|
SelectedNode: TTreeNode;
|
|
begin
|
|
Result := CanRenameSelectedItem;
|
|
if Result then
|
|
begin
|
|
SelectedNode := TreeView.Selected;
|
|
if AnImmediate then
|
|
Result := SelectedNode.EditText
|
|
else
|
|
Result := PostMessage(TreeView.Handle, TVM_EDITLABEL, 0, lParam(SelectedNode.ItemId));
|
|
Host.UpdateState;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.EndEdit(ACancel: Boolean);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
if TreeView.IsEditing then
|
|
begin
|
|
Node := TreeView.Selected;
|
|
if Node <> nil then Node.EndEdit(ACancel);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.CollapseItem(AnItem: TCustomdxPSExplorerItem;
|
|
ARecursive: Boolean = False);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := GetNodeByItem(AnItem);
|
|
if Node <> nil then Node.Collapse(ARecursive);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.ExpandItem(AnItem: TCustomdxPSExplorerItem;
|
|
ARecursive: Boolean = False);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := GetNodeByItem(AnItem);
|
|
if Node <> nil then
|
|
begin
|
|
dxPSCore.dxPSStartWait;
|
|
try
|
|
Node.Expand(ARecursive);
|
|
finally
|
|
dxPSCore.dxPSStopWait;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.MakeItemVisible(AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := GetNodeByItem(AnItem);
|
|
if Node <> nil then
|
|
begin
|
|
Node.MakeVisible;
|
|
Node.Focused := True;
|
|
Node.Selected := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.BeginUpdate;
|
|
begin
|
|
inherited;
|
|
TreeView_GetItems(TreeView).BeginUpdate;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.EndUpdate;
|
|
begin
|
|
TreeView_GetItems(TreeView).EndUpdate;
|
|
inherited;
|
|
end;
|
|
|
|
function TreeSortFunc(lParam1, lParam2, lParamSort: Longint): Integer; stdcall;
|
|
begin
|
|
if lParam2 <> 0 then
|
|
Result := TCustomdxPSExplorerItemComparator.CompareItems(TTreeNode(lParam1).Data, TTreeNode(lParam2).Data)
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.RefreshSorting(ANode: TObject);
|
|
begin
|
|
if Explorer.State * [esLoading{, esRefreshing}] = [] then
|
|
if ANode <> nil then
|
|
TTreeNode(ANode).CustomSort(TreeSortFunc, (0) {$IFDEF DELPHI6}, False{$ENDIF})
|
|
else
|
|
TreeView.CustomSort(TreeSortFunc, (0) {$IFDEF DELPHI6}, True{$ENDIF})
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.RefreshSorting(AFolder: TdxPSExplorerFolder);
|
|
var
|
|
Node: TObject;
|
|
begin
|
|
if (AFolder = nil) or AFolder.IsRoot then
|
|
Node := nil
|
|
else
|
|
Node := GetNodeByItem(AFolder);
|
|
RefreshSorting(Node);
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerTreeViewContainer.ControlClass: TWinControlClass;
|
|
begin
|
|
Result := TreeViewClass;
|
|
end;
|
|
|
|
class function TCustomdxPSExplorerTreeViewContainer.TreeViewClass: TCustomTreeViewClass;
|
|
begin
|
|
Result := TCustomTreeView;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetItemAt(X, Y: Integer): TCustomdxPSExplorerItem;
|
|
begin
|
|
Result := GetItemByNode(TreeView.GetNodeAt(X, Y))
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetItemAtMousePos: TCustomdxPSExplorerItem;
|
|
begin
|
|
with Control.ScreenToClient(Mouse.CursorPos) do
|
|
Result := GetItemAt(X, Y);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetDropTarget(X, Y: Integer): TdxPSExplorerFolder;
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
begin
|
|
if TreeView.DropTarget <> nil then
|
|
if [ComCtrls.htBelow, ComCtrls.htNowhere] * GetHitTestInfoAt(X, Y) = [] then
|
|
begin
|
|
Item := GetItemByNode(TreeView.DropTarget);
|
|
if Item is TdxPSExplorerFolder then
|
|
Result := TdxPSExplorerFolder(Item)
|
|
else
|
|
Result := nil;
|
|
end
|
|
else
|
|
Result := Explorer.Root
|
|
else
|
|
Result := Explorer.Root;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.AddItem(AParent: TdxPSExplorerFolder;
|
|
AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := AddNode(GetNodeByItem(AParent), AnItem);
|
|
if AnItem is TdxPSExplorerFolder then
|
|
Node.HasChildren := TdxPSExplorerFolderHelper.GetHasChildren(TdxPSExplorerFolder(AnItem));
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.Clear;
|
|
begin
|
|
TreeView_GetItems(TreeView).Clear;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.DeleteItem(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
inherited;
|
|
GetNodeByItem(AnItem).Delete;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.InvalidateItem(AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
Node: TTreeNode;
|
|
R: TRect;
|
|
begin
|
|
Node := GetNodeByItem(AnItem);
|
|
if Node <> nil then
|
|
begin
|
|
R := Node.DisplayRect(False);
|
|
InvalidateRect(TreeView.Handle, @R, True);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.MoveItem(AnItem: TCustomdxPSExplorerItem);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := GetNodeByItem(AnItem);
|
|
if Node <> nil then { We are not in creation phase of parent assigning }
|
|
if AnItem is TdxPSExplorerFolder then
|
|
Node.MoveTo(GetNodeByItem(AnItem.Parent), naAddChildFirst)
|
|
else
|
|
Node.MoveTo(GetNodeByItem(AnItem.Parent), naAddChild);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.RenameItem(AnItem: TCustomdxPSExplorerItem);
|
|
begin
|
|
GetNodeByItem(AnItem).Text := AnItem.DisplayName;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetCreationParent: TdxPSExplorerFolder;
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
begin
|
|
Item := SelectedItem;
|
|
if Item = nil then
|
|
Result := Explorer.Root
|
|
else
|
|
if not (Item is TdxPSExplorerFolder) then
|
|
Result := Item.Parent
|
|
else
|
|
Result := TdxPSExplorerFolder(Item);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetFocusedItem: TCustomdxPSExplorerItem;
|
|
begin
|
|
Result := GetItemByNode(FocusedNode);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetIsEditing: Boolean;
|
|
begin
|
|
Result := TreeView.IsEditing;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetIsFolderSelected: Boolean;
|
|
begin
|
|
Result := SelectedItem is TdxPSExplorerFolder;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetIsItemSelected: Boolean;
|
|
begin
|
|
Result := SelectedItem is TdxPSExplorerItem;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetIsRootSelected: Boolean;
|
|
begin
|
|
Result := SelectedItem = Explorer.Root;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetSelectedFolder: TdxPSExplorerFolder;
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
begin
|
|
Item := SelectedItem;
|
|
if Item is TdxPSExplorerFolder then
|
|
Result := TdxPSExplorerFolder(Item)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetSelectedItem: TCustomdxPSExplorerItem;
|
|
begin
|
|
Result := GetItemByNode(TreeView.Selected);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetSelectedItemText: string;
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := GetNodeByItem(SelectedItem);
|
|
if Node <> nil then
|
|
Result := Node.Text
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.SetFocusedItem(Value: TCustomdxPSExplorerItem);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := GetNodeByItem(Value);
|
|
if Node <> nil then
|
|
Node.Focused := True;
|
|
FFocusedNode := Node;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.SetSelectedItem(Value: TCustomdxPSExplorerItem);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := GetNodeByItem(Value);
|
|
if Node <> nil then
|
|
Node.Selected := True;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.SetSelectedItemText(const Value: string);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Node := GetNodeByItem(SelectedItem);
|
|
if Node <> nil then
|
|
begin
|
|
Node.Text := Value;
|
|
//RefreshSorting(Node.Parent); {.1}
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.RestoreState;
|
|
begin
|
|
FStorageStream.Position := 0;
|
|
ReadTreeViewState;
|
|
FreeAndNil(FStorageStream);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.SaveState;
|
|
begin
|
|
FStorageStream := TMemoryStream.Create;
|
|
WriteTreeViewState;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.InitializeTreeContainer;
|
|
begin
|
|
inherited;
|
|
TCustomTreeViewAccess(TreeView).OnCustomDrawItem := TreeCustomDrawItem;
|
|
TCustomTreeViewAccess(TreeView).OnEdited := TreeEdited;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.AddNode(AParent: TTreeNode;
|
|
AnItem: TCustomdxPSExplorerItem): TTreeNode;
|
|
begin
|
|
Result := TreeView_GetItems(TreeView).AddChildObject(AParent, AnItem.DisplayName, AnItem);
|
|
Result.ImageIndex := TCustomdxPSExplorerItemHelper.GetImageIndex(AnItem);
|
|
Result.SelectedIndex := TCustomdxPSExplorerItemHelper.GetSelectedIndex(AnItem);
|
|
// RefreshSorting(AParent); //3.1
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.CanDragNode(ANode: TTreeNode): Boolean;
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
begin
|
|
Item := GetItemByNode(ANode);
|
|
Result := (Item <> nil) and Item.CanMove;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetHitTestInfoAt(X, Y: Integer): THitTests;
|
|
begin
|
|
Result := TreeView.GetHitTestInfoAt(X, Y);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetItemByNode(ANode: TTreeNode): TCustomdxPSExplorerItem;
|
|
begin
|
|
if ANode <> nil then
|
|
Result := TCustomdxPSExplorerItem(ANode.Data)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetNodeByItem(AnItem: TCustomdxPSExplorerItem): TTreeNode;
|
|
|
|
function FindInChildren(ANode: TTreeNode): TTreeNode;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to ANode.Count - 1 do
|
|
begin
|
|
Result := ANode[I];
|
|
if GetItemByNode(Result) = AnItem then
|
|
Exit;
|
|
if Result.HasChildren then
|
|
begin
|
|
Result := FindInChildren(Result);
|
|
if Result <> nil then Exit;
|
|
end;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
begin
|
|
Result := RootNode;
|
|
if (Result <> nil) and (GetItemByNode(Result) <> AnItem) then
|
|
Result := FindInChildren(Result);
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetRootNode: TTreeNode;
|
|
begin
|
|
Result := TreeView_GetItems(TreeView).GetFirstNode;
|
|
end;
|
|
|
|
function TCustomdxPSExplorerTreeViewContainer.GetTreeView: TCustomTreeView;
|
|
begin
|
|
Result := TCustomTreeView(Control);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeCollapsing(Sender: TObject;
|
|
Node: TTreeNode; var AllowCollapse: Boolean);
|
|
begin
|
|
AllowCollapse := GetItemByNode(Node) <> Explorer.Root;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeCustomDrawItem(Sender: TCustomTreeView;
|
|
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
begin
|
|
Item := GetItemByNode(Node);
|
|
if Item is TdxPSExplorerItem then
|
|
with Sender.Canvas do
|
|
begin
|
|
if TdxPSExplorerItem(Item).IsCurrentlyLoaded then
|
|
Font.Style := Font.Style + [fsBold];
|
|
if TdxPSExplorerItem(Item).HasInvalidData then
|
|
Font.Color := clGrayText;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeDblClick(Sender: TObject);
|
|
begin
|
|
if (SelectedItem <> nil) and (GetItemAtMousePos = SelectedItem) and CanLoadSelectedItemData then
|
|
LoadSelectedItemData;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeDragDrop(Sender, Source: TObject;
|
|
X, Y: Integer);
|
|
begin
|
|
SelectedItem.Parent := GetDropTarget(X, Y);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeDragOver(Sender, Source: TObject;
|
|
X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
begin
|
|
Accept := (Source = Sender) and SelectedItem.CanMoveTo(GetDropTarget(X, Y));
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeCancelEdit(Sender: TObject; ANode: TTreeNode);
|
|
begin
|
|
Host.UpdateState;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeChanged(Sender: TObject; ANode: TTreeNode);
|
|
begin
|
|
FFocusedNode := ANode;
|
|
Host.UpdateState;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeEdited(Sender: TObject; Node: TTreeNode;
|
|
var S: string);
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
ErrorText: string;
|
|
begin
|
|
if Node.Selected then Node.Focused := True;
|
|
|
|
Item := GetItemByNode(Node);
|
|
if not dxSameStr(Item.DisplayName, S) then
|
|
if not Item.CanRenameTo(S) then
|
|
begin
|
|
ErrorText := Item.CannotRenameMessageText(Item.DisplayName, S);
|
|
dxPSUtl.MessageError(ErrorText);
|
|
BeginEdit(False);
|
|
end
|
|
else
|
|
Item.Name := S;
|
|
|
|
Host.UpdateState;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeEditing(Sender: TObject; Node: TTreeNode;
|
|
var AllowEdit: Boolean);
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
Editor: HWND;
|
|
begin
|
|
Item := GetItemByNode(Node);
|
|
AllowEdit := (Item <> nil) and Item.CanRename;
|
|
if AllowEdit then
|
|
begin
|
|
TreeView.Selected.Text := Item.DisplayName;
|
|
Editor := TreeView_GetEditControl(TreeView.Handle);
|
|
if IsWindow(Editor) then
|
|
SendMessage(Editor, WM_SETTEXT, 0, Integer(PChar(Item.DisplayName)));
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeExpanding(Sender: TObject; Node: TTreeNode;
|
|
var AllowExpansion: Boolean);
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
begin
|
|
Item := GetItemByNode(Node);
|
|
if Item is TdxPSExplorerFolder then
|
|
begin
|
|
TdxPSExplorerFolder(Item).Populate;
|
|
//RefreshSorting(Item);
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeKeyDown(Sender: TObject;
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
ProcessKeyDown(Key, Shift);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeKeyPress(Sender: TObject;
|
|
var Key: Char);
|
|
begin
|
|
ProcessKeyPress(Key);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.TreeMouseDown(Sender: TObject;
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
Host.UpdateState;
|
|
end;
|
|
|
|
type
|
|
TdxNodeInfo = record
|
|
Expanded: Integer;
|
|
Count: Integer;
|
|
UniqueIDSize: Integer;
|
|
//UniqueID: TBytes with UniqueIDSize length
|
|
end;
|
|
|
|
function GetNodeInfoSize: Integer;
|
|
begin
|
|
Result := SizeOf(TdxNodeInfo);
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.ReadTreeViewState;
|
|
|
|
function ReadNode(ARecursive: Boolean): TTreeNode;
|
|
var
|
|
NodeInfo: TdxNodeInfo;
|
|
Bytes: TBytes;
|
|
Item: TCustomdxPSExplorerItem;
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
FStorageStream.ReadBuffer(NodeInfo, GetNodeInfoSize);
|
|
if NodeInfo.UniqueIDSize <> 0 then
|
|
begin
|
|
SetLength(Bytes, NodeInfo.UniqueIDSize);
|
|
FStorageStream.ReadBuffer(Pointer(Bytes)^, NodeInfo.UniqueIDSize);
|
|
Item := Explorer.FindCustomItemByUniqueID(Bytes);
|
|
if Item <> nil then
|
|
begin
|
|
Result := GetNodeByItem(Item);
|
|
if Result <> nil then
|
|
Result.Expanded := NodeInfo.Expanded = 1;
|
|
end;
|
|
end;
|
|
if ARecursive then
|
|
for I := 0 to NodeInfo.Count - 1 do
|
|
ReadNode(ARecursive);
|
|
end;
|
|
|
|
procedure ReadSelection;
|
|
var
|
|
Buffer: Integer;
|
|
begin
|
|
FStorageStream.ReadBuffer(Buffer, SizeOf(Buffer));
|
|
if Buffer <> 0 then
|
|
TreeView.Selected := ReadNode(False);
|
|
end;
|
|
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
ReadNode(True);
|
|
ReadSelection;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomdxPSExplorerTreeViewContainer.WriteTreeViewState;
|
|
|
|
procedure WriteNode(ANode: TTreeNode; ARecursive: Boolean);
|
|
var
|
|
Item: TCustomdxPSExplorerItem;
|
|
NodeInfo: TdxNodeInfo;
|
|
Bytes: TBytes;
|
|
I: Integer;
|
|
begin
|
|
Item := GetItemByNode(ANode);
|
|
with NodeInfo do
|
|
begin
|
|
Expanded := Ord(ANode.Expanded);
|
|
if Expanded = 1 then
|
|
Count := ANode.Count
|
|
else
|
|
Count := 0;
|
|
UniqueIDSize := Item.GetUniqueID(Bytes);
|
|
end;
|
|
FStorageStream.WriteBuffer(NodeInfo, GetNodeInfoSize);
|
|
if NodeInfo.UniqueIDSize <> 0 then
|
|
FStorageStream.WriteBuffer(Pointer(Bytes)^, NodeInfo.UniqueIDSize);
|
|
|
|
for I := 0 to ANode.Count - 1 do
|
|
WriteNode(ANode[I], ARecursive);
|
|
end;
|
|
|
|
procedure WriteSelection;
|
|
var
|
|
Flag: Integer;
|
|
begin
|
|
Flag := Ord(TreeView.Selected <> nil);
|
|
FStorageStream.WriteBuffer(Flag , SizeOf(Flag));
|
|
if TreeView.Selected <> nil then
|
|
WriteNode(TreeView.Selected, False);
|
|
end;
|
|
|
|
begin
|
|
WriteNode(RootNode, True);
|
|
WriteSelection;
|
|
end;
|
|
|
|
{ TdxPSExplorerTreeView }
|
|
|
|
constructor TdxPSExplorerTreeView.Create(AOwner: TComponent);
|
|
|
|
function CreateTimer(AnInterval: Integer; AnOnTimer: TNotifyEvent): TTimer;
|
|
begin
|
|
Result := TTimer.Create(Self);
|
|
Result.Enabled := False;
|
|
Result.Interval := AnInterval;
|
|
Result.OnTimer := AnOnTimer;
|
|
end;
|
|
|
|
begin
|
|
inherited;
|
|
Align := alClient;
|
|
DragMode := dmAutomatic;
|
|
HideSelection := False;
|
|
Images := dxPSExplorerImages;
|
|
ShowHint := True;
|
|
ShowRoot := False;
|
|
if IsWin32Version(5, 1) then
|
|
begin
|
|
ShowLines := False;
|
|
//HotTrack := True;
|
|
end;
|
|
|
|
FDragImage := TDragImageList.Create(Self);
|
|
|
|
FExpandTimer := CreateTimer(500, OnExpandTimer);
|
|
FScrollTimer := CreateTimer(80, OnScrollTimer);
|
|
end;
|
|
|
|
constructor TdxPSExplorerTreeView.CreateEx(AOwner: TComponent;
|
|
AContainer: TCustomdxPSExplorerTreeViewContainer);
|
|
begin
|
|
Create(AOwner);
|
|
FContainer := AContainer;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.DragDrop(Source: TObject; X, Y: Integer);
|
|
begin
|
|
inherited;
|
|
Container.TreeDragDrop(Self, Source, X, Y);
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.CanCollapse(Node: TTreeNode): Boolean;
|
|
begin
|
|
Result := inherited CanCollapse(Node);
|
|
Container.TreeCollapsing(Self, Node, Result);
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.CanEdit(Node: TTreeNode): Boolean;
|
|
begin
|
|
Result := inherited CanEdit(Node);
|
|
Container.TreeEditing(Self, Node, Result);
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.CanExpand(Node: TTreeNode): Boolean;
|
|
begin
|
|
Result := inherited CanExpand(Node);
|
|
Container.TreeExpanding(Self, Node, Result);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.Change(Node: TTreeNode);
|
|
begin
|
|
inherited;
|
|
Container.TreeChanged(Self, Node);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.CreateParams(var Params: TCreateParams);
|
|
begin
|
|
inherited;
|
|
Params.Style := Params.Style or TVS_INFOTIP;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.DblClick;
|
|
begin
|
|
inherited;
|
|
Container.TreeDblClick(Self);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.DoEndDrag(Target: TObject; X, Y: Integer);
|
|
begin
|
|
FDragImage.Clear;
|
|
FSavedScrollActiveAreas := [];
|
|
FSavedDropTarget := nil;
|
|
FExpandTimer.Enabled := False;
|
|
FScrollTimer.Enabled := False;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.DoStartDrag(var DragObject: TDragObject);
|
|
var
|
|
Pt: TPoint;
|
|
DragNode: TTreeNode;
|
|
Bitmap: Graphics.TBitmap;
|
|
begin
|
|
inherited;
|
|
Pt := ScreenToClient(Mouse.CursorPos);
|
|
DragNode := GetNodeAt(Pt.X, Pt.Y);
|
|
if DragNode <> nil then
|
|
begin
|
|
FDragImage.Handle := TreeView_CreateDragImage(Handle, DragNode.ItemId);
|
|
if FDragImage.Handle <> 0 then
|
|
begin
|
|
//Item := GetItemFromNode(DragNode);
|
|
//Item.Unload;
|
|
Bitmap := MakeDragBitmap(DragNode);
|
|
try
|
|
with FDragImage do
|
|
begin
|
|
Clear;
|
|
Width := Bitmap.Width;
|
|
Height := Bitmap.Height;
|
|
AddMasked(Bitmap, clDefault);
|
|
SetDragImage(0, 2, 2);
|
|
end;
|
|
finally
|
|
Bitmap.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
|
var Accept: Boolean);
|
|
begin
|
|
inherited;
|
|
Container.TreeDragOver(Self, Source, X, Y, State, Accept);
|
|
if Accept and (DropTarget <> nil) and not DropTarget.Expanded then
|
|
begin
|
|
FSavedDropTarget := DropTarget;
|
|
FExpandTimer.Enabled := False;
|
|
FExpandTimer.Enabled := True;
|
|
end;
|
|
if IsMouseInScrollArea then
|
|
begin
|
|
FSavedScrollActiveAreas := ScrollActiveAreas;
|
|
FScrollTimer.Enabled := False;
|
|
FScrollTimer.Enabled := True;
|
|
end;
|
|
end;
|
|
|
|
{$IFNDEF DELPHI6}
|
|
procedure TdxPSExplorerTreeView.Edit(const Item: TTVItem);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
inherited;
|
|
if Item.pszText = nil then
|
|
begin
|
|
if (Item.State and TVIF_PARAM) <> 0 then
|
|
Node := Pointer(Item.lParam)
|
|
else
|
|
Node := Items.GetNode(Item.hItem);
|
|
if Assigned(FOnCancelEdit) then FOnCancelEdit(Self, Node);
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function TdxPSExplorerTreeView.GetDragImages: TDragImageList;
|
|
begin
|
|
if FDragImage.Count <> 0 then
|
|
Result := FDragImage
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.KeyDown(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
inherited;
|
|
Container.TreeKeyDown(Self, Key, Shift);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.KeyPress(var Key: Char);
|
|
begin
|
|
inherited;
|
|
Container.TreeKeyPress(Self, Key);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
inherited;
|
|
Container.TreeMouseDown(Self, Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
Pt: TPoint;
|
|
Node: TTreeNode;
|
|
begin
|
|
if Button = mbRight then
|
|
begin
|
|
Pt := MakePoint(X, Y);
|
|
{$IFDEF DELPHI5}
|
|
{$IFNDEF DELPHI7}
|
|
Pt := ScreenToClient(Pt);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
Node := GetNodeAt(Pt.X, Pt.Y);
|
|
if Node <> nil then
|
|
begin
|
|
Node.Focused := True;
|
|
Node.Selected := True;
|
|
end;
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.WndProc(var Message: TMessage);
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
if (Message.Msg = WM_LBUTTONDOWN) or (Message.Msg = WM_LBUTTONDBLCLK) then
|
|
with TWMMouse(Message) do
|
|
if Keys and MK_LBUTTON = MK_LBUTTON then
|
|
begin
|
|
Node := GetNodeAt(XPos, YPos);
|
|
if Node <> nil then
|
|
UpdateDragMode(Node);
|
|
end;
|
|
try
|
|
inherited;
|
|
except
|
|
end;
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.CanDragNode(ANode: TTreeNode): Boolean;
|
|
begin
|
|
Result := (Container = nil) or Container.CanDragNode(ANode);
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.DrawFlatEdge;
|
|
var
|
|
R: TRect;
|
|
DC: HDC;
|
|
begin
|
|
GetWindowRect(Handle, R);
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
|
|
DC := GetWindowDC(Handle);
|
|
try
|
|
FrameRect(DC, R, GetSysColorBrush(COLOR_BTNSHADOW));
|
|
InflateRect(R, -1, -1);
|
|
FrameRect(DC, R, GetSysColorBrush(COLOR_WINDOW));
|
|
finally
|
|
ReleaseDC(Handle, DC);
|
|
end;
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.GetInfoTip(AnItem: HTREEITEM): string;
|
|
var
|
|
ExplorerItem: TCustomdxPSExplorerItem;
|
|
begin
|
|
ExplorerItem := TCustomdxPSExplorerItem(Items.GetNode(AnItem).Data);
|
|
if ExplorerItem <> nil then
|
|
Result := ExplorerItem.InfoTip
|
|
else
|
|
Result := '';
|
|
if Result <> '' then
|
|
Result := Result + ' ' + #0#0;
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.MakeDragBitmap(ANode: TTreeNode): Graphics.TBitmap;
|
|
const
|
|
Format: UINT = DT_LEFT or DT_CENTER or DT_END_ELLIPSIS or DT_SINGLELINE;
|
|
var
|
|
S: string;
|
|
R: TRect;
|
|
begin
|
|
S := ANode.Text;
|
|
|
|
Result := Graphics.TBitmap.Create;
|
|
with Result do
|
|
begin
|
|
Width := Images.Width + 2 + Self.Canvas.TextWidth(S) + 1;
|
|
Height := TreeView_GetItemHeight(Self.Handle);
|
|
R := MakeRect(0, 0, Width, Height);
|
|
|
|
Canvas.Brush.Color := clWhite;
|
|
Canvas.FillRect(R);
|
|
|
|
Images.Draw(Canvas, 0, 0, ANode.ImageIndex);
|
|
|
|
Canvas.Font.Assign(Self.Font);
|
|
Canvas.Brush.Style := bsClear;
|
|
Inc(R.Left, Images.Width + 2);
|
|
Windows.DrawText(Canvas.Handle, PChar(S), Length(S), R, Format);
|
|
Canvas.Brush.Style := bsSolid;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.UpdateDragMode(ANode: TTreeNode);
|
|
const
|
|
DragModesMap: array[Boolean] of TDragMode = (dmManual, dmAutomatic);
|
|
begin
|
|
DragMode := DragModesMap[CanDragNode(ANode)];
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.GetIsMouseInScrollArea: Boolean;
|
|
var
|
|
ScrollArea: TdxPSExplorerTreeViewScrollArea;
|
|
begin
|
|
Result := True;
|
|
for ScrollArea := Low(ScrollArea) to High(ScrollArea) do
|
|
if IsMouseInScrollAreaBounds[ScrollArea] then Exit;
|
|
Result := False;
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.GetIsMouseInScrollAreaBound(ScrollArea: TdxPSExplorerTreeViewScrollArea): Boolean;
|
|
begin
|
|
Result := PtInRect(ScrollAreaBounds[ScrollArea], ScreenToClient(Mouse.CursorPos));
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.GetScrollActiveAreas: TdxPSExplorerTreeViewScrollAreas;
|
|
var
|
|
ScrollArea: TdxPSExplorerTreeViewScrollArea;
|
|
begin
|
|
Result := [];
|
|
for ScrollArea := Low(ScrollArea) to High(ScrollArea) do
|
|
if IsMouseInScrollAreaBounds[ScrollArea] then
|
|
Include(Result, ScrollArea);
|
|
end;
|
|
|
|
function TdxPSExplorerTreeView.GetScrollAreaBounds(ScrollArea: TdxPSExplorerTreeViewScrollArea): TRect;
|
|
type
|
|
TScrollBarKind = (sbkHorz, sbkVert);
|
|
|
|
function HasScrollBar(AScrollBarKind: TScrollBarKind): Boolean;
|
|
const
|
|
ScrollBarKindMap: array[TScrollBarKind] of Integer = (WS_HSCROLL, WS_VSCROLL);
|
|
begin
|
|
Result := Windows.GetWindowLong(Handle, GWL_STYLE) and ScrollBarKindMap[AScrollBarKind] <> 0;
|
|
end;
|
|
|
|
function ScrollBarWidth(AScrollBarKind: TScrollBarKind): Integer;
|
|
const
|
|
ScrollBarWidthIndexMap: array[TScrollBarKind] of Integer = (SM_CYHSCROLL, SM_CXVSCROLL);
|
|
begin
|
|
Result := GetSystemMetrics(ScrollBarWidthIndexMap[AScrollBarKind]);
|
|
end;
|
|
|
|
begin
|
|
case ScrollArea of
|
|
etsaLeft:
|
|
Result := MakeRect(0, 0, ScrollAreaWidth, Height);
|
|
etsaTop:
|
|
Result := MakeRect(0, 0, Width, ScrollAreaHeight);
|
|
etsaRight:
|
|
begin
|
|
Result := MakeRect(Width - ScrollAreaWidth, 0, Width, Height);
|
|
if HasScrollBar(sbkVert) then
|
|
Dec(Result.Left, ScrollBarWidth(sbkVert));
|
|
end;
|
|
else //etsaBottom
|
|
begin
|
|
Result := MakeRect(0, Height - ScrollAreaHeight, Width, Height);
|
|
if HasScrollBar(sbkHorz) then
|
|
Dec(Result.Top, ScrollBarWidth(sbkHorz));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.SetFlat(Value: Boolean);
|
|
begin
|
|
if FFlat <> Value then
|
|
begin
|
|
FFlat := Value;
|
|
RecreateWnd;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.OnExpandTimer(Sender: TObject);
|
|
begin
|
|
FExpandTimer.Enabled := False;
|
|
|
|
if DropTarget = FSavedDropTarget then
|
|
begin
|
|
ImageList_DragShowNolock(False);
|
|
try
|
|
DropTarget.Expand(False);
|
|
finally
|
|
Update;
|
|
ImageList_DragShowNolock(True);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.OnScrollTimer(Sender: TObject);
|
|
|
|
procedure DoScroll(AMessage: Cardinal; AScrollCode: Integer);
|
|
begin
|
|
Perform(AMessage, AScrollCode, 0);
|
|
end;
|
|
|
|
const
|
|
ScrollMessages: array[TdxPSExplorerTreeViewScrollArea] of Cardinal = (WM_HSCROLL, WM_VSCROLL, WM_HSCROLL, WM_VSCROLL);
|
|
ScrollCodes: array[TdxPSExplorerTreeViewScrollArea] of Integer = (SB_LINELEFT, SB_LINEUP, SB_LINERIGHT, SB_LINEDOWN);
|
|
|
|
var
|
|
ScrollActiveAreas: TdxPSExplorerTreeViewScrollAreas;
|
|
ScrollArea: TdxPSExplorerTreeViewScrollArea;
|
|
begin
|
|
ScrollActiveAreas := Self.ScrollActiveAreas * FSavedScrollActiveAreas;
|
|
if ScrollActiveAreas <> [] then
|
|
begin
|
|
ImageList_DragShowNolock(False);
|
|
try
|
|
for ScrollArea := Low(ScrollArea) to High(ScrollArea) do
|
|
if ScrollArea in ScrollActiveAreas then
|
|
DoScroll(ScrollMessages[ScrollArea], ScrollCodes[ScrollArea]);
|
|
finally
|
|
Update;
|
|
ImageList_DragShowNolock(True);
|
|
end;
|
|
end;
|
|
FSavedScrollActiveAreas := Self.ScrollActiveAreas;
|
|
end;
|
|
|
|
{$IFDEF WMCONTEXTMENU}
|
|
procedure TdxPSExplorerTreeView.WMContextMenu(var Message: TWMContextMenu);
|
|
var
|
|
KeyState: TKeyboardState;
|
|
begin
|
|
inherited;
|
|
GetKeyboardState(KeyState);
|
|
MouseUp(mbRight, KeyboardStateToShiftState(KeyState), Message.Pos.X, Message.Pos.Y);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TdxPSExplorerTreeView.WMNCPaint(var Message: TWMNCPaint);
|
|
begin
|
|
inherited;
|
|
if Flat then DrawFlatEdge;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeView.CMHintShow(var Message: TCMHintShow);
|
|
|
|
function HasInfoTip: Boolean;
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
Result := dxPSGlbl.CanShowHints;
|
|
if Result then
|
|
begin
|
|
with Message.HintInfo^.CursorPos do
|
|
Node := GetNodeAt(X, Y);
|
|
Result := (Node <> nil) and (GetInfoTip(Node.ItemId) <> '');
|
|
end;
|
|
end;
|
|
|
|
var
|
|
Node: TTreeNode;
|
|
begin
|
|
if HasInfoTip then
|
|
begin
|
|
with Message.HintInfo^ do
|
|
begin
|
|
Node := GetNodeAt(CursorPos.X, CursorPos.Y);
|
|
|
|
CursorRect := Node.DisplayRect(True);
|
|
Windows.MapWindowPoints(Handle, 0, CursorRect, 2);
|
|
HintStr := GetInfoTip(Node.ItemId);
|
|
HintPos.Y := CursorRect.Top + Windows.GetSystemMetrics(SM_CYCURSOR);
|
|
HintPos.X := CursorRect.Left + Windows.GetSystemMetrics(SM_CXCURSOR);
|
|
HintMaxWidth := ClientWidth;
|
|
end;
|
|
Message.Result := 0;
|
|
end
|
|
else
|
|
inherited;
|
|
end;
|
|
|
|
{ TdxPSExplorerTreeViewContainer }
|
|
|
|
class function TdxPSExplorerTreeViewContainer.TreeViewClass: TCustomTreeViewClass;
|
|
begin
|
|
Result := TdxPSExplorerTreeView;
|
|
end;
|
|
|
|
procedure TdxPSExplorerTreeViewContainer.InitializeTreeContainer;
|
|
begin
|
|
inherited;
|
|
TreeView.Container := Self;
|
|
TreeView.Flat := Host.Flat;
|
|
TreeView.OnCancelEdit := TreeCancelEdit;
|
|
end;
|
|
|
|
function TdxPSExplorerTreeViewContainer.GetTreeView: TdxPSExplorerTreeView;
|
|
begin
|
|
Result := TdxPSExplorerTreeView(inherited TreeView)
|
|
end;
|
|
|
|
initialization
|
|
TCustomdxPSExplorerTreeViewContainer.Register;
|
|
TdxPSExplorerTreeViewContainer.Register;
|
|
|
|
finalization
|
|
TdxPSExplorerTreeViewContainer.Unregister;
|
|
TCustomdxPSExplorerTreeViewContainer.Unregister;
|
|
|
|
end.
|
|
|