现已实现在添加了CheckBox的TreeView中响应打勾事件,但目前的状况是要响应打勾事件必须得让某个node被选中,然后再对其打勾;我的想法是在node没有被选中时打勾也可以被响应。比如说我想对一个TreeView的node进行打勾选择后通过一个按钮将打勾的项的名称全部添加到一个表格中,请问怎么实现。
以下是我的代码,请问能怎么修改,感谢
TreeView响应打勾事件
procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ht:THitTests;
  function GetTreeNodeChecked(Node:TTreeNode):Boolean;
  var
    vItem : TTVItem;
  begin
    vItem.mask:=TVIF_HANDLE or TVIF_STATE;
    vItem.hItem:=Node.ItemId;
    vItem.stateMask:=TVIS_STATEIMAGEMASK;
    TreeView_GetItem(Node.TreeView.Handle,vItem);
    Result:=Boolean((vItem.state shr 12)-1);
  end;
begin
  ht:=TreeView1.GetHitTestInfoAt(x,y);
  if htOnStateIcon in ht then
    if GetTreeNodeChecked(TreeView1.Selected) then
      Label1.Caption:=TreeView1.Selected.Text;
end;

解决方案 »

  1.   

    下面的代码让node必须先选中才能打勾procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      hitTst  : THitTests;
      chkStat : Boolean;
      hotNode : TTreeNode;
      treeView  : TTreeView;
    begin
      if( (not (Sender is TTreeView))or(Button<>mbLeft) )then Exit;
      treeView  := TTreeView(Sender);
      hotNode   := treeView.GetNodeAt(X, Y);
      if(not Assigned(hotNode))then Exit;  chkStat := GetTreeNodeChecked(hotNode);
      hitTst  := treeView.GetHitTestInfoAt(X, Y);
      if((treeView.Selected<>hotNode)and(htOnStateIcon in hitTst))then
      begin
        hotNode.StateIndex  := Byte(chkStat)+1;
        hotNode.StateIndex  := Byte(not chkStat)+1;
      end;
    end;procedure TForm1.TreeView1DblClick(Sender: TObject);
    var
      curPos  : TPoint;
      treeView  : TTreeView;
    begin
      if(not (Sender is TTreeView))then Exit;
      treeView  := TTreeView(Sender);
      curPos    := treeView.ScreenToClient(Mouse.CursorPos);
      treeView.OnMouseDown(treeView, mbLeft, [ssLeft], curPos.X, curPos.Y);
    end;顺便说一下,又看到你的问题了我才想起来看了一下,那个GetTreeNodeChecked还是上次我辛辛苦苦查msdn写出来的,你居然连1分都没给我,我真是服了你了
      

  2.   

    - -#
    我记得我把所有的分都给你了哦,只是不是给在那一条的,你还有别的地方有回帖
    这个问题真是很烦哎,有没办法不选中node也可以实现的?我现在就烦这个,哪有人那样操作的
      

  3.   

    你什么都不需要处理,它就会给打勾的,TreeView.Selected是当前获得焦点的TreeNode,而不是点击checkbox时的TreeNode,后者用TreeView.GetNodeAt()获取
    另外,不要在MouseUp事件中处理,因为在MosueDown的时候,checkbox的状态已经改变了,但用户可能会按着鼠标挪到别的地方才放开
      

  4.   

    对于这样处理的事件,我可以动态的将已打勾节点属性放到一个表格中不,比如说节点标题存到excel档,我不知道这样处理后用遍历能不能行得通,最好是打勾一个,就在对应表格中生成一个
    我一直在做BIOS方面的事,突然说要通过软件控制表格,我突然来学的,实在不怎么明白,请赐教
      

  5.   

    可以啊,在MouseDown事件中,TreeView.GetNodeAt()得到的就是当前鼠标所在的TreeNode,如果按下事件发生的区域在checkbox,鼠标所在的TreeNode的打勾情况就变了。能取得TreeNode,能判断是不是正在被勾上,符合条件就往表格里加呗,拿前面的代码来改的话:procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      chkStat : Boolean;
      hotNode : TTreeNode;
      treeView  : TTreeView;
    begin
      if( (not (Sender is TTreeView))or(Button<>mbLeft) )then Exit;  //不是鼠标左键则离开
      treeView  := TTreeView(Sender);
      hotNode   := treeView.GetNodeAt(X, Y);
      if(not Assigned(hotNode))then Exit;  //鼠标所在位置没有TreeNode则离开  if(htOnStateIcon in treeView.GetHitTestInfoAt(X, Y))then  //如果按下的区域在图标区,说明checked状态变了
      begin
        chkStat := GetTreeNodeChecked(hotNode); //获取是否勾上
        //do ...
      end;
    end;