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_FrameRate AS SINGLE, __UI_Font8Offset AS INTEGER, __UI_Font16Offset AS INTEGER
DIM SHARED __UI_ClipboardCheck$, __UI_MenuBarOffsetV AS INTEGER
DIM SHARED __UI_KeepScreenHidden AS _BYTE
'Control types:
DIM SHARED __UI_Type(0 TO 18) AS __UI_Types
@ -478,7 +479,7 @@ SUB __UI_Init
__UI_BeforeInit
_SCREENSHOW
IF __UI_KeepScreenHidden = False THEN _SCREENSHOW
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 RevertEdit AS _BYTE, OldColor 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 Stream$, FormDataReceived AS _BYTE, LastFormData$
DIM SHARED prevScreenX AS INTEGER, prevScreenY AS INTEGER
@ -177,6 +178,10 @@ $IF WIN THEN
FUNCTION GetExitCodeProcess& (BYVAL hProcess AS LONG, lpExitCode AS LONG)
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
''Code courtesy of Michael Calkins
''winreg.h
@ -834,11 +839,13 @@ END SUB
SUB __UI_BeforeUpdateDisplay
DIM b$, c$
DIM i AS LONG, j AS LONG, Answer AS _BYTE
DIM incomingData$, Signal$
DIM thisData$, thisCommand$
STATIC OriginalImageWidth AS INTEGER, OriginalImageHeight AS INTEGER
STATIC PrevFirstSelected AS LONG, PreviewHasMenuActive AS INTEGER
STATIC CheckUpdateDone AS _BYTE
STATIC LastChange AS SINGLE
IF TIMER - BlinkStatusBar < 1 THEN
IF TIMER - LastChange > .2 THEN
IF Control(StatusBar).BackColor = StatusBarBackColor THEN
@ -858,6 +865,64 @@ SUB __UI_BeforeUpdateDisplay
IF Caption(StatusBar) = "" THEN Caption(StatusBar) = "Ready."
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 CheckUpdateDone = False THEN
STATIC ThisStep AS INTEGER
@ -932,8 +997,6 @@ SUB __UI_BeforeUpdateDisplay
CheckPreview
DIM incomingData$, Signal$
GET #Client, , incomingData$
Stream$ = Stream$ + incomingData$
STATIC bytesIn~&&, refreshes~&
@ -995,7 +1058,6 @@ SUB __UI_BeforeUpdateDisplay
END IF
SignalsFirstSent = True
DIM thisData$, thisCommand$
DO WHILE INSTR(Stream$, "<END>") > 0
thisData$ = LEFT$(Stream$, INSTR(Stream$, "<END>") - 1)
Stream$ = MID$(Stream$, INSTR(Stream$, "<END>") + 5)
@ -1979,6 +2041,7 @@ SUB SaveSettings
END SUB
SUB __UI_BeforeInit
__UI_KeepScreenHidden = True
END SUB
SUB __UI_FormResized
@ -2029,6 +2092,50 @@ SUB __UI_OnLoad
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
AutoNameControls = True
CheckUpdates = True
@ -2175,22 +2282,6 @@ SUB __UI_OnLoad
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..."
GOSUB ShowMessage