RASHAD may have the better solution.
This is what I have been using quite successfully. You MUST compile and run the sample for it top work properly.
Code: Select all
; Sample code I built from bits and pieces collected from this forum
; to illustrate how to force single instance of your app.
; YOU MUST compile and run this sample to see it work properly!!!
; Pay attention to these two globals:
Global windowname$ = "One Instance" ; Full display name for the window.
Global TargetName$ = "One Instanc" ; first 11 characters to satisfy Gt_Prog() procedure below.
; The following globals and FOUR prodecures MUST BE at the top of your program.
Global targetWindow$, hWin.i, m_hWnd.i, active.W
Procedure ReallySetForegroundWindow(m_hWnd.i)
; http://www.drdobbs.com/184405755
hOtherWnd.i = GetForegroundWindow_()
;
; get thread handles on our window and foreground window
hMyThread.i = GetWindowThreadProcessId_(m_hWnd, 0)
hOtherThread.i = GetWindowThreadProcessId_(hOtherWnd,0)
;
; attach our thread to foreground thread, take foreground, and detach threads
AttachThreadInput_(hMyThread,hOtherThread, #True)
SetForegroundWindow_(m_hWnd)
AttachThreadInput_(hMyThread,hOtherThread, #False)
; AttachThreadInput_(hOtherThread,hMyThread, #True); backward set
; SetForegroundWindow_(m_hWnd)
; AttachThreadInput_(hOtherThread,hMyThread, #False)
;
; Now that our window "thread" has fisrt place in the queue...
; make sure our "window" is visible
If IsIconic_(m_hWnd)
ShowWindow_(m_hWnd,#SW_RESTORE)
Else
ShowWindow_(m_hWnd,#SW_SHOW)
EndIf
SetActiveWindow(GetDlgCtrlID_(m_hWnd))
WaitWindowEvent()
SetForegroundWindow_(m_hWnd)
EndProcedure
Procedure.i ListWindows(Window, Parameter) ; used inside Gt_Prog()
WindowTitle.s = Space(255)
GetWindowText_(Window, WindowTitle, 255)
WindowTitle = LCase(WindowTitle)
If LCase(WindowTitle) = targetWindow$
active.W = 1
hWin.i = Window
ElseIf Left(WindowTitle,11) = targetWindow$
active.W = 1
hWin.i = Window
ElseIf Left(WindowTitle,6) = Left(targetWindow$,6) ; "From: "
If Right(WindowTitle,9) = Right(targetWindow$,9) ; " - E-mail"
If Left(WindowTitle,6) <> Right(targetWindow$,6)
active.W = 1
hWin.i = Window
EndIf
EndIf
EndIf
ProcedureReturn #True
EndProcedure
Procedure Gt_Prog(dmy$) ; input : 11 char PROCESS name , active.w = true if running : hWin.i holds Window handle
targetWindow$ = LCase(dmy$)
active.W = 0
hWin.i = 0
EnumWindows_(@ListWindows(), 0) ; Windows CallBack operation.
ProcedureReturn active.W
EndProcedure
If Gt_Prog("One Instanc") ; Using 1st 11 characters to Prevent 2nd instance if already running
SetForegroundWindow_(hWin.i) ; AND bring current instance into foreground.
ShowWindow_(hWin.i, #SW_RESTORE)
Delay(250)
End ; Quit from this duplicate instance.
EndIf
If OpenWindow(0, 0, 0, 270, 140,windowname$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(0, 40, 20, 250, 20, "Bury this window under other window(s)")
TextGadget(1, 40, 40, 250, 20, "Then TRY to open a 2nd instance", #PB_Text_Center)
TextGadget(2, 40, 70, 250, 20, "It won't happen. You can ONLY")
TextGadget(3, 40, 90, 250, 20, "bring the fhe 1st instace to the top.")
ButtonGadget (4, 80, 110, 100, 20, "CLOSE")
Repeat ; This loop only here to enable and simplify program exit.
Event = WaitWindowEvent() ; Real magic is in the proceedures above.
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 4
Event = #PB_Event_CloseWindow
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
EndIf