100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C++

Creating Windows with MFC

How MFC's CWnd/CFrameWnd hierarchy and CWinApp::InitInstance replace manual Win32 window registration and message-loop code.

Windows and DialogsBeginner8 min readJul 10, 2026
Analogies

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.

cpp
// 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

Was this page helpful?

Topics covered

#MFCMicrosoftFoundationClassesStudyNotes#MicrosoftTechnologies#CreatingWindowsWithMFC#Creating#Windows#MFC#CWnd#StudyNotes#SkillVeris#ExamPrep