Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Tree Control

Posted on 2003-12-04
16
575 Views
Last Modified: 2013-11-20
I have written the following code as an handler when an item in a Tree Control is right clicked.

NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
    CTreeCtrl* pTree = (CTreeCtrl*) GetDlgItem(IDC_TREEVIEW);
    HTREEITEM hSelected = pNMTreeView->itemNew.hItem;

But i am getting hSelected as NULL always

What could be the error ???

Thanks in advance!!!
0
Comment
Question by:VS_Learner
  • 8
  • 8
16 Comments
 
LVL 11

Expert Comment

by:KurtVon
ID: 9874637
According to MS docs:

itemNew
TV_ITEM structure that contains information about the new item state. This member is zero for messages that do not use it.

Unfortunately, since right clicking does not actually select an item in the tree, the value here is 0.  On the bright side, that means you aren't doing anything wrong, Windows is just being annoying.  If you want to find out where the right-click occurred, you need to use the ptDrag to find the item under the cursor.  Unfortunately this means stepping through a loop with GetNextVisibleItem and GetItemRect sinc ethere is no GetItemFromPoint member of CTreeCtrl.

Hope this helps.
0
 

Author Comment

by:VS_Learner
ID: 9879226
Could anyone present a sample code as to how to find the item(in the tree control) on which the right click has occured??

Thanks
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9882549
Hmm, I have some such code at home, but that would take a while to get (that's why I recognized your problem, went through the same thing myself).  It went something like:

CRect rcItem;
HTREEITEM hItem = m_TreeCtrl.GetFirstVisibleItem();
while (hItem != NULL)
{
    m_TreeCtrl.GetItemRect(hItem, rcItem, FALSE);
    if (rcItem.PtInRect(pNMTreeView->ptDrag)
        break;
    else
        hItem = m_TreeCtrl.GetNextVisibleItem(hItem);
}

if (hItem != NULL)
{
    // The non-null hItem is the item that was clicked in.
}

This was done by hand, so watch out for typos.

Hope this helps.
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:VS_Learner
ID: 9886953
Hi KurtVon ,
                Thanks for writing the code . But unfortunately i am getting the hItem as NULL always irrespective of where ever i click.
Like it is never going into the 'if loop' .so its never breaking and hItem is always becoming NULL.
And i think in the code while calling the function GetItemRect ..the second argument should be a pointer to the CRect structure.(coz..its an input parameter i guess.).But still the code isn't working.
I have also tried calling GetCursorPos and giving that point as an argument to PtInRect ..But even that isn't working.

So please help me out in finding out the error!!!!!!!

Thanks again.!!!
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9896778
Hmm, the code works perfectly for me.  What message are you trapping?  I used the TVN_BEGINRDRAG, but that meant I had to move the mouse a bit while the button was down.

And the CRect should not be a pointer.  GetItemRect takes a pointer to a RECT, but a CRect can be a pointer to a RECT through a typecast.  Using the & will work too, but only because a CRect is descended from RECT and has no virtual functions.  In general, typecast operators are safer than assumptions like that.
0
 

Author Comment

by:VS_Learner
ID: 9897192
I am trapping the NM_RCLICK ( right mouse click )..Like I want to display a menu (when right-clicked ) to only some items in the tree control.So i want to know whether an item is clicked or not , and if clicked which item?? Hope I am clear .!

Thanks
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9897239
NM_RCLICK only notifies when the mouse button is released.  But if that's okay, the problem is simple, the notification message does not send a NM_TREEVIEW object.  To get the mouse position you will need to use this code:

    CPoint ptDrag;
    GetCursorPos(&ptDrag);
    m_TreeCtrl.ScreenToClient(&ptDrag);

then just check the CRect position with ptDrag.

Hope this helps.
0
 

Author Comment

by:VS_Learner
ID: 9897304
I have already tried this code (i.e using GetCursorPos to get the point ) , but unfortunately i am getting hItem as NULL always ..
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9897525
I assume you did the ScreenToClient too (for the control).  Very odd since it works perfectly for me.

Does it do into the while loop, or does it skip over the loop on the first try?  If it skips, then GetFirstVisibleItem is returning NULL, which would mean that the tree control is reporting no visible items.  If it is going into teh loop, but not finding any item for the rectangle, it may be that GetItemRect has the third parameter set to TRUE somehow, and is only allowing teh selection of text.  Try clicking on the text itself.

Hope this helps.
0
 

Author Comment

by:VS_Learner
ID: 9903415
Irrespective of whereever i click , it is going through the while loop i ( i = GetVisibleCount) number of times. And that "i" value is perfectly right..(I checked it ) . It is only that in the "while" loop always "else" is getting executed. I have also checked everyother possible thing.The only thing is that , the point where i click is "never" in the rectangle of any visible item.

Thanks
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9904145
What are the coordinates of the click point?  It almost sounds like ScreenToClient isn't working properly.  Make sure you are calling it for the tree control object, not for the dialog.  Also check the coordinates of the rectangles.

Also make sure you really are using the point collected in GetCursorPos to compare against the rectangles.  If that still doesn't work, could you post the code up to the end of the while loop?  I'll compare it to what I have and see if I can find the problem.
0
 

Author Comment

by:VS_Learner
ID: 9904933

Here is the code upto end of while loop...

void CFolderPage::OnNMRclickTreeview(NMHDR *pNMHDR, LRESULT *pResult)
{

        CRect rcItem;

       HTREEITEM hItem = m_treectrl.GetFirstVisibleItem();
       while (hItem != NULL)
      {
      m_treectrl.GetItemRect(hItem, rcItem, FALSE);
      POINT point ;
      GetCursorPos(&point) ;
      m_treectrl.ScreenToClient(&point);
      if ( rcItem.PtInRect(point) )
            break;
      else
            hItem = m_treectrl.GetNextVisibleItem(hItem);
      }
0
 
LVL 11

Expert Comment

by:KurtVon
ID: 9905280
Odd, that looks like it should work.  You can make the code more efficient by taking the GetCursorPos out of the while loop (since you only care about where the curosr was when the loop was entered).  of course, it will not work while debugging since the mouse is moved, so test it without a breakpoint or make sure the breakpoint is after the cursor position is retrieved:

void CFolderPage::OnNMRclickTreeview(NMHDR *pNMHDR, LRESULT *pResult)
{
    CRect rcItem;
    POINT point ;

    GetCursorPos(&point) ;
    m_treectrl.ScreenToClient(&point);
    HTREEITEM hItem = m_treectrl.GetFirstVisibleItem(); // put breakpoint here or later
    while (hItem != NULL)
    {
        m_treectrl.GetItemRect(hItem, rcItem, FALSE);
        if ( rcItem.PtInRect(point) )
            break;
        else
            hItem = m_treectrl.GetNextVisibleItem(hItem);
    }

that way the cursor position will be where you clicked rather than where you moved the mouse after it was hit.  Then check the point against each rect and see if it makes any more sense why it wouldn't work.

Hope this helps.
0
 

Author Comment

by:VS_Learner
ID: 9905443
Hey ...Its working!!!...when i moved the 3 lines ( getting cursor pos) above the while loop.Its working fine..!!!
Thank You Very much for taking some time to test the code.
Actually now i got the actual error..!!! when i added debugging code ( like putting some messageboxes ) the cursor is moving to the "ok" button of the messagebox and the actual click point is missing everytime when it enters the while loop!!!

Thanks Once Again!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0
 

Author Comment

by:VS_Learner
ID: 9905529
I need to attach the same functionality for a list control box...So can i use the same type of code for that too..Or any changes are required???

Thank You
0
 
LVL 11

Accepted Solution

by:
KurtVon earned 20 total points
ID: 9905788
To do this with a list control is easier, since CListCtrl::HitTest will return the index of the item the point is in automatically, so no need for the while loop.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question