15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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





| Вернуться в корень Архива |