Board index » cppbuilder » multiple application instance problem

multiple application instance problem


2005-01-21 06:36:08 AM
cppbuilder15
Hi all,
My MDI app uses a data file.
The data file is registered to open an instance of the app when one double
clicks on it.
I do not want multiple instances of my program running.
Code has been implemented to prevent multiple instances
(checks for the existance of a named Event)
and pass to the running instance the data file to open.
I use FindWindow to get the handle to the running app
then use SendMessage with the command line as the passed
parameter.
Everything seems to be running fine, except when
no instance of the program exists, and one attepts to
open several data files simultaneously (hilight several files,
hit enter)
What happens is that windows creates an instance
and passes one file to it, then opens another and so on
until all data files are accounted for.
when the app opens, it checks for the existance of the
Event object.
If it doesn't exist, it creates it and becomes the Primary app
and continues to load until everything is finished, then it
signals the event.
If the event does exist, I use WaitForSingleObject to halt execution until
the primary app signals the event.
After that, well I haven't been successful in acheiving a solution.
I have tried
HWND hWnd;
hWnd = FindWindow( "TMyForm", 0);
but this doesn't seem to be able to pick out the primary application
out of the many that were currently open.
I've tried capturing the primary app by specifying the window name
in the FindWindow call by specifying the default window name as
"notme" and changing it to Caption = "FirstInstance" at runtime,
as FindWindow("TMyForm", "FirstInstance" );
but this wouldn't find the primary app. I think it's not finding it
because the caption changes to show the name of the loaded
data file in the primary app.
Now, I am trying to use shared memory to hold a handle to the
primary app
// If hSignal is 0 then the signaling object doesn't exist.
if( !hSignal )
{
hSignal = CreateEvent( NULL, true, false, "eReaDataSignal" );
FHandle = CreateFileMapping((HANDLE)0xFFFFFFFF,
NULL,
PAGE_READWRITE,
0,
sizeof(HANDLE),
"ReaDataInstance1");
if( FHandle != 0 )
{
DWORD dwFoom;
dwFoom = sizeof( (HANDLE)Application );
FAccess = MapViewOfFile(FHandle, FILE_MAP_WRITE, 0, 0, dwFoom );
if ( FAccess != 0 )
{
*FAccess = (HANDLE)Application; // this line doesn't compile
}
}
}
Is there an easier way to acheive what I am trying to do?
thanks.
Stephan
 
 

Re:multiple application instance problem

"Stephan Laska" <ask & maybe I'll Tell>wrote:
Quote

[...] Is there an easier way to acheive what I am trying to
do?
Use my component. You can modify the code to pass the file to
the first instance:
tinyurl.com/4wkxy
~ JD
 

Re:multiple application instance problem

"JD" < XXXX@XXXXX.COM >wrote in message
Quote

"Stephan Laska" <ask & maybe I'll Tell>wrote:
>
>[...] Is there an easier way to acheive what I am trying to
>do?

Use my component. You can modify the code to pass the file to
the first instance:

tinyurl.com/4wkxy
thanks, looks like a great tutorial for using enumwindows
 

{smallsort}

Re:multiple application instance problem

"Stephan Laska" <ask & maybe I'll Tell>wrote:
Quote

thanks, looks like a great tutorial for using enumwindows
Just so you know, CreateMutex is the only 100% reliable way to
prevent multiple instances and EnumWindows is the only 100%
reliable way to find the first instance from within the second
instance and for EnumWindows to work, you must have an unique
class name for the main form.
That link also addresses a problem that you will experience,
depending on the window state of the first instance, when you
try to set control to it from the second instance.
To simplify the example, you can skip making a component and
add most of the code to the WinMain but you'll still need to
override the main form's WndProc method *or* use a MessageMap
so that you can keep track of the window state manually and so
that you have a means of receiving a custom message from the
second instance.
www.flounder.com/messages.htm
~ JD
 

Re:multiple application instance problem

"JD" < XXXX@XXXXX.COM >wrote in message
Quote
Just so you know, CreateMutex is the only 100% reliable
way to prevent multiple instances
That statement is misleading. CreateMutex() is not the only way to do it.
Any named object will work. That includes semaphores and events as well as
mutexes.
Quote
EnumWindows is the only 100% reliable way to find the
first instance from within the second instance
Not true. There are other ways to accomplish it just as reliably, such as
using RegisterWindowMessage() and SendMessage(HWND_BROADCAST). Any
application instance that recognizes the broadcasted messages can report its
window handle back to the broadcaster.
Gambit
 

Re:multiple application instance problem

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

"JD" < XXXX@XXXXX.COM >wrote in message
news:41f1fe16$ XXXX@XXXXX.COM ...

>Just so you know, CreateMutex is the only 100% reliable
>way to prevent multiple instances

That statement is misleading. CreateMutex() is not the only way to do it.
Any named object will work. That includes semaphores and events as well as
mutexes.
I'll buy that.
Quote
>EnumWindows is the only 100% reliable way to find the
>first instance from within the second instance

Not true. There are other ways to accomplish it just as reliably, such as
using RegisterWindowMessage() and SendMessage(HWND_BROADCAST). Any
application instance that recognizes the broadcasted messages can report its
window handle back to the broadcaster.
I disagree. While broadcasting a registered message is
reliable within your own code, it can cause problems with
other applications that are poorly written and such was the
case with my tests.
Researching the problem, I found a short list of applications
that were problematic but I didn't save it because it was
enough just to know what was happening.
I'll leave it to you to think of another alternative.
~ JD
 

Re:multiple application instance problem

"JD" < XXXX@XXXXX.COM >wrote in message
Quote
I disagree. While broadcasting a registered message is
reliable within your own code, it can cause problems with
other applications that are poorly written and such was the
case with my tests.
The whole point of using RegisterWindowMessage() is that the broadcasted
message will be a value that only participating applications will recognize.
Any unrecognized message that is received by other applications is filtered
to the application's default message handler, and then to the Win32 API's
DefWindowProc(), both of which will ignore the message as well.
Gambit