圖三
單選按鈕部分選擇“MFC AppWizard Executable”,語言支持部分選擇 “中文[中國](APPWZCHS.DLL)”。然后單擊“Finish”進(jìn)入確認(rèn)對(duì)話框。單擊“OK”開始產(chǎn)生定制AppWizard的程序代碼。
添加定制的對(duì)話框
因?yàn)槲覀兊腃ustom AppWizard有一個(gè)額外的對(duì)話框。所以我們首先要定制這個(gè)對(duì)話框的模板資源,以便它能收集輸入信息,今后用此定制AppWizard創(chuàng)建的所有應(yīng)用程序的“關(guān)于”對(duì)話框中都會(huì)顯示這些信息。選擇“ResourceView”標(biāo)簽,打開工程資源表中的“Dialog”。你會(huì)發(fā)現(xiàn)有一個(gè)原始對(duì)話框,其ID是IDD_CUSTOM1。定制后的對(duì)話框應(yīng)該如圖四:
圖四
表一中是對(duì)話框中編譯框控制的ID,注意這里的“程序介紹”和“代碼注釋”編輯框控制的風(fēng)格屬性都要設(shè)置成“Multiline”。
控制 |
控制ID |
程序員編輯框 |
IDC_EDT_PROGRAMMER |
Web 站點(diǎn)編輯框 |
IDC_EDT_WEB_PAGE |
程序介紹編輯框 |
IDC_EDT_GENERAL_INFO |
代碼注釋編輯框 |
IDC_EDT_COMMENT_INFO |
表一 對(duì)話框中的控制的資源IDs
添加完對(duì)話框的資源,我們還要為對(duì)話框控制定義成員變量。進(jìn)入菜單“View|ClassWizard”,選擇“Member Variables”標(biāo)簽,程序變量的類型都是CString類型,名稱分別為:m_strProgrammer、m_strWebPage、m_strGeneralInfo、m_strCommentInfo。 接下來是實(shí)現(xiàn)CCustom1Dlg對(duì)話框類初始化成員函數(shù)OnInitDialog()。在OnInitDialog()的return語句前面添加如下代碼
//
VckbaseWizaw.m_Dictionary.Lookup("PROGRAMMER", m_strProgrammer);
VckbaseWizaw.m_Dictionary.Lookup("WEB_PAGE", m_strWebPage);
VckbaseWizaw.m_Dictionary.Lookup("GENERAL_INFO", m_strGeneralInfo);
VckbaseWizaw.m_Dictionary.Lookup("COMMENT_INFO", m_strConmmentInfo);
UpdateData(FALSE);
//
此段代碼的作用是從Dictionary字典中獲取定制AppWizard宏的值。VckbaseWizaw是一個(gè)CVckbaseWizAppWiz(派生于CCustomAppWiz)類型的全局對(duì)象,它在VckbaseWizaw.h中定義。接下來是從CCustom1Dlg的構(gòu)造函數(shù)中刪除初始化代碼,因?yàn)樗鼈兊闹祵⒃贑VckbaseWizAppWiz::InitCustomAppWiz()函數(shù)中初始化。
我們還要做一件事情就是存儲(chǔ)輸入對(duì)話框中的數(shù)據(jù),也就是說要用創(chuàng)建新工程時(shí)輸入的數(shù)據(jù)更新Dictionary字典。這件事情要在CCustom1Dlg::OnDismiss()函數(shù)中完成。在CCustom1Dlg::OnDismiss()的return語句前面加入以下代碼:
//
VckbaseWizaw.m_Dictionary.SetAt("PROGRAMMER", m_strProgrammer);
VckbaseWizaw.m_Dictionary.SetAt("WEB_PAGE", m_strWebPage);
VckbaseWizaw.m_Dictionary.SetAt("GENERAL_INFO", m_strGeneralInfo);
VckbaseWizaw.m_Dictionary.SetAt("COMMENT_INFO", m_strCommentInfo);
CTime date = CTime::GetCurrentTime();
CString szDate = date.Format( "%A, %B %d, %Y" );
VckbaseWizaw.m_Dictionary["DATE_INFO"] = szDate;
return TRUE;
//
如果你現(xiàn)在構(gòu)造這個(gè)定制的AppWizard并用它來創(chuàng)建新的應(yīng)用程序的話,你可以看到剛才創(chuàng)建的對(duì)話框,但是還有問題,那就是如何將輸入對(duì)話框的值作為宏存儲(chǔ)在AppWizard的字典中,以便今后在新的工程中使用?答案是使用模板文件中的占位符,AppWizard正是用這些包含有占位符的模板文件來構(gòu)造新的工程文件。在下面的主題中,我們將討論如何創(chuàng)建新的模板文件。
創(chuàng)建自己的模板文件
對(duì)于一個(gè)用AppWizard創(chuàng)建的默認(rèn)的MFC程序來說,用于定義“關(guān)于”對(duì)話框?qū)ο蠛虯pp對(duì)象的文件是相同的。我們?cè)诒疚闹卸ㄖ频腁ppWizard除了要產(chǎn)生常規(guī)的新工程文件模板以外,還要?jiǎng)?chuàng)建一個(gè)全新的模板文件——About.h。這個(gè)文件必須存放在AppWizard工程的Template文件夾中。下面是About.h的代碼:
/////////////////////////////////////////////////////////////////////////////
// Project:$$ROOT$$
// Author:$$PROGRAMMER$$
// Date:$$DATE_INFO$$
// Description:$$COMMENT_INFO$$
//
/////////////////////////////////////////////////////////////////////////////
#pragma once
#include "StatLink.h"
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App $$Root$$
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
protected:
CStaticLink m_wndLink1;
CStaticLink m_wndLink2;
CStaticLink m_wndLink3;
CStaticLink m_wndLink4;
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_wndLink1.m_link = _T("http://www.vckbase.com");
m_wndLink2.m_link = _T("http://www.vckbase.com");
m_wndLink3.m_link = _T("mailto:vckbase@publik.hk.hi.cn");
m_wndLink4.m_link = _T("http://www.vckbase.com");
m_wndLink1.SubclassDlgItem(IDC_STATIC_ICON, this);
m_wndLink2.SubclassDlgItem(IDC_STATIC_TEXT, this);
m_wndLink3.SubclassDlgItem(IDC_STATIC_MAIL, this);
m_wndLink4.SubclassDlgItem(IDB_STATIC_IMG, this);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
IDC_STATIC_ICON、IDC_STATIC_TEXT、IDC_STATIC_MAIL、IDB_STATIC_IMG是“關(guān)于”對(duì)話框中要用到的四個(gè)控制,它們是在Dlgres.h和resource.h中定義的,稍候我們?cè)谛薷馁Y源模板文件時(shí)會(huì)定義這四個(gè)控制ID。
About.h的代碼中包含了OnInitDialog()處理。當(dāng)它被調(diào)用時(shí),做一些控制的初始化。接下來我們要做的事情是把模板添加到工程中。
前面我們講過,Custom AppWizard創(chuàng)建新工程的時(shí)候,由MFCAPWZ.DLL負(fù)責(zé)用模板文件來生成新工程的源文件。那么如何告訴AppWizard除了要產(chǎn)生默認(rèn)的源文件以外,你還要求創(chuàng)建一個(gè)新模板文件呢?實(shí)際上,要解決這個(gè)問題需要兩個(gè)步驟。第一步,你必須更新資源文件,在創(chuàng)建新工程時(shí),將自定義資源插入到每一個(gè)Custom AppWizard創(chuàng)建的文件中。為此,必須以文本模式打開.rc文件,定位到下面注釋的位置:
//TEMPLATE
你應(yīng)該看到這個(gè)注釋行的后面列出了所有模板文件,它們都是定制AppWizard要用來生成新工程源文件的模板。我們要在其中加入一個(gè)新的模板文件——About.h,將下面這幾行代碼加到模板文件清單中:
//
ABOUT.H TEMPLATE DISCARDABLE "template\\about.h"
VCKBASELOGO.BMP TEMPLATE DISCARDABLE "template\\vckbaselogo.bmp"
HYPRLINK.H TEMPLATE DISCARDABLE "template\\HyprLink.h"
STATLINK.H TEMPLATE DISCARDABLE "template\\StatLink.h"
STATLINK.CPP TEMPLATE DISCARDABLE "template\\StatLink.cpp"
//
這里hyprlink.h、statlink.h、statlink.cpp三個(gè)文件是超鏈接類,它是由MSDN 專欄作家Paul Dilascia 編寫的可重用類,很多讀者一定熟悉Paul 在MSDN的專欄——《C++ Q&A》,他的大多數(shù)文章的示例代碼都用到這個(gè)類在“關(guān)于”對(duì)話框中創(chuàng)建靜態(tài)超鏈接。筆者深受啟發(fā),在VC知識(shí)庫中也多次使用這個(gè)類來做Demo程序的“關(guān)于”對(duì)話框。但每次做都要去重復(fù)定制“關(guān)于”對(duì)話框豈不是很累。所以才決定做一個(gè)自己的AppWizard。 下一步,我們的任務(wù)是修改newproj.inf文件
修改newproj.inf文件
這個(gè)文件乍一看有點(diǎn)怪模怪樣,它位于AppWizard工程的Template目錄。在創(chuàng)建新的工程文件時(shí),MFCAPWZ.DLL需要用到這個(gè)文件。前面我們提到過占位符,它以“$$”作為前綴和后綴,并且它與AppWizard宏的名字相關(guān)聯(lián),宏名所對(duì)應(yīng)的宏的值存儲(chǔ)在Dictionary字典中。除此之外,“$$”也被用于表示某種命令——這些命令被稱為AppWizard指令,它們被用于處理模板文件。 Newproj.inf中的第一行指令是注釋行,用“$$//”表示,這四個(gè)字符后的任何文本都被MFCAPWZ.DLL忽略,不予解析。打開newproj.inf文件,其第一行就是:
$$// newproj.inf = template for list of template files
通常在一個(gè)模板文件被轉(zhuǎn)換為新工程中的源文件時(shí),宏的作用是命名目的文件。但是,某些標(biāo)準(zhǔn)文件的名字與所建工程類型無關(guān),不管創(chuàng)建什么樣的工程,其名字都是一樣的。例如:stdafx.h和stdafx..cpp。下面的代碼行告訴MFCAPWZ.DLL將stdafx.h和stdafx.cpp文件拷到新工程文件夾,文件名不變。這里要注意兩個(gè)文件名(模板文件和目的文件)之間使用一個(gè)Tab鍵分開,這一點(diǎn)很重要,而且經(jīng)常被忽略。如果你是手工編寫此代碼行,必須保證兩個(gè)文件之間只能是一個(gè)Tab,不能是別的任何字符。 stdafx.h StdAfx.h stdafx.cpp StdAfx.cpp newproj.inf文件中的下一條指令是$$IF。它檢查括弧中宏的布爾狀態(tài)。注意這里宏的使用方法,$$IF中用的不是宏本身,換句話說,如果你想在代碼中引用宏的話,必須加上前綴和后綴$$,如$$PROGRAMMER$$。 參見下面的代碼段,其前兩行表示的意義是:如果此工程不是DLL并且不是基于對(duì)話框的程序,則將模板文件Frame.h和Frame.cpp拷貝成名字為frame_hfile 和frame_ifile宏所表示的文件名。你可能還記得用AppWizard創(chuàng)建MDI程序時(shí)最后一個(gè)對(duì)話框可以讓你根據(jù)不同的類命名文件,因?yàn)槌绦騿T可以改變這些類的名字,其對(duì)應(yīng)的值存儲(chǔ)在宏中。這個(gè)對(duì)話框就象我們?cè)谇懊娑ㄖ茖?duì)話框那樣,使用輸入對(duì)話框的文件名并更新Dictionary字典中的宏。請(qǐng)看一下代碼如何命名目的文件:
$$IF(!PROJTYPE_DLL)
$$IF(!PROJTYPE_DLG)
frame.h $$frame_hfile$$.h
frame.cpp $$frame_ifile$$.cpp
下面的$$IF指令和前面的兩個(gè)$$IF的作用一樣,唯一不同的是根據(jù)這個(gè)宏判斷的結(jié)果導(dǎo)致另一個(gè)從模板到文件的拷貝。
$$IF(MDICHILD)
childfrm.h $$child_frame_hfile$$.h
childfrm.cpp $$child_frame_ifile$$.cpp
最后,每一個(gè)$$IF指令都必須有匹配的$$ENDIF指令。此外,指令行末尾可以加入類似C++的注釋,如:
$$ENDIF //MDICHILD
$$ENDIF //!PROJTYPE_DLG
現(xiàn)在你應(yīng)該很容易理解newproj.inf文件了,我們來加入自己的代碼,首先,在文件最上面(在注釋的后面)加入以下代碼,記住在模板文件和目的文件之間是一個(gè)Tab鍵。
//
$$IF(PROJTYPE_DLG)
$$IF(ABOUT)
about.h about.h
HYPRLINK.H HyprLink.h
STATLINK.CPP StatLink.cpp
STATLINK.H StatLink.h
$$ENDIF //ABOUT
$$ELIF(PROJTYPE_MDI)
about.h about.h
HYPRLINK.H HyprLink.h
STATLINK.CPP StatLink.cpp
STATLINK.H StatLink.h
$$ELIF(PROJTYPE_SDI)
about.h about.h
HYPRLINK.H HyprLink.h
STATLINK.CPP StatLink.cpp
STATLINK.H StatLink.h
$$ENDIF //PROJTYPE_DLG
//
這段代碼的主要作用是保證about.h、hyprlink.h、statlink.cpp、statlink.h四個(gè)文件在三種情況下都被拷貝:
- 基于對(duì)話框的工程類型,程序員不用取消“About Box”復(fù)選框。
- SDI類型的工程
- MDI類型的工程
其次,不要忘了拷貝我們?cè)?#8220;關(guān)于”對(duì)話框中要用到的圖像資源文件,定位到newproj.inf的/res行,然后找到這一段的如下代碼行
$$IF(!PROJTYPE_DLL)
=:root.ico res\$$root$$.ico
在這行代碼后加上:
=:root.ico res\APP.ico
=:VCKBASELOGO.BMP res\VCKBASELOGO.BMP
newproj.inf文件的修改就OK了。
修改AppWizard模板
前面我們已經(jīng)知道了如何創(chuàng)建新的模板文件并將它添加到新的工程中(在newproj.inf文件中操作)。現(xiàn)在我們來學(xué)習(xí)如何修改創(chuàng)建Custom AppWizard時(shí)由AppWizard建立的一般模板。
——修改模板資源定義文件
由于我們?cè)贏ppWizard所創(chuàng)建之新工程的“關(guān)于”對(duì)話框中加入了幾個(gè)靜態(tài)控制,那么我們就必須在模板文件中將這些控制的資源ID定義好。以便AppWizard在生成新工程的源文件時(shí)也能在目標(biāo)源文件中定義這些資源ID。這里要涉及兩個(gè)文件,一個(gè)是AppWizard工程Template目錄中的Dlgres.h,另一個(gè)是同目錄中的resource.h。前者用于基于對(duì)話框的程序,后者用于SDI和MDI。在Dlgres.h文件的最前面(注釋之后)加上如下代碼:
//
$$IF(PROJTYPE_DLG)
$$IF(ABOUT)
#define IDC_STATIC_ICON 1000
#define IDC_STATIC_TEXT 1001
#define IDC_STATIC_MAIL 1002
#define IDB_STATIC_IMG 129
$$ENDIF //ABOUT
$$ELIF(PROJTYPE_MDI)
#define IDC_STATIC_ICON 1000
#define IDC_STATIC_TEXT 1001
#define IDC_STATIC_MAIL 1002
#define IDB_STATIC_IMG 129
$$ELIF(PROJTYPE_SDI)
#define IDC_STATIC_ICON 1000
#define IDC_STATIC_TEXT 1001
#define IDC_STATIC_MAIL 1002
#define IDB_STATIC_IMG 129
$$ENDIF //PROJTYPE_DLG
//
找到_APS_NEXT_RESOURCE_VALUE和_APS_NEXT_CONTROL_VALUE,并降下一個(gè)值的定義改為:
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_CONTROL_VALUE 1003
如法炮制resource.h文件,不同的是IDB_STATIC_IMG的值為:
#define IDB_STATIC_IMG 130
而#define _APS_NEXT_RESOURCE_VALUE定義的下一個(gè)值是131。
——修改模板資源文件
因?yàn)槲覀儎?chuàng)建的定制AppWizard包含了一個(gè)新對(duì)話框,所以你必須在資源模板文件中插入一個(gè)新的對(duì)話框模板資源。你在創(chuàng)建定制AppWizard時(shí),你規(guī)定了起始點(diǎn)是“Standard MFC AppWizard steps”。所以在Template目錄中,你會(huì)看到用這個(gè)定制AppWizard創(chuàng)建每種類型的MFC可執(zhí)行文件所需的全部模板文件。這意味著你可以按自己的要求任意修改這些模板文件。但是我們要確定如何改,以及改什么!這個(gè)目錄中的模板資源文件(.rc)不止一個(gè),到底應(yīng)該改哪一個(gè)呢?,其實(shí)細(xì)想一下,很容易確定要改哪一個(gè)rc文件。
主要的資源文件名中都包含有三個(gè)字母的后綴,它表示語言支持(English=enu,Chinese=chs等等)。此外還有每個(gè)資源文件的本地化Macintosh版本。因此,對(duì)于一個(gè)面向運(yùn)行Windows的Intel PC的中文版應(yīng)用程序來說,資源文件的數(shù)目無外乎四個(gè):all.rc、dlgall.rc、dlgloc_chs.rc、loc_chs.rc。
打開all.rc和dlgall.rc文件,你會(huì)發(fā)現(xiàn)其中的指令和宏都是用于支持語言和平臺(tái)的基本資源文件。進(jìn)而可以斷定這兩個(gè)文件包含特定語言和平臺(tái)所需的資源定義,由串表和對(duì)話框這樣的資源使用。排除了這兩個(gè)文件,那么我們必須修改的兩個(gè)對(duì)話框資源文件非dlgloc_chs.rc和loc_chs.rc莫屬。每種語言之所以有兩個(gè)資源文件是因?yàn)槠渲幸粋€(gè)文件(loc_chs.rc)用于基于文檔/視圖的應(yīng)用程序(SDI和MDI),另一個(gè)文件(dlgloc_chs.rc)用于基于對(duì)話框的程序。
既然知道了要修改哪一個(gè)資源文件,那么就把對(duì)話框資源添加進(jìn)去吧,遺憾的是你不能象往常創(chuàng)建對(duì)話框模板資源那樣用資源編輯器來做這件事情。這是因?yàn)樵谀阍噲D打開模板資源文件的時(shí)候,資源編輯器會(huì)去編譯文件的資源。而現(xiàn)在這些模板文件含有AppWizard指令,文件編譯將不會(huì)成功,因此Visual Studio會(huì)強(qiáng)行讓你用文本方式(Edit code)打開它。也可以在“File Open Dialog”對(duì)話框中,將“Open As”設(shè)為“Text”。 按照上面所講的方法打開loc_chs.rc文件,用下面的代碼替換IDD_ABOUT對(duì)話框模板資源定義:
$$IF(ABOUT)
IDD_ABOUTBOX DIALOG DISCARDABLE 34, 22, 313, 159
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "關(guān)于 111"
FONT 9, "宋體"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC_ICON,11,10,21,21
LTEXT "$$GENERAL_INFO$$",IDC_STATIC,46,14,237,45
CONTROL 129,IDB_STATIC_IMG,"Static",SS_BITMAP |
WS_BORDER,46,72,110,36
LTEXT "@@VCKBASE 版權(quán)所有 (C) $$YEAR$$@@",IDC_STATIC,187,83,106,8
LTEXT "VC 知識(shí)庫\n$$WEB_PAGE$$",IDC_STATIC_TEXT,187,97,73,
16
DEFPUSHBUTTON "@@確定@@",IDOK,56,117,84,14,WS_GROUP
LTEXT "@@與我們聯(lián)系@@",IDC_STATIC_MAIL,187,119,58,8
END
$$ENDIF //ABOUT
接下來用相同的方法打開dlgloc_chs.rc文件,如法炮制。注意對(duì)話框定義中宏的使用方法。它說明了用戶在Custom AppWizard對(duì)話框中輸入的信息如何最終反映在資源文件中。現(xiàn)在如果你構(gòu)造AppWizard工程,則它可以創(chuàng)建基于對(duì)話框的應(yīng)用程序,填寫完“程序員”、“Web 站點(diǎn)”等信息,并構(gòu)造新創(chuàng)建的工程就可以欣賞定制的“關(guān)于”對(duì)話框了。但是如果對(duì)話框中沒有系統(tǒng)菜單怎么辦呢?從哪里訪問“關(guān)于”對(duì)話框呢?為了解決這個(gè)問題,我們還要對(duì)資源模板文件(dlgloc_chs.rc)進(jìn)行修改。在它定義的主對(duì)話框中加一個(gè)“關(guān)于”按鈕。這樣的話,定制的AppWizard創(chuàng)建每一個(gè)基于對(duì)話框的程序時(shí)都會(huì)自動(dòng)在對(duì)話框上加一個(gè)“關(guān)于”按鈕。打開dlgloc_chs.rc文件,將主對(duì)話框的資源定義替換為以下代碼,注意“幫助”按鈕的位置取決于是否創(chuàng)建“關(guān)于”按鈕。
IDD_$$SAFE_ROOT$$_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "$$TITLE$$"
FONT @@9@@, "@@宋體@@"
BEGIN
DEFPUSHBUTTON "@@確定@@",IDOK,260,7,50,14
PUSHBUTTON "@@取消@@",IDCANCEL,260,23,50,14
$$IF(ABOUT)
PUSHBUTTON "@@關(guān)于(&A)@@",ID_APP_ABOUT,260,45,50,14
$$IF(HELP)
PUSHBUTTON "@@幫助(&H)@@",ID_HELP,260,40,50,14
$$ENDIF
$$ELIF(HELP)
PUSHBUTTON "@@幫助(&H)@@",ID_HELP,260,45,50,14
$$ENDIF
LTEXT "@@TODO: 在這里設(shè)置對(duì)話控制。@@",IDC_STATIC,50,90,200,8
END
——修改模版頭文件和模板實(shí)現(xiàn)文件
為了在AppWizard所創(chuàng)建的每一個(gè)工程源文件中加上作者自己的專門注釋(比如,作者姓名、代碼許可聲明、創(chuàng)建日期等),我們必須修改AppWizard工程Template目錄中所有的.h文件和.cpp文件,在每個(gè)文件最上面添加如下代碼段:
/////////////////////////////////////////////////////////////////////////////
// Project:$$ROOT$$
// Author:$$PROGRAMMER$$
// Date:$$DATE_INFO$$
// Description:$$COMMENT_INFO$$
//
/////////////////////////////////////////////////////////////////////////////
——修改文檔/視圖模板文件和對(duì)話框模板文件
這一部分我們將修改文檔/視圖類和對(duì)話框類的頭文件和實(shí)現(xiàn)文件,之所以要改這些文件是因?yàn)槿笔〉囊晥D實(shí)現(xiàn)文件和對(duì)話框?qū)崿F(xiàn)文件通常都要聲明和實(shí)現(xiàn)默認(rèn)的CAboutDlg類,而我們?cè)谇懊鎰?chuàng)建的about.h文件中已經(jīng)包含了CAboutDlg的聲明。
如果你用AppWizard創(chuàng)建一個(gè)名叫MyApp的SDI或者M(jìn)DI程序,主程序類的聲明將會(huì)在MyApp.h中,實(shí)現(xiàn)將會(huì)在MyApp.cpp中。這是因?yàn)槊麨?$ROOT$$的宏其值被設(shè)置為工程的名字,并且被用來命名包含主程序類定義和聲明的文件。newproj.inf中的兩行代碼證明了這一點(diǎn):
root.h $$root$$.h
root.cpp $$root$$.cpp
1、 打開root.cpp文件(在Template目錄中),按照如下的步驟進(jìn)行修改:
2、 刪除文件尾部的CAboutDlg類聲明。
3、 刪除所有的CAboutDlg成員函數(shù)。添加如下代碼:
// App command to run the About dialog
void $$APP_CLASS$$::OnAppAbout()
{
CAboutDlg().DoModal();
}
4、 到文件頂部,在#include "$$root$$.h"語句之后加上,#include "about.h"
現(xiàn)在基于文檔/視圖的模板文件已經(jīng)修改完成,下面要修改基于對(duì)話框的模板文件。分析一下root.h和root.cpp以及dlgroot.h和dlgroot.cpp模板文件的作用,不難得出root.h和root.cpp模板用于創(chuàng)建所有基于文檔/視圖程序的主程序類源文件,dlgroot.h和dlgroot.cpp模板用于創(chuàng)建所有基于對(duì)話框程序的主程序類源文件。與基于文檔/視圖的應(yīng)用程序不同,基于對(duì)話框的程序其“關(guān)于”對(duì)話框的定義與主程序類的定義不在同一個(gè)文件當(dāng)中。而是定義在主對(duì)話框的實(shí)現(xiàn)文件中,其模板文件是dialog..cpp。打開dialog.h文件(位于Template目錄),定位到以下代碼處:
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
插入下面的函數(shù)聲明:
afx_msg void OnAbout();
打開dialog.cpp,按照以下步驟進(jìn)行修改:
1、 刪除$$IF(ABOUT) 到 $$ENDIF之間的所有代碼行。
2、 在$$IF(ABOUT) 和 $$ENDIF //ABOUT之間加上語句 #include "about.h":
$$IF(ABOUT)
#include "about.h"
$$ENDIF //ABOUT
3、 定位到MESSAGE_MAP 部分中的ON_WM_SYSCOMMAND()位置,添加下列代碼行:
ON_BN_CLICKED(ID_APP_ABOUT, OnAbout)
4、 在文件末尾添加下列函數(shù)定義:
$$IF(ABOUT)
void $$DLG_CLASS$$::OnAbout()
{
CAboutDlg().DoModal();
}
$$ENDIF //ABOUT
到此,定制AppWizard要做的主要工作以及要編寫的主要代碼已經(jīng)完成,在構(gòu)造和測試它之前,讓我們?cè)僮鲆恍╁\上添花的工作。每次用AppWizard產(chǎn)生工程的時(shí)候,其最后一個(gè)對(duì)話框是一個(gè)確認(rèn)對(duì)話框,其中總結(jié)性地顯示在前面一系列對(duì)話框中做出的選擇或者選項(xiàng)。下面我們將學(xué)習(xí)如何輕松確認(rèn)輸入信息,將我們?cè)贏ppWizard定制對(duì)話框中輸入的信息也顯示在這個(gè)確認(rèn)對(duì)話框里。
修改confirm.inf文件
打開confirm.inf文件,你會(huì)馬上感覺到這個(gè)文件與newproj.inf太相似了,其中充斥著大量的AppWizard指令和宏。我們對(duì)它的修改很簡單,把自己定義的宏加入這個(gè)文件即可,如果你想顯示一下在定制對(duì)話框中輸入的內(nèi)容,那么在confirm.inf文件的頂部加入下面的代碼就可以了:
$$IF(PROJTYPE_DLG)
$$IF(ABOUT)
定制對(duì)話框信息:
作者:$$PROGRAMMER$$
網(wǎng)站: $$WEB_PAGE$$
程序說明:$$GENERAL_INFO$$
程序注釋:$$COMMETN_INFO$$
$$ENDIF //ABOUT
$$ELIF(PROJTYPE_MDI)
定制對(duì)話框信息:
作者:$$PROGRAMMER$$
網(wǎng)站:$$WEB_PAGE$$
程序說明:$$GENERAL_INFO$$
程序注釋:$$COMMETN_INFO$$
$$ELIF(PROJTYPE_SDI)
定制對(duì)話框信息:
作者:$$PROGRAMMER$$
網(wǎng)站:$$WEB_PAGE$$
程序說明:$$GENERAL_INFO$$
程序注釋:$$COMMETN_INFO$$
$$ENDIF //PROJTYPE_DLG
在這個(gè)文件中,$$IF/$$ELIF/$$ENDIF的結(jié)構(gòu)和語法完全與newproj.inf一樣。$$IF/$$ENDIF指令之間的語句是按原樣顯示的對(duì)話框輸入信息。 |