////////////////////////////////////////////////////////////////
// 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!
}
};
// 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);
}