This is quite easy to do with Windows3.x but with Windows NT and Windows95, 32bit applications run in there own memory space. With Windows3.x, all 16bit applications share the same piece of memory. With the Handle(This,TRUE) function in the application's open event you can simple determine if the application is arelady running. With NT and PB for NT, this code won't work. So, is there another method for this? Secondly, we want a method that works on both operating systems so that you don't have to add OS specific code. Well, there is another method: DDE.
In fact, this method is also quite simple. We just check if we can open a DDE channel with our own, already running, application. If this succeeds, you know that the applications already is running and you can close the current one. Another advantage is that you can send DDE commands to the other application, for instance to put itself to the foregrond.
So, what do we have to do:
|Our application must be operating as DDE server. Herefore we need a window which is always open. In most cases, we can use the MDIframe for this function.|
|Secondly, for openening a DDE channel, you need a clientwindow. This clientwindow should be the first window opened, before the application becomes a DDE server. In most cases, we can use the logon window for this. The logon window opens the MDIframe after checking if the application is already running|
|And we need a name for the DDE server. You can use anything you want for this but I always use the application's executable name. This one is unique enough|
So, we need a logon window ( w_logon ) and a MDIframe ( w_mdi_frame ). The DDE server name is in our case "TESTAPP.EXE". Here's the code. First of all we need to make our application a DDE server. This happens in the open event of the MDIframe:
w_mdi_frame::open event StartServerDDE ( this, "TESTAPP.EXE", "popup" )
If we close the application, we can also stop the DDE server:
w_mdi_frame::close event StopServerDDE ( "TESTAPP.EXE" ,"popup")
We also place some code in the RemoteExec event so that our DDE server kan receive commands:
w_mdi_frame::remoteexec string sItem /* Get the DDE command */ GetCommandDDE(sItem) /* For instance, 'popup' for bringing our application to top */ CHOOSE CASE lower(sItem) CASE "popup" This.WindowState = Normal! This.Show() This.BringToTop = TRUE END CHOOSE
In the logon window, we try to open a DDE channel with our already running DDE server:
w_logon::open event int iChannel iChannel = OpenChannel("TESTAPP.EXE","popup") IF iChannel > 0 THEN /* the application is already running so display a message */ Messagebox("Notice","The application is already runing") /* send a command to the DDE server to bring itself to top */ ExecRemote("popup",iChannel) /* Close the DDE channel and close the application */ CloseChannel(iChannel) HALT CLOSE END IF /* the application is not running, so start up the DDE server */ open(w_mdi_frame) close(this)
That's all! This code works with 16- and 32bit PB applications on Windows3.x, Windows95 and WindowsNT.