1
1
Fork 0
mirror of https://github.com/FellippeHeitor/InForm.git synced 2025-01-15 03:49:56 +00:00

Implements single-instance mode for the editor.

Launching the binary while another instance is already open will instruct the existing instance to open a new file or simply to come forward (in Windows).
This commit is contained in:
FellippeHeitor 2018-06-17 00:39:44 -03:00
parent 52de6bae6d
commit a9e6626ca7
2 changed files with 113 additions and 21 deletions

View file

@ -207,6 +207,7 @@ DIM SHARED __UI_SnappedXID AS LONG, __UI_SnappedYID AS LONG
DIM SHARED __UI_SnapLines AS _BYTE, __UI_SnapDistance AS INTEGER, __UI_SnapDistanceFromForm AS INTEGER DIM SHARED __UI_SnapLines AS _BYTE, __UI_SnapDistance AS INTEGER, __UI_SnapDistanceFromForm AS INTEGER
DIM SHARED __UI_FrameRate AS SINGLE, __UI_Font8Offset AS INTEGER, __UI_Font16Offset AS INTEGER DIM SHARED __UI_FrameRate AS SINGLE, __UI_Font8Offset AS INTEGER, __UI_Font16Offset AS INTEGER
DIM SHARED __UI_ClipboardCheck$, __UI_MenuBarOffsetV AS INTEGER DIM SHARED __UI_ClipboardCheck$, __UI_MenuBarOffsetV AS INTEGER
DIM SHARED __UI_KeepScreenHidden AS _BYTE
'Control types: 'Control types:
DIM SHARED __UI_Type(0 TO 18) AS __UI_Types DIM SHARED __UI_Type(0 TO 18) AS __UI_Types
@ -478,7 +479,7 @@ SUB __UI_Init
__UI_BeforeInit __UI_BeforeInit
_SCREENSHOW IF __UI_KeepScreenHidden = False THEN _SCREENSHOW
IF __UI_FormID = 0 THEN SYSTEM IF __UI_FormID = 0 THEN SYSTEM

View file

@ -121,6 +121,7 @@ DIM SHARED UiEditorTitle$, Edited AS _BYTE, ZOrderingDialogOpen AS _BYTE
DIM SHARED OpenDialogOpen AS _BYTE, OverwriteOldFiles AS _BYTE DIM SHARED OpenDialogOpen AS _BYTE, OverwriteOldFiles AS _BYTE
DIM SHARED RevertEdit AS _BYTE, OldColor AS _UNSIGNED LONG DIM SHARED RevertEdit AS _BYTE, OldColor AS _UNSIGNED LONG
DIM SHARED ColorPreviewWord$, BlinkStatusBar AS SINGLE, StatusBarBackColor AS _UNSIGNED LONG DIM SHARED ColorPreviewWord$, BlinkStatusBar AS SINGLE, StatusBarBackColor AS _UNSIGNED LONG
DIM SHARED InstanceHost AS LONG, InstanceClient AS LONG
DIM SHARED HostPort AS STRING, Host AS LONG, Client AS LONG DIM SHARED HostPort AS STRING, Host AS LONG, Client AS LONG
DIM SHARED Stream$, FormDataReceived AS _BYTE, LastFormData$ DIM SHARED Stream$, FormDataReceived AS _BYTE, LastFormData$
DIM SHARED prevScreenX AS INTEGER, prevScreenY AS INTEGER DIM SHARED prevScreenX AS INTEGER, prevScreenY AS INTEGER
@ -177,6 +178,10 @@ $IF WIN THEN
FUNCTION GetExitCodeProcess& (BYVAL hProcess AS LONG, lpExitCode AS LONG) FUNCTION GetExitCodeProcess& (BYVAL hProcess AS LONG, lpExitCode AS LONG)
END DECLARE END DECLARE
DECLARE DYNAMIC LIBRARY "user32"
FUNCTION SetForegroundWindow& (BYVAL hWnd AS LONG)
END DECLARE
''Registry routines taken from the Wiki: http://www.qb64.net/wiki/index.php/Windows_Libraries#Registered_Fonts ''Registry routines taken from the Wiki: http://www.qb64.net/wiki/index.php/Windows_Libraries#Registered_Fonts
''Code courtesy of Michael Calkins ''Code courtesy of Michael Calkins
''winreg.h ''winreg.h
@ -834,11 +839,13 @@ END SUB
SUB __UI_BeforeUpdateDisplay SUB __UI_BeforeUpdateDisplay
DIM b$, c$ DIM b$, c$
DIM i AS LONG, j AS LONG, Answer AS _BYTE DIM i AS LONG, j AS LONG, Answer AS _BYTE
DIM incomingData$, Signal$
DIM thisData$, thisCommand$
STATIC OriginalImageWidth AS INTEGER, OriginalImageHeight AS INTEGER STATIC OriginalImageWidth AS INTEGER, OriginalImageHeight AS INTEGER
STATIC PrevFirstSelected AS LONG, PreviewHasMenuActive AS INTEGER STATIC PrevFirstSelected AS LONG, PreviewHasMenuActive AS INTEGER
STATIC CheckUpdateDone AS _BYTE STATIC CheckUpdateDone AS _BYTE
STATIC LastChange AS SINGLE STATIC LastChange AS SINGLE
IF TIMER - BlinkStatusBar < 1 THEN IF TIMER - BlinkStatusBar < 1 THEN
IF TIMER - LastChange > .2 THEN IF TIMER - LastChange > .2 THEN
IF Control(StatusBar).BackColor = StatusBarBackColor THEN IF Control(StatusBar).BackColor = StatusBarBackColor THEN
@ -858,6 +865,64 @@ SUB __UI_BeforeUpdateDisplay
IF Caption(StatusBar) = "" THEN Caption(StatusBar) = "Ready." IF Caption(StatusBar) = "" THEN Caption(StatusBar) = "Ready."
END IF END IF
'Check if another instance was launched and is passing
'parameters:
STATIC BringToFront AS _BYTE, InstanceStream$
IF InstanceClient THEN
IF BringToFront = False THEN
$IF WIN THEN
i = SetForegroundWindow&(_WINDOWHANDLE)
$END IF
BringToFront = True
END IF
GET #InstanceClient, , incomingData$
InstanceStream$ = InstanceStream$ + incomingData$
IF INSTR(InstanceStream$, "<END>") THEN
IF LEFT$(InstanceStream$, 12) = "NEWINSTANCE>" THEN
InstanceStream$ = MID$(InstanceStream$, 13)
InstanceStream$ = LEFT$(InstanceStream$, INSTR(InstanceStream$, "<END>") - 1)
IF _FILEEXISTS(InstanceStream$) THEN
IF INSTR(InstanceStream$, "/") > 0 OR INSTR(InstanceStream$, "\") > 0 THEN
FOR i = LEN(InstanceStream$) TO 1 STEP -1
IF ASC(InstanceStream$, i) = 92 OR ASC(InstanceStream$, i) = 47 THEN
CurrentPath$ = LEFT$(InstanceStream$, i - 1)
InstanceStream$ = MID$(InstanceStream$, i + 1)
EXIT FOR
END IF
NEXT
END IF
IF Edited THEN
$IF WIN THEN
Answer = MessageBox("Save the current form?", "", MsgBox_YesNoCancel + MsgBox_Question)
$ELSE
Answer = MessageBox("Save the current form?", "", MsgBox_YesNo + MsgBox_Question)
$END IF
IF Answer = MsgBox_Cancel THEN
CLOSE InstanceClient
InstanceClient = 0
EXIT SUB
ELSEIF Answer = MsgBox_Yes THEN
SaveForm False, False
END IF
END IF
Text(FileNameTextBox) = InstanceStream$
OpenDialogOpen = True
__UI_Click OpenBT
END IF
END IF
CLOSE InstanceClient
InstanceClient = 0
END IF
ELSE
InstanceClient = _OPENCONNECTION(InstanceHost)
BringToFront = False
InstanceStream$ = ""
END IF
IF CheckUpdates THEN IF CheckUpdates THEN
IF CheckUpdateDone = False THEN IF CheckUpdateDone = False THEN
STATIC ThisStep AS INTEGER STATIC ThisStep AS INTEGER
@ -932,8 +997,6 @@ SUB __UI_BeforeUpdateDisplay
CheckPreview CheckPreview
DIM incomingData$, Signal$
GET #Client, , incomingData$ GET #Client, , incomingData$
Stream$ = Stream$ + incomingData$ Stream$ = Stream$ + incomingData$
STATIC bytesIn~&&, refreshes~& STATIC bytesIn~&&, refreshes~&
@ -995,7 +1058,6 @@ SUB __UI_BeforeUpdateDisplay
END IF END IF
SignalsFirstSent = True SignalsFirstSent = True
DIM thisData$, thisCommand$
DO WHILE INSTR(Stream$, "<END>") > 0 DO WHILE INSTR(Stream$, "<END>") > 0
thisData$ = LEFT$(Stream$, INSTR(Stream$, "<END>") - 1) thisData$ = LEFT$(Stream$, INSTR(Stream$, "<END>") - 1)
Stream$ = MID$(Stream$, INSTR(Stream$, "<END>") + 5) Stream$ = MID$(Stream$, INSTR(Stream$, "<END>") + 5)
@ -1979,6 +2041,7 @@ SUB SaveSettings
END SUB END SUB
SUB __UI_BeforeInit SUB __UI_BeforeInit
__UI_KeepScreenHidden = True
END SUB END SUB
SUB __UI_FormResized SUB __UI_FormResized
@ -2029,6 +2092,50 @@ SUB __UI_OnLoad
GOSUB ShowMessage GOSUB ShowMessage
b$ = "Opening communication port (click 'unblock' if your Operating System asks)..."
GOSUB ShowMessage
DIM HostAttempts AS INTEGER
DO
HostAttempts = HostAttempts + 1
InstanceHost = _OPENHOST("TCP/IP:60680") '60680 = #ED08, as the functionality was implemented in Beta 8 of the EDitor ;-)
LOOP UNTIL InstanceHost <> 0 OR HostAttempts > 1000
IF InstanceHost = 0 THEN
'There is probably another instance of InForm Designer running.
'(i) attempt to communicate and pass parameters and
'(ii) bring it to the front.
HostAttempts = 0
DO
HostAttempts = HostAttempts + 1
Host = _OPENCLIENT("TCP/IP:60680:localhost")
LOOP UNTIL Host <> 0 OR HostAttempts > 1000
IF Host THEN
b$ = "NEWINSTANCE>" + COMMAND$ + "<END>"
Send Host, b$
_DELAY 1
CLOSE Host
END IF
SYSTEM
END IF
_SCREENSHOW
RANDOMIZE TIMER
HostAttempts = 0
DO
HostAttempts = HostAttempts + 1
HostPort = LTRIM$(STR$(INT(RND * 5000 + 60000)))
Host = _OPENHOST("TCP/IP:" + HostPort)
LOOP UNTIL Host <> 0 OR HostAttempts > 1000
IF Host = 0 THEN
DIM Answer AS _BYTE
Answer = MessageBox("Unable to open communication port.", "", MsgBox_OkOnly + MsgBox_Critical)
SYSTEM
END IF
PreviewAttached = True PreviewAttached = True
AutoNameControls = True AutoNameControls = True
CheckUpdates = True CheckUpdates = True
@ -2175,22 +2282,6 @@ SUB __UI_OnLoad
END IF END IF
END IF END IF
b$ = "Starting host (click 'unblock' if your Operating System asks)..."
GOSUB ShowMessage
DIM HostAttempts AS INTEGER
RANDOMIZE TIMER
DO
HostAttempts = HostAttempts + 1
HostPort = LTRIM$(STR$(INT(RND * 5000 + 60000)))
Host = _OPENHOST("TCP/IP:" + HostPort)
LOOP UNTIL Host <> 0 OR HostAttempts > 1000
IF Host = 0 THEN
DIM Answer AS INTEGER
Answer = MessageBox("Can't start as host.", "", MsgBox_OkOnly + MsgBox_Critical)
SYSTEM
END IF
b$ = "Checking Preview component..." b$ = "Checking Preview component..."
GOSUB ShowMessage GOSUB ShowMessage