第一部分 AppWizard及其工作原理 |
AppWizard即應(yīng)用程序向?qū)?,它是Visual Studio開發(fā)環(huán)境中強(qiáng)大的編程工具之一,用它可以創(chuàng)建各種不同類型的程序。比如Win32應(yīng)用、ATL、MFC應(yīng)用等等。在Windows的術(shù)語中,向?qū)В╳izard)一詞指得是一個(gè)應(yīng)用程序,它的一個(gè)主要特點(diǎn)就是提供一系列對(duì)話框引導(dǎo)用戶進(jìn)行必要的選擇來完成給定的任務(wù)。VC中的應(yīng)用程序向?qū)А狝ppWizard提供一系列特定工程類型對(duì)話框來讓程序員定義各種類型的新工程。其中每一個(gè)對(duì)話框都顯示一些用來指定工程類型的選項(xiàng)。例如,用AppWizard創(chuàng)建Windows DLL的時(shí)候,第一個(gè)對(duì)話框讓程序員指定諸如要?jiǎng)?chuàng)建什么類型的DLL,是常規(guī)類型還是MFC擴(kuò)展類型,是否要包括自動(dòng)化支持,以及要不要源代碼注釋等等。 根據(jù)程序員所填充的對(duì)話框,AppWizard會(huì)自動(dòng)創(chuàng)建構(gòu)造工程所需的框架文件,它們包括:工程文件、工作間文件、源代碼文件、頭文件、資源文件等等。AppWizard是Visual Studio開發(fā)環(huán)境中使用最多的工具之一。盡管如此,AppWizard也有它的不足之處。那就是常用的工程類型都是內(nèi)建在Visual Studio中,無法創(chuàng)建自己的AppWizard。自從有了Custom AppWizard(Visual C++ 4.0)以后,這個(gè)問題得到了解決。Custom AppWizard也就是定制的AppWizard。在創(chuàng)建類似的多個(gè)工程時(shí),Custom AppWizards顯得特別有用。例如你創(chuàng)建的工程都是SDI,并且都支持自動(dòng)化(automation),那么你就可以創(chuàng)建一個(gè)自己定制的 AppWizard,將SDI自動(dòng)化設(shè)為默認(rèn)選項(xiàng)。這樣可以提高工作效率。此外,利用Custom AppWizard也可以創(chuàng)建具有個(gè)性化的工程。例如你想要所有工程都有一個(gè)“關(guān)于”對(duì)話框,并且在這個(gè)對(duì)話框中顯示個(gè)人信息或者公司的標(biāo)徽及其它專有信息,每個(gè)源代碼文件中都加上自己的專門注釋。那么通過創(chuàng)建一個(gè)Custom AppWizard很容易實(shí)現(xiàn)這個(gè)需求。你甚至可以定義并顯示自己定制的對(duì)話框來收集工程類型所需的信息和選項(xiàng)。本文的第一部分我們將討論AppWizard的工作原理,然后在后續(xù)部分中循序漸進(jìn)地學(xué)習(xí)如何創(chuàng)建Custom AppWizard。最終我們將創(chuàng)建一個(gè)在實(shí)際編程中非常實(shí)用的Custom AppWizard。并提供全部源代碼。 在學(xué)會(huì)使用Custom AppWizard之前,首先必須了解AppWizard的工作原理,理解 AppWizard是如何根據(jù)不同的用戶選擇來創(chuàng)建工程的。 AppWizard有一個(gè)管理裝置(manager),它不是一個(gè)單獨(dú)的應(yīng)用程序。Custom AppWizard運(yùn)行于Visual Studio框架之中。AppWizard的這個(gè)所謂的“管理器”,實(shí)際上就是MFCAPWZ.DLL,它控制不同的AppWizard執(zhí)行。在創(chuàng)建新工程的對(duì)話框中,“Project”標(biāo)簽是默認(rèn)的選項(xiàng),列表框中顯示出內(nèi)建的工程類型。此外,這個(gè)列表框中還列出用戶定制的AppWizard,如圖一所示。 |
|
圖一 |
這些定制AppWizard文件擴(kuò)展名為*.awx,它們存放在一個(gè)特定的目錄中。如果安裝VC6.0時(shí)是按照默認(rèn)的路徑安裝的,則定制的AppWizard文件在成功編譯后都會(huì)被存放到\Program Files\Microsoft Visual Studio\Common\MSDev98\Template文件夾中。注意列表框中此新的列表項(xiàng)“MFC AppWizard (exe) – VC知識(shí)庫”,這就是我們后面要定制的AppWizard。從這里可以看出,只要產(chǎn)生了*.awx文件,那么它就會(huì)與標(biāo)準(zhǔn)的(或者說內(nèi)建的)Visual C++ AppWizard一起自動(dòng)顯示在這個(gè)列表框中。 |
——CCustomAppWiz 類和Dictionary字典 |
CCustomAppWiz 基類提供了MFCAPWZ.DLL 和Custom AppWizard之間的通訊服務(wù)。CCustomAppWiz()成員函數(shù)的實(shí)現(xiàn)就在MFCAPWZ.DLL中。為了實(shí)現(xiàn)特定應(yīng)用的行為,你只要從CCustomAppWiz派生一個(gè)類,改寫相應(yīng)的虛擬函數(shù),然后在MFCAPWZ.DLL運(yùn)行時(shí)調(diào)用SetCustomAppWizClass()函數(shù)注冊(cè)派生類即可。 通常,AppWizard顯示一系列對(duì)話框獲取創(chuàng)建新工程所需的設(shè)置。每一個(gè)步進(jìn)對(duì)話框顯示不同的選項(xiàng)。AppWizard將這些選項(xiàng)的值存儲(chǔ)在一個(gè)串映射中。這個(gè)串映射就叫做Dictionary字典。Dictionary字典實(shí)際上是一個(gè)CCustomAppWiz 類的成員變量(m_Dictionary),其類型為CMapStringToString。Dictionary將AppWizard宏映射到相關(guān)聯(lián)的值。這里所說的宏是指工程選項(xiàng)或設(shè)置的名稱。例如,在創(chuàng)建MFC的時(shí)候,你可以選擇應(yīng)用程序?yàn)?/span>SDI,那么,Dictionary中就會(huì)有一個(gè)名為PROJTYPE_SDI的宏。Dictionary中這個(gè)項(xiàng)目的值就是1,否則這個(gè)與這個(gè)宏關(guān)聯(lián)的值為0。 m_Dictionary成員變量可以被用于創(chuàng)建宏,刪除宏或者更新宏的值。因?yàn)?/span>m_Dictionary是一個(gè)CMapStringToString對(duì)象,肯定有相應(yīng)的成員函數(shù)存取不同宏的值。下面的代碼返回PROJTYPE_SDI宏的值,它被用于判斷這個(gè)工程是不是一個(gè)SDI應(yīng)用。 m_Dictionary.Lookup("PROJTYPE_SDI", m_strProjType); if (_T("1") == m_strProjType) { // SDI類型應(yīng)用 } else // 其它類型的程序 { } MFCAPWZ.DLL提供了一些標(biāo)準(zhǔn)宏,任何其它定制AppWizard所需要的宏都可以用SetAt函數(shù)添加到Dictionary字典中。你從在線文檔中可以找到六十多個(gè)標(biāo)準(zhǔn)宏 當(dāng)你創(chuàng)建Custom AppWizard并按下Finish按鈕后,MFCAPWZ.DLL用Dictionary創(chuàng)建新的工程文件。每一個(gè)AppWizard(不論是標(biāo)準(zhǔn)的還是定制的)都有一套模板文件用于創(chuàng)建AppWizard生成的工程源文件。Dictionary中的值被用于與模板文件相連接來創(chuàng)建最終的輸出(新的工程文件)。下面是一個(gè)例子,中文的基于對(duì)話框程序的模板資源文件名叫DlgLoc_chs.rc。下面是從中摘錄出的一段: ... IDD_ABOUTBOX DIALOGEX 0, 0, 160, 129 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "關(guān)于$$ROOT$$" ... 注意這里 $$ROOT$$ 串的用法。當(dāng)MFCAPWZ.DLL創(chuàng)建新工程文件時(shí),它首先掃描每一個(gè)模板,查找以$$開始并以$$結(jié)尾的串。在這兩個(gè)前綴和后綴之間的文本串叫做占位苻。每一個(gè)占位符是Dictionary中一個(gè)宏的名字。MFCAPWZ.DLL在Dictionary中查詢占位符的值并用這個(gè)值替換占位符。當(dāng)所有的占位符都被Dictionary中相應(yīng)的值替換之后,工程文件也就產(chǎn)生了。 ——用MFCAPWZ.DLL替代占為符 為了理解MFCAPWZ.DLL用Dictionary中宏的值替換模板文件的占位符。我們來做一個(gè)實(shí)驗(yàn): 1、 用AppWizard創(chuàng)建一個(gè)基于對(duì)話框的應(yīng)用程序,將工程取名為MyTestDlgApp。 2、 創(chuàng)建完工程之后,以文本方式打開MyTestDlgApp.rc文件。 3、 找到IDD_ABOUT的對(duì)話框模板資源。 4、 你應(yīng)該看到原來模板文件中$$ROOT$$占位符已經(jīng)被工程的名字(MyTestDlgApp)替換掉了。這是因?yàn)?/span>Dictionary有一個(gè)ROOT宏,其缺省值被設(shè)置為工程的名字。 宏即可被用于定義模板文件中指定的占位符的替換值,有時(shí)AppWizard也用宏來協(xié)助步進(jìn)對(duì)話框的顯示,或者確定用哪個(gè)模板來創(chuàng)建新的工程文件。例如,如果Dictionary中PROJTYPE_SDI宏的值為1,則創(chuàng)建的應(yīng)用程序是SDI類型。但是,如果PROJTYPE_DLG宏的值為1的話,創(chuàng)建的應(yīng)用程序是基于對(duì)話框的。根據(jù)宏的值是否為1,MFCAPWZ.DLL使用不同的模板文件來創(chuàng)建工程文件。 大多數(shù)AppWizard都由一系列固定的對(duì)話框組成。其中后一個(gè)對(duì)話框的顯示完全依賴于前一個(gè)對(duì)話框所選擇的選項(xiàng)來決定。這種多步進(jìn)對(duì)話框形式稱為軌跡。創(chuàng)建MFC應(yīng)用程序的AppWizard是一個(gè)多軌跡的AppWizard。 ——多軌跡AppWizard 多軌跡AppWizard提供了更為復(fù)雜的應(yīng)用程序設(shè)置。為了理解多軌跡AppWizard概念,請(qǐng)做一個(gè)如下實(shí)驗(yàn): 1、 按下Ctrl+N創(chuàng)建新工程 2、 單擊“Project”標(biāo)簽,然后選中“MFC AppWizard (exe)”。 3、 注意對(duì)話框的標(biāo)題條內(nèi)容為“MFC AppWizard - Step 1”,沒有指明總共有幾步,這是因?yàn)榭偣驳牟竭M(jìn)數(shù)在你決定要?jiǎng)?chuàng)建的MFC工程類型前時(shí)未知的。 4、 看一下不同類型工程的選項(xiàng)有何差別:single document (SDI),multiple document (MDI),和 dialog-based。選擇multiple document (MDI)類型,然后單擊Next按鈕。 5、 注意標(biāo)題條的內(nèi)容中指定了總共的步進(jìn)數(shù)——“MFC AppWizard - Step 2 of 6”。由于你選擇了MDI類型,這個(gè)類型總共有六個(gè)步進(jìn)對(duì)話框,每一個(gè)步進(jìn)對(duì)話框包含特定的基于文檔的MFC應(yīng)用程序選項(xiàng)。 6、 單擊Back按鈕,選擇基于對(duì)話框的工程類型,然后單擊Next按鈕。這一次標(biāo)題條的內(nèi)容指定的步進(jìn)總數(shù)是——“MFC AppWizard - Step 2 of 4”。這說明創(chuàng)建基于對(duì)話框的應(yīng)用程序共有四個(gè)步進(jìn)對(duì)話框。 以上是對(duì)AppWizards 及其工作原理的討論。在下一部分我們將嘗試創(chuàng)建一個(gè)簡(jiǎn)單的Custom AppWizard。 |
第二部分 創(chuàng)建一個(gè)簡(jiǎn)單的AppWizard |
在第一部分中我們介紹了Custom AppWizard的概念及其工作原理。在這一部分,我們將嘗試用Custom AppWizards來創(chuàng)建一個(gè)最簡(jiǎn)單的Custom AppWizard。 首先,我們先創(chuàng)建一個(gè)什么事情也不做的Custom AppWizard,主要是了解它的創(chuàng)建過程和步驟。按Ctrl+N 打開New對(duì)話框,新建一個(gè)Custom AppWizards工程。填入工程名字后單擊OK,從步進(jìn)對(duì)話框的標(biāo)題中,我們可以了解到總共有兩個(gè)步驟,在第一個(gè)步的對(duì)話框中包含三個(gè)輸入域。 第一個(gè)輸入域是新Custom AppWizards的起點(diǎn)。它有三個(gè)單選按鈕: |
l Existing project——這個(gè)選項(xiàng)是以一個(gè)現(xiàn)存的工程作為藍(lán)本來創(chuàng)建Custom AppWizards。使用這個(gè)選項(xiàng)有兩個(gè)缺點(diǎn)。第一,AppWizards創(chuàng)建的是一個(gè)已經(jīng)存在的工程。第二,AppWizards創(chuàng)建的工程文件名和類名必須與現(xiàn)存工程的文件名和類名一致。 l Standard MFC AppWizard steps——這個(gè)選項(xiàng)是最常用的選項(xiàng),它創(chuàng)建的AppWizard模板可用于每一種MFC支持的工程類型。從修改各種MFC工程模板文件的靈活性方面,這個(gè)選項(xiàng)也是最靈活的。因?yàn)檫@是最通用的一種定制AppWizard類型,所以我們將以它為例。 l Your own customized steps——這個(gè)選項(xiàng)全新定制一組步進(jìn)對(duì)話框和選項(xiàng)。例如,假設(shè)你需要一個(gè)定制的AppWizard來自動(dòng)創(chuàng)建一個(gè)非MFC應(yīng)用程序。這時(shí)你就得用這個(gè)選項(xiàng)創(chuàng)建所有自己定制的對(duì)話框。 第二個(gè)輸入域讓你命名新建的定制AppWizard。這個(gè)名字將被用于顯示在New Project List對(duì)話框中. 最后一個(gè)輸入域用來指定定制步進(jìn)的數(shù)目或者對(duì)話框的數(shù)目,它將被添加到新的定制AppWizard中。有時(shí)候我們不需要額外的步進(jìn)對(duì)話框,比如我們即將創(chuàng)建的簡(jiǎn)單AppWizard就不用任何步進(jìn)。但在第三部分中,我們將會(huì)學(xué)習(xí)如何定制步進(jìn)對(duì)話框。 接下來,按Next按鈕繼續(xù)到定制AppWizard的第二步(對(duì)話框),也是最后一步。這個(gè)對(duì)話框中有兩個(gè)域都是自解釋的。第一個(gè)域定義新定制的AppWizard是個(gè)可執(zhí)行程序還是一個(gè)DLL。第二個(gè)域指定語言支持選項(xiàng)。 |
設(shè)置工程的缺省選項(xiàng) |
前面我們講過用AppWizard創(chuàng)建工程時(shí)可以有多種類型可以選擇。這一部分我們創(chuàng)建的AppWizard名字叫SDIAutomationWiz,在默認(rèn)情況下,用這個(gè)AppWizard創(chuàng)建的工程類型是支持自動(dòng)化的SDI工程。 打開工程的New 對(duì)話框,在Project List中選擇Custom AppWizard,在Project Name編輯框中輸入SDIAutomationWiz,單擊OK進(jìn)入第一個(gè)步進(jìn)對(duì)話框,選擇“Standard MFC AppWizard steps”,然后指定一個(gè)它在Project List中顯示的名字。因?yàn)檫@個(gè)AppWizard沒有額外的步進(jìn)對(duì)話框,因此步進(jìn)數(shù)編輯框中填寫0,單擊Next按鈕到下一步。選擇“MFC AppWizard Executable”,語言支持為中文,單擊Finish按鈕,出現(xiàn)確認(rèn)對(duì)話框。單擊OK后便開始創(chuàng)建新的AppWizard工程。 ——定義CCustomAppWiz 類 雖然編譯后的Custom AppWizard文件擴(kuò)展名都是.awx,但是它實(shí)際上就是一個(gè)通常我們使用的Windows動(dòng)態(tài)鏈接庫(DLL)文件。如果你打開SDIAutomationWiz.cpp文件,你就會(huì)看到如下的DLLMain()函數(shù)代碼: // Defining the DLLMain() Function extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { TRACE0("SDIAUTOMATIONWIZ.AWX Initializing!\n");
// Extension DLL one-time initialization AfxInitExtensionModule(SDIAutomationWizDLL, hInstance);
// Insert this DLL into the resource chain new CDynLinkLibrary(SDIAutomationWizDLL);
// Register this Custom AppWizard with MFCAPWZ.DLL SetCustomAppWizClass(&SDIAutomationWizaw); } else if (dwReason == DLL_PROCESS_DETACH) { TRACE0("SDIAUTOMATIONWIZ.AWX Terminating!\n");
// Terminate the library before destructors are called AfxTermExtensionModule(SDIAutomationWizDLL); } return 1; // ok } 除了常規(guī)的CDynLinkLibrary MFC擴(kuò)展動(dòng)態(tài)鏈接庫例程之外,還有一個(gè)對(duì)SetCustomAppWizClass()函數(shù)的調(diào)用。這個(gè)函數(shù)是從MFCAPWZ.DLL輸出的,用于傳遞定制AppWizard 中CCustomAppWiz派生類的指針。因?yàn)?/span>MFCAPWZ.DLL通過調(diào)用CCustomAppWiz的成員函數(shù)來控制所有AppWizard的執(zhí)行,因此它必須用這個(gè)指針來調(diào)用CCustomAppWiz派生類中重載的成員函數(shù)。 有一點(diǎn)必須牢記在心,那就是盡管你創(chuàng)建了定制的AppWizard,但MFCAPWZ.DLL仍然控制著一切。換句話說,你定制的AppWizard只是用于顯示步進(jìn)對(duì)話框,確定對(duì)話框以什么順序顯示,以及設(shè)置新工程的模人選項(xiàng)。一些重要的工作,諸如解析模板文件,合并Dictionary中的宏和模板文件中的占為符,創(chuàng)建工程文件等等還是要MFCAPWZ.DLL來做。 前面我們講過,CCustomAppWiz類負(fù)責(zé)AppWizard與MFCAPWZ.DLL之間的通訊。實(shí)際上這種通訊是單邊的。MFCAPWZ.DLL告訴你的CCustomAppWiz對(duì)象什么時(shí)候需要調(diào)用相應(yīng)的虛擬成員函數(shù)。 CCustomAppWiz類中大約有十來個(gè)函數(shù),其中只有五個(gè)函數(shù)是可以看到并使用的常用例程。通過這些函數(shù)的命名你基本上就能了解其主要作用。例如,InitCustomAppWiz()函數(shù)是進(jìn)行初始化,包括初始化宏。除此之外,ExitCustomAppWiz()函數(shù)的作用是卸載AppWizard。 另外,還有兩個(gè)函數(shù)用來控制步進(jìn)對(duì)話框的顯示順序。Next()和Back()。不說肯定你也知道,這兩個(gè)函數(shù)與AppWizard對(duì)話框中的Next和Back按鈕是關(guān)聯(lián)的。 最后一個(gè)很重要的函數(shù)是CustomizeProject(),一旦程序員完成工程選項(xiàng)的設(shè)置,AppWizard便創(chuàng)建工程的make文件并定義工程缺省的debug和release配置。然后AppWizard調(diào)用CustomizeProject()函數(shù),以便定制的AppWizard能在存儲(chǔ)工程之前修改make文件設(shè)置。 ——宏指令的處理 我們已經(jīng)知道了宏的初始化是在InitCustomAppWiz()中進(jìn)行的,我們也知道了CCustomAppWiz類有一個(gè)成員變量m_Dictionary,它存儲(chǔ)宏名及其值。因?yàn)檫@個(gè)成員變量是CMapStringToString類型的,用標(biāo)準(zhǔn)的MFC映射函數(shù)就能get或者set不同的宏,請(qǐng)看下列代碼: // retrieve value for Automation CString strValue; m_Dictionary.Lookup(_T("AUTOMATION"), strValue);
// Include support for context sensitive help m_Dictionary.SetAt(_T("HELP"), strValue.Compare("1")); 現(xiàn)在打開SDIAutomationWizAW.cpp文件,在InitCustomAppWiz()函數(shù)末尾敲入: m_Dictionary.SetAt(_T("PROJTYPE_SDI"), _T("1")); m_Dictionary.SetAt(_T("PROJTYPE_MDI"), _T("0")); m_Dictionary.SetAt(_T("AUTOMATION"), _T("1")); 然后構(gòu)造(build)定制的AppWizard工程。如果沒有出錯(cuò)的話,AppWizard的.awx文件會(huì)被自動(dòng)拷貝到專門的目錄中,以便MFCAPWZ.DLL能找到它。 現(xiàn)在按下Ctrl+N,新定制的AppWizard應(yīng)該出現(xiàn)在New對(duì)話框的Project清單中。如果你使用新的AppWizard,你會(huì)看到工程的默認(rèn)選項(xiàng)是SDI程序并支持自動(dòng)化。通過這個(gè)簡(jiǎn)單的Demo,我們基本上了解了如何通過定制AppWizard來設(shè)置默認(rèn)的工程選項(xiàng)。 如果要分發(fā)你創(chuàng)建的AppWizard,只要分發(fā).awx文件就可以了,把它拷到Visual Studio的模板文件目錄即可。 在這一部分,我們定制了一個(gè)簡(jiǎn)單的AppWizard,通過一個(gè)例子示范了如何處理宏字典。在第三部分中,我們將涉及更多定制AppWizard的內(nèi)容,并且還要制作一個(gè)實(shí)用價(jià)值很高的AppWizard。包括新增加一個(gè)步進(jìn)對(duì)話框,獲得新步進(jìn)對(duì)話框中的輸入信息。用這個(gè)定制的AppWizard創(chuàng)建的所有工程都會(huì)在其“關(guān)于”對(duì)話框中顯示在步進(jìn)對(duì)話框輸入的信息,并通過靜態(tài)控制和圖像建立URL鏈接。此外,用這個(gè)AppWizard創(chuàng)建的每一個(gè)源文件都會(huì)自動(dòng)建立程序員自己的專用注釋。 |
我們?cè)诘诙糠种惺痉兜腁ppWizard例子很簡(jiǎn)單,沒有任何實(shí)用性。在這一部分我們將討論幾個(gè)關(guān)于制作AppWizard的高級(jí)話題。然后利用VC提供的Custom AppWizard來創(chuàng)建一個(gè)在編程中非常實(shí)用的AppWizard。與MFC AppWizard(exe) 產(chǎn)生的常規(guī)應(yīng)用程序相比,用這個(gè)定制的AppWizard所創(chuàng)建的工程構(gòu)造出來的應(yīng)用程序有兩個(gè)定制特點(diǎn):
一是所有程序都會(huì)有一個(gè)定制的“關(guān)于”對(duì)話框,在這個(gè)對(duì)話框中顯示自己或公司的有關(guān)信息,對(duì)話框中還有一個(gè)將用戶定向到Web站點(diǎn)的靜態(tài)文字控制或圖像(icon和bmp)。
二是工程中每一個(gè)源代碼文件(*.h和*.cpp)的最上面都會(huì)有程序編寫著的名字及程序創(chuàng)建日期以及簡(jiǎn)單的程序說明和注釋。
這一部分要介紹的主要技術(shù)包括:
1、 如何定義和添加AppWizard要用到步進(jìn)對(duì)話框。
2、 如何將Custom AppWizard的專用宏添加到字典中。
3、 如何修改定制AppWizard要用到的模板文件,包括inf文件,資源模板文件等。
4、 將輸入信息存儲(chǔ)到注冊(cè)表中,使得每一個(gè)工程的公共信息都不用重復(fù)輸入。
下面我們就開始吧: 進(jìn)入Visual C++開發(fā)環(huán)境,如圖一:
圖一
選擇“Project”標(biāo)簽,工程名字可以隨便取。這里我取的名字是“VckbaseWiz”,其它選項(xiàng)都默認(rèn)。
然后單擊OK。進(jìn)入下一個(gè)對(duì)話框。如圖二:
圖二
因?yàn)槲覀円ㄒ粋€(gè)標(biāo)準(zhǔn)的MFC AppWizard,所以選擇“Standard MFC AppWizard steps”單選按鈕。AppWizard的命名最好規(guī)范一些,這樣便于記憶和辨認(rèn)。與AppWizard的工程名不同,這個(gè)名字要在Project類型清單中列出。我們把它命名為“MFC AppWizard(exe)——VC知識(shí)庫”。因?yàn)樵谖覀儎?chuàng)建的這個(gè)Custom AppWizard中有一個(gè)額外的對(duì)話框,所以在設(shè)置步進(jìn)步驟的數(shù)目時(shí)輸入1。單擊“Next”進(jìn)入下一個(gè)對(duì)話框。如圖三:

1、 打開VckbaseWizAw.cpp,在“#include "chooser.h"” 包含語句后面加上“#include "registry.h"” 2、 在InitCustomAppWiz成員函數(shù)前面加上如下注冊(cè)表鍵值定義: 3、 在VCKBASEWIZ_KEY #define指令之后,定義下列靜態(tài)結(jié)構(gòu),其中包含:宏名、注冊(cè)表值名、宏的缺省值。注冊(cè)表值名被用來在注冊(cè)表中查找VCKBASEWIZ_KEY指定的鍵。如果沒有找到鍵值(例如第一次運(yùn)行程序時(shí)),則會(huì)使用宏的缺省值: static struct { char szMacroName[50]; char szRegistryValueName[50]; char szMacroDefaultValue[1024];//512個(gè)漢字 } macroPairs[] = { "PROGRAMMER", "Programmer", "程序員", "WEB_PAGE", "Web Page", "網(wǎng)站", "GENERAL_INFO", "General Info", "程序描述", "COMMENT_INFO", "Comment Info", "程序注釋" }; 4、 將下列代碼添加到CVckbaseWizAppWiz::InitCustomAppWiz()函數(shù)末尾,其作用是在堆棧創(chuàng)建CRegistry對(duì)象,然后遍歷上一步定義的靜態(tài)結(jié)構(gòu)。對(duì)于這個(gè)宏結(jié)構(gòu)數(shù)組每一個(gè)元素,程序都會(huì)在注冊(cè)表中找對(duì)應(yīng)值,如果找到則取注冊(cè)表中的值,否則取缺省值。不論哪一種情況,宏的值一旦建立,Dictionary字典的值就被更新為當(dāng)前宏的值: CRegistry registry(HKEY_LOCAL_MACHINE, VCKBASEWIZ_KEY); CString strValue; for (int i = 0; i < sizeof macroPairs / sizeof macroPairs[0]; i++) { if (registry.ReadString(macroPairs[i].szRegistryValueName, strValue.GetBuffer(strValue.GetLength()))) { m_Dictionary.SetAt(macroPairs[i].szMacroName, strValue); } else { m_Dictionary.SetAt(macroPairs[i].szMacroName, macroPairs[i].szMacroDefaultValue); if (m_Dictionary.Lookup(macroPairs[i].szMacroName, strValue)) { registry.WriteString(macroPairs[i].szRegistryValueName, strValue.GetBuffer(strValue.GetLength())); } } }5、 將下列代碼添加到CVckbaseWizAppWiz::ExitCustomAppWiz()函數(shù)末尾,其作用是當(dāng)卸載定制的AppWizard DLL時(shí)程序會(huì)調(diào)用這個(gè)函數(shù)存儲(chǔ)數(shù)據(jù)。 CRegistry registry(HKEY_LOCAL_MACHINE, VCKBASEWIZ_KEY); CString strValue; for (int i = 0; i < sizeof macroPairs / sizeof macroPairs[0]; i++) { if (m_Dictionary.Lookup(macroPairs[i].szMacroName, strValue)) { registry.WriteString(macroPairs[i].szRegistryValueName, strValue.GetBuffer(strValue.GetLength())); } } ![]() 圖五 輸入相應(yīng)的信息后,單擊“Finish”按鈕,顯示確認(rèn)對(duì)話框,你在定制對(duì)話框中輸入的信息也應(yīng)該在此確認(rèn)對(duì)話框中顯示。單擊“OK”按鈕創(chuàng)建工程。然后編譯并運(yùn)行。對(duì)話框中可以見到三個(gè)按鈕:“確定”、“取消”、“關(guān)于”。單擊“關(guān)于”按鈕,彈出對(duì)話框如圖六: ![]() 圖六 這就是我們定制的“關(guān)于”對(duì)話框。這個(gè)對(duì)話框中有帶URL鏈接的靜態(tài)文字、icon和Bitmap圖像。 我真的覺得它很酷! [全文完] |
![]() |
![]() ![]() ![]() |
![]() ![]() #import "devbld.pkg" #include <bldauto.h> #include <blddefs.h> #include <bldguid.h> 在cpp文件中修改CustomizeProject函數(shù) CustomizeProject(IBuildProject* pProject) { using namespace DSProjectSystem; long lNumConfigs; IConfigurationsPtr pConfigs; IBuildProjectPtr pProj; CString sTemp; // Needed to convert IBuildProject to the DSProjectSystem namespace pProj.Attach((DSProjectSystem::IBuildProject*)pProject, true); pProj->get_Configurations(&pConfigs); pConfigs->get_Count(&lNumConfigs); //Get each individual configuration for (long j = 1 ; j < lNumConfigs+1 ; j++) { _bstr_t varTool; _bstr_t varSwitch; IConfigurationPtr pConfig; _variant_t varj = j; pConfig = pConfigs->Item(varj); varTool = "link.exe";//修改鏈接選項(xiàng) varSwitch = "yourlib.lib"; pConfig->AddToolSettings(varTool, varSwitch, varj); } } ( liuke716 發(fā)表于 2003-12-29 14:32:00) |
轉(zhuǎn)載自:http://www.vckbase.com/document/viewdoc/?id=276
畢業(yè)以后想從事計(jì)算機(jī)的大學(xué)生必須去一個(gè)網(wǎng)站:http://www.RuPeng.com