Drop down button notification

Hi,

I am using a custom toolbar class in my MDI app. I am adding a dropdown button to it, which is working fine. My problem is that I am not receiving any notification as to when the drop down menu for the button is being created, though I have a handler for that event. Here are the pieces I am executing:

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
        ...
        ON_NOTIFY(TBN_DROPDOWN, IDR_MYTOOLBAR, OnToolbarDropDown) // call me when user clicks button drop down!

    END_MESSAGE_MAP()

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        ...
        m_MyToolbar.AddDropDownButton(this, BUTTON_ID_DRAW_A_HOUSE, MENU_ID_DRAW_A_HOUSE);
    }

    void CMainFrame::OnToolbarDropDown(NMHDR* pNMHDR, LRESULT* plRes)
    {
        // Shouldn't this be called when the user clicks the drop down arrow for my button?
        AfxMessageBox("user hit drop down for toolbar button");
    }

    void CTrueColorToolBar::AddDropDownButton(CWnd* pParent, UINT uButtonID, UINT uMenuID)
    {
        // Custom toolbar class method for making a button 'drop down' - able.
        GetToolBarCtrl().SendMessage(TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_DRAWDDARROWS);
      
        SetButtonStyle(CommandToIndex(uButtonID), TBSTYLE_DROPDOWN);

        stDropDownInfo DropDownInfo;
        DropDownInfo.pParent      = pParent;
        DropDownInfo.uButtonID      = uButtonID;
        DropDownInfo.uMenuID      = uMenuID;
        m_lstDropDownButton.Add(DropDownInfo);
    }

So my button has a dropdown with the menu I supplied, but my OnToolbarDropDown() handler is never getting called when my menu pops up. Any ideas why it is not getting called? I can supply more source code if necessary,

Thanks
LVL 7
minnirokAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
I think the window isn't getting the message.
(Have a quick test - put the handler into the main frame of the app)
0
AlexFMCommented:
Maybe it is enough to add WM_COMMAND handlers for every menu item? What do you need to do when menu is opened?
0
AndyAinscowFreelance programmer / ConsultantCommented:
Just a sec.
Notify messages will go through the  OnNotify virtual function.

Try overriding the OnNotify (NO message map entry) and test for the message there.
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

minnirokAuthor Commented:
Ok I  added the OnNotify() handler to Main frame, i am getting notify messages when I click on the drop down arrow. But how do I handle only those messages for the drop down activation as opposed to all the rest like when the user is clicking around the window etc?

The reason I need to handle this action is because I want to check off one of the drop down menu items when the menu is created. This way the user can see the last option they chose.

Thanks
0
AndyAinscowFreelance programmer / ConsultantCommented:
The menu is like any other menu.
You handle the menu clicks as Alex suggests, the updating in the update handler (pCmdUI->SetCheck(..))
0
minnirokAuthor Commented:
Hi Andy,

Can you just explain how to do that? This is what I have now:

    BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    {
        TRACE("yes being notified!......\n");

        return CMDIFrameWnd::OnNotify(wParam, lParam, pResult);  
    }

But I am getting messages for any type of user interaction now. How do I 'know' that the notify message that is coming in is due to my drop down menu coming up, how do I then access it to set the check mark?

Thanks
0
DanRollinsCommented:
As AndyAinscow said:  Use the MFC system that is designed to handle this automatically and easily.  Create an
    ON_UPDATE_COMMAND_UI
handler.  It gets called automatically just before the menu is displayed.  That's when you do the SetCheck -- based on the current values of global or memeber variables.  See:

     How to: Update User-Interface Objects  
     http://msdn2.microsoft.com/en-us/library/72t5ykb7.aspx

In your message map, you'll have a line like:
      ON_UPDATE_COMMAND_UI(BUTTON_ID_DRAW_A_HOUSE, OnUpdateDrawHouse)

Then you'll write a handler like:
//-----------------------------------------------------
void CWhatever::OnUpdateDrawHouse(CCmdUI* pCmdUI)
{
      if ( m_fDrawAHouseToolCurrentlyActive ) {
            pCmdUI->SetCheck(1);
      }
      else {
            pCmdUI->SetCheck(0);   // note 2 means indeterminate
      }
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DanRollinsCommented:
Note: The first item in the ON_UPDATE_COMMAND_UI macro is the Command ID (usually, but not always the same as the button ID)  It will be the same as used in the ON_COMMAND handler that is in the same message map.
0
AndyAinscowFreelance programmer / ConsultantCommented:
I use
((LPNMHDR)lParam)->code
in the OnNotify to get at the ID.
0
minnirokAuthor Commented:
Hi guys,

Sorry I'm a bit confused now -

If I were to add that update command UI mapping, won't I get messages anytime that button is being drawn? How do I know that the dropdown menu for the button is coming up? That's all I'm really interested in. I just want to get a pointer to the menu and check the appropriate item right before it's to be displayed.

Can I have a few more instructions?

Thanks

0
AndyAinscowFreelance programmer / ConsultantCommented:
Menu and toolbar.
You get a message when the user selects one (typically you have an OnDoSomething function to react to that).
Just prior to the menu item / toolbar button being shown there is another message passed.
If you use the wizard to add an event handler for the button you will see TWO messages you can respond to.  If you select the one for the updating then you will see a function like
OnUpdateDoSomething(CCmdUI* pCmdUI)
Now add the line
pCmdUI->SetCheck(true);
in the function and you should get a check mark next to the menu item you have the update handler for.
0
minnirokAuthor Commented:
Ok I guess that's where my confusion is. I've added an update UI function for my toolbar button:

    ON_UPDATE_COMMAND_UI(TOOLBAR_BUTTON_ID, OnUpdateMyToolbarButton)

And its body is:

    void CMainFrame::OnUpdateDrawOneClickDropDown(CCmdUI* pCmdUI)
    {
        pCmdUI->SetCheck(1);
    }

But this just has the effect of making the toolbar button look de-pressed, as if it is selected. I need to know how to check an item off in the drop down menu associated with the button.

I'm increasing the points for this question, sorry to be such a pain, thanks for your continuing help
0
AndyAinscowFreelance programmer / ConsultantCommented:
replace TOOLBAR_BUTTON_ID with the ID of the menu item you want to display the check next to.
0
minnirokAuthor Commented:
Ahhhhh ok that's what I was missing.

Works perfectly now, thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.