TMenu / TMenuItem
Pull-down menus, popup menus, and context menus
Fuente: source/classes/menu.prg | Header: FiveWin.ch
Overview
TMenu manages a menu bar or popup menu, while TMenuItem represents an individual item within a menu. FiveWin menus support hierarchical popups, separators, checkmarks, accelerator keys, bitmaps, and modern visual styles (2007, 2010, 2013, 2015).
There are two main usage patterns:
- Menu bar -- attached to a window via
DEFINE MENU oMenu OF oWnd - Popup / context menu -- shown at a position via
ACTIVATE POPUP oMenu AT nRow, nCol OF oWnd
Menu Structure
graph TD
WINDOW["TWindow / TDialog"] --> MENUBAR["TMenu
(Menu Bar)"] MENUBAR --> MI_FILE["TMenuItem
&File"] MENUBAR --> MI_EDIT["TMenuItem
&Edit"] MENUBAR --> MI_HELP["TMenuItem
&Help"] MI_FILE --> POPUP_FILE["TMenu
(Popup)"] POPUP_FILE --> MI_NEW["TMenuItem: New"] POPUP_FILE --> MI_OPEN["TMenuItem: Open"] POPUP_FILE --> MI_SEP["Separator"] POPUP_FILE --> MI_EXIT["TMenuItem: Exit"] MI_EDIT --> POPUP_EDIT["TMenu
(Popup)"] POPUP_EDIT --> MI_CUT["TMenuItem: Cut"] POPUP_EDIT --> MI_COPY["TMenuItem: Copy"] POPUP_EDIT --> MI_PASTE["TMenuItem: Paste"] MI_HELP --> POPUP_HELP["TMenu
(Popup)"] POPUP_HELP --> MI_ABOUT["TMenuItem: About"] style MENUBAR fill:#1c2129,stroke:#58a6ff,stroke-width:2px,color:#e6edf3 style MI_FILE fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3 style MI_EDIT fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3 style MI_HELP fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3
(Menu Bar)"] MENUBAR --> MI_FILE["TMenuItem
&File"] MENUBAR --> MI_EDIT["TMenuItem
&Edit"] MENUBAR --> MI_HELP["TMenuItem
&Help"] MI_FILE --> POPUP_FILE["TMenu
(Popup)"] POPUP_FILE --> MI_NEW["TMenuItem: New"] POPUP_FILE --> MI_OPEN["TMenuItem: Open"] POPUP_FILE --> MI_SEP["Separator"] POPUP_FILE --> MI_EXIT["TMenuItem: Exit"] MI_EDIT --> POPUP_EDIT["TMenu
(Popup)"] POPUP_EDIT --> MI_CUT["TMenuItem: Cut"] POPUP_EDIT --> MI_COPY["TMenuItem: Copy"] POPUP_EDIT --> MI_PASTE["TMenuItem: Paste"] MI_HELP --> POPUP_HELP["TMenu
(Popup)"] POPUP_HELP --> MI_ABOUT["TMenuItem: About"] style MENUBAR fill:#1c2129,stroke:#58a6ff,stroke-width:2px,color:#e6edf3 style MI_FILE fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3 style MI_EDIT fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3 style MI_HELP fill:#1c2129,stroke:#3fb950,stroke-width:1px,color:#e6edf3
TMenu Key Properties
| Property | Type | Description |
|---|---|---|
aMenuItems | Array | Array of TMenuItem objects in this menu |
oWnd | Object | Parent window that owns the menu |
hMenu | Handle | Windows HMENU handle |
l2007 | Logical | Office 2007 visual style |
l2010 | Logical | Office 2010 visual style |
l2013 | Logical | Office 2013 visual style |
l2015 | Logical | Office 2015 (modern flat) visual style |
lPopup | Logical | .T. if this is a popup (context) menu rather than a menu bar |
TMenuItem Key Properties
| Property | Type | Description |
|---|---|---|
cPrompt | String | Text displayed for the item. Use & for accelerator underline. |
bAction | Block | Code block executed when this item is selected |
bWhen | Block | Condition block; item is grayed when it returns .F. |
lChecked | Logical | When .T., a checkmark appears beside the item |
lActive | Logical | When .F., the item is disabled (grayed out) |
oMenu | Object | If this item opens a sub-popup, this points to that TMenu |
cBmpFile | String | Path to a bitmap file shown beside the item |
nVirtKey | Numeric | Virtual key for the keyboard accelerator (e.g. VK_F5) |
Command Syntax
Menu Bar
DEFINE MENU oMenu OF oWnd [ 2007 | 2010 | 2013 | 2015 ]
MENUITEM "&File"
MENU
MENUITEM "&New" ACTION NewDoc() RESOURCE "NEW"
MENUITEM "&Open" ACTION OpenDoc() RESOURCE "OPEN"
SEPARATOR
MENUITEM "E&xit" ACTION oWnd:End()
ENDMENU
MENUITEM "&Edit"
MENU
MENUITEM "Cu&t" ACTION CutText() ACCELERATOR ACC_CTRL, VK_X
MENUITEM "&Copy" ACTION CopyText() ACCELERATOR ACC_CTRL, VK_C
MENUITEM "&Paste" ACTION PasteText() ACCELERATOR ACC_CTRL, VK_V
ENDMENU
ENDMENU
Popup Context Menu
DEFINE MENU oPopup POPUP [ 2015 ]
MENUITEM "Edit" ACTION EditRecord()
MENUITEM "Delete" ACTION DeleteRecord()
SEPARATOR
MENUITEM "Properties" ACTION ShowProperties()
ENDMENU
// Activate on right-click
ACTIVATE POPUP oPopup AT nRow, nCol OF oWnd
Menu Event Lifecycle
sequenceDiagram
participant User
participant Window as TWindow
participant Menu as TMenu
participant Item as TMenuItem
User->>Window: Click on menu bar
Window->>Menu: WM_INITMENUPOPUP
Menu->>Item: Eval( bWhen ) for each item
Item-->>Menu: Enable/Disable items
Menu-->>Window: Display popup
User->>Item: Click menu item
Item->>Item: Check lActive
alt Item is active
Item->>Item: Eval( bAction )
end
Note over Menu,Item: For checkable items,
lChecked is toggled
before bAction fires
lChecked is toggled
before bAction fires
Code Examples
Example 1: Complete Application Menu
#include "FiveWin.ch"
FUNCTION Main()
LOCAL oWnd, oMenu
DEFINE WINDOW oWnd TITLE "Menu Demo" FROM 1, 1 TO 30, 80
DEFINE MENU oMenu OF oWnd 2015
MENUITEM "&File"
MENU
MENUITEM "&New" ACTION NewDoc() RESOURCE "NEW"
MENUITEM "&Open..." ACTION OpenDoc() RESOURCE "OPEN"
MENUITEM "&Save" ACTION SaveDoc() RESOURCE "SAVE"
MENUITEM "Save &As..." ACTION SaveDocAs()
SEPARATOR
MENUITEM "&Print..." ACTION PrintDoc() RESOURCE "PRINT" ;
ACCELERATOR ACC_CTRL, VK_P
SEPARATOR
MENUITEM "Recent Files"
MENU
MENUITEM "Document1.dbf" ACTION OpenRecent( 1 )
MENUITEM "Report2.prg" ACTION OpenRecent( 2 )
MENUITEM "Data3.xls" ACTION OpenRecent( 3 )
ENDMENU
SEPARATOR
MENUITEM "E&xit" ACTION oWnd:End()
ENDMENU
MENUITEM "&Edit"
MENU
MENUITEM "&Undo" ACTION Undo() ACCELERATOR ACC_CTRL, VK_Z
SEPARATOR
MENUITEM "Cu&t" ACTION Cut() ACCELERATOR ACC_CTRL, VK_X
MENUITEM "&Copy" ACTION Copy() ACCELERATOR ACC_CTRL, VK_C
MENUITEM "&Paste" ACTION Paste() ACCELERATOR ACC_CTRL, VK_V
SEPARATOR
MENUITEM "Select &All" ACTION SelectAll() ACCELERATOR ACC_CTRL, VK_A
ENDMENU
MENUITEM "&View"
MENU
MENUITEM "&Toolbar" ACTION ToggleToolbar() CHECK
MENUITEM "&Status Bar" ACTION ToggleStatus() CHECK
SEPARATOR
MENUITEM "&Refresh" ACTION Refresh() ACCELERATOR 0, VK_F5
ENDMENU
MENUITEM "&Help"
MENU
MENUITEM "&Contents" ACTION HelpContents() ACCELERATOR 0, VK_F1
MENUITEM "&About..." ACTION MsgAbout()
ENDMENU
ENDMENU
SET MESSAGE OF oWnd TO "Ready" CENTERED
ACTIVATE WINDOW oWnd
RETURN NIL
Example 2: Right-Click Context Menu
#include "FiveWin.ch"
FUNCTION SetupContextMenu( oWnd, oBrw )
// Assign to the browse's right-click event
oBrw:bRClicked := {|nRow, nCol| ShowContextMenu( oWnd, oBrw, nRow, nCol ) }
RETURN NIL
FUNCTION ShowContextMenu( oWnd, oBrw, nRow, nCol )
LOCAL oMenu
DEFINE MENU oMenu POPUP 2015
MENUITEM "&Edit Record" ACTION EditCurrentRecord( oBrw )
MENUITEM "&Delete Record" ACTION DeleteCurrentRecord( oBrw ) ;
WHEN ( !oBrw:cAlias->( Eof() ) )
SEPARATOR
MENUITEM "&Copy Row" ACTION oBrw:ClipRow()
MENUITEM "Copy &All" ACTION oBrw:ToClip()
SEPARATOR
MENUITEM "Export to &Excel" ACTION oBrw:ToExcel()
MENUITEM "Export to &CSV" ACTION ExportCSV( oBrw )
SEPARATOR
MENUITEM "&Print..." ACTION oBrw:Report()
ENDMENU
ACTIVATE POPUP oMenu AT nRow, nCol OF oWnd
RETURN NIL
Example 3: Dynamic Menu with bWhen
#include "FiveWin.ch"
FUNCTION BuildDynamicMenu( oWnd )
LOCAL oMenu, oMI_Save, oMI_Paste
DEFINE MENU oMenu OF oWnd 2013
MENUITEM "&File"
MENU
MENUITEM "&Save" ACTION SaveDoc() ;
WHEN ( lDocModified ) ; // grayed when doc is unchanged
MESSAGE "Save current document"
MENUITEM "E&xit" ACTION oWnd:End()
ENDMENU
MENUITEM "&Edit"
MENU
MENUITEM "&Paste" ACTION PasteText() ;
WHEN ( !Empty( GetClipboardText() ) ) // grayed when clipboard is empty
ENDMENU
ENDMENU
RETURN NIL
Visual Styles
FiveWin supports multiple menu rendering styles controlled by flags on the DEFINE MENU command:
| Style | Appearance |
|---|---|
| (default) | Classic Windows look |
2007 | Office 2007 gradient with rounded selections |
2010 | Office 2010 softer gradient |
2013 | Office 2013 flat with colored accent bar |
2015 | Modern flat appearance, recommended for new applications |
Tips
- Use
&inMENUITEMtext to set the Alt-key accelerator:"&File"means Alt+F. - Use
ACCELERATORto assign keyboard shortcuts like Ctrl+S, F5, etc. - The
CHECKclause makes a menu item toggleable; each click flipslChecked. - Use
RESOURCEorFILENAMEto display a small icon beside the menu item. - The
bWhenblock is evaluated each time the popup opens, so items gray/ungray dynamically. - For very long menus, consider nested
MENU...ENDMENUblocks to create sub-popups.
Ver También
- TWindow -- menus are attached to windows
- TButton / TBtnBmp -- toolbar buttons often mirror menu actions
- Commands -- full command reference