2017-10-31 41 views
1

MFC SDI C++プロジェクトでCFormViewsを切り替える際に助けが必要です。私は長い間掘り下げていて、なぜ自分のコードが機能していないのか理解できません。インターネット(とこのサイトが含まれています)を検索して、MainFrm.cpp(CMainFrameオブジェクト、CFrameWndから継承したオブジェクト)に2つの関数を追加してフォームを切り替えるためのチュートリアルをいくつか紹介しました。それらのうちの1つは、私が切り替えたいフォームのidを渡され、アクティブなビューへのポインタを取得し、そこから他のコードを実行します。ただし、GetActiveView()は常にNULLのポインタ値を返します。私はアクティブなフォームからボタンをクリックしているので、アクティブなビューがあることを知っています。私のコードは以下の通りです。これはちょうど私が参照している関数です。 MainFrm.cpp(新しいMFCプロジェクトを開始するときに作成される既定のウィンドウファイル)にあります。MFC SDI GetActiveView()は常にNULLを返します

これまでのところ、私はどこからでも現在のCDocumentCViewを取得する方法についての協議は、私はその後、CFrameWndからGetActiveViewと呼ばれ、最初のアクティブなフレームを取得しようとしました、と私は、コードを試したことのMicrosoft Knowledge Baseからのコードを試してみました以下。すべて無駄に。私は明らかに何かを理解するためにMFCについて十分に知りません。私からのより多くの情報が必要な場合は、お尋ねください。私はおそらく私が持っているべきすべてを言及しなかった。私は学校プロジェクトのためにMFCを選択しましたが、UMLを作成したり、他のコードを書くことはできません。

void CMainFrame::SelectView(UINT ViewID) 
{ 
    // If the view the user selected is already displaying, do nothing 
    if (ViewID == m_CurrentView) 
     return; 

    // Get a pointer to the current view 
    CView* pCurrentView = GetActiveView(); 

    // We are about to change the view, so we need a pointer to the runtime class 
    CRuntimeClass* pNewView = NULL; // Added = NULL because it wouldn't allow program to be run without initialization of pNewView 

    // We will process a form 
    // First, let's change the identifier of the current view to our integer 
    ::SetWindowLong(pCurrentView->m_hWnd, GWL_ID, m_CurrentView); 

    // Now we will identify what form the user selected 
    switch (ViewID) 
    { 
    case IDD_CHOOSE_ITEM: 
     pNewView = RUNTIME_CLASS(CChooseItemView); 
     break; 

    case IDD_ITEM_INFORMATION: 
     pNewView = RUNTIME_CLASS(CItemInformationView); 
     break; 
    } 

    // We will deal with the frame 
    CCreateContext crtContext; 

    // We have a new view now. So we initialize the context 
    crtContext.m_pNewViewClass = pNewView; 
    // No need to change the document. We keep the current document 
    crtContext.m_pCurrentDoc = GetActiveDocument(); 

    CView* pNewViewer = STATIC_DOWNCAST(CView, CreateView(&crtContext)); 

    // Now we can create a new view and get rid of the previous one 
    if (pNewViewer != NULL) 
    { 
     pNewViewer->ShowWindow(SW_SHOW); 
     pNewViewer->OnInitialUpdate(); 
     SetActiveView(pNewViewer); 
     RecalcLayout(); 
     m_CurrentView = ViewID; 
     pCurrentView->DestroyWindow(); 
    } 
} 
+0

を追加します。どのようにさまざまなオブジェクトへのポインタを取得しますか?[リンク](http://forums.codeguru.com/showthread.php?281430-MFC-Doc-View-How-to-obtain-a-pointer-to-various-objects)非常に良い概観、この表からの1つは助けるべきです..! –

+0

NULLを返すと、他のペイン、スプリッタなどがアクティブになることがあります。しかし、既存のCDocumentから関連付けられたCViewを取得することはできます。 –

+0

ありがとうございますが、私はすでにあなたが与えたリンクを試しました。私はCMainFrameからCView(上のコードの一部)を取得しようとしました。他のペインとスプリッターはどのようにアクティブになりますか?私は1つのウィンドウと1つのフォーム(ウィザードが設定するデフォルトフォームが何であれ)を開くだけのデフォルトのSDIコードを使用しています。 MainFrameからCViewにアクセスする必要がある場合、CDocumentファイルからどのようにビューを取得できますか?私はCDocumentオブジェクトを作成し、その中から関数を呼び出しますか?ご協力いただきありがとうございます! –

答えて

0

CDocumentのから非アクティブなビューが、関連のCViewを取得するには、あなたはドク

// ----- GetCChooseItemView() -- -Search the first associated CView in INACTIVE Views too ! ------ 
CView* CMyDoc::GetCChooseItemView(void) 
{ 
    CRuntimeClass* prt = RUNTIME_CLASS(CChooseItemView); 
    CView* pView = NULL; 

    // Continue search in inactive View by T(o)m 

    POSITION pos = GetFirstViewPosition(); 
    while (pos != NULL) 
    { 
    pView = GetNextView(pos); 
    if (pView->GetRuntimeClass() == prt) 
    { 
     if (pView->IsKindOf(RUNTIME_CLASS(CChooseItemView))) 
      break; 
    } 
    pView = NULL;  // not valid vie 
    } 

    return static_cast<CChooseItemView*>(pView); 
} 

でこのスキーマを実装することができ、その後MFCドキュメント/ビューあなたSelectViewコードで

void CMainFrame::SelectView(UINT ViewID) 
{ 
    : (code as before) 
    :  
    // Get a pointer to the current view 
    CView* pCurrentView = GetActiveView(); 

    // Get a pointer to the current view 
    CView* pCurrentView = GetActiveView(); 
    if (pCurrentView == NULL 
    { 
    CMyDoc* pDoc = static_cast<CMyDoc*>(GetActiveDocument()); 
    if (pDoc) 
    { 
     pCurrentView = pDoc->GetChhoseItemView(); 
     if (pCurrentView == NULL) 
     mpCurrentView = pDoc->GetCItemInformationView() // let as exercise for the OP 

     if (pCurrentView == NULL 
     { 
      DebugBreak();  // Errror No View found.. 
     } 
    } 

    : (code as befeore) 
    : 
} 
+0

上記のコードをSelectViewコードに追加したとします。上のコードは、新しい関数(SwitchToView)のように見えます。よくわかりません。 MainFrm.cppにオリジナルのSelectViewコードがあり、ドキュメントファイルにSwitchToView関数を追加する必要がありますか? –

+0

私の設定を少し上手く説明します。私のプロジェクトの名前はProject2なので、もともとmfc sdiプログラムをセットアップしたとき、Project2.h/cpp、Project2Doc.h/cpp、およびProject2View.h/cppでセットアップしました。 MainFrm.h/cppもあります。 Project2View.h/cppに添付されているデフォルトのダイアログ(CFormViewから派生しています)で、いくつかのボタンを追加しました。私はCRecordViewから派生したいくつかのダイアログを追加しました。それぞれに.h/cppファイルが関連付けられています。デフォルトのダイアログ(アプリケーションの実行時にロードするもの)のボタンをクリックすると、新しいCMainFrameを作成するコードがあります。 –

+0

...オブジェクトに変更したいビューのIDを渡します。変更したいビューのidをMainFrmコンストラクタに渡します。このコンストラクタは、idをSelectView関数に渡します。たぶんこれは私が間違ってやっている部分です。既定のダイアログビュー(Project2View.cpp)でボタンを押したときに、どのようなコードを使用する必要がありますか?私はかなりスマートな女性ですが、これは私に困っています。私は明らかに何かが欠けている。 –

0

次のコードは、私のために働いている:

virtual CView* SwitchToView(CView* pNewView);

とcppの中:

CView* CMyDoc::SwitchToView(CView* pNewView) 
 
{ 
 
\t CMDIFrameWndEx* pMainWnd = (CMDIFrameWndEx*)AfxGetMainWnd(); 
 
\t // Get the active MDI child window 
 
\t CMDIChildWndEx* pChild = (CMDIChildWndEx*)pMainWnd->MDIGetActive(); 
 
\t // Get the active view attached to the active MDI child window. 
 
\t CView* pOldActiveView = pChild->GetActiveView(); 
 
\t // Exchange control ID of old view 
 
\t // note: if you have more than two view you have to remember which view you switched to 
 
\t // so you can set it's old control ID correctly 
 
\t if(pNewView == m_pMyView) 
 
\t \t pOldActiveView->SetDlgCtrlID(CTRLID_MYVIEW2); 
 
\t if(pNewView == m_pMyView2) 
 
\t \t pOldActiveView->SetDlgCtrlID(CTRLID_MYVIEW); 
 
\t // Exchange control ID of new new 
 
\t // note: the control ID of the active view must always be AFX_IDW_PANE_FIRST 
 
\t pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST); 
 
\t // Set flag so that document will not be deleted when view is dettached. 
 
\t BOOL bAutoDelete = m_bAutoDelete; 
 
\t m_bAutoDelete = FALSE; 
 
\t // Dettach existing view 
 
\t RemoveView(pOldActiveView); 
 
\t // restore flag 
 
\t m_bAutoDelete = bAutoDelete; 
 
\t // Show the newly active view and hide the inactive view. 
 
\t pNewView->ShowWindow(SW_SHOW); 
 
\t pOldActiveView->ShowWindow(SW_HIDE); 
 
\t // Attach new view 
 
\t AddView(pNewView); 
 
\t pChild->RecalcLayout(); 
 
\t pNewView->UpdateWindow(); 
 
\t pChild->SetActiveView(pNewView); 
 

 
\t return pOldActiveView; 
 
}

私はそれがあなたを助けてくれることを願っています。

+1

これはMDIインターフェイスのコードです。 OPにはSDIアプリケーションに問題があります。 –

関連する問題