Disambiguating Calls to Windows API Functions

At its core, MFC wraps the Windows API (or large portions of it). MFC uses C++ classes to represent common Windows-based abstractions, such as windows, dialog boxes, device contexts, controls, brushes and other GDI objects, and so on. Most of these classes encapsulate a Windows handle, such as an HWND or HDC, as well as the relevant APIs that use that handle type. For example, class CWnd and all of the classes derived from it wrap an HWND by defining a class member variable to hold the HWND and class member functions to create and destroy the HWND and to otherwise operate on it. Most of the Windows API functions that take an HWND parameter are wrapped by CWnd or one of its derived classes.

Within an MFC program, though, you can freely call either the MFC wrapper function or the corresponding Windows API. You can get at all of the Windows API anytime you need to.

It can be pretty confusing if you're mixing MFC calls with Windows API calls, so you need to disambiguate your Windows API calls — the ones with the same names as MFC wrappers — using the C++ scope resolution operator (::). To use the scope operator, prefix the API name with it:


::BeginPaint(m_hWnd, &ps);

This lets the compiler know you're calling outside the class scope.

Tip If you aren't sure whether to disambiguate a function call, use F1 help in Visual C++ on the API name. Functions that MFC wraps bring up a dialog box asking you to specify whether you want help on the MFC version or the Windows API version. If the dialog box appears and lists "Class Library Reference," disambiguate the call. In most cases, the MFC version has a different parameter signature, and often a different return type. The MFC migration tool also helps you spot functions that must be disambiguated.

For SHOWDIB, whose message handling switch statement uses nothing but Windows API calls, you need to disambiguate lots of function calls. Adding the scope operator to nearly all calls that take an initial HWND or HDC parameter in your view's WindowProc, OnDraw, and OnCmdMsg takes care of most of them. The compiler will give you error messages about parameter types or numbers of parameters for the rest.