Set Multiple
Set Multiple
Hi all
If I call SetMultiple(.F.) at the tope of my main function this does not prevent my app from running more than once on the same PC
Is there something else that I should be doing
Thanks
Peter
If I call SetMultiple(.F.) at the tope of my main function this does not prevent my app from running more than once on the same PC
Is there something else that I should be doing
Thanks
Peter
Peter,
You could add this code at the beginning of your main function :
This function tests if your current application is already running on your system.
Good luck.
You could add this code at the beginning of your main function :
Code: Select all
IF IsExeRunning(cFileName(HB_ARGV(0)))
MsgAlert("Your application is already running !","Attention")
Quit
ENDIF
Good luck.
Last edited by driessen on Thu Nov 22, 2007 3:41 pm, edited 1 time in total.
Regards,
Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 21.01 - Harbour 3.2.0 (October 2020) - xHarbour Builder (January 2020) - Bcc7
Michel D.
Genk (Belgium)
_____________________________________________________________________________________________
I use : FiveWin for (x)Harbour v. 21.01 - Harbour 3.2.0 (October 2020) - xHarbour Builder (January 2020) - Bcc7
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
This works similar to the old 16bit way; if the EXE is already running it maximizes it and brings it to the foreground.
James
9/15/2005 5:28 PM
Run only 1 instance of an exe
James
9/15/2005 5:28 PM
Run only 1 instance of an exe
Code: Select all
// Author: "hua" <tomyam At rocketmail Dot com>
function main()
if AlreadyRunning()
return
endif
.
.
return
/**************************************************************************
If an exe is already running, bring window to front and maximize it.
NOTE: Though the exe is the same, but if it's being run from a different
path, they're considered different exe when using this routine.
*********/
#include "fivewin.ch"
#define GW_HWNDFIRST 0
#define GW_HWNDLAST 1
#define GW_HWNDNEXT 2
#define GW_HWNDPREV 3
#define GW_OWNER 4
#define GW_CHILD 5
#define SW_SHOWMAXIMIZED 3
function AlreadyRunning()
local lRet := .f., cMod := hb_Argv( 0 ), hWnd
if isExeRunning( cFileName( cMod ) )
hWnd := findWindowByModuleFilename( cMod )
setForeGroundWindow(hWnd)
showWindow( hWnd, SW_SHOWMAXIMIZED)
lRet := .t.
endif
return lRet
//----------------------------------------------------------------------
static function FINDWINDOWBYMODULEFILENAME( cModuleFileName )
LOCAL hWnd := getForegroundWindow(), cFile, hRet
while hWnd != 0
cFile := getWindowModuleFilename( hWnd )
cFile := left(cFile, len(cFile)-1) // remove null-termination char
IF cFile == cModuleFileName
hRet := hWnd
exit
ENDIF
hWnd := getWindow( hWnd, GW_HWNDNEXT )
enddo
return hRet
//--------------------------------------------------------------------------
DLL32 FUNCTION GETFOREGROUNDWINDOW() AS LONG;
PASCAL FROM "GetForegroundWindow" LIB "user32.dll"
//--------------------------------------------------------------------------
#pragma BEGINDUMP
#include "windows.h"
#include "hbapi.h"
HB_FUNC( GETWINDOWMODULEFILENAME ) // ( hWnd ) --> cFileName
{
char szFileName[ 256 ];
UINT wChar = GetWindowModuleFileName( ( HWND ) hb_parnl( 1 ),
szFileName, 256 );
hb_retclen( szFileName, wChar );
}
#pragma ENDDUMP
Thanks to all. Thank you James.
I was too quick with my question.
What I search is a method to bring the running prg to the forground.
At the moment I do the task the following way but I thought there would be a better method without a fix coded Window title - as I check for a previous exe before I create the main window.
if IsExeRunning( cFileName( HB_ARGV( 0 ) ) )
ShowApplication()
else
/*
Main Programm
********** -> On first start of the program I write oWnd:cTitle() to a ini-file.
*/
endif
Then I test with IsExeRunning and if YES
I call function ShowApplication
in the FindWnd() function I use the Window-title which is stored in the Ini-file.
I will try as James suggested with FINDWINDOWBYMODULEFILENAME in stet of FindWnd().
I was too quick with my question.
What I search is a method to bring the running prg to the forground.
At the moment I do the task the following way but I thought there would be a better method without a fix coded Window title - as I check for a previous exe before I create the main window.
if IsExeRunning( cFileName( HB_ARGV( 0 ) ) )
ShowApplication()
else
/*
Main Programm
********** -> On first start of the program I write oWnd:cTitle() to a ini-file.
*/
endif
Then I test with IsExeRunning and if YES
I call function ShowApplication
in the FindWnd() function I use the Window-title which is stored in the Ini-file.
I will try as James suggested with FINDWINDOWBYMODULEFILENAME in stet of FindWnd().
- Richard Chidiak
- Posts: 946
- Joined: Thu Oct 06, 2005 7:05 pm
- Location: France
- Contact:
Otto
This is a sample
#include "FiveWin.ch"
#define GW_CHILD 5
#define GW_HWNDNEXT 2
function Main()
local oWnd
if IsExeRunning( cFileName( HB_ARGV( 0 ) ) )
ShowApplication()
else
DEFINE WINDOW oWnd TITLE "Test"
ACTIVATE WINDOW oWnd
endif
return nil
function ShowApplication()
local hWnd := FindWnd( cFileNoExt( HB_ARGV( 0 ) ) )
if hWnd != nil
SetForeGroundWindow( hWnd )
endif
return nil
function FindWnd( cTitle )
local hWnd := GetWindow( GetDesktopWindow(), GW_CHILD )
while hWnd != 0
if Upper( cTitle ) $ Upper( GetWindowText( hWnd ) )
return hWnd
endif
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
end
return nil
This is a sample
#include "FiveWin.ch"
#define GW_CHILD 5
#define GW_HWNDNEXT 2
function Main()
local oWnd
if IsExeRunning( cFileName( HB_ARGV( 0 ) ) )
ShowApplication()
else
DEFINE WINDOW oWnd TITLE "Test"
ACTIVATE WINDOW oWnd
endif
return nil
function ShowApplication()
local hWnd := FindWnd( cFileNoExt( HB_ARGV( 0 ) ) )
if hWnd != nil
SetForeGroundWindow( hWnd )
endif
return nil
function FindWnd( cTitle )
local hWnd := GetWindow( GetDesktopWindow(), GW_CHILD )
while hWnd != 0
if Upper( cTitle ) $ Upper( GetWindowText( hWnd ) )
return hWnd
endif
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
end
return nil
Thank you Richard. Does this work on minimized?
I tested your code but it does not bring a minimized window to the foreground.
This is my test:
FindWnd1 is your code
FindWnd1
hWnd = 36700336 and cTitle = xRechnung
FindWnd the way with INI-file
hWnd=38732612 and cTitle = W i n H o t e l * 2007-Juni Demo - Computer-Nr: 5
This way it works. I use Vista.
function FindWnd1( cTitle )
local hWnd := GetWindow( GetDesktopWindow(), GW_CHILD )
msginfo(cTitle )
while hWnd != 0
if Upper( cTitle ) $ Upper( GetWindowText( hWnd ) )
return hWnd
endif
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
end
return nil
function FindWnd( cTitle )
local hWnd := GetWindow( GetDesktopWindow(), GW_CHILD )
msginfo(cTitle )
while hWnd != 0
if Upper( cTitle ) $ Upper( GetWindowText( hWnd ) )
return hWnd
endif
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
end
return nil
I tested your code but it does not bring a minimized window to the foreground.
This is my test:
FindWnd1 is your code
FindWnd1
hWnd = 36700336 and cTitle = xRechnung
FindWnd the way with INI-file
hWnd=38732612 and cTitle = W i n H o t e l * 2007-Juni Demo - Computer-Nr: 5
This way it works. I use Vista.
function FindWnd1( cTitle )
local hWnd := GetWindow( GetDesktopWindow(), GW_CHILD )
msginfo(cTitle )
while hWnd != 0
if Upper( cTitle ) $ Upper( GetWindowText( hWnd ) )
return hWnd
endif
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
end
return nil
function FindWnd( cTitle )
local hWnd := GetWindow( GetDesktopWindow(), GW_CHILD )
msginfo(cTitle )
while hWnd != 0
if Upper( cTitle ) $ Upper( GetWindowText( hWnd ) )
return hWnd
endif
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
end
return nil
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
I found a bug in the code I posted above. This line:
Apparently there is no null-termination character so it is truncating the name by one character and this the funcion is returning hWnd as nil always. I fixed it like this:
So hWnd is found.
However setForegroundWindow() window doesn't appear to do anything. I researched this via Google and it seems that you have to call allowSetForegroundWindow() first, but xHarbour does not have this function. I found it in xHarbour\contrib\what32\source\_winwnd.c and I cut and pasted it into the test program. But still no luck. Anyone have any ideas?
James
Code: Select all
cFile := left(cFile, len(cFile)-1) // remove null-termination char
Code: Select all
if right( cFile, 1) == chr(0)
cFile := left(cFile, len(cFile)-1) // remove null-termination char
endif
However setForegroundWindow() window doesn't appear to do anything. I researched this via Google and it seems that you have to call allowSetForegroundWindow() first, but xHarbour does not have this function. I found it in xHarbour\contrib\what32\source\_winwnd.c and I cut and pasted it into the test program. But still no luck. Anyone have any ideas?
James
Code: Select all
#pragma BEGINDUMP
#ifndef ASFW_ANY
#define ASFW_ANY ((DWORD)-1)
#endif
HB_FUNC( ALLOWSETFOREGROUNDWINDOW )
{
HINSTANCE h = LoadLibraryEx( "user32.dll", NULL, 0 );
BOOL bASFWRet = (BOOL) FALSE ;
DWORD dwProcessId = ISNIL( 1 ) ? ASFW_ANY : (DWORD) hb_parnl( 1 );
if( h )
{
typedef BOOL (WINAPI *xbAllowSetForegroundWindow)( DWORD dwProcessId );
xbAllowSetForegroundWindow pfnASFW = (xbAllowSetForegroundWindow)
GetProcAddress( h, "AllowSetForegroundWindow") ;
if( pfnASFW )
{
bASFWRet = (BOOL) pfnASFW( dwProcessId ) ;
}
FreeLibrary( h );
}
hb_retl( bASFWRet );
}
#pragma ENDDUMP
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Try this:Otto wrote:What do you pass as cFileName - the name of the EXE or the Title of the window? Does it work if the exe is minimized?
Regards,
Otto
Code: Select all
#include "Fivewin.ch"
FUNCTION MAIN()
LOCAL oWnd
LOCAL cTitle := "This is a test"
IF ISEXERUNNING( CFILENAME( HB_ARGV( 0 ) ) )
SHOWWINDOW( FINDWINDOW( 0, cTitle ), 9 )
SETFOREGROUNDWINDOW( FINDWINDOW( 0, cTitle ) )
RETURN NIL
ENDIF
DEFINE WINDOW oWnd;
TITLE cTitle
ACTIVATE WINDOW oWnd
RETURN NIL
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Enrico,
Your function works. I note that FindWindow() and oWnd:hWnd have the same value. I don't know why the findWindowByModuleFilename( cMod ) in the code I posted doesn't return the same value as oWnd:hWnd.
There are issues when using the window title. If you have a folder open with the same name, then it can get confused. I expect this is not a big issue as normally a user wouldn't have the folder open, but it did happen to me when testing.
Also, what if you are running a MDI application and the name changes when you open a MDI child. Does it still find a match even though the complete titles are different?
James
Your function works. I note that FindWindow() and oWnd:hWnd have the same value. I don't know why the findWindowByModuleFilename( cMod ) in the code I posted doesn't return the same value as oWnd:hWnd.
There are issues when using the window title. If you have a folder open with the same name, then it can get confused. I expect this is not a big issue as normally a user wouldn't have the folder open, but it did happen to me when testing.
Also, what if you are running a MDI application and the name changes when you open a MDI child. Does it still find a match even though the complete titles are different?
James
- Enrico Maria Giordano
- Posts: 7355
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Try this other:
EMG
Code: Select all
#include "Fivewin.ch"
FUNCTION MAIN()
LOCAL oWnd
LOCAL cTitle := "This is a test"
IF ISEXERUNNING( CFILENAME( HB_ARGV( 0 ) ) )
SHOWWINDOW( FINDWND( cTitle ), 9 )
SETFOREGROUNDWINDOW( FINDWND( cTitle ) )
RETURN NIL
ENDIF
DEFINE WINDOW oWnd;
TITLE "Prefix - " + cTitle + " - Postfix"
ACTIVATE WINDOW oWnd
RETURN NIL
#define GW_HWNDFIRST 0
#define GW_HWNDLAST 1
#define GW_HWNDNEXT 2
#define GW_HWNDPREV 3
#define GW_OWNER 4
#define GW_CHILD 5
FUNCTION FINDWND( cTitle )
LOCAL hWnd := GETWINDOW( GETDESKTOPWINDOW(), GW_CHILD )
WHILE hWnd != 0
IF UPPER( cTitle ) $ UPPER( GETWINDOWTEXT( hWnd ) )
RETURN hWnd
ENDIF
hWnd = GETWINDOW( hWnd, GW_HWNDNEXT )
ENDDO
RETURN NIL