` Printed Icetips Article

Icetips Article



Par2: Check for multiple instances of a program
2000-01-16 -- Alexey Solovjev
 
Far ago I posted an example of the program which uses mutex objects to
find another its instance. Attached one is its extension which uses
SetProp/GetProp functions to get a handle of first instance's window
from another program instance (really, in this way mutex objects become
unnecessary).

--------------------------------------------------------------------------------

            PROGRAM

  OMIT ('=== 16 bit', _WIDTH32_)
    This program uses 32 bit specific API calls
! === 16 bit

HANDLE                 EQUATE(UNSIGNED)
HWND                   EQUATE(HANDLE)
DWORD                  EQUATE(LONG)
BOOL                   EQUATE(SIGNED)
LPARAM                 EQUATE(LONG)

SW_RESTORE             EQUATE(9)
ERROR_ALREADY_EXISTS   EQUATE(183)

            MAP
              MODULE('')
                CreateMutex (<*DWORD>, BOOL,
<*CSTRING>),HANDLE,RAW,PASCAL,NAME('CreateMutexA')
                CloseHandle (HANDLE),BOOL,PROC,PASCAL,NAME('CloseHandle')
                GetLastError (),DWORD,PASCAL,NAME('GetLastError')

                GetDesktopWindow (),HWND,PASCAL,NAME('GetDesktopWindow')
                GetWindowText
(HWND,*CSTRING,SIGNED),SIGNED,RAW,PROC,PASCAL,NAME('GetWindowTextA')

                SetProp    (HWND,*CSTRING,HANDLE),BOOL,RAW,PROC,PASCAL,NAME('SetPropA')
                GetProp    (HWND,*CSTRING),HANDLE,RAW,PASCAL,NAME('GetPropA')
                RemoveProp (HWND,*CSTRING),HANDLE,RAW,PROC,PASCAL,NAME('RemovePropA')

                IsIconic            (HWND),BOOL,PASCAL,NAME('IsIconic')
                ShowWindow          (HWND,SIGNED),BOOL,PROC,PASCAL,NAME('ShowWindow')
                SetForegroundWindow (HWND),BOOL,PROC,PASCAL,NAME('SetForegroundWindow')
              END

              ShutProc()
              Main()
              TestInst(),BOOL
              SwitchToOther(),BOOL
            END

IDString    CSTRING('00000ABC000')     ! Some program ID string
AppMutexH   HANDLE(0)
PropSet     BOOL(FALSE)

  CODE
  SHUTDOWN (ShutProc)

  IF  NOT TestInst()
    IF  SwitchToOther()
      RETURN
    END
  END

  Main()

  RETURN

! ===================================================================

ShutProc  PROCEDURE()
  CODE
  IF  AppMutexH <> 0
    CloseHandle (AppMutexH)
    AppMutexH = 0
  END

  IF  PropSet
    RemoveProp (GetDesktopWindow(), IDString)
    PropSet = FALSE
  END

! ===================================================================

TestInst  PROCEDURE()
  CODE
  AppMutexH = CreateMutex (, FALSE, IDString)

  RETURN CHOOSE (GetLastError() <> ERROR_ALREADY_EXISTS)

! ===================================================================

SwitchToOther  PROCEDURE()

OtherInstFrame  HWND,AUTO
Info            CSTRING(128),AUTO

  CODE
  OtherInstFrame = GetProp (GetDesktopWindow(), IDString)

  IF  OtherInstFrame = 0
    MESSAGE ('Property is FALSE')
    RETURN FALSE
  END

  GetWindowText (OtherInstFrame, Info, SIZE (Info))
  MESSAGE (Info, OtherInstFrame)

  SetForegroundWindow (OtherInstFrame)

  IF  IsIconic (OtherInstFrame)
    ShowWindow (OtherInstFrame, SW_RESTORE)
  END

  RETURN TRUE

! ===================================================================

Main  PROCEDURE()

W0   APPLICATION('One Instance Test Program'),AT(,,280,100),FONT('MS Sans
Serif',8,,FONT:regular),SYSTEM, |
         RESIZE,ICON(ICON:Application),MAX
       TOOLBAR,AT(0,0,,30)
         BUTTON('&Close'),AT(8,7,45,14),USE(?Close),STD(STD:Close)
       END
     END

hWnd    HWND,AUTO

  CODE
  OPEN (W0)

  hWnd = W0 {PROP:Handle}

  SetProp (GetDesktopWindow(), IDString, hWnd)
  PropSet = TRUE

  W0 {PROP:Text} = W0 {PROP:Text} & ' - ' & hWnd

  ACCEPT
  END

  CLOSE (W0)



Printed May 3, 2024, 6:49 pm
This article has been viewed/printed 35119 times.