FAQ: Frequently Asked Questions About 16-bit Foundation Classes

Last reviewed: July 22, 1997
Article ID: Q109039
 This article applies to:

   The Microsoft Foundation Classes (MFC) included with:
    - Microsoft Visual C++ for Windows, versions 1.0, 1.5

SUMMARY

       Microsoft Foundation Class Library Questions and Answers
                      Last revised: June 14, 1993

The text below presents a list of 25 frequently asked questions regarding the Microsoft Foundation Class (MFC) Library and the answers to these questions. For additional information regarding the Microsoft Foundation Class Library, please refer to the Microsoft Knowledge Base and to the Microsoft Software Library.

Index to Questions

The following questions are addressed in this document:

  1. How do I perform multiple levels of derivation with ClassWizard? 2. How do I size a CFormView? 3. How do I use new views with document templates? 4. How do I size a view? 5. How do I create an application that is initially maximized? 6. How do I activate a previous instance of an application? 7. How do I change the background color of a view? 8. How do I update the text of a pane in a status bar? 9. What are the user interface guidelines?
10. Can I use the CTRL3D three-dimensional controls dynamic-link library
   (DLL) in a application developed with the Microsoft Foundation Class
    (MFC) Library?
11. Should I use in my application functions of the Microsoft Foundation
    Class Library that are not listed in the printed documentation or in
    the Help file?
12. Do I need to use documents and views? 13. How should I define the WEP in an MFC DLL? 14. Do I need a CWinApp object in a DLL developed with the Microsoft
    Foundation Class Library?
15. Can I use a VBX control in a DLL developed with the Microsoft
    Foundation Class Library?
16. How can I work around the fact that the HSZ data type is different for
    VBX controls and for the Dynamic Data Exchange Management Library
    (DDEML)?
17. When will the Microsoft Foundation Class Library support version 2.0 of
    the Object Linking and Embedding (OLE) specification?
18. When will the Microsoft Foundation Class Library version 2.0 be
    available for Windows NT?
19. How can I track down memory leaks in my application? 20. How do I enable TRACE macros in my application? 21. Why does the debug version of Windows run so slowly? 22. How do I change the styles of a window that is created by the
    framework?
23. How do I create a C++ object that corresponds to a control in a dialog
    box?
24. How do I perform background processing in an application developed with
    the Microsoft Foundation Class Library?
25. How do I use a custom icon for a window in an application developed
    with the Microsoft Foundation Class Library?

Microsoft Foundation Class Library Frequently Asked Questions List

 1. Q. How do I perform multiple levels of derivation with ClassWizard?

    A. A Microsoft Knowledge Base article discusses this issue. The full
       text of this article is reproduced below.

       Deriving from Classes Not Listed in ClassWizard
       \* Q99161
       ---------------------------------------------------------------
       The information in this article applies to:

        - Microsoft Visual Workbench for Windows, version 1.0
       ---------------------------------------------------------------

       SUMMARY
       =======

       Microsoft ClassWizard version 1.0 supports deriving classes
       only from the classes listed in the Class Type field of the Add
       Class dialog box. To create a class derived from a previously
       derived class or to derive from another class based on the
       Microsoft Foundation Class Library CWnd class that is not
       listed in the Class Type field, a few extra steps are required.

       MORE INFORMATION
       ================

       For example, suppose the following derivation tree is desired:

          MyDerivedClass
                ^
                |
            MyBaseClass
                ^
                |
             CDialog

       or, it is desirable to derive a class from a class based on
       CWnd that is not listed in the Class Type field in the Add
       Class dialog box, such as CFileDialog. There is no predefined
       method to create this type of class hierarchy using the
       ClassWizard. However, by using the parsing techniques
       ClassWizard uses, you can create these class hierarchies.

       The steps below use CDialog as the default class type. Before
       proceeding, determine which predefined class type is closest to
       the desired base class. For example, CFileDialog is similar to
       CDialog. If none of the classes correspond closely to your
       desired class, use the generic CWnd class.

       To create a class with multiple levels of derivation, perform
       the following three steps:

       1. Use ClassWizard to create MyDerivedClass, deriving it from
          CDialog (or another appropriate predefined class).

       2. Use ClassWizard to create MyBaseClass, deriving it from
          CDialog (or another appropriate predefined class).

       3. Edit the code generated for MyDerivedClass and replace all
          references to CDialog with MyBaseClass. This step is very
          important; many errors occur if this is not done correctly
          and these errors may  be difficult to track down.

       To create a class based on a class based on CWnd that is not
       supported by ClassWizard, perform the following two steps:

       1. Use ClassWizard to create MyDerivedClass, deriving it from
          CDialog (or another appropriate predefined class based on
          CWnd).

       2. Edit the code generated for MyDerivedClass and replace all
          references to CDialog with the name of the class from which
          you are deriving this class, for example, CFileDialog. This
          step is very important; many errors occur if this is not
          done correctly and these errors may be difficult to track
          down.

       Then, for either type of class, perform the following three
       steps:

       1. Delete the project .CLW file.

       2. Start App Studio, load your project .RC file, and activate
          ClassWizard.

       3. Because the project does not have a .CLW file, ClassWizard
          prompts to generate a .CLW file. Choose Yes to generate the
          file. NOTE: You must generate this file in App Studio. If
          you attempt to generate the file in Visual Workbench, VWB
          instructs you to generate the file in App Studio.

       Once App Studio has created the .CLW file, the base class of
       the derived class has been changed successfully. To verify
       this, view the class in ClassWizard and see the data in the
       Class Info dialog box.

       For classes created using multiple levels of derivation, you
       can use ClassWizard to pass system messages, such as
       WM_INITDIALOG, to the base class as well. To do this, perform
       the following nine steps:

       1. Start ClassWizard.

       2. Select the MyDerivedClass class.

       3. Select MyDerivedClass in the Object IDs window.

       4. Select the WM_INITDIALOG message in the Messages window.

       5. Choose Add Function to add a function skeleton that calls
          the OnInitDialog() function in MyBaseClass.

       6. Select the MyBaseClass class.

       7. Select MyBaseClass in the Object IDs window.

       8. Select the WM_INITDIALOG message in the Messages window.

       9. Choose Add Function to add a function skeleton that calls
          the OnInitDialog() function in CDialog. This step is
          required only once. If you derive additional classes from
          the base class, you do not need to redo this operation.

 2. Q. How do I size a CFormView?

    A. Knowledge Base article Q98598 discusses this issue. The full
       text of this article is reproduced below.

       Using CFormView in SDI and MDI Applications

       ---------------------------------------------------------------
       The information in this article applies to:

        - Microsoft Foundation Class Library for Windows, version 2.0
       ---------------------------------------------------------------

       SUMMARY
       =======

       The CFormView class provides a convenient method to place
       controls into a view that is based on a dialog box template.
       The general procedure to use a CFormView is described in the
       documentation for the class and is illustrated in the VIEWEX
       and CHKBOOK sample applications provided with Microsoft
       Foundation Class Library version 2.0. However, these
       applications do not demonstrate making the initial size of the
       frame window to be the same as the initial size of the form.

       In an application that uses the CFormView class, CFormView
       replaces the default AppWizard CView class. The documentation
       does not demonstrate editing a Visual C++ project to remove the
       unneeded CView class and reconstruct the ClassWizard .CLW file.
       The text below demonstrates this technique.

       The following section lists the steps required to support
       creating a single document interface (SDI) or multiple document
       interface (MDI) application based on a CFormView, sizing the
       initial frame window around the form, changing the style of the
       frame, and closing an MDI document using a button in the form.

       MORE INFORMATION
       ================

       No fully automated method exists to use a CFormView object in
       an application generated by AppWizard. However, the following
       nine steps are quite straightforward.

       1. Use the AppWizard to generate an SDI or MDI application
          skeleton.

       2. Design the form (dialog box) in App Studio. Set the styles
          according to the CFormView documentation.

       3. Use ClassWizard to create a new class based on CFormView.
          Either delete the default OK and Cancel buttons, or modify
          the ID for these buttons. The values IDOK and IDCANCEL cause
          ClassWizard to generate incorrect entries in the message map
          and incorrect message handler functions when they are used
          in a class derived from CFormView.

       4. In the main .CPP file for the application, find the
          AddDocTemplate function. Replace the name of the view class
          that AppWizard generates with the name of the class derived
          from CFormView. Use the #include statement to include the .H
          file for the CFormView class.

       5. Delete the .CPP and .H files that AppWizard generated to
          contain the original CView object. Edit other files in the
          project to remove any references to these files.

       6. In the Visual Workbench, edit the project to remove
          references to the view files deleted in step 5 above.

       7. In ClassWizard, choose the deleted view class. ClassWizard
          displays its "Repair Class Information" dialog box. Choose
          the Remove button to delete the obsolete class from the
          project's ClassWizard (.CLW) file.

       8. Override the OnUpdate() and UpdateData() member functions as
          documented in the CFormView documentation to update the
          member variables with the current document data and to
          perform dialog data exchange (DDX).

       9. If you would like to set the initial size of the form view,
          override the OnInitialUpdate() function. The text below
          provides additional information about this step, which is
          slightly different in an SDI or MDI application.

       Changing the Size of an SDI Main Frame Around a CFormView
       ---------------------------------------------------------

       To change the size of the main frame of an SDI application
       (that uses CFormView as its view class) to be the appropriate
       size for the form you designed in App Studio, override the
       OnInitialUpdate() function in your class derived from
       CFormView, as follows:

          void CMyFormView::OnInitialUpdate()
          {
             CFormView::OnInitialUpdate();
             GetParentFrame()->RecalcLayout();
             ResizeParentToFit(/*FALSE*/); // default argument is TRUE
          }

       If the size of the CMyFormView window, before calling
       ResizeParentToFit(), is smaller than the size specified in the
       dialog box template, and the application overrides the default
       TRUE argument in the ResizeParentToFit() function with FALSE,
       the following two consequences may occur:

        - In the ResizeParentToFit() call, the new size of the parent
          window may be calculated based on a form that includes
          scroll bars. This takes place if the initial size chosen by
          Microsoft Windows is smaller than the form designed in App
          Studio.

          Because the scroll bars are not needed after changing the
          size of the view, the view includes extra unused area on the
          right side and at the bottom of the resized form in a width
          equal to that of the scroll bars. To work around this
          behavior, call ResizeParentToFit() twice; once to "expand"
          the view and remove the scroll bars, and the second time to
          reduce the size of the view to the smallest size available
          without scroll bars. In the second call, the default
          bShrinkOnly = TRUE parameter is appropriate.

        - The main frame may be too large for the screen if the form
          is designed on a system that has a high-resolution monitor
          and the code runs on a system that has a standard VGA
          resolution.

       The ResizeParentToFit() function does not prevent the form from
       changing size when the user changes the size of the application
       main frame (scroll bars are added automatically if needed). To
       modify the style of the frame window that is the parent of a
       form view, you can override the PreCreateWindow() function in
       the CMainFrame class generated by AppWizard. For example, to
       remove the WS_THICKFRAME style and prevent the user from
       changing the size of the window, declare PreCreateWindow() in
       MAINFRM.H and add the following code to MAINFRM.CPP:

          BOOL CMainFrame::PreCreateWindow(CREATESTRUCT &cs)
          {
             cs.style &= ~WS_THICKFRAME;
             return CFrameWnd::PreCreateWindow(cs);
          }

       Changing the Size of an MDI Child Frame Around a CFormView
       ----------------------------------------------------------

       The process of changing the size of an MDI child frame is
       similar to changing the size of a main frame for an SDI
       application, as explained above. However, the RecalcLayout()
       call is not required.

       To change the size of an MDI child frame around a form view,
       override the OnInitialUpdate() function in your class derived
       from CFormView as follows:

          void CMDIFormView::OnInitialUpdate()
          {
             CFormView::OnInitialUpdate();
             ResizeParentToFit(/*FALSE*/); // default argument is TRUE
          }

       If the application overrides the default argument to the
       ResizeParentToFit() function, essentially the same consequences
       occur as for an SDI application, as explained above. In
       addition, the child window may be too large for the enclosing
       MDI main frame or for the entire screen.

       To change the style of the MDI child frame (for example, to
       remove the WS_THICKFRAME style so the user cannot change the
       size of the window), derive an MDI child window class and
       override the PreCreateWindow function as demonstrated in the
       SDI example above.

       Closing an MDI Form with a Button
       ---------------------------------

       To create a button on a form that closes the document, use
       ClassWizard to add a message handler for the BN_CLICKED message
       to the CFormView class. Make sure that the buttons in CFormView
       do not have the default IDOK or IDCANCEL identifiers. If they
       do, ClassWizard creates incorrect entries in the message map
       and incorrect functions for the buttons.

       Once the message handler is in place, you can simulate the
       Close command on the File menu with the following code:

          void CMyForm::OnClickedButton1()
          {
             PostMessage(WM_COMMAND, ID_FILE_CLOSE);
          }

       This method to close a form prompts the user to save the file
       if the IsModified() member function associated with the
       document returns TRUE.

 3. Q. How do I use new views with document templates?

    A. 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 AppWizard
       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 AppWizard. 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 additional information, please see the following article(s)
       in the Microsoft Knowledge Base:

          ARTICLE-ID: Q99562
          TITLE     : Switching views in a Single Document
                      Interface Program

 4. Q. How do I size a view?

    A. 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.

 5. Q. How do I create an application that is initially maximized?

    A. For an MDI application, in the CWinApp::InitInstance()
       function, set CWinApp::m_nCmdShow to SW_SHOWMAXIMIZED before
       calling pMainFrame->ShowWindow(m_nCmdShow). For example, in an
       application generated by AppWizard, the code is as follows:

          // create main MDI Frame window
          CMainFrame* pMainFrame = new CMainFrame;
          if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
              return FALSE;
          m_nCmdShow = SW_SHOWMAXIMIZED;  // ADD THIS LINE!
          pMainFrame->ShowWindow(m_nCmdShow);
          pMainFrame->UpdateWindow();
          m_pMainWnd = pMainFrame;

      In an SDI application, in the CWinApp::InitInstance() function,
      set CWinApp::m_nCmdShow to SW_SHOWMAXIMIZED before calling
      OnFileNew(). For example, in an application generated by AppWizard,
      the code is as follows:

         m_nCmdShow = SW_SHOWMAXIMIZED;
         // create a new (empty) document
         OnFileNew();

 6. Q. How do I activate a previous instance of an application?

    A. Knowledge Base article Q70074 discusses two common techniques
       to reactivate a previous instance of an application. One
       technique involves using the FindWindow() function and the
       other uses the hPrevInst parameter. The hPrevInst method
       described in this article uses the GetInstanceData() function,
       which is not available in Windows NT.

       The FindWindow() method requires the application to enumerate
       top-level windows looking for a WndClass value that matches
       that of the application. An application developed with the
       Microsoft Foundation Class (MFC) Library can use this technique;
       however, the application must register its own WndClass value.
       By default, an application developed with the Microsoft
       Foundation Class Library uses classes registered by the
       Library. For more information on registering private windows
       classes, please refer to Technical Note #1 in the MFC Tech
       Notes help file distributed with Microsoft Visual C++ version
       1.0 for Windows.

 7. Q. How do I change the background color of a view?

    A. Knowledge Base article Q103786 discusses changing the background
       color of a CFrameWnd, CView, or CWnd object. The full text of
       this article is reproduced below.

       Changing Window Background Color with Foundation Classes

       ---------------------------------------------------------------
       The information in this article applies to:

        - Microsoft Foundation Classes for Windows, version 2.0
       ---------------------------------------------------------------

       SUMMARY
       =======

       To change the background color for a CView, CFrameWnd, or CWnd
       object, process the WM_ERASEBKGND message. The text below
       demonstrates doing this.

          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;
          }

       MORE INFORMATION
       ================

       To change the background color of a CFormView object, either
       process the WM_ERASEBKGND message and use the code above or
       process the WM_CTLCOLOR message to change the background color.

       For more information on changing the background color of a
       dialog box by processing the WM_CTLCOLOR message, please search
       in the Microsoft Knowledge Base on the following words:

          Changing Background Color MFC

 8. Q. How do I update the text of a pane in a status bar?

    A. 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.

       For additional information, please see the following article(s) in
       the Microsoft Knowledge Base:

          ARTICLE-ID: Q99198
          TITLE     : Displaying the Current Time in a CStatusBar Pane

 9. Q. What are the user interface guidelines?

    A. Most "first class" applications for the Microsoft Windows
       operating system share a familiar and consistent user
       interface. This improves the usability of the application
       because the user is not forced to relearn common operations.
       For example, a user that regularly prints documents from
       Microsoft Word intuitively looks for a Print option on the File
       menu when confronted with the task of printing in an unfamiliar
       application.

       Microsoft provides suggested guidelines for applications to use
       the standard Windows user interface objects and environment in
       a consistent manner. The book "The Windows Interface: An
       Application Design Guide" is available from Microsoft Press; it
       contains a chapter on overall principles and methodology along
       with specific guidelines for keyboard input, windows, menus,
       and so on. For a brief introduction to usability and its
       associated issues, please refer to pages 18-19 of the
       "Presenting Visual C++" tabloid provided with Microsoft Visual
       C++ version 1.0 for Windows.

       The Microsoft Foundation Class (MFC) Library, and especially the
       skeleton applications created with AppWizard, provide a good
       starting point to develop an application that conforms to the
       published guidelines. These tools ease the process of
       developing an application that has the "look and feel" expected
       by experienced users of the Windows environment.

       Please note that the Microsoft Foundation Class Library was
       designed to support the published user interface guidelines.
       Overriding the default behavior in derived classes may be vary
       difficult in some cases. However, adding to the default
       behavior is relatively simple.

10. Q. Can I use the CTRL3D three-dimensional controls dynamic-link
       library (DLL) in a application developed with the Microsoft
       Foundation Class Library?

    A. CTL3D.DLL was updated recently to be compatible with version
       2.0 of the Microsoft Foundation Class Library. The new version
       of CTL3D.DLL is available in the Microsoft Developer Network
       (MSDN) software library.

11. Q. Should I use in my application functions of the Microsoft
       Foundation Class Library that are not listed in the printed
       documentation or in the online help file?

    A. In general, it is best to use functions that are listed in the
       "Class Libraries Reference" manual or in the MFC Tech Notes
       help file. However, classes in the Microsoft Foundation Class
       Library contain many functions that are not listed in the
       printed manuals but that may be useful to develop an
       application. The class definitions in the Microsoft Foundation
       Class Library header files list each of the functions in a
       class. These functions are grouped into different categories
       such as Constructors, Operations, Overrideables, and
       Implementation. If you choose to use a function not listed in
       the printed documentation, it is best to avoid functions in the
       Implementation section. Even though any function not listed in
       the printed documentation is subject to change in a future
       version of the Microsoft Foundation Class Library, the
       functions in the Implementation section are most likely to
       change and functions in the remaining sections are less likely
       to change.

12. Q. Do I need to use documents and views?

    A. The architecture of applications developed with version 2.0 of
       the Microsoft Foundation Class Library was designed using the
       document/view concept. However, it is not necessary to use this
       in your application. For example, even though the HELLOAPP
       sample application uses neither a document nor a view, you can
       use any applicable tool (such as ClassWizard or App Studio)
       with the application and you can incorporate any desired
       features from the Microsoft Foundation Class Library, such as
       status bars or tool bars.

13. Q. How should I define the WEP in an MFC DLL?

    A. Knowledge Base article Q98374 discusses this issue. The full
       text of this article is reproduced below.

       Using the C Run-Time WEP() in an MFC 2.0 _USRDLL Library

       ---------------------------------------------------------------
       The information in this article applies to:

        - Microsoft Foundation Class Library for Windows, version 2.0
       ---------------------------------------------------------------

       SUMMARY
       =======

       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.

       MORE INFORMATION
       ================

       To use the WEP() function in the C run-time library, the DLL
       must export WEP in its module definition (.DEF) file. To do so,
       add the following statement  to the .DEF file:

          EXPORTS
             WEP  @1 RESIDENTNAME

       While the ordinal number you choose is not important, you must
       specify the RESIDENTNAME attribute when you export WEP(). Do
       not include a WEP() function in the DLL code. If you do,
       Windows calls that function instead of the C library WEP() and
       the destructors for global objects and static objects, and
       CWinApp::ExitInstance() are not called.

       If you DLL must contain clean-up code, overload the
       ExitInstance() function. If your DLL uses an import library to
       link to another DLL developed with the Microsoft Foundation
       Classes, be sure to list the Microsoft Foundation Class Library
       and the C run-time library before the import library for the
       other DLL. This step ensures that the linker includes the WEP()
       in the C run-time library instead of linking in a reference to
       the WEP() in the other DLL.

       The instructions above describe building a _USRDLL that unloads
       itself and cleans up properly. The text below describes the
       process that occurs when a DLL cleans up.

       When Windows unloads the DLL, it calls the WEP() function in
       the DLL, which, using the procedure above, is the WEP()
       function in the C run-time library. WEP() calls the _WEP()
       function implemented in the Microsoft Foundation Class Library.
       The _WEP() function calls CWinApp::ExitInstance(). When
       ExitInstance() and _WEP() return, the WEP function calls the
       destructors for any static or global objects in the DLL.

       For more information about using the C run-time library WEP()
       function in an _USRDLL, please refer to Technical Note 11:
       "Using MFC as Part of a DLL" in the MFC Tech Notes help file
       distributed with Visual C++ version 1.0.

14. Q. Do I need a CWinApp object in a DLL developed with the
       Microsoft Foundation Class (MFC) Library?

    A. 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.
       MFC Tech Note 33 describes these requirements in detail.

15. Q. Can I use a VBX control in a dynamic-link library (DLL) developed
       with the Microsoft Foundation Class (MFC) Library?

    A. You can use VBX controls in an _AFXDLL but not in an _USRDLL.
       If using a VBX control in a AFXDLL, please read below:
       Because VBX controls are not standard Windows controls, they do
       not have a class name. MFC works around this by providing a
       Windows class, VBControl, which it can use to create VBX controls.
       The VBControl class is used as the class name in the dialog box
       template for every VBX control used in the dialog box.

       When the application that calls the DLL calls the EnableVBX()
       function, it registers the VBControl window class with
       Microsoft Windows. The VBControl class is registered as a local
       window class, not as a global window class. A local window
       class is available only to the module in which the class is
       registered. Because a DLL has its own module that is different
       from the calling application, the VBControl class is not
       available to the DLL.

       Workarounds to this problem:

        - The application can call the Create() member function of
          the CVBControl class to create the VBX control. Call
          Create() in the OnInitDialog() function (for a modal dialog
          box) or in the OnCreate() function (for a modeless dialog
          box).

        - Re-register the VBControl class in the DLL so that it can
          be used from the DLL. Also, change the resource instance
          handle during the OnInitDialog() function so that resource
          in the DLL will be used while the controls are being created.

          This second method is demonstrated in the AFXVBX sample
          described in article Q104239.

16. Q. How can I work around the fact that the HSZ data type is
       different for VBX controls and for the Dynamic Data Exchange
       Management Library (DDEML)?

    A. If you want to use VBX controls and the DDEML in the same
       application, then you must perform the following:

        - Separate the VBX code and the DDEML code into different
          modules. In the module that contains the DDEML code, define
          the preprocessor symbol NO_VBX_SUPPORT.

17. Q. When will the Microsoft Foundation Class (MFC) Library support
       version 2.1 of the Object Linking and Embedding (OLE)
       specification?

    A. Microsoft is actively working on MFC classes for OLE 2.1 and
       expects to release these classes by the end of this year.

18. Q. When will the Microsoft Foundation Class (MFC) Library version 2.0
       be available for Windows NT?

    A. Microsoft has announced that Visual C++ for Windows NT, which
       includes version 2.0 of the Microsoft Foundation Class Library,
       will be released within 90 days of the retail release of
       Windows NT.

19. Q. How can I track down memory leaks in my application?

    A. Most of the text below is present in the Microsoft Foundation
       Class (MFC) Library online help file.

       You can substitute DEBUG_NEW for the new operator in each
       location that the application allocates storage from the help.
       In debugging mode (when the code is compiled with the _DEBUG
       symbol defined), DEBUG_NEW tracks the filename and line number
       for each object it allocates. Then, when the application calls
       the CMemoryState::DumpAllObjectsSince() member function, the
       application displays each memory object allocated with
       DEBUG_NEW along with the filename and line number of the
       statement that performed the allocation. To use DEBUG_NEW in
       your application, insert the following directive into your
       source files:

          #define new DEBUG_NEW

       Once this directive is in place, the preprocessor replaces all
       occurrences of new with DEBUG_NEW and the Microsoft Foundation
       Class Library handles the remainder of the processing. When you
       compile a release version of your application, DEBUG_NEW
       reverts to the new operator and eliminates the filename and
       line number overhead.

       If you define DEBUG_NEW and your application has a memory leak,
       the system displays information about the memory leak when the
       application terminates. The system writes the data to a
       terminal connected to COM1 (or to the DBWIN application if it
       is running).

       For example, modify the HELLOAPP sample by adding the following
       lines to the CHelloApp::InitInstance() function (beginning on
       line 33 in the HELLOAPP.CPP file)

          char *p;
          p = new char[1];

       and define DEBUG_NEW at the beginning of the file. Compile the
       application for debugging mode. When you exit the application,
       it displays text such as the following on your debugging
       terminal or in the DBWIN window:

          Detected memory leaks!
          Dumping objects ->
          {5} c:\msvc\mfc\samples\helloapp\helloapp.cpp(34) :
              non-object block at $45CF3Eg
          Object dump complete.

       Line 34 is the line that contains the new operator.

       For more information on the DEBUG_NEW macro, please refer to
       Chapter 15 of the "Class Libraries User's Guide."

20. Q. How do I enable TRACE macros in my application?

    A. If you use Visual C++ 1.0, run the TRACER application from your
       Microsoft Visual C++ program group (its icon has the title "MFC
       Trace Options"). Select "Enable Tracing," then choose OK.

       If you use Microsoft C/C++ 7.0, you must copy the AFX.INI file
       from the Microsoft Foundation Class (MFC) Library source directory
       (by default, C:\C700\MFC\SRC) to your Windows directory (by
       default, C:\WINDOWS). This file should contain a section such
       as the following:

          [Diagnostics]
          TraceEnabled = 1
          TraceFlags = 0

       As long as TraceEnabled is set to 1, tracing is enabled.

       This AFX.INI file is the same for both C/C++ 7.0 and Visual C++
       1.0.

21. Q. Why does the debug version of Windows run so slowly?

    A. The debug version of Windows runs slightly slower than the
       retail version because it performs extensive parameter
       validation on calls to Windows application programming
       interface (API) functions.

22. Q. How do I change the styles of a window that is created by the
       framework?

    A. Knowledge Base article Q99847 discusses this issue. The full
       text of this article is reproduced below.

       Changing Window Attributes in an MFC Application

       ---------------------------------------------------------------
       The information in this article applies to:

        - Microsoft Foundation Class Library for Windows, version 2.0
       ---------------------------------------------------------------

       SUMMARY
       =======

       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.

       MORE INFORMATION
       ================

       In a single document interface (SDI) application, the default
       window style in the framework is a combination of the
       WS_OVERLAPPEDWINDOW and FWS_ADDTOTITLE styles. FWS_ADDTOTITLE
       is a framework-specific style that instructs the framework to
       add the document title to the window's caption. To change the
       window attributes in an SDI application, override the
       PreCreateWindow() function in your class derived form
       CFrameWnd. For example:

       BOOL CMainFrame::PreCreateWindow(CREATESTRUt& cs)
       {
          // Create a window without
          // min/max buttons or sizable border
          cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER;

          // Size the window to 1/3 screen size and center it
          cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3;
          cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3;
          cs.y = ((cs.cy * 3) - cs.cy) / 2;
          cs.x = ((cs.cx * 3) - cs.cx) / 2;

          return CFrameWnd::PreCreateWindow(cs);
          }

       A little more work is required to change the window style of a
       child window in a multiple document interface (MDI)
       application. By default, an MDI application generated in
       AppWizard uses the default CMDIChildWnd class defined in the
       Microsoft Foundation Class Library. To change the window style
       of an MDI child window, your application must derive a new
       class from CMDIChildWnd and replace all references to
       CMDIChildWnd in your project with references to the new class.
       Most likely, the only reference to CMDIChildWnd in the
       application is located in your application's InitInstance()
       member function.

       The default window style used in an MDI application is a
       combination of the WS_CHILD, WS_OVERLAPPEDWINDOW, and
       FWS_ADDTOTITLE styles. To change the window attributes of an
       MDI application's child windows, override the PreCreateWindow()
       function in your class derived from CMDIChildWnd. For example:

          BOOL CMyChildWnd::PreCreateWindow(CREATESTRUCT& cs)
          {
             // Create a child window without the maximize button
             cs.style &= ~WS_MAXIMIZEBOX;
             return CMDIChildWnd::PreCreateWindow(cs);
          }

       For more information about the PreCreateWindow() function,
       please refer to the Microsoft Visual C++ "Class Library
       Reference, Volume 1" or to the Visual C++ Help file.

23. Q. How do I create a C++ object that corresponds to a control in a
       dialog box?

    A. You can use the CWnd::GetDlgItem() function to retrieve a
       pointer to the specified control or child window in a dialog
       box. Specify the control ID as an argument and the function
       returns a CWnd pointer. Usually, you need to cast the return
       value to the proper type. An example of using this function
       follows:

          MyEditCtrlPtr =  (CEdit *)GetDlgItem(IDC_MYEDITCTRL);

24. Q. How do I perform background processing in an application
       developed with the Microsoft Foundation Class (MFC) Library?

    A. Knowledge Base article Q99999 discusses this issue. The full
       text of this article is reproduced below.

       Background Processing In an MFC Application

       ---------------------------------------------------------------
       The information in this article applies to:

        - Microsoft Foundation Class Library for Windows, version 2.0
       ---------------------------------------------------------------

       SUMMARY
       =======

       Many applications perform lengthy processing "in the
       background" during intervals that the user is not otherwise
       interacting with the application. In an application developed
       for the Microsoft Windows operating system, an application can
       perform background processing by splitting a lengthy process
       into many small fragments. After processing each fragment, the
       application yields execution control to Windows using a
       PeekMessage() loop.

       An application developed with the Microsoft Foundation Class
       Library can perform background processing either by using the
       PeekMessage() loop in the library code's main message loop or
       by embedding another PeekMessage() loop in the application.

       MORE INFORMATION
       ================

       In an application developed with the Microsoft Foundation Class
       Library, the main message loop in the CWinApp class contains a
       PeekMessage() loop. This loop calls the CWinApp::OnIdle()
       function between messages. An application can process messages
       in this idle time by overriding the OnIdle() function. For more
       information about performing background processing in the
       OnIdle() function, please refer to the documentation for the
       CWinApp::OnIdle() function in the "Class Libraries Reference"
       manual.

       Another method to perform background processing in an
       application involves embedding a PeekMessage() loop in a
       function. Because a PeekMessage() loop is very similar to the
       main message loop, such a loop in an application developed with
       the Microsoft Foundation Class Library must perform many of the
       functions of the main message loop in the library. The
       following code fragment demonstrates writing a PeekMessage()
       loop that is compatible with the Microsoft Foundation Class
       Library:

          while (bDoingBackgroundProcessing)
          {
             while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
             {
                if (msg.message == WM_QUIT)
                {
                   bDoingBackgroundProcessing = FALSE;
                   ::PostQuitMessage();
                   break;
                }
                if (!AfxGetApp()->PreTranslateMessage(&msg))
                {
                   ::TranslateMessage(&msg);
                   ::DispatchMessage(&msg);
                }
             }
             AfxGetApp()->OnIdle(0);   // updates user interface
             AfxGetApp()->OnIdle(1);   // frees temporary objects

             // Perform some background processing here
          }

25. Q. How do I use a custom icon for a window in an application
       developed with the Microsoft Foundation Class (MFC) Library?

    A. 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 the Microsoft Foundation Class Library, 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.


Additional query words: q&a q & a faq 2.00 2.50
Keywords : kb16bitonly kbprg MfcMisc kbfaq
Technology : kbMfc
Version : 1.0 1.5
Platform : WINDOWS
Issue type : kbinfo


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 22, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.