请问我想单击treeview里的一项,把它的text取出来,应该在哪个事件里写代码?
我用click事件试过,可不管单击哪里都会执行相同代码,我在change事件中也试了,可以是可以,不过在change里写代码就不能区分单击和双击操作了
  因此我想请问,如果在click事件中写代码,如何防止单击不相干的地方也同时执行相同代码,谢谢,很急!
  哦,我想知道treeview中的各数据项是如何编码的,比如如何区分点击的是同级树的第几项!
  还有,感问那位兄台有treeview的资料,包括属性、事件、函数等,感激不尽!

解决方案 »

  1.   

    var
      ListItem:  TListItem;
    begin
      ListItem:=ListView1.Items.Add;
      ListItem.Caption := FlatEdit1.text;
      ListItem.SubItems.Add(FlatEdit3.Text);
      ListItem.SubItems.Add( FlatEdit2.Text);
      ListItem.SubItems.Add( FlatEdit5.Text);
      ListItem.SubItems.Add(FlatEdit4.Text);
      ListItem.SubItems.Add(FlatEdit6.Text);
    看看这样吧!
    也许对你有一点点用!
      

  2.   

    OnClick就可以,你要进行判断,不是什么时候Click都要求执行里面的代码的,具体如下:
    procedure TForm1.TreeView1Click(Sender:TObject);
    begin
      with TreeView1 do 
        if Selected<>Nil then
          ShowMessage(Selected.Text);
    end;至于你说的如何判断当前Click的是TreeView1的第几项,你可以这样判断:
    if TreeView1.Selected<>Nil then
      ShowMessage(IntToStr(TreeView1.Selected.AbsoluteIndex-TreeView1.Selected.Parent.AbsoluteIndex));  //这里显示多少,就说明是同级中的第几项目。
    另外,至于你说TreeView中是如何编码的,以及它的相关的属性,方法等信息,你完全可以直接看D的帮助,那是最权威的东西!
      

  3.   

    click事件里,不知道你怎么写的 if (TreeView1.Items.Count > 0) then
    begin
       showmessage(TreeView1.selected.text);
    end
      

  4.   

    click事件里,不知道你怎么写的 if (TreeView1.Items.Count > 0) then
    begin
       showmessage(TreeView1.selected.text);
    end
      

  5.   

    可以用变通的手法。
      TreeView有Images属性不是吗?自己做三张小图片:全选中、部分选中、不选状态(直接拍下CheckBox三种状态的图片在加工一下就可以了),然后在点击事件中根据具体情况设置TTreeNodes的ImageIndex就OK了。
      如果嫌麻烦的话就去Down一个控件,其实有些控件也是这样做的,界面上你是看不出来的.     :)
    **************
    Manan Patel <[email protected]>
    重载TreeView的CreateParams:
    type
      TCheckBoxTreeView = class(TTreeView)
      protected
        procedure CreateParams(var Params: TCreateParams); override;
      end;procedure TCheckBoxTreeView.CreateParams(var Params: TCreateParams);
    begin
      inherited;
      Params.Style:=Params.Style or TVS_CHECKBOXES; 
      { TVS_CHECKBOXES declared in CommCtrl }
    end;如果要Check这个CheckBox,可以用下面的代码:
    function IsNodeChecked(Node :TTreeNode) :Boolean;
    const
      TVIS_CHECKED = $2000;
    var
      TvItem :TTVItem;
    begin
      TvItem.Mask  := TVIF_STATE;
      TvItem.hItem := Node.ItemId;
      TreeView_GetItem(Node.TreeView.Handle, TvItem);
      Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED;
    end;procedure SetNodeChecked(Node :TTreeNode; Checked :Boolean);
    const
      TVIS_CHECKED = $2000;
    var
      TvItem :TTVItem;
    begin
      FillChar(TvItem, SizeOf(TvItem), 0);
      with TvItem do begin
        hItem     := Node.ItemId;
        Mask      := TVIF_STATE;
        StateMask := TVIS_STATEIMAGEMASK;
        if Checked then
          TvItem.State :=TVIS_CHECKED
        else
          TvItem.State :=TVIS_CHECKED shr 1;
        TreeView_SetItem(Node.TreeView.Handle, TvItem);
      end;
    end;
    可以做成事件和封装成一个类:
    private OldState :Boolean;procedure Change(Node: TTreeNode); override;
    begin
      inherited Change(Node);
      OldState := IsNodeChecked(Node);
    end;procedure Click; override;
    var
      NewState :Boolean;
    begin
      inherited Click;
      NewState := IsNodeChecked(Self.Selected);
      if NewState = OldState then Exit;
      if (NewState) and Assigned(OnNodeChecked) then OnNodeChecked()
      else if (not NewState) and Assigned(OnNodeUnChecked) then 
    OnNodeUnChecked()// OnNodeChecked & OnNodeUnchecked will be events that you declare
    end;
      

  6.   

    一. 如何初始化一个TreeView? 
    弄一个窗口,放上一个TreeView和一个Button,分别取名为TV1和Btn1。如果需要 
    在每个节点前有个图,请在窗口上放上一个ImageList,取名为ImageList1,双击 
    它,加入六个图标。还要记得记得将TV1的Images属性改为ImageList1噢。双击按 
    钮Btn1,在里面填入以下代码,然后按F9运行,点击Btn1就可以看到效果了。 
    procedure TForm1.Btn1Click(Sender: TObject); 
    Const 
    MyDocDir = 'C:\My Documents'; 
    PersonDir = '3hSoft'; 
    Var 
    Var 
    I : Word; 
    SubNodeName : array [1..5] of ShortString; 
    RootNode, SubNode : TTreeNode; 
    P : PString; 
    begin 
    SubNodeName[1] := '便笺'; 
    SubNodeName[2] := '发件箱'; 
    SubNodeName[3] := '联系人'; 
    SubNodeName[4] := '任务'; 
    SubNodeName[5] := '日记'; 
    TV1.Items.Clear; 
    TV1.Items.BeginUpdate; 
    New(P); 
    P^ := MyDocDir + '\' + PersonDir; 
    RootNode := TV1.Items.AddObject(Nil, '个人文件夹', P); 
    // 此 Node 的图标已对 Images 属性中取第 0 个了。 
    For I := 1 to 5 do 
    begin 
    New(P); 
    P^ := MyDocDir + '\' + PersonDir + '\' + SubNodeName[I]; 
    SubNode := TV1.Items.AddChildObject(RootNode, SubNodeName[I], P) 


    // 如果不想使用图标的话请删除以下两行 
    SubNode.ImageIndex := I; 
    SubNode.SelectedIndex := I; 
    end; 
    TV1.Items.EndUpdate; 
    end; 
    二.在TreeView中如何设置选中结点 
    var 
    i:integer; {i为设置的选中结点的索引值} 
    begin 
    if i>treeview1.items.count then 
    treeview1.items[i].selected:=true; 
    或 
    treeview1.selected:=treeview1.items[i]; 
    三。设置TreeView结点的图形 
    1. 设置TreeView的images属性为已存在的images对象 
    treeview1.images:=imagelist1; 
    2. 在加入结点后执行: 
    var 
    anode:TTreeNode; 
    begein 
    anode:=Treeview1.add(nil,'item1'); 
    anode.imageindex:=0; {结点未选中时显示的图标} 
    anode.selectedindex:=1; {结点选中时显示的图标} 
    end 
    3. 如果结点图形在改变后未发生变化,可以执行: 
    treeview1.refresh; 
    四。如何批量处理TreeView结点 
    使用TreeView的items属性的BeginUpdate和EndUpdate方法,例: 
    TreeView1.items.BeginUpdate; 
    for i:=0 to TreeView1.items.count-1 do 
    begin 
    //将每个结点的文字改成为小写字母 
    TreeView1.items[i].text:=lowercase(TreeView1.items[i].text); 
    end; 
    TreeView1.items.EndUpdate; 五。实现TreeView结点拖拽的实例 
    下面的程序片段演示了如何实现拖拽treeview构件结点的例子 
    {鼠标按下时执行的语句} 
    procedure TForm1.Treeview1MouseDown(Sender: TObject; 
    Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
    begin 
    {判断左键按下并且鼠标点在一个结点上开始实现拖拽} 
    if ( Button = mbLeft ) and 
    ( htOnItem in Treeview1.GetHitTestInfoAt( X, Y ) ) then 
    begin 
    Treeview1.BeginDrag( False ); 
    end; 
    end; 
    {鼠标拖动执行语句} 
    procedure TForm1.Treeview1DragOver( Sender, Source: TObject; 
    X, Y: Integer; State: TDragState; var Accept: Boolean); 
    var 
    Node : TTreeNode; 
    begin 
    if Source = Treeview1 then 
    begin 
    Node := Treeview1.GetNodeAt( X, Y ); {取当前结点} 
    if Node <> nil then {当前结点不为空才能实现拖拽,accept:=true} 
    Accept := true; 
    end; 
    end; 
    {鼠标释放时执行的语句} 
    procedure TForm1.Treeview1DragDrop( Sender, Source: TObject; 
    X, Y : Integer ); 
    var 
    TempNode : TTreeNode; 
    AttachMode : TNodeAttachMode; 
    begin 
    if Treeview1.Selected = nil then 
    Exit; 
    AttachMode := naAddChild; {设置结点移动模式,设移动结点为子结点} 
    { 注意在这里存在一个bug,当移动结点时,如果目标结点没有子结点,} 
    { 则加入的新的子结点会失败,所以先在当前目标结点的下面 } 
    { 加入一个临时子结点,移动完毕后,再将临时结点删除 } 
    Treeview1.Items.BeginUpdate; 
    try 
    TempNode := Treeview1.Items.AddChild( Treeview1.DropTarget, 
    'Temp' ); 
    try 
    { 移动选中的结点到目标结点 } 
    Treeview1.Selected.MoveTo( Treeview1.DropTarget, AttachMode ); 
    finally 
    TempNode.Free; { 不要忘了释放临时结点 } 
    end; 
    finally 
    Treeview1.Items.EndUpdate; 
    end; 
    end; 
      

  7.   

    add a double-click event to the header of a Listview?

      MS did not see fit to send a notification to the listview when the user 
      Double - clicks on the header. But the header control class does have the 
      CS_DBLCLKS Style, so it does get WM_LBUTTONDBLCLK messages, it just does 
      not do anything with them. To get at these messages requires API - Style 
      subclassing of the header control. 
    } uses commctrl; 
    function HeaderProc(wnd: HWND; Msg: Cardinal; wParam: wParam; lParam: lParam): Longint; 
      stdcall; 
    var 
      hti: THDHitTestInfo; 
    begin 
      Result := CallWindowProc(Pointer(GetWindowLong(wnd, GWL_USERDATA)), 
        wnd, Msg, wParam, lParam); 
      if Msg = WM_LBUTTONDBLCLK then 
      begin 
        FillChar(hti, SizeOf(hti), 0); 
        hti.Point := SmallPointToPoint(TSmallPoint(lParam)); 
        if SendMessage(wnd, HDM_HITTEST, 0, Longint(@hti)) >= 0 then 
          if hti.Flags = HHT_ONHEADER then 
            // would usually send a custom notification to GetParent(wnd) here 
            Form1.Memo1.Lines.Add(Format('doubleclick on header item %d', [hti.Item])); 
      end; 
    end; procedure TForm1.Button1Click(Sender: TObject); 
    var 
      wnd: HWND; 
      buffer: array [0..80] of Char; 
      oldProc: Integer; 
    begin 
      wnd := GetWindow(Listview1.Handle, GW_CHILD); 
      if wnd <> 0 then 
      begin 
        Windows.GetClassname(wnd, buffer, SizeOf(buffer)); 
        memo1.Text := buffer; 
        if (GetClassLong(wnd, GCL_STYLE) and CS_DBLCLKS) <> 0 then 
        begin 
          Memo1.Lines.Add('Has doubleclicks style'); 
          oldproc := GetWIndowLong(wnd, GWL_WNDPROC); 
          if GetWindowLong(wnd, GWL_USERDATA) <> 0 then 
            raise Exception.Create('Cannot sublcass header, USERDATA already in use'); 
          SetWIndowLong(wnd, GWL_USERDATA, oldproc); 
          SetWindowLong(wnd, GWL_WNDPROC, Integer(@HeaderProc)); 
        end; 
      end 
      else 
        Memo1.Text := 'No child'; 
    end; 
      

  8.   

    如果是通过单击取text的话应该很简单;
    procedure TForm1.TreeView1MouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    var
     Node: TTreeNode;
    begin
      Node := TreeView.GetNodeAt(x, y);
      if node <> nil then
        msgbox(node.text)
    end;