關於CMDIChildWnd和InitInstance的作用機理
InitIstance中,程式進行
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))return FALSE;
m_pMainWnd = pMainFrame;
進行對框架,視類視窗,文件的建立,在建立過程中:
對視類的建立:在Create建立時會執行視類的OnCreate函式,所以我們可以在OnCreate函式裡面修改檢視視窗,返回到Create併成功建立後,程式接著會執行OnInitialUpdate函式,這個函式用來對視類進行初始化。然後進行UpdateWindow函式傳送WM_PAINT訊息引起訊息響應函式OnPaint函式的執行,在OnPaint函式中,呼叫了OnDraw函式,所以我們可以在OnDraw函式中對檢視進行改變。且每次重繪視窗都會傳送WM_PAINT訊息,然後對其進行響應。
對話方塊建立:對話方塊同樣進行Create之後,執行OnCreate函式,此時,函式的控制元件還並沒有建立,所以不能再這個函式裡對控制元件進行修改,建立成功後執行了OnInitDialog函式,這個函式可以對對話方塊內部控制元件等進行初始化。
對CMainFrame的框架建立:視窗在設計註冊之後,執行Create和CreateEx,在執行CreateEX時,傳送訊息WM_CREATE,這時,CMainFrame類的OnCreate函式進行響應:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
在OnCreate函式裡,可以看到,函式繼續呼叫了基類CFrameWnd的OnCreate函式,然後呼叫了工具欄的建立函式,OnCreate函式呼叫結束之後返回到CreateEx函式,在CreateEx函式中,若查詢我們可以發現,其呼叫了PreCreateWindow函式,這個函式為視窗的型別再改變函式,之後CreateEx結束,至此,視窗建立完成,但還並沒有顯示,所以,回到InitInstance函式執行ShowWindow和UpdataWindow進行視窗的顯示和更新,在次,我們做個試驗:
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
m_pMainWnd = pMainFrame;
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; //此句表示不建立預設文件的視窗和檢視!!!!!!
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// pMainFrame->MessageBox("hello"); 當訊息盒子程式碼在這裡時,視窗還未顯示之前就會出現
// The main window has been initialized, so show and update it.
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
// pMainFrame->MessageBox("hello"); 當訊息盒子程式碼在這裡是,視窗顯示之後會出現
pMainFrame->FrameWndInit(); //所以,當框架建立完畢時,這個自定義函式才會執行
return TRUE;
註釋中已經解釋明確,當我們將MessageBox放在ShowWindow之前時,訊息盒子會在視窗出現之前出現,當我們將其放在之後時,訊息盒子會在視窗出現之後出現,所以,當我們想在視窗建立的時候就改變視窗時,可以在CMainFrame的OnCreate和PreCreateWindow函式中進行實現,而當我們想在視窗建立之後改變視窗時,就可以在InitInstance的顯示視窗和更新視窗之後加入程式碼進行視窗改變,如上例return之前我的那句加入了自定義函式的程式碼。我的自定義函式是一個為主框架新增3個子視窗函式,因為我建立的是一個單文件多程式的MFC框架,而且我取消了預設視窗的建立,所以在建立框架完成並顯示之後,只會出現CMainFrame的框架,並不會出現視類視窗,而我之後要做的就是在主框架建立完成之後在其客戶區新增3個子視窗並顯示出來。我的FrameWndInit函式程式碼如下:
void CMainFrame::FrameWndInit()
{
CRect rect;
CRect m_3Drect;
CRect m_Initrect;
CRect m_TimShowrect;
GetClientRect(&rect);
m_3Drect.right=rect.right/2;
m_3DViewWnd = new C3DViewWnd();
m_3DViewWnd->Create(NULL,"3DViewWnd",WS_CHILD|WS_BORDER|WS_VISIBLE/* |WS_OVERLAPPEDWINDOW */,m_3Drect,NULL,NULL);
m_Initrect.left=rect.right/2;
m_Initrect.right=rect.right;
m_Initrect.bottom=rect.bottom/2;
m_InitWnd = new CInitWnd();
m_InitWnd->Create(NULL,"InitWnd",WS_CHILD|WS_BORDER|WS_VISIBLE/* |WS_OVERLAPPEDWINDOW */,m_Initrect,NULL,NULL);
m_TimShowrect.top=rect.bottom/2;
m_TimShowrect.left=rect.right/2;
m_TimShowrect.right=rect.right;
m_TimShowrect.bottom=rect.bottom;
m_TimeShowWnd = new CTimeShowWnd();
m_TimeShowWnd->Create(NULL,"TimeShowWnd",WS_CHILD|WS_BORDER|WS_VISIBLE/* |WS_OVERLAPPEDWINDOW */,m_TimShowrect,NULL,NULL);
}
這個函式是初始化了我的3個建立好的CMDIChildWnd的子類。其3個類的物件指標定義程式碼如下:
CTimeShowWnd* m_TimeShowWnd;
CInitWnd* m_InitWnd;
C3DViewWnd* m_3DViewWnd;
至此,子視窗建立完成,執行之後發現如期所想。
本人QQ:401190754,如果感覺文章有什麼問題,歡迎討論。
相關文章
- 計算機網路中關於路由器的作用計算機網路路由器
- 基於AD作用於域使用者和計算機的組策略(1)計算機
- 基於AD作用於域使用者和計算機的組策略(2)計算機
- SD-WAN對於雲的關鍵作用
- 關於pwn題的棧平衡中ret的作用
- 詳細介紹php和apache的關係和作用PHPApache
- 關於高併發和分散式中的冪等處理分散式
- 關於資料庫事務併發的理解和處理資料庫
- 驗證碼的作用和相關技術
- Postgresql關於Vacuum的作用和操作方法,Vacuum full鎖表並生成新的relfilenodeSQL
- 物件的使用處理,作用域的和ajax中this的理解物件
- 淺談Java的反射機制和作用Java反射
- 關於Python中的日期處理Python
- 關於ASM的一些理論ASM
- 關於go的跨域處理 ginGo跨域
- 關於Android的幾種事件處理Android事件
- 關於linux病毒`kinsing` `kdevtmpfsi`的處理Linuxdev
- 關於解決主機和虛擬機器ping不通的問題虛擬機
- 工業交換機在電力系統排程和監控中的關鍵作用
- 交換機的作用、功能和工作原理詳解
- 關於JavaScript的作用域你應該瞭解的那點事!JavaScript
- 由一道關於變數作用域的面試題,來加深對var和let的理解變數面試題
- 關於attention中對padding的處理:maskpadding
- 關於特殊符號&與& 的處理符號
- Java--- 關於null的處理若干方法JavaNull
- 關於產品經理的幾點思考?
- 關於GCD多工處理GC
- 關於php rsa加密處理PHP加密
- 關於input 中 hidden屬性在後臺作用的例項
- 關於JMeter中正規表示式提取器的作用域問題JMeter
- js的作用域和作用域鏈JS
- 關於rpc的整理和理解RPC
- 關於Oracle的BLOB和CLOBOracle
- 關於Fork和Malloc的思考
- 03 Windows批處理的作用域和延遲擴充套件Windows套件
- 電腦shift鍵你會用嗎?關於鍵盤shift鍵的作用和11個使用技巧
- static關鍵字的作用
- 關於Java中的反射機制Java反射