Detached Popup Menus


Floating popup menus that are not 'attached' to the frame (as is a main menu) are also available. The program of this section supplies an example of a detached popup menu. Pictured below is a snapshot of this application with the detached popup exposed.

Two functions exist to manipulate detached popup menus:

These functions can track only a submenu or a popup menu created via the function create_popup_menu. Because of this, a popup menu will be created as a submenu. The submenu will then be tracked as a detached popup. The source code files of such an application consists of:

Menu Resource For a Detached Popup

Because the function track_popup_menu requires a submenu (not a main menu) the resource specification encapsulates the menu to be tracked in a main menu as shown below.

MenuIdentity MENU
{
 POPUP ""
  {
   POPUP "&file"
    {
     MENUITEM "&New",               MenuItemNew
     MENUITEM "&Open...",           MenuItemOpen
     MENUITEM "&Save",              MenuItemSave
     MENUITEM "Save &As...",        MenuItemSaveAs
     MENUITEM SEPARATOR
     MENUITEM "E&xit",              MenuItemExit
    }
   POPUP "&edit"
    {
     MENUITEM "&undo",              MenuItemundo
     MENUITEM SEPARATOR
     MENUITEM "Cu&t",               MenuItemcut
     MENUITEM "&copy",              MenuItemcopy
     MENUITEM "&paste",             MenuItempaste
     MENUITEM "De&lete",            MenuItemDelete
    }
   POPUP "&background"
    {
     MENUITEM "&White",             MenuItemWhite, CHECKED
     MENUITEM "&Light Gray",        MenuItemlight_gray
     MENUITEM "&Gray",              MenuItemGray
     MENUITEM "&Dark Gray",         MenuItemDarkGray
     MENUITEM "&Black",             MenuItemBlack
     }
   POPUP "&help"
    {
     MENUITEM "&help...",              MenuItemHelp
     MENUITEM "&About Popup menu...",  MenuItemAbout
    }
  }
}

The popup is given no name and it is the first and only item of the containing menu. Within the client window procedure, the variable menu is declared as static - as shown below.

result __stdcall client(handle window_handle,
                       unsigned identity,
                       parameter parameter1,
                       parameter parameter2)
{
 static handle MenuHandle;
 static int Selection = MenuItemWhite;
 ....
}

The window procedure initializes this variable during the processing of the message message::create - as shown below.

case message::create:
 MenuHandle = load_menu(get_module_handle(),MenuIdentity);
 MenuHandle = get_submenu(menu,0);
 break;

The containing menu is loaded via function load_menu, then the handle of the submenu is obtained via the function get_submenu. Items within a menu are ascribed a numeric offset beginning at zero. When loading the submenu, its offset is zero and it is the only item within the containing menu.

Tracking the Popup

Most often, applications initiate the tracking of a submenu via right mouse button interaction. By way of showing the popup, the notification message::right_button_down is coded as shown below.

case message::right_button_down:
 {
  ipoint track(low_part(parameter2),high_part(parameter2));
  client_to_screen(window_handle,&track);
  track_popup_menu(MenuHandle,0,track(0),track(1),0,window_handle,(const rectangle*)null);
 }
 break;

The position of the mouse is in client coordinates when the notification message::right_button_down is received. These coordinates are converted to screen coordinates and passed to the function track_popup_menu. The client window is set to be the owner window; thereby ensuring that notifications are directed to the client. The parent of the popup is the desktop - so the popup may extend beyond the boundaries of the client when displayed. Although the display of the menu was initiated via right mouse button interaction (which is usually the case), selection of items within the menu are made using the left mouse button - unless otherwise specified.