I would not resort to your "dirty workaround." You have the previous row and column sizes so I would calculate new sizes and compare them with the old ones and only recalculate the layout if either of them change. If neither change then you don't have to do anything with the splitters.
-ETA:
I messed around with this a bit and got something to work. The key things are don't call the base class' OnSize method initially. Also, you have to take the width of the splitter into account. Here's what I ended up with for a single vertical splitter. This can be easily extended to more splitters.
void CMainFrame::OnSize( UINT type, int cx, int cy )
{
static int splitwidth = 0;
static bool first = true;
int temp;
if( m_InitSplitter && first )
{
first = false;
RECT cr;
GetClientRect( & cr );
int width = cr.right - cr.left;
int svx1, svx2;
m_SplitterV.GetColumnInfo( 0, svx1, temp );
m_SplitterV.GetColumnInfo( 1, svx2, temp );
int colw = svx1 + svx2;
splitwidth = width - colw;
}
if( m_InitSplitter && ( type != SIZE_MINIMIZED ) )
{
int svx1, svx2;
m_SplitterV.GetColumnInfo( 0, svx1, temp );
m_SplitterV.GetColumnInfo( 1, svx2, temp );
int colw = svx1 + svx2 + splitwidth;
double colScale = (double) svx1 / (double)( colw );
int cx1 = (int)( cx * colScale + 0.5 );
m_SplitterV.SetColumnInfo( 0, cx1, 0 );
m_SplitterV.RecalcLayout();
}
__super::OnSize( type, cx, cy );
}
The m_InitSplitter member is initially false and set true after all the splitters and their views have been created. This test program made a vertical splitter and a horizontal splitter. This logic changed only the vertical splitter when the window was resized horizontally.