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/GBJEnvironment: 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
| Вернуться в корень Архива |