プログラミングメモ →目次

MFCのSDIベースに複数のビューを持たせる方法(VC++,MFC)

MFCのSDIベースに複数のビューを持たせる方法(VC++,MFC)についてのメモです。

GWL_IDを引数にして、LONG GetWindowLong( int nIndex ); とLONG SetWindowLong( int nIndex, LONG dwNewLong );を呼べば、SDI フレームで複数のビューを切り替えることができます。 なぜ、GWL_IDという引数で、ビューのWindow identifierを入れ替える必要があるというと、SDI フレーム側は、Window ID(AFX_IDW_PANE_FIRST = 0xE900)で、ビューを制御するからです。

1.MultiVwTestというSDIアプリケーションを作成してから、CView2というビューを追加します。

2.CMultiVwTestAppクラスに、下記のメンバーを追加します。

CView* m_pView1;
CView* m_pView2;
CView* SwitchView(CView* pNewView);

3.BOOL CMultiVwTestApp::InitInstance()に、CView2のオブジェクトを作成する為のコードを追加します。

	if (!ProcessShellCommand(cmdInfo))
		return FALSE;

	CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();
	m_pView1 = pActiveView;
	m_pView2 = (CView2*) new CView2;

	CDocument* pCurrentDoc = ((CFrameWnd*) m_pMainWnd)->GetActiveDocument();
	CCreateContext newContext;
	newContext.m_pNewViewClass = NULL;
	newContext.m_pNewDocTemplate = NULL;
	newContext.m_pLastView = NULL;
	newContext.m_pCurrentFrame = NULL;
	newContext.m_pCurrentDoc = pCurrentDoc;

	UINT viewID = AFX_IDW_PANE_FIRST + 1;
	CRect rect(0, 0, 0, 0); // gets resized later
	m_pView2->Create(NULL, _T("View2"), WS_CHILD, rect,
							m_pMainWnd, viewID, &newContext);

	m_pView2->ModifyStyleEx(0, WS_EX_CLIENTEDGE);
	m_pView2->OnInitialUpdate();


	m_pMainWnd->ShowWindow(SW_SHOW);
4.ビューを切り替える関数SwitchView 関数を実装します。
CView* CMultiVwTestApp::SwitchView(CView* pNewView)
{
	CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();

	UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
	::SetWindowLong(pActiveView->m_hWnd, GWL_ID,
	::GetWindowLong(pNewView->m_hWnd, GWL_ID));
	::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);

	pActiveView->ShowWindow(SW_HIDE);
	pNewView->ShowWindow(SW_SHOW);
	((CFrameWnd*) m_pMainWnd)->SetActiveView(pNewView);
	((CFrameWnd*) m_pMainWnd)->RecalcLayout();
	pNewView->Invalidate();
	return pActiveView;
}
5.テスト用のソース