Introduction
I suspect this may be the most trivial class ever presented on CodeProject.
In an MFC application I'm writing I wanted an explorer style interface with a tree control on the left and a view class on the right. But I wanted
to prevent the user being able to grab the divider and resize the views.
The application was created using the AppWizard, selecting MFC, Explorer style and a splitter. The resulting project contains the standard classes
one would expect, CMainFrame, a CDocument derivative, a CLeftView derived from CTreeView and another
view class for the right hand side of the application.
The two views are managed by an instance of CSplitterWnd embedded in the CMainFrame object. All of this is MFC 101 material.
Given that I wanted to prevent resizing of the views via the splitter it made sense to look at the MSDN documentation for CSplitterWnd. There
are a bunch of functions in that class but not one to let you disable mouse operations on the splitter. Hmmm... A quick check on CodeProject under the
Splitter Windows[^]
topic offered nothing obvious. And then the penny dropped. A CSplitterWnd is a CWnd with some extra functionality.
Since CSplitterWnd is derived from CWnd it's easy to intercept Windows messages. In this case the windows message I was interested
in is WM_NCHITTEST which is Windows way of asking a window, is the mouse over something special? In the case of a splitter window, the answer is
yes if the mouse is over the splitter. If we change that answer to no the extra logic in CSplitterWnd won't kick in.
The CSplitOverride class
Here's the declaration. It's an extremely simple class containing only a constructor, a message map and a single message map entry.
class CSplitOverride : public CSplitterWnd
{
DECLARE_DYNAMIC(CSplitOverride)
public:
CSplitOverride() { }
protected:
DECLARE_MESSAGE_MAP()
afx_msg UINT OnNcHitTest(CPoint point);
}
And here's the implementation.
IMPLEMENT_DYNAMIC(CSplitOverride, CSplitterWnd)
BEGIN_MESSAGE_MAP(CSplitOverride, CSplitterWnd)
ON_WM_NCHITTEST()
END_MESSAGE_MAP()
afx_msg UINT CSplitOverride::OnNcHitTest(CPoint )
{
return HTNOWHERE;
}
Hey, I did say it was a trivial class! The override for the
WM_NCHITTEST message handler simply returns
HTNOWHERE which tells
Windows there's nothing special about the location of the mouse pointer.
Using the code
To use the class add the two files in the download to your project and then, in the header for your
CMainFrame class change the
CSplitterWnd
variable type to
CSplitOverride. Bingo! Your app will now ignore mouse operations on the splitter window. Don't forget to disable any menu or keyboard
access to splitter resizing.
History
February 25, 2004 - Initial version (and probably the last).