## Adding Menu Items to the System Menu

The System Menu, ( also called the window menu, or control menu ) is accessed by the user when the program icon is 'clicked', or the [ ALT SPACE ] keyboard combination is used.

The following example will show you how to add your own menu items to this, and how to handle the messages which Windows sends to your application if any of these items are 'selected' by the user.

.

-- system-menu.exw

    -- Simple timer,  and a trick system menu !

    include win32lib.ew
    without warning

    atom jk
    integer ticks
    ticks = 0

    constant
    zWM_SYSCOMMAND = 274,

    SysMenu_Reset = WM_USER + 100,  -- your two user defined messages
    SysMenu_About = WM_USER + 101,

    PWin = create( Window, "<< SYSTEM-MENU", 0, Default, Default, 250, 120, 0 ),
    note = create( LText, "^^ Click on the program's icon!", PWin, 3, 3, 230, 20, 0 ),
    timerdisp = create( RText, "0", PWin, 10, 30, 225, 42, 0 ),
    MyTimer = 1

    setFont( note, "Arial", 10, or_all( {Bold, Italic} ) )
    setFont( timerdisp, "Arial", 28, Bold )

    -- the next two functions access our program's system menu.

    function GetSystemMenu( atom hWnd,  atom bRevert )
      return w32Func( xGetSystemMenu, {hWnd, bRevert} )
    end function

    function AppendMenu( atom hmenu, sequence new_item )
    atom ptr
      ptr = allocate_string( new_item[3] )
      return  w32Func( xAppendMenu, {hmenu, new_item[1], new_item[2], ptr} )
      free( ptr )
    end function

    atom hSysMenu

    -- get the handle of this program's system menu,
    hSysMenu = GetSystemMenu( getHandle( PWin ), 0 )
    -- then add a separator, and 2 new items to the system menu
    jk = AppendMenu( hSysMenu, {MF_SEPARATOR, 0, ""} )
    jk = AppendMenu( hSysMenu, {MF_STRING, SysMenu_Reset, "Reset count"} )
    jk = AppendMenu( hSysMenu, {MF_STRING, SysMenu_About, "What's this?"} )

    -- update our timer display every second.
    procedure onTimer_PWin(  integer self,  integer event,  sequence params  )
      ticks = ticks + 1
      setText( timerdisp, sprintf( "%d", {ticks} ) )
    end procedure

    procedure onOpen_PWin(  integer self,  integer event,  sequence params  )
      setTimer(  PWin,  MyTimer,  1000  )
    end procedure

    procedure about()
    jk = message_box(  "A simple timer demo, \n\n" &
      "with two added items in the system menu.\n" &
      "-- using code originally by Jacques Deschênes --",
      "... a Win32 Tutorial about 'messages'.", #2000 )
    end procedure

    procedure reset()
      killTimer( PWin, MyTimer )
      ticks=0
      setText( timerdisp, sprintf( "%d", {ticks} ) )
      setTimer(  PWin,  MyTimer,  1000  )
    end procedure

    -- and here's our private event handler,
    -- which tells our program what to do when it
    -- receives a zWM_SYSCOMMAND message from Windows,
    -- with our user defined message in the low word of wParam.
    procedure onEvent_PWin(  integer self,  integer event,  sequence params  )
    atom cmd
        event = params[1]    -- cheat old code
        atom wParam = params[2]

        if event = zWM_SYSCOMMAND then  -- *this
            -- use only low word of wParam, just in case...
            cmd = lo_word( wParam )
            if cmd = SysMenu_About then
                about()
            elsif cmd = SysMenu_Reset then
                reset()
            end if
        end if  -- *and this

    end procedure

    --

    setHandler(  PWin,  w32HOpen,  routine_id(  "onOpen_PWin"  )  )
    setHandler(  PWin,  w32HTimer,  routine_id(  "onTimer_PWin"  )  )
    setHandler(  PWin,  w32HEvent,  routine_id(  "onEvent_PWin"  )  )

    WinMain( PWin, Normal )
    -----------

If you want to understand a bit more about handling Windows messages, try commenting out the two lines marked in red above, in the program's code. If you do so, notice what happens when your 'mouse' cursor moves over either of the two system menu items which have been added to this program. No 'clicking' required !

I should point out that any private messages your programs use should be between WM_USER, ( #400 ), and #7FFF, since all other values are reserved for use by Windows itself.
( ... with apparently, some further restrictions ? ...if your button or other control suddenly doesn't work, you've probably found one. )

..end of lesson.

CONTENTS