Q: How would I encapsulate a control in a window that can be placed on a dialog in MFC? I wish to have a window that will be placed on a dialog that can contain another control.  The reason for this is so that I can have the encapsulated control exceed the size of the allocated area on the dialog and have independent scrollbars to see the full control.
This description sounds like there should be something that is already made for this.  Is that correct?  If so, what is it?  If not, how would I go about doing this?
EDIT
Oh wait, I have seen this.  With tabbed pages.  These actually create a dialog that is parented to the main dialog.  If the page is too small, scrollbars appear.  So this is possible to do, just have to figure out how.  Playing around with VS, there is a Custom Control which may be what I'm looking for.

A: To encapsulate a control in a dialog to be used within a dialog, do the following:


*

*Create dialog resource and empty it (i.e. delete all controls on it) and set the following flags:


*

*Appearance


*

*Border: Thin

*Style: Child

*Title Bar: False // automatic


*Behavior


*

*Application Window: False // automatic


*Misc


*

*Control: True

*ID: IDD_CONTROL_WRAPPER (or whatever you want)



This will be the wrapper dialog.

*Create a class for the wrapper dialog (right click on dialog and select Add Class...), I'm going to call it CControlWrapper for these instructions.

*In your wrapper dialog, add the control you wish to encapsulate to your class and add a variable to associate with it (In my example, I'll use a listbox with the id IDC_WRAPPED_CTRL and the member variable name m_ctrl).

*To make it so that the control takes up the entire space of the dialog:


*

*Add ON_WM_SIZE() message to your to your wrapper dialog's message map.

*Create the OnSize() function.


Or use the wizard.  Your OnSize() function should look like something like this:
void CControlWrapper::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    if (m_ctrl.m_hWnd)
        m_ctrl.SetWindowPos(nullptr, 0, 0, cx, cy, SWP_SHOWWINDOW);
}

You can change the size of the control to whatever you wish.  Making it larger just makes the control get clipped.

*If you haven't done so already, create the main dialog class.

*Add the wrapped dialog control as a variable to to your main dialog class (in this example, I called it m_childDlg).

*In the main dialog's OnInitDialog() function create the dialog.
m_childDlg.Create(IDD_CONTROL_WRAPPER, this);


*Set it's position and size:
m_childDlg.SetWindowPos(0, 8, 8, 500, 500, SWP_SHOWWINDOW);

And that's it!
Here are some optionals you can do.


*

*To make it so that you can use the dialog editor to position your control on the main dialog, you can make it so that the encapsulated control can just place itself over the one you specified:
void CControlWrapper::CreateOvertop(CWnd* pParent, int originalId)
{
    CreateOvertop(pParent, pParent->GetDlgItem(originalId));
}

void CControlWrapper::CreateOvertop(CWnd* pParent, CWnd* pOrignalWnd)
{
    // Create the control wrapper
    Create(IDD_CONTROL_WRAPPER, pParent);

    // This two lines makes it so that the drawing zorder is respected
    ModifyStyle(0, WS_CLIPSIBLINGS);
    // Also this line stops the original window from having a tab stop,
    // if not cleared in dialog editor.
    pOrignalWnd->ModifyStyle(WS_TABSTOP, WS_CLIPSIBLINGS);

    // Position the control wrapper dialog control over the old control
    CRect rect;
    pOrignalWnd->GetWindowRect(rect);
    pParent->ScreenToClient(rect);
    // position this control over old control less border
    SetWindowPos(pOrignalWnd->GetWindow(GW_HWNDPREV)
        , rect.left + 2, rect.top + 2, rect.Width() - 4, rect.Height() - 4
        , SWP_SHOWWINDOW);
}

Then from the main dialog's OnInitDialog(), you can call either of those functions instead of the CControlWrapper::OnCreate(), and your control will use the border of the control it is replacing.

*Add the WRAPPED_CTRL* CControlWrapper::operator->() so that you can easily access the wrapped object.

*The sky is the limit... :)

