Figure 2 CSysCmdRouter
////////////////////////////////////////////////////////////////
// MSDN Magazine May 2005
// If this program works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
//
#include "Subclass.h"

//////////////////
// Class to route user-defined WM_SYSCOMMAND messages through the normal 
// MFC command routing system, so you can handle them the normal MFC way 
// with ON_COMMAND and ON_UPDATE_COMMAND_UI handlers. The simplest way to 
// achieve this is to translate the system commands to ordinary WM_COMMAND 
// messages.
//
// To use: instantiate in your CMainFrame and call Init from OnCreate.
//
// You must also link Subclass.cpp in your app.
//
class CSysCmdRouter : public CSubclassWnd {
protected:
    CWnd* m_pMainWnd;    // main window hooked
public:
    CSysCmdRouter() { }
    virtual ~CSysCmdRouter() { }

    // Initialize: hook the main window
    BOOL Init(CWnd* pMainWnd) {
        ASSERT(pMainWnd);
        m_pMainWnd = pMainWnd;
        return HookWindow(pMainWnd);
    }

    // Terminate: unhook. No need to call unless you want to stop hooking 
    // for some reason; CSubclassWnd will automatically unhook itself when 
    // the hooked window is destroyed.
    void Term() {
        Unhook();
    }

protected:

    // virtual WndProc handler: convert WM_SYSCOMMAND to WM_COMMAND if the 
    // command is not a system command: That is, if the command ID is less 
    // than SC_SIZE = 0xFFFF.
    //
    virtual LRESULT WindowProc(UINT msg, WPARAM wp, LPARAM lp)
    {
        if (msg==WM_SYSCOMMAND && wp<SC_SIZE) {
            return m_pMainWnd->SendMessage(WM_COMMAND, wp, NULL);
        } else if (msg==WM_INITMENUPOPUP) {
          // Hide system menu flag (= HIWORD(lp)) so even system menu can 
          // be initialized through MFC. This is somewhat dangerous 
          // because you lose the ability to distinguish between the 
          // system menu and other menus—but if you're adding your own 
          // commands it shouldn't matter which menu(s) they come from! 
          // Just make sure your command IDs don't conflict with the 
          // built-in commands like SC_SIZE,and so on, which start at
          // 0xF000. By default, MFC command IDs start at 0x8000 so you'll 
          // be safe if you follow MFC.
            lp = LOWORD(lp);
        }
        return CSubclassWnd::WindowProc(msg, wp, lp); // pass along
                                                      //-important!
    }
};

Figure 4 MinFrm.cpp
// MSDN Magazine May 2005  
// If this program works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
//
#include "StdAfx.h"
#include "TbMenu.h"
#include "MainFrm.h"
...
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_WM_CREATE()
    ON_COMMAND(ID_CHECKME, OnCheckMe)
    ON_UPDATE_COMMAND_UI(ID_CHECKME, OnUpdateCheckMe)
END_MESSAGE_MAP()

CMainFrame::CMainFrame() : m_bChecked(0)
{
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    ... // normal MFC stuff: call base class OnCreate,
    ... // create toolbar and status bar (not shown here)

    // Append my own items to the system menu
    CMenu* pMenu = GetSystemMenu(FALSE);
    ASSERT(pMenu!=NULL);
    pMenu->AppendMenu(MF_BYPOSITION|MF_SEPARATOR);
    pMenu->AppendMenu(MF_STRING,(UINT_PTR)ID_CHECKME, _T("Chec&k Me"));
    pMenu->AppendMenu(MF_STRING,(UINT_PTR)ID_APP_ABOUT, 
        _T("&About TBMenu"));

    // Hook system commands so they're routed through MFC 
    // command routing to ON_COMMAND handlers.
    m_sysCmdHook.Init(this);

    return 0;
}

//////////////////
// Handle "Check Me" command
//
void CMainFrame::OnCheckMe()
{
    m_bChecked = !m_bChecked;
    MessageBox(m_bChecked ? _T("Checked") : _T("Unchecked"), _T("TBMenu"));
}

//////////////////
// Set checkmark next to "Check Me" command (or not)
//
void CMainFrame::OnUpdateCheckMe(CCmdUI* pCmdUI)
{
    pCmdUI->SetCheck(m_bChecked);
}