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
- 25th February, 2004 - Initial version (and probably the last)