我在用TreeCtrl做一个树的时候发现了一个奇怪的问题,在鼠标点击时,事件总是不会立即响应,总是第二次事件发生后,第一次的点击事件运行结果才会出来。以下是我的鼠标点击事件代码:
void CVCTREEDlg::OnClickTreectrl(NMHDR* pNMHDR, LRESULT* pResult) 
{
hSel=m_TreeCtrl.GetSelectedItem();//取得选项句柄;
m_TreeCtrl.GetItemImage(hSel, nImage, nSelectedImage);//得到结点图标索引值
nImage=(nImage==0)?1:0;  //如果是1就设为0,是0则变成1
m_TreeCtrl.SetItemImage(hSel, nImage,nImage); //重新设置图标
*pResult = 0;
}

解决方案 »

  1.   

    I think this because the message first will be dispatched by dialog,not treectrl,so i suggest you should derive your own treectrl class ,and overide it. or try this way:
    void CVCTREEDlg::OnLButtonDown(..)
    {
    hSel=m_TreeCtrl.GetSelectedItem();//取得选项句柄;
    m_TreeCtrl.GetItemImage(hSel, nImage, nSelectedImage);//得到结点图标索引值
    nImage=(nImage==0)?1:0;  //如果是1就设为0,是0则变成1
    m_TreeCtrl.SetItemImage(hSel, nImage,nImage); //重新设置图标
    *pResult = 0;
    }
      

  2.   

    this is my code ,it works well.you can try it
    void CProjectTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    BOOL nSelect;
    HTREEITEM hItem = HitTest(point, &nFlags);
    if ((hItem != NULL) && (TVHT_ONITEM & nFlags))
    {
    nSelect=Select(hItem, TVGN_CARET);
    }
    CString ItemText;
    ItemText=GetItemText(hItem);
    if(nSelect == 1)
                 ...//add your code here
    }
      

  3.   

    SetItemImage 后调用 InvalidateRect 强制窗口刷新看看?
      

  4.   

    在回答你这个问题前,请先告诉我:1. 你的imagelist中有几个图标?
    2. 当你插入一个item时,是如何定义image和selectedimage的?我估计你的问题是把image和selectedimage搞混了.
      

  5.   

    imagelist有3个图标.//定义image
    CVCTREEApp *pApp=(CVCTREEApp *)AfxGetApp();//创建图象列表
    Cil1.Create(16,16,ILC_COLOR,4,4);
    Cil1.Add(pApp->LoadIcon(IDI_NONSELECTED));
    Cil1.Add(pApp->LoadIcon(IDI_SELECTED));
    Cil1.Add(pApp->LoadIcon(IDI_SOMESELECTED));m_TreeCtrl.SetImageList(&Cil1,TVSIL_NORMAL); //设置图象列表 //树控制
    HTREEITEM hRoot,hCur;//树控制项目句柄
    TV_INSERTSTRUCT TCItem;//插入数据项数据结构
    TCItem.hParent=TVI_ROOT;//增加根项
    TCItem.hInsertAfter=TVI_LAST;//在最后项之后
    TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽
    TCItem.item.pszText="根结点";
    TCItem.item.lParam=0;//序号
    TCItem.item.iImage=0;//正常图标
    TCItem.item.iSelectedImage=0;//选中时图标
    hRoot=m_TreeCtrl.InsertItem(&TCItem);//返回根项句柄//设置SetItemImage
    m_TreeCtrl.SetItemImage(hSel, nImage, nImage);

      

  6.   

    To tomew(渔夫㊣):邮件已发,请查收.
      

  7.   

    我用的很好呀,点一下就有反映,你的程序是好的,我没有改,估计是你的ie有问题,升级ie吧修改你的windows组件
      

  8.   

    To tomew(渔夫㊣):
    啊?不可能吧,我试了3台机器都不正常。你多点几次看看,尤其是在
    鼠标在同一个地方点击第二次时无反应。。我的是win2000professor版+VC6.0中文版
      

  9.   

    你要在 TVN_SELCHANGED中用,如果你在onclick中用的话你得到的是上一次的handle所以总是慢一拍
      

  10.   

    ImageList和Item Image均无问题.楼上说得对,通常这种情况下是处理TVN_SELCHANGED消息的.当你点击一次TREEVIEW时,其父窗口先收到NM_CLICKED消息,然后是TVN_SELCHANGING,再后是TVN_SELCHANGED消息.也就是说,当你用点击的方法处理时,这时TREEVIEW中的SELECTED ITME还没有变化呢!
      

  11.   

    楼上的兄弟,你说的方法我也试过,把处理事件放在TVN_SELCHANGED消息会出现这样的
    问题:当在同一树结点上点击时,只有第一次点击事件有反应,后面的事件没有反应。
      

  12.   

    是的,当时回帖的时候我也曾想过你可能会有这一方面的要求,不过当时想这种要求不大合理,所以也就没有考虑.既然你有这样的要求,那么你可以处理NM_CLICKED消息,不过不要用GetSelectedItem(),而是像楼上那样,用HitTest()找出你目前的点击的是哪一个HTREEITEM,然后同样处理即可.
      

  13.   

    to  xschenhao(netboy):
    你就直接在那个OnLButtonDown里面处理就可以了!
    Zark(金陵五月)已经解释的很清楚了,你如果用GetSelectedItem()想来取你要的这个ITEM的话,一定取到的是前一个选中的ITEM,所以你所说的慢一帕其实是在对之前的一个选中的ITEM进行处理,所以从第二次之后都是对的,所以你也只能通过HitTest()来满足你的要求了,OnSelChanged()消息,从函数名字上可以看出SELECT CHANGED,当点选的ITEM不变的时候,是不会进这个消息的。