Microsoft Foundation Class (MFC) ライブラリで作成された単一ドキュメント インターフェイス (SDI) アプリケーションでは、各ドキュメントの種類は 1 つのビューの種類に関連付けられます。 場合によっては、ドキュメントの現在のビューを新しいビューで切り替える機能が必要な場合があります。
ヒント
1 つのドキュメントに対して複数のビューを実装する手順については、 CDocument::AddView と COLLECT MFC サンプルを参照してください。
この機能を実装するには、新しい CView
派生クラスと、ビューを既存の MFC アプリケーションに動的に切り替えるためのコードを追加します。
手順は次のとおりです。
このトピックの残りの部分では、次のことを前提としています。
CWinApp
派生オブジェクトの名前はCMyWinApp
であり、CMyWinApp
は MYWINAPP.H および MYWINAPP.CPP で宣言および定義されます。CNewView
は新しいCView
派生オブジェクトの名前であり、CNewView
は NEWVIEW で宣言および定義されます 。H と NEWVIEW。CPP。
既存のアプリケーション クラスを変更する
アプリケーションでビューを切り替えるには、ビューを格納するメンバー変数と、それらを切り替えるメソッドを追加して、アプリケーション クラスを変更する必要があります。
MYWINAPP の CMyWinApp
の宣言に次のコードを追加します 。H:
CView *m_pOldView;
CView *m_pNewView;
CView *SwitchView();
新しいメンバー変数 ( m_pOldView
と m_pNewView
) は、現在のビューと新しく作成されたビューをポイントします。 新しいメソッド (SwitchView
) は、ユーザーが要求したときにビューを切り替えます。 メソッドの本体については、このトピックの「 切り替え関数の実装」で後述します。
アプリケーション クラスの最後の変更には、切り替え関数で使用される Windows メッセージ (WM_INITIALUPDATE) を定義する新しいヘッダー ファイルを含める必要があります。
MYWINAPP.CPP のインクルードセクションに次の行を挿入します。
#include <AFXPRIV.H>
変更を保存し、次の手順に進みます。
新しいビュー クラスを作成および変更する
新しいビュー クラスの作成は、クラス ビューから使用できる [新しいクラス ] コマンドを使用して簡単に作成できます。 このクラスの唯一の要件は、 CView
から派生することです。 この新しいクラスをアプリケーションに追加します。 プロジェクトに新しいクラスを追加する方法の詳細については、「 クラスの追加」を参照してください。
プロジェクトにクラスを追加したら、一部のビュー クラス メンバーのアクセシビリティを変更する必要があります。
NEWVIEW.H を修正し、コンストラクターとデストラクターのアクセス指定子を protected
から public
に変更します。 これにより、クラスを動的に作成および破棄したり、表示する前にビューの外観を変更したりすることができます。
変更を保存し、次の手順に進みます。
新しいビューを作成してアタッチする
新しいビューを作成してアタッチするには、アプリケーション クラスの InitInstance
関数を変更する必要があります。 この変更により、新しいビュー オブジェクトを作成し、既存の 2 つのビュー オブジェクトを使用して m_pOldView
と m_pNewView
の両方を初期化する新しいコードが追加されます。
InitInstance
関数内に新しいビューが作成されるため、新しいビューと既存のビューの両方がアプリケーションの有効期間中保持されます。 ただし、アプリケーションは新しいビューを動的に簡単に作成できます。
ProcessShellCommand
の呼び出しの後に次のコードを挿入します。
CView *pActiveView = ((CFrameWnd *)m_pMainWnd)->GetActiveView();
m_pOldView = pActiveView;
m_pNewView = (CView *)new CNewView;
if (NULL == m_pNewView)
return FALSE;
CDocument *pCurrentDoc = ((CFrameWnd *)m_pMainWnd)->GetActiveDocument();
// Initialize a CCreateContext to point to the active document.
// With this context, the new view is added to the document
// when the view is created in CView::OnCreate().
CCreateContext newContext;
newContext.m_pNewViewClass = NULL;
newContext.m_pNewDocTemplate = NULL;
newContext.m_pLastView = NULL;
newContext.m_pCurrentFrame = NULL;
newContext.m_pCurrentDoc = pCurrentDoc;
// The ID of the initial active view is AFX_IDW_PANE_FIRST.
// Incrementing this value by one for additional views works
// in the standard document/view case but the technique cannot
// be extended for the CSplitterWnd case.
UINT viewID = AFX_IDW_PANE_FIRST + 1;
CRect rect(0, 0, 0, 0); // Gets resized later.
// Create the new view. In this example, the view persists for
// the life of the application. The application automatically
// deletes the view when the application is closed.
m_pNewView->Create(NULL, _T("AnyWindowName"), WS_CHILD, rect, m_pMainWnd, viewID, &newContext);
// When a document template creates a view, the WM_INITIALUPDATE
// message is sent automatically. However, this code must
// explicitly send the message, as follows.
m_pNewView->SendMessage(WM_INITIALUPDATE, 0, 0);
変更を保存し、次の手順に進みます。
切り替え関数を実装する
前の手順では、新しいビュー オブジェクトを作成して初期化するコードを追加しました。 最後の主要な部分は、 SwitchView
切り替え方法を実装する方法です。
アプリケーション クラスの実装ファイルの末尾 (MYWINAPP。CPP)、次のメソッド定義を追加します。
CView *CMyWinApp::SwitchView()
{
CView *pActiveView = ((CFrameWnd *)m_pMainWnd)->GetActiveView();
CView *pNewView = NULL;
if (pActiveView == m_pOldView)
pNewView = m_pNewView;
else
pNewView = m_pOldView;
// Exchange view window IDs so RecalcLayout() works.
#ifndef _WIN32
UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
::SetWindowWord(pActiveView->m_hWnd, GWW_ID, ::GetWindowWord(pNewView->m_hWnd, GWW_ID));
::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
#else
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);
#endif
pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
((CFrameWnd *)m_pMainWnd)->SetActiveView(pNewView);
((CFrameWnd *)m_pMainWnd)->RecalcLayout();
pNewView->Invalidate();
return pActiveView;
}
変更を保存し、次の手順に進みます。
ビューの切り替えのサポートを追加する
最後の手順では、アプリケーションがビューを切り替える必要があるときに SwitchView
メソッドを呼び出すコードを追加します。 これはいくつかの方法で行うことができます。ユーザーが選択できるように新しいメニュー項目を追加するか、特定の条件が満たされたときにビューを内部的に切り替えます。
新しいメニュー項目とコマンド ハンドラー関数の追加の詳細については、「コマンド とコントロール通知のハンドラー」を参照してください。