# Menu

The Menu function shows a menu.

    int WINAPI Menu(
      int PluginNumber,
      int X,
      int Y,
      int MaxHeight,
      DWORD Flags,
      const char *Title,
      const char *Bottom,
      const char *HelpTopic,
      const int *BreakKeys,
      int *BreakCode,
      const struct FarMenuItem *Item,
      int ItemsNumber
    );

### Parameters

PluginNumber
Number of the plugin module. It is passed to the plugin in the SetStartupInfo function.
X,Y
Top left menu corner coordinates.
To assign coordinates automatically set them to `-1`
MaxHeight
Maximum count of visible menu items. If it is less than the items number, items will be scrolled.
To use maximum possible height set this parameter to `0`.
Flags
Can be a combination of the following values (FARMENUFLAGS enum):

Constant | Description
--- | ---
FMENU_AUTOHIGHLIGHT | If specified, item hot keys will be assigned automatically, beginning from the first item.
FMENU_CHANGECONSOLETITLE | If specified, the the title of the console window will be set to Title (if Title is not empty).
FMENU_SHOWAMPERSAND | Shows ampersands in menu item texts. Without this flags ampersands are used to specify item hot keys.
FMENU_REVERSEAUTOHIGHLIGHT | If specified, item hot keys will be assigned automatically, beginning from the last item.
FMENU_USEEXT | Instead of FarMenuItem the FarMenuItemEx structure is used.
FMENU_WRAPMODE | If specified, attempts to move the cursor above the first item or below the last will move the cursor to the last or the first item, respectively. It is recommended to always set this flag, unless you have specific reasons not to do so.

If the FMENU_USEEXT flag is set then it is necessary to perform a type cast:

    struct FarMenuItemEx FooEx[]={
      ...
    };
    Info.Menu(...,FMENU_USEEXT|...,(const struct FarMenuItem *)FooEx,...)

Title
Menu title. Set to `NULL` if menu title is not needed.
Bottom
Menu bottom title. Set to `NULL` if menu bottom title is not needed.
HelpTopic
The help topic associated with the menu. Set to `NULL` if help is not needed.
BreakKeys
Address of an array with virtual key codes (VK_*), that will close the menu. The last array item must be 0. If you do not need to define such keys in addition to the standard keys (`<Enter>`, `<Esc>` and `<F10>`), set this parameter to `NULL`. The high word of an array item can be either 0 or a combination of PKF_CONTROL, PKF_ALT and PKF_SHIFT flags to describe corresponding key combinations.

For example in the MultiArc plugin in the "Archive commands" menu (`Shift-F3` on archive) the `F4` keystroke is processed in the following way:

    int BreakCode;
    int BreakKeys[2]={VK_F4,0};
    ExitCode=Info.Menu(Info.ModuleNumber,-1,-1,0,FMENU_USEEXT|FMENU_WRAPMODE,
         GetMsg(MArcCmdTitle),GetMsg(MSelectF4),"ArcCmd",BreakKeys,&BreakCode,
         (struct FarMenuItem *)MenuItems,Count);
    if(ExitCode>=0)
    {
      if(BreakCode == 0)  // F4 pressed
      {
        GetFormatName(MenuItems[0].Text.Text);
        ConfigCommands(MenuItems[0].Text.Text,2+MenuData[ExitCode].Cmd*2);
        continue;
      }
    }
    else
      return FALSE;

BreakCode
Address of a variable that will receive the index in the BreakKeys array of the key used to close the menu, or -1 if the menu was closed using one of the standard keys. This parameter can be `NULL`.
Item
Address of an array of FarMenuItem structures or if the FMENU_USEEXT flag is specified, address of an array of FarMenuItemEx structures. Each structure describes one menu item.
ItemsNumber
Number of FarMenuItem structures.

### Return value

This function returns either -1, if the user cancelled the menu, or the selected menu item number.

### Example

This example is taken from the EditCase plugin:

    struct FarMenuItem MenuItems[2];
    memset(MenuItems,0,sizeof(MenuItems));
    strcpy(MenuItems[0].Text,GetMsg(MCaseLower));
    strcpy(MenuItems[1].Text,GetMsg(MCaseUpper));
    MenuItems[0].Selected=TRUE;
    int MenuCode=Info.Menu(Info.ModuleNumber,-1,-
          1,0,FMENU_AUTOHIGHLIGHT|FMENU_WRAPMODE,
          GetMsg(MCaseConversion),NULL,
          "Contents",NULL,NULL,
          MenuItems,
          sizeof(MenuItems)/sizeof(MenuItems[0]));
    if (MenuCode<0)
      return(INVALID_HANDLE_VALUE);
    . . .

Info is defined as a global variable:

    struct PluginStartupInfo Info;

...and is initialized in the SetStartupInfo function:

    void WINAPI _export SetStartupInfo(struct PluginStartupInfo *Info)
    {
      ...
      ::Info=*Info;
      ...
    }

See also:
FarMenuItem