views:

1039

answers:

3

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.

-Praveen

A: 

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
  pt.toWindow(this);

  //-- 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.

jussij
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().
ChrisN
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.
ChrisN
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 );
ChrisN
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
ChrisN
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.
jussij
A: 

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.

Steffen
+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