MFC 1.0 introduced these classes:
General:
  CObject
     CWinApp
     CMenu
  CArchive
  CDumpContext
  CRuntimeClass
  CMemoryState
  CFileStatus
  CString
  CTime
  CTimeSpan
  CPoint
  CRect
  CSize
Exceptions:
  CException
     CMemoryException
     CNotSupportedException
     CArchiveException
     CFileException
     CResourceException
File Services:
  CFile
     CStdioFile
     CMemFile
Collections:
  CByteArray
  CWordArray
  CDWordArray
  CPtrArray
  CObArray
  CStringArray
  CPtrList
  CObList
  CStringList
  CMapWordToPtr
  CMapWordToOb
  CMapPtrToWord
  CMapPtrToPtr
  CMapStringToPtr
  CMapStringToOb
  CMapStringToString
Graphics:
  CDC
     CClientDC
     CWindowDC
     CPaintDC
     CMetaFileDC
  CGdiObject
     CPen
     CBrush
     CFont
     CBitmap
     CPalette
     CRgn
Windows Support:
   CWnd
    CFrameWnd
       CMDIChildWnd
    CMDIFrameWnd
    CDialog
       CModalDialog
    CStatic
    CButton
    CEdit
    CListBox
    CComboBox
    CScrollBar
---------------------------------------------------------------------------
3.4.  MFC 2.0
=============
   MFC 2.0 was a 16-bit release that shipped with Visual C++ 1.0.  It
   added the Document/View framework on top of MFC 1.0 and also added OLE
   1.0 classes, message maps and common dialog classes.  This was a
   16-bit release released on 02/93
   MFC 2.0 introduced these classes:
General:
  CCreateContext
  CPrintInfo
  CDataExchange
  CCmdUI
Exceptions:
  CFileException
  COleException
Dialogs:
  [Note CModalDialog was nuked and functionality moved to CDialog, you
   can still see a #define CModalDialog CDialog in the header files]
  CDialog [not introduced here, but revamped to be a base for common dlgs]
     CFileDialog
     CColorDialog
     CFontDialog
     CPrintDialog
     CFindReplaceDialog
Windows Support:
   [Just new derivatives of CButton/CEdit and VBX class.]
   CButton
      CBitmapButton
   CEdit
      CHEdit
         CBEdit
   CVBControl
Document Architecture:
     CCmdTarget
      CWinApp [Moved in hierarchy, use to be derived from CObject]
      CDocTemplate
         CSingleDocTemplate
         CMultiDocTemplate
      CDocument
         COleDocument
            COleClientDoc
            COleServerDoc
Views:
   CView
      CScrollView
         CFormView
      CEditView
Control Bars:
   CControlBar
      CToolBar
      CStatusBar
      CDialogBar
   CSplitterWnd
OLE 1.0 Classes:
   COleServer
      COleTemplateServer
   CDocItem
      COleClientItem
      COleServerItem
---------------------------------------------------------------------------
3.5.  MFC 2.1
=============
   MFC 2.1 shipped with Visual C++ 1.1 for NT, it was basically a Win32
   port of MFC 2.0.  It was a 32-bit release that was released on
   08/93.
   MFC 2.1 did not introduce any new classes.
---------------------------------------------------------------------------
3.6.  MFC 2.5
=============
   MFC 2.5 shipped with Visual C++ 1.5.  It introduced the OLE 2 and ODBC
   classes.  It was the last 'official' 16-bit release.
   Released in 12/93
   MFC 2.5 introduced these classes:
General: [OLE and DB related]
   CFieldExchange
   COleDataObject
   COleDispatchDriver
   CRectTracker
Exceptions: [OLE and DB exceptions]
   COleException
      COleDispatchException
   CDBException
Files: [New OLE File support]
   CFile
      COleStreamfile
Dialogs: [New OLE Dialogs]
   CDialog
      COleDialog
         COleInsertdialog
         COleChangeIconDialog
         COlePasteSpecialDialog
         COleConvertDialog
         COleBusyDialog
         COleLinksDialog
            COleUpdateDialog
Windows Support: [Some OLE additions]   
   CFrameWnd
      COleIPFrameWnd
   CControlBar
      COleResizeBar
Document Architecture:  [Significant classes added for OLE here.]
   CCmdTarget
      COleObjectFactory
         COleTemplateServer
      COleDataSource
      COleDropSource
      COleDropTarget
      COleMessageFilter
      CDocument
         COleDocument
            COleLinkingDoc
               COleServerDoc
      CDocItem
         COleClientItem
         COleServerItem
Views: [New view for DB support]
   CView
      CScrollView
         CFormView
            CRecordView
ODBC/Database Classes:
   CDatabase
   CRecordSet
   CLongBinary
...........................................................................
3.6.1. MFC 2.51
----------------
   A point release to 2.5 (16-bit) that was a bug fix release.  Shipped
   with MSVC 2.0 in 9/94 with MFC 3.0 (32-bit).
...........................................................................
3.6.2. MFC 2.52
----------------
   A point release to 2.5 (16-bit) that added some of the MFC 3.0
   features such as property sheets, Winsock and MAPI support.
   Shipped with MSVC 2.1 in 1/95 with MFC 3.1 (32-bit).
   NOTE: This is only available via the MSVC Subscription.
Classes added in 2.52:
   CSocket
   CAsyncSocket
   CSocketFile
   CPropertyPage
   CPropertySheet
MAPI:
[Note that MAPI support was added to CDocument, no new classes]
   CDocument::OnFileSendMail
   CDocument::OnUpdateFileSendMail
   COleDocument::OnFileSendMail
...........................................................................
3.6.3.  MFC 2.52b
----------------
   [Excerpt from the 2.52b rel notes]
   Visual C++ 1.52b includes the industry-standard Microsoft
   Foundation Class Library (MFC) version 2.52b. Besides classes for OLE
   and database, this version includes classes for OLE control
   development. 
   Bugs Fixed in Visual C++ 1.52b
   Visual C++ 1.52b fixes a number of bugs from Visual C++ 1.5. Of
   particular interest to most developers are the following bug fixes: 
   MFC 2.52b
   Error L2025 occurred on CWnd::DoDataExchange.
   This bug has been corrected. See Microsoft Knowledge Base article
   Q120152 for more information. 
   CArchive::ReadObject sometimes caused an assertion in a CPtrArray
   object because CPtrArray can hold a maximum object size of 16K in a
   large memory model application. CArchive did not take the memory model
   into account; since CArchive enforced a 32K limit, objects of 32K
   could be written but an assertion was generated if CArchive read in
   more than 16K. 
   This bug has been corrected.
   There was a memory leak in 16-bit AUX_DATA.
   The three pens used in the class CPropertySheet were leaking. See
   Microsoft Knowledge Base article Q128604 for more information. 
   The CArchive buffer pointer could wrap around the end of a segment unintentionally.
   This bug has been corrected.
   If AfxSockInit failed, applications sometimes produced a General
   Protection Fault. 
   This bug has been corrected. See Microsoft Knowledge Base article
   Q130653 for more information. 
   The MAPISendMail dialog did not stay modal.
   This bug has been corrected.
   Source file DLGPROP.CPP had non-near data. This could prevent
   applications from being able to run multi-instance. 
   This bug has been corrected.
---------------------------------------------------------------------------
3.7.  MFC 3.0
=============
   MFC 3.0 shipped with Visual C++ 2.0 in 9/94.  It introduced docking
   toolbars, property sheets and template based collection classes.  This
   was the first release in the MSVC subscription, it was a 32-bit release.
   Classes added in MFC 3.0:
Tabbed Dialog Support:
CWnd
  CPropertySheet
  CDialog
     CPropertyPage
---------------------------------------------------------------------------
3.8.  MFC 3.1
=============
   MFC 3.1 shipped with Visual C++ 2.1 in 1/95.  It introduced MAPI,
   WinSock and Windows Common Controls.  The MFC toolbar, status bar,
   etc.. still live in MFC. This is the latest release out.  It is a
   32-bit release. 
   NOTE: Only available via MSVC subscription.
   Classes added in MFC 3.1: 
MAPI:
[Note that MAPI support was added to CDocument, no new classes]
   CDocument::OnFileSendMail
   CDocument::OnUpdateFileSendMail
   COleDocument::OnFileSendMail
Windows Common Controls Classes: [All of these are CWnd derived]
   CAnimateCtrl
   CHeaderCtrl
   CHotkeyCtrl
   CImageList
   CListCtrl
   CProgressCtrl
   CSliderCtrl
   CSpinButtonCtrl
   CStatusBarCtrl
   CTabCtrl
   CToolBarCtrl
   CToolTipCtrl
   CTreeCtrl
WinSock Support:
   CAsyncSocket
      CSocket
---------------------------------------------------------------------------
3.9.  MFC 3.2
=============
   MFC 3.2 shipped with Visual C++ 2.2 via the subscription in
   mid/late July. It is a 32-bit release.  Includes a  2.52b 16-bit
   release update. 
   [here's an excerpt from the release notes]
   Support for Windows Common Controls in USRDLLs. In order to use the
   MFC Windows Common Control classes you must link in the appropriate
   static libraries, as shown in the following table: 
   Library      Target
   DAFXCC.LIB   Release version
   DAFXCCD.LIB  Debug version
   DAFXCCU.LIB  Release Unicode version
   DAFXCCUD.LIB Debug Unicode version
   Updated MFC Common Control classes that work with those controls
   that have been recently released in Windows NT 3.51 and those that
   will be available in Windows 95 and a future version of Win32s.
   Improved common control documentation that is more complete and
   reflects changes since the first implementation.  
   New MFC sample applications
   ---------------------------
    NOTEPAD +   Notepad+ is an enhanced version of Notepad.  The
                enhancements are mainly from questions our customers
                have been asking. 
  
    SAVER       Saver is a screen saver written using MFC.  It
                "morphs" the text "MFC" to the text "C++".
    OLEVIEW     The OLEVIEW sample is very similar to the OLE2VIEW.EXE
                applet provided in \MSVC20\BIN. The sample illustrates
                how to implement OLE Object viewers through custom OLE
                interfaces. These custom interfaces are implemented in
                IVIEWERS.DLL
    BATCH       BATCH is an MDI application that lets you compress
                different AVI (Audio Video Interleaved) files in
                different ways. 
    WORDPAD     WORDPAD illustrates use of the CRichEditCtrl and
                CRichEditView classes, which encapsulate the new Rich
                Edit common control.
 
   These samples are located in the SAMPLES\MFC directory of your
   Visual C++ installation. 
   Updated Win32 SDK components
   ----------------------------
   With the release of Windows NT 3.51 and the upcoming release of
   Windows 95, the Win32 SDK has been updated to support both of these
   operating systems. Changes include new header files, new import
   libraries, and additional documentation. Visual C++ 2.2 includes the
   latest header files, import libraries and Win32 API documentation to
   support writing Windows NT- and Windows 95-compatible applications. 
---------------------------------------------------------------------------
3.10.  MFC 4.0
==============
   Rumor has it that MFC 4.0 will be part of MSVC 4.0 (they are finally
   going to get the numbers in synch) to ship shortly after Windows 95
   ships (9/95).  The MFC status bar, toolbars, property dialog and
   other UI classes will be rewritten to use the Windows 95 common
   controls. There will be other Windows 95 enhancements as well and much
   better OLE control support too!  Just heard that there will be some
   new database classes based on the Jet Engine  and
   something called message reflection, so you can stop messages from
   bouncing up to parents if you want to grab them all.
   Classes added in MFC 4.0: 
      CSynchronize
      CMutex
      CEvent
      CMultiLock
      CShellNew - Windows 95 
   
   **NOTE: This has not been released yet, MFC 3.2/MSVC 2.2 is the latest
     release with MFC 4.0/VC++ 4.0 due out in September.
---------------------------------------------------------------------------
3.11.  Table of MFC releases
============================
   ** Hint, MFC releases are always MSVC release - 1. This is because MFC
      1.0 came out with MS C 7.
   MFC Rel     MSVC Release  16 or 32 bit Notes
   ---------------------------------------------------------------------------
   1.0             16          Just thin Windows coverage
   2.0         1.0            16          Document/Views added
   2.1         1.1 for NT     32          First 32-bit release for NT
   2.5         1.5            16          OLE/ODBC, last 16-bit release
   2.51        2.0            16          Bug fixes.
   2.52        2.1            16          Adds prop sheets to 2.5
   2.52b       2.2            16          Shipped in July '95, bug fixes
   3.0         2.0            32          Property sheets, dock toolbars
   3.1         2.1            32          Winsock/MAPI, Win commcntrls
   3.2         2.2            32          Shipped in July '95, more commcntrls
   4.0         4.0            32          Not out yet, Win 95, OLE Control container
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
4. Generic Class Questions
=========================
4.1. CException - Exceptions and exception handling.
----------------------------------------------------
4.1.1.  How do I throw a CUserException derived exception?
----------------------------------------------------------   
   When I try to catch a derived exception I get the following error: 
   error C2039: 'classCMyException' : is not a member of
   'CMyException' 'classCMyException' : undeclared identifier
   'IsKindOf' : cannot convert parameter 1 from 'int*' to 'const
    struct CRuntimeClass*' 
   You need to make your CMyException class dynamically creatable 
   using the DECLARE_DYNAMIC() and IMPLEMENT_DYNAMIC() macros.  The
   CATCH macro expects to be able to access run-time information about
   the thrown class.
   -blaszczak@bix.com, Mike B, 6/5/95, comp.os.ms-windows.programmer.misc
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
5. GDI Class Questions
======================
5.1. CDC
========
5.1.1. How do I create a CDC from a HDC?
----------------------------------------
   Sometimes the Windows API will just give you a handle to a DC and
   you might want to create a CDC from that.  On example is
   owner-drawn lists, combos and buttons.  You will receive a draw
   item message with a hDC.  Here's some code to turn that hdc into
   the more familiar CDC.
   void MyODList::DrawItem(LPDRAWITEMSTRUCT lpDrawItem)
   {
       CDC myDC;
       myDC.Attach(lpDrawItem->hDC);
       //Do more stuff here
       //If you don't detach, it will get deleted and windows will
       //not be happy if you delete it's dc..
       myDC.Detach();
   }
   You can use this technique for any of the other MFC class/ Windows
   handle pairs too.
   Another approach is to call the CDC FromHandle method:
   CDC * pDC = CDC:FromHandle(lpDrawItem->hDC);
   It's not clear which is 'better', FromHandle is less error prone
   because you do not have to remember to 'detach'.
   -jmccabe@portage1.portup.com (Jim McCabe) 6/5/95
---------------------------------------------------------------------------
5.2. CBitmap
============
5.2.1. How do I read a 256 color bitmap file from disk?
------------------------------------------------------
   Currently, MFC does not contain direct support for reading and
   displaying DIBs or BMPs. However, there are a number of sample
   applications that illustrate just how to do this. 
   The first sample is the MFC sample application DIBLOOK. The
   MULTDOCS sample uses the same source code provided by DIBLOOK to read
   and display DIBs and BMPs. 
   Two other examples provided with Visual C++ are the SDK samples
   DIBVIEW and SHOWDIB. 
  - Question posted on comp.lang.c++, 6/5/95, found this in MS FAQ, 6/25/95
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
6. Window, Control, and Dialogs Class Questions
===============================================
6.1. Windows
============
6.1.1.  How can I use a custom icon for a window?
-------------------------------------------------
   The Microsoft Foundation Class Library stores icons for the main
   frame window and the MDI frame window as resources. The icon with
   resource ID AFX_IDI_STD_MDIFRAME is the icon for the MDI frame
   window, and the icon with resource ID AFX_IDI_STD_FRAME is the icon
   for the main frame window. To replace these icons in your
   application, add an icon to your resources file with the
   appropriate ID.
   
   The application specifies the icon for a view in an MDI child
   window when it creates the template. The application uses the icon
   with the specified resource ID when the user minimizes the MDI
   child window that contains the corresponding view.
   
   This technique allows you to specify one icon for the application
   to associate with these windows. Windows also supports dynamically
   painting a minimized window. To do this with MFC, use
   AfxRegisterWndClass() to register a window class with a NULL icon
   handle. Override the PreCreateWindow() function in the window class
   for the dynamically painted icon and copy the name returned by
   AfxRegisterWndClass() into the lpszClassName member of the
   CREATESTRUCT. This creates the window using the class that has a
   NULL icon. When the user minimizes this window, the icon receives
   WM_PAINT messages that it can process to display information
   appropriately. To do so, override the OnPaint() message handler and
   call the IsIconic() function to see if the window is minimized. If
   so, create a CPaintDC object and use it to draw on the icon. If the
   window is not minimized, call the base class version of OnPaint()
   to update the window normally.
   -MSVC Knowledge Base 6/4/94
...........................................................................
6.1.2. How do I change the styles for a window that's created by MFC?
---------------------------------------------------------------------
   To change the default window attributes used by a framework
   application created in AppWizard, override the window's
   PreCreateWindow() virtual member function. PreCreateWindow()
   allows an application to access the creation process normally
   processed internally by the CDocTemplate class. The framework
   calls PreCreateWindow() just prior to creating the window. By
   modifying the CREATESTRUCT structure parameter to
   PreCreateWindow(), your application can change the attributes
   used to create the window.
   The CTRLBARS sample application, provided with the Microsoft
   Foundation Class Library version 2.0, demonstrates this
   technique to change window attributes. Note that depending on
   what your application changes in PreCreateWindow(), it may be
   necessary to call the base class implementation.
   For more information, see MSVC knowledge base article Q99847.
   -MSVC Knowledge Base 6/7/95
............................................................................
6.1.3.  How do I get the minimal size of a window using MFC?
------------------------------------------------------------
   Write a handler for WM_GETMINMAXINFO.
   -blaszczak@BIX.com, Mike Blaszczak, 6/12/95 via programmer.misc
............................................................................
6.1.4.  How do I change a Window's title?
-----------------------------------------
  AfxGetApp()->m_pMainWnd->SetWindowText("My Window Title");
                      -or-
  AfxGetMainWnd()->SetWindowText ( "My Own Title" ) ;
   -aj536@freenet.toronto.on.ca, mfc-l, 7/9/95
............................................................................
6.1.5.  How do I get rid of 'Untitled' in my main window caption?
-----------------------------------------------------------------
   Override the PreCreateWindow function in your MainFrame class and
   do the following in it..
        cs.style &= ~FWS_ADDTOTITLE ;
   You can also set the initial window position (cs.x, cs.y, cs.cx,
   cs.cy) this way and change your class (cs.lpszClass) this way! 
   Remember to call CFrameWnd::PreCreateWindow at the end...
   -netninja@svpal.org, programmer.misc, 7/29/95
............................................................................
6.1.6.  How do I maximize my MDI child?
---------------------------------------
   void CMainFrame::ActivateFrame(int nCmdShow) 
   {
       if (!m_bActivated) {
         m_bActivated = TRUE;
         nCmdShow = SW_SHOWMAXIMIZED;
       }       
       CFrameWnd::ActivateFrame(nCmdShow);
   }
  
   where m_bActivated is a member variable of your frame object.
   -duane@anasazi.com, programmer.win32, 8/3/95
............................................................................
6.1.7.  Why does focus go nutso with a CSplitterWnd?
----------------------------------------------------
   <<< Whenever I move the splitter bar, the I-beam cursor in my edit
   control goes away. I have to click again in the edit control to get 
   back the cursor.>>> 
 
   The following Knowledge Base Article (GO MSKB on CIS) explains the
   focus problem associated with splitter windows and a couple of
   work-arounds to the problem. This may be of help to you. 
   ID: Q108434
   FIX: CSplitterWnd Class Does Not Handle All Focus Cases
  -Ramesh, NetQuest., MSMFC, 8/3/95
----------------------------------------------------------------------------
   
6.2. Controls
=============
6.2.1.  How do I get a CControl from a Dialog Template?
-------------------------------------------------------
   You can get a pointer to a control from a already created dialog
   control by doing a simple typecast of the results from GetDlgItem.
   Here's an example that creates a CButton from a checkbox with ID
   IDC_CHECK1.
   
    void my_function(CDialog * pDialog)
    {
       
       CButton * pButton = (CButton *)pDialog->GetDlgItem(IDC_CHECK1);
    
       ASSERT(pButton != NULL);
       pButton->SetCheck(m_bShowState);
    }
    Note that it's always safer to check for the validity of the
    results from GetDlgItem.
   -scot_wingo@msn.com, 6/1/95
    
............................................................................
6.2.2.  How do I subclass a control using MFC?
----------------------------------------------
   Read the documentation on SubClassDlgItem.  Here's an example of
   how to call it:
   BOOL CMyDialog::OnInitDialog()
   {
        //Do your subclassing first.        
        m_MyControl.SubClassDlgItem(ID_MYCONTROL, this);
        //Let the base class do its thing.
        CDialog::OnInitDialog();
        // Perhaps do some more stuff
        
        // Be sure to call Ctl3d last, or it will cause
        // assertions from multiple subclassing.
        
        Ctl3dSubclassDlg(m_hWnd, CTL3D_ALL);
   }
   -Mike Williams, mikew@marlin.ssnet.com, mfc-l 6/1/95
...........................................................................
6.2.3.  Why do I get an ASSERT when I subclass a control?
---------------------------------------------------------
   Make sure that you subclass the control BEFORE you call
   Ctl3dSubclassDlg, if the 3-d control DLL is loaded first, it will
   already have subclassed your controls and you will get an assert.
   - Mike Williams, mikew@marlin.ssnet.com, mfc-l 6/1/95
...........................................................................
6.2.4.  How do I validate the contents of a control when it loses focus?
------------------------------------------------------------------------
   NOTE: This is in the Microsoft Software Library.
   The FCSVAL sample application was created to show how an
   application can do control-by-control validation in a dialog box. 
   The application itself is just a modal dialog box displayed by the
   CWinApp::InitInstance(). After displaying the dialog box,
   InitInstance() simply quits the application.  
   The important part of the sample takes place in the dialog-box
   class implementation: There are two edit controls. The first takes
   input of an integer between 1 and 20. The second takes a character
   string as input with length less than or equal to 5. When you Tab or
   mouse-click from control to control within the displayed dialog box,
   the contents of the control that is losing focus are validated. 
   The CFocusDlg Class
   The application's functionality centers around the CFocusDlg class
   and its implementation of four message handlers (discussed below).
   Normal data exchange (DDX) and validation (DDV) using the routines
   provided by MFC take place in OnInitialUpdate(), when the dialog box
   is first displayed, and when the user chooses the OK button to accept
   the input. This is default behavior provided by ClassWizard when
   member variables are connected to dialog-box controls and can be
   examined in the dialog class DoDataExchange() function. 
   Validating control contents when switching focus from one control
   to the next is done by handling the EN_KILLFOCUS notification sent by
   the edit control that is losing focus. The idea here is to check the
   contents and, if they are not valid, to display the message box,
   inform the user, and then set the focus back to the control from which
   it came. Unfortunately, some difficulties arise when trying to set the
   focus (or display the message boxes) within a killfocus message
   handler. At this point, Windows is in an indeterminate state as it is
   moving focus from one control to the other. This is a bad place to do
   the validation and SetFocus() call. 
   The solution here is to post a user-defined message to the dialog
   box (parent) and do the validation and SetFocus() there, thus waiting
   for a safer time to do the work. (See "CFocusDlg::OnEditLostFocus()"
   in the file FOCUSDLG.CPP and "WM_EDITLOSTFOCUS user-defined message"
   in the file FOCUSDLG.H.) 
   Another thing you will notice about this function is that it uses
   TRY/CATCH to do the validation. The provided DDX/DDV routines throw
   CUserExceptions when failing to validate or load a control's data. You
   should catch these and do the SetFocus() in the CATCH block. 
   Note: This sample has other cool stuff, but this is the major one
   I've seen asked about on the net.
   -MS FAQ, 6/25/95
...........................................................................
6.2.5.  How do I enable/disable a bank of checkboxes?
-----------------------------------------------------
   I don't know about a magic way to do this using a single HWND, but there
   is a simple and self-documenting technique that I've been using for a
   long time.  You can make a routine that accepts an array of UINTs (your
   control IDs) and a visibility flag.
   This function can be a stand-alone function, or you can put it inside a
   class.  I have been collecting little utility functions like this and keep
   them in a CDialogBase class -- when I create a new dialog box in ClassWizard,
   I fix up the code to derive from CDialogBase instead of CDialog.
  
   For example, the function might look like this:
   void CDialogBase::ShowControls(UINT* pControls, UINT cControls, BOOL fVisible)
   {
       for (UINT uIndex = 0; uIndex < cControls; uIndex++)
       {
           CWnd* pwnd = GetDlgItem(pControls[uIndex]);
           if (pwnd)
           {
               pwnd->ShowWindow(fVisible ? SW_SHOW : SW_HIDE);
               pwnd->EnableWindow(fVisible);
           }
       }
   }
   Then later, often in your OnInitDialog handler, you can call this
   function with your control group:
   #define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(a[0]))
   {
       static UINT aGroup1[] = { DLG_CHBOX1, DLG_CHBOX2, DLG_STATIC1 };
       static UINT aGroup2[] = { DLG_LABEL2, DLG_LABEL7 };
       ShowControls(aGroup1, SIZEOF_ARRAY(aGroup1), TRUE);
       ShowControls(aGroup2, SIZEOF_ARRAY(aGroup2), FALSE);
   }
   You can find many uses for these control arrays later too...
   (Changing fonts in a series of controls, etc...)  Good luck,
   -jmccabe@portage1.portup.com, mfc-l, 7/18/95
...........................................................................
6.2.6.  How do I change the background color of a control?
----------------------------------------------------------
   Your dialog can trap the WM_CTLCOLOR message, look up the MFC help
   file notes for CWnd::OnCtlColor().  Before a control is about to paint
   itself, the parent window receives a chance to set its own default
   text color and background brush. 
   -jmccabe@portage1.portup.com, mfc-l, 7/18/95
   Also check out the MS KB article  ID: Q117778
   TITLE: Changing the Background Color of an MFC Edit Control
   -Ramesh, MSMFC, 7/19/95
...........................................................................
6.2.7.  How do I trap the  key for my control?
-----------------------------------------------------
   Handle WM_GETDLGCODE and return the appropriate value.  Remember that
   the listbox (or any other control) can only handle keyboard input when
   it has the focus.
   -joej@golddisk.com, programmer.misc, 8/21/95, programmer.misc
...........................................................................
6.2.8.  How can I DDX with a multiple selection listbox?
--------------------------------------------------------
   Download MLBDDX.ZIP from the MSMFC library on CIS. You'll get all
   the necessary code. When the dialog closes, a provided CStringList
   will be filled with the selected items. Freeware. 
   -Patrick Philippot, CIS email, 8/3/95
...........................................................................
6.2.9.  How do I change the background color of a BUTTON???
-----------------------------------------------------------
   NOTE: THE METHOD IN 6.2.6 WILL NOT WORK FOR BUTTONS!
   If you want to change the color of a dialog button, you have to use
   owner-draw button. (you can use bitmap buttons) Changing the color
   through  OnCtlColor() will not work for buttons. 
   The following Knowledge Base  articles (GO MSKB on CIS) may be of help to you.
   ID: Q32685
   TITLE: Using the WM_CTLCOLOR Message
   ID: Q64328
   SAMPLE: Owner-Draw: 3-D Push Button Made from Bitmaps with Text
   This article explains sample code for a owner-draw button.
   -Ramesh, NetQuest., MSMFC, 8/3/95
...........................................................................
6.2.10.  Why isn't CEdit putting things on separate lines?
----------------------------------------------------------
  Make sure that the lines are separated with \r\n, not just \n.
  -sutor@watson.ibm.com, mfc-l, 8/7/95
...........................................................................
6.2.11.  How do I get to the CEdit in a combobox?
-------------------------------------------------
   CComboCox combo;
   CEdit edit;
   // combobox creation ...
   // ...
   POINT tmpPoint = {1,1};
   edit.SubclassWindow( combo.ChildWindowFromPoint(tmpPoint)->GetSafeHwnd());
   -jahans@slb.com, mfc-l, 8/25/95
   
---------------------------------------------------------------------------
6.3.  Dialogs
============
6.3.1. How do I center my dialog?
---------------------------------
   Use the CWnd::CenterWindow method accomplish this.  I usually put
   it in my OnInitDialog overloaded function.  Since CDialog is an
   ancestor of CWnd, you can call the method directly->
   BOOL CMyDialog::OnInitDialog()
   {
      //Perform any other dialog initialization up here.
      CenterWindow();
      return TRUE;
   }
   - scot_wingo@msn.com, 6/1/95.
...........................................................................
6.3.2.  How do I get the 'old style' common dialogs on win95?
-------------------------------------------------------------
   MFC detects if it is running on Win95, and if so, replaces the 
   standard FileOpen Dialog with an explorer version of the FileOpen
   Dialog.   You can prevent MFC  from using this "explorer" version by
   adding the following line to your CFileDialog derived  class
   constructor:   m_ofn.Flags &= ~OFN_EXPLORER;
   -andyd@andyne.on.ca (Andy DeWolfe), via programmer.win32, 5/10/95
...........................................................................
6.3.3.  How do I subclass a win95 common dialog?
------------------------------------------------
   You can do it but Microsoft has made it much more difficult in
   Win95.  You need to create a "child dialog template" (with the
   WS_CHILD style) and set it to m_ofn.lpTemplateName (making sure
   m_ofn.hInstance is set to your app instance). This template must
   *only* contain the controls that you are adding to the dialog (ie. NOT
   the whole dialog with the standard controls  duplicated as in Win3.x).
   When the dialog is invoked, your template will appear (by default)
   below the regular file dialog controls.  If you put a static control
   with id stc32 (defined in include\dlgs.h), the common dialog code will
   rearrange things so that the original controls will appear wherever
   your put the stc32 control (you don't have to size it to match - the
   common dlg code will do that for you). 
   You will need to supply m_ofn.lpfnHook and handle your additional
   controls through the hook proc.  Note that since the system puts your
   dialog template ON TOP of the normal dialog, MFC message routing won't
   get to your controls so you can't code them through a message map in
   your CFileDialog derivative.  If anybody has found a way around this,
   I'd love to hear it!! 
   This is very messy and Microsoft knows it.  They promise a fix in
   MFC 4.0.  
   -joej@golddisk.com, Joe Janakovic, via programmer.win32, 6/10/95
...........................................................................
6.3.4.  CDialog::Create fails, what could be wrong?
---------------------------------------------------
   - Invalid HWND passed as a parent
   - Invalid dialog resource ID passed (be careful about numeric IDs
     vs. string IDs -- be careful with #define ID_MYDIALOG 0x1234 -- it is
     a "string" ID to the resource compiler). 
   - one or more controls on your dialog could not be created, usually
     because of the use of a custom control that was not registered. 
   - calling EndDialog during the OnInitDialog message (or some other
     handler called early in the game)! 
   - NULL HWND passed as parent when dialog has WS_CHILD style
   That's about all I can think of right now,
   -Dean McCrory, MSMFC, 6/16/95
...........................................................................
6.3.5.  How do I create a toolbar/statusbar in a dialog?
--------------------------------------------------------
   There's a sample in the Microsoft Software Library, DLGCBR, that
   demonstrates how to do this.
   Basically there's four steps, outlined and then coded below->
   To add a control bar to a dialog, you must create the control bar
   as usual, and then make room for the control bar within the client
   area of the dialog. For the control bar to function properly, the
   dialog must duplicate some of the functionality of frame windows. If
   you want ON_UPDATE_COMMAND_UI handlers to work for the control bars,
   you also need to derive new control bar classes, and handle the
   WM_IDLEUPDATECMDUI message. If your dialog is not the main window of
   your application, you will also need to modify its parent frame window
   to pass the WM_IDLEUPDATECMDUI message on to the dialog's control
   bars. 
   To make room for a control bar within the client area of the dialog,
   follow these steps in your dialog's OnInitDialog() function: 
   1. Create the control bars.
   2. Figure out how much room the control bars will take by using the
      reposQuery option of RepositionBars(): 
      CRect rcClientStart;
      CRect rcClientNow;
      GetClientRect(rcClientStart);
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,
                     0, reposQuery, rcClientNow);
   3. Move all the controls in your dialog to account for space used
      by control bars at the top or left of the client area. If your dialog
      contains a menu, you also need to account for the space used by the
      menu: 
      CPoint ptOffset(rcClientStart.left - rcClientNow.left,
      rcClientStart.top - rcClientNow.top);
      ptOffset.y += ::GetSystemMetrics(SM_CYMENU);
      CRect rcChild;
      CWnd* pwndChild = GetWindow(GW_CHILD);
      while (pwndChild) {
        pwndChild->GetWindowRect(rcChild);
        rcChild.OffsetRect(ptOffset);
        pwndChild->MoveWindow(rcChild, FALSE);
        pwndChild = pwndChild->GetNextWindow();
      }
   4. Increase the dialog window dimensions by the amount of space used
      by the control bars: 
      CRect rcWindow;
      GetWindowRect(rcWindow);
      rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
      rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
      MoveWindow(rcWindow, FALSE);
   5. Position the control bars using RepositionBars().
   To update the first pane of a status bar with menu item text, you
   must handle WM_MENUSELECT, WM_ENTERIDLE, and WM_SETMESSAGESTRING in
   your dialog class. You need to duplicate the functionality of the
   CFrameWnd handlers for these messages. See the CModelessMain class in
   the sample program for examples of these message handlers. 
   To allow ON_UPDATE_COMMAND_UI handlers to work for other status bar
   panes and for toolbar buttons, you must derive new control bar classes
   and implement a message handler for WM_IDLEUPDATECMDUI. This is
   necessary because the default control bar implementations of
   OnUpdateCmdUI() assume the parent window is a frame window. However,
   it doesn't do anything but pass the parent window pointer on to a
   function which only requires a CCmdTarget pointer. Therefore, you can
   temporarily tell OnUpdateCmdUI() that the parent window pointer you
   are giving it is a CFrameWnd pointer to meet the compiler
   requirements. Here's an example: 
     LRESULT CDlgToolBar::OnIdleUpdateCmdUI(WPARAM wParam,LPARAM lParam)
     {
      if (IsWindowVisible()) {
        CFrameWnd* pParent = (CFrameWnd*)GetParent();
        if (pParent)
           OnUpdateCmdUI(pParent, (BOOL)wParam);
      }
      return 0L;
     }
   To pass WM_IDLEUPDATECMDUI messages on to dialogs other than the
   main window, save dialog pointers in your frame window class and
   create a WM_IDLEUPDATECMDUI handler in that class. The handler should
   send the WM_IDLEUPDATECMDUI message on to the dialog child windows by
   using CWnd::SendMessageToDescendants(). Then perform default
   processing for the message within the frame window. 
   -MS FAQ 6/25/95
...........................................................................
6.3.6.  Why isn't my CDialog::PreCreateWindow getting called?
-------------------------------------------------------------
   PreCreateWindow does not get called when you create a dialog box.
   If you would like to init some data/controls for a dialog box you have
   to trap the OnInitDialog message and do you stuff there.
   PreCreateWindow is use to modify params for a window that you are
   creating.  
   -ewalker@tezcat.com, mfc-l, 7/12/95
...........................................................................
6.3.7.  How do I embed a common dialog in a property page?
-----------------------------------------------------------
   This question comes up frequently on the "MFC" forum of CompuServe
   and the simple answer - unfortunately - is that there is no way to do
   it :-( 
   -chris@chrism.demon.co.uk, programmer.win32, 7/12/95
...........................................................................
6.3.8.  Why can't I DDX/DDV to initialize my CDialog controls?
--------------------------------------------------------------
   You can't do anything with the dialog controls until your dialog is
   created - which doesn't happen until DoModal(). The standard way of
   overcoming the problems is to create member variables for the data,
   initialise them before calling DoModal and then transfer the values
   in OnInitDialog. Or perhaps in UpdateData(). Much like the
   ClassWizard member variables does it. 
   So have your dialog include a CStringList or CStringArray, put the
   values  for the listbox in that and transfer them to the listbox in
   OnInitDialog. [etc...] 
   -null@diku.dk, programmer.controls, 7/11/95
   Init your dialog in OnInitDialog. If neccessary pass a pointer to
   your document to the constructor of your dialog (and save it in a
   private/protected m_pDoc member). 
   -jhasling@gascad.co.at, programmer.controls, 7/11/95
...........................................................................
6.3.9.  How do I change the captions of a CPropertyPage?
--------------------------------------------------------
   You can change the label before adding the page to the property sheet
   in the following way.
   You have to derive a class from CPropertyPage and add a public function
   SetCaption which sets the caption.
   void CPage1::SetCaption(char *str)
   {
        m_strCaption = str; // m_strCaption is protected member of
                            //CPropertyPage
   }
   Now you can us the SetCaption() function in the following way.
   CMySheet my("My PropSheet");
   CPage1 p1;
   p1.SetCaption(str); // Setting the caption
   my.AddPage(&p1);
   CAnotherSheet newps("New Sheet");
   CPage1 p2;
   p2.SetCaption(newstr);
   newps.AddPage(&p2);
   my.DoModal();
  -Ramesh,  NetQuest., MSMFC 8/3/95
...........................................................................
6.3.10.  How do I trap F1 in my dialog?
---------------------------------------
   The following Knowledge Base Article explains a way to trap the
   WM_KEYDOWN messages in the dialog box. 
   ID: Q117563,  TITLE: How to Trap WM_KEYDOWN Messages in a CDialog
   The next article explains how to provide context sensitive help in
   a dialog. It also points to sample code. 
   ID: Q110506, SAMPLE: Context Sensitive Help in a CDialog
   -Ramesh, NetQuest., MSMFC, 8/31/95
---------------------------------------------------------------------------
6.4. Control bars, status bars, toolbars, dialog bars.
=======================================================
6.4.1.  How do I add a combobox to my toolbar?
----------------------------------------------
   You can do this using the CToolBar::SetButtonInfo method.
   The MFC sample ctrlbars shows how to do this.  Basically you call
   SetButtonInfo with the resource ID of your combobox.  You might
   want to throw some separators in there too.
   -scot_wingo@msn.com, 6/1/95
...........................................................................
6.4.2.  How do I update the text of a pane in a status bar?
-----------------------------------------------------------
   By default, a CStatusBar pane is not enabled when the pane is
   created. To activate a pane, you must call the
   ON_UPDATE_COMMAND_UI() macro for each pane on the status bar and
   update the panes. Because panes do not send WM_COMMAND messages,
   you cannot use ClassWizard to activate panes; you must type the
   code manually. For example, suppose one pane has ID_INDICATOR_PAGE
   as its identifier and that it contains the current page number in a
   document. To make the ID_INDICATOR_PAGE pane display text, add the
   following to a header file (probably the MAINFRM.H file):
   
          afx_msg void OnUpdatePage(CCmdUI *pCmdUI);
          
   Add the following to the application message map:
          ON_UPDATE_COMMAND_UI(ID_INDICATOR_PAGE, OnUpdatePage)
   Add the following to a source code file (probably MAINFRM.CPP):
          void CMainFrame::OnUpdatePage(CCmdUI *pCmdUI)
          {
             pCmdUI->Enable();
          }
          
   To display text in the panes, either call SetPaneText() or call
   CCmdUI::SetText() in the OnUpdate() function. For example, you
   might want to set up an integer variable m_nPage that contains the
   current page number. Then, the OnUpdatePage() function might read
   as follows: 
          void CMainFrame::OnUpdatePage(CCmdUI *pCmdUI)
          {
             pCmdUI->Enable();
             char szPage[16];
             wsprintf((LPSTR)szPage, "Page %d", m_nPage);
             pCmdUI->SetText((LPSTR)szPage);
          }
          
   This technique causes the page number to appear in the pane during
   idle processing in the same manner that the application updates
   other indicators. 
   - MSVC Knowledge Base 6/4/94
...........................................................................
6.4.3.  How do I make my CToolBar customizable at run-time?
-----------------------------------------------------------
   You might consider reading article "CToolBarCtrl :Handling
   Customization Notifications" in the Product Documentation of VC++
   2.1. 
   Here is the relevant extract :
   "A Windows toolbar common control has built-in customization
   features, including a system-defined customization dialog box, which
   allow the user to insert, delete, or rearrange toolbar buttons. The
   application determines whether the customization features are
   available and controls the extent to which the user can customize the
   toolbar. These customization features are available in the
   CToolBarCtrl class but not in the current CToolBar class.
   You can make these customization features available to the user by
   giving the toolbar the CCS_ADJUSTABLE style. The customization
   features allow the user to drag a button to a new position or to
   remove a button by dragging it off the toolbar. In addition, the user
   can double-click the toolbar to display the Customize Toolbar dialog
   box, which allows the user to add, delete, and rearrange toolbar
   buttons. The application can display the dialog box by using the
   Customize member function."
   - R.Rajendran (NetQuest), 76041.2245@compuserve.com,
     MSMFC Forum, May-9-95 
   If you want to make a standard MFC CToolbar customizable, you can
   download CUSBAR.ZIP from the MSMFC library on Compuserve.  This
   package implements CCustomTolbar, the run-time customizable toolbar
   and also provides the necessary user tools (customization dialog
   box including the code for a bitmapped listbox). Freeware.
   -Patrick Philippot, 8/3/95 via email on CSERVE
...........................................................................
6.4.4.  How do I turn off the toolbar or status bar?
----------------------------------------------------
   You can turn the status bar off in any of your views (i.e. in the 
   OnViewStatusBar() method you describe above) with the following code:
   if( ((CMainFrame*)GetParent())->m_wndToolBar.IsWindowVisible() )
    GetParent()->SendMessage(WM_COMMAND, ID_VIEW_TOOLBAR, 0L);
   if( ((CMainFrame*)GetParent())->m_wndStatusBar.IsWindowVisible() )
    GetParent()->SendMessage(WM_COMMAND, ID_VIEW_STATUS_BAR, 0L);
   Use 1L instead of 0L for the SendMessage's lParam to turn the bars on.
   -JKBenjamin@aol.com via mfc-l, 5/16/95
...........................................................................
6.4.5.  How do I create a toolbar/statusbar in a dialog?
--------------------------------------------------------
  See section 6.3.5. of this FAQ
---------------------------------------------------------------------------
6.5. Menus
=======================================================
---------------------------------------------------------------------------
6.5.1.  How do I get a pointer to the menu bar in a MDI app?
------------------------------------------------------------
   Q>I'm writing a MDI application and I have problems to get a pointer to the
     actual menu bar. The normal construction doesn't seem to work in MDI:
     CMenu *menu;
     menu = GetMenu()->GetSubMenu(0);
     How can I get a pointer to the menu bar to update the menu?
    A> AfxGetApp()->m_pMainWnd->GetMenu()->GetSubMenu(n)
    -mlinar@pollux.usc.edu, Mitch Mlinar, 6/8/95
...........................................................................
6.5.2.  How do I implement a right-mouse popup-menu?
----------------------------------------------------
   //////////////////////////////////////////////////////////////////////
   // WM_RBUTTONDOWN handler.
   //
   // Trap this message and display the button properties popup menu.
   // The main frame receives the popup menu messages. This allows the
   // status bar to be updated with the help text.
   //
   /////////////////////////////////////////////////////////////////////// 
   void CAppButton::OnRButtonDown(UINT flags, CPoint point)
   {
    
      CMenu menu;
      CMenu *submenu;
         
      // load the menu
      menu.LoadMenu(IDR_LAUNCH); 
         
      // get the popup menu
      submenu = menu.GetSubMenu(0);
         
      // convert to screen coordinates
      ClientToScreen(&point);
                  
      // post the menu
      submenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,                  
                              point.x,
                              point.y,
                              AfxGetApp()->m_pMainWnd,NULL);
                  
   }
   -johnm@unipalm.co.uk, programmer.win32, 7/12/95
...........................................................................
6.5.3.  How do I dynamically change the mainframe menu?
-------------------------------------------------------
    CMenu newMenu;
    newMenu.LoadMenu (IDR_MENU1);
    AfxGetMainWnd()->SetMenu( &newMenu );
    AfxGetMainWnd()->DrawMenuBar();
    newMenu.Detach ();
    -Arun Rao, MSMFC, 6/27/95
...........................................................................
6.5.4.  How do I 'attach' a menu to a window's creation/destruction?
--------------------------------------------------------------------
{Note the original question talked about dialogs, but you can
interpolate this code to any kind of window that you want to have
change the menu.}
    One of the ways to do this is as follows -
    1. Declare a variable CMenu pNewMenu in one of the dialog class.
    2. Handle the WM_INITDIALOG and WM_CLOSE messages in the
       dialog class as follows.
    3. BOOL CMydlg::OnInitDialog()
       {
           CDialog::OnInitDialog();
           // Load the IDR_MYFRAME menu
           pNewMenu = new CMenu;
           pNewMenu->LoadMenu(IDR_MYFRAME);
           // Set the mainframe menu to mainframe.
           ((CMainFrame *)AfxGetMainWnd())->SetMenu(pNewMenu);
           return TRUE;
       }
     And
       void CMydlg::OnClose()
       {
           // Detach the previous HMenu handle from the object.
           pNewMenu->Detach();
           pNewMenu->LoadMenu(IDR_MAINFRAME);
           // Restore the mainframe menu.
           ((CMainFrame *)AfxGetMainWnd())->SetMenu(pNewMenu);
           CDialog::OnClose();
       }
     4. If there are other methods of closing the dialog (example-
        By clicking a button in the Dialog), then The code given
        above in OnClose handler, must be put in the button click
        handler.
     -Sanjeev Kumar, MSMFC, 6/23/95
---------------------------------------------------------------------------
6.6.  Windows Common Controls (a.k.a. Windows 95 controls)
=======================================================
---------------------------------------------------------------------------
6.6.1.  Can I use these controls under NT or Win32s?
------------------------------------------------------------
   Windows NT 3.50 does not support the common controls, and will not
   in the future.  You must use Windows NT version 3.51 to gain the
   common controls.
   -blaszczak@BIX.com, mfc-l, 7/6/95
   Version 1.30 of Win32s supports the Common controls.
6.6.2.  Where's a demo of this wickedly cool controls?
------------------------------------------------------
   Check out the MFC sample, fire, it features most of the controls in
   action:  MSVC20\samples\mfc\fire.
   -scot_wingo@msn.com, 7/27/95
...........................................................................
6.6.3.  How do you handle NM_DBLCLK for a CListCtl?
---------------------------------------------------
   BEGIN_MESSAGE_MAP(CListView, CView)
   ON_NOTIFY( NM_DBLCLK,ID_LISTCTRL,OnDblClick )
   END_MESSAGE_MAP()
   void CListView::OnDblClick(NMHDR* /*k*/, LRESULT* /*j*/) 
   {
      int nItem, nFlags;
      char szTest[80];
      nFlags = LVNI_SELECTED;
      nItem = m_ListCtrl->GetNextItem(-1, nFlags );
      if ( nItem != -1 )
      {
           sprintf( szTest, "Selected Item %d", nItem);
           AfxMessageBox(szTest);
      }
    }
    -spolyak@interaccess.com, mfc-l, 7/21/95
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
7. Documents, Views and Frame Class Questions
=============================================
---------------------------------------------------------------------------
7.1.  Views
===========
7.1.1. How do I size a view?
----------------------------
   Normally, you can change the size of a window by calling
   MoveWindow(). In an application developed with the Microsoft
   Foundation Class (MFC) Library, the view window is a child window of
   the frame window that surrounds the view. To change the size of the
   view window, retrieve a pointer to the frame window of the view by
   calling GetParentFrame(), then call MoveWindow() to change the size of
   the parent. When the parent frame window changes size, it
   automatically changes the size of the view window to fit in the parent
   frame.
   -MSVC Knowledge Base. 6/4/94
...........................................................................
7.1.2. How do I size a CFormView?
---------------------------------
   See MS Knowledge Base article Q98598 for a very long answer.
   Basically, you need to override OnInitialUpdate() in a CFormView
   derived class.  There's other details to deriving from CFormView
   that the article goes into.
   -MSVC Knowledge Base. 6/7/95
   In the view ClikethisView declaration:
       virtual void OnInitialUpdate();       
   In the ClikethisView code:
   void ClikethisView::OnInitialUpdate()
   {  
      // make the window the size of the main dialog
      CFormView::OnInitialUpdate();
      GetParentFrame()->RecalcLayout();
      ResizeParentToFit( /*FALSE*/ );
   }
   -andyr@gate.net, programmer.misc, 8/11/95
...........................................................................
7.1.3. How do I use new views with a doc template?
--------------------------------------------------
   In an application created with AppWizard, you have two options:
   change the derivation of the current view, or create a new view
   and use the new view in your MDI application along with the
   original view.
   To create a new view, use ClassWizard to create a new class
   derived from CView. After the class has been created, the steps
   to use the new view or to modify the view provided by App
   Wizard are the same.
   1. Modify the header file for the view class to change all
      references to CView to the name of the desired view class.
      In this example, the class is derived from CScrollView.
      Usually, this step involves changing the class the view
      class is derived from as follows:
      class CMyView : public CScrollView
   2. Modify the implementation file for the view class to change
      all references to CView to the name of the desired view
      class. This involves changing the IMPLEMENT_DYNCREATE line
      as follows:
      IMPLEMENT_DYNCREATE(CMyView, CScrollView)
      changing the BEGIN_MESSAGE_MAP as follows:
      BEGIN_MESSAGE_MAP(CMyView, CScrollView)
      and changing any other references to CView to CScrollView.
   3. No further modifications are required if you are modifying a
      view created by App Wizard. If you create a new view, find
      the AddDocTemplate() call in the CWinApp::InitInstance()
      function. The third parameter to AddDocTemplate() is
      RUNTIME_CLASS(CSomeView). To replace the current view with
      the new view class, change CSomeView to CMyView. In an MDI
      application, you can use multiple view types by adding a
      second AddDocTemplate() call that changes
      RUNTIME_CLASS(CSomeView) to RUNTIME_CLASS(CMyView).
      For more information, please see Knowledge Base article Q99562.
      -MSVC Knowledge Base 6/7/95
...........................................................................
7.1.4. How do I change the background color of a view?
------------------------------------------------------
   To change the background color for a CView, CFrameWnd, or CWnd
   object, process the WM_ERASEBKGND message. The following code shows how:
   BOOL CSampleView::OnEraseBkgnd(CDC* pDC)
   {
     // Set brush to desired background color
     CBrush backBrush(RGB(255, 128, 128));
     // Save old brush
     CBrush* pOldBrush = pDC->SelectObject(&backBrush);
     CRect rect;
     pDC->GetClipBox(&rect);     // Erase the area needed
     pDC->PatBlt(rect.left, rect.top, rect.Width(),
                 rect.Height(), PATCOPY);
     pDC->SelectObject(pOldBrush);
     return TRUE;
   }
...........................................................................
7.1.5. How do I get the current View?
-------------------------------------
   The best thing to do is to pass the view along as a parameter.
   If this is impractical, you can get the view if you KNOW, that it is
   the currently active document and the currently active view. For
   details, see Microsoft KB, article Q108587, "Get Current CDocument or
   CView from Anywhere". In brief, use 
   (CFrameWnd*)(AfxGetApp()->m_pMainWnd)->GetActiveDocument()
   and 
   (CFrameWnd*)(AfxGetApp()->m_pMainWnd)->GetActiveView()
   to get the document and the view. It might be a good idea to wrap them
   in static functions in your CMyDoc and CMyView and check that they are
   of the correct RUNTIME_CLASS.
   If the view isn't the currently active view or if you can run OLE
   in-place, this won't work however.
   -null@diku.dk, Niels Ull Jacobsen, programmer.misc, 6/8/95
...........................................................................
7.1.6.  How do I create multiple views on one document?
-------------------------------------------------------
   The CDocTemplate::CreateNewFrame() function creates additional
   views of a document in an MDI application written with MFC.
   To call this function, specify a pointer to a CDocument object (the
   document for which the function will create a view) and a pointer to a
   frame window that has the properties to duplicate. Typically, the
   second parameter of this function is NULL. 
   When an application calls CreateNewFrame(), the function creates a
   new frame window and a view in the frame window. The frame window type
   and view type depend on the document template (CDocTemplate)
   associated with the document specified in the CreateNewFrame() call. 
   The CHKBOOK MFC sample application that ships with Visual C++ also
   demonstrates creating additional frames and views for documents.
   Check out CHKBOOK.CPP, the CChkBookApp::OpenDocumentfile() function.
   Another example of using CreateNewFrame() is the MULTVIEW sample
   application. Also, Dale Rogerson's article, "Multiple Views for a
   Single Document" located on the Microsoft Developer Network
   Development Library CD-ROM, which explains in detail how to add
   additional views to an existing document, is an excellent source of
   information. 
   CreateNewFrame() creates both a frame and a view; not only a view.
   If, for some reason, CreateNewFrame() does not quite address your
   situation, the source code for CreateNewFrame() is quite useful to
   demonstrate the steps required to create frames and views. 
   -MS FAQ with mods, 6/25/95
...........................................................................
7.1.7.  How do I get all the views in an MDI app?
-------------------------------------------------
   You need to use some functions which are undocumented:
      CDocument::GetFirstViewPosition(); // DOCCORE.CPP
      CDocument::GetNextView(); // DOCCORE.CPP
      CMultiDocTemplate::GetFirstDocPosition(); // DOCMULTI.CPP
      CMultiDocTemplate::GetNextDoc(); // DOCMULTI.CPP
   You'll also need to mess with the m_templateList member of CWinApp. 
   -blaszczak@Bix.com, mfc-l, 7/11/95
...........................................................................
7.1.8.  How do I make a CScrollView "mouse scrollable"?
-------------------------------------------------------
   Download AUTOSV.LZH from the MSMFC library on CIS. This code shows
   you how to implement a secondary message loop taking care of the
   mouse activity. Hooks are provided to customize the code. Freeware. 
   -Patrick Philippot, CIS email, 8/3/95
----------------------------------------------------------------------
7.2.  Documents
---------------
7.2.1.  Do I have to use the Document/View architecture?
----------------------------------------------------
   MFC does not force you to use document/views.  Check out hello,
   mdi, and helloapp samples, they don't use it at all.  Most MFC
   features can be used in non-document/view applications.  You do
   lose features like print preview and of many OLE features when you
   don't go document/view.
   -scot_wingo@msn.com 6/7/95
...........................................................................
7.2.2. How do I get the current Document?
-----------------------------------------
   See section 7.1.5. for the details.
...........................................................................
7.2.3.  When are documents destroyed?
-------------------------------------
   In SDI applications, the document is deleted when the application
   exits.  In MDI applications, the document is deleted when the last
   view on the document is closed.  To help keep your document SDI/MDI
   compatible, you should delete the document's data in the virtual
   DeleteContents() function, not in the destructor.
   -Richard Hazenberg, drmcode@euronet.nl, programmer.misc, 6/24/95
...........................................................................
7.2.4.  How do I create multiple documents?
-------------------------------------------
   To add support for additional document types, you can create and
   register additional CMultiDocTemplate objects with your CWinApp
   derived object. This technique is illustrated in the MULTDOCS sample
   application. The general steps needed to add an additional document
   type to an MFC application are listed below: 
   1. Use AppWizard to create a new document class and a new view class.
   2. Use the Resource Editor to add a new resource string to support
      the new document class. For more information on the format of the
      document template string resource, see the topic How to Interpret a
      Document Template String. 
   3. Use the Resource Editor to add an additional icon and menu
      resource to the application. Note, the ID for each of these resources
      needs to be the same ID as the resource ID used for the document
      template string created in step 2. This ID is used by the
      CMultiDocTemplate class to identify the resources associated with the
      additional document type. 
   4. In the applications InitInstance() function, create another
      CMultiDocTemplate object and register it with the
      CWinApp::AddDocTemplate() function. For example: 
      CMultiDocTemplate* pDocTemplate2 = new CMultiDocTemplate(
       IDR_DOC2TYPE, RUNTIME_CLASS(CDoc2),
       RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CView2));
      AddDocTemplate(pDocTemplate2);
   5. And finally, add the custom serialization and painting code to
      your new document and view classes. 
     -MS FAQ, 6/25/95
...........................................................................
7.2.5.  How do I get a list of open documents?
----------------------------------------------
   The code below demonstrates how to retrieve a list of pointers to
   all CDocuments that were created using a CDocTemplate object. 
   In the code below, CMyApp is derived from CWinApp. The variable
   m_templateList is a CPtrList object that is a member of CWinApp, and
   it contains a list of pointers to all of the document templates
   (CDocTemplates). The CDocTemplate functions GetFirstDocPosition() and
   GetNextDoc() are used to iterate through the list of documents for
   each document template. 
   Sample Code
   void CMyApp::GetDocumentList(CObList * pDocList)
   {
      ASSERT(pDocList->IsEmpty());
      POSITION pos = m_templateList.GetHeadPosition();
      while (pos){
         CDocTemplate* pTemplate = 
            (CDocTemplate*)m_templateList.GetNext(pos);
         POSITION pos2 = pTemplate->GetFirstDocPosition();
         while (pos2) {
            CDocument * pDocument;
            if ((pDocument=pTemplate->GetNextDoc(pos2)) != NULL)
               pDocList->AddHead(pDocument);
         }
     }
   }
   There are two public member functions of the CDocTemplate class that
   are not documented in the reference manual or the online help.
   However, these are public member functions defined in the CDocTemplate
   class and provide simple functionality for traversing the list of open
   documents. These functions operate as follows: 
   Function: virtual POSITION GetFirstDocPosition() const;
   Remarks:   Call this function to get the position of the first
              document in the list of open documents associated with
              the template.  
   Return Value:  A POSITION value that can be used for iteration with
                  the GetNextDoc member function. 
   Function: virtual CDocument* GetNextDoc(POSITION& rPosition) const;
     rPosition:  A reference to a POSITION value returned by a previous
                 call to the GetNextDoc or GetFirstDocPosition member
                 function. This value must not be NULL. 
   Remarks:   Call this function to iterate through all of the
              document template's open documents. The function
              returns the document identified by rPosition and then
              sets rPosition to the POSITION value of the next
              document in the list. If the retrieved document is the
              last in the list, then rPosition is set to NULL.  
   Return Value:  A pointer to the view identified by rPosition.
   -MS FAQ, 6/25/95
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
8. OLE Class Questions
======================
8.1. Structured Storage/Compound Files
======================================
8.1.1.  When I upgraded, I could not read my files generated by
        the old version of MFC.  What do I do?
---------------------------------------------------------------
   There may be an easier way, but here is how I did it:
   Use VERSIONABLE_SCHEMA and GetObjectSchema to identify the version.
   If old version, then it is stored in OLE 1.0 format.  To read this 
   format, first read a WORD and a CString (type and name info).  Next is 
   the OLE data itself (the hard part). Use the following steps:
   1) use StgCreateDocfile to create a temporary Compound File.
   2) use OleConvertOLESTREAMToIStorage to copy the data to the Compound 
      file, converting to OLE 2 format.
   3) call OleLoad using the IStorage to get an IUnknown pointer, then call 
      QueryInterface to set the COleClientItem::m_lpObject member, and set 
      m_nDrawAspect to DVASPECT_CONTENT.
    4) release the IUnknown pointer and the IStorage pointer
    5) The OleConvertOLESTREAMToIStorage code requires an OLESTREAM 
       implementation.  Copy the code from MSVC 1.0 MFC code.
    This actually works.  Theres some issues with messing with the schema 
    parameter, and I have not implemented writing OLE 1/MFC files.
    Code available on request.
    -ronjones@xnet.com, Ron Jones, via programmer.tools, 5/9/95
--------------------------------------------------------------------------
8.2.  OLE Controls (previously called OCX's)
============================================
8.2.1.  What is an OLE control?
-------------------------------
    OLE controls are the 32-bit successor to 16-bit VBX controls.
    Instead of being stored in a plain DLL and having functional
    interfaces, OLE controls rely on OLE automation.  Hopefully this
    will make the interface more flexible and easier to use than VBXs.
    -scot_wingo@msn.com, 6/25/95
...........................................................................
8.2.2.  How do I write OLE controls?
------------------------------------
    In VC++ 2.x, Microsoft released the CDK (OLE control developer
    kit), you use that kit and it's tools to write OLE controls.
    -scot_wingo@msn.com, 6/25/95
...........................................................................
8.2.3.  What versions of MFC support OLE control containment?
-------------------------------------------------------------
   To clarify the situation:
   VC++ 2.x can create OCX controls.
   VC++ 2.x does NOT yet have built-in "OCX container" support. That will
   be added in VC++ 4, due out this autumn. The only popular application
   I'm aware of which currently supports OCXs (albeit in only a limited
   way) is Access 2.
   The problem is that obviously the place you want OCX container support in
   MFC is in classes like "CDialog" and (possibly) "CWnd" or "CView". As I'm
   sure you know, OCX controls have to implement a LARGE number of OLE2
   interfaces, which makes the support code large.
   At present, OLE2 support in MFC happens in the "CCmdTarget" class, which
   is the base class from which ALL "application architecture" classes are
   derived. I guess the choice is to extend the OLE2 support in this class
   to include OCX support (which would make ALL apps using OLE2 a LOT larger),
   or to add OCX-specific support to certain specific classes such as
   CDialog. Either way, it's a major undertaking!
   -Chris Marriott, chris@chrism.demon.co.uk, programmer.tools, 6/24/95
TODO: Find out more about OLE control limitations/support in 4.0
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
9. WOSA Class Questions
=======================
9.1. CRecordSet
---------------
9.1.1.  When I add a CRecordSet class, I get tons of linker errors..
--------------------------------------------------------------------
  
   If you haven't told the AppWizard to use Database Support when you
   created your project, the AppWizard doesn't include the database
   headers.  If you add "#include " in your stdafx.h,
   CRecordSet will be "legalized".
   Then open the Linker Options window and add the library: "odbc".
   This avoids tons of linker errors.
   -bessler@highland.swb.de (Wolfgang Bessler) 06/05/95, comp.lang.c++
--------------------------------------------------------------------------
9.2.  WinSock
=============
9.2.1.  I'm having problems with CSocket blocking, what's up?
-------------------------------------------------------------
   I've worked around this by creating a dialog box that I pop up after
   calling Connect()... ie:
         CMySocket MySocket;
         MySocket.Create();
         MySocket.Connect("mysmtphost",25);
         CDummyDlg DummyDialog;
         MySocket.m_pDialog=&DummyDialog;
         DummyDialog.DoModal();
    This suspends the thread until MySocket sends a WM_CLOSE message to
    DummyDialog.
    I'd rather it look like:
         MySocket.m_hEvent=CreateEvent(...);
         WaitForSingleObject(MySocket.m_hEvent,INFINITE);
    But that stops all processing of MySocket.
    -Cynthia Jennings (idlewild@is.net), programmer.win32, 6/19/95
    TODO: Find better answer.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
10. DLL and Build Questions
===========================
   If you have questions about extension and user DLLs, be sure to read
   technical notes 11 and 33.  Volume 2 of the documentation has more
   info too.  Finally, try searching on the sample names dllhusk
   (extension DLL) and dlltrace (user DLL) in books on-line.
--------------------------------------------------------------------------
10.1. Do I need a CWinApp object in a DLL?
------------------------------------------
   The Microsoft Foundation Class Library supports two types of DLLs:
   _USRDLL and _AFXDLL. The _USRDLL model requires one CWinApp object
   to perform the initialization and cleanup of the Microsoft
   Foundation Class Library Windows classes that the DLL uses. This
   requirement is described in MFC Tech Note 11; the DLLTRACE sample
   demonstrates a _USRDLL that contains a CWinApp object.
   
   An _AFXDLL does not require a CWinApp object. Because it shares the
   Microsoft Foundation Class Library classes with the application, it
   does not require a CWinApp to provide initialization and cleanup.
   Instead, an _AFXDLL requires a special version of LibMain() and a
   DLL initialization function. 
   -MSVC Knowledge Base 6/4/95
---------------------------------------------------------------------------
10.2. How should I define the WEP in a MFC DLL?
------------------------------------------------
   In a dynamic-link library (DLL) built with Microsoft Foundation
   Class Library version 2.0, the _USRDLL model uses the WEP()
   (Windows exit procedure) function provided in the C run-time
   library. Because the code uses the C library WEP() function,
   the destructors for static and global objects in the DLL are
   called and the CWinApp::ExitInstance() function for the DLL
   application object is called.
   See MSVC Knowledge Base article Q98374 and Tech notes 11 and 33.
   -MSVC Knowledge Base 6/7/95
---------------------------------------------------------------------------
10.3.  How do I build an 'extension DLL'?
------------------------------------------------
   1.  When you're building a 32-bit extension DLL, define _AFXEXT on the
   compiler command line.  If you look in AFXVER_.H, you'll see that this forces
   _AFXDLL to also be defined.  So an "AFXEXT" DLL is an AFXDLL.
   2. When _AFXDLL is defined, AfxGetResourceHandle returns a value stored in
   MFC's global data, which is shared by the EXE, the extension DLL and the MFC
   DLL.  The handle returned identifies the module which will be searched first
   when looking for a resource.
   (See the source code for AfxFindResourceHandle() if you're curious about the
   order of the search.)
   3. Strictly speaking, what we need to load a resource is a module handle
   rather than an instance handle.  (Instances share modules --- e.g., code and
   resources --- but have different data.)  A DLL has a module handle which is
   distinct from the handle of the EXE.
   4. You can use ::GetModuleHandle to get the handle for your DLL, then pass it
   to AfxSetResourceHandle so that your DLL is the first place searched for
   resources.  But note that this removes the EXE module from of modules
   searched.  You'll probably want to save a copy of the handle returned by
   AfxGetResourceHandle before calling AfxSetResourceHandle, then restore it
   once you're done loading the DLL resource.
   -Charlie Kester, Microsoft Developer Support, MSMFC, 7/19/95
---------------------------------------------------------------------------
10.4.  How can I manage resources in a resource only DLL and still
       benefit from ClassWizard? 
==================================================================
   The following text is available as RESDLL.ZIP in the MSMFC library
   on Compuserve (applies to MSVC20):
   How to manage an MFC project storing its resources into a resource-only DLL
   ***************************************************************************
   Software localization is much easier when your project stores its
   resources in a resource-only DLL. There area also many situations
   where storing the project's resources in a DLL can be a good idea.
   However, if this project is an MFC project, doing so will generate
   a major drawback: you will not benefit from the Class Wizard
   capabilities any longer because the resources will be managed in a
   separate project. 
   However, there's a trick that you can use to develop your project
   as if it were a standard project while being able to quickly switch
   to the resource-only DLL model. Here's how to proceed:
   METHOD 1
   ********
   1. Create your project as usual using AppWizard (we'll name it TEST).
   2. Close the project and create a new DLL project in the same
   directory (call it RESDLL). When you click on the Create button,
   VC++ opens the Add file dialog.  Take this opportunity to add the
   resource file of the previous project (TEST.RC) to this new project.
   3. Before being able to compile the resources of the TEST project
   as a resource-only DLL, you must add the /NOENTRY option to the
   linker. Unfortunately, the settings dialog box of VC++ doesn't
   allow to do that in a simple way: 
     3.1 Select Project|Settings from the man menu.
     3.2 Click on the Link tab.
     3.3 Select General from the category combobox.
     3.4 In the Object/Library Modules field, remove all references to
         any .LIB file (they are useless) and add /NOENTRY. This
         option should then appear in the Common Options display area.
     3.5 Click OK and compile. You now have a DLL containing only the
         resources for your project.
   4. Do not open the TEST.MAK project. Instead, copy TEST.MAK to
      TEST_RES.MAK in your project directory.
   5. Open TEST_RES.MAK and remove TEST.RC from the project files.
 
   6. Select Project|Settings, click on the General tab and add
      "USE_RESDLL" to the list of Preprocessor Definitions.
   7. Open TEST.H and modify the class declaration of CTestApp this way:
     public:
        CTestApp();
     #ifdef USE_RESDLL
     public:
        virtual int ExitInstance();
     private:
        HINSTANCE m_hInstDLL;
     #endif
   8. Open TEST.CPP and modify CTestApp::InitInstance as follows.
      Also, add the newly declared ExitInstance member function:
    BOOL CTestApp::InitInstance()
    {
        // Standard initialization
        // If you are not using these features and wish to reduce the size
        //  of your final executable, you should remove from the following
        //  the specific initialization routines you do not need.
    #ifdef USE_RESDLL
        if ((m_hInstDLL = LoadLibrary("resdll.dll")) == NULL)
        {
          return FALSE; // failed to load the localized resources
        }
        else
        {
          AfxSetResourceHandle(m_hInstDLL); // get resources from the DLL
        }
    #endif
    ...
    #ifdef USE_RESDLL
    int CTestApp::ExitInstance()
    {
        FreeLibrary(m_hInstDLL);
        return CWinApp::ExitInstance();
    }
    #endif
   9. Compile. TEST_RES.EXE should work very nicely, loading its
      resources from the DLL.
   10. Close the project and open TEST.MAK. Compile. TEST.EXE shoudl
       also work very well but this time, the resources are loaded from the
       .EXE file because you had not defined USE_RESDLL in this version of
       the project. 
    BEWARE: when switching from one model to another, you must either
    Rebuild All
சனி, 20 பிப்ரவரி, 2010
இதற்கு குழுசேர்:
கருத்துரைகளை இடு (Atom)
 
கருத்துகள் இல்லை:
கருத்துரையிடுக