How to Handle the BCN_DROPDOWN Notification from a Split Button

This topic describes one possible way of responding to the BCN_DROPDOWN notification in a dialog procedure.

The C++ application retrieves the client coordinates of the button from the notification header and converts them to screen coordinates. It then creates a popup menu and displays it at the bottom of the button. To keep the example simple, keyboard shortcuts are not implemented for the menu.

What you need to know

Technologies

Prerequisites

  • C/C++
  • Windows User Interface Programming

Instructions

Step 1: Wait for the BCN_DROPDOWN notification.

case BCN_DROPDOWN:
{
    NMBCDROPDOWN* pDropDown = (NMBCDROPDOWN*)lParam;
    if (pDropDown->hdr.hwndFrom = GetDlgItem(hDlg, IDC_SPLIT))
    {

Step 2: Get the screen coordinates of the button.

Use the ClientToScreen function to convert the window coordinates of the button's lower left edge to screen coordinates.

POINT pt;
pt.x = pDropDown->rcButton.left;
pt.y = pDropDown->rcButton.bottom;
ClientToScreen(pDropDown->hdr.hwndFrom, &pt);

Step 3: Create a menu and add items.

Use the CreatePopupMenu function to create a menu. Use the AppendMenu function to add items to the menu. IDC_MENUCOMMAND1 and IDC_MENUCOMMAND2 are application-defined constants for menu commands.

HMENU hSplitMenu = CreatePopupMenu();
AppendMenu(hSplitMenu, MF_BYPOSITION, IDC_MENUCOMMAND1, L"Menu item 1");
AppendMenu(hSplitMenu, MF_BYPOSITION, IDC_MENUCOMMAND2, L"Menu item 2");

Step 4: Display the menu.

The TrackPopupMenu function displays a shortcut menu at the specified location and tracks the selection of items on the menu.

TrackPopupMenu(hSplitMenu, TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, hDlg, NULL);

Complete example

case WM_NOTIFY:
    switch (((LPNMHDR)lParam)->code)
    {
        case BCN_DROPDOWN:
        {
            NMBCDROPDOWN* pDropDown = (NMBCDROPDOWN*)lParam;
            if (pDropDown->hdr.hwndFrom = GetDlgItem(hDlg, IDC_SPLIT))
            {

                // Get screen coordinates of the button.
                POINT pt;
                pt.x = pDropDown->rcButton.left;
                pt.y = pDropDown->rcButton.bottom;
                ClientToScreen(pDropDown->hdr.hwndFrom, &pt);
        
                // Create a menu and add items.
                HMENU hSplitMenu = CreatePopupMenu();
                AppendMenu(hSplitMenu, MF_BYPOSITION, IDC_MENUCOMMAND1, L"Menu item 1");
                AppendMenu(hSplitMenu, MF_BYPOSITION, IDC_MENUCOMMAND2, L"Menu item 2");
        
                // Display the menu.
                TrackPopupMenu(hSplitMenu, TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, hDlg, NULL);
                return TRUE;
            }
            break;
        }
    }
    return FALSE;
}

BCN_DROPDOWN Notification Code

About Buttons

Button Control Reference

Using Buttons

Button