VC++ Multiple Views

download VC++ Multiple Views

of 55

Transcript of VC++ Multiple Views

  • 7/29/2019 VC++ Multiple Views

    1/55

    Module 14: Splitter Windows and Multiple Views

    Program examples compiled using Visual C++ 6.0 (MFC 6.0) compiler on Windows XP Pro machine with Service Pack2. Topics and sub topics for this Tutorial are listed below:

    Splitter Windows and Multiple Views

    The Splitter WindowView Options

    Dynamic and Static Splitter Windows

    The MYMFC21 Example: A Single View Class SDI Dynamic Splitter

    Resources for Splitting

    CMai nFr ame Class

    The MYMFC20 steps

    Testing the MYMFC21 Application

    The MYMFC21B Example: A Double View Class SDI Static Splitter

    The stepsCHexVi ewclass, the cloned CSt r i ngVi ewClass

    CMai nFr ame Class

    Testing the MYMFC21B ApplicationThe MYMFC21C Example: Switching View Classes Without a Splitter

    Resource RequirementsCMai nFr ame Class

    Testing the MYMFC21C Application

    The MYMFC21D Example: A Multiple View Class MDI Application

    The Steps

    Resource Requirements

    CMymf c21DApp Class

    CMai nFr ame Class

    Testing the MYMFC21D Application

    Splitter Windows and Multiple Views

    Except for the MYMFC18 example, each program you've seen so far in this book has had only one view attached to a

    document. If you've used a Microsoft Windows-based word processor, you know that it's convenient to have two

    windows open simultaneously on various parts of a document. Both windows might contain normal views, or one

    window might contain a page layout view and another might contain an outline view.With the application framework, you can use a splitter windowormultiple MDI child windowsto display multipleviews. You'll learn about both presentation options here, and you'll see that it's easy to make multiple view objects of the

    same view class (the normal view) in both cases. It's slightly more difficult, however, to use two or more view classes in

    the same application (say, the outline view and the page layout view).This module emphasizes the selection and presentation of multiple views. The examples depend on a document with

    data initialized in the OnNewDocument ( ) function. Look back now to Module 10 for a review of document-viewcommunication.

    The Splitter Window

    A splitter window appears as a special type of frame window that holds several views in panes. The application can split

    the window on creation, or the user can split the window by choosing a menu command or by dragging a splitter box onthe window's scroll bar. After the window has been split, the user can move the splitter bars with the mouse to adjust the

    relative sizes of the panes. Splitter windows can be used in both SDI and MDI applications. You can see examples of

    splitter windows in this module.

    An object of class CSpl i t t erWnd represents the splitter window. As far as Windows is concerned, aCSpl i t t erWnd object is an actual window that fully occupies the frame window (CFr ameWnd orCMDI Chi l dWnd)client area. The view windows occupy the splitter window pane areas. The splitter window does not take part in the

    command dispatch mechanism. The active view window (in a splitter pane) is connected directly to its frame window.

    http://www.tenouk.com/visualcplusmfc/visualcplusmfc10.htmlhttp://www.tenouk.com/visualcplusmfc/visualcplusmfc10.html
  • 7/29/2019 VC++ Multiple Views

    2/55

    View Options

    When you combine multiview presentation methods with application models, you get a number of permutations. Here

    are some of them:

    SDI application with splitter window, single view class. This module's first example, MYMFC21, covers thiscase. Each splitter window pane can be scrolled to a different part of the document. The programmer

    determines the maximum number of horizontal and vertical panes; the user makes the split at runtime. SDI application with splitter window, multiple view classes. The MYMFC21B example illustrates this case.

    The programmer determines the number of panes and the sequence of views; the user can change the pane size

    at runtime. SDI application with no splitter windows, multiple view classes. The MYMFC21C example illustrates this

    case. The user switches view classes by making a selection from a menu. MDI application with no splitter windows, single view class. This is the standard MDI application you've

    seen already in Module 12. The New Window menu item lets the user open a new child window for adocument that's open already.

    MDI application with no splitter windows, multiple view classes. A small change to the standard MDI

    application allows the use of multiple views. As example MYMFC21D shows, all that's necessary is to add amenu item and a handler function for each additional view class available.

    MDI application with splitter child windows. This case is covered thoroughly in the online documentation.

    The SCRIBBLE example illustrates the splitting of an MDI child window.

    Dynamic and Static Splitter Windows

    A dynamic splitter window allows the user to split the window at any time by choosing a menu item or by dragging asplitter box located on the scroll bar. The panes in a dynamic splitter window generally use the same view class. The topleft pane is initialized to a particular view when the splitter window is created. In a dynamic splitter window, scroll bars

    are shared among the views. In a window with a single horizontal split, for example, the bottom scroll bar controls both

    views. A dynamic splitter application starts with a single view object. When the user splits the frame, other view objectsare constructed. When the user un-splits the frame, view objects are destroyed.

    The panes of a static splitter windoware defined when the window is first created and they cannot be changed. Theuser can move the bars but cannot un-split or re-split the window. Static splitter windows can accommodate multiple

    view classes, with the configuration set at creation time. In a static splitter window, each pane has separate scroll bars. In

    a static splitter window application, all view objects are constructed when the frame is constructed and they are alldestroyed when the frame is destroyed.

    The MYMFC21 Example: A Single View Class SDI Dynamic Splitter

    In this example, the user can dynamically split the view into four paneswith four separate viewobjects, all managedby a single view class. We'll use the document and the view code from MYMFC19. AppWizard lets you add a dynamicsplitter window to a new application. Create an SDI project. Click the Advanced button in the AppWizard Step 4 dialog.Click on the Window Stylestab, and select Use Split Window as shown here.

    http://www.tenouk.com/visualcplusmfc/visualcplusmfc12mdi.htmlhttp://www.tenouk.com/visualcplusmfc/visualcplusmfc12mdi.html
  • 7/29/2019 VC++ Multiple Views

    3/55

    Figure 1: MYMFC21 step 4 of 6 AppWizard, the Advanced options settings.

    Figure 2: MYMFC21 step 6 of 6 AppWizard, using CScrol l Vi ewfor the view base class.

  • 7/29/2019 VC++ Multiple Views

    4/55

    Figure 3: MYMFC21 project summary.

    When you check the Use Split Window check box, AppWizard adds code to yourCMai nFr ame class. Of course, youcould add the same code to the CMai nFr ame class of an existing application to add splitter capability.

    Resources for Splitting

    Build and run MYMFC21 program. When AppWizard generates an application with a splitter frame, it includes a Splitoption in the project's View menu when you build and run the program. The I D_WI NDOW_SPLI T command ID ismapped in the CVi ewclass within the MFC library.

  • 7/29/2019 VC++ Multiple Views

    5/55

    Figure 4: MYMFC21 program output with split windows without any coding.

    CMai nFr ame Class

    The application's main frame window class needs a splitter window data member and a prototype for an overridden

    OnCr eat eCl i ent ( ) function. Here are the additions that AppWizard makes to the MainFrm.h file:

    pr otect ed:

    CSpl i t t erWnd m_wndSpl i t t er ;

    publ i c: vi r t ual BOOL OnCr eat eCl i ent ( LPCREATESTRUCT l pcs, CCr eat eCont ext * pCont ext ) ;

    Listing 1.

    The application framework calls the CFr ameWnd: : OnCr eateCl i ent virtual member function when the frameobject is created. The base class version creates a single view window as specified by the document template. The

    AppWizard-generated OnCr eat eCl i ent ( ) override shown here (in MainFrm.cpp) creates a splitter windowinstead, and the splitter window creates the first view:

    BOOL CMai nFr ame: : OnCr eat eCl i ent ( LPCREATESTRUCT / *l pcs*/ , CCr eat eCont ext* pCont ext)

    {r et ur n m_wndSpl i t t er . Cr eat e( t hi s,

    2, 2, / / TODO: adj ust t he number of r ows, col umnsCSi ze(10, 10) , / / TODO: adj ust t he mi ni mumpane si zepCont ext ) ;

    }

    Listing 2.

    The CSpl i t t erWnd Cr eat e( ) member function creates a dynamic splitter window, and the CSpl i t t erWndobject knows the view class because its name is embedded in the CCr eat eCont ext structure that's passed as a

    parameter to Create(). The second and third Cr eat e( ) parameters (2, 2) specify that the window can be split intoa maximum of two rows and two columns. If you changed the parameters to (2, 1), you would allow only a single

    horizontal split. The parameters (1, 2) allow only a single vertical split. The CSi ze parameter specifies the minimumpane size.

    The MYMFC20 steps

  • 7/29/2019 VC++ Multiple Views

    6/55

    Before we see the action, let put in the MYMFC20 steps in this example. Add a CSt r i ngAr r ay data member to theCMymf c21Doc class. Edit the Mymfc21Doc.h header file or use ClassView.

    publ i c: CSt r i ngAr r ay m_st r i ngAr r ay;

    Figure 5: Adding member variable to CMymf c21Doc class using ClassView.

    Figure 6: Entering the member variables type and name.

    Listing 3.

    The document data is stored in a string array. The MFC library CSt r i ngAr r ay class holds an array ofCSt r i ngobjects, accessible by a zero-based subscript. You need not set a maximum dimension in the declaration because the

    array is dynamic.

    Add a CRect data member to the CSt r i ngVi ewclass. Edit the StringView.h header file or use Cl assVi ew:

    pr i vat e: CRect m_r ect Pri nt ;

  • 7/29/2019 VC++ Multiple Views

    7/55

    Figure 7: Using ClassView to add a CRect data member to the CSt r i ngVi ewclass.

    Figure 8: Entering the member variable type and name.

    Listing 4.

    Edit three CMymf c21Doc member functions in the file Mymfc21Doc.cpp. AppWizard generated skeletonOnNewDocument ( ) and Ser i al i ze( ) functions, but we'll have to use ClassWizard to override the

    Del eteCont ent s( ) function. We'll initialize the poem document in the overridden OnNewDocument ( ) function.Del eteCont ent s( ) is called in CDocument : : OnNewDocument , so by calling the base class function first we'resure the poem won't be deleted. The text, by the way, is an excerpt from the twentieth poem in Lawrence Ferlinghetti's

    book A Coney Island of the Mind. Type 10 lines of your choice. You can substitute another poem or maybe your

    favorite Win32 function description. Add the following code:

    BOOL CMymf c21Doc: : OnNewDocument ( ) {

    i f ( ! CDocument : : OnNewDocument( ) ) r et urn FALSE;

    m_st r i ngAr r ay. Set Si ze( 10) ;

  • 7/29/2019 VC++ Multiple Views

    8/55

    m_st r i ngAr r ay[0] = "The pennycandyst ore beyond t he El " ; m_st r i ngAr r ay[ 1] = "i s wher e I f i r st "; m_st r i ngAr r ay[ 2] = " f el l i n l ove"; m_st r i ngAr r ay[3] = " wi t h unr eal i t y"; m_st r i ngAr r ay[ 4] = " J el l ybeans gl owed i n t he semi - gl oom"; m_st r i ngAr r ay[ 5] = "of t hat sept ember af t ernoon" ; m_st r i ngAr r ay[ 6] = "A cat upon the count er moved among"; m_st r i ngAr r ay[ 7] = " t he l i cor i ce st i cks"; m_st r i ngAr r ay[8] = " and t oot si e r ol l s";

    m_st r i ngAr r ay[ 9] = " and Oh Boy Gum";

    r et urn TRUE; }

    Listing 5.

    The CSt r i ngAr r ay class supports dynamic arrays, but here we're using the m_st r i ngAr r ay object as though itwere a static array of 10 elements. The application framework calls the document's virtual Del eteCont ent s( )

    function when it closes the document; this action deletes the strings in the array. A CSt r i ngAr r ay contains actualobjects, and a CObAr r ay contains pointers to objects. This distinction is important when it's time to delete the arrayelements. Here the RemoveAl l ( ) function actually deletes the string objects:

    voi d CMymf c21Doc: : Del eteCont ent s( ) {

    / / cal l ed bef ore OnNewDocument ( ) and when document i s cl osedm_st r i ngAr r ay. RemoveAl l ( ) ;

    }

  • 7/29/2019 VC++ Multiple Views

    9/55

    Figure 10: Adding the RemoveAl l ( ) function to the CMymf c21Doc class.

    Listing 6.

    Serialization isn't important in this example, but the following function illustrates how easy it is to serialize strings. The

    application framework calls the Del eteCont ent s( ) function before loading from the archive, so you don't have toworry about emptying the array. Add the following code:

    voi d CMymf c21Doc: : Ser i al i ze( CAr chi ve& ar) {

    m_str i ngArr ay. Ser i al i ze( ar ) ; }

    Listing 7.

  • 7/29/2019 VC++ Multiple Views

    10/55

    Edit the OnI ni t i al Updat e( ) function in mymfc21View.cpp. You must override the function for all classes derivedfrom CScrol l Vi ew. This function's job is to set the logical window size and the mapping mode. Add the followingcode:

    voi d CMymf c21Vi ew: : OnI ni t i al Update( ) {

    CScrol l Vi ew: : OnI ni t i al Updat e( ) ; CSi ze si zeTot al ( m_r ectPri nt . Wi dt h( ) , - m_r ectPri nt . Hei ght ( ) ) ;

    CSi ze si zePage( si zeTot al . cx / 2, si zeTot al . cy / 2) ; / / page scrol l CSi ze si zeLi ne( si zeTot al . cx / 100, si zeTot al . cy / 100) ; / / l i ne scrol l Set Scrol l Si zes( MM_TWI PS, si zeTot al , si zePage, si zeLi ne) ;

    }

    Listing 8.

    Edit the OnDr aw( ) function in mymfc21View.cpp. The OnDr aw( ) function of class CMymf c21Vi ewdraws on boththe display and the printer. In addition to displaying the poem text lines in 10-point roman font, it draws a border around

    the printable area and a crude ruler along the top and left margins. OnDr aw( ) assumes the MM_TWI PS mapping mode,in which 1 inch = 1440 units. Add the code shown below.

    voi d CMymf c21Vi ew: : OnDr aw( CDC* pDC) {

    i nt i , j , nHei ght ; CSt r i ng st r ; CFont f ont ; TEXTMETRI C t m;

    CMymf c21Doc* pDoc = Get Document ( ) ; / / Dr aw a bor der - sl i ght l y smal l er t o avoi d t r uncat i onpDC- >Rectangl e(m_r ectPr i nt + CRect ( 0, 0, - 20, 20) ) ; / / Dr aw hor i zont al and ver t i cal r ul er sj = m_r ect Pr i nt . Wi dt h( ) / 1440; f or ( i = 0; i Text Out ( i * 1440, 0, st r ) ;

    }j = - ( m_r ect Pr i nt . Hei ght ( ) / 1440) ; f or ( i = 0; i Text Out ( 0, - i * 1440, st r ) ;

    }/ / Pri nt t he poem0. 5 i nch down and over ; / / use 10- poi nt r oman f ont f ont . Cr eat eFont( - 200, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI _CHARSET,

    OUT_DEFAULT_PRECI S, CLI P_DEFAULT_PRECI S, DEFAULT_QUALI TY, DEFAULT_PI TCH | FF_ROMAN, "Ti mes New Roman") ;

    CFont * pOl dFont = ( CFont *) pDC- >Sel ectObj ect ( &f ont ) ; pDC- >Get Text Met r i cs( &t m) ; nHei ght = t m. t mHei ght + t m. t mExternal Leadi ng; TRACE( " f ont hei ght = %d, i nt ernal l eadi ng = %d\ n", nHei ght ,

    t m. t mI nt er nal Leadi ng) ; j = pDoc- >m_st r i ngAr r ay. Get Si ze( ) ; f or ( i = 0; i < j ; i ++)

  • 7/29/2019 VC++ Multiple Views

    11/55

    {pDC- >Text Out ( 720, - i * nHei ght - 720, pDoc- >m_st r i ngAr r ay[ i ] ) ;

    }pDC- >Sel ectObj ect ( pOl dFont ) ; TRACE( "LOGPI XELSX = %d, LOGPI XELSY = %d\ n", pDC- >Get Devi ceCaps( LOGPI XELSX) ,

    pDC- >Get Devi ceCaps( LOGPI XELSY) ) ; TRACE( "HORZSI ZE = %d, VERTSI ZE = %d\ n", pDC- >Get Devi ceCaps( HORZSI ZE) ,

    pDC- >Get Devi ceCaps( VERTSI ZE) ) ;

    }

    Listing 9.

    Edit the OnPr epar ePr i nt i ng( ) function in mymfc21View.cpp. This function sets the maximum number of pages

    in the print job. This example has only one page. It's absolutely necessary to call the base classDoPr eparePr i nt i ng( ) function in your overridden OnPr eparePr i nt i ng( ) function. Add the following code:

    BOOL CMymf c21Vi ew: : OnPr eparePr i nti ng( CPr i nt I nf o* pI nf o) {

    pI nf o- >Set MaxPage( 1) ; r et ur n DoPr epar ePri nt i ng( pI nf o) ;

    }

    Listing 10.

    Edit the constructor in mymfc21View.cpp. The initial value of the print rectangle should be 8-by-15 inches, expressedin twips (1 inch = 1440 twips). Add the following code:

    CMymf c21Vi ew: : CMymf c21Vi ew( ) : m_r ect Pr i nt ( 0, 0, 11520, - 15120) {

    / / TODO: add const r uct i on code here}

  • 7/29/2019 VC++ Multiple Views

    12/55

    Listing 11.

    Testing the MYMFC21 Application

    When the application starts, you can split the window by choosing Split from the View menu or by dragging the splitterboxes at the left and top of the scroll bars. Figure 11 shows a typical single view window with a four-way split. Multiple

    views share the scroll bars.

    Figure 11: MYMFC21 output, a single view window with a four-way split.

    The MYMFC21B Example: A Double View Class SDI Static Splitter

    In MYMFC21B, we'll extend MYMFC21 by defining a second view class and allowing a static splitter window to show

    the two views. (The HexView.hand HexView.cpp files are cloned from the original view class.) This time the splitterwindow works a little differently. Instead of starting off as a single pane, the splitter is initialized with two panes. The

    user can move the bar between the panes by dragging it with the mouse or by choosing the Window Split menu item.The easiest way to generate a static splitter application is to let AppWizard generate a dynamic splitter application and

    then edit the generated CMai nFrame: : OnCr eat eCl i ent function.

    The steps

  • 7/29/2019 VC++ Multiple Views

    13/55

    As usual, begin with the Visual C++ AppWizard, creating an SDI application.

    Figure 12: Step 4 of 6 AppWizard for MYMFC21B, invoking the Advanced options.

  • 7/29/2019 VC++ Multiple Views

    14/55

    Figure 13: Using the split window.

    Figure 14: Step 6 of 6, renaming the view files, class and using CScrol l Vi ewas the base view class.

    Figure 15: Step 6 of 6, renaming the document files and class.

  • 7/29/2019 VC++ Multiple Views

    15/55

    Figure 16: MYMFC21B project summary.

    Note that this is an SDI application. Add a CSt r i ngAr r ay data member to the CPoemDoc class. Edit the PoemDoc.hheader file or use ClassView.

    publ i c: CSt r i ngAr r ay m_st r i ngAr r ay;

  • 7/29/2019 VC++ Multiple Views

    16/55

    Figure 17: Using ClassView to add a CSt r i ngAr r ay data member to the CPoemDoc class.

    Figure 18: Entering the member variable type and name.

    Listing 12.

    The document data is stored in a string array. The MFC library CSt r i ngAr r ay class holds an array ofCSt r i ng

    objects, accessible by a zero-based subscript. You need not set a maximum dimension in the declaration because thearray is dynamic.

    Add a CRect data member to the CSt r i ngVi ewclass. Edit the StringView.h header file or use ClassView:

    pr i vat e: CRect m_r ectPri nt ;

  • 7/29/2019 VC++ Multiple Views

    17/55

    Figure 19: Using ClassView to add a CRect data member to the CSt r i ngVi ewclass.

    Figure 20: Entering the member variable type and name.

    Listing 13.

    Edit three CPoemDoc member functions in the file PoemDoc.cpp. AppWizard generated skeletonOnNewDocument ( ) and Ser i al i ze( ) functions, but we'll have to use ClassWizard to override the

    Del eteCont ent s( ) function. We'll initialize the poem document in the overridden OnNewDocument ( ) function.Del eteCont ent s( ) is called in CDocument : : OnNewDocument , so by calling the base class function first we'resure the poem won't be deleted. The text, by the way, is an excerpt from the twentieth poem in Lawrence Ferlinghetti's

    book A Coney Island of the Mind. Type 10 lines of your choice. You can substitute another poem or maybe your

    favorite Win32 function description. Add the following code:

    BOOL CPoemDoc: : OnNewDocument ( ) {

    i f ( ! CDocument : : OnNewDocument ( ) ) r et ur n FALSE;

  • 7/29/2019 VC++ Multiple Views

    18/55

    m_st r i ngAr r ay. Set Si ze( 10) ; m_st r i ngAr r ay[ 0] = "The pennycandyst ore beyond t he El " ; m_st r i ngAr r ay[ 1] = "i s wher e I f i r st "; m_st r i ngAr r ay[ 2] = " f el l i n l ove"; m_st r i ngAr r ay[ 3] = " wi t h unr eal i t y"; m_st r i ngAr r ay[ 4] = " J el l ybeans gl owed i n t he semi - gl oom"; m_st r i ngAr r ay[ 5] = "of t hat sept ember af t ernoon" ; m_st r i ngAr r ay[ 6] = "A cat upon t he count er moved among";

    m_st r i ngAr r ay[ 7] = " t he l i cor i ce st i cks"; m_st r i ngAr r ay[ 8] = " and t oot si e r ol l s"; m_st r i ngAr r ay[ 9] = " and Oh Boy Gum" ;

    r et urn TRUE; }

    Listing 14.

    The CSt r i ngAr r ay class supports dynamic arrays, but here we're using the m_st r i ngAr r ay object as though itwere a static array of 10 elements. The application framework calls the document's virtual Del eteCont ent s( ) function when it closes the document; this action deletes the strings in the array. A CSt r i ngAr r ay contains actualobjects, and a CObAr r ay contains pointers to objects. This distinction is important when it's time to delete the arrayelements. Here, the RemoveAl l ( ) function actually deletes the string objects:

    voi d CPoemDoc: : Del et eCont ent s( ) {

    / / cal l ed bef ore OnNewDocument ( ) and when document i s cl osedm_st r i ngAr r ay. RemoveAl l ( ) ;

    }

  • 7/29/2019 VC++ Multiple Views

    19/55

    Figure 21: As in MYMFC21, adding the RemoveAl l ( ) function to the document class.

    Listing 15.

    Serialization isn't important in this example, but the following function illustrates how easy it is to serialize strings. The

    application framework calls the Del eteCont ent s( ) function before loading from the archive, so you don't have toworry about emptying the array. Add the following code:

    voi d CPoemDoc: : Seri al i ze( CAr chi ve& ar) {

    m_str i ngAr r ay. Ser i al i ze( ar ) ; }

    Listing 16.

    Edit the OnI ni t i al Updat e( ) function in StringView.cpp. You must override the function for all classes derivedfrom CScrol l Vi ew. This function's job is to set the logical window size and the mapping mode. Add the followingcode:

  • 7/29/2019 VC++ Multiple Views

    20/55

    voi d CSt r i ngVi ew: : OnI ni t i al Updat e( ) {

    CScrol l Vi ew: : OnI ni t i al Updat e( ) ; CSi ze si zeTot al ( m_r ectPri nt . Wi dt h( ) , - m_r ectPri nt . Hei ght ( ) ) ; CSi ze si zePage( si zeTot al . cx / 2, si zeTot al . cy / 2) ; / / page scrol l CSi ze si zeLi ne( si zeTot al . cx / 100, si zeTot al . cy / 100) ; / / l i ne scrol l Set Scrol l Si zes( MM_TWI PS, si zeTot al , si zePage, si zeLi ne) ;

    }

    Listing 17.

    Edit the OnDr aw( ) function in StringView.cpp. The OnDr aw( ) function of class CSt r i ngVi ewdraws on both the

    display and the printer. In addition to displaying the poem text lines in 10-point roman font, it draws a border around theprintable area and a crude ruler along the top and left margins. OnDr aw( ) assumes the MM_TWI PS mapping mode, inwhich 1 inch = 1440 units. Add the code shown below.

    voi d CSt r i ngVi ew: : OnDr aw( CDC* pDC) {

    i nt i , j , nHei ght ; CSt r i ng st r ; CFont f ont ; TEXTMETRI C t m;

    CPoemDoc* pDoc = Get Document ( ) ; / / Dr aw a bor der sl i ght l y smal l er t o avoi d t r uncat i on

    pDC- >Rectangl e(m_r ect Pri nt + CRect ( 0, 0, - 20, 20) ) ; / / Dr aw hor i zont al and ver t i cal r ul er sj = m_r ect Pr i nt . Wi dt h( ) / 1440; f or ( i = 0; i TextOut ( i * 1440, 0, st r ) ;

    }j = - ( m_r ect Pr i nt . Hei ght ( ) / 1440) ; f or ( i = 0; i Text Out ( 0, - i * 1440, st r ) ;

    }

    / / Pri nt t he poem 0. 5 i nch down and over; / / use 10- poi nt r oman f ont f ont . Cr eat eFont ( - 200, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI _CHARSET,

    OUT_DEFAULT_PRECI S, CLI P_DEFAULT_PRECI S, DEFAULT_QUALI TY, DEFAULT_ PI TCH | FF_ROMAN, "Ti mes New

    Roman" ) ; CFont * pOl dFont = ( CFont *) pDC- >Sel ect Obj ect ( &f ont ) ; pDC- >Get Text Met r i cs( &t m) ; nHei ght = t m. t mHei ght + t m. t mExt ernal Leadi ng; TRACE( " f ont hei ght = %d, i nt er nal l eadi ng = %d\ n", nHei ght ,

    t m. t mI nt er nal Leadi ng) ;

  • 7/29/2019 VC++ Multiple Views

    21/55

    j = pDoc- >m_st r i ngAr r ay. GetSi ze( ) ; f or ( i = 0; i < j ; i ++) {

    pDC- >TextOut ( 720, - i * nHei ght - 720, pDoc- >m_st r i ngAr r ay[ i ] ) ; }pDC- >Sel ect Obj ect ( pOl dFont ) ; TRACE( "LOGPI XELSX = %d, LOGPI XELSY = %d\ n", pDC-

    >Get Devi ceCaps( LOGPI XELSX) ,

    pDC- >Get Devi ceCaps( LOGPI XELSY) ) ; TRACE( "HORZSI ZE = %d, VERTSI ZE = %d\ n", pDC- >Get Devi ceCaps( HORZSI ZE) ,

    pDC- >Get Devi ceCaps( VERTSI ZE) ) ; }

    Listing 18.

    Edit the OnPr epar ePr i nt i ng( ) function in StringView.cpp. This function sets the maximum number of pages inthe print job. This example has only one page. It's absolutely necessary to call the base class

    DoPr eparePr i nt i ng( ) function in your overridden OnPr eparePr i nt i ng( ) function. Add the following code:

    BOOL CSt r i ngVi ew: : OnPr eparePr i nt i ng( CPr i nt I nf o* pI nf o) {

    pI nf o- >Set MaxPage( 1) ; r et ur n DoPr epar ePr i nt i ng( pI nf o) ;

    }

    Listing 19.

    Edit the constructor in StringView.cpp. The initial value of the print rectangle should be 8-by-15 inches, expressed intwips (1 inch = 1440 twips). Add the following code:

    CSt r i ngVi ew: : CSt r i ngVi ew( ) : m_r ect Pr i nt ( 0, 0, 11520, - 15120) {

  • 7/29/2019 VC++ Multiple Views

    22/55

    }

    Listing 20.

    Build and test the application.

    Figure 22: MYMFC21B program output.

    CHexVi ewclass, the cloned CSt r i ngVi ewClass

    Next, create CHexVi ewby cloning the CSt r i ngVi ew. Create the header and source files (HexView.handHexView.cpp).

    Figure 23: Creating and adding new CHexVi ewclass.

  • 7/29/2019 VC++ Multiple Views

    23/55

    Figure 24: Creating the HexView.hheader file.

    Copy the cloned codes (StringView.h and StringView.cpp) and paste it to the HexView.h and HexView.cpprespectively. It is essentially the same code used forCSt r i ngVi ewexcept for the OnDr aw( ) member function

    HEXVIEW.H/ / HexVi ew. h : i nt erf ace of t he CHexVi ew cl ass/ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /

    #i f ! def i ned( AFX_CHEXVI EW_H__0A59E9CC_50F1_4B8E_8A3E_C3ED2955CE9D__I NCLUDED_) #def i ne AFX_CHEXVI EW_H__0A59E9CC_50F1_4B8E_8A3E_C3ED2955CE9D__I NCLUDED_

    #i f _MSC_VER > 1000#pr agma once#endi f / / _MSC_VER > 1000

    cl ass CHexVi ew : publ i c CScrol l Vi ew{

    pr ot ect ed: / / creat e f romseri al i zat i on onl yCHexVi ew( ) ; DECLARE_DYNCREATE( CHexVi ew)

    / / At t r i butespubl i c:

    CPoemDoc* Get Document ( ) ;

    / / Oper at i onspubl i c:

    / / Over r i des

  • 7/29/2019 VC++ Multiple Views

    24/55

    / / Cl assWi zar d gener at ed vi r t ual f unct i on over r i des/ / {{AFX_VI RTUAL( CHexVi ew) publ i c: vi r t ual voi d OnDr aw( CDC* pDC) ; / / over r i dden t o dr aw t hi s vi ewvi r t ual BOOL Pr eCr eat eWi ndow( CREATESTRUCT& cs) ; pr otect ed: vi r t ual voi d OnI ni t i al Updat e( ) ; / / cal l ed f i r st t i me af t er constr uct vi r t ual BOOL OnPrepar ePri nt i ng( CPri nt I nf o* pI nf o) ; vi r t ual voi d OnBegi nPri nt i ng( CDC* pDC, CPri nt I nf o* pI nf o) ;

    vi r t ual voi d OnEndPri nt i ng( CDC* pDC, CPri nt I nf o* pI nf o) ; / / }}AFX_VI RTUAL

    / / I mpl ement at i onpubl i c:

    vi r t ual ~CHexVi ew( ) ; #i f def _DEBUG

    vi r t ual voi d Asser t Val i d( ) const ; vi r t ual voi d Dump( CDumpCont ext & dc) const ;

    #endi f

    pr ot ect ed:

    / / Gener at ed message map f unct i onspr ot ect ed:

    / / {{AFX_MSG( CHexVi ew) / / NOTE - t he Cl assWi zar d wi l l add and r emove member f unct i ons here. / / DO NOT EDI T what you see i n t hese bl ocks of gener at ed code !

    / / }}AFX_MSGDECLARE_MESSAGE_MAP( )

    pr i vat e: CRect m_r ect Pri nt ;

    };

    #i f ndef _DEBUG / / debug vers i on i n CHexVi ew. cppi nl i ne CPoemDoc* CHexVi ew: : Get Document ( )

    { return ( CPoemDoc*) m_pDocument ; }#endi f

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /

    / / {{AFX_I NSERT_LOCATI ON}}/ / Mi crosof t Vi sual C++ wi l l i nser t addi t i onal decl ar at i ons i mmedi at el y bef or e t hepr evi ous l i ne.

    #endi f / / ! def i ned( AFX_CHEXVI EW_H__0A59E9CC_50F1_4B8E_8A3E_C3ED2955CE9D__I NCLUDED_)

    HEXVIEW.CPP/ / HexVi ew. cpp : i mpl ement at i on of t he CHexVi ew cl ass/ /

    #i ncl ude "st daf x. h" #i ncl ude "mymf c21B. h"

    #i ncl ude "PoemDoc. h"

    #i ncl ude "HexVi ew. h"

    #i f def _DEBUG#def i ne new DEBUG_NEW#undef THI S_FI LEs tat i c char THI S_FI LE[ ] = __FI LE__; #endi f

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ewI MPLEMENT_DYNCREATE( CHexVi ew, CScr ol l Vi ew)

  • 7/29/2019 VC++ Multiple Views

    25/55

    BEGI N_MESSAGE_MAP( CHexVi ew, CScr ol l Vi ew)

    / / {{AFX_MSG_MAP(CHexVi ew) / / NOTE - t he Cl assWi zar d wi l l add and remove mappi ng macr os here. / / DO NOT EDI T what you see i n t hese bl ocks of generat ed code!

    / / }}AFX_MSG_MAP/ / Standar d pr i nt i ng commandsON_COMMAND( I D_FI LE_PRI NT, CScr ol l Vi ew: : OnFi l ePr i nt ) ON_COMMAND( I D_FI LE_PRI NT_DI RECT, CScrol l Vi ew: : OnFi l ePr i nt )

    ON_COMMAND( I D_FI LE_PRI NT_PREVI EW, CScrol l Vi ew: : OnFi l ePri ntPrevi ew) END_MESSAGE_MAP( )

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew const r uct i on/ dest r uct i on

    CHexVi ew: : CHexVi ew( ) : m_r ectPr i nt ( 0, 0, 11520, - 15120) {

    / / TODO: add const r uct i on code here

    }

    CHexVi ew: : ~CHexVi ew( ) {}

    BOOL CHexVi ew: : Pr eCr eat eWi ndow( CREATESTRUCT& cs) {

    / / TODO: Modi f y t he Wi ndow cl ass or st yl es here by modi f yi ng/ / t he CREATESTRUCT cs

    return CScrol l Vi ew: : PreCr eat eWi ndow( cs) ; }

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew drawi ng

    voi d CHexVi ew: : OnDr aw( CDC* pDC) {

    / / hex dump of document st r i ngs

    i nt i , j , k, l , n, nHei ght ; CSt r i ng out put Li ne, s t r ; CFont f ont ; TEXTMETRI C t m;

    CPoemDoc* pDoc = Get Document ( ) ; f ont . Cr eat eFont ( - 160, 80, 0, 0, 400, FALSE, FALSE, 0,

    ANSI _CHARSET, OUT_DEFAULT_PRECI S, CLI P_DEFAULT_PRECI S, DEFAULT_QUALI TY, DEFAULT_PI TCH | FF_SWI SS, "Ar i al " ) ;

    CFont * pOl dFont = pDC- >Sel ect Obj ect ( &f ont ) ; pDC- >Get Text Met r i cs( &t m) ; nHei ght = t m. t mHei ght + t m. t mExternal Leadi ng;

    j = pDoc- >m_st r i ngAr r ay. Get Si ze( ) ; f or ( i = 0; i < j ; i ++) {

    out put Li ne. For mat( "%02x ", i ) ; l = pDoc- >m_st r i ngAr r ay[ i ] . GetLengt h( ) ; f or ( k = 0; k < l ; k++) {

    n = pDoc- >m_st r i ngAr r ay[ i ] [ k] & 0x00f f ; st r . For mat( "%02x ", n) ; out put Li ne += st r ;

    }pDC- >TextOut( 720, - i * nHei ght - 720, out put Li ne) ;

    }pDC- >Sel ectObj ect ( pOl dFont ) ;

    }

  • 7/29/2019 VC++ Multiple Views

    26/55

    voi d CHexVi ew: : OnI ni t i al Update( ) {

    CScrol l Vi ew: : OnI ni t i al Updat e( ) ; CSi ze si zeTot al ( m_r ectPri nt . Wi dt h( ) , - m_r ectPri nt . Hei ght ( ) ) ; CSi ze si zePage( si zeTot al . cx / 2, si zeTot al . cy / 2) ; / / page scrol l CSi ze si zeLi ne( si zeTot al . cx / 100, si zeTot al . cy / 100) ; / / l i ne scrol l Set Scrol l Si zes( MM_TWI PS, si zeTot al , si zePage, si zeLi ne) ;

    }

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew pr i nt i ng

    BOOL CHexVi ew: : OnPrepar ePr i nt i ng( CPri nt I nf o* pI nf o) {

    pI nf o- >Set MaxPage( 1); return DoPrepar ePri nt i ng( pI nf o) ;

    }

    voi d CHexVi ew: : OnBegi nPr i nt i ng( CDC* / *pDC*/ , CPri nt I nf o* / *pI nf o*/ ) {

    / / TODO: add ext r a i ni t i al i zat i on bef or e pr i nt i ng}

    voi d CHexVi ew: : OnEndPr i nt i ng( CDC* / *pDC*/ , CPri nt I nf o* / *pI nf o*/ ) {

    / / TODO: add cl eanup af t er pr i nt i ng}

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew di agnost i cs

    #i f def _DEBUGvoi d CHexVi ew: : Assert Val i d( ) const {

    CScrol l Vi ew: : Asser t Val i d( ) ; }

    voi d CHexVi ew: : Dump( CDumpContext & dc) const

    {CScrol l Vi ew: : Dump(dc) ;

    }

    CPoemDoc* CHexVi ew: : Get Document ( ) / / non- debug ver si on i s i nl i ne{

    ASSERT( m_pDocument - >I sKi ndOf ( RUNTI ME_CLASS(CPoemDoc) ) ) ; return ( CPoemDoc*) m_pDocument ;

    }#endi f / / _DEBUG

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew message handl ers

    Listing 21: CHexVi ewclass, the cloned CSt r i ngVi ewclass.

    The CHexVi ewclass (HexView.h and HexView.cpp) was written to allow programmers to appreciate poetry. It isessentially the same code used forCSt r i ngVi ewexcept for the OnDr aw( ) member function:

    voi d CHexVi ew: : OnDr aw( CDC* pDC) {

    / / hex dump of document st r i ngsi nt i , j , k, l , n, nHei ght ; CSt r i ng out put Li ne, st r ; CFont f ont ;

  • 7/29/2019 VC++ Multiple Views

    27/55

    TEXTMETRI C t m;

    CPoemDoc* pDoc = Get Document ( ) ; f ont . Cr eat eFont ( - 160, 80, 0, 0, 400, FALSE, FALSE, 0,

    ANSI _CHARSET, OUT_DEFAULT_PRECI S, CLI P_DEFAULT_PRECI S, DEFAULT_QUALI TY, DEFAULT_PI TCH | FF_SWI SS, "Ar i al " ) ;

    CFont * pOl dFont = pDC- >Sel ect Obj ect ( &f ont ) ; pDC- >Get Text Met r i cs( &t m) ; nHei ght = t m. t mHei ght + t m. t mExternal Leadi ng;

    j = pDoc- >m_st r i ngAr r ay. Get Si ze( ) ; f or ( i = 0; i < j ; i ++) {

    out put Li ne. For mat( "%02x ", i ) ; l = pDoc- >m_st r i ngAr r ay[ i ] . Get Lengt h( ) ; f or ( k = 0; k < l ; k++) {

    n = pDoc- >m_st r i ngAr r ay[ i ] [ k] & 0x00f f ; st r . For mat( "%02x ", n) ; out put Li ne += st r ;

    }pDC- >Text Out ( 720, - i * nHei ght - 720, out put Li ne) ;

    }pDC- >Sel ectObj ect ( pOl dFont ) ;

    }

    This function displays a hexadecimal dump of all strings in the document's m_st r i ngAr r ay collection. Notice the useof the subscript operator to access individual characters in a CSt r i ng object.

    CMai nFr ame Class

    As in MYMFC21, the MYMFC21B application's main frame window class needs a splitter window data member and a

    prototype for an overridden OnCr eat eCl i ent ( ) function. You can let AppWizard generate the code by specifyingUse Split Window, as in MYMFC21. You won't have to modify the MainFrm.h file. The implementation file,MainFrm.cpp, needs both view class headers (and the prerequisite document header), as shown here:

    #i ncl ude "PoemDoc. h"#i ncl ude "St r i ngVi ew. h" #i ncl ude "HexVi ew. h"

    Listing 22.

    AppWizard generates dynamic splitter code in the OnCr eat eCl i ent ( ) function, so you'll have to do some editing ifyou want a static splitter. Instead of calling CSpl i t t er Wnd: : Cr eat e, you'll call theCSpl i t t er Wnd: : Cr eat eSt at i c function, which is tailored for multiple view classes. The following calls toCSpl i t t er Wnd: : Cr eat eVi ewattach the two view classes. As the second and third Cr eat eSt at i c()

    parameters (2, 1) dictate, this splitter window contains only two panes. The horizontal split is initially 100 device units

    from the top of the window. The top pane is the string view; the bottom pane is the hex dump view. The user can change

    the splitter bar position but the view configuration cannot be changed.

    BOOL CMai nFr ame: : OnCr eat eCl i ent ( LPCREATESTRUCT / *l pcs*/ , CCr eat eCont ext* pCont ext)

  • 7/29/2019 VC++ Multiple Views

    28/55

    {VERI FY( m_wndSpl i t t er . Cr eat eSt at i c(t hi s, 2, 1) ) ; VERI FY( m_wndSpl i t t er. Cr eat eVi ew( 0, 0, RUNTI ME_CLASS( CStr i ngVi ew) , CSi ze( 100,

    100) , pCont ext ) ) ; VERI FY(m_wndSpl i t t er . Cr eat eVi ew( 1, 0, RUNTI ME_CLASS( CHexVi ew) , CSi ze( 100, 100) ,

    pCont ext ) ) ; r et urn TRUE;

    }

    Listing 23.

    Testing the MYMFC21B Application

    When you start the MYMFC21B application, the window should look like the one shown below. Notice the separate

    horizontal scroll bars for the two views.

    Figure 25: MYMFC21B program output with horizontal split views.

  • 7/29/2019 VC++ Multiple Views

    29/55

    The MYMFC21C Example: Switching View Classes Without a Splitter

    Sometimes you just want to switch view classes under program control and you don't want to be bothered with a splitter

    window. The MYMFC21C example is an SDI application that switches between CSt r i ngVi ewand CHexVi ewinresponse to selections on the View menu. Starting with what AppWizard generates, all you need to do is add two newmenu commands and then add some code to the CMai nFr ame class. You also need to change the CSt r i ngVi ewandCHexVi ewconstructors from pr ot ect ed to publ i c.We will use MYMFC21B project. Copy the MYMFC21B project folder to another folder as a backup and use the

    original one for this exercise. You can copy Visual C++ project (directory) to any other directory or computer, then you

    can edit and run the project as usual.

    Resource Requirements

    The following two items have been added to the View menu in the I DR_MAI NFRAME menu resource.

    Caption Command ID CMainFrame Function

    St&ring

    ViewI D_VI EW_STRI NGVI EW OnVi ewStr i ngVi ew( )

    &Hex

    ViewI D_VI EW_HEXVI EW OnVi ewHexVi ew( )

    Table 1

    Figure 26: Adding and modifying menu items properties.

    ClassWizard was used to add the command-handling functions (and corresponding update command UI handlers) to the

    CMai nFr ame class.

  • 7/29/2019 VC++ Multiple Views

    30/55

    Figure 27: Adding the command-handling functions and corresponding update command UI handlers.

    CMai nFr ame Class

    The CMai nFr ame class gets a new private helper function, Swi t chToVi ew( ) , which is called from the two menucommand handlers. The enumparameter tells the function which view to switch to. Here are the two added items in the

    MainFrm.h header file, added manually:

    pr i vat e: enum eVi ew { STRI NG = 1, HEX = 2 }; voi d Swi t chToVi ew( eVi ew nVi ew) ;

    Listing 24.

    The Swi t chToVi ew( ) function (in MainFrm.cpp) makes some low-level MFC calls to locate the requested viewand to activate it. Don't worry about how it works. Just adapt it to your own applications when you want the view-

    switching feature. Add the following code manually:

    voi d CMai nFrame: : Swi t chToVi ew( eVi ew nVi ew) {

    CVi ew* pOl dAct i veVi ew = Get Act i veVi ew( ) ; CVi ew* pNewAct i veVi ew = ( CVi ew*) Get Dl gI t em( nVi ew) ; i f ( pNewAct i veVi ew == NULL) {

  • 7/29/2019 VC++ Multiple Views

    31/55

    swi t ch (nVi ew) {case STRI NG:

    pNewAct i veVi ew = ( CVi ew*) new CSt r i ngVi ew; break;

    case HEX: pNewAct i veVi ew = ( CVi ew*) new CHexVi ew; break;

    }CCr eat eCont ext cont ext ;

    context . m_pCur r entDoc = pOl dAct i veVi ew- >Get Document( ) ; pNewAct i veVi ew- >Cr eate( NULL, NULL, WS_BORDER, CFr ameWnd: : r ect Def aul t , t hi s,

    nVi ew, &cont ext ) ; pNewAct i veVi ew- >OnI ni t i al Update( ) ;

    }Set Act i veVi ew( pNewAct i veVi ew) ; pNewAct i veVi ew- >ShowWi ndow( SW_SHOW) ; pOl dAct i veVi ew- >ShowWi ndow( SW_HI DE) ; pOl dAct i veVi ew- >Set Dl gCt r l I D(

    pOl dAct i veVi ew- >Get Runt i meCl ass( ) == RUNTI ME_CLASS( CSt r i ngVi ew) ? STRI NG :HEX) ;

    pNewAct i veVi ew- >Set Dl gCt r l I D( AFX_I DW_PANE_FI RST) ; Recal cLayout ( ) ;

    }

    Listing 25.

    Finally, here are the menu command handlers and update command UI handlers that ClassWizard initially generated

    along with message map entries and prototypes. The update command UI handlers test the current view's class.

    voi d CMai nFrame: : OnVi ewSt r i ngVi ew( ) {

    Swi t chToVi ew( STRI NG) ;

  • 7/29/2019 VC++ Multiple Views

    32/55

    }

    voi d CMai nFr ame: : OnUpdat eVi ewSt r i ngVi ew( CCmdUI * pCmdUI ) {

    pCmdUI - >Enabl e( ! GetAct i veVi ew( ) - >I sKi ndOf ( RUNTI ME_CLASS( CSt r i ngVi ew) ) ) ; }

    voi d CMai nFr ame: : OnVi ewHexVi ew( ) {

    Swi t chToVi ew( HEX) ; }

    voi d CMai nFr ame: : OnUpdat eVi ewHexVi ew( CCmdUI * pCmdUI ) {

    pCmdUI - >Enabl e( ! GetAct i veVi ew( ) - >I sKi ndOf ( RUNTI ME_CLASS( CHexVi ew) ) ) ; }

    Listing 26.

    Change the CSt r i ngVi ew(StringView.h) and CHexVi ew(HexView.h) constructors from pr ot ect ed to publ i c.

    Listing 27.

  • 7/29/2019 VC++ Multiple Views

    33/55

    Listing 28.

    Testing the MYMFC21C Application

    The MYMFC21C application initially displays the CSt r i ngVi ewview of the document. You can toggle between theCSt r i ngVi ewand CHexVi ewviews by choosing the appropriate command from the View menu. Both views of thedocument are shown side by side in Figure 28 and 29.

    Figure 28: MYMFC21C program output with two new view menus.

  • 7/29/2019 VC++ Multiple Views

    34/55

    Figure 29: The CSt r i ngVi ewview and the CHexVi ewview of the document.

    The MYMFC21D Example: A Multiple View Class MDI Application

    The final example, MYMFC21D, uses the previous document and view classes to create a multiple view class MDIapplication without a splitter window. The logic is different from the logic in the other multiple view class applications.

    This time the action takes place in the application class in addition to the main frame class. As you study MYMFC21D,

    you'll gain more insight into the use ofCDocTempl at e objects.This example was generated with the AppWizard Context-Sensitive Help option (step 4). In next Module, Module 15,

    you'll activate the context-sensitive help capability. If you're starting from scratch, use AppWizard to generate anordinary MDI application with one of the view classes. Then add the second view class to the project and modify the

    application class files and main frame class files as described in the following sections.

    The Steps

    As usual, use AppWizard to create a MDI application. Follow the shown steps.

    http://www.tenouk.com/visualcplusmfc/visualcplusmfc15.htmlhttp://www.tenouk.com/visualcplusmfc/visualcplusmfc15.html
  • 7/29/2019 VC++ Multiple Views

    35/55

    Figure 30: MYMFC21D AppWizard step 1 of 6.

    Figure 31: MYMFC21D step 4 of 6 AppWizard. Dont forget to tick the Context-sensitive Help; this option will be used

    in the next modules project.

  • 7/29/2019 VC++ Multiple Views

    36/55

    Figure 32: MYMFC21D step 6 of 6 AppWizard, renaming the view class, their related files and using CScrol l Vi ewas the view base class.

    Figure 33: MYMFC21D step 6 of 6 AppWizard, renaming the document class and their related files.

  • 7/29/2019 VC++ Multiple Views

    37/55

    Figure 34: MYMFC21D project summary.

    Note that this is an MDI application. Add a CSt r i ngAr r ay data member to the CPoemDoc class. Edit thePoemDoc.h header file or use ClassView.

    publ i c: CSt r i ngAr r ay m_st r i ngAr r ay;

  • 7/29/2019 VC++ Multiple Views

    38/55

    Figure 35: Adding a CSt r i ngAr r ay data member to the CPoemDoc class using ClassView.

    Figure 36: Entering the member variable type and name.

    Listing 29.

    The document data is stored in a string array. The MFC library CSt r i ngAr r ay class holds an array ofCSt r i ngobjects, accessible by a zero-based subscript. You need not set a maximum dimension in the declaration because the

    array is dynamic.

    Add a CRect data member to the CSt r i ngVi ewclass. Edit the StringView.h header file or use ClassView:

    pr i vat e: CRect m_r ectPri nt ;

    Figure 37: Adding a CRect data member to the CSt r i ngVi ewclass.

  • 7/29/2019 VC++ Multiple Views

    39/55

    Figure 38: Entering the member variable type and name.

    Listing 30.

    Edit three CPoemDoc member functions in the file PoemDoc.cpp. AppWizard generated skeletonOnNewDocument ( ) and Ser i al i ze( ) functions, but we'll have to use ClassWizard to override theDel eteCont ent s( ) function. We'll initialize the poem document in the overridden OnNewDocument ( ) function.Del eteCont ent s( ) is called in CDocument : : OnNewDocument , so by calling the base class function first we'resure the poem won't be deleted. The text, by the way, is an excerpt from the twentieth poem in Lawrence Ferlinghetti's

    book A Coney Island of the Mind. Type 10 lines of your choice. You can substitute another poem or maybe yourfavorite Win32 function description. Add the following code:

    BOOL CPoemDoc: : OnNewDocument ( ) {

    i f ( ! CDocument : : OnNewDocument ( ) ) r et ur n FALSE;

    m_st r i ngAr r ay. Set Si ze( 10) ; m_st r i ngAr r ay[ 0] = "The pennycandyst ore beyond t he El " ; m_st r i ngAr r ay[ 1] = "i s wher e I f i r st "; m_st r i ngAr r ay[ 2] = " f el l i n l ove"; m_st r i ngAr r ay[ 3] = " wi t h unr eal i t y"; m_st r i ngAr r ay[ 4] = " J el l ybeans gl owed i n t he semi - gl oom"; m_st r i ngAr r ay[ 5] = "of t hat sept ember af t ernoon" ; m_st r i ngAr r ay[ 6] = "A cat upon t he count er moved among"; m_st r i ngAr r ay[ 7] = " t he l i cor i ce st i cks"; m_st r i ngAr r ay[ 8] = " and t oot si e r ol l s"; m_st r i ngAr r ay[ 9] = " and Oh Boy Gum";

    r et urn TRUE; }

  • 7/29/2019 VC++ Multiple Views

    40/55

    Listing 31.

    The CSt r i ngAr r ay class supports dynamic arrays, but here we're using the m_st r i ngAr r ay object as though it

    were a static array of 10 elements. The application framework calls the document's virtual Del eteCont ent s( ) function when it closes the document; this action deletes the strings in the array. A CSt r i ngAr r ay contains actualobjects, and a CObAr r ay contains pointers to objects. This distinction is important when it's time to delete the arrayelements. Here the RemoveAl l ( ) function actually deletes the string objects:

    voi d CPoemDoc: : Del et eCont ent s( ) {

    / / cal l ed bef ore OnNewDocument ( ) and when document i s cl osedm_st r i ngAr r ay. RemoveAl l ( ) ;

    }

  • 7/29/2019 VC++ Multiple Views

    41/55

    Figure 39: Similar to the previous example, adding the RemoveAl l ( ) function.

    Listing 32.

    Serialization isn't important in this example, but the following function illustrates how easy it is to serialize strings. The

    application framework calls the Del eteCont ent s( ) function before loading from the archive, so you don't have toworry about emptying the array. Add the following code:

    voi d CPoemDoc: : Seri al i ze( CAr chi ve& ar) {

    m_str i ngAr r ay. Ser i al i ze( ar ) ; }

    Listing 33.

    Edit the OnI ni t i al Updat e( ) function in StringView.cpp. You must override the function for all classes derivedfrom CScrol l Vi ew. This function's job is to set the logical window size and the mapping mode. Add the following

    boldface code:

    voi d CSt r i ngVi ew: : OnI ni t i al Updat e( ) {

    CScrol l Vi ew: : OnI ni t i al Updat e( ) ;

    CSi ze si zeTot al ( m_r ectPri nt . Wi dt h( ) , - m_r ectPri nt . Hei ght ( ) ) ; CSi ze si zePage( si zeTot al . cx / 2, si zeTot al . cy / 2) ; / / page scrol l CSi ze si zeLi ne( si zeTot al . cx / 100, si zeTot al . cy / 100) ; / / l i ne scrol l Set Scrol l Si zes( MM_TWI PS, si zeTot al , si zePage, si zeLi ne) ;

    }

    Listing 34.

    Edit the OnDr aw( ) function in StringView.cpp. The OnDr aw( ) function of class CSt r i ngVi ewdraws on both thedisplay and the printer. In addition to displaying the poem text lines in 10-point roman font, it draws a border around the

    printable area and a crude ruler along the top and left margins. OnDr aw( ) assumes the MM_TWI PS mapping mode, inwhich 1 inch = 1440 units. Add the code shown below.

    voi d CSt r i ngVi ew: : OnDr aw( CDC* pDC) {

  • 7/29/2019 VC++ Multiple Views

    42/55

    i nt i , j , nHei ght ; CSt r i ng st r ; CFont f ont ; TEXTMETRI C t m;

    CPoemDoc* pDoc = Get Document ( ) ; / / Dr aw a bor der sl i ght l y smal l er t o avoi d t r uncat i onpDC- >Rectangl e(m_r ect Pri nt + CRect ( 0, 0, - 20, 20) ) ;

    / / Dr aw hor i zont al and ver t i cal r ul er sj = m_r ect Pr i nt . Wi dt h( ) / 1440; f or ( i = 0; i Text Out ( i * 1440, 0, st r ) ;

    }j = - ( m_r ect Pr i nt . Hei ght ( ) / 1440) ; f or ( i = 0; i TextOut ( 0, - i * 1440, st r ) ;

    }/ / Pri nt t he poem 0. 5 i nch down and over / / use 10- poi nt r oman f ont f ont . Cr eat eFont ( - 200, 0, 0, 0, 400, FALSE, FALSE, 0, ANSI _CHARSET,

    OUT_DEFAULT_PRECI S, CLI P_DEFAULT_PRECI S, DEFAULT_QUALI TY, DEFAULT_ PI TCH | FF_ROMAN, "Ti mes New

    Roman" ) ; CFont * pOl dFont = ( CFont *) pDC- >Sel ect Obj ect ( &f ont ) ; pDC- >Get Text Met r i cs( &t m) ; nHei ght = t m. t mHei ght + t m. t mExt ernal Leadi ng; TRACE( " f ont hei ght = %d, i nt er nal l eadi ng = %d\ n", nHei ght ,

    t m. t mI nt er nal Leadi ng) ; j = pDoc- >m_st r i ngAr r ay. Get Si ze( ) ; f or ( i = 0; i < j ; i ++) {

    pDC- >Text Out ( 720, - i * nHei ght - 720, pDoc- >m_st r i ngAr r ay[ i ] ) ; }pDC- >Sel ectObj ect ( pOl dFont ) ; TRACE( "LOGPI XELSX = %d, LOGPI XELSY = %d\ n", pDC-

    >Get Devi ceCaps( LOGPI XELSX) , pDC- >Get Devi ceCaps( LOGPI XELSY) ) ;

    TRACE( "HORZSI ZE = %d, VERTSI ZE = %d\ n", pDC- >Get Devi ceCaps( HORZSI ZE) , pDC- >Get Devi ceCaps( VERTSI ZE) ) ;

    }

  • 7/29/2019 VC++ Multiple Views

    43/55

    Listing 35.

    Edit the OnPr epar ePr i nt i ng( ) function in StringView.cpp. This function sets the maximum number of pages inthe print job. This example has only one page. It's absolutely necessary to call the base class

    DoPr eparePr i nt i ng( ) function in your overridden OnPr eparePr i nt i ng( ) function. Add the following code:

    BOOL CSt r i ngVi ew: : OnPr eparePr i nt i ng( CPr i nt I nf o* pI nf o) {

    pI nf o- >Set MaxPage( 1) ; r et ur n DoPr epar ePr i nt i ng( pI nf o) ;

    }

    Listing 36.

    Edit the constructor in StringView.cpp. The initial value of the print rectangle should be 8-by-15 inches, expressed intwips (1 inch = 1440 twips). Add the following code:

    CSt r i ngVi ew: : CSt r i ngVi ew( ) : m_r ect Pr i nt ( 0, 0, 11520, - 15120) {}

    Listing 37.

    Build and test the application.

  • 7/29/2019 VC++ Multiple Views

    44/55

    Figure 40: MYMFC21D program output, the MDI.

    Next, create CHexVi ewby cloning the CSt r i ngVi ewas shown in the previous example.

    Figure 41: Creating and adding new files (class) to project.

  • 7/29/2019 VC++ Multiple Views

    45/55

    Figure 42: Adding empty HexView.hheader file to the project.

    Copy the following cloned codes (StringView.h and StringView.cpp) into the HexView.hand HexView.cpprespectively.

    HEXVIEW.H/ / HexVi ew. h : i nt erf ace of t he CHexVi ew cl ass

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /

    #i f ! def i ned( AFX_CHEXVI EW_H__0A59E9CC_50F1_4B8E_8A3E_C3ED2955CE9D__I NCLUDED_) #def i ne AFX_CHEXVI EW_H__0A59E9CC_50F1_4B8E_8A3E_C3ED2955CE9D__I NCLUDED_

    #i f _MSC_VER > 1000#pr agma once#endi f / / _MSC_VER > 1000

    cl ass CHexVi ew : publ i c CScrol l Vi ew{pr ot ect ed: / / creat e f romseri al i zat i on onl y

    CHexVi ew( ) ;

    DECLARE_DYNCREATE( CHexVi ew)

    / / At t r i butespubl i c:

    CPoemDoc* Get Document ( ) ;

    / / Oper at i onspubl i c:

    / / Over r i des/ / Cl assWi zar d gener at ed vi r t ual f unct i on over r i des/ / {{AFX_VI RTUAL( CHexVi ew)

  • 7/29/2019 VC++ Multiple Views

    46/55

    publ i c: vi r t ual voi d OnDr aw( CDC* pDC) ; / / over r i dden t o dr aw t hi s vi ewvi r t ual BOOL Pr eCr eat eWi ndow( CREATESTRUCT& cs) ; pr otect ed: vi r t ual voi d OnI ni t i al Updat e( ) ; / / cal l ed f i r st t i me af t er constr uct vi r t ual BOOL OnPrepar ePri nt i ng( CPri nt I nf o* pI nf o) ; vi r t ual voi d OnBegi nPri nt i ng( CDC* pDC, CPri nt I nf o* pI nf o) ; vi r t ual voi d OnEndPri nt i ng( CDC* pDC, CPri nt I nf o* pI nf o) ; / / }}AFX_VI RTUAL

    / / I mpl ement at i onpubl i c:

    vi r t ual ~CHexVi ew( ) ; #i f def _DEBUG

    vi r t ual voi d Asser t Val i d( ) const ; vi r t ual voi d Dump( CDumpCont ext & dc) const ;

    #endi f

    pr ot ect ed:

    / / Gener at ed message map f unct i onspr ot ect ed:

    / / {{AFX_MSG( CHexVi ew) / / NOTE - t he Cl assWi zar d wi l l add and r emove member f unct i ons here.

    / / DO NOT EDI T what you see i n t hese bl ocks of gener at ed code ! / / }}AFX_MSGDECLARE_MESSAGE_MAP( )

    pr i vat e: CRect m_r ect Pri nt ;

    };

    #i f ndef _DEBUG / / debug vers i on i n CHexVi ew. cppi nl i ne CPoemDoc* CHexVi ew: : Get Document ( )

    { return ( CPoemDoc*) m_pDocument ; }#endi f

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /

    / / {{AFX_I NSERT_LOCATI ON}}

    / / Mi crosof t Vi sual C++ wi l l i nser t addi t i onal decl ar at i ons i mmedi at el y bef or e t he pr evi ousl i ne.

    #endi f / / ! def i ned( AFX_CHEXVI EW_H__0A59E9CC_50F1_4B8E_8A3E_C3ED2955CE9D__I NCLUDED_)

    HEXVIEW.CPP/ / HexVi ew. cpp : i mpl ement at i on of t he CHexVi ew cl ass/ /

    #i ncl ude "st daf x. h" #i ncl ude "mymf c21D. h"

    #i ncl ude "PoemDoc. h" #i ncl ude "HexVi ew. h"

    #i f def _DEBUG#def i ne new DEBUG_NEW#undef THI S_FI LEs tat i c char THI S_FI LE[ ] = __FI LE__; #endi f

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ewI MPLEMENT_DYNCREATE( CHexVi ew, CScr ol l Vi ew)

    BEGI N_MESSAGE_MAP( CHexVi ew, CScr ol l Vi ew)

  • 7/29/2019 VC++ Multiple Views

    47/55

    / / {{AFX_MSG_MAP(CHexVi ew) / / NOTE - t he Cl assWi zar d wi l l add and remove mappi ng macr os here. / / DO NOT EDI T what you see i n t hese bl ocks of generat ed code!

    / / }}AFX_MSG_MAP/ / Standar d pr i nt i ng commandsON_COMMAND( I D_FI LE_PRI NT, CScr ol l Vi ew: : OnFi l ePr i nt ) ON_COMMAND( I D_FI LE_PRI NT_DI RECT, CScrol l Vi ew: : OnFi l ePr i nt ) ON_COMMAND( I D_FI LE_PRI NT_PREVI EW, CScrol l Vi ew: : OnFi l ePri ntPrevi ew)

    END_MESSAGE_MAP( )

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew const r uct i on/ dest r uct i on

    CHexVi ew: : CHexVi ew( ) : m_r ectPr i nt ( 0, 0, 11520, - 15120) {

    / / TODO: add const r uct i on code here

    }

    CHexVi ew: : ~CHexVi ew( ) {}

    BOOL CHexVi ew: : Pr eCr eat eWi ndow( CREATESTRUCT& cs)

    {/ / TODO: Modi f y t he Wi ndow cl ass or st yl es here by modi f yi ng/ / t he CREATESTRUCT cs

    return CScrol l Vi ew: : PreCr eat eWi ndow( cs) ; }

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew drawi ng

    voi d CHexVi ew: : OnDr aw( CDC* pDC) {/ / hex dump of document st r i ngs

    i nt i , j , k, l , n, nHei ght ; CSt r i ng out put Li ne, st r ;

    CFont f ont ; TEXTMETRI C t m;

    CPoemDoc* pDoc = Get Document ( ) ; f ont . Cr eat eFont ( - 160, 80, 0, 0, 400, FALSE, FALSE, 0,

    ANSI _CHARSET, OUT_DEFAULT_PRECI S, CLI P_DEFAULT_PRECI S, DEFAULT_QUALI TY, DEFAULT_PI TCH | FF_SWI SS, "Ar i al " ) ;

    CFont * pOl dFont = pDC- >Sel ect Obj ect ( &f ont ) ; pDC- >Get Text Met r i cs( &t m) ; nHei ght = t m. t mHei ght + t m. t mExternal Leadi ng;

    j = pDoc- >m_st r i ngAr r ay. Get Si ze( ) ; f or ( i = 0; i < j ; i ++) {

    out put Li ne. For mat( "%02x ", i ) ; l = pDoc- >m_st r i ngAr r ay[ i ] . GetLengt h( ) ;

    f or ( k = 0; k < l ; k++) {n = pDoc- >m_st r i ngAr r ay[ i ] [ k] & 0x00f f ; st r . For mat( "%02x ", n) ; out put Li ne += st r ;

    }pDC- >TextOut ( 720, - i * nHei ght - 720, out put Li ne);

    }pDC- >Sel ectObj ect ( pOl dFont ) ;

    }

    voi d CHexVi ew: : OnI ni t i al Update( ) {

  • 7/29/2019 VC++ Multiple Views

    48/55

    CScrol l Vi ew: : OnI ni t i al Updat e( ) ; CSi ze si zeTot al ( m_r ectPri nt . Wi dt h( ) , - m_r ectPri nt . Hei ght ( ) ) ; CSi ze si zePage( si zeTot al . cx / 2, si zeTot al . cy / 2) ; / / page scrol l CSi ze si zeLi ne( si zeTot al . cx / 100, si zeTot al . cy / 100) ; / / l i ne scrol l Set Scrol l Si zes( MM_TWI PS, si zeTot al , si zePage, si zeLi ne) ;

    }

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /

    / / CHexVi ew pr i nt i ng

    BOOL CHexVi ew: : OnPrepar ePr i nt i ng( CPri nt I nf o* pI nf o) {

    pI nf o- >Set MaxPage( 1); return DoPrepar ePri nt i ng( pI nf o) ;

    }

    voi d CHexVi ew: : OnBegi nPr i nt i ng( CDC* / *pDC*/ , CPri nt I nf o* / *pI nf o*/ ) {

    / / TODO: add ext r a i ni t i al i zat i on bef or e pr i nt i ng}

    voi d CHexVi ew: : OnEndPr i nt i ng( CDC* / *pDC*/ , CPri nt I nf o* / *pI nf o*/ ) {

    / / TODO: add cl eanup af t er pr i nt i ng}

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew di agnost i cs

    #i f def _DEBUGvoi d CHexVi ew: : Assert Val i d( ) const {

    CScrol l Vi ew: : Asser t Val i d( ) ; }

    voi d CHexVi ew: : Dump( CDumpContext & dc) const {

    CScrol l Vi ew: : Dump(dc) ;

    }

    CPoemDoc* CHexVi ew: : Get Document ( ) / / non- debug ver si on i s i nl i ne{

    ASSERT( m_pDocument - >I sKi ndOf ( RUNTI ME_CLASS(CPoemDoc) ) ) ; return ( CPoemDoc*) m_pDocument ;

    }#endi f / / _DEBUG

    / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / CHexVi ew message handl ers

    Listing 38: The CHexVi ewclass, a cloned CSt r i ngVi ewclass.

    Resource Requirements

    The two items below have been added to the Window menu in the I DR_MYMFC2TYPE menu resource.

    Caption Command ID CMainFrame Function

    New &String Window (replacesNew Window item)

    I D_WI NDOW_NEW_STRI NGCMDI Fr ameWnd: : OnWi ndowNew(default when the program start)

    New &Hex Window I D_WI NDOW_NEW_HEX OnWi ndowNewHex

    Table 2.

  • 7/29/2019 VC++ Multiple Views

    49/55

    Figure 43: Adding and modifying menu items properties.

    ClassWizard was used to add the command-handling function OnWi ndowNewHex( ) to the CMai nFr ame class.

    Figure 44: Adding the command-handling function OnWi ndowNewHex( ) to the CMai nFr ame class.

    CMymf c21DApp Class

    In the application class header file, mymfc21D.h, the following data member and function prototype have been added:

  • 7/29/2019 VC++ Multiple Views

    50/55

    publ i c: CMul t i DocTempl at e* m_pTempl at eHex;

    Listing 39.

    The implementation file, mymfc21D.cpp, contains the #i ncl ude statements shown here:

    #i ncl ude "HexVi ew. h"

    Listing 40.

    The CMymf c21DAppI ni t I nstance( ) member function has the code shown below inserted immediately after theAddDocTempl at e( ) function call.

    m_pTempl at eHex = new CMul t i DocTempl at e( I DR_MYMFC2TYPE, RUNTI ME_CLASS(CPoemDoc) , RUNTI ME_CLASS(CChi l dFr ame) , RUNTI ME_CLASS(CHexVi ew) ) ;

    Listing 41.

    The AddDocTempl at e( ) call generated by AppWizard established the primary document/frame/view combinationfor the application that is effective when the program starts. The template object above is a secondary template that can

    be activated in response to the New Hex Window menu item.Now all you need is an Exi t I nst ance( ) member function that cleans up the secondary template:

  • 7/29/2019 VC++ Multiple Views

    51/55

    Figure 45: Adding an Exi t I nst ance( ) member function that cleans up the secondary template.

    Figure 46: Entering the member functions type and declaration.

    i nt CMymf c21DApp: : Exi t I nst ance( ) {

    del et e m_pTempl at eHex; r et ur n CWi nApp: : Exi t I nst ance( ) ; / / saves pr of i l e set t i ngs

    }

    Listing 42.

    CMai nFr ame

  • 7/29/2019 VC++ Multiple Views

    52/55

    The main frame class implementation file, MainFrm.cpp, has the CHexVi ewclass header (and the prerequisitedocument header) included:

    #i ncl ude "PoemDoc. h"#i ncl ude "HexVi ew. h"

    Listing 43.

    The base frame window class, CMDI Fr ameWnd, has an OnWi ndowNew( ) function that is normally connected to thestandard New Window menu item on the Window menu. The New String Window menu item is mapped to thisfunction in MYMFC21D. The New Hex Windowmenu item is mapped to the command handler function below tocreate new hex child windows. The function is a clone ofOnWi ndowNew( ) , adapted for the hex view-specific templatedefined in I ni t I nstance( ) .

    voi d CMai nFr ame: : OnWi ndowNewHex( ){

    CMDI Chi l dWnd* pAct i veChi l d = MDI Get Act i ve( ) ; CDocument * pDocument ; i f ( pAct i veChi l d == NULL | |

    ( pDocument = pAct i veChi l d- >Get Act i veDocument( ) ) == NULL) {TRACE( "War ni ng: No act i ve document f or Wi ndowNew command\ n") ; Af xMessageBox( AFX_I DP_COMMAND_FAI LURE) ; return; / / Command f ai l ed

    }

    / / Ot her wi se, we have a new f r ame! CDocTempl at e* pTempl at e = ( ( CMymf c21DApp*) Af xGet App() ) - >m_pTempl at eHex; ASSERT_VALI D( pTempl at e) ; CFr ameWnd* pFr ame = pTempl at e- >Cr eat eNewFr ame( pDocument , pAct i veChi l d) ; i f ( pFr ame == NULL)

    {TRACE( "War ni ng: f ai l ed t o cr eat e new f r ame\ n") ; Af xMessageBox( AFX_I DP_COMMAND_FAI LURE) ; return; / / Command f ai l ed

    }

    pTempl at e- >I ni t i al Updat eFrame(pFrame, pDocument ) ; }

  • 7/29/2019 VC++ Multiple Views

    53/55

    Listing 44.

    The function cloning above is a useful MFC programming technique. You must first find a base class function thatdoes almost what you want, and then copy it from the \VC98\mfc\src subdirectory into your derived class, changing itas required. The only danger of cloning is that subsequent versions of the MFC library might implement the original

    function differently.

    Testing the MYMFC21D Application

    When you start the MYMFC21D application, a text view child window appears. Choose New Hex Window from the

    Window menu. The application should look like this.

  • 7/29/2019 VC++ Multiple Views

    54/55

    Figure 47: MYMFC21D MDI program output with cascade view.

    Try the CascadeandTilemenus.

  • 7/29/2019 VC++ Multiple Views

    55/55

    Figure 48: MYMFC21D MDI program output with tile view.

    Further reading and digging:

    1. MSDN MFC 6.0 class library online documentation - used throughout this Tutorial.2. MSDN MFC 7.0 class library online documentation - used in .Net framework and also backward compatible

    with 6.0 class library

    3. MSDN Library4. Windows data type.5. Win32 programming Tutorial.6. The best of C/C++, MFC, Windows and other related books.7. Unicode and Multibyte character set: Story andprogram examples.

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/mfchm.asphttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_Class_Library_Reference_Introduction.asphttp://msdn.microsoft.com/library/default.asphttp://www.tenouk.com/ModuleC.htmlhttp://www.tenouk.com/cnwin32tutorials.htmlhttp://www.tenouk.com/cplusbook.htmlhttp://www.tenouk.com/ModuleG.htmlhttp://www.tenouk.com/ModuleM.htmlhttp://www.tenouk.com/ModuleM.htmlhttp://www.tenouk.com/ModuleG.htmlhttp://www.tenouk.com/cplusbook.htmlhttp://www.tenouk.com/cnwin32tutorials.htmlhttp://www.tenouk.com/ModuleC.htmlhttp://msdn.microsoft.com/library/default.asphttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_Class_Library_Reference_Introduction.asphttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/mfchm.asp