 |
|
 |
New Project Wizard > Visual C++ > MFC > MFC Application > Application type: Multiple top-level documents
|
|
|
|
 |
|
 |
Hi,
Can you tell me if I am free to use this in a comercial application?
Thanks
|
|
|
|
 |
|
 |
This class is wonderful. Thanks.
I noticed that if the application ever pops up a message box it is possible that it will use the first frame that was created instead of the active frame for the parent of the dialog box. This activates the other frame and is annoying. This can be fixed by overriding DoMessageBox. I tried override WM_ACTIVATE in CTopLevelFrame and setting m_pMainWnd to this when a window was activated (only for WA_ACTIVE and WA_MOUSEACTIVE) but that didn't work. Anyways, here is the code for the CWinApp::DoMessageBox override.
int CMultiTopApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
{
CWnd* pActiveWnd = CWnd::FromHandle(GetForegroundWindow());
CFrameWnd* pParentFrame = NULL;
if (NULL != pActiveWnd){
if (pActiveWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd))){
pParentFrame = (CFrameWnd*)pActiveWnd;
} else {
pParentFrame = pActiveWnd->GetParentFrame();
}
}
CWnd* pOldMainWnd = m_pMainWnd;
if (NULL != pParentFrame){
m_pMainWnd = pParentFrame;
}
int nRet = CMultiTopApp::DoMessageBox(lpszPrompt, nType, nIDPrompt);
m_pMainWnd = pOldMainWnd;
return nRet;
}
-Kevin Hoffman
|
|
|
|
 |
|
 |
Thank you for your great sample.
But How can I get only one icon on start bar of Windows when I minimized the MainForm of the application?
|
|
|
|
 |
|
 |
Great ! Good job !
Its almost that I am looking for.
I just change few lines of your code, and implemented on MDI.
I am using in Doc/View Architecture.
Thanks.
Rodrigo Pinho Pereira de Souza
|
|
|
|
 |
|
 |
I want write a mfc application(MDI doc/view) same as winword 2000(XP) style.
A document appear in Taskbar
|
|
|
|
 |
|
 |
I've added a small function to CMultiTopApp that allows you close frame windows only of a certain type. In my situation, I've got a screen to browse the database records, one to browse images and one to edit each individual image. If the user closes the image browsing screen, all the image editing screens need to close:
/*
* Close frames of the appropriate type, as long as it is not the main window
*/
void CMultiTopApp::CloseFramesKindOf(const CRuntimeClass * pClass)
{
MSG msg ;
//
// clear out pending messages
//
while( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
::DispatchMessage( &msg ) ;
std::list::iterator ppFrame = m_listMainFrames.begin() ;
while ( ppFrame != m_listMainFrames.end() )
{
if ( (*ppFrame) != m_pMainWnd )
{
if ((*ppFrame)->IsKindOf(pClass))
{
(*ppFrame)->PostMessage( WM_CLOSE ) ;
}
}
ppFrame++ ;
//
// because top-level window processing is based on both WM_CLOSE
// and WM_DESTROY being processed, we make sure that all messages
// have been processed before continuing
//
while( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
::DispatchMessage( &msg ) ;
}
}
declared as:
void CloseFramesKindOf(const CRuntimeClass * pClass);
and to use it:
CMultiTopApp * pApp = (CMultiTopApp*) AfxGetApp();
pApp->CloseFramesKindOf(RUNTIME_CLASS(CEditFrame));
I thought I'd post just in case anyone else found it useful (not that it's hard to work out for yourself!
|
|
|
|
 |
|
 |
Hi, I am new to GUI development and have currently being working with Borland C++ Builder 6. I was wondering if anyone knows how to accomplish the multiple top level windows program described in the article above using the Borland libraries.
Thanks
Ryan
|
|
|
|
 |
|
 |
Just something to look out for in the future
I don't remember seeing the option in VC++ 6, but the MFC class wizard in the .NET version theres an option for a "Mulitple Top Level Frame" application.
Looks like they've taken note and removed the need for this idiom
|
|
|
|
 |
|
 |
Just tried this out. Their implementation is limited in that if any frame is closed the whole application is closed.
|
|
|
|
 |
|
 |
Are you sure ?
I just tried a simple test. Created a Visual C++, MFC Application, Multiple Top Level everything else default. Select "New Frame". From this point there are two distinctions dependent upon which Frame you decided to close.
Case 1 - If you close the originating frame (parent) then you're correct all frames do close.
Case 2 - If you close the newly created frame (child) that is the only frame closed, the parent isn't touched.
I suppose it all depends on your requirements. I'd guess overriding the onClose method of the parent is one option, but I'm not sure how well this sits with killing the parent frame and having the child window living. Maybe the orginal idiom does have advantages, unfortunately I haven't the time to look into this fully now, was something I worked on 6 months ago.
I just wanted to make people aware of the options.
GL with your project.
|
|
|
|
 |
|
 |
Hi James,
Yeh, looking at what I wrote before, I didn't make it very clear did I? What you've written is what I was trying to say.
In the application I'm writing, I've got three CFrameWnd classes that perform three distinct functions - searching, browsing and editing. They all connect to the same document. I'm switching from one frame window to the next (only keeping one open at a time), as the user moves around the application. I'm finding that it's a little disconcerting for the user to see the window disappear and another one pop up. I'm going to try and change it so that the new window opens in exactly the same size as the previous window....
|
|
|
|
 |
|
 |
Great example, but it's seems to be missing any mention of documents.
I'm asking because this code doesn't use the CDocTemplate to create a frame-view-doc triplet, but the more brute-force approach of calling CFrameWnd::LoadFrame and CView::Create.
So what's the glue code to tie in documents into this architecture?
|
|
|
|
 |
|
 |
Multiple Top-Level Windows in Internet Explorer and Netscape are seperate threads of the same process, and it's OK; they have Taskbar entries.
When you have a thread that's just a worker function, we call it a "worker thread;" an example is a function that performs some math.
However, anytime a Window appears on the screen, it's part of a "user-interface thread." The way CWinApp is implemented was changed in MFC 4.2 under VC++ 6. The main window that you see is actually the main window of the only user-interface thread your program creates. Notice that CWinApp isn't derived from CCmdTarget directly anymore; it's now derived from CWinThread, the base-class for all user-interface threads.
To start, look up AfxBeginThread() in the help. This article is a good start, but is really a kludgy hack when you consider how it's done, what with main window lists and all.
Also, there are several MFC samples which illustrate multi-threadedness, and I'm sure there's a MultiPad version which is multi-UI-threaded. Let your mouse do the walking!
Yours,
Brian Har
|
|
|
|
 |
|
 |
Whether or not you have multiple UI threads (I've never seen the point myself), MFC needs to be accomodated if you're going to have multiple top level windows.
Look at the MFC source code.
When a CFrameWnd receives a WM_CLOSE message _AND_ it is pointed to by the CWinApp's m_pMainWnd member, it tries to end the program. The classes in the article juggle m_pMainWnd so that MFC only ends the program when the last TLW is closed
|
|
|
|
 |
|
 |
Brian:
I have been writing Windows applications using Stingray's MTI class for three years now. This class enables your application to have multiple top level windows within a single thread. I have the Stingray source, and while their implementation is somewhat cleaner, the core functionality is the same. By the way, Stingray does have a multi-UI-threaded Multipad example.
Regards,
Rob Krakor
|
|
|
|
 |
|
 |
Just got a taste of doing mutithreading in MFC and found that transfering data between threads is a major task in MFC.
It appears that MFC went to lot of trouble keeping threads from stepping on each other but forgot that the purpose od many application is to process data. MFC does not do that well - for example I ended up posting a message in a new thread to MFC MainFrame and propagating this message to the view for processing. Simply put - long way around the barn process.
I have not tested this application - I do need doc/view.
What I need is single user interface and than I need multi document with muti view and be able to process these and show results to the user.
What I have done so far - using multithreading is complicated way to do it.
|
|
|
|
 |
|
 |
Hi Rob, di you know what the sample is called?
|
|
|
|
 |
|
 |
Hello!
I saw your article and I does the same as the MTI model in Stingray Objective Toolkit. All window are top-level and that's OK. However every window also get an entry in the taskbar.
My app works like the old Visual Basic, with one top-window with menus and the N dialogs/windows with grids/formviews.
Stingray also have a FDI model which I use today. However that model has the flaw that the parent is always 'behind' any of its children.
So the MTI model creates too many taskbar entries (otherwise perfect for me) and the FDI model makes the 'main' window hard to find if hidden by child windows (otherwise it's fine too).
Isn't there any way I can have the best of both worlds?
Contact me on via e-mail if you need more info. I value all input on this topic since I have no idea how to solve this.
/Peter
|
|
|
|
 |
|
 |
Peter:
Hi, my name is Rob Krakora, and I am a Software Engineer with Thomson Consumer Electronics (RCA) in Indianapolis, Indiana. I to use the MTI from Stingray, and if you take a gander at Chris Maunder's article "Creating an application with no taskbar icon" in the "Doc/View" section and implement his code snippet, your problem is solved. I tried it in my MTI based application and the top level windows no longer show up in the task bar, but they can still be minimized on the desk top. See the code snippet below borrowed from Chris's article and modified to replace CFrameWnd with SECToplevelFrame.
Happy coding,
Rob Krakora
class CMainFrame : public SECToplevelFrame
{
...
protected:
CWnd m_wndInvisible;
...
Then override CMainFrame::PreCreateWindow:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if (!SECToplevelFrame::PreCreateWindow(cs))
return FALSE;
// Create invisible window
if (!::IsWindow(m_wndInvisible.m_hWnd))
{
LPCTSTR pstrOwnerClass = AfxRegisterWndClass(0);
if (!m_wndInvisible.CreateEx(0, pstrOwnerClass, _T(""), WS_POPUP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, 0))
return FALSE;
}
cs.hwndParent = m_wndInvisible.m_hWnd;
return TRUE;
}
|
|
|
|
 |
|
 |
I have seen people mention STRINGRAY Stuido. Do you or anyone else have a ballpark pricing scheme for the studio? Their website just says contact a sales rep. I made that mistake once with another company and now I get hounded constantly about when I would like to purchase the product.
If they would just post a price I can say heck no, being a small time developer one who writes applications for in house development as well as some small hobby apps can't really afford the 1K-3K pricetags of many of the library and tools I would really like
Sam C
----
Allsys Technologies
http://www.allsystech.com
"Making software simpler..."
|
|
|
|
 |
|
 |
Sounds like the menu in a fancy restaurant: If you need to ask, then you can't afford it
|
|
|
|
 |