For my latest project we needed splitter panes that had proper
minimum sizes, in that the user couldn’t physically resize the
splitter pane smaller than a specified amount. The standard MFC
splitter class allows you to set minimum sizes, but these only
affect what is displayed, not how small the panes can be.
CMinSplitterWnd is a drop-in replacement for (and is derived
from) CSplitterWnd.
Instructions:
- Add MinSplitterWnd.cpp and MinSplitterWnd.h
to your current project (e.g. Menu Project->Add to
project->Add files). - Where you currently use CSplitterWnd, replace
with CMinSplitterWnd (Note: remember to include MinSplitterWnd.h): - Call SetRowInfo and SetColumnInfo as
necessary, specifying the required minimum row and column
sizes: (this is normally done in the parent window’s OnCreateClient function) - In the splitter’s parent window, add a message handler
for OnWindowPosChanging (this prevents the user
from sizing the window too small) and add the following
code to it: - That’s it!
#include "MinSplitterWnd.h" // Minimum size splitter. .... class CMyWnd : public CMDIChildWnd { .... CMinSplitterWnd m_wndSplitter; .... };
.... m_wndSplitter.CreateStatic( this, 2, 2 ); // Create with 2 rows and 2 columns. m_wndSplitter.SetRowInfo( 0, 100, 100 ); // Set ideal and minimum size to 100. m_wndSplitter.SetRowInfo( 1, 100, 100 ); // Set ideal and minimum size to 100. m_wndSplitter.SetColumnInfo( 0, 100, 100 ); // Set ideal and minimum size to 100. m_wndSplitter.SetColumnInfo( 1, 100, 100 ); // Set ideal and minimum size to 100. ....
void CMyWnd::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) { // Don't do anything if minimized. if ( IsIconic() ) { CMDIChildWnd::OnWindowPosChanging( lpwndpos ); return; } // if // Calculate the window rect if we have no client area. CRect rc( 0, 0, 0, 0 ); CalcWindowRect( rc ); // Add on the minimum client width and height from the splitter. int nMinWidth = rc.Width() + m_wndSplitter.GetMinClientWidth(); int nMinHeight = rc.Height() + m_wndSplitter.GetMinClientHeight(); // Get the current window size. CRect rcWindow; GetWindowRect( rcWindow ); GetParent()->ScreenToClient( rcWindow ); // If trying to size too small... if ( lpwndpos->cx < nMinWidth ) { // If dragging left border right... if ( rcWindow.left < lpwndpos->x ) { // How much over are we? int nOver = nMinWidth - lpwndpos->cx; // Adjust left coord. lpwndpos->x -= nOver; } // if // Fix width. lpwndpos->cx = nMinWidth; } // if // If trying to size too small... if ( lpwndpos->cy < nMinHeight ) { // If dragging top border down... if ( rcWindow.top < lpwndpos->y ) { // How much over are we? int nOver = nMinHeight - lpwndpos->cy; // Adjust left coord. lpwndpos->y -= nOver; } // if // Fix height. lpwndpos->cy = nMinHeight; } // if }
Limitation:
If the minimum sizes exceed the initial frame window size, the window will
snap when the window is first resized.
Download demo project and executable – 36 KB