Click here to Skip to main content
12,953,349 members (48,362 online)
Click here to Skip to main content
Add your own
alternative version


34 bookmarked
Posted 16 Jul 2002

Command routing beyond a split frame

, 16 Jul 2002 CPOL
Rate this:
Please Sign up or sign in to vote.
Command routing and UI updates for inactive views in a split frame.


The article presents three simple methods of routing WM_COMMAND messages through a number of views in a split frame window. This simplifies dealing with the command routing and UI updates for inactive views.

Introduction to the Problem

The standard framework route does not include inactive views, which causes toolbar buttons and menus to gray when their mother view is deactivated. Users are confused. I present three simple methods to bring their happiness back. :) All solutions base on overriding the CCmdTarget::OnCmdMsg function in the frame class. I assumed that this class is derived directly from CFrameWnd (SDI case), but these methods can be used with MDI child window as well.

In each case, the overridden function browses through a list of views and calls CCmdTarget::OnCmdMsg for each of them, passing the received arguments. If TRUE is returned, we can return – the message has undoubtedly been handled by the view and no further processing is needed. Naturally, the active view is excluded from this call, because it is to be processed by the base handler – this is the default case. You may place a base function call in the beginning of the overridden function body if you expect the messages to be successfully processed mostly by an active view, a frame itself or a CWinApp-derived object, as these three calls are made in the base CFrameWnd::OnCmdMsg implementation. Our custom routine should then be executed only if the base implementation returns FALSE.

Classic Document/View Case

The first quite obvious method is to use a list of views that is available in the CDocument class and accessible through the GetFirstViewPosition / GetNextView helper function pair. Along with the active view, this method browses all inactive ones, but you may filter the list as you wish to suit your application’s needs.

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra,
    CDocument *pDoc = GetActiveDocument();
	POSITION pos = pDoc->GetFirstViewPosition();
	CView *pView = NULL;
	while(pView = pDoc->GetNextView(pos))
	    if(pView != GetActiveView()
		&& pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;

    return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

Splitter Window Case

What if we didn’t like to use any CDocument-derived class object at all? This may be the case, and the first method would then be useless. Yet, to achieve the routing goal, we don’t need a document, as we only have to get access to windows that process the message, i.e. the splitter panes. This is no hassle if you have an explicit splitter object – either as a pointer, or as a member in your frame class, which I find a common case. Simply use CSplitterWnd::GetPane and have it done! This case has also been hinted by Samuel Chow some time ago.

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra,
        AFX_CMDHANDLERINFO* pHandlerInfo) {
        int rc = m_wndSplitter.GetRowCount(),
            cc = m_wndSplitter.GetColumnCount();

        for(int r = 0; r < rc; r++)
            for(int c = 0; c < cc; c++)
                CWnd *pWnd = m_wndSplitter.GetPane(r, c);
                if(pWnd != m_wndSplitter.GetActivePane()
                    && pWnd->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
                    return TRUE;
    return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); }

A Possibly Universal Case

A young eager mind would then like to have a universal handler, independent of existence of member splitters or even a document. Seeking inspiration in MFC sources, namely CView and CSplitterWnd classes, I noticed that they utilize standard pane IDs (see afxres.h) to get access to inactive views in a frame. And surely they use neither a document pointer, nor a splitter object directly! Now here comes the Holy Grail:

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra,
    for(UINT id = AFX_IDW_PANE_FIRST; id <= AFX_IDW_PANE_LAST; id++)
	CWnd *pWnd = GetDescendantWindow(id, TRUE);
	if(pWnd && pWnd != GetActiveView()
	    && pWnd->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
	    return TRUE;
    return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

As with the first method, the handler doesn’t have to be called for all views, as the calls may be freely filtered. It may be even done dynamically, e.g. depending on nID or nCode values, but I’m afraid this would complicate the routing a bit too much. Such roundabout solutions should always be thought over twice – there are many straightforward methods of distributing the message handling among the existing command targets, and this is not the case.

There is no possibility that these snippets would solve all your trouble with MFC command message routing, but it may get you closer or simply bring you a little clue. Any comments and suggestions are warmly welcome.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Bartosz Bien
CEO SPIN Software
Poland Poland
I am a software designer and developer. I build bridges!

I build bridges between reality and imagination (design and creation of video games, video game production tools):
• experience managing a technological team for almost 10 years (around 30 projects),
• co-created multiple video games for demanding hardware platforms,
• implemented game-like interaction and awarding systems in non-game applications to make them

I build bridges between theory and visualization (design and creation of decision support systems):
• created an innovative tool for interconnecting various techniques of artificial intelligence,
• created multiple expert systems that were used for proving PhD theses, and then implemented in
the industry.

I build bridges between companies and people (design and creation of scientific, industrial and
business software):
• created multiple software packages in the field of civionics, including bridge management systems
and real-time measurement / data processing software,
• created and developed 7 large applications for business / state customers,
• created and sold first own C++ application back in 1996; after some upgrades it still serves its
commercial purpose for the client.

Projects with value up to $14M, ranging from complex industrial, business and scientific applications using highly customized MFC and proprietary user interaction systems, through AAA video games and creation tools, up to WinRT applications created for the launch event of Microsoft Windows 8.


Primary Technologies (everyday usage):
C++ (expert level), C++11, MFC, proprietary systems

Also: .NET (C#, C++/CX), WPF, Silverlight, DirectX (+ Direct2D), OpenGL, HTML5/JS, PHP, SQL, XML, Python, Visual Studio Tools for Office, Perforce, SVN, ...anything that gets me closer to the goal!

Primary Platforms: Win32/Win64, WinRT (Windows 8), Xbox360, Playstation 3, Xbox One, Playstation 4, Windows Phone 8, Nintendo 3DS (also: GBA, Digiblast, PocketPC/ARM)

You may also be interested in...

Comments and Discussions

QuestionCompiling error Pin
Michael Klim1-Mar-09 14:57
memberMichael Klim1-Mar-09 14:57 
AnswerRe: Compiling error Pin
Bartosz Bien1-Mar-09 21:00
memberBartosz Bien1-Mar-09 21:00 
AnswerRe: Compiling error Pin
Bartosz Bien2-Mar-09 9:30
memberBartosz Bien2-Mar-09 9:30 
GeneralRe: Compiling error Pin
Michael Klim2-Mar-09 12:59
memberMichael Klim2-Mar-09 12:59 
GeneralCommand routing Pin
sdancer7510-Jul-07 0:05
membersdancer7510-Jul-07 0:05 
GeneralPerfect! Pin
John Simmons / outlaw programmer30-Nov-06 10:20
memberJohn Simmons / outlaw programmer30-Nov-06 10:20 
GeneralRe: Perfect! Pin
Bartosz Bien30-Nov-06 10:43
memberBartosz Bien30-Nov-06 10:43 
GeneralThankyou. Exactly what I wanted :) Pin
Gautam Jain28-Jul-06 4:03
memberGautam Jain28-Jul-06 4:03 
GeneralMFC Print preview Pin
gowharjan26-Apr-05 21:11
membergowharjan26-Apr-05 21:11 
GeneralWell done... thanks Pin
hw7704115-Feb-05 15:46
memberhw7704115-Feb-05 15:46 
QuestionTypo? Pin
Michael Hendrickx21-Oct-04 13:48
memberMichael Hendrickx21-Oct-04 13:48 
AnswerRe: Typo? Pin
Bartosz Bien23-Oct-04 23:19
memberBartosz Bien23-Oct-04 23:19 
Generalbrilliant Pin
Domagoj23-Jun-04 11:19
memberDomagoj23-Jun-04 11:19 
GeneralAnother thanks! Pin
Carl Smigielski18-Sep-02 18:41
memberCarl Smigielski18-Sep-02 18:41 
GeneralThanks Pin
John Gilbert27-Aug-02 8:58
memberJohn Gilbert27-Aug-02 8:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170525.1 | Last Updated 17 Jul 2002
Article Copyright 2002 by Bartosz Bien
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid