I have tree control object created using CTreeCtrl MFC class. The tree control needs to support rename. When I left click on any of item in Tree the TVN_SELCHANGED event is called from which I can get the selected item of the tree as below : HTREEITEM h = m_moveListTree.GetSelectedItem(); CString s = m_moveListTree.GetItemText(h);

However when I rightclick on any item in tree I do not get any TVN_SELCHANGED event and hence my selected item still remains the same from left click event. This is causing following problem : 1)User leftclicks on item A 2)user right clicks on item B and says rename 3)Since the selected item is still A the rename is applying for item A.

Please help in solving problem.



I created my own MFC like home grown C++ GUI library on top of the Win32 API and looking at my code, this is how it handles that situation:

LRESULT xTreeCtrl::onRightClick(NMHDR *)
  xPoint pt;

  //-- get the cursor at the time the mesage was posted
  DWORD dwPos = ::GetMessagePos();

  pt.x = GET_X_LPARAM(dwPos);
  pt.y = GET_Y_LPARAM (dwPos);

  //-- now convert to window co-ordinates

  //-- check for a hit
  HTREEITEM hItem = this->hitTest(pt);

  //-- select any item that was hit
  if ((int)hItem != -1) this->select(hItem);

  //-- leave the rest to default processing
  return 0;

I suspect if you do something similar in the MFC right click or right button down events that will fix the problem.

NOTE: The onRightClick code above is nothing more than the handler for the WM_NOTIFY, NM_RCLICK message.

Hi Jussij, Thanks for the reply. Where can I find the xPoint class ? or How can I convert the oiint from CPoint class to window co-ordinated
Just use CPoint, then call ScreenToClient().
Hi Chris , Thanks for the reply.I have coded like this after getting CPoint pt: LPPOINT p = new tagPOINT ; p->x = pt.x; p->y = pt.y; ScreenToClient(p); pt.x =p->x; pt.y = p->y; HTREEITEM hItem = m_moveListTree.HitTest(pt);But the item being pointed is wrong. What should I do ?
Sorry Praveen, that should have been m_moveListTree.ScreenToClient.
Also, note that you shouldn't need to allocate a tagPOINT object with operator new. Just do: CPoint pt; pt.x = ...; pt.y = ...; m_moveListTree.ScreenToClient( pt );
Thanks Chris that worked.But the ScreenToClient takes a LPPoint object and is not able to take CPoint object. Should I not use the tag point object ?Thanks Praveen
Thanks a lot Chris and Jussij . My problem is solved
The class library that I used is a hand written C++ layer over Win32. For example the xPoint is just a wrapper to the POINT structure.The other names will MAP closely to the other Win32 API.

Not sure how you popup the context menu, but you can use HitTest() to get from a point to a tree item. So you might use this in your right click handler.

Don't forget that the context menu can also be activated by a key on reasonable modern keyboards. Then you probably want to use the selected item as target.

+2  A: 

This behaviour is by design -- right-clicking doesn't move the selection.

For what you want, turn on the TVS_EDITLABELS style on the tree view. Then you handle the TVN_BEGINLABELEDIT and TVN_ENDLABELEDIT notifications.

Roger Lipscombe