Componentes.Terceros.DevExp.../official/x.44/ExpressDBTree Suite/Sources/dxtree.pas

840 lines
27 KiB
ObjectPascal

unit dxtree;
{*******************************************************************}
{ }
{ Developer Express Visual Component Library }
{ Express tree view control }
{ }
{ Copyright (c) 1998-2009 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 EXPRESSGRID 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. }
{ }
{*******************************************************************}
{$I cxVer.inc}
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, CommCtrl, ExtCtrls ;
type
TdxTreeViewOption = (trCanDelete, trConfirmDelete);
TdxTreeViewOptions = set of TdxTreeViewOption;
TDragDropTreeNode = procedure(Destination, Source: TTreeNode;
var Accept: Boolean) of object;
TEndDragTreeNode = procedure(Destination, Source: TTreeNode;
var AttachMode: TNodeAttachMode) of object;
TDragDropIsCopy = procedure(Destination, Source: TTreeNode;
var IsCopy: Boolean) of object;
TTreeViewCustomDraw = procedure(Sender: TObject; TreeNode: TTreeNode;
AFont: TFont; var AColor, ABkColor: TColor) of object;
// Avoid MoveTo bug in D4.
TdxTreeNode = class(TTreeNode)
{$IFDEF DELPHI4}
procedure MoveTo(Destination: TTreeNode; Mode: TNodeAttachMode); override;
{$ENDIF}
end;
TCustomdxTreeView = class(TCustomTreeView)
private
FOptions: TdxTreeViewOptions;
FSelectedIndex: Integer;
FDragDropProcessingFlag: Boolean;
FDragObject: TDragObject;
FDeletingConfirmationMessage: string;
FIsConfirmationAssigned: Boolean;
FScrollTimerID: Integer;
fntcd: TFont;
FCanvas: TControlCanvas;
FOnDragDropTreeNode: TDragDropTreeNode;
FOnEndDragTreeNode: TEndDragTreeNode;
FOnDragDropIsCopy: TDragDropIsCopy;
FOnCustomDraw: TTreeViewCustomDraw;
FOnSetEditText: TTVEditedEvent;
FShowNodeHint: Boolean;
FInternalDragObject: TDragObject;
function GetDragSourceTreeNode: TTreeNode;
function GetDeletingConfirmationMessage: string;
procedure SetSelectedIndex(Value: Integer);
procedure SetDeletingConfirmationMessage(const AValue: string);
procedure CMDrag(var Message: TCMDrag); message CM_DRAG;
function DoCNNotify(var Message: TWMNotify): Boolean;
function DoWMNotify(var Message: TWMNotify): Boolean;
procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY;
procedure ReadIsAssigned(AReader: TReader);
procedure WriteIsAssigned(AWriter: TWriter);
protected
CopyTreeNodeStructFlag: Boolean;
procedure DefineProperties(AFiler: TFiler); override;
procedure DoCustomDraw(TreeNode: TTreeNode; AFont: TFont;
var AColor, ABkColor: TColor); virtual;
procedure DoStartDrag(var DragObject: TDragObject); override;
procedure DoEndDrag(Target: TObject; X, Y: Integer); override;
function GetNodeFromItem(const Item: TTVItem): TTreeNode;
function GetListItemText(TreeNode: TTreeNode): String; virtual;
procedure InsertTreeNodeStructure(ListS, ListD: TList; Flag: Boolean); virtual;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure DoDragDropTreeNode(Destination, Source: TTreeNode; var Accept: Boolean); virtual;
procedure DoDragDropIsCopy(Destination, Source: TTreeNode; var IsCopy: Boolean); virtual;
property Options: TdxTreeViewOptions read FOptions write FOptions
default [trCanDelete, trConfirmDelete];
property SelectedIndex: Integer read FSelectedIndex write SetSelectedIndex;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function CreateNode: TTreeNode; override;
procedure SetFocus; override;
procedure GetNodeStructure(TreeNode: TTreeNode; List: TList); virtual;
function IsCustomDraw: Boolean; virtual;
function MoveTreeNodeStructure(Source, Destination: TTreeNode; IsCopy: Boolean): TTreeNode;
property DragSourceTreeNode: TTreeNode read GetDragSourceTreeNode;
property IsConfirmationAssigned: Boolean read FIsConfirmationAssigned write FIsConfirmationAssigned;
property OnSetEditText: TTVEditedEvent read FOnSetEditText write FOnSetEditText;
property Color;
property DragCursor;
property Font;
property Images;
property Items;
property Indent;
property PopupMenu;
property ReadOnly;
property ShowButtons;
property ShowLines;
property ShowRoot;
property SortType;
property StateImages;
property OnClick;
property OnChanging;
property OnDblClick;
property OnGetImageIndex;
property OnGetSelectedIndex;
published
{$IFDEF DELPHI3}
property ImeMode;
property ImeName;
property RightClickSelect;
{$ENDIF}
property ShowNodeHint: Boolean read FShowNodeHint write FShowNodeHint;
property OnCustomDraw: TTreeViewCustomDraw read FOnCustomDraw write FOnCustomDraw;
property OnDragDropIsCopy: TDragDropIsCopy read FOnDragDropIsCopy write FOnDragDropIsCopy;
property OnDragDropTreeNode: TDragDropTreeNode read FOnDragDropTreeNode
write FOnDragDropTreeNode;
property OnEndDragTreeNode: TEndDragTreeNode read FOnEndDragTreeNode
write FOnEndDragTreeNode;
{$IFDEF DELPHI4}
property Anchors;
property AutoExpand;
property BiDiMode;
property Constraints;
property DeletingConfirmationMessage: string read GetDeletingConfirmationMessage write SetDeletingConfirmationMessage stored FIsConfirmationAssigned;
property DragKind;
property HotTrack;
property ParentBiDiMode;
property RowSelect;
property ToolTips;
property OnCustomDrawItem;
property OnEndDock;
property OnStartDock;
{$ENDIF}
{$IFDEF DELPHI5}
property OnAdvancedCustomDraw;
{$ENDIF}
end;
TdxTreeView = class(TCustomdxTreeView)
published
property ShowButtons;
property BorderStyle;
property DragCursor;
property ShowLines;
property ShowRoot;
property ReadOnly;
property DragMode;
property HideSelection;
property Indent;
property Items;
property OnEditing;
property OnEdited;
property OnExpanding;
property OnExpanded;
property OnCollapsing;
property OnCompare;
property OnCollapsed;
property OnChanging;
property OnChange;
property OnDeletion;
property OnGetImageIndex;
property OnGetSelectedIndex;
property Align;
property Enabled;
property Font;
property Color;
property ParentColor;
property ParentCtl3D;
property Ctl3D;
property Options;
property SelectedIndex;
property SortType;
property TabOrder;
property TabStop default True;
property Visible;
property OnClick;
property OnEnter;
property OnExit;
property OnDragDrop;
property OnDragOver;
property OnStartDrag;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnDblClick;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property PopupMenu;
property ParentFont;
property ParentShowHint;
property ShowHint;
property Images;
property StateImages;
end;
resourcestring
dxTreeViewDelConfirm = 'Do you want to delete the item "%s"';
dxDBTreeViewSmartLoadS = 'Set trSmartRecordLoad in the Options property to decrease the loading time. Do you want to do it now?';
implementation
uses ImgList ;
{$I dxcmctl.inc}
{$R dxtree.res}
const
crdxTreeDrag = -1011;
var
{$IFDEF DELPHI4}
dxTreeViewDragImages: TDragImageList;
{$ELSE}
dxTreeViewDragImages: TCustomImageList;
{$ENDIF}
DropSourceTreeNode: TTreeNode;
OldDragOverTreeNode: TTreeNode;
type
TDummyControl = class(TWinControl)
public
function GetDragImages: {$IFDEF DELPHI4}TDragImageList{$ELSE}TCustomImageList{$ENDIF}; override;
end;
function TDummyControl.GetDragImages: {$IFDEF DELPHI4}TDragImageList{$ELSE}TCustomImageList{$ENDIF};
begin
Result := inherited GetDragImages;
end;
{TdxTreeNode}
{$IFDEF DELPHI4}
//Avoid MoveTo bug in D4.
procedure TdxTreeNode.MoveTo(Destination: TTreeNode; Mode: TNodeAttachMode);
var
Dummy: TTreeNode;
begin
if Mode in [naAddChild, naAddChildFirst] then
begin
TCustomdxTreeView(TreeView).CopyTreeNodeStructFlag := True;
if Mode = naAddChildFirst then
Dummy := TTreeView(Destination.TreeView).Items.AddChildFirst(Destination, '')
else
Dummy := TTreeView(Destination.TreeView).Items.AddChild(Destination, '');
TCustomdxTreeView(TreeView).CopyTreeNodeStructFlag := False;
inherited MoveTo(Dummy, naInsert);
TCustomdxTreeView(TreeView).CopyTreeNodeStructFlag := True;
Dummy.Free;
TCustomdxTreeView(TreeView).CopyTreeNodeStructFlag := False;
end
else
inherited MoveTo(Destination, Mode);
end;
{$ENDIF}
{TCustomdxTreeView}
constructor TCustomdxTreeView.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FScrollTimerID := -1;
FSelectedIndex := -1;
FOptions := [trCanDelete, trConfirmDelete];
FDragDropProcessingFlag := False;
fntcd := TFont.Create;
FCanvas := TControlCanvas.Create;
FShowNodeHint := True;
end;
destructor TCustomdxTreeView.Destroy;
begin
fntcd.Free;
FCanvas.Free;
inherited;
end;
type
TtmpDragObject = class(TDragControlObject)
protected
function GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor; override;
end;
function TtmpDragObject.GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor;
begin
if not Accepted then
Result := crNoDrop
else
if not (GetKeyState(VK_CONTROL) < 0) then
Result := TCustomdxTreeView(Control).DragCursor
else
Result := crdxTreeDrag;
end;
procedure TCustomdxTreeView.DoStartDrag(var DragObject: TDragObject);
begin
DragObject := TtmpDragObject.Create(Self);
FInternalDragObject := DragObject;
inherited;
dxTreeViewDragImages := GetDragImages;
if Self.Focused then
DropSourceTreeNode := Selected
else
DropSourceTreeNode := nil;
end;
procedure TCustomdxTreeView.DoEndDrag(Target: TObject; X, Y: Integer);
begin
inherited DoEndDrag(Target, X, Y);
FInternalDragObject.Free;
DropSourceTreeNode := nil;
end;
procedure TCustomdxTreeView.DoDragDropTreeNode(Destination, Source: TTreeNode;
var Accept: Boolean);
begin
if Assigned(FOnDragDropTreeNode) then
FOnDragDropTreeNode(Destination, Source, Accept);
end;
procedure TCustomdxTreeView.DoDragDropIsCopy(Destination, Source: TTreeNode; var IsCopy: Boolean);
begin
if Assigned(FOnDragDropIsCopy) then
FOnDragDropIsCopy(Destination, Source, IsCopy);
end;
procedure TCustomdxTreeView.GetNodeStructure(TreeNode: TTreeNode; List: TList);
procedure GetNodeStructure_(TreeNode: TTreeNode; List: TList);
var
tn: TTreeNode;
begin
if (TreeNode <> nil) and TreeNode.HasChildren then
begin
tn := TreeNode.GetFirstChild;
while tn <> nil do
begin
List.Add(tn);
if tn.HasChildren then
GetNodeStructure_(tn, List);
tn := TreeNode.GetNextChild (tn);
end;
end;
end;
begin
List.Add(TreeNode);
GetNodeStructure_(TreeNode, List);
end;
procedure TCustomdxTreeView.InsertTreeNodeStructure(ListS, ListD: TList; Flag: Boolean);
begin
end;
function TCustomdxTreeView.GetDragSourceTreeNode: TTreeNode;
begin
if (DropSourceTreeNode <> nil) and (DropSourceTreeNode.TreeView = Self) then
Result := DropSourceTreeNode
else
Result := nil;
end;
function TCustomdxTreeView.GetDeletingConfirmationMessage: string;
begin
Result := FDeletingConfirmationMessage;
if not FIsConfirmationAssigned then
Result := dxTreeViewDelConfirm;
end;
procedure TCustomdxTreeView.SetSelectedIndex(Value: Integer);
var
i: Integer;
begin
if Value <> FSelectedIndex then
begin
FSelectedIndex := Value;
for i := 0 to Items.Count - 1 do
Items[i].SelectedIndex := FSelectedIndex;
end;
end;
procedure TCustomdxTreeView.SetDeletingConfirmationMessage(const AValue: string);
begin
FDeletingConfirmationMessage := AValue;
IsConfirmationAssigned := True;
end;
function TCustomdxTreeView.CreateNode: TTreeNode;
begin
Result := TdxTreeNode.Create(Items);
if (Result <> nil) and (FSelectedIndex <> -1) then
Result.SelectedIndex := FSelectedIndex
end;
procedure TCustomdxTreeView.ReadIsAssigned(AReader: TReader);
begin
FIsConfirmationAssigned := AReader.ReadBoolean;
end;
procedure TCustomdxTreeView.WriteIsAssigned(AWriter: TWriter);
begin
AWriter.WriteBoolean(FIsConfirmationAssigned);
end;
procedure TCustomdxTreeView.SetFocus;
begin
if (GetParentForm(Self) <> nil) or (ParentWindow <> 0) then
inherited SetFocus;
end;
procedure TCustomdxTreeView.KeyDown(var Key: Word; Shift: TShiftState);
var
St: string;
begin
if (Key = VK_DELETE) and (trCanDelete in Options)
and not ReadOnly and (Selected <> nil) and not IsEditing then
begin
if IsConfirmationAssigned then
St := Format(DeletingConfirmationMessage, [Selected.Text])
else
St := Format(dxTreeViewDelConfirm, [Selected.Text]);
if not (trConfirmDelete in Options) or
(MessageDlg(St, mtConfirmation, mbOKCancel, 0) <> idCancel) then
Items.Delete(Selected);
end;
inherited;
end;
procedure TCustomdxTreeView.CMDrag(var Message: TCMDrag);
var
lpht: TTVHitTestInfo;
TreeNode: TTreeNode;
procedure HideDragImage;
begin
if dxTreeViewDragImages <> nil then
dxTreeViewDragImages.HideDragImage
else
if FDragObject <> nil then
FDragObject.HideDragImage;
end;
procedure ShowDragImage;
begin
if dxTreeViewDragImages <> nil then
dxTreeViewDragImages.ShowDragImage
else
if FDragObject <> nil then
FDragObject.ShowDragImage;
end;
function IsNodeVisible(TreeNode: TTreeNode): Boolean;
var
Rect: TRect;
begin
Result := TreeView_GetItemRect(Handle, TreeNode.ItemId, Rect, False);
Result := Result and (Rect.Top < ClientHeight);
end;
var
CorrectDragFlag, IsCopyFlag: Boolean;
begin
CorrectDragFlag := False;
with Message, DragRec^ do
begin
case DragMessage of
dmDragEnter:
begin
FDragDropProcessingFlag := True;
OldDragOverTreeNode := nil;
FDragObject := Source;
end;
dmDragMove:
begin
lpht.pt := ScreenToClient(Point(Pos.X, Pos.Y));
lpht.flags := TVHT_ONITEM;
TreeNode := Items.GetNode(TreeView_HitTest(Handle, lpht));
if TreeNode <> nil then
begin
if (OldDragOverTreeNode <> nil) and (OldDragOverTreeNode = TreeNode) then
begin
if (TreeNode = TopItem) or
((TreeNode.GetPrevVisible <> nil) and (TreeNode.GetPrevVisible = TopItem))
and (TopItem.GetPrevVisible <> nil) then
TopItem := TopItem.GetPrevVisible
else
if ((TreeNode.GetNextVisible <> nil) and not IsNodeVisible(TreeNode.GetNextVisible)
or ((TreeNode.GetNextVisible <> nil) and (TreeNode.GetNextVisible.GetNextVisible <> nil)
and not IsNodeVisible(TreeNode.GetNextVisible.GetNextVisible))) then
TopItem := TopItem.GetNextVisible;
end;
if OldDragOverTreeNode <> TreeNode then
begin
OldDragOverTreeNode := TreeNode;
HideDragImage;
TreeView_SelectDropTarget(Handle, OldDragOverTreeNode.ItemId);
ShowDragImage;
end;
end
else
begin
OldDragOverTreeNode := nil;
HideDragImage;
TreeView_SelectDropTarget(Handle, nil);
ShowDragImage;
end;
end;
dmDragLeave:
begin
if DropSourceTreeNode <> nil then
begin
HideDragImage;
TreeView_SelectDropTarget(Handle, nil);
DropSourceTreeNode.Selected := True;
ShowDragImage;
end;
FDragObject := nil;
end;
dmDragCancel:
begin
FDragObject := nil;
FDragDropProcessingFlag := False;
OldDragOverTreeNode := nil;
Invalidate;
end;
dmDragDrop:
begin
FDragObject := nil;
IsCopyFlag := GetKeyState(VK_CONTROL) < 0;
if OldDragOverTreeNode <> nil then
begin
TreeView_SelectDropTarget(Handle, nil);
OldDragOverTreeNode.Selected := True;
Invalidate;
if (DropSourceTreeNode <> nil) and not OldDragOverTreeNode.HasAsParent(DropSourceTreeNode)
and (OldDragOverTreeNode <> DropSourceTreeNode) then
begin
DoDragDropIsCopy(DropSourceTreeNode, OldDragOverTreeNode, IsCopyFlag);
if ((OldDragOverTreeNode <> DropSourceTreeNode.Parent)
or IsCopyFlag or Assigned(FOnEndDragTreeNode)) then
begin
CorrectDragFlag := True;
DoDragDropTreeNode(OldDragOverTreeNode, DropSourceTreeNode, CorrectDragFlag);
end;
end;
end
else
if DropSourceTreeNode <> nil then
begin
DoDragDropIsCopy(DropSourceTreeNode, OldDragOverTreeNode, IsCopyFlag);
DoDragDropTreeNode(OldDragOverTreeNode, DropSourceTreeNode, CorrectDragFlag);
end;
if CorrectDragFlag then
begin
TreeNode := MoveTreeNodeStructure(DropSourceTreeNode, OldDragOverTreeNode, IsCopyFlag);
if TreeNode <> nil then
begin
TreeNode.MakeVisible;
Selected := TreeNode;
end;
Message.DragMessage := dmDragDrop;
DropTarget := OldDragOverTreeNode;
end;
FDragDropProcessingFlag := False;
OldDragOverTreeNode := nil;
Invalidate;
end; // dmDragDrop:
end; // case
end; // with
if (DropSourceTreeNode <> nil) and (Message.DragMessage <> dmDragDrop)
and (Message.DragMessage <> dmDragCancel)
and (OldDragOverTreeNode <> DropSourceTreeNode) then
begin
if OldDragOverTreeNode <> nil then
begin
CorrectDragFlag := (not DropSourceTreeNode.HasChildren
or not OldDragOverTreeNode.HasAsParent(DropSourceTreeNode))
and not Assigned(OnDragOver);
if CorrectDragFlag then
DoDragDropTreeNode(OldDragOverTreeNode, DropSourceTreeNode, CorrectDragFlag);
end
else
DoDragDropTreeNode(OldDragOverTreeNode, DropSourceTreeNode, CorrectDragFlag);
end;
inherited;
if (Message.DragMessage = dmDragDrop) or (Message.DragMessage = dmDragCancel) then
begin
DropSourceTreeNode := nil;
dxTreeViewDragImages := nil;
DropTarget := nil;
end;
if ((Message.DragMessage = dmDragMove) or (Message.DragMessage = dmDragLeave))
and CorrectDragFlag and (Message.Result = 0) then
Message.Result := 1;
end;
function TCustomdxTreeView.MoveTreeNodeStructure(Source, Destination: TTreeNode; IsCopy: Boolean): TTreeNode;
var
i, ind: Integer;
ListS, ListD: TList;
tr: TTreeNode;
AStyle: TNodeAttachMode;
begin
Result := nil;
ListS := TList.Create;
ListD := TList.Create;
CopyTreeNodeStructFlag := IsCopy or (Self <> Source.TreeView);
GetNodeStructure(Source, ListS);
CopyTreeNodeStructFlag := False;
if Destination <> nil then
AStyle := naAddChild
else
AStyle := naAdd;
if Assigned(FOnEndDragTreeNode) then
FOnEndDragTreeNode(Destination, Source, AStyle);
if (AStyle = naAddChild) or (AStyle = naAddChildFirst) then
Destination.HasChildren := True;
if (Self <> Source.TreeView) or IsCopy then
begin
CopyTreeNodeStructFlag := True;
tr := nil;
for i := 0 to ListS.Count - 1 do
begin
if i = 0 then
case AStyle of
naAdd: tr := Items.Add(Destination, GetListItemText(TTreeNode(ListS.List[i])));
naAddFirst: tr := Items.AddFirst(Destination, GetListItemText(TTreeNode(ListS.List[i])));
naAddChild: tr := Items.AddChild(Destination, GetListItemText(TTreeNode(ListS.List[i])));
naAddChildFirst: tr := Items.AddChildFirst(Destination, GetListItemText(TTreeNode(ListS.List[i])));
naInsert: tr := Items.Insert(Destination, GetListItemText(TTreeNode(ListS.List[i])));
end
else
begin
ind := ListS.IndexOf(TTreeNode(ListS.List[i]).Parent);
tr := Items.AddChild(TTreeNode(ListD.List[ind]), GetListItemText(TTreeNode(ListS.List[i])))
end;
if tr <> nil then
ListD.Add(tr);
end;
InsertTreeNodeStructure(ListS, ListD, True);
CopyTreeNodeStructFlag := False;
if ListD.Count > 0 then
begin
Result := TTreeNode(ListD[0]);
Destination.HasChildren := True;
end;
end;
if (Self = Source.TreeView) and not IsCopy then
begin
CopyTreeNodeStructFlag := True;
Source.MoveTo(Destination, AStyle);
CopyTreeNodeStructFlag := False;
Result := Source;
end;
ListS.Free;
ListD.Free;
if (Source <> nil) and not TdxTreeView(Source.TreeView).ReadOnly
and (Self <> Source.TreeView) and not IsCopy then
Source.Free;
end;
function TCustomdxTreeView.GetNodeFromItem(const Item: TTVItem): TTreeNode;
begin
with Item do
if (state and TVIF_PARAM) <> 0 then
begin
Result := TTreeNode(lParam);
end else Result := Items.GetNode(hItem);
end;
function TCustomdxTreeView.GetListItemText(TreeNode: TTreeNode): String;
begin
if TreeNode <> nil then
Result := TreeNode.Text;
end;
function TCustomdxTreeView.IsCustomDraw: Boolean;
begin
Result := Assigned(FOnCustomDraw);
end;
procedure TCustomdxTreeView.DefineProperties(AFiler: TFiler);
begin
inherited DefineProperties(AFiler);
AFiler.DefineProperty('IsConfirmationAssigned', ReadIsAssigned,
WriteIsAssigned, IsConfirmationAssigned);
end;
procedure TCustomdxTreeView.DoCustomDraw(TreeNode: TTreeNode; AFont: TFont;
var AColor, ABkColor: TColor);
begin
if Assigned(FOnCustomDraw) then
FOnCustomDraw(Self, TreeNode, AFont, AColor, ABkColor);
end;
function TCustomdxTreeView.DoCNNotify(var Message: TWMNotify): Boolean;
var
pnmlv: PNMTVCustomDraw;
tr: TTreeNode;
htr: HTReeItem;
Color, BkColor: TColor;
St: String;
begin
if (Message.nmhdr^.code = NM_CUSTOMDRAW) {$IFDEF DELPHI5}and not (Assigned(OnAdvancedCustomDraw)
or Assigned(OnAdvancedCustomDrawItem)){$ENDIF} then
begin
Result := False;
pnmlv := PNMTVCustomDraw(TMessage(Message).lParam);
if pnmlv^.nmcd.dwDrawStage = CDDS_PREPAINT then
begin
if IsCustomDraw then
Message.Result := CDRF_NOTIFYITEMDRAW
else
Message.Result := CDRF_DODEFAULT;
end;
if pnmlv^.nmcd.dwDrawStage = CDDS_ITEMPREPAINT then
begin
htr := Pointer(pnmlv^.nmcd.dwItemSpec);
tr := Items.GetNode(htr);
fntcd.Assign(Font);
Color := Font.Color;
BkColor := clWindow;
DoCustomDraw( tr, fntcd, Color, BkColor);
if ((pnmlv^.nmcd.uItemState and TVGN_CARET = 0)
and (pnmlv^.nmcd.uItemState and TVGN_DROPHILITE = 0)
and (OldDragOverTreeNode <> tr)) or not Focused then
begin
pnmlv^.clrText := ColorToRGB(Color);
pnmlv^.clrTextBk := ColorToRGB(bkColor);
end;
SelectObject(pnmlv^.nmcd.hdc, fntcd.Handle);
Message.Result := CDRF_NEWFONT;
end;
end
else Result := True;
with Message.NMHdr^ do
if code = TVN_BEGINLABELEDIT then
begin
SetImeMode(TreeView_GetEditControl(handle), ImeMode);
if Assigned(FOnSetEditText) then
with PTVDispInfo(Pointer(Message.NMHdr))^ do
begin
tr := GetNodeFromItem(item);
St := tr.Text;
FOnSetEditText(Self, tr, St);
SendMessage(TreeView_GetEditControl(handle), WM_SETTEXT, 0, Integer(PChar(St)));
end;
end;
end;
procedure TCustomdxTreeView.CNNotify(var Message: TWMNotify);
begin
if DoCNNotify(Message) then
inherited;
end;
type
PAToolTipText = ^TAToolTipText;
TAToolTipText = packed record
hdr: TNMHDR;
lpszText: PAnsiChar;
szText: array[0..79] of {$IFNDEF DELPHI12}Char {$ELSE} AnsiChar{$ENDIF};
hinst: THandle;
uFlags: UINT;
end;
function TCustomdxTreeView.DoWMNotify(var Message: TWMNotify): Boolean;
begin
if ((Message.nmhdr^.code = TTN_NEEDTEXTA) or (Message.nmhdr^.code = TTN_NEEDTEXTW))
and not FShowNodeHint then
begin
PAToolTipText(TMessage(Message).lparam).lpszText := {$IFDEF DELPHI12}PAnsiChar{$ELSE}PChar{$ENDIF}('');
TMessage(Message).Result := 0;
Result := False;
end else Result := True;
end;
procedure TCustomdxTreeView.WMNotify(var Message: TWMNotify);
begin
if DoWMNotify(Message) then
inherited;
end;
initialization
OldDragOverTreeNode := nil;
dxTreeViewDragImages := nil;
Screen.Cursors[crdxTreeDrag] := LoadCursor(HInstance, 'DXTREEDRAGCOPY');
end.