SDI で,MDI の「新しいウィンドウを開く」で 4 つのビューを表示した様な動作が欲しかったので,調べてみた.
動的な分割ウィンドウである程度の所まではできそう.
1. MainFrm.h の CMainFrame に以下を追加.
CSplitterWnd m_wndSplitter;
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
2. CMainFrame::OnCreateClient の追加.
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
{
if (!m_wndSplitter.Create(this,2, 2,CSize(10, 10), pContext,
WS_CHILD | WS_VISIBLE /* | WS_HSCROLL | WS_VSCROLL */ | SPLS_DYNAMIC_SPLIT)) {
TRACE0("Failed to create split bar ");
return FALSE;
}
return TRUE;
}
}
スクロールバーを付加したくなかったので,6 つ目のウィンドウスタイルを変更している.
テスト用に分割動作をコマンドとして実装.
void CMainFrame::OnSplit()
{
if (IsSplit) {
if (m_wndSplitter.GetColumnCount() > 1) { m_wndSplitter.DeleteColumn(1) ; }
if (m_wndSplitter.GetRowCount() > 1) { m_wndSplitter.DeleteRow (1) ; }
IsSplit = !IsSplit ;
}
else {
CRect rect ;
m_wndSplitter.GetClientRect(&rect) ;
if (m_wndSplitter.GetColumnCount() == 1) { m_wndSplitter.SplitColumn(rect.Width ()/2) ; }
if (m_wndSplitter.GetRowCount() == 1) { m_wndSplitter.SplitRow (rect.Height()/2) ; }
IsSplit = !IsSplit ;
}
}
2 x 2 の分割ウィンドウのコントロールの ID (Spy++ で確認)
左上(0,0) E900 AFX_IDW_PANE_FIRST
右上(0,1) E901
左下(1,0) E910
右下(1,1) E911
ビューの OnDraw を以下の様に書き換えると
void CSpltWView::OnDraw(CDC* pDC)
{
int row = -1 ;
int clm = -1 ;
CMainFrame* mw = (CMainFrame*)AfxGetMainWnd() ;
CSplitterWnd* sw = &mw->m_wndSplitter ;
CString str ;
if (sw->IsChildPane(this,&row,&clm)) {
int id = sw->IdFromRowCol(row,clm) ;
CString tmp1 ; tmp1.Format(_T("row = %d , clm = %d"),row,clm) ;
CString tmp2 ; tmp2.Format(_T("IdFromRowCol = %04X"), id) ;
str += tmp1 + _T("\r\n") ;
str += tmp2 + _T("\r\n") ;
}
{
UINT nID = GetDlgCtrlID() ;
CString tmp ; tmp.Format(_T("GetDlgCtrlID = %04X"),nID) ;
str += tmp + _T("\r\n") ;
}
{
CWnd* pw = GetParent() ;
CString tmp1 ; tmp1.Format(_T("Splitter = %08x "),sw->GetSafeHwnd()) ;
CString tmp2 ; tmp2.Format(_T("Parent = %08x "),pw->GetSafeHwnd()) ;
str += tmp1 + _T("\r\n") ;
str += tmp2 + _T("\r\n") ;
}
CRect rect ;
GetClientRect(rect) ;
rect.top = rect.left = 10 ;
pDC->DrawText(str,rect,0) ;
}

MFC の ソースを眺めていると CView::GetParentSplitter があったので,間接的にはそれを使えば良さそう.
ビューでどの位置かを求めるだけなら,
short texNo = 0 ;
{
UINT nID = GetDlgCtrlID() ;
switch (nID) {
case AFX_IDW_PANE_FIRST + 0x00 : texNo = 1 ; break ;
case AFX_IDW_PANE_FIRST + 0x01 : texNo = 2 ; break ;
case AFX_IDW_PANE_FIRST + 0x10 : texNo = 3 ; break ;
case AFX_IDW_PANE_FIRST + 0x11 : texNo = 4 ; break ;
}
}