前面我們利用AppWizard建立了一個應用程式架構,它除了顯示一個Windows的多重文件介面以外,目前還沒有任何實際的用處,我們必須為它添加實際的功能。事實上,大多數Visual C++程式員都是在這個應用程式架構的基礎上從事添加各種功能模組的工作,包括設計自己的類,編寫具有一定功能的成員函數。
Visual C++的整合式開發環境向使用者提供了一個功能很強的操作類的工具—ClassWizard,我們可以利用該工具非常方便地嚮應用程式中添加類、向類中添加訊息處理函數、成員函數、以及新增成員變數等。利用ClassWizard,我們再也不用手工編寫那些繁瑣的代碼,只需使用簡單的滑鼠和鍵盤操作就能夠完成大量的工作,相當於用機器製造機器。
一 ClassWizard簡介
從字面上看,Class是類的意思,而Wizard則是“智者”的意思,兩者合起來,ClassWizard的意思就是智能地操作類的工具。
在Visual C++ 6.0的整合式開發環境中,ClassWizard最能體現它的特徵。與AppWizard類似,ClassWizard也能自動產生程式碼,只是兩者產生的對象不同,AppWizard主要用來建立應用程式的架構,而ClassWizard則主要是在應用程式架構的基礎上建立和編輯各種類。
ClassWizard既可以操作由AppWizard在應用程式架構中建立的類,又可以操作後來由ClassWizard自己添加的類。利用ClassWizard可以很輕鬆地完成一些最基本、最普通的工作,如在自己的應用程式中建立新類、映射訊息為其添加訊息處理函數、覆蓋虛擬函數、將對話方塊中的控制項與某個變數相關聯等。
ClassWizard只能用於使用MFC類庫的應用程式中。
ClassWizard可以完成的主要功能如下:
◆ 建立新類。這是ClassWizard最基本的用途之一。建立的新類由一些主要的基類派生而來,這些基類用於處理Windows的訊息,對一般使用者來說,這些基類已經足夠了。
◆ 進行訊息映射。這些訊息主要和視窗、菜單、工具列、對話方塊、控制項以及加速鍵相關聯。
◆ 新增成員變數。利用ClassWizard,可以很方便地向類中新增成員變數,並將這些成員變數與對話方塊或視窗中的控制項關聯起來,當控制項的值改變時,所對應的成員變數的值也跟著發生變化。
◆ 覆蓋虛擬函數。使用ClassWizard可以方便地覆蓋基類中定義的虛擬函數。
二 ClassWizard操作說明
在剛進入Visual C++ 整合式開發環境時,功能表項目View|ClassWizard是灰化禁止的,只有在開啟一個工作區檔案後,該功能表項目才能正常顯示,表明該選項是可用的。
首先開啟以前建立的多文檔應用程式FirstApp,再選擇功能表項目View|ClassWizard,即可啟動ClassWizard,進入ClassWizard環境,ClassWizard是一個對話方塊,其中包含五個選項卡,分別為:Message Maps、Member Variables、Automation、ActiveX Events、以及Class Info。它們針對不同的對象完成不同的任務。
1. Message Maps選項卡
它是ClassWizard對話方塊中最重要的選項卡,主要完成建立新類、添加、刪除訊息處理函數等任務。
該選項卡中包含了兩個下拉式清單方塊:Project下拉式清單方塊和Class name下拉式清單方塊;三個列表框:Object IDs列表框、Message列表框和Member functions列表框;一個文本資訊框;四個工具按鈕。
★ Project下拉式清單方塊:該下拉式清單方塊用於選擇當前操作的項目。噹噹前開啟的工作區中包含多重專案檔案時,使用者可以從這個下拉式清單方塊中選擇將要操作的專案檔。對於單項目工作區來說,其預設值就是專案檔。
★ Class name下拉式清單方塊:該下拉式清單方塊用於選擇當前要操作的類。當使用者在Class name下拉式清單方塊中選中了某個類之後,Object IDs視窗中的內容將會發生相應的變化。
★ Object IDs列表框:該列表框用於顯示當前選定類中能夠產生訊息的對象的ID值。這些對象包括菜單選項、工具列按鈕選項、對話方塊以及各種控制項等。
通常Object IDs列表框中所包含的第一個對象就是當前類名。
★ Message列表框:Message列表框中列出了對應於Object IDs列表框中所選中的當前項可以處理的訊息以及可被重寫的MFC虛函數。當Object IDs列表框中選定當前類名時,Message列表框前部分顯示的是當前類所能覆蓋的虛擬函數,後部分顯示的是能夠處理的訊息。如Object IDs列表框中選定其它對象,則Message列表框顯示的就是當前項可以處理的訊息。
★ Member functions列表框:Member functions列表框中列出了在Class name下拉式清單方塊中所選中的當前類包含的所有成員函數。其中用字母“V”標出的是MFC虛函數,用字母“W” 標出的是Windows訊息處理函數。
★ 文本資訊框:在Project下拉式清單方塊的下方有一個文本資訊框,用於顯示當前選中類的源檔案,包括.h檔案和.cpp檔案。該文本資訊框中顯示的內容會隨著選定類的變化而變化。
★ Add Class按鈕:該按鈕用於向當前的Project中添加一個新類,新類可以是自己建立,也可以是從已有的檔案中選取。
★ Add Function按鈕:該按鈕用於向當前選定類中為當前選定的訊息添加一個訊息處理函數。其中類是在Class name下拉式清單方塊中選定的類;而當前訊息則是在Message列表框中選定的訊息。
Add Function按鈕平時是灰化禁止的,只有當使用者在Message列表框中選中某個特定的訊息之後,該按鈕才能正常顯示,即此時才能使用。
★ Delete Function按鈕:該按鈕用於在當前選定的類中刪除已有的成員函數。Delete Function按鈕平時是灰化禁止的,只有當使用者在Member functions列表框中選中某個訊息處理函數之後,才能選擇該按鈕。
★ Edit Code按鈕:單擊該按鈕將開啟編輯視窗,並將游標位置自動跳到當前選定的成員函數的原始碼處。
2. Member Variables選項卡
該選項卡主要用於添加與對話方塊中的控制項相關聯的成員變數,以便程式能利用這些成員變數與對話方塊中的控制項進行資料交換。該選項卡與Message Maps選項卡一樣,也包含Project下拉式清單方塊和Class name下拉式清單方塊,分別用於選定使用者操作的當前項目和當前類;Add Class按鈕用於向當前項目中添加一個新類;一個文本資訊框,用於顯示當前選中類的源檔案。
此外,Member Variables選項卡中還包含另一個列表框以及另外四個工具按鈕。列表框中共有3列資料,分別為:
★ Control IDs:該項顯示了當前選定類中能夠映射成員變數的控制項的ID值。所謂能映射成員變數的控制項,就是可以使用類中的成員變數來代表某個控制項,當控制項發生改變時,該成員變數的值也發生相應變化。
★ Type:該項表示成員變數的類型。
★ Member:該項表示成員變數的名字。
注意:並不是所有的類都有這些資訊,只有在選擇了對話方塊類、有格式視圖類或記錄視圖類時才能顯示出這些資訊。
★ Add Variable按鈕:該按鈕用於為當前選定的控制項添加一個成員變數。
★ Delete Variable按鈕:該按鈕用於刪除一個現有的成員變數。該按鈕平時是灰化禁止的,只有當使用者在Control IDs列表框中選中某個成員變數以後,才能選擇該按鈕執行刪除工作。
★ Update Columns按鈕:該按鈕用於選定一個資料來源,只在記錄集合類中才可以使用。
★ Bind All按鈕:只適用於記錄集合類,單擊此按鈕將把所有未綁定的記錄集裡的資料成員綁定到資料來源的一個表中相應的列上。在預設情況下,MFC AppWizard和ClassWizard將綁定所有的列,所以很少需要使用資料繫結。如果通過刪除相關的資料成員將一些或所有列取消綁定,那麼在這之後還可以重新綁定它們。
3. Automation選項卡
該選項卡允許使用者加入方法或屬性以增強Automation功能。
4. ActiveX Events選項卡
該選項卡允許使用者加入事件以支援ActiveX控制項。
5. Class Info選項卡
該選項卡用於顯示和設定當前選定類中的一些重要訊息。
三 使用ClassWizard建立新類
使用ClassWizard最重要的作用就是建立新類,使用者將不必手工添加建立類所需的大量代碼,只需指定一些關於新類的重要訊息,ClassWizard將自動為你產生這些代碼。
下面以應用程式FirstApp為例說明建立過程。步驟如下:
(1) 首先開啟FirstApp的項目工作區。
(2) 點擊功能表項目View|ClassWizard,進入ClassWizard對話方塊。
(3) 在Message Maps選項卡中選擇功能按鈕Add Class,並從其下拉選項欄中單擊New選項,將會開啟New Class對話方塊。
(4) 首先在Name欄中鍵入新類的名稱,如FirstButton。此時我們將看到在下面的File name欄中顯示出ClassWizard自動為新類定義的預設檔案名稱:FirstButton.cpp。如果你不想要這個名字,也可以單擊Change按鈕對檔案名稱進行修改。
(5) 接下來應當設定新類的基類,即該類是由什麼類派生而來的。在Base class下拉式清單方塊中選中所需的基類名,如CButton。
(6) 如果你建立的基類需要對話方塊或其它資源,則應當在Dialog ID框中選擇一個資源ID值。
(7) Automation組框用於設定類的自動化資訊,這隻適用於能夠自動化的類,即由CCmdTarget所派生的類,我們保持其預設選擇None。
(8) 最後單擊OK按鈕結束。
至此我們已經成功地向項目中添加了一個新類FirstButton。
回到Visual C++的主視窗中,我們將發現在FirstApp的項目工作區中發生了一些變化。開啟ClassView選項卡,將看到一個新類FirstButton已經被添加到該項目的類列表中了。同時在FirstView選項卡中將發現FirstApp項目中新增加了兩個檔案:FirstButton.h,FirstButton.cpp。
四 使用ClassWizard添加訊息處理函數
使用ClassWizard來為類添加訊息處理函數,使用者將不需要手工編寫訊息映射所需的各種訊息宏,這樣大大減輕了工作量。
本節將以FirstApp應用程式為例來添加訊息處理函數,處理使用者在視圖中的單擊滑鼠操作。步驟如下:
(1) 首先開啟FirstApp的項目工作區。
(2) 點擊功能表項目View|ClassWizard,進入ClassWizard對話方塊。
(3) 選擇Message Maps選項卡,在Project下拉式清單方塊中選擇項目名FirstApp,在Class name下拉式清單方塊中選擇類名CFirstAppView。
(4) 在Object IDs列表框中選擇對象ID為CFirstAppView。
(5) 在Message列表框中選擇需要處理的訊息為WM_LBUTTONDOWN,即按下滑鼠左鍵訊息。
(6) 此時會發現Add Function按鈕已經可用。單擊此按鈕,ClassWizard將選中訊息的處理函數添加到Member Functions列表框中。在本例中,對應WM_LBUTTONDOWN訊息的處理函數是OnLButtonDown()。
(7) 最後單擊OK按鈕結束。
注意:當使用者為一些標準的Windows訊息添加訊息處理函數時,ClassWizard一般會自動地為你建立一個預設的訊息處理函數名。而當使用者為非標準訊息添加處理函數時,ClassWizard將彈出一個對話方塊,並給出一個預設的函數名,使用者可以重新命名該訊息響應函數。
在Visual C++的主視窗中開啟項目工作區的ClassView選項卡,並開啟CFirstAppView類的成員列表,就會發現訊息處理函數OnLButtonDown()已經被添加進去了。
同時,通過查看檔案,將會看到在CFirstAppView類的標頭檔FirstAppView.h中新加了訊息處理函數OnLButtonDown()的聲明。
可以看到該函數體是空的,其中只調用了一個其父類的成員函數,並且ClassView為使用者產生了一些重要的注釋行,以提示使用者在何處添加自己的代碼。
五 使用ClassWizard新增成員變數
成員變數也是類中不可或缺的組成部分,用於儲存類的資訊,我們將利用ClassView來為類新增成員變數。具體步驟如下:
(1) 首先開啟FirstApp的項目工作區。
(2) 點擊功能表項目View|ClassWizard,進入ClassWizard對話方塊。
(3) 在ClassWizard對話方塊中選擇Member Variables選項卡,在Project下拉式清單方塊中選擇當前項目名FirstApp,在Class name下拉式清單方塊中選擇當前類名CAboutDlg。此時在Controls IDs列表框中將顯示該類中包含的控制項ID:“IDOK”,這個ID值對應於About對話方塊中的OK按鈕。
(4) 單擊Add Variables按鈕,將開啟Add Member Variables對話方塊。有3個控制項用來設定新成員變數的一些重要訊息。
◆ Member variables name文字框:該文字框用來輸入新成員變數的名字,在預設情況下,ClassWizard提供“m_”這個首碼以便將這個變數確認為成員變數。
◆ Category下拉式清單方塊:該下拉式清單方塊用於指定新變數是一個“Value”類型的成員變數還是一個“Control”類型的成員變數。對於標準的Windows控制項來說,選擇Value可以建立一個包含由使用者來輸入控制項文本和控制項狀態的成員變數。而當使用者選中Control選項時,就可以建立一個“Control”類型的變數,我們可以對這個控制項直接進行訪問。
◆ Variable type下拉式清單方塊:該下拉式清單方塊用於選擇變數的資料類型。
(5) 在Member variables name欄中輸入變數名m_ok;在Category欄中選擇該變數的類型:copntrol類型;在Variable type欄中選擇該變數的資料類型CButton。
(6) 單擊OK按鈕退出,這時我們可以看到,ClassWizard對話方塊中發生了改變。
開啟FirstApp程式的項目工作區,可以看到,在CAboutDlg類的資料成員中,新增加了一個成員變數:m_ok。在CAboutDlg類的成員函數DoDataExchange()中,也添加了一條語句來映射控制項ID值IDOK和成員變數m_ok:
DDX_Control(pDX, IDOK, m_ok);
六 使用ClassWizard覆蓋虛擬函數
我們還可以使用ClassWizard來覆蓋基類中定義的虛擬函數,方法如下:
(1) 開啟ClassWizard對話方塊的Message Maps選項卡。
(2) 在Class name下拉式清單方塊中選擇一個類名來作為當前類。如CFirstAppView。
(3) 在Object Ids列表框中再次選擇該類名,如CFirstAppView。此時在Message列表框中將列出所有可以覆蓋的虛擬函數名和所有可操作的Windows訊息。
(4) 在Message列表框中選擇所要覆蓋的虛擬函數,如OnPaint()。
(5) 單擊Add Function按鈕覆蓋基類的該虛擬函數。此時在Member functions列表框中將顯示虛擬函數名OnPaint()。注意在此函數前有一個“V”字母,表示該函數是一個虛擬函數。
(6) 單擊OK按鈕結束。
我們在標頭檔FirstAppView.h中可看到該虛擬函數的定義:
virtual void OnPaint(CDC * pDC, CPrintInfo * pInfo);
同時在實現函數FirstAppView.cpp中可看到該虛擬函數的函數體:
void CFirstAppView::OnPaint(CDC * pDC, CPrintInfo * pInfo)
{
//在此處加上專門代碼或調用基類
CView::OnPaint(pDC, pInfo);
}