Creating Windows with MFC
MFC (Microsoft Foundation Classes) wraps the raw Win32 windowing API in a C++ class hierarchy rooted at CObject and CCmdTarget, with CWnd sitting directly above every visible window type. Instead of calling RegisterClass and CreateWindowEx by hand and writing a WndProc switch statement, you derive a class from CWnd (or a subclass like CFrameWnd), override virtual functions, and let the framework's message-pumping machinery route Windows messages to your C++ methods.
Cricket analogy: It's like a franchise handing a new player a ready-made kit bag and training program instead of making them assemble pads, gloves, and a bat from raw materials the way Bradman's generation effectively had to.
The CWnd Class and the Message Loop
CWnd encapsulates an HWND and provides member functions like Create(), ShowWindow(), and UpdateWindow() that map almost one-to-one onto their Win32 counterparts, but it also hooks into MFC's message-map dispatch so that Windows messages such as WM_PAINT or WM_LBUTTONDOWN arrive as calls to your overridden OnPaint() or OnLButtonDown() methods rather than requiring you to parse a UINT message ID inside a giant switch statement. The framework's CWinThread::Run() method owns the actual GetMessage/TranslateMessage/DispatchMessage loop, so an MFC application rarely writes that loop explicitly.
Cricket analogy: It's like a captain trusting a bowling coach's signal system so that a specific hand gesture from the boundary automatically triggers a field change, instead of shouting instructions across the ground every ball.
CFrameWnd, Window Classes, and Styles
Registering a Window Class and Choosing Styles
Before any window can be created, Windows needs a registered window class describing its default cursor, icon, background brush, and WndProc; MFC handles this transparently through AfxRegisterWndClass() or by reusing the standard 'AfxFrameOrView' class, so most MFC programmers never call RegisterClassEx directly. A typical top-level application window derives from CFrameWnd and is created by calling Create() with a WNDCLASS-style combination of window styles such as WS_OVERLAPPEDWINDOW, plus extended styles passed as dwExStyle, controlling borders, resizability, and taskbar presence.
Cricket analogy: It's like a stadium's groundstaff pre-marking the pitch dimensions and boundary rope to ICC standard before a Test match, so each new fixture doesn't require re-measuring the field from scratch.
// MyApp.h — application class
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
// MyApp.cpp
BOOL CMyApp::InitInstance()
{
CFrameWnd* pFrame = new CFrameWnd();
CString className = AfxRegisterWndClass(
CS_HREDRAW | CS_VREDRAW,
::LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1),
::LoadIcon(NULL, IDI_APPLICATION));
pFrame->Create(
className,
_T("MFC Main Window"),
WS_OVERLAPPEDWINDOW,
CRect(100, 100, 700, 500),
NULL, NULL, 0, NULL);
m_pMainWnd = pFrame;
pFrame->ShowWindow(m_nCmdShow);
pFrame->UpdateWindow();
return TRUE;
}
CMyApp theApp; // the one and only CWinApp-derived global instance
m_pMainWnd must be assigned before InitInstance() returns TRUE; MFC's CWinThread::Run() uses it to decide when the application should terminate — the app exits once this window is destroyed and its WM_QUIT propagates back to the message loop.
Only one CWinApp-derived object should exist per process (the global 'theApp' instance). Constructing a second CWinApp object, or forgetting to define theApp at global scope, leaves AfxGetApp() returning NULL and crashes framework code that relies on it during static initialization.
- CWnd is the base class for every visible MFC window and wraps an underlying Win32 HWND.
- CWinApp::InitInstance() is where the main frame window is constructed and shown, replacing a manual WinMain.
- MFC's CWinThread::Run() owns the GetMessage/TranslateMessage/DispatchMessage loop so you rarely write one by hand.
- AfxRegisterWndClass() registers a window class automatically instead of requiring an explicit RegisterClassEx call.
- Window styles (WS_OVERLAPPEDWINDOW, etc.) and extended styles still control borders, resizing, and taskbar behavior exactly as in raw Win32.
- Exactly one global CWinApp-derived object (theApp) must exist per application for AfxGetApp() to function.
- m_pMainWnd must be set for the framework to know which window's closure should end the application.
Practice what you learned
1. Which MFC class directly wraps a Win32 HWND and is the base for all visible windows?
2. Where does an MFC SDI/frame-based application typically create its main frame window?
3. What does AfxRegisterWndClass() do?
4. How many CWinApp-derived global objects should a standard MFC application define?
5. Which member of CWinApp must be set to a valid window for the application to terminate correctly when that window closes?
Was this page helpful?
You May Also Like
Dialog-Based Applications
How MFC's dialog-based application template uses DoModal and DDX/DDV to build a self-contained UI without a document/view frame.
Message Maps
How MFC's message-map macros build a static dispatch table that replaces a hand-written WndProc, plus how command routing and UI updates work on top of it.
MFC Controls Overview
A tour of MFC's C++ wrapper classes for Windows common controls, how to bind them via DDX_Control, and practical examples with CListCtrl and CComboBox.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics
Microsoft TechnologiesMVVM Design Pattern Study Notes
.NET · 30 topics