实际上很简单的。想想表示一个Checkbox需要几幅图。(两幅,一张check状态,一张uncheck状态)。
所以,你只要在Onclick的时候,变化图就可以了。(TreeView有Images属性)

解决方案 »

  1.   

    chechy说的做法应该是可以的,但实现起来却不是那么容易,因为click是对于整个tree的,除非可以精确控制到每一幅图。
    我看windows 98中的系统配置程序中就有这样的带checkbox的treeview,究竟怎么做呢?
      

  2.   

    用stateindex来控制(两张图片,一张check,一张uncheck)
    用mouseup来
    procedure TfTree.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
      Y: Integer);
    var tf:Ttreenode;
    begin
      inherited;
        tf:=self.GetNodeAt(x,y);
        if tf=nil then exit;
        if (x>=tf.Level*self.Indent) and (x<=tf.Level*self.Indent+12) then
            tf.StateIndex:=fokimg+fnoimg-tf.StateIndex;//改变stateindex图片
    end;
      

  3.   

    myxfang的程序已经差不多了。不过我觉得,用MouseDown比MouseUp更好些。
    procedure THlCheckPartTreeView.MouseDown(Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      MyHitTest : THitTests;
      Node: TTreeNode;
    begin
      MyHitTest := GetHitTestInfoAt(X,Y);
      if htOnIcon in MyHitTest then
      begin
        Node := GetNodeAt(X, Y);
        // Do it yourself to toggle the imageindex
      end;
    end;
      

  4.   

    fokimg 是选中check状态的图像的imageindex值
    fnoimg 是uncheck状态的图像的iamgeindex值
      

  5.   

    用TTreeView的StateImages属性和TTreeNode的StateIndex属性,这儿有个范本:
    Const
    ST_UNCHECK=0;
      ST_CHECK=1;
      ST_CHECKING=2;//设置当前结点及上下级的复选关系。
    procedure TForm1.tvwMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
    Node:TTreeNode;
      //将结点子树(含该结点)标为复选或清除状态
      Procedure SetChildState(Node:TTreeNode;State:Integer);
      Begin
        Node.StateIndex:=State;
        Node:=Node.getFirstChild;
        while Node<>nil do
        begin
          Node.StateIndex:=State;
          IF Node.Count>0 Then SetChildState(Node,State);
          Node:=Node.getNextSibling;
        end;
      End;
      //返回结点子树(不含该结点)中的复选项数
      Function GetCheckCount(Node:TTreeNode):Integer;
      var
        i:Integer;
      Begin
        i:=0;
        IF Node.Count>0 Then
        Begin
          Node:=Node.getFirstChild;
          While Node<>nil do
          Begin
            if Node.StateIndex=ST_CHECK then Inc(i);
            Inc(i,GetCheckCount(Node));
            Node:=Node.getNextSibling;
          End;
        End;
        Result:=i;
      End;
      //返回结点子树(不含该结点)中的项数
      Function GetChildCount(Node:TTreeNode):Integer;
      var
        i:Integer;
      Begin
        i:=0;
        IF Node.Count>0 Then
        Begin
          Node:=Node.getFirstChild;
          While Node<>nil do
          Begin
            Inc(i);
            Inc(i,GetCheckCount(Node));
            Node:=Node.getNextSibling;
          End;
        End;
        Result:=i;
      End;  //根据指定结点状态,设置父结点状态
      Procedure SetParentState(Node:TTreeNode);
      var
        i,j:Integer;
      Begin
        Node:=Node.Parent;
        While Node<>nil Do
        Begin
          i:=GetChildCount(Node);
          j:=GetCheckcount(Node);
          if i=j then
            Node.StateIndex:=ST_CHECK
          else if (i>0) And (j=0) Then
            Node.StateIndex:=ST_UNCHECK
          else
            Node.StateIndex:=ST_CHECKING;
          Node:=Node.Parent;
        End;
      End;
    begin
    if (htOnStateIcon in tvw.GetHitTestInfoAt(X,Y)) And (Button=mbLeft) then
      Begin
       Node:=tvw.GetNodeAt(X,Y);
        Case Node.StateIndex Of
         ST_CHECK:Begin
          SetChildState(Node,ST_UNCHECK);
            end;
          ST_UNCHECK:Begin
           SetChildState(Node,ST_CHECK);
           End;
    ST_CHECKING:Begin
           SetChildState(Node,ST_UNCHECK);
          End;
        End;
        SetParentState(Node);
      End;
    end;