Forms-Based Applications

OverviewHow Do I

is the base class for form views. A form view is essentially a view that contains controls. A forms-based application lets the user create and use one or more forms within the application, as do the AppWizards and other dialog-based applications. The view class of a forms-based application is based on one of the form-style classes such as CFormView, CRecordView, CDaoRecordView, or CDialog.

To create a forms-based application, use one of the following procedures:

  • Create an application using MFC AppWizard. Either create a dialog-based application or select a form-style class as the view's base class.

  • . Even if your application did not initially support forms, Visual C++ will add this support when you insert a new form.

The procedures above are preferred for creating forms-based applications. Because these procedures automatically and correctly implement the forms-based architecture, you should never have to do so by hand. However, if you need to create a forms-based application without using the AppWizard or the New Form command on the Insert menu, the following steps are provided for your information. These steps are the same as those that the MFC AppWizard performs in creating a CFormView-based application.

Note   The following steps do not apply to CDialog-based applications. For dialog-based applications, the MFC AppWizard creates a CDialog-based class and a dialog resource with appropriate styles as described in step 1 below.

  1. Creating a view based on CFormView is similar to creating a dialog box. Use the dialog editor to design the dialog box.

  2. In the Styles and More Styles property pages, set the following properties:

    • In the Style box, select Child (WS_CHILD on).

    • In the Border box, select None (WS_BORDER off).

    • Clear the Visible check box (WS_VISIBLE off).

    • Clear the Titlebar check box (WS_CAPTION off).

    These steps are necessary because a form view is not a true dialog box. For more information about creating a dialog-box resource, see .

  3. Create a view class.

    With your dialog template open, run ClassWizard and choose CFormView as the class type when you are filling in the Add Class dialog box. ClassWizard creates a CFormView-derived class and connects it to the dialog template you just designed. This connection is established in the constructor for your class; ClassWizard generates a call to the base-class constructor, CFormView::CFormView, and passes the resource ID of your dialog template. For example:

        : CFormView( CMyFormView::IDD )
        //{{AFX_DATA_INIT( CMyFormView )
        // NOTE: the ClassWizard will add member
        // initialization here
        // Other construction code, such as data initialization

    Note   If you choose not to use ClassWizard, you must define the appropriate ID you supply to the CFormView constructor (that is, CMyFormView::IDD is not predefined). ClassWizard declares IDD as an enum value in the class it creates for you.

    If you want to define member variables in your view class that correspond to the controls in your form view, use the Add Variables button on the Member Variables tab of the ClassWizard. This allows you to use the dialog data exchange (DDX) mechanism. If you want to define message handlers for control-notification messages, use the Add Function button on the Message Maps tab of the ClassWizard. For more information see in the Visual C++ Programmer's Guide.

  4. Override the OnUpdate member function.

    The OnUpdate member function is defined by CView and is called to update the form view’s appearance. Override this function to update the member variables in your view class with the appropriate values from the current document. Then, if you are using DDX, use the UpdateData member function (defined by CWnd) with an argument of FALSE to update the controls in your form view.

    The OnInitialUpdate member function (also defined by CView) is called to perform one-time initialization of the view. CFormView overrides this function to use DDX to set the initial values of the controls you have mapped using ClassWizard. Override OnInitialUpdate if you want to perform custom initialization.

  5. Implement a member function to move data from your view to your document.

    This member function is typically a message handler for a control-notification message or for a menu command. If you are using DDX, call the UpdateData member function to update the member variables in your view class. Then move their values to the document associated with the form view.

  6. Override the OnPrint member function (optional).

    The OnPrint member function is defined by CView and prints the view. By default, printing and print preview are not supported by the CFormView class. To add printing support, override the OnPrint function in your derived class.

  7. Associate your view class with a document class and a frame-window class using a document template.

Unlike ordinary views, form views do not require you to override the OnDraw member function defined by CView. This is because controls are able to paint themselves. Only if you want to customize the display of your form view (for example, to provide a background for your view) should you override OnDraw. If you do so, be careful that your updating does not conflict with the updating done by the controls.

Form views support scrolling, as needed, using functionality provided by . If your view contains controls that are derived from (or instances of) CSliderCtrl or CSpinButtonCtrl and you have message handlers for WM_HSCROLL and WM_VSCROLL, you should write code that calls the proper routines. The code example below calls CWnd::OnHScroll if a WM_HSCROLL message is sent by either a spin button or slider control.

void CMyFormView::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
    if ( pScrollBar->IsKindOf( RUNTIME_CLASS( CScrollBar ) ))
        CFormView::OnHScroll( nSBCode, nPos, pScrollBar );
    else if ( pScrollBar->IsKindOf( RUNTIME_CLASS( CSliderCtrl ) ))
        CWnd::OnHScroll( nSBCode, nPos, pScrollBar );
    else if ( pScrollBar->IsKindOf( RUNTIME_CLASS( CSpinButtonCtrl ) ))
        CWnd::OnHScroll( nSBCode, nPos, pScrollBar );

If the view becomes smaller than the dialog template, scroll bars appear automatically. Views derived from CFormView support only the MM_TEXT mapping mode.

If you are not using DDX, use the CWnd dialog functions to move data between the member variables in your view class and the controls in your form view. For more information about DDX, see .

What do you want to know more about?