PlanetSquires Forums

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: Mutex and Firefly  (Read 208 times)

Richard Marchessault

  • FireFly3 Registered User
  • Junior Member
  • *
  • Posts: 185
Mutex and Firefly
« on: January 31, 2019, 09:23:01 AM »

What code would you recommend to determine if a program is already and switch to the running program instead of starting it up again? I can see examples of using CreateMutex on the PowerBasic forums but wonder how best to implement this with FireFly.

Pierre Bellisle

  • FireFly3 User
  • Junior Member
  • *
  • Posts: 85
Re: Mutex and Firefly
« Reply #1 on: January 31, 2019, 11:26:16 AM »

Sadly, I'm not a FireFly user, but still, here is the same Mutex & GW_HWNDNEXT approach I had in PowerBASIC...
Code: [Select]
#Define JumpCompiler "<D:\Free\64\fbc.exe>" 'Compiler to use "< = left delimiter, >" = right delimiter
#Define JumpCompilerCmd "<-s gui -w pedantic "D:\Free\bas\~~Default.rc">" 'Command line to send to compiler (gui or console)

#define UniCode
#Include Once ""
#Include Once "win\"

#Define AppName "Mutex demo"
#Define StaticInfo 101
#Define CrLf Chr(13, 10)
#Define dwMutex 1901310955 '[YYMMDDHHMM] - 10 digits - Max is 4,294,967,295, I use current time

Dim Shared As HINSTANCE hInstance : hInstance = GetModuleHandle(NULL)

Function WndProc(ByVal hWnd As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
 Dim    hStaticInfo        As HWND
 Static hWindowDefaultFont As HFONT

 Function = 0

 Select Case (uMsg)

     Dim As NONCLIENTMETRICS NotClientMetrics
     NotClientMetrics.cbSize = SizeOf(NONCLIENTMETRICS)
     SystemParametersInfo(SPI_GETNONCLIENTMETRICS, NotClientMetrics.cbSize, @NotClientMetrics, 0)
     hWindowDefaultFont = CreateFontIndirect(@NotClientMetrics.lfMessageFont)

     hStaticInfo = CreateWindowEx(0, "Static", "Try to run another self instance" & CRLF & "(Minimize me before)", _
                                  WS_CHILD Or WS_VISIBLE Or SS_CENTER Or SS_NOTIFY, _
                                  10, 30, 200, 30, _
                                  hWnd, Cast(HMENU, StaticInfo), _
                                  hInstance, NULL)
    SendMessage(hStaticInfo, WM_SETFONT, Cast(UInteger, hWindowDefaultFont), TRUE)

     DeleteObject(hWindowDefaultFont) 'Clean up
     PostQuitMessage(0) 'Ask message loop to end
     Exit Function

 End Select

 Function = DefWindowProc(hWnd, uMsg, wParam, lParam)

End Function

Function WinMain(ByVal hInstance As HINSTANCE, ByVal hPrevInst As HINSTANCE, _
                 ByVal CmdLine As WString Ptr, ByVal CmdShow As Integer) As UINT
 Dim WinClass   As WNDCLASS
 Dim wMsg       As MSG
 Dim hWnd       As HWND
 Dim hIco       As HICON
 Dim WindowSize As SIZEL
 Dim wsAppName  As WString * 128

 wsAppName              = AppName          = 230          = 120
 hIco                   = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294) 'o         = CS_HREDRAW Or CS_VREDRAW
 WinClass.lpfnWndProc   = ProcPtr(WndProc)
 WinClass.cbClsExtra    = 0
 WinClass.cbWndExtra    = 0
 WinClass.hInstance     = hInstance
 WinClass.hIcon         = hIco
 WinClass.hCursor       = LoadCursor(NULL, IDC_ARROW)
 WinClass.hbrBackground = Cast(HGDIOBJ, COLOR_BTNFACE + 1) 'Default color
 WinClass.lpszMenuName  = NULL
 WinClass.lpszClassName = @wsAppName

 Dim hTry        As HWND
 Dim hMutex      As HWND
 Dim zMutex      As ZString * 16

 zMutex  = "MyUniqueMutex" 'MaxStringLen is %MAX_PATH, no "\", case sensitive
 hMutex  = CreateMutex(ByVal NULL, 0, zMutex)
   'Optionnal: MessageBox(HWND_DESKTOP, AppName & " is already running!", AppName, MB_TOPMOST Or MB_OK)
   hTry =  GetForegroundWindow()
   Do While hTry
     If  GetWindowLongPtr(hTry, GWLP_USERDATA) = dwMutex Then
       If IsIconic(hTry) Then ShowWindow(hTry, SW_RESTORE) 'Unminimize exe
       Exit Do
     End If
     hTry = GetWindow(hTry, GW_HWNDNEXT)
   If hTry = 0 Then 'Can't find it!!!
     MessageBox(HWND_DESKTOP, AppName & " is running hidden in background!", AppName, MB_TOPMOST Or MB_OK)
   End IF
 End If

 If (RegisterClass(@WinClass)) Then
   hWnd = CreateWindowEx(WS_EX_WINDOWEDGE, _
                         wsAppName, wsAppName, _
                         WS_MAXIMIZEBOX Or WS_MINIMIZEBOX Or WS_SYSMENU , _
                         (GetSystemMetrics(SM_CXSCREEN) - / 2, _ 'PosX
                         (GetSystemMetrics(SM_CYSCREEN) - / 2, _ 'PosY
               ,, _ 'Width, height
                         NULL, NULL, hInstance, NULL)

   SetWindowLongPtr(hWnd, GWLP_USERDATA, dwMutex) 'Set window mutex

   ShowWindow(hWnd, SW_SHOW)

   While GetMessage(@wMsg, ByVal NULL, 0, 0) > 0
     If IsDialogMessage(hWnd, @wMsg) = 0 Then
     End If
 End If



 Function = wMsg.message

End Function

End WinMain(hInstance, NULL, Command(), SW_NORMAL) 'Call main() and return the error code to the OS

José Roca

  • FireFly3 Registered User
  • Master Member
  • *
  • Posts: 3147
    • Jos
Re: Mutex and Firefly
« Reply #2 on: January 31, 2019, 12:13:39 PM »


Firefly uses PowerBasic, not Freebasic.
« Last Edit: January 31, 2019, 03:45:40 PM by José Roca »

Pierre Bellisle

  • FireFly3 User
  • Junior Member
  • *
  • Posts: 85
Re: Mutex and Firefly
« Reply #3 on: January 31, 2019, 03:27:48 PM »

This was my impression, so I double checked with a quick search and got FireFly for FreeBASIC v3.78 uploaded... by Paul and then because the PowerBASIC's answers where quite explicit I thought Richard was adapting code, I guess that it was kind of a redundant variant of the same question.
In any case, for easy find, the PB equivalent of the above code is at Mutex and GWL_USERDATA
« Last Edit: January 31, 2019, 07:53:31 PM by Pierre Bellisle »

José Roca

  • FireFly3 Registered User
  • Master Member
  • *
  • Posts: 3147
    • Jos
Re: Mutex and Firefly
« Reply #4 on: January 31, 2019, 03:51:20 PM »

Sorry, I forgot that there was a version of Firefly for FreeBasic. I wonder why somebody will want to use it, since it was deprecated long time ago.

Klaas Holland

  • FireFly3 Registered User
  • Junior Member
  • *
  • Posts: 102
  • FF3 User
Re: Mutex and Firefly
« Reply #5 on: January 31, 2019, 06:27:15 PM »

I do use FireFly for FreeBasic and I am pleased with it.
That was my way to learn FreeBasic.
Now I am waiting for WinFBE to become as good and easy as FireFly.

Marc Pons

  • FireFly3 Registered User
  • Junior Member
  • *
  • Posts: 135
  • FF3 User
Re: Mutex and Firefly
« Reply #6 on: February 01, 2019, 07:39:49 AM »

@José, I also use Firefly for freebasic and with the extension i have done arround , it is totally usable,
i use it still with freebasic from 0.24  to 1.06 on 32bits and 1.05 or 1.06 on 64bits

in my understanding it is a vey interresting tool to create simple windowed app , I even can make windowed dll with it.
Even COM app using my old axsuite3 adaptation...
until the new Paul's visual editor is not totally done it is a very simple solution for people not wanting to write all sdk stuff.

As a nostalgic of vb6, it was the closest i've found, and hope to find the same simplicity with the new Paul's visual editor (sorry still not tested)

I take here alse the opportunity to thank you again Paul and you José for the great features of your contributions
kind regards

Paul:  i did not make the evolution on the French translation for your last ide version, (was travelling in your countrie in Montréal)
is it some changes in the existing I have to check or just adding new translations?
« Last Edit: February 01, 2019, 07:46:50 AM by Marc Pons »

David Kenny

  • FireFly3 Registered User
  • Senior Member
  • *
  • Posts: 452
  • Windows 7
Re: Mutex and Firefly
« Reply #7 on: February 03, 2019, 05:04:59 AM »


This code is the entire FF_WinMain in one of my old programs. You can get to FF_WinMain from the Firefly Workspace dialog (F9 to activate the dialog). On the Explorer tab, under Special Functions.

Code: [Select]
Function FF_WINMAIN(ByVal hInstance     As Dword, _
                    ByVal hPrevInstance As Dword, _
                    ByVal lpCmdLine     As Asciiz Ptr, _
                    ByVal iCmdShow      As Long) As Long
Local hWin      As   Dword
Local ProgName   As   String
'If this function returns TRUE (non-zero) then the actual WinMain will exit
'thus ending the program. You can do program initialization in this function.
Dim DrSelFlag(5)         
ProgName="User Copy"
If FF_PrevInstance Then
   hWin = FindWindow(ByVal %Null, ByVal StrPtr(ProgName))
   OpenIcon hWin                       '-- Activate the first instance
   SetForegroundWindow hWin
   Function = %True    'return %TRUE if you want the program to end.
   Function = %False     
End If

End Function

Just change the ProgramName from "User Copy" to your program name.  The mutex is handled by the FF routine FF_PrevInstance (in the Functions Library - Hit F8 - in the General branch). The rest I got from the PB forums.
It does exactly what you are asking for.

« Last Edit: February 03, 2019, 05:11:46 AM by David Kenny »