我想扩展树型控件节点数据类型的功能,
主要是添加一个属性如Checked(True,False);
用来标识改节点已经被用户做了一个选择标志。有很多这样类似的控件功能扩展,主要是如何修改
Items一类的数据,如:TreeView.Items
ListBox.Items
等等,然后在构造出相应的高级控件,TreeView,ListBox等。
主要是添加一个属性如Checked(True,False);
用来标识改节点已经被用户做了一个选择标志。有很多这样类似的控件功能扩展,主要是如何修改
Items一类的数据,如:TreeView.Items
ListBox.Items
等等,然后在构造出相应的高级控件,TreeView,ListBox等。
treenode内容如下
-------------------------------
TTreeNode = class(TPersistent)
private
FOwner: TTreeNodes;
FText: string;
FData: Pointer;
FItemId: HTreeItem;
FImageIndex: TImageIndex;
FSelectedIndex: Integer;
FOverlayIndex: Integer;
FStateIndex: Integer;
FDeleting: Boolean;
FInTree: Boolean;
function CompareCount(CompareMe: Integer): Boolean;
function DoCanExpand(Expand: Boolean): Boolean;
procedure DoExpand(Expand: Boolean);
procedure ExpandItem(Expand: Boolean; Recurse: Boolean);
function GetAbsoluteIndex: Integer;
function GetExpanded: Boolean;
function GetLevel: Integer;
function GetParent: TTreeNode;
function GetChildren: Boolean;
function GetCut: Boolean;
function GetDropTarget: Boolean;
function GetFocused: Boolean;
function GetIndex: Integer;
function GetItem(Index: Integer): TTreeNode;
function GetSelected: Boolean;
function GetCount: Integer;
function GetTreeView: TCustomTreeView;
procedure InternalMove(ParentNode, Node: TTreeNode; HItem: HTreeItem;
AddMode: TAddMode);
function IsEqual(Node: TTreeNode): Boolean;
function IsNodeVisible: Boolean;
procedure ReadData(Stream: TStream; Info: PNodeInfo);
procedure SetChildren(Value: Boolean);
procedure SetCut(Value: Boolean);
procedure SetData(Value: Pointer);
procedure SetDropTarget(Value: Boolean);
procedure SetItem(Index: Integer; Value: TTreeNode);
procedure SetExpanded(Value: Boolean);
procedure SetFocused(Value: Boolean);
procedure SetImageIndex(Value: TImageIndex);
procedure SetOverlayIndex(Value: Integer);
procedure SetSelectedIndex(Value: Integer);
procedure SetSelected(Value: Boolean);
procedure SetStateIndex(Value: Integer);
procedure SetText(const S: string);
procedure WriteData(Stream: TStream; Info: PNodeInfo);
protected
function GetState(NodeState: TNodeState): Boolean;
procedure SetState(NodeState: TNodeState; Value: Boolean);
procedure SetSelectedBit(Value: Boolean);
public
constructor Create(AOwner: TTreeNodes);
destructor Destroy; override;
function AlphaSort(ARecurse: Boolean = False): Boolean;
procedure Assign(Source: TPersistent); override;
procedure Collapse(Recurse: Boolean);
function CustomSort(SortProc: TTVCompare; Data: Longint; ARecurse: Boolean = False): Boolean;
procedure Delete;
procedure DeleteChildren;
function DisplayRect(TextOnly: Boolean): TRect;
function EditText: Boolean;
procedure EndEdit(Cancel: Boolean);
procedure Expand(Recurse: Boolean);
function getFirstChild: TTreeNode; {GetFirstChild conflicts with C++ macro}
function GetHandle: HWND;
function GetLastChild: TTreeNode;
function GetNext: TTreeNode;
function GetNextChild(Value: TTreeNode): TTreeNode;
function getNextSibling: TTreeNode; {GetNextSibling conflicts with C++ macro}
function GetNextVisible: TTreeNode;
function GetPrev: TTreeNode;
function GetPrevChild(Value: TTreeNode): TTreeNode;
function getPrevSibling: TTreeNode; {GetPrevSibling conflicts with a C++ macro}
function GetPrevVisible: TTreeNode;
function HasAsParent(Value: TTreeNode): Boolean;
function IndexOf(Value: TTreeNode): Integer;
procedure MakeVisible;
procedure MoveTo(Destination: TTreeNode; Mode: TNodeAttachMode); virtual;
property AbsoluteIndex: Integer read GetAbsoluteIndex;
function IsFirstNode: Boolean;
property Count: Integer read GetCount;
property Cut: Boolean read GetCut write SetCut;
property Data: Pointer read FData write SetData;
property Deleting: Boolean read FDeleting;
property Focused: Boolean read GetFocused write SetFocused;
property DropTarget: Boolean read GetDropTarget write SetDropTarget;
property Selected: Boolean read GetSelected write SetSelected;
property Expanded: Boolean read GetExpanded write SetExpanded;
property Handle: HWND read GetHandle;
property HasChildren: Boolean read GetChildren write SetChildren;
property ImageIndex: TImageIndex read FImageIndex write SetImageIndex;
property Index: Integer read GetIndex;
property IsVisible: Boolean read IsNodeVisible;
property Item[Index: Integer]: TTreeNode read GetItem write SetItem; default;
property ItemId: HTreeItem read FItemId;
property Level: Integer read GetLevel;
property OverlayIndex: Integer read FOverlayIndex write SetOverlayIndex;
property Owner: TTreeNodes read FOwner;
property Parent: TTreeNode read GetParent;
property SelectedIndex: Integer read FSelectedIndex write SetSelectedIndex;
property StateIndex: Integer read FStateIndex write SetStateIndex;
property Text: string read FText write SetText;
property TreeView: TCustomTreeView read GetTreeView;
end;
-------------------------
这个如果转换成selected就很方便了
系统已经完成
我的树型控件已经扩展了,其效果就好像金山杀毒软件中的目录选择树型控件一样
是有一个选择构选框的,可以有多个节点被选中。
所以就需要有一个Checked属性来检测某个节点是否被构选了。
uses CommCtrl;function TreeNodeGetChecked(mTreeNode: TTreeNode): Boolean;
var
vTVItem: TTVItem;
begin
Result := False;
if not Assigned(mTreeNode) or not Assigned(mTreeNode.TreeView) then Exit;
vTVItem.mask := TVIF_STATE;
vTVItem.hItem := mTreeNode.ItemId;
if TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem) then
Result := (vTVItem.State and IndexToStateImageMask(2)) > 0; //0: None 1: False 2: True
end; { TreeNodeGetChecked }function TreeNodeSetChecked(mTreeNode: TTreeNode; mChecked: Boolean): Boolean;
var
vTVItem: TTVItem;
begin
Result := False;
if not Assigned(mTreeNode) or not Assigned(mTreeNode.TreeView) then Exit; vTVItem.mask := TVIF_STATE;
vTVItem.hItem := mTreeNode.ItemId;
TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem);
if not TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem) then Exit;
vTVItem.stateMask := TVIS_STATEIMAGEMASK;
vTVItem.state := IndexToStateImageMask(Succ(Ord(mChecked)));
Result := TreeView_SetItem(mTreeNode.TreeView.Handle, vTVItem);
end; { TreeNodeSetChecked }procedure TForm1.FormCreate(Sender: TObject);
begin
SetWindowLong(TreeView1.Handle, GWL_STYLE,
GetWindowLong(TreeView1.Handle, GWL_STYLE) or TVS_CHECKBOXES);
end;procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure pSelect(mTreeNode: TTreeNode; mChecked: Boolean);
var
I: Integer;
begin
TreeNodeSetChecked(mTreeNode, mChecked);
for I := 0 to mTreeNode.Count - 1 do pSelect(mTreeNode[I], mChecked);
end; procedure pSelectYes(mTreeNode: TTreeNode);
begin
while Assigned(mTreeNode.Parent) and
not TreeNodeGetChecked(mTreeNode.Parent) do begin
TreeNodeSetChecked(mTreeNode.Parent, True);
mTreeNode := mTreeNode.Parent;
end;
end; procedure pSelectNo(mTreeNode: TTreeNode);
var
I: Integer;
begin
if Assigned(mTreeNode.Parent) and TreeNodeGetChecked(mTreeNode.Parent) then begin
for I := 0 to mTreeNode.Parent.Count - 1 do
if TreeNodeGetChecked(mTreeNode.Parent[I]) then Exit;
TreeNodeSetChecked(mTreeNode.Parent, False);
pSelectNo(mTreeNode.Parent);
end;
end;var
vTreeNode: TTreeNode;
begin
if not (htOnStateIcon in TTreeView(Sender).GetHitTestInfoAt(X, Y)) then Exit;
vTreeNode := TTreeView(Sender).GetNodeAt(X, Y);
pSelect(vTreeNode, TreeNodeGetChecked(vTreeNode));
if not TreeNodeGetChecked(vTreeNode) then
pSelectNo(vTreeNode)
else pSelectYes(vTreeNode);
end;function TreeNodeSetValue(mTreeNode: TTreeNode; mValue: Integer): Boolean;
var
vTVItem: TTVItem;
begin
Result := False;
if not Assigned(mTreeNode) or not Assigned(mTreeNode.TreeView) then Exit; vTVItem.mask := TVIF_STATE;
vTVItem.hItem := mTreeNode.ItemId;
TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem);
if not TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem) then Exit;
vTVItem.stateMask := TVIS_STATEIMAGEMASK;
vTVItem.state := IndexToStateImageMask(mValue);
Result := TreeView_SetItem(mTreeNode.TreeView.Handle, vTVItem);
end; { TreeNodeSetChecked }
我的实现原理差不多是这样的,但是我需要每个节点要有一个Checked属性啊,兄弟。TO zswang(伴水清清)(专家门诊清洁工)
好像你的代码有一定的道理,我去研究一下。呵呵,谢谢各位的支持,希望再接再厉,共同进步。
TVS_CHECKBOXES:是一个什么东西,是系统常量还是自定义的常量.你能不能把你上面的所 有代码都发给我看看。
[email protected]
请问怎样才能把属性编辑器也一起继承过来啊。