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.