Multiple Top-level Windows
Lance Lovette -- lovette@iftech.com Wednesday, August 14, 1996 Environment: MSVC 4.2, NT 3.51 SP4 I would like to create an application that has multiple top-level windows. (I'm not sure how to explain this so please bear with me.) For example, when exploring 'My Computer' on Windows 95, (by default) every time you open a directory, a new window is created that shows the contents of that directory. Another example is DISPTEST, where there are multiple windows for different functions. Sort of like having multiple MDI child frame windows without the MDI parent frame window. My question is, how would you do this in MFC? Can you just create new CFrameWnd's that are children of the desktop and have a "main" frame window that m_pMainWnd points to? Or would you implement each as a modeless dialog (then you would lose the ability to use views)? Does the framework have any problems with multiple frame windows? I looked for an example in the obvious places (which for me is the Books Online, the MSDN CD, the MFC FAQ, and each of the four MFC books I have on hand), but I can't find anything. Probably because I don't know what terminology to use. Thanks, Lance lovette@iftech.com +-------------------------------------------------------------------+ Interface Technologies, Inc. For a collection of free tutorials covering a variety of programming and computer-related topics such as Visual C++, MFC, and Windows NT check out the ITI On-line Training Center at http://www.iftech.com.
Don.Irvine@net-tel.co.uk Friday, August 16, 1996 [Mini-digest: 8 responses] > I would like to create an application that has multiple top-level > windows. (I'm not sure how to explain this so please bear with me.) > For example, when exploring 'My Computer' on Windows 95, (by default) > every time you open a directory, a new window is created that shows > the contents of that directory. Another example is DISPTEST, where > there are multiple windows for different functions. Sort of like > having multiple MDI child frame windows without the MDI parent frame > window. Stingray have an MFC extension class for MTI - you may want to checkout their WEB page http://www.stingsoft.com/ Don -----From: Deepak SaxenaText item: I'm doing this with my app and what I do is just create new CFrameWnd derived windows dynamically. Basically your App becomes a manager for all the windows and keeps a list of all windows that exist. Whenever a top-level wnd is destroyed, it notifies the app. When all windows have been closed, you can exit the app by posting a WM_QUIT message. If a user closes the original top-level wnd but keeps another open, you might have to watch out for what happens with CWinApp::m_pMainWnd, since it will point to an invalid window. Deepak -----From: Jim Leavitt Lance: Stingray software has written the classes to accomplish the top level interface. They are in their Objective Toolkit product. Jim Leavitt -----From: Hugh Robinson This is not an advert, but if you value your time more than your bosses' cash (!), you could investigate Objective Toolkit from Stingray Software www.stingray.com. This includes some classes to do what you need with very little code change from a regular MDI application. Hugh Robinson -----From: michael berganovsky Hi, Lance In general when you need another top-level window (in MFC app) you can just derive a class from CFrameWnd or CWnd and go. Unfortunately if you are planning to use MFC support for Doc-View-Frame staff (and when you want MFC OLE support you have no other choice) picture becomes much more complicated. Before you start - decide what will be your UI model? How you want your COMMANDs to be processed. Are your menus in the main (parent) frame and buttons on the main TOOLBAR depend on what top-level window is currently active? Do you have main window at all? Then if your application and resources model allows - you can buy SEC++ from Stingray. SEC++ (if my memory doesn't fail me) supports several UI models on top of MFC - like multiple SDI windows for example. (You can also look into SEC++ source). On the other hand you can take winfrm.cpp and winmdi.cpp out of MFC sources and modify them - building you own UI model. I did that making my app look something like VB - all windows are WS_POPUPs and forms are WS_OVERLAPPED and I survived. Good luck --Michael Berganovsky -----From: Dave Kolb Go to Stingray Software's www.stingsoft.com and download the demos for = Objective Toolkit. They have several MDI variations including TDI or Top = Level Windows like VB has. I don't use OT yet but do use their Objective = Grid product and am pretty happy with it. Dave Kolb PC Research and Development SAS Institute Inc. 919-677-8000 x6827 -----From: "Rex Lam" > Environment: MSVC 4.2, NT 3.51 SP4 There are several ways to do this. One is to create simple modeless dialog or some CWnd-derived object. But I assume that you probably has a frame window with client views with menubars, toolbars, statusbars etc (the works)... That requires just little more work. The document-view architecture makes this simple and straight- forward-- it allows mutliple doc-view templates within an app. Here are the steps: 0. Create your additional docs, views and frame classes. 1. Add document templates to the app. 2. Write a handler to bring up the frame window. Step 1: ------- In your CMyApp::InitInstance() add all templates needed: BOOL CMyApp::InitInstance() { ... // save the template pointers!! m_pMainDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME, RUNTIME_CLASS(CMainDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CMainView)); m_pMainDocTemplate2 = new CSingleDocTemplate(IDR_MAINFRAME2, RUNTIME_CLASS(CMainDoc2), RUNTIME_CLASS(CMainFrame2), RUNTIME_CLASS(CMainView2)); m_pMainDocTemplate3 = new CSingleDocTemplate(IDR_MAINFRAME3, RUNTIME_CLASS(CMainDoc3), RUNTIME_CLASS(CMainFrame3), RUNTIME_CLASS(CMainView3)); .... } Step 2: ------ The trick is to call CDocTemplate::InitialUpdateFrame() to create the new frame which indirectly creates the view. The documentation indicates that the document should also get created by the framework. My experience is that this is NOT the case. I had to create the document myself. It took me a while to get it resolved. May be it is fixed in VC++ 4.2? BOOL CMyApp::OnLaunchFrame(LPARAM lParam) { CSingleDocTemplate *pDocTemplate = NULL; CDocument* pDoc = NULL; if (lParam == FRAME2) { pDoc = new CMainDoc2(); pDocTemplate = pMainDocTemplate2; } if (lParam == FRAME3) { pDoc = new CMainDoc3(); pDocTemplate = pMainDocTemplate3; } ASSERT_VALID(pDocTemplate); pFrame = pDocTemplate->CreateNewFrame(pDoc, NULL); ASSERT_VALID(pFrame); if (pFrame) { // frame successfully created frame pDocTemplate->InitialUpdateFrame(pFrame, pDoc, 1); // update frame to make visible return TRUE; } return FALSE; } And that's it! The frame should come up and everything is working. But keep in mind that there some abnomalities that you have to deal with. The frame work will use your initial document template as THE template. For example, this makes your first frame as the parent window when display messageboxes e.g. But once you take care of the little things, you'll be surprised how well it works! Good luck... -Rex Lam Global Village Communications Inc. Telephone: (408) 523-2040 Internet: Rex_Lam@globalvillage.com -----From: tim Environment: MSVC 4.1, NT 4.0 BETA This may not answer you question, but the Stingray objective toolkit has just this sort of thing and more. source is available. This is not an ad, I am using it in a project that I am working on. tim@mstus.com Marconi Systems Technology Reston, Virginia
Roger Onslow -- Roger_Onslow@compsys.com.au Tuesday, August 20, 1996 >I would like to create an application that has multiple top-level >windows. (I'm not sure how to explain this so please bear with me.) This is what I did for similar functionality... I had menu items Window|New, Window|Close to create/close new windows In doc class had handlers for them as follows ON_COMMAND(ID_WINDOW_NEW, OnWindowNew) ON_UPDATE_COMMAND_UI(ID_WINDOW_CLOSE, OnUpdateWindowClose) void CMyDoc::OnWindowNew() { CDocTemplate* pDocTemplate = GetDocTemplate(); if (! pDocTemplate) { ASSERT(FALSE); return; } // create frame - set as main document frame BOOL bAutoDelete = m_bAutoDelete; m_bAutoDelete = FALSE; // don't destroy if something goes wrong CFrameWnd* pMainFrame = pDocTemplate->CreateNewFrame(this, (QIDMainFrame*)::AfxGetMainWnd()); m_bAutoDelete = bAutoDelete; if (pMainFrame == NULL) { ASSERT(FALSE); // ::AfxMessageBox(::AFX_IDP_FAILED_TO_CREATE_DOC); return; } pDocTemplate->InitialUpdateFrame(pMainFrame, this, TRUE); m_nAdditionalFrames++; // my member var to count number of windows pMainFrame->ShowWindow(SW_RESTORE); // optional -- add an offset to each window so they "cascade" CRect rect; pMainFrame->GetWindowRect(rect); rect += CSize(m_nAdditionalFrames*::GetSystemMetrics(SM_CXMIN),m_nAdditionalFrames*::GetSystemMetrics(SM_CYMIN)); pMainFrame->MoveWindow(rect); } void CMyDoc::OnUpdateWindowClose(CCmdUI* pCmdUI) { pCmdUI->Enable(m_nAdditionalFrames > 0); } void CMyDoc::CloseFrame(CMainFrame* pMainFrame) { if (pMainFrame) pMainFrame->DestroyWindow(); pMainFrame = (CMainFrame*)::AfxGetMainWnd(); if (pMainFrame) pMainFrame->SetActiveWindow(); m_nAdditionalFrames--; } In my main frame class I had this... ON_COMMAND(ID_WINDOW_CLOSE, OnWindowClose) void CMainFrame::OnWindowClose() { CMyDoc* pDoc = (CMyDoc*)GetActiveDocument(); if (pDoc) pDoc->CloseFrame(this); } Hope this gives you a starting point!! Roger Onslow Senior Software Engineer Computer Systems Australia RogerO@compsys.com.au
| Вернуться в корень Архива |