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)
I've been programming for 35 years - started in machine language on the National Semiconductor SC/MP chip, moved via the 8080 to the Z80 - graduated through HP Rocky Mountain Basic and HPL - then to C and C++ and now C#.
I used (30 or so years ago when I worked for Hewlett Packard) to repair HP Oscilloscopes and Spectrum Analysers - for a while there I was the one repairing DC to daylight SpecAns in the Asia Pacific area.
Afterward I was the fourth team member added to the Australia Post EPOS project at Unisys Australia. We grew to become an A$400 million project. I wrote a few device drivers for the project under Microsoft OS/2 v 1.3 - did hardware qualification and was part of the rollout team dealing directly with the customer.
Born and bred in Melbourne Australia, now living in Scottsdale Arizona USA, became a US Citizen on September 29th, 2006.
I work for a medical insurance broker, learning how to create ASP.NET websites in VB.Net and C#. It's all good.
Oh, I'm also a Kentucky Colonel.
http://www.kycolonels.org