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

MFC Application Architecture

How an MFC application is structured around CWinApp, message maps, and frame windows, and how these pieces cooperate to start up, route input, and shut down cleanly.

FoundationsIntermediate9 min readJul 10, 2026
Analogies

MFC Application Architecture

Every MFC application is organized around three cooperating pieces: a single CWinApp-derived object that represents the process and drives startup, a CFrameWnd-derived (or CWnd-derived) main window that hosts the UI, and a message map on each window-owning class that declares which member function handles which incoming message or command. Understanding how these three pieces hand off control to one another - from process entry, to InitInstance, to the running message loop - is the key to understanding how any MFC program actually executes.

🏏

Cricket analogy: The CWinApp/CFrameWnd/message-map trio is like a Test match's structure: the match referee (CWinApp) oversees the whole fixture, the stadium (CFrameWnd) hosts the actual play, and the scoring rules (message map) determine exactly how each ball bowled is recorded.

CWinApp and Startup

When an MFC executable starts, the C runtime constructs the single global CWinApp-derived object (commonly named theApp) before WinMain even runs, since that constructor call happens at static-initialization time. The MFC-provided WinMain then calls the virtual InitInstance() member function on that object, which is where application-specific setup belongs - creating the main window, loading a document template, parsing the command line - and returning FALSE from InitInstance() tells the framework to abort startup immediately without ever entering the message loop.

🏏

Cricket analogy: theApp being constructed before WinMain runs is like a stadium's groundstaff preparing the pitch before the umpires even walk out - setup happens automatically ahead of the match officially starting, driven by a fixed schedule rather than a referee's command.

Message Maps and Command Routing

A message map is a static table generated by the DECLARE_MESSAGE_MAP macro in a class's header and populated with entries like ON_WM_PAINT() or ON_COMMAND(ID_FILE_OPEN, &CMyFrame::OnFileOpen) between BEGIN_MESSAGE_MAP and END_MESSAGE_MAP in the .cpp file, and MFC's CWnd::WindowProc walks this table (and its base classes' tables) at runtime to find the right handler for each incoming message. Command messages specifically - generated by menu items, toolbar buttons, and accelerator keys - go through an additional mechanism called command routing, where MFC walks a chain of candidate objects (view, then document, then frame, then application) looking for the first one whose message map claims that command ID, which is what lets a single 'Save' menu item be handled by whichever object currently makes sense.

🏏

Cricket analogy: Command routing walking view, document, frame, then application is like a cricket board's appeal escalation: an on-field umpire (view) rules first, and if uncertain it escalates to the third umpire (document), then the match referee (frame), then the ICC (application).

cpp
// CMainFrame.h
class CMainFrame : public CFrameWnd
{
protected:
    afx_msg void OnFileOpen();
    afx_msg void OnPaint();
    DECLARE_MESSAGE_MAP()
};

// CMainFrame.cpp
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_COMMAND(ID_FILE_OPEN, &CMainFrame::OnFileOpen)
    ON_WM_PAINT()
END_MESSAGE_MAP()

void CMainFrame::OnFileOpen()
{
    CFileDialog dlg(TRUE); // TRUE = Open dialog
    if (dlg.DoModal() == IDOK)
    {
        // load the selected file
    }
}

void CMainFrame::OnPaint()
{
    CPaintDC dc(this);
    dc.TextOutW(10, 10, _T("Hello, MFC!"));
}

Command routing is precisely why the same 'Copy' menu command can behave differently depending on which document is active: MFC routes ID_EDIT_COPY first to the active view, and only falls back to the frame or application if the view's message map doesn't handle it.

Frame Windows and Resources

A CFrameWnd (or CMDIFrameWnd for a multiple-document-interface application) is the top-level window that hosts the menu bar, toolbar, and status bar, and it is typically constructed and shown from CWinApp::InitInstance(). Its visual layout - the menu's text and command IDs, the toolbar's button bitmaps, dialog templates, string tables, and icons - lives in a separate resource script (a .rc file) that Visual Studio's resource editor manipulates, and each resource is referenced from code by a numeric ID defined in resource.h, which is why keeping resource.h and the .rc file in sync matters when editing dialogs by hand.

🏏

Cricket analogy: The .rc file's resources (menus, toolbars, icons) being separate from the C++ logic is like a stadium's signage and scoreboard graphics being managed separately from the actual match officiating rules - both matter, but they're maintained independently.

  • Every MFC app centers on one CWinApp object, a main CFrameWnd-derived window, and message maps on each handling class.
  • theApp is constructed at static-initialization time, before WinMain or InitInstance() runs.
  • CWinApp::InitInstance() is where application-specific startup (creating windows, loading templates) happens.
  • Returning FALSE from InitInstance() aborts startup before the message loop ever begins.
  • Message maps, built with BEGIN_MESSAGE_MAP/END_MESSAGE_MAP, route messages to named member functions.
  • Command messages use command routing, checking view, document, frame, and application in order for a handler.
  • Visual resources (menus, toolbars, dialogs, icons) live in a .rc file referenced by IDs defined in resource.h.

Practice what you learned

Was this page helpful?

Topics covered

#MFCMicrosoftFoundationClassesStudyNotes#MicrosoftTechnologies#MFCApplicationArchitecture#MFC#Application#Architecture#CWinApp#StudyNotes#SkillVeris#ExamPrep