One instance
SIT/CS -- tangst@nyp.ac.sg Wednesday, April 03, 1996 I am working on MFC 2.5 on MS Windows 3.11 I want to restrict my application to one instance only. If there is previous instance exist, the previous window is activated. I read the FAQ, the answer is seem for MFC 4.0. It provides the following: const char * MyMainWndClassName = "MyScribble"; BOOL CMyApp::InitApplication() { ... ::GetClassInfo(AfxGetInstanceHandle(), "AfxFrameOrView", &wndcls); wndcls.lpszClassName = MyMainWndClassName return ::RegisterClass(&wndcls); } I did the same thing in my application. However, the WinMain in MFC 2.5 performed the following: int PASCAL WinMain(...) { ... // App global initializations (rare) if (hPrevInstance == NULL && !AfxGetApp()->InitApplication()) goto InitFailure; ... } Since hPrevInstance is not NULL, the AfxF=GetApp()->InitApplication() never get executed. Therefore, the wndcls.lpszClassName does not get changed to "MyScribble". In MyApp::InitInstance(), I am unable to find the window of the previous instance using FindWindow(MyMainWndClassName, NULL) because MyMainWndClassName is not initialized. Does anyone have a solution to restricting application to one instance in MFC 2.5? Appreciate any help. Thanks Tang S. T.
David W. Gillett -- DGILLETT@expertedge.com Thursday, April 04, 1996 [Mini-digest: 2 responses] > I am working on MFC 2.5 on MS Windows 3.11 > > I want to restrict my application to one instance only. If there > is previous instance exist, the previous window is activated. Absolutely the easiest way to do this is to build your app using the "large" memory model and turn on the "extern and uninitialized data 'far'" option. You might, just possibly, still need to specifically designate some global/static variable as 'far', but most likely not. What we're trying to do here is force the linker to create an executable with two or more data segments. 16-bit Windows can't run multiple instances of such an .EXE, and when the user tries to start a second instance, Windows will instead activate the instance already running and bring it to the front. And that's what you want. There might be some reason why you don't want to take the easy way. If hPrevInstance is non-zero, you know that there's already an instance running. The problem is to activate that instance's window and bring it to the foreground. The documented/recommended approach is to use FindWindow(). It has looked to me like it should also be possible to make it work with GetInstanceData(), but I have never actually gotten that to work.... [Matt Pietrek has covered this question extensively in articles for MSJ which are on the MSDN CD-ROM....] Dave -----From: "VARughese GEOrge"hi, try to use this code in the beginig of InitInstace. BOOL CMyApp::InitInstance() { // Do not run the second Instance HWND hFirsthWnd, hFirstChildhWnd; if (m_hPrevInstance != NULL) { ::GetInstanceData(m_hPrevInstance, (unsigned char *)&FirsthWnd,2); if (hFirsthWnd ) { hFirstChildhWnd = ::GetLastActivePopup(hFirsthWnd); ::BringWindowToTop(hFirsthWnd); // Bring main window to top. if (hFirsthWnd != hFirstChildhWnd) ::BringWindowToTop(hFirstChildhWnd);//A pop-up is active so bring it to the to top too. return (FALSE); // Do not run second instance. } } // go with the first instance... ...... } hopw this helps thanx vargeo http://www.ramco.com/vargeo.htm
Chong Zhang -- cz@dana.ucc.nau.edu Friday, April 05, 1996 We used to have problem of making our MFC-based application multiple instance one. In Win3.11, your application will be single instanced if it has multiple data segment. So if you declare DATA MULTIPLE in your .DEF file, it do the trick. Or you can declare some global objects, such as a CString object CString myGlobalText; then the linker will treat your application as one with multiple DATA segments and your application will be single instanced. On Wed, 3 Apr 1996, Tang Siong Tiing, SIT/CS wrote: > > I am working on MFC 2.5 on MS Windows 3.11 > > I want to restrict my application to one instance only. If there is previous > instance exist, the previous window is activated. > > I read the FAQ, the answer is seem for MFC 4.0. It provides the following: > const char * MyMainWndClassName = "MyScribble"; > BOOL CMyApp::InitApplication() { > ... > ::GetClassInfo(AfxGetInstanceHandle(), "AfxFrameOrView", &wndcls); > wndcls.lpszClassName = MyMainWndClassName > return ::RegisterClass(&wndcls); > } > > I did the same thing in my application. However, the WinMain in MFC 2.5 > performed the following: > int PASCAL WinMain(...) > { > ... > // App global initializations (rare) > if (hPrevInstance == NULL && !AfxGetApp()->InitApplication()) > goto InitFailure; > ... > } > > Since hPrevInstance is not NULL, the AfxF=GetApp()->InitApplication() never > get executed. Therefore, the wndcls.lpszClassName does not get changed to > "MyScribble". > > In MyApp::InitInstance(), I am unable to find the window of the previous > instance using FindWindow(MyMainWndClassName, NULL) because > MyMainWndClassName is not initialized. > > Does anyone have a solution to restricting application to one instance in > MFC 2.5? > > Appreciate any help. > > Thanks > Tang S. T. >
Crucial Software -- crucial@ix.netcom.com Friday, April 05, 1996 ------ =_NextPart_000_01BB23C0.F18C0900 Content-Type: text/plain; charset="us-ascii"
David W. Gillett -- DGILLETT@expertedge.com Monday, April 08, 1996 > >> What we're trying to do here is force the linker to create an > >> executable with two or more data segments. 16-bit Windows can't run > >> multiple instances of such an .EXE, and when the user tries to start > >> a second instance, Windows will instead activate the instance already > >> running and bring it to the front. And that's what you want. > > Windows does _NOT_ do this. If you try and run a 16-bit application with > multiple, writable data segments, WinExec() will fail with the appropriate > error code (there is one indicating this). Program Manager displays an > error message box indicating the problem. I do not get any such message from Program Manager -- I get the running instance activated and brought to the front. Same thing from File Manager. According to MSJ's "Windows Q and A" column, 1994 - number 6, the magic to activate the first instance in this case is in the ShellExecute() function. So it appears that perhaps the missing key is simply to use ShellExecute() instead of calling WinExec() directly. Dave
| Вернуться в корень Архива |