DIY一つのMFCプログラム
4143 ワード
MFCの基本フレームワークを前に分析した.
1.アプリケーションを開始するには、CXXX(プロジェクト名)AppクラスのグローバルオブジェクトtheAppを定義します(WinMain関数にアクセスする前に).
具体的には、theAppオブジェクトを定義するときにCXXXAppクラスのコンストラクション関数が自動的に呼び出され、C++継承の原理に基づいて、呼び出される前にベースクラスのCWinAppコンストラクション関数が呼び出されます.初期化作業を完了しました.ここでtheAppオブジェクトをm_に保存しました.pCurrentWinAppにあります.
2.次にWinMain関数(実際にはAfxWinMainによって実現される)に入り、InitApplication、InitInstance、Runの3つの関数によってウィンドウクラスの選択、登録、ウィンドウの確立、ウィンドウの表示、更新、メッセージループの確立を完了する.
具体的にはAfxWinMainでAfxGetApp,AfxGetThread関数でm_pCurrentWinAppに保存されているtheAppオブジェクトは、pAppとpThreadに割り当てられ、pApp->InitApplication()はMFC内部管理を完了し、pThread->InitInstance()は登録ウィンドウクラスを完了し、ウィンドウを作成するなどの作業を完了し、pThread->Run()はメッセージループの確立を完了する.
3.メッセージループに進む.デフォルトのウィンドウ・プロシージャ関数も設定されていますが、実際にはメッセージ・マッピング・メカニズムを使用して様々なメッセージを処理します.WM_を受け取るとQUITメッセージの場合,メッセージループを終了し,プログラムを終了する.
これらの下位フレームワークにカプセル化されたWindows API関数と、MFCフレームワークについていくつかの理解が見つかった以上、MFCクラスライブラリのいくつかのクラスを借りることで、Win 32プロジェクトで1つのMFCプログラムをDIYすることもできるはずです.
まず、VS 2013でMFCframeというWin 32空のプロジェクトを作成し、ソリューションエクスプローラのウィンドウの下でソースファイルに追加---MFCというC++ファイルを新規作成します.
前述の剖析により、CWinAppの派生クラスを確立し、この派生クラスのオブジェクトtheAppを定義する必要があることが明らかになった.また、CframeWndの派生クラス(AfxWinMainでウィンドウ関連操作を行うには欠かせない.この派生クラスのm_pMainWndはCreateWindowが返すウィンドウハンドルを保存するために使用される).
Win 32プロジェクトの下で1つのMFCプログラムをDIYする:
コンパイルを間違えたでしょう.ここでは、このプロジェクトのプロパティページで、プロパティの構成--一般--MFCの使用--静的ライブラリでのMFCの使用が必要です.
(または共有DLLでMFCを使用することを選択します.違い:ダイナミックリンクを使用する場合、ライブラリファイルまたはバージョンが互換性がないライブラリの依存問題が発生しないように、いくつかのライブラリを一緒にパッケージ化する必要がある場合があります.静的リンクを使用すると、プログラムに必要なライブラリがコンパイルされ、生成されたファイルは大きくなる可能性がありますが、ファイル移植を実行できる場合はエラーはありません.)
これでリンクのコンパイルに成功しました~
コードには多くの注釈と前の私のノートも分析されていますが、理解しにくい点を説明しています.
1.最初のMessageBox関数はなぜ3つのパラメータしかないのか(ウィンドウハンドルをパラメータにする必要はありません)、TEXT関数は何に使いますか?
まずTEXTについて説明します.私が使っているVS 2013作IDEは、選択したUnicode文字セットで、UnicodeはANSIよりも良い本を探しています.ここでは言わない.
#ifdef UNICODE
#define MessageBox MessageBoxW//Wはワイド、ワイド文字(2バイト)
......
一方、Char*はLPCTSTRタイプではなく、TEXT変換を使用します.
MyFrameクラスで使用されるMessageBox関数は実際には非_stdcall MessageBoxではなく、CWnd::MessageBoxで定義はもちろん異なり、CWndクラス内にウィンドウハンドルを格納するメンバー変数があれば、ウィンドウハンドルというパラメータを提出する必要はありません~
2.InitInstanceはどのように呼び出しますか?
ここで注意しなければならないのは、MFCでWinMainがコンパイルリンクによってプログラムに組み込まれていることであり、InitInstanceはWinMainで呼び出されているので、WinMain定義を探して見ることができます.
3.m_pMainWndはどうやって来ましたか?何の役に立つの?
CWinThreadで定義:CWnd*m_pMainWnd; そして継承してCWinApp、そしてMyAppにあげました.
注記を参照してください.この変数はスレッドクラスであるため、スレッドが終了しないとライフサイクルが終了しません.スレッドがないと消え、フォームフレームワークも終了します.
4.ShowWindowとUpdateWindowはなぜWindows SDKプログラミングのようにウィンドウハンドルをパラメータにしなかったのですか?
意図すると、ここではpFrameポインタが指すMyFrameクラスオブジェクトで呼び出されていることに気づきますが、MyFrameクラスはウィンドウハンドルを格納するウィンドウオブジェクト(メンバー変数)を継承しており、メンバー関数を呼び出す際にこのクラスのメンバー変数を使用するのは当然合法であり、パラメータとして渡す必要はありません.
実験:MyApp::InitInstance関数からp_を削除MainWnd=pFrame;
結果:ウィンドウはもちろん生成できますが、同時に(ウィンドウの右上をクリックしないで閉じて閉じたイベントが発生し、オペレーティングシステムがこのイベントをパッケージしてWM_QUITメッセージを送信する)ExitInstance関数を識別するための小さなMessageBoxウィンドウが表示されます.つまり、ウィンドウが生成したばかりで(InitInstanceが実行したばかり)、ウィンドウオブジェクトのライフサイクルが台無しになります.ウィンドウオブジェクトが分析されると、ウィンドウは自然に破棄され、ExitInstance終了プログラムが実行されます.
1.アプリケーションを開始するには、CXXX(プロジェクト名)AppクラスのグローバルオブジェクトtheAppを定義します(WinMain関数にアクセスする前に).
具体的には、theAppオブジェクトを定義するときにCXXXAppクラスのコンストラクション関数が自動的に呼び出され、C++継承の原理に基づいて、呼び出される前にベースクラスのCWinAppコンストラクション関数が呼び出されます.初期化作業を完了しました.ここでtheAppオブジェクトをm_に保存しました.pCurrentWinAppにあります.
2.次にWinMain関数(実際にはAfxWinMainによって実現される)に入り、InitApplication、InitInstance、Runの3つの関数によってウィンドウクラスの選択、登録、ウィンドウの確立、ウィンドウの表示、更新、メッセージループの確立を完了する.
具体的にはAfxWinMainでAfxGetApp,AfxGetThread関数でm_pCurrentWinAppに保存されているtheAppオブジェクトは、pAppとpThreadに割り当てられ、pApp->InitApplication()はMFC内部管理を完了し、pThread->InitInstance()は登録ウィンドウクラスを完了し、ウィンドウを作成するなどの作業を完了し、pThread->Run()はメッセージループの確立を完了する.
3.メッセージループに進む.デフォルトのウィンドウ・プロシージャ関数も設定されていますが、実際にはメッセージ・マッピング・メカニズムを使用して様々なメッセージを処理します.WM_を受け取るとQUITメッセージの場合,メッセージループを終了し,プログラムを終了する.
これらの下位フレームワークにカプセル化されたWindows API関数と、MFCフレームワークについていくつかの理解が見つかった以上、MFCクラスライブラリのいくつかのクラスを借りることで、Win 32プロジェクトで1つのMFCプログラムをDIYすることもできるはずです.
まず、VS 2013でMFCframeというWin 32空のプロジェクトを作成し、ソリューションエクスプローラのウィンドウの下でソースファイルに追加---MFCというC++ファイルを新規作成します.
前述の剖析により、CWinAppの派生クラスを確立し、この派生クラスのオブジェクトtheAppを定義する必要があることが明らかになった.また、CframeWndの派生クラス(AfxWinMainでウィンドウ関連操作を行うには欠かせない.この派生クラスのm_pMainWndはCreateWindowが返すウィンドウハンドルを保存するために使用される).
Win 32プロジェクトの下で1つのMFCプログラムをDIYする:
#include <afxwin.h> // MFC
class MyFrame : public CFrameWnd
{
//m_pMainWnd ,
public:
MyFrame()
{
MessageBox(TEXT(" MyFrame , "), TEXT("MyMFC"), MB_OK);
Create(NULL, TEXT("MyMFC")); // CFrameWnd::Create, ,
}
};
class MyApp : public CWinApp
{
public:
MyApp()
{
MessageBox(0, TEXT(" CWinApp , theApp "), TEXT("MyMFC"), MB_OK);
}
BOOL InitInstance(); //MFC InitIntance , CWinApp
BOOL ExitInstance();
};
BOOL MyApp::InitInstance()
{
MessageBox(0, TEXT(" WinMain , InitInstance"), TEXT("MyMFC"), MB_OK);
MyFrame* pFrame=NULL;
pFrame = new MyFrame; // MyFrame
m_pMainWnd = pFrame; //pFrame InitInstance , m_pMainWnd MyFrame
pFrame->ShowWindow(SW_NORMAL);
pFrame->UpdateWindow();
return TRUE;
};
BOOL MyApp::ExitInstance()
{
MessageBox(0, TEXT(" , ExitInstance "), TEXT("MyMFC"), MB_OK);
return TRUE;
};
MyApp theApp;
コンパイルを間違えたでしょう.ここでは、このプロジェクトのプロパティページで、プロパティの構成--一般--MFCの使用--静的ライブラリでのMFCの使用が必要です.
(または共有DLLでMFCを使用することを選択します.違い:ダイナミックリンクを使用する場合、ライブラリファイルまたはバージョンが互換性がないライブラリの依存問題が発生しないように、いくつかのライブラリを一緒にパッケージ化する必要がある場合があります.静的リンクを使用すると、プログラムに必要なライブラリがコンパイルされ、生成されたファイルは大きくなる可能性がありますが、ファイル移植を実行できる場合はエラーはありません.)
これでリンクのコンパイルに成功しました~
コードには多くの注釈と前の私のノートも分析されていますが、理解しにくい点を説明しています.
1.最初のMessageBox関数はなぜ3つのパラメータしかないのか(ウィンドウハンドルをパラメータにする必要はありません)、TEXT関数は何に使いますか?
まずTEXTについて説明します.私が使っているVS 2013作IDEは、選択したUnicode文字セットで、UnicodeはANSIよりも良い本を探しています.ここでは言わない.
#ifdef UNICODE
#define MessageBox MessageBoxW//Wはワイド、ワイド文字(2バイト)
......
一方、Char*はLPCTSTRタイプではなく、TEXT変換を使用します.
MyFrameクラスで使用されるMessageBox関数は実際には非_stdcall MessageBoxではなく、CWnd::MessageBoxで定義はもちろん異なり、CWndクラス内にウィンドウハンドルを格納するメンバー変数があれば、ウィンドウハンドルというパラメータを提出する必要はありません~
2.InitInstanceはどのように呼び出しますか?
ここで注意しなければならないのは、MFCでWinMainがコンパイルリンクによってプログラムに組み込まれていることであり、InitInstanceはWinMainで呼び出されているので、WinMain定義を探して見ることができます.
3.m_pMainWndはどうやって来ましたか?何の役に立つの?
CWinThreadで定義:CWnd*m_pMainWnd; そして継承してCWinApp、そしてMyAppにあげました.
注記を参照してください.この変数はスレッドクラスであるため、スレッドが終了しないとライフサイクルが終了しません.スレッドがないと消え、フォームフレームワークも終了します.
4.ShowWindowとUpdateWindowはなぜWindows SDKプログラミングのようにウィンドウハンドルをパラメータにしなかったのですか?
意図すると、ここではpFrameポインタが指すMyFrameクラスオブジェクトで呼び出されていることに気づきますが、MyFrameクラスはウィンドウハンドルを格納するウィンドウオブジェクト(メンバー変数)を継承しており、メンバー関数を呼び出す際にこのクラスのメンバー変数を使用するのは当然合法であり、パラメータとして渡す必要はありません.
実験:MyApp::InitInstance関数からp_を削除MainWnd=pFrame;
結果:ウィンドウはもちろん生成できますが、同時に(ウィンドウの右上をクリックしないで閉じて閉じたイベントが発生し、オペレーティングシステムがこのイベントをパッケージしてWM_QUITメッセージを送信する)ExitInstance関数を識別するための小さなMessageBoxウィンドウが表示されます.つまり、ウィンドウが生成したばかりで(InitInstanceが実行したばかり)、ウィンドウオブジェクトのライフサイクルが台無しになります.ウィンドウオブジェクトが分析されると、ウィンドウは自然に破棄され、ExitInstance終了プログラムが実行されます.