These two little demo's illustrate how one can write a program so that only one copy can be running at the same time. If one tries to start a second copy, it will detect the presence of the first, and shut down.
This feature has been added by using the same FindWindowA() function we used in the previous examples.
Since the first example is so short, I've added two lines at the beginning of the check_self() procedure, which insert the default Euphoria icon into this program's title bar.
--
kick-it3.exw
-- start demo --
include win32lib.ew
atom ptr, ptr2, ok, proghwnd
constant
-- new functions !
zFindWindow = registerw32Function( user32, "FindWindowA", {C_POINTER, C_INT}, C_INT ),
-- ok, the above func is now in win32lib !
zBeep = registerw32Function( user32, "MessageBeep", {C_INT}, C_INT )
ptr = allocate_string( "Win32Lib AppWindow 1" ) -- classname
ptr2 = allocate_string( "kick_self" ) -- title
-- first, try and find a window using:
-- classname and title, as in above strings.
proghwnd = w32Func( zFindWindow, { ptr, ptr2 } )
constant
Win = create( Window, "kick_self", 0, Default, Default, 300, 100, 0 )
procedure check_self( integer self, integer event, sequence params )
-- get the default Euphoria icon from exw.exe,
ok = w32Func( xLoadIcon, { instance( ), allocate_string( "exw" ) } )
-- and insert it in this program's title bar.
ok = sendMessage( Win, 128, 0, ok )
if proghwnd != 0 then
ok = w32Func( zBeep, { 0 } )
-- just to test, lets see/report this instance for 3 seconds...
setVisible( Win, 1 )
setFont( Win, "System", 10, 1 )
setPenPos( Win, 1, 1 )
wPuts( Win, "...another instance found, so good-bye." )
sleep( 3 )
-- set focus to first instance
ok = w32Func( xSetForegroundWindow, {proghwnd} )
-- closeWindow( Win ) -- no longer works here !!!???
abort( 0 ) -- I'd rather closeWindow() than abort,
-- but only this works now.
end if
end procedure
setHandler( Win, w32HOpen, routine_id( "check_self" ) )
WinMain( Win, Normal )
-- end demo --
The second example uses the CreateSemaphore() function to do essentially the same thing... detect if an instance of this program is already running. Since semaphores are actually used as simple objects to communicate between different applications, the CreateSemaphore() function will return an error message if the same semaphore already exists.
This error message can be retrieved by the GetLastError() function, so we'll know our previous instance has already created the semaphore, and shut down the second instance of our program.
--
kick-it4.exw
-- start demo --
include win32lib.ew
atom ptr, ptr2, ok, proghwnd
constant
-- new functions !
zCreateSemaphore = registerw32Function( kernel32, "CreateSemaphoreA", {C_POINTER, C_INT, C_INT, C_POINTER}, C_INT ),
zGetLastError = registerw32Function( kernel32, "GetLastError", {}, C_INT ),
zBeep = registerw32Function( user32, "MessageBeep", {C_INT}, C_INT ),
zERROR_ALREADY_EXISTS = 183
ptr = allocate_string( "Win32Lib AppWindow 1" ) -- classname
ptr2 = allocate_string( "..using a semaphore" ) -- title
-- first, try and find a window using:
-- classname and title, as in above strings,
-- *before* we create THIS window.
proghwnd = w32Func( xFindWindow, { ptr, ptr2 } )
constant
Win = create( Window, "..using a semaphore", 0, Default, Default, 300, 100, 0 )
procedure check_self( integer self, integer event, sequence params )
-- create a semaphore for this instance, using pointer to classname
ok = w32Func( zCreateSemaphore, {NULL, 0, 1, ptr} )
ok = w32Func( zGetLastError, {} )
if ok = zERROR_ALREADY_EXISTS then
ok = w32Func( zBeep, { 0 } )
setText( Win, "..semaphore found !" )
-- just to test, lets see/report this instance for 3 seconds...
setVisible( Win, 1 )
setFont( Win, "System", 10, 1 )
setPenPos( Win, 1, 1 )
wPuts( Win, "...another instance found, so good-bye." )
sleep( 3 )
-- set focus to first instance
ok = w32Func( xSetForegroundWindow, {proghwnd} )
abort( 0 ) -- and quit.
end if
end procedure
setHandler( Win, w32HOpen, routine_id( "check_self" ) )
------------------------------------------------------
WinMain( Win, Normal )
-- end second demo --...end...