初學者分析MFC代碼4

來源:互聯網
上載者:User

作者:liguisen

blog:http://blog.csdn.net/liguisen/

在MFC瘦身代碼中,你或者已經發現有兩個特殊的檔案,StdAfx.hS和tdAfx.cpp,它們僅僅是include標頭檔,什麼也沒做。如果你夠細心,你還會發現在每個cpp檔案最上面都include了StdAfx.h,這到底是幹什麼的呢?可以去掉嗎?我們在Test1.cpp把#include "stdafx.h"這一句去掉,編譯發現出現這樣的錯誤:fatal error C1010: unexpected end of file while looking for precompiled header directive。意思大概是找不到先行編譯指示。這個檔案到底是幹什麼用的?其實wizard已經告訴我們答案了,答案就在“注釋”   裡面!什嗎?注釋?不是已經刪掉了嗎?是的,就是在我們刪掉的注釋裡面,所以,wizard所做的每一件事都是有道理的。那我們為什麼要刪掉注釋?不就是為了能讓你集中注意力看關鍵的東西嘛!還記得我們一開始備份的工程嗎?開啟看看:
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
哦,原來它是用來包含一些標準的系統標頭檔以及在工程中一些經常用到的但又很少改動的標頭檔(到此看到我說的話,你應該體會到英語的重要性了)。再看StdAfx.cpp的注釋:
// stdafx.cpp : source file that includes just the standard includes
// Test1.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
看第一行,的確如此,在stdafx.cpp只有一行#include "StdAfx.h"。Test1.pch是先行編譯頭(可以在工程目錄下的debug檔案夾找到),到底有什麼作用呢?答案是這樣的:VC++程式一般包含的標頭檔都比較複雜,如果每次編譯都分析每一行代碼(其中很多代碼是一直不變的),將耗費大量時間在重複分析上面,因此,有必要把一些不變的結果暫時儲存起來,留待下次使用,以節省編譯時間。怎麼使用Test1.pch呢?我們要指定一個標頭檔StdAfx.h,當然,也可以是別的名字,在Project->settings裡的c/c++頁,Category選擇Precompiled Headers,選中Use precompiled header file,在Through header裡就可以修改名字了。我猜是因為.h檔案不能編譯,因此還需要一個cpp(stdafx.cpp)檔案來產生pch檔案。

    既然這個pch先行編譯頭是用來節省時間的,是不是說我們也可以不用?當然,我們有的是時間。首先在Project->settings裡的c/c++頁,Category選擇Precompiled Headers,選中Not using precompiled headers,然後在Test1.cpp和Test1Dlg.cpp中把#include "stdafx.h"去掉,加上StdAfx.h中的內容,跟著在工程裡面刪掉StdAfx.h和StdAfx.cpp,編譯運行都沒有問題!當然,這不是一個聰明的做法!不要胡鬧了,把關於先行編譯的修改複原。

    還有一個小問題:為什麼StdAfx.h要在cpp中include而不在.h中?那是為了避免標頭檔的重複包含。

    下面我們來看看這個程式到底是怎麼執行的。對於初學者來說,我有一個比較好的方法,姑且稱之為“斷點大法”。我們把所有代碼都加上斷點,然後F5進行調試。當然,這樣做你會發現vc會提示你有些斷點是無效的。好了,GO,一直到程式運行,出來視窗,然後關閉。我把程式執行步驟列出來:
////////////////////////////////////////////////////////
Test1.cpp:
#include .....
CTest1App theApp;/*第1步*/
BOOL CTest1App::InitInstance()
{/*第2步*/
 CTest1Dlg dlg;/*第3步*/
 dlg.DoModal();/*第6步*/ 
 return FALSE;/*第7步*/
}/*第8步*/
////////////////////////////////////////////////////////
Test1Dlg.cpp:
#include .....
CTest1Dlg::CTest1Dlg(CWnd* pParent )
: CDialog(CTest1Dlg::IDD, pParent)
{/*第4步*/
}/*第5步*/
其中,第6步到第7步之間需要你在對話方塊中點“確定”或“取消”按鈕或者點標題列中的“×”退出程式。

第1步:
    先看看CTest1App theApp的注釋:// The one and only CTest1App object。又看注釋?呵呵,你可以開啟另一個vc,然後開啟一開始的工程查看。theApp是應用程式類的一個對象,代表了一個應用程式,這是一個單獨的全域的對象。提示:你也可以改為其它的名字。

第2步:
    進入應用程式類的一個InitInstance()函數(注釋:// CTest1App initialization,從函數名也能看出來)。

第3步:
    跟著聲明一個CTest1Dlg對象dlg。

第4、5步:
    CTest1Dlg類聲明一個對象後,立即調用其建構函式(關於建構函式,你需要看相關c++書籍),而這又引起其父類CDialog建構函式的調用。這裡要提醒你注意,我們原來的代碼是這樣的:
在.h中的聲明 CTest1Dlg(CWnd* pParent = NULL);
在.cpp中的實現
CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)
 : CDialog(CTest1Dlg::IDD, pParent)
注意到了嗎?pParent為NULL。(詳細資料請查看MSDN中CDialog::CDialog)
    我們著重關注CTest1Dlg::IDD這個參數。IDD從何而來?在標頭檔中:enum { IDD = IDD_TEST1_DIALOG },你盡可以把名字改掉,例如改成MYIDD:
enum { MYIDD = IDD_TEST1_DIALOG };
CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)
 : CDialog(CTest1Dlg::MYIDD, pParent)
還可以這樣:
CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)
 : CDialog(MYIDD, pParent)
甚至,你可以開啟Resource.h找到IDD_TEST1_DIALOG的定義:
#define IDD_TEST1_DIALOG    102
那麼你可以這樣:
CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)
 : CDialog(102, pParent)

這說明了什嗎?說明這個參數不過是對話方塊模板資源的ID而已,那麼我們可以更改這個ID讓程式裝載另外一個對話方塊模板資源。在ResourceView 的Dialog檔案夾上右鍵->insert dialog插入一個對話方塊,它的預設ID是IDD_DIALOG1,我們這樣做:
enum { IDD = IDD_DIALOG1 };
CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)
 : CDialog(CTest1Dlg::IDD, pParent)
運行看看。於是我們得到一個啟發:在InitInstance()函數裡面可以根據不同的條件顯示不同的面板。

第6步:
    CTest1Dlg對象dlg調用其成員函數DoModal()顯示對話方塊。

第7、8步:
    退出程式。

    MFC程式的流程如此簡單(至少目前我們表面上看到的是這樣),你還有什麼好怕的呢?學習MFC也很容易啊,呵呵,事實並非如此,下次我會結合F10、F11讓你看到更多的東西。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.