Prevent multiple instance of dialog-based app
Todd Davis -- tigger@idir.net
Tuesday, December 03, 1996
Environment: VC++ 4.1, Win 95
I have a dialog-based application with the modal dialog code residing in a
.dll. The executable logs into a server within InitInstance() and then
calls a function within the .dll that does a DoModal.
Here's my problem:
The "Onetime" sample application that demonstrates how to prevent multiple
instances wants to have a window registered within PreCreateWindow.
CDialog::PreCreateWindow is not called when you do a DoModal, and dialogs in
general don't register themselves the way frames do, it appears. I was
unable to tweak this example to work for dialog-based applications.
So I figured if you can't beat 'em, join 'em. I modified my .exe to have a
Frame/Doc/View architecture, to have it hide the mainframe, and run the
.dll's dialog from within my application class' override of Run (I don't
know if this latter is a good idea or not, but it works). I am able to
prevent multiple instances now. BUT, I want to hide the "do-nothing" frame
window created by the application and still have an entry for my
dialog/frame on the taskbar. Also, when I minimize the dialog, I want it to
go to the taskbar too, not to the bottom-left of the desktop.
Does it have to be one or the other (dialog-based many instances possible
vs. frame-based minimizing weirdness) or does someone know of a way to get
either of these possibilities to work like I want?
Panicky screams in advance,
Todd Davis
Software Engineer
Gateway 2000
Lin Sebastian Kayser -- Lin.Kayser@munich.netsurf.de
Friday, December 06, 1996
[Mini-digest: 9 responses]
Todd,
if you're having all this pain only to prevent multiple instantiation of =
your program then you might want to try my approach instead. You simply =
create a named Mutex and test for it in you InitInstance. If it is =
already there then you simply broadcast a user defined unique message =
and exit. The other instance of the program receives the messages and =
restores its position.
The following code has to be inserted in your app:
in MyApp.h:
protected:
CMutex* m_pmtxInstanceWatch;
In MyApp.cpp override OnInitInstance, OnExitInstance und =
PreTranslateMessage using Class Wizard.
Insert at the top of the file (global):
const UINT wm_Activate =3D RegisterWindowMessage("MyAppActivate");
in CMyApp::OnInitInstance:
m_pmtxInstanceWatch =3D new CMutex(FALSE, "MyApp");
if (!m_pmtxInstanceWatch->Lock(0))
{
//Activate previous Instance
::PostMessage(HWND_BROADCAST, wm_Activate, 0,0);
return FALSE;
}
In CMyApp::OnExitInstance:
ASSERT(m_pmtxInstanceWatch !=3D NULL);
delete m_pmtxInstanceWatch;
In CMyApp::PreTranslateMessage
if (pMsg->message =3D=3D wm_Activate)
{
// Activate main window
ASSERT(AfxGetMainWnd() !=3D NULL)
// Does not work for in-place activated objects
AfxGetMainWnd()->ShowWindow(SW_RESTORE);
}
That should do it.
Regards,
Lin Sebastian Kayser,
Kayser & Nass, Germany
-----Original Message-----
From: Todd Davis [SMTP:tigger@idir.net]
Sent: Tuesday, December 03, 1996 10:38 PM
To: mfc-l@netcom.com
Subject: Prevent multiple instance of dialog-based app
Environment: VC++ 4.1, Win 95
I have a dialog-based application with the modal dialog code residing in =
a
.dll. The executable logs into a server within InitInstance() and then
calls a function within the .dll that does a DoModal.
Here's my problem:
The "Onetime" sample application that demonstrates how to prevent =
multiple
instances wants to have a window registered within PreCreateWindow.
CDialog::PreCreateWindow is not called when you do a DoModal, and =
dialogs in
general don't register themselves the way frames do, it appears. I was
unable to tweak this example to work for dialog-based applications.
So I figured if you can't beat 'em, join 'em. I modified my .exe to =
have a
Frame/Doc/View architecture, to have it hide the mainframe, and run the
.dll's dialog from within my application class' override of Run (I =
don't
know if this latter is a good idea or not, but it works). I am able to
prevent multiple instances now. BUT, I want to hide the "do-nothing" =
frame
window created by the application and still have an entry for my
dialog/frame on the taskbar. Also, when I minimize the dialog, I want =
it to
go to the taskbar too, not to the bottom-left of the desktop.
Does it have to be one or the other (dialog-based many instances =
possible
vs. frame-based minimizing weirdness) or does someone know of a way to =
get
either of these possibilities to work like I want?
Panicky screams in advance,
Todd Davis
Software Engineer
Gateway 2000
-----From: Per Clausen - PCL/TC/GBJ
Environment: VC++ 4.1, Win 95
I have a dialog-based application with the modal dialog code residing in a
.dll. The executable logs into a server within InitInstance() and then
calls a function within the .dll that does a DoModal.
Here is one way of doing it:
#include
static CMutex mtxMyApp(FALSE, "MUTEX_MYAPP");
static CSingleLock slockMyApp(&mtxMyApp, FALSE);
if (!slockMyApp.Lock(150))
{
MessageBox(NULL, "MyApp can only be started once\nSwitch to running program",
"MyApp", MB_ICONSTOP);
return FALSE;
}
Per Clausen
-----From: Stuart Downing
According to the help for ::WinMain (SDK level), in Win16, you could just
look at the hPrevInstance parameter to WinMain to decide if a previous
instance of your application was running.
A new technique is suggested for Win32. Create a named mutex using
CreateMutex. If GetLastError function returns ERROR_ALREADY_EXISTS,
another instance of your application exists. You would do this in
InitInstance.
The Doc/View solution sounds a bit Rube Goldbergesque. :)
-----
Stuart Downing
sdowning@fame.com
FAME Information Services, Inc.
----------
From: Todd Davis[SMTP:tigger@idir.net]
Sent: Tuesday, December 03, 1996 5:38 PM
To: mfc-l@netcom.com
Subject: Prevent multiple instance of dialog-based app
Environment: VC++ 4.1, Win 95
I have a dialog-based application with the modal dialog code residing in a
.dll. The executable logs into a server within InitInstance() and then
calls a function within the .dll that does a DoModal.
Here's my problem:
The "Onetime" sample application that demonstrates how to prevent multiple
instances wants to have a window registered within PreCreateWindow.
CDialog::PreCreateWindow is not called when you do a DoModal, and dialogs in
general don't register themselves the way frames do, it appears. I was
unable to tweak this example to work for dialog-based applications.
So I figured if you can't beat 'em, join 'em. I modified my .exe to have a
Frame/Doc/View architecture, to have it hide the mainframe, and run the
.dll's dialog from within my application class' override of Run (I don't
know if this latter is a good idea or not, but it works). I am able to
prevent multiple instances now. BUT, I want to hide the "do-nothing" frame
window created by the application and still have an entry for my
dialog/frame on the taskbar. Also, when I minimize the dialog, I want it to
go to the taskbar too, not to the bottom-left of the desktop.
Does it have to be one or the other (dialog-based many instances possible
vs. frame-based minimizing weirdness) or does someone know of a way to get
either of these possibilities to work like I want?
Panicky screams in advance,
Todd Davis
Software Engineer
Gateway 2000
-----From: "Unmesh Ballal"
>From owner-mfc-l@majordomo.netcom.com Thu Dec 5 22:51:58 1996
>Received: by majordomo.netcom.com (8.7.5/8.7.3/(NETCOM MLS v1.01)) id
OAA12595; Thu, 5 Dec 1996 14:37:39 -0800 (PST)
>Message-Id: <1.5.4.32.19961203223813.00686584@idir.net>
>X-Sender: tigger@idir.net
>X-Mailer: Windows Eudora Light Version 1.5.4 (32)
>Mime-Version: 1.0
>Content-Type: text/plain; charset="us-ascii"
>Date: Tue, 03 Dec 1996 16:38:13 -0600
>To: mfc-l@netcom.com
>From: Todd Davis
>Subject: Prevent multiple instance of dialog-based app
>Sender: owner-mfc-l@majordomo.netcom.com
>Errors-To: owner-mfc-l@majordomo.netcom.com
>Precedence: bulk
>Reply-To: mfc-l@netcom.com
>Environment: VC++ 4.1, Win 95
>
>I have a dialog-based application with the modal dialog code residing in a
>.dll. The executable logs into a server within InitInstance() and then
>calls a function within the .dll that does a DoModal.
>
>Here's my problem:
>
>The "Onetime" sample application that demonstrates how to prevent multiple
>instances wants to have a window registered within PreCreateWindow.
>CDialog::PreCreateWindow is not called when you do a DoModal, and dialogs in
>general don't register themselves the way frames do, it appears. I was
>unable to tweak this example to work for dialog-based applications.
>
>So I figured if you can't beat 'em, join 'em. I modified my .exe to have a
>Frame/Doc/View architecture, to have it hide the mainframe, and run the
>.dll's dialog from within my application class' override of Run (I don't
>know if this latter is a good idea or not, but it works). I am able to
>prevent multiple instances now. BUT, I want to hide the "do-nothing" frame
>window created by the application and still have an entry for my
>dialog/frame on the taskbar. Also, when I minimize the dialog, I want it to
>go to the taskbar too, not to the bottom-left of the desktop.
>
>Does it have to be one or the other (dialog-based many instances possible
>vs. frame-based minimizing weirdness) or does someone know of a way to get
>either of these possibilities to work like I want?
>
>Panicky screams in advance,
>Todd Davis
>Software Engineer
>Gateway 2000
>
>
Hi, To prevent multiple instance of the same dlg based app this is a simple
solution. dont forget to call ReleaseMutex in the destructor.
BOOL CTestDialog::InitInstance()
{
HANDLE hMutex = CreateMutex(NULL, FALSE, "OneInstance");
DWORD dwErr = GetLastError();
if (dwErr == 0)
{
AfxMessageBox("First instance created successfully.");
}
else if(ERROR_ALREADY_EXISTS == dwErr)
{
AfxMessageBox("Another instance of this program already exists. exiting
program.");
// can do a find window and setfocus here
return FALSE;
}
else
{
AfxMessageBox("Could not create mutex.");
}
.. // continue with dialog instantiation
}
i hope this serves the purpose.
Unmesh Ballal
unmesh@hotmail.com
---------------------------------------------------------
Get Your *Web-Based* Free Email at http://www.hotmail.com
---------------------------------------------------------
-----From: "Philip T. Carey"
Todd Davis wrote:
>
> Environment: VC++ 4.1, Win 95
>
> I have a dialog-based application with the modal dialog code residing in a
> .dll. The executable logs into a server within InitInstance() and then
> calls a function within the .dll that does a DoModal.
>
> Here's my problem:
>
> The "Onetime" sample application that demonstrates how to prevent multiple
> instances wants to have a window registered within PreCreateWindow.
> CDialog::PreCreateWindow is not called when you do a DoModal, and dialogs in
> general don't register themselves the way frames do, it appears. I was
> unable to tweak this example to work for dialog-based applications.
>
> So I figured if you can't beat 'em, join 'em. I modified my .exe to have a
> Frame/Doc/View architecture, to have it hide the mainframe, and run the
> .dll's dialog from within my application class' override of Run (I don't
> know if this latter is a good idea or not, but it works). I am able to
> prevent multiple instances now. BUT, I want to hide the "do-nothing" frame
> window created by the application and still have an entry for my
> dialog/frame on the taskbar. Also, when I minimize the dialog, I want it to
> go to the taskbar too, not to the bottom-left of the desktop.
>
> Does it have to be one or the other (dialog-based many instances possible
> vs. frame-based minimizing weirdness) or does someone know of a way to get
> either of these possibilities to work like I want?
>
> Panicky screams in advance,
> Todd Davis
> Software Engineer
> Gateway 2000
Use CFormView.
-----From: Luke Stephens
Why don't you create a named mutex, event, or semaphone. If =
GetLastError() returns ERROR_ALREADY_EXISTS that means your app is =
already running. You can find the previous instance of the app and =
activate it and then exit.
Hope this helps,
Luke Stephens
----------
From: Todd Davis
Sent: Tuesday, December 03, 1996 4:38 PM
To: mfc-l@netcom.com
Subject: Prevent multiple instance of dialog-based app
Environment: VC++ 4.1, Win 95
I have a dialog-based application with the modal dialog code residing in =
a
.dll. The executable logs into a server within InitInstance() and then
calls a function within the .dll that does a DoModal.
Here's my problem:
The "Onetime" sample application that demonstrates how to prevent =
multiple
instances wants to have a window registered within PreCreateWindow.
CDialog::PreCreateWindow is not called when you do a DoModal, and =
dialogs in
general don't register themselves the way frames do, it appears. I was
unable to tweak this example to work for dialog-based applications.
So I figured if you can't beat 'em, join 'em. I modified my .exe to =
have a
Frame/Doc/View architecture, to have it hide the mainframe, and run the
.dll's dialog from within my application class' override of Run (I =
don't
know if this latter is a good idea or not, but it works). I am able to
prevent multiple instances now. BUT, I want to hide the "do-nothing" =
frame
window created by the application and still have an entry for my
dialog/frame on the taskbar. Also, when I minimize the dialog, I want =
it to
go to the taskbar too, not to the bottom-left of the desktop.
Does it have to be one or the other (dialog-based many instances =
possible
vs. frame-based minimizing weirdness) or does someone know of a way to =
get
either of these possibilities to work like I want?
Panicky screams in advance,
Todd Davis
Software Engineer
Gateway 2000
-----From: "Kenneth A. Argo"
Instead of looking for a window, since you really don't need one anyway. =
Try creating a "named" resource, for instance a MUTEX. Then you can =
check to see if it exists and if so then you already have and instance =
running. It's cheaper than all the code for a hidden window and frame, =
and lighter weight for the OS.
Ken
----------
From: Todd Davis[SMTP:tigger@idir.net]
Sent: Tuesday, December 03, 1996 5:38 PM
To: mfc-l@netcom.com
Subject: Prevent multiple instance of dialog-based app
Environment: VC++ 4.1, Win 95
I have a dialog-based application with the modal dialog code residing in =
a
.dll. The executable logs into a server within InitInstance() and then
calls a function within the .dll that does a DoModal.
Here's my problem:
The "Onetime" sample application that demonstrates how to prevent =
multiple
instances wants to have a window registered within PreCreateWindow.
CDialog::PreCreateWindow is not called when you do a DoModal, and =
dialogs in
general don't register themselves the way frames do, it appears. I was
unable to tweak this example to work for dialog-based applications.
So I figured if you can't beat 'em, join 'em. I modified my .exe to =
have a
Frame/Doc/View architecture, to have it hide the mainframe, and run the
.dll's dialog from within my application class' override of Run (I =
don't
know if this latter is a good idea or not, but it works). I am able to
prevent multiple instances now. BUT, I want to hide the "do-nothing" =
frame
window created by the application and still have an entry for my
dialog/frame on the taskbar. Also, when I minimize the dialog, I want =
it to
go to the taskbar too, not to the bottom-left of the desktop.
Does it have to be one or the other (dialog-based many instances =
possible
vs. frame-based minimizing weirdness) or does someone know of a way to =
get
either of these possibilities to work like I want?
Panicky screams in advance,
Todd Davis
Software Engineer
Gateway 2000
-----From: Claus Michelsen
Hi Todd,
If the caption of your dialog box is always the same then you can use =
FindWindow. This can search for a window with a certain caption. If it =
finds it, you know that you application is already running.
Best regards,
Claus Michelsen
-----Original Message-----
From: Todd Davis [SMTP:tigger@idir.net]
Sent: 3. december 1996 23:38
To: mfc-l@netcom.com
Subject: Prevent multiple instance of dialog-based app
Environment: VC++ 4.1, Win 95
I have a dialog-based application with the modal dialog code residing in =
a
.dll. The executable logs into a server within InitInstance() and then
calls a function within the .dll that does a DoModal.
Here's my problem:
The "Onetime" sample application that demonstrates how to prevent =
multiple
instances wants to have a window registered within PreCreateWindow.
CDialog::PreCreateWindow is not called when you do a DoModal, and =
dialogs in
general don't register themselves the way frames do, it appears. I was
unable to tweak this example to work for dialog-based applications.
So I figured if you can't beat 'em, join 'em. I modified my .exe to =
have a
Frame/Doc/View architecture, to have it hide the mainframe, and run the
.dll's dialog from within my application class' override of Run (I =
don't
know if this latter is a good idea or not, but it works). I am able to
prevent multiple instances now. BUT, I want to hide the "do-nothing" =
frame
window created by the application and still have an entry for my
dialog/frame on the taskbar. Also, when I minimize the dialog, I want =
it to
go to the taskbar too, not to the bottom-left of the desktop.
Does it have to be one or the other (dialog-based many instances =
possible
vs. frame-based minimizing weirdness) or does someone know of a way to =
get
either of these possibilities to work like I want?
Panicky screams in advance,
Todd Davis
Software Engineer
Gateway 2000
-----From: Richard Braley
Try using CreateMutex to create a mutex object within your apps =
InitInstance method. Immediately after creating the mutex, call =
GetLastError to see if the mutex already existed. If it did, your app is =
already running. If it did not, free the mutex and continue!
Here is a sample of the code to add to your apps InitInstance method :
HANDLE hMutexOneInstance =3D CreateMutex(NULL,TRUE,_T("MyInstance"));
if(GetLastError() !=3D ERROR_ALREADY_EXISTS)
{
if(hMutexOneInstance)=20
ReleaseMutex(hMutexOneInstance);
}
else
return FALSE;
Rick
----------
From: Todd Davis[SMTP:tigger@idir.net]
Sent: Tuesday, December 03, 1996 4:38 PM
To: mfc-l@netcom.com
Subject: Prevent multiple instance of dialog-based app
Environment: VC++ 4.1, Win 95
I have a dialog-based application with the modal dialog code residing in =
a
.dll. The executable logs into a server within InitInstance() and then
calls a function within the .dll that does a DoModal.
Here's my problem:
The "Onetime" sample application that demonstrates how to prevent =
multiple
instances wants to have a window registered within PreCreateWindow.
CDialog::PreCreateWindow is not called when you do a DoModal, and =
dialogs in
general don't register themselves the way frames do, it appears. I was
unable to tweak this example to work for dialog-based applications.
So I figured if you can't beat 'em, join 'em. I modified my .exe to =
have a
Frame/Doc/View architecture, to have it hide the mainframe, and run the
.dll's dialog from within my application class' override of Run (I =
don't
know if this latter is a good idea or not, but it works). I am able to
prevent multiple instances now. BUT, I want to hide the "do-nothing" =
frame
window created by the application and still have an entry for my
dialog/frame on the taskbar. Also, when I minimize the dialog, I want =
it to
go to the taskbar too, not to the bottom-left of the desktop.
Does it have to be one or the other (dialog-based many instances =
possible
vs. frame-based minimizing weirdness) or does someone know of a way to =
get
either of these possibilities to work like I want?
Panicky screams in advance,
Todd Davis
Software Engineer
Gateway 2000
| Вернуться в корень Архива
|