;
; MENU.ASM - Sample API using menu functions.
;
; Fox Software System's Group
;
; Copyright (c) 1991 Fox Software, Inc.
; 134 W. South Boundary
; Perrysburg, Ohio  43551
;
; Description: On load places a new pad "Display" on the system menu
;   bar with items to switch between 25 and 50 row display.
;


                .MODEL large
                .STACK 0                 ; need no stack of our own

                INCLUDE pro_ext.inc


 .DATA

                PUBLIC  _myFoxInfo
                PUBLIC  __FoxTable

StartUpName        DB "STARTUP", 0
StartUpParmTypes   DB "C", 0

ShutDownName       DB "SHUTDOWN", 0
ShutDownParmTypes  DB "C", 0

_myFoxInfo FoxInfo <StartUpName,  StartUp,  CALLONLOAD,   StartUpParmTypes>
           FoxInfo <ShutDownName, ShutDown, CALLONUNLOAD, ShutDownParmTypes>

sizeof_myFoxInfo = $ - _myFoxInfo

__FoxTable FoxTable <0, sizeof_myFoxInfo/TYPE FoxInfo, _myFoxInfo>


PadPrompt       DB "Displa\<y", 0
Bar1_Prompt     DB "VGA \<50", 0
Bar2_Prompt     DB "VGA \<25", 0
NullString      DB 0
Alt5_String     DB "Alt+5", 0
Alt2_String     DB "Alt+2", 0
DispVGA25       DB "SET DISP TO VGA25", 0
DispVGA50       DB "SET DISP TO VGA50", 0


 .DATA?


SysMenuId       DW 2 DUP(?)     ;typedef long MENUID
PopupId         DW 2 DUP(?)     ;typedef long MENUID
PadId           DW 2 DUP(?)     ;typedef long ITEMID


 .CODE


SetDispVGA25 PROC FAR

            FarEnter

            push    ax
            push    dx
;
;       _Execute("SET DISP TO VGA25")
;
            mov     dx, @data
            mov     ax, offset DispVGA25

            call    _Execute

            pop     dx
            pop     ax

            FarExit

            ret
SetDispVGA25 ENDP



SetDispVGA50 PROC FAR

            FarEnter

            push    ax
            push    dx
;
;       _Execute("SET DISP TO VGA50")
;
            mov     dx, @data
            mov     ax, offset DispVGA50

            call    _Execute

            pop     dx
            pop     ax

            FarExit

            ret
SetDispVGA50 ENDP


StartUp PROC FAR

            FarEnter                    ; bp := sp
;
;       ITEMID Bar1_Id
;       ITEMID Bar2_Id
;
Bar1_Id = -sizeof_ITEMID
Bar2_Id = Bar1_Id-sizeof_ITEMID

            sub     sp, 2*sizeof_ITEMID

            push    ax
            push    bx
            push    cx
            push    dx
            push    ds

            mov     ax, @data
            mov     ds, ax
;
;   Add a new pad to SYSMENU
;
;       SysMenuId = _MenuId(_SYSMENU)
;
            mov     ax, _SYSMENU

            _MenuId                         ; dx:ax := _MenuId(ax)

            mov     [SysMenuId], ax
            mov     [SysMenuId+2], dx

;
;       PadId = _GetNewItemId(SysMenuId)
;
            _GetNewItemId                   ; dx:ax := _GetNewItemId(dx:ax)

            mov     [PadId], ax
            mov     [PadId+2], dx
;
;       if (_NewItem(SysMenuId, PadId, _LASTITEM, "Displa\\<y"))
;       {
;           _Error(623); /* "Menu item cannot be defined." */
;       }
;
            mov     bx, ax                  ; cx:bx := ITEMID PadId
            mov     cx, dx

            mov     ax, offset PadPrompt    ; push char FAR * PadPrompt

            push    ds
            push    ax

            mov     ax, _LASTITEM           ; push ITEMID _LASTITEM
            cwd
            push    dx
            push    ax

            mov     ax, [SysMenuId]
            mov     dx, [SysMenuId+2]

            call    _NewItem

            or      ax, ax
            jz      L1

            mov     ax,  623                ; "Menu item cannot be defined."
            call    _Error
L1:
;
;   Define popup menu.
;
;       PopupId = _GetNewMenuId();
;
            _GetNewMenuId

            mov     [PopupId], ax
            mov     [PopupId+2], dx
;
;       if (Error = _NewMenu(MPOPUP, PopupId))
;       {
;           _Error(-Error);
;       }
;
            mov     bx, ax
            mov     cx, dx

            mov     ax, MPOPUP

            call    _NewMenu

            or      ax, ax
            jz      L2

            neg     ax
            call    _Error
L2:
;
;       Bar1_Id = _GetNewItemId(PopupId);
;
            mov     ax, [PopupId]           ; dx:ax := PopupId
            mov     dx, [PopupId+2]

            _GetNewItemId

            mov     [bp+Bar1_Id], ax
            mov     [bp+Bar1_Id+2], dx
;
;   WARNING: Call _NewItem() before another _GetNewItemId().
;
;       if (_NewItem(PopupId, Bar1_Id, _LASTITEM, "VGA \\<50"))
;       {
;           _Error(623); /* "Menu item cannot be defined." */
;       }
;
            mov     bx, ax                  ; cx:bx := ITEMID Bar1_Id
            mov     cx, dx

            mov     ax, offset Bar1_Prompt  ; push char FAR * Bar1_Prompt

            push    ds
            push    ax

            mov     ax, _LASTITEM           ; push ITEMID _LASTITEM
            cwd
            push    dx
            push    ax

            mov     ax, [PopupId]
            mov     dx, [PopupId+2]

            call    _NewItem

            or      ax, ax
            jz      L3

            mov     ax,  623                ; "Menu item cannot be defined."
            call    _Error
L3:
;
;       Bar2_Id = _GetNewItemId(PopupId);
;
            mov     ax, [PopupId]           ; dx:ax := PopupId
            mov     dx, [PopupId+2]

            _GetNewItemId

            mov     [bp+Bar2_Id], ax
            mov     [bp+Bar2_Id+2], dx
;
;       if (_NewItem(PopupId, Bar2_Id, _LASTITEM, "VGA \\<25"))
;       {
;           _Error(623); /* "Menu item cannot be defined." */
;       }
;
            mov     bx, ax                  ; cx:bx := ITEMID Bar2_Id
            mov     cx, dx

            mov     ax, offset Bar2_Prompt  ; push char FAR * Bar2_Prompt
            push    ds
            push    ax

            mov     ax, _LASTITEM           ; push ITEMID _LASTITEM
            cwd
            push    dx
            push    ax

            mov     ax, [PopupId]
            mov     dx, [PopupId+2]

            call    _NewItem

            or      ax, ax
            jz      L4

            mov     ax,  623                ; "Menu item cannot be defined."
            call    _Error
L4:
;
;   Attach popup to pad.
;
;       _SetItemSubMenu(SysMenuId, PadId, PopupId);
;
            mov     ax, [PopupId]
            mov     dx, [PopupId+2]
            push    dx
            push    ax

            mov     bx, [PadId]
            mov     cx, [PadId+2]

            mov     ax, [SysMenuId]
            mov     dx, [SysMenuId+2]

            call    _SetItemSubMenu
;
;   Set up keyboard shortcuts.
;
;       _SetItemCmdKey(SysMenuId, PadId, 0x4100 |  21, "");
;
            mov     ax, offset NullString

            push    ds
            push    ax

            mov     ax, 4100h or 21
            push    ax

            mov     bx, [PadId]
            mov     cx, [PadId+2]

            mov     ax, [SysMenuId]
            mov     dx, [SysMenuId+2]

            call    _SetItemCmdKey
;
;       _SetItemCmdKey(PopupId, Bar1_Id, 0x4100 | 124, "Alt+5");
;
            mov     ax, offset Alt5_String

            push    ds
            push    ax

            mov     ax, 4100h or 124
            push    ax

            mov     bx, [bp+Bar1_Id]
            mov     cx, [bp+Bar1_Id+2]

            mov     ax, [PopupId]
            mov     dx, [PopupId+2]

            call    _SetItemCmdKey
;
;       _SetItemCmdKey(PopupId, Bar2_Id, 0x4100 | 121, "Alt+2");
;
            mov     ax, offset Alt2_String
            push    ds
            push    ax

            mov     ax, 4100h or 121
            push    ax

            mov     bx, [bp+Bar2_Id]
            mov     cx, [bp+Bar2_Id+2]

            mov     ax, [PopupId]
            mov     dx, [PopupId+2]

            call    _SetItemCmdKey
;
;   Set up selection action.
;
;       _OnSelection(PopupId, Bar1_Id, SetDispVGA50);
;
            mov     ax, offset SetDispVGA50
            push    cs
            push    ax

            mov     bx, [bp+Bar1_Id]
            mov     cx, [bp+Bar1_Id+2]

            mov     ax, [PopupId]
            mov     dx, [PopupId+2]

            call    _OnSelection
;
;       _OnSelection(PopupId, Bar2_Id, SetDispVGA25);
;
            mov     ax, offset SetDispVGA25
            push    cs
            push    ax

            mov     bx, [bp+Bar2_Id]
            mov     cx, [bp+Bar2_Id+2]

            mov     ax, [PopupId]
            mov     dx, [PopupId+2]

            call    _OnSelection

            pop     ds
            pop     dx
            pop     cx
            pop     bx
            pop     ax

            add     sp, 2*sizeof_ITEMID

            FarExit

            ret
StartUp     ENDP


ShutDown PROC FAR

            FarEnter

            push    ax
            push    bx
            push    cx
            push    dx
            push    ds

            mov     ax, @data
            mov     ds, ax
;
;       _DisposeItem(SysMenuId, PadId);
;
            mov     bx, [PadId]
            mov     cx, [PadId+2]
            mov     ax, [SysMenuId]
            mov     dx, [SysMenuId+2]

            call    _DisposeItem
;
;       _DisposeMenu(PopupId);
;
            mov     ax, [PopupId]
            mov     dx, [PopupId+2]

            pop     ds
            pop     dx
            pop     cx
            pop     bx
            pop     ax

            FarExit

            ret
ShutDown    ENDP
            END