Set Multiple

Set Multiple

Postby Peterg » Thu Nov 22, 2007 1:33 pm

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
Peterg
 
Posts: 62
Joined: Mon Nov 28, 2005 5:36 pm
Location: Oxford UK

Postby driessen » Thu Nov 22, 2007 2:10 pm

Peter,

You could add this code at the beginning of your main function :

Code: Select all  Expand view  RUN
IF IsExeRunning(cFileName(HB_ARGV(0)))
   MsgAlert("Your application is already running !","Attention")
   Quit
ENDIF

This function tests if your current application is already running on your system.

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. 24.07 - Harbour 3.2.0 (February 2024) - xHarbour Builder (January 2020) - Bcc773
User avatar
driessen
 
Posts: 1422
Joined: Mon Oct 10, 2005 11:26 am
Location: Genk, Belgium

Postby Peterg » Thu Nov 22, 2007 2:44 pm

Many thanks that works well
Peterg
 
Posts: 62
Joined: Mon Nov 28, 2005 5:36 pm
Location: Oxford UK

Postby Otto » Thu Nov 22, 2007 8:31 pm

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
User avatar
Otto
 
Posts: 6346
Joined: Fri Oct 07, 2005 7:07 pm

Postby Antonio Linares » Thu Nov 22, 2007 8:38 pm

Otto,

The parameter is HB_ARGV(0) which it is the name and path of the EXE
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42127
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Enrico Maria Giordano » Thu Nov 22, 2007 10:32 pm

Otto wrote:What do you pass as cFileName


Please note that cFileName() is a function.

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8719
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby James Bott » Fri Nov 23, 2007 12:11 am

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

Code: Select all  Expand view  RUN
// 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
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Postby Otto » Fri Nov 23, 2007 8:03 am

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().
User avatar
Otto
 
Posts: 6346
Joined: Fri Oct 07, 2005 7:07 pm

Postby Richard Chidiak » Fri Nov 23, 2007 8:13 am

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
http://www.cbati.com

Uestudio
Fwh 13.05 Harbour 3.2 MSVC 2013
User avatar
Richard Chidiak
 
Posts: 946
Joined: Thu Oct 06, 2005 7:05 pm
Location: France

Postby Otto » Fri Nov 23, 2007 8:34 am

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
User avatar
Otto
 
Posts: 6346
Joined: Fri Oct 07, 2005 7:07 pm

Postby James Bott » Fri Nov 23, 2007 6:12 pm

I found a bug in the code I posted above. This line:

Code: Select all  Expand view  RUN
        cFile := left(cFile, len(cFile)-1) // remove null-termination char


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:

Code: Select all  Expand view  RUN
if right( cFile, 1) == chr(0)
   cFile := left(cFile, len(cFile)-1) // remove null-termination char
endif


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  Expand view  RUN
#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
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Postby James Bott » Fri Nov 23, 2007 6:33 pm

I forgot to mention that oWnd:hWnd and findWindowByModuleFilename( cMod ) don't have the same value. I would think that they should. Perhaps we are sending the wrong hWnd to setForeground()?

James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Postby Enrico Maria Giordano » Fri Nov 23, 2007 7:20 pm

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


Try this:

Code: Select all  Expand view  RUN
#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


EMG
User avatar
Enrico Maria Giordano
 
Posts: 8719
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Postby James Bott » Fri Nov 23, 2007 7:37 pm

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
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Postby Enrico Maria Giordano » Fri Nov 23, 2007 8:31 pm

Try this other:

Code: Select all  Expand view  RUN
#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


EMG
User avatar
Enrico Maria Giordano
 
Posts: 8719
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 39 guests