MFCフレーム下でのポインタの獲得(転写と個人まとめ)

9518 ワード

VCのプログラミングは学習を始めたばかりの学生にとって、最大の障害と問題はメッセージメカニズムとポインタの取得と操作である.実はこれらの内容は基本的にVC学習ツールの本ごとに必ず言う内容で、MSDNを通じて多くの問題を解決することができます.
以下の文字は主に個人がプログラミングの中でポインタを使ういくつかの体得で、言うのが適切でないところを指摘してください.
一般に我々が使用するフレームワークは,VCが提供するWizardによって生成されたMFC App Wizard(exe)フレームワークであり,マルチドキュメントでも単一ドキュメントでもポインタ取得と操作の問題がある.
次のセクションでは、主に一般的なフレームワークについて説明し、マルチスレッドのポインタの使用について説明します.使用するクラスには、応答を含むヘッダファイルが必要です.まず、このクラス(ドキュメント、ダイアログボックスでサポートされている)のインスタンスポインタthisを一般的に取得します.thisの目的では、主にクラス内の関数を通じて他のクラスまたは関数にポインタを送ることで、非クラスでの機能の操作と使用を容易にすることができます.
1)ViewでDocポインタを取得する

   
   
   
   
CYouSDIDoc  * pDoc = GetDocument();

)AppでMainFrameポインタを取得
CWinAppのm_pMainWnd変数はMainFrameのポインタです
次のこともできます.

   
   
   
   
CMainFrame  * pMain  = (CMainFrame  * )AfxGetMainWnd();

)ビューでMainFrameポインタを取得する

   
   
   
   
CMainFrame  * pMain = (CmaimFrame  * )AfxGetApp() -> m_pMainWnd;

)ビュー(確立済み)ポインタを取得
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;
CyouView *pView=(CyouView *)pMain->GetActiveView();
)現在のドキュメントポインタを取得
CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd->GetActiveDocument();
)ステータスバーとツールバーポインタを取得
CStatusBar * pStatusBar=(CStatusBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
CToolBar * pToolBar=(CtoolBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);
)フレームにツールバーとステータスバー変数を追加する場合は、
(CMainFrame *)GetParent()->m_wndToolBar;
(CMainFrame *)GetParent()->m_wndStatusBar;
)Mainframeでメニューポインタを取得
CMenu *pMenu=m_pMainWnd->GetMenu();
)どのクラスでもアプリケーションクラスを取得
MFCグローバル関数AfxGetApp()で取得します.
10)文書類からビュー類のポインタを取得する
わたしはhttp://download.cqcnc.com/soft/program/article/vc/vc405.html学んだことは、ドキュメントからビュークラスポインタを取得する目的は、一般的に同じドキュメントの複数のビューの位置決め問題を制御するためであり、特に文字処理CEditViewは、複数のビュークラスを生成する際に、この機能が非常に必要であることを理解しています.
CDocumentクラスには、ビュークラスの配置に使用する2つの関数があります.
GetFirstView()とGetNextView()
virtual POSITION GetFirstViewPosition() const;
virtual CView* GetNextView(POSITION& rPosition) const;

注意:GetNextView()カッコのパラメータは参照形式で使用されるため、実行後に値が変更される可能性があります.
GetFirstView()は、最初のビュー位置(ビュークラスポインタではなくPOSITIONタイプの値を返す)を返すために使用され、GetNextView()には、次のビュークラスに戻るポインタと、受信したPOSITIONタイプのパラメータの値を参照呼び出しで変更する2つの機能があります.明らかに、Testプログラムでは1つのビュークラスしかないので、この2つの関数を1回呼び出すだけでCTestViewのポインタは次のようになります(POSITION構造変数を定義して操作を支援する必要があります):
CTestView* pTestView;
POSITION pos=GetFirstViewPosition();
pTestView=GetNextView(pos);
は、CTestViewクラスのポインタpTestViewに到達する.いくつかの文を実行する後、変数pos=NULLは、次のビュークラスがないため、当然次のビュークラスのPOSITIONもない.しかし、これらの文は簡単すぎて、汎用性とセキュリティの特徴があまり強くありません.前述したように、複数のビューペアで指定したクラスのポインタを返す場合は、指定したクラスが見つかるまですべてのビュークラスを巡回する必要があります.クラスポインタがクラスのインスタンスを指しているかどうかを判断する場合、IsKindOf()メンバー関数を使用して、次のようにチェックします.
pView->IsKindOf(RUNTIME_CLASS(CTestView));
pViewがCTestViewクラスを指すかどうかを確認できます.
以上の基礎があれば、ドキュメントクラスから任意のクラスのポインタを取得することができます.便宜上、ドキュメントクラスのメンバー関数として、どのクラスのポインタを取得するかを示すパラメータがあります.次のようになります.

   
   
   
   
CView *  CTestDoc::GetView(CRuntimeClass *  pClass)
{
    CView
*  pView;
    POSITION pos
= GetFirstViewPosition();

    
while (pos != NULL){
        pView
= GetNextView(pos);
        
if ( ! pView -> IsKindOf(pClass))
        
break ;
    }

    
if ( ! pView -> IsKindOf(pClass)){
        AfxMessageBox(
" Connt Locate the View.\r
 http://www.VCKBASE.com
" );
        
return  NULL;
    }

    
return  pView;
}



ビュークラスのメンバー関数IsKindOf()を2回使用して判断したのは、whileループを終了するには3つの可能性があるからです.
1.posはNULLであり、操作のために次のビュークラスが存在しない.
2.pViewはすでに要求を満たしている.
1と2は同じ満足です.これはGetNextView()の機能は、現在のビューポインタを1つのビューの位置に変更しながら現在のビューポインタを返すことであるため、posはpViewの次のビュークラスのPOSITIONであり、pos=NULLでありpViewである可能性が十分にあるからである.必要なビューが最後のビューが最後のビュークラスである場合は、引用のようになります.そのため、2回の判断が必要です.
この関数を使用するには、次の形式に従う必要があります(CTestViewポインタの取得を例に挙げます).
CTestView* pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView));
RUNTIME_CLASSは、クラスの名前をポインタに変換するマクロです.
強制タイプ変換も、同じベースクラス間のポインタタイプが互いに互換性があるため、セキュリティ特性のために考慮される.このような強制型変換は必要ないかもしれませんが、いくつかのトラブルを避けることができます.
3.一つのビュークラスから別のビュークラスのポインタを統合1と2を取得すると、ビュークラス間でポインタを相互に取得する方法が容易に得られる:ドキュメントクラスを中継し、まず1の方法でドキュメントクラスのポインタを得、さらに2の方法で、ドキュメントクラスのビュー位置決め関数で別のビュークラスを取得する.同様に、関数として実装できます.
(CTestaviewから他のビュークラスへのポインタを取得すると仮定)
CView* CTestAView::GetView(CRuntimeClass* pClass)
{
CTestDoc* pDoc=(CTestDoc*)GetDocument();
CView* pView;
POSITION pos=pDoc->GetFirstViewPosition();
while(pos!=NULL){
pView=pDoc->GetNextView(pos);
if(!pView->IsKindOf(pClass))
break;
}
if(!pView->IsKindOf(pClass)){
AfxMessageBox("Connt Locate the View.");
return NULL;
}

return pView;
}
この関数は、2のGetView()と比較して、1つはドキュメントクラスポインタを取得するために第1文が多くなったこと、2つはGetFirstView()とGetNextView()の前にドキュメントクラスポインタを加えて、ドキュメントクラスメンバー関数であることを示します.
この関数があります.CTestAViewからCTestBViewのポインタを取得するには、次のようにします.
CTestBView* pTestbView=(CTestView*)GetView(RUNTIME_CLASS(CTestBView));
11)単一ドキュメントに複数のドキュメントテンプレートを組み込むこともできますが、一般的な開発ではMDI方式でマルチドキュメントテンプレートを開発しています.その方法は上記ビューの取得方法に近いので、ここで少し説明します.不明な場合はMSDNを参照してください(以下の4つのコンテンツ(11、12、13、14)のソース:http://sanjianxia.myrice.com/vc/vc45.htm)
CWinApp::GetFirstDocTemplatePostionを使用して、アプリケーションが登録した最初のドキュメントテンプレートの場所を取得できます.
この値を使用してCWinApp::GetNextDocTemplate関数を呼び出し、最初のCDocTemplateオブジェクトポインタを取得します.
POSITION GetFirstDocTemplate( ) const; 
CDocTemplate *GetNextDocTemplate( POSITION & pos ) const;
の2番目の関数はposによって識別されたドキュメントテンプレートを返します.POSITIONは、MFCが定義した反復またはオブジェクトポインタ取得のための値である.この2つの関数を使用すると、アプリケーションはドキュメントテンプレートのリスト全体を巡回できます.検索されたドキュメントテンプレートがテンプレートリストの最後のテンプレートである場合、posパラメータはNULLに設定されます.
12)1つのドキュメントテンプレートに複数のドキュメントがあり、各ドキュメントテンプレートに対応するすべてのポインタリストが保持され、維持されます.
CDocTemplate::GetFirstDocPosition関数を使用して、ドキュメントテンプレートに関連するドキュメントのセット内の最初のドキュメントの場所を取得し、POSITION値をCDocTemplate::GetNextDocのパラメータとして使用して、テンプレートに関連するドキュメントのリストを繰り返します.関数の原形は次のとおりです.
viaual POSITION GetFirstDocPosition( ) const = 0; 
visual CDocument *GetNextDoc(POSITION & rPos) const = 0;
リストが空の場合、rPosはNULLに設定.
13)ドキュメント内でCDocument::GetDocTemplateを呼び出し、ドキュメントテンプレートへのポインタを取得できます.関数の原形は次のとおりです.
CDocTemplate * GetDocTemplate ( ) const; 
ドキュメントがドキュメントテンプレート管理に属していない場合、NULLが返されます.
14)1つのドキュメントに複数のビューを表示できます.各ドキュメントは、関連するすべてのリストを保持し、維持します.CDocument::AddViewは、1つのビューをドキュメントに接続し、そのビューをドキュメントに関連付けられたビューのリストに追加し、ビューのドキュメントポインタをドキュメントに指します.File/New、File/Open、Windows/NewまたはWindow/Splitのコマンドによって新しく作成されたビューのオブジェクトがドキュメントに接続されると、MFCは自動的にこの関数を呼び出し、フレームワークはドキュメント/ビューの構造によってドキュメントとビューを関連付けます.もちろん、プログラマは自分の必要に応じてこの関数を呼び出すこともできます.
Virtual POSITION GetFirstViewPosition( ) const; 
Virtual CView * GetNextView( POSITION &rPosition) cosnt;
アプリケーションは、CDocument::GetFirstViewPositionを呼び出して呼び出しドキュメントに関連付けられたビューのリストの最初のビューの位置を返し、CDocument::GetNextViewを呼び出して指定された位置のビューを返し、rPositonの値をリストの次のビューのPOSITION値に設定します.見つかったものがリストの最後のものと見なされた場合、rPositionはNULLに設定.
15)あるビュークラスから別のビュークラスのポインタを取得する
このアプリケーションは多視のアプリケーションで多く見られますが、一般的には自分がメインプログラムやメインフレームワークに変数記号をつけていれば、入手することもできます.また、ドキュメントクラスを中継して、ドキュメントクラスのビューで位置決めし、別のビュークラスを取得するのが一般的です.この機能は本明細書の10項から得ることができる.