Pop-Up Frame Window


Click here to change the theme.

This is an example of creating a frame window using MFC that is separate from the MFC main frame and the MFC document/view stuff. The "Without a View" sample is incomplete.

With a View

The following can be used if you want to use a view in the window. Normally there you will have a class derived from a view class. CFormView is a view class and I will assume you have a class called CPopupView derived from a view class.

CFrameWnd* pFramePopUp = new CFrameWnd;
CCreateContext Context;
Context.m_pNewViewClass = RUNTIME_CLASS(CPopupView);
if (!pFramePopUp->LoadFrame(IDR_POPUPFRAME, WS_OVERLAPPEDWINDOW, NULL, &Context)) {
	AfxMessageBox("LoadFrame failed");
	return FALSE;
	}
CString strFullString, strTitle;
if (strFullString.LoadString(IDR_POPUPFRAME))
AfxExtractSubString(strTitle, strFullString, CDocTemplate::docName);
pFramePopUp->SetTitle(strTitle);
pFramePopUp->InitialUpdateFrame(NULL, TRUE);

Without a View

If you want to add controls dynamically then the following is one possibility, but when using VC 6 a copy constructor and opertator= must be supplied for the CFramePopUp class and I don't know how to do that.

First, create a frame window class CFramePopUp derived from CFrameWnd. Make the constructor and destructor public. Then put a pointer to a CFramePopUp in the main frame class:

CFramePopUp *m_pFramePopUp;

Create a member variable in the CMainFrame class for the window's class name:

CString m_ClassName;

In PreCreateWindow of the CMainFrame class and in the override save the window class name for use later:

m_ClassName = cs.lpszClass;

In the CMainFrame::OnCreate use something such as the following (you will want to customize the values for the size and position rectangle):

	DWORD Style;
	CRect Rect;
	WNDCLASS wndcls;
SystemParametersInfo(SPI_GETWORKAREA, 0, &Rect, 0);
Rect.left = lpCreateStruct->x;
Rect.top = lpCreateStruct->y;
Rect.right = (Rect.right >> 2) + lpCreateStruct->x;
Rect.bottom = (Rect.bottom >> 2) + lpCreateStruct->y;
m_pFramePopUp = new CFramePopUp;
Style = WS_POPUPWINDOW|WS_CAPTION|WS_THICKFRAME|WS_VISIBLE;
Style |= WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_CHILD;
::GetClassInfo(AfxGetInstanceHandle(), m_ClassName, &wndcls);
const char* pszClassName = AfxRegisterWndClass(wndcls.style);
if (!m_pFramePopUp->CreateEx(0, pszClassName, "Popup Frame", Style, Rect, this, 0)) {
	MessageBox("The Popup Frame window was not created");
	return -1;
	}

Notice that using the window class name I get the window class style from the main frame window and  use it. The CFramePopUp window is separate from the main frame because I use the WS_POPUPWINDOW style (See Pop-up Windows). It is not necessary to use SystemParametersInfo; I use it to calculate a window size and position but you can do it any way you need to. To put something in the window, you can create controls in CFramePopUp::OnCreate. The following will create an edit control in the window:

if (!m_EditBox.Create(WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE,
		CFrameWnd::rectDefault, this, IDC_STATIC)) {
	MessageBox("The edit control was not created");
	return -1;
	}
m_EditBox.SetWindowText("This is the edit control;\r\nobviously it was created");

Where m_EditBox is defined as:

CEdit m_EditBox;

If the following is used in the WM_SIZE handler (CFramePopUp::OnSize) then the edit control will be resized when the the frame window is resized:

if (nType==SIZE_RESTORED || nType==SIZE_MAXIMIZED) {
    m_EditBox.MoveWindow(0, 0, cx, cy);
    }

Variations

Alternatives to the CFrameWnd class for deriving from are CWnd and CMiniFrameWnd. If you use one of them you might get a memory leak if you do not delete the object in PostNcDestroy. This is not necessary for CFrameWnd because they delete themselves by default. If you create the window object in the heap and have no other place to delete it that is more appropriate then you can delete it in PostNcDestroy as in the following:

void CWndPopUp::PostNcDestroy() {
CWnd::PostNcDestroy();
delete this;
}