Click to See Complete Forum and Search --> : A new window?


xyjiang
May 18th, 1999, 09:54 AM
How do I make a new window?

I want to make a new windows when I press a button. How to do?

BrianOG
May 18th, 1999, 09:55 AM
CWnd::Create

xyjiang
May 19th, 1999, 05:19 AM
virtual BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);

I really have no sense with this function. How do I start? I have the code below:


void CMyView::OnShowWindow()
{
// TODO: Add your command handler code here

}

BrianOG
May 19th, 1999, 05:31 AM
>> How do I start?

By looking up "creating windows" in the VC (MSDN) help.


There is no one answer to your question, it depends on what type of window you want, what you want it for, what you want to do with it etc.

May 19th, 1999, 10:24 AM
Hello,

There are indeed many ways to create a window, without wanting to seem patronising, perhaps this would be of any help:

Having created a new dialog in the resources, create a class for it using the class wizard. From the mainframe, create a handler for your button and enter...

CMyDialog m_MyDialog;
m_MyDialog.DoModal();

xyjiang
May 20th, 1999, 11:45 PM
I have already looked it, but I still don't know how to do. The document in MSDN only describes the concepts of creating a window. That is not what I need.

Now, I can create a new window by application wizard and place a button on tool bar. What I want is that when I press the button on tool bar, my program will produce a new MDI window with tool bar.

xyjiang
May 20th, 1999, 11:47 PM
I know the way that you say. But I want to create a new MDI window. A dialog box is not a good solution... :(

Jason Teagle
May 21st, 1999, 03:00 AM
Here is a part solution to your problem. This solution assumes that your app is already an MDI app, and it assumes that you want to use exactly the same class of CMainFrame, CChildFrame, CxxxDoc, CxxxView and resources (icon, toolbar, menu, etc.) for the other top-level frames you create. Details of how to use different classes, and of how to deal with the other major problem this solution poses, are given afterwards.

1) In your CMainFrame class, add a private BOOL member variable called m_bIsMainFrame. This will indicate whether this is the original frame of your app, or one of the alternate frames you have created. In your CMainFrame constructor, add the following line:

--- m_bIsMainFrame = FALSE ;




---

2) In your CMainFrame class, add two functions, as follows:

---void CMainFrame::SetIsMainFrameFlag(BOOL bIsMainFrame)
{
m_bIsMainFrame = bIsMainFrame ;
}

BOOL CMainFrame::IsMainFrame(void)
{
return m_bIsMainFrame ;
}




---

3) Add a handler for the WM_DESTROY message (NOT DestroyWindow as shown in the override list) for your CMainFrame, using ClassWizard, and code it as follows:

---void CMainFrame::OnDestroy()
{
// Remember, the main frame is not stored in the array, although it would have
// been safe to call the remove function anyway.
if (!IsMainFrame() )
theApp.RemoveFrame(this);

CMDIFrameWnd::OnDestroy();
}




---

This completes the changes to the main frame window.

4) In your app class' header file, add the following line at the very bottom, outside of the class definition (but if the #ifndef - #define - #endif construct has been used, it should obviously be within this!):

---extern CMyApp theApp ;




---

(change CMyApp to your app's class name). This allows other classes to access the main app global variable easily.

5) In your app class, add a private CObArray member variable called m_aryObFrames. This stores pointers to the alternate frames, but not the main frame; this allows them to be destroyed when the application exits if they haven't already been destroyed.

6) In your app's InitInstance() method, AFTER the main frame is created and assigned to m_pMainWnd, add the following line:

--- pMainFrame->SetIsMainFrameFlag();




---

7) Using ClassWizard, add an override for the ExitInstance() method for your app. Put the following code in it:

---int CMyApp::ExitInstance()
{
CFrameWnd *pFrame ;
UINT n, uSize ;

uSize = m_aryObFrames.GetSize();
for (n = 0 ; n < uSize ; n++)
{
pFrame = (CFrameWnd *)m_aryObFrames.GetAt(n);
if (pFrame != NULL)
{
// CFrameWnds delete their own MFC wrapper object.
pFrame->DestroyWindow();
}
}

return CWinApp::ExitInstance();
}




---

8) In your app class, add two functions, as follows:

---
void CMyApp::AddFrame(CFrameWnd *pFrame)
{
m_aryObFrames.Add(pFrame);
}

void CMyApp::RemoveFrame(CFrameWnd *pFrame)
{
CFrameWnd *pTempFrame ;
UINT n, uSize ;

// Note that we only remove its entry from the array, we don't attempt to
// delete it - that is done automatically when the window is closed.
uSize = m_aryObFrames.GetSize();
for (n = 0 ; n < uSize ; n++)
{
pTempFrame = (CFrameWnd *)m_aryObFrames.GetAt(n);
if (pTempFrame != NULL && pTempFrame == pFrame)
{
m_aryObFrames.RemoveAt(n);
break ;
}
}
}




---

This concludes the changes to the app.

9) Finally, in your handler for the toolbar button that you want to create the new frame, put the following code:

---
void CMyView::OnBtnNewFrame()
{
CMainFrame* pMainFrame = new CMainFrame;
if (pMainFrame->LoadFrame(IDR_MAINFRAME) )
{
pMainFrame->ShowWindow(SW_SHOWNORMAL);
theApp.AddFrame(pMainFrame);
}
}




---

Unless I have missed anything, you should now be able to compile this and run it. You will see that new top-level frames are created when you click the button, and no memory leaks when the app exits.

* If you want to use different resources, simply change the IDR_MAINFRAME in the routine for creating new frames.

* If you want to use different classes, you will have to create them using ClassWizard, create a new CMultiDocTemplate (which you should NOT add to the app object, but rather store a pointer to the CMultiDocTemplate so that you can access it). You will then have to override the file new / open / close behaviour, as explained below, and use the new template for the other frames.

* As it stands, this code is not enough; although it creates the frames, you will find that opening a file, closing a file or creating a new file will do so in the ORIGINAL FRAME. This is because these functions are handled in the app by default, and that uses the top-level frame registered as the app's main frame.

So, you will have to provide your own functions within your app to mimic these functions (copy them from the MFC!), but use the alternate frame for creation - I recommend that your new routines take a pointer to a CMainFrame, so that it knows where to create the child frames. Also, this is where you would use the alternate doc template to create child frames with different docs and views, if that's what you want. I'm not sure how closing the document will behave, but I'm sure you'll find that out.

If you still need further help on this, let me know (jteagle@solartron.com), but this should be more than enough to get you going.