我在VB6中用TreeView做了一个分配权限的窗口,权限是分级的,所以有时候要判断子节点或父节点有无选中的情况,
我把TreeView控件的Checkboxes属性设置为True,这样用户就可以选择节点进行权限分配了,
但是我在Delphi 7中用Win32卡下面的TreeView控件,怎么在它的属性页里没有Checkboxes属性
是不是Delphi不支持TreeView节点前的Checkboxes呀?请指教,谢谢!

解决方案 »

  1.   

    原生控件好象没有,推荐用Raize的控件包,里面的RzTreeView有Checkbox
      

  2.   

    CheckTreeView
    unit uCheckTreeView;interfaceuses
      SysUtils, Windows, Classes, Controls, ComCtrls, CommCtrl, Menus,
      Variants, Forms, Math;type
      TCheckTreeNode = class(TTreeNode)
      private
        { Private declarations }
        FChecked: Boolean;
        FHint: String;
        procedure SetChecked(const Value: Boolean);
      public
        { public declarations }
        property Checked: Boolean read FChecked write SetChecked;
        property Hint: String read FHint write FHint;
      end;
      TCheckTreeView = class(TTreeView)
      private
        { Private declarations }
        FPopupMenu: TPopupMenu;
      protected
        { Protected declarations }
        procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
        procedure CreateWnd; override;
        procedure CreateCheckNodeClass(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass);
      public
        { Public declarations }
        constructor Create(AOwner: TComponent); reintroduce; overload;
        destructor Destroy; override;
        property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;
      published
        { Published declarations }
      end;//procedure Register;implementationuses StrUtils;//procedure Register;
    //begin
    //  RegisterComponents('Budded', [TCheckTreeView]);
    //end;{ TCheckTreeView }procedure TCheckTreeView.CreateWnd;
    begin
      inherited CreateWnd;
      SetWindowLong(Handle, GWL_STYLE,
        GetWindowLong(Handle, GWL_STYLE) or TVS_CHECKBOXES);
    end;procedure TCheckTreeView.MouseDown(Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      vTreeNode: TCheckTreeNode;
      PT: TPoint;
      Rect: TRect;
    begin
      inherited;
      vTreeNode := TCheckTreeNode(GetNodeAt(X, Y));
      if (vTreeNode <> nil) then
        if (Button = mbLeft)
        then begin
               if (htOnStateIcon in GetHitTestInfoAt(X, Y)) then
               begin
                 vTreeNode.Checked := not vTreeNode.Checked;
               end;
             end
        else begin
               vTreeNode.Selected := True;
               if Assigned(PopupMenu) and ((htOnLabel in GetHitTestInfoAt(X, Y))
                 or(htOnIcon in GetHitTestInfoAt(X, Y))) then
               begin
                 Rect := vTreeNode.DisplayRect(True);
                 PT := ClientToScreen(Point(Rect.Left, Rect.Bottom));
                 PopupMenu.Popup(PT.X, PT.Y);
               end;
             end;
    end;constructor TCheckTreeView.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);  OnCreateNodeClass := CreateCheckNodeClass;
      ReadOnly := True;
      HideSelection := False;
    end;destructor TCheckTreeView.Destroy;
    begin  inherited;
    end;procedure TCheckTreeView.CreateCheckNodeClass(Sender: TCustomTreeView;
      var NodeClass: TTreeNodeClass);
    begin
      NodeClass := TCheckTreeNode;
    end;{ TCheckTreeNode }procedure TCheckTreeNode.SetChecked(const Value: Boolean);  function TreeNodeSetChecked(mTreeNode: TCheckTreeNode; mChecked: Boolean): Boolean;
      var
        vTVItem: TTVItem;
      begin
        Result := False;
        if not Assigned(mTreeNode) then Exit;    FillChar(vTVItem, SizeOf(vTVItem), 0);
        with vTVItem do
        begin
          hItem := mTreeNode.ItemId;
          mask := TVIF_STATE;
          StateMask := TVIS_STATEIMAGEMASK;
          State := IndexToStateImageMask(Succ(Ord(mChecked)));
          Result := TreeView_SetItem(mTreeNode.Handle, vTVItem);
        end;
      end;  procedure pSelect(mTreeNode: TCheckTreeNode; mChecked: Boolean);
      var
        I: Integer;
      begin
        for I := 0 to mTreeNode.Count - 1 do
          TCheckTreeNode(mTreeNode[I]).Checked := mChecked;
      end;  procedure pSelectYes(mTreeNode: TCheckTreeNode);
      begin
        if Assigned(mTreeNode.Parent) then
          if not TCheckTreeNode(mTreeNode.Parent).Checked then
          begin
            TreeNodeSetChecked(TCheckTreeNode(mTreeNode.Parent), True);
            TCheckTreeNode(mTreeNode.Parent).FChecked := True;
          end;
      end;  procedure pSelectNo(mTreeNode: TCheckTreeNode);
      var
        I: Integer;
      begin
        if Assigned(mTreeNode.Parent) and TCheckTreeNode(mTreeNode.Parent).Checked then
        begin
          for I := 0 to mTreeNode.Parent.Count - 1 do
            if TCheckTreeNode(mTreeNode.Parent[I]).Checked then Exit;
          TCheckTreeNode(mTreeNode.Parent).Checked := False;
        end;
      end;
    begin
      FChecked := Value;
      TreeNodeSetChecked(Self, Value);
      pSelect(Self, Value);
      if Value
      then pSelectYes(Self)
      else pSelectNo(Self);
    end;end.