




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第8章數(shù)據(jù)庫(kù)編程用數(shù)據(jù)庫(kù)方式來(lái)管理日常生活中大量的信息已變得越來(lái)越重要,并出現(xiàn)了許多數(shù)據(jù)庫(kù)管理系統(tǒng),如MicrosoftAccess,MicrosoftSQLServer,OracleServer等,盡管這些系統(tǒng)能進(jìn)行數(shù)據(jù)庫(kù)的管理,但卻不能開(kāi)發(fā)出其它功能強(qiáng)大的Windows應(yīng)用程序。而VisualC++能將關(guān)系數(shù)據(jù)庫(kù)與面向?qū)ο蟮木幊谭椒ㄓ袡C(jī)地結(jié)合起來(lái),使得數(shù)據(jù)庫(kù)處理和應(yīng)用程序開(kāi)發(fā)都能很好地兼顧。VisualC++6.0為用戶(hù)提供了ODBC、DAO及OLEDB三種數(shù)據(jù)庫(kù)方式,這三種方式中最簡(jiǎn)單、最常用的是ODBC。因而我們重點(diǎn)介紹MFC的ODBC編程方法和技巧,并介紹一些用于數(shù)據(jù)庫(kù)的ACtiveX控件。8、1MFC的ODBC數(shù)據(jù)庫(kù)概述ODBC(OpenDatabaseConneCtivity開(kāi)放數(shù)據(jù)庫(kù)連接),是一種使用SQL的程序設(shè)計(jì)接口,使用ODBC能使用戶(hù)編寫(xiě)數(shù)據(jù)庫(kù)應(yīng)用程序變得容易、簡(jiǎn)單、避免了與數(shù)據(jù)源相連接的復(fù)雜性。在VisualC++中,MFC的ODBC數(shù)據(jù)庫(kù)類(lèi)CDatabase(數(shù)據(jù)庫(kù)類(lèi))、CRecordSet(記錄集類(lèi))和CRecordView(記錄視圖類(lèi))可為用戶(hù)管理數(shù)據(jù)庫(kù)提供切實(shí)可行的解決方案。用MFCAppWizard(exe)創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)處理的SDI/MDI程序,只需在向?qū)У牡诙街羞x中“Databaseviewwithoutfilesupport"或“Databaseviewwithfilesupport”即可。當(dāng)然,在創(chuàng)建之前預(yù)先構(gòu)造好一個(gè)數(shù)據(jù)庫(kù),然后進(jìn)行ODBC的數(shù)據(jù)源定義。8、1、1數(shù)據(jù)庫(kù)基本概念1、 數(shù)據(jù)庫(kù)和DBMS數(shù)據(jù)庫(kù)是指以一定的組織形式存放在計(jì)算機(jī)存儲(chǔ)介質(zhì)上的相互關(guān)聯(lián)的數(shù)據(jù)集合。例如,把一個(gè)學(xué)校的教師、學(xué)生和課程等數(shù)據(jù)有序地組織起來(lái),存儲(chǔ)在計(jì)算機(jī)磁盤(pán)上,就構(gòu)成了一個(gè)數(shù)據(jù)庫(kù)。為了有效地管理數(shù)據(jù)庫(kù),常常需要一些數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)為用戶(hù)提供對(duì)數(shù)據(jù)庫(kù)操作的各種命令、工具及方法,包括數(shù)據(jù)庫(kù)的建立和記錄的輸入、修改、檢索、顯示、刪除和統(tǒng)計(jì)等。流行的DBMS都提供一個(gè)SQL接口。2、 SQL(結(jié)構(gòu)化查詢(xún)語(yǔ)言)作為用在DBMS中訪(fǎng)問(wèn)和操作的語(yǔ)言,SQL(結(jié)構(gòu)化查詢(xún)語(yǔ)言)語(yǔ)句分為2類(lèi):一類(lèi)是DDL(DataDefinitionLanguage,數(shù)據(jù)定義語(yǔ)句,它用于創(chuàng)建表、索引等,另一類(lèi)是DML(DataManipulationLanguage,數(shù)據(jù)操作語(yǔ)言)語(yǔ)句,這些語(yǔ)句用于讀取數(shù)據(jù)、更新數(shù)據(jù)和執(zhí)行其他類(lèi)似操作的語(yǔ)句。3、 ODBC、DAO和OLEDBVisualC++為用戶(hù)提供了ODBC(OpenDatabaseConnectivity,開(kāi)放數(shù)據(jù)庫(kù)連接)、DAO(DataAccessObjects,數(shù)據(jù)訪(fǎng)問(wèn)對(duì)象)及OLEDB(OLEDataBase,OLE數(shù)據(jù)庫(kù))3種數(shù)據(jù)庫(kù)方式,使用戶(hù)的應(yīng)用程序從特定的數(shù)據(jù)管理系統(tǒng)(DBMS)脫離出來(lái)。ODBC提供了應(yīng)用程序接口(API),使得任何一個(gè)數(shù)據(jù)庫(kù)都可以通過(guò)ODBC驅(qū)動(dòng)器與指定的DBMS相聯(lián)。用戶(hù)的程序可以通過(guò)調(diào)用ODBC驅(qū)動(dòng)管理器中相應(yīng)的驅(qū)動(dòng)程序達(dá)到管理數(shù)據(jù)庫(kù)的目的。作為MicrosoftWindowsOpenStandardsArchitecture(WOSA,Windows開(kāi)放式服務(wù)體系結(jié)構(gòu))的主要組成部分,ODBC一直沿用至今。DAO類(lèi)似于用MicrosoftAccess或MicrosoftVisualBasic編寫(xiě)的數(shù)據(jù)庫(kù)應(yīng)用程序,它使用Jet數(shù)據(jù)庫(kù)引擎形成一系列的數(shù)據(jù)訪(fǎng)問(wèn)對(duì)象:數(shù)據(jù)庫(kù)對(duì)象、表和查詢(xún)對(duì)象、記錄集對(duì)象等。它可以打開(kāi)一個(gè)Access數(shù)據(jù)庫(kù)文件(MDB文件),也可直接打開(kāi)一個(gè)ODBC數(shù)據(jù)源以及使用Jet引擎打開(kāi)一個(gè)ISAM(被索引的順序訪(fǎng)問(wèn)方法)類(lèi)型的數(shù)據(jù)源(dBASE、FoxPro、Paradox、Excel或文本文件)。OLEDB試圖提供一種統(tǒng)一的數(shù)據(jù)訪(fǎng)問(wèn)接口,并能處理除了標(biāo)準(zhǔn)關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)之外,還能處理包括郵件數(shù)據(jù)、Web上的文本或圖形、目錄服務(wù)(DirectoryServices)以及主機(jī)系統(tǒng)中的IMS和VSAM數(shù)據(jù)。OLEDB提供一個(gè)數(shù)據(jù)庫(kù)編程COM(組件對(duì)象模型)接口,使得數(shù)據(jù)的使用者(應(yīng)用程序)可以使用同樣的方法訪(fǎng)問(wèn)各種數(shù)據(jù),而不用考慮數(shù)據(jù)的具體存儲(chǔ)地點(diǎn)、格式或類(lèi)型。這個(gè)COM接口與ODBC相比,其健壯性和靈活性要高得多。但是,由于OLEDB的程序比較復(fù)雜,因而對(duì)于一般用戶(hù)來(lái)說(shuō)使用ODBC和DAO方式已能滿(mǎn)足一般數(shù)據(jù)庫(kù)處理的需要。4、ADOADO是目前在Windows環(huán)境中比較流行的客戶(hù)端數(shù)據(jù)庫(kù)編程技術(shù)。它是Microsoft為最新和最強(qiáng)大的數(shù)據(jù)訪(fǎng)問(wèn)范例OLEDB而設(shè)計(jì)的,是一個(gè)便于使用的應(yīng)用程序?qū)咏涌?。ADO使用應(yīng)用程序能夠通過(guò)“OLEDB提供者“訪(fǎng)問(wèn)和操作數(shù)據(jù)庫(kù)服務(wù)器中的數(shù)據(jù)。由于它兼有強(qiáng)大的數(shù)據(jù)處理功能(處理各種不同類(lèi)型的數(shù)據(jù)源、分布式的數(shù)據(jù)處理等)和極其簡(jiǎn)單、易用的編程接口,因而得到了廣泛的應(yīng)用。ADO技術(shù)基于COM(ComponentObjiectModel,組件對(duì)象模型),具有COM組件的許多優(yōu)點(diǎn),可以用于構(gòu)造可復(fù)用應(yīng)用框架,被許多種語(yǔ)言支持,能夠訪(fǎng)問(wèn)包括關(guān)系數(shù)據(jù)庫(kù)、非關(guān)系數(shù)據(jù)庫(kù)及所有的文件系統(tǒng)。另外,ADO還支持各種B/S與基于Web的應(yīng)用程序,具有遠(yuǎn)程數(shù)據(jù)服務(wù)RDS(RemoteDataService)的特性,是遠(yuǎn)程數(shù)據(jù)存取的發(fā)展方向。8、1、2MFCODBC向?qū)н^(guò)程用MFCAppWizard使用ODBC數(shù)據(jù)庫(kù)的一般過(guò)程是:(1)用Access或其他數(shù)據(jù)庫(kù)工具構(gòu)造一個(gè)數(shù)據(jù)庫(kù);(2)在Windows中為剛才構(gòu)造的數(shù)據(jù)庫(kù)定義一個(gè)ODBC數(shù)據(jù)源;(3)在創(chuàng)建數(shù)據(jù)庫(kù)處理的文檔應(yīng)用程序向?qū)е羞x擇數(shù)據(jù)源;(4)設(shè)計(jì)界面,并使控件與數(shù)據(jù)表字段關(guān)聯(lián)。1、設(shè)計(jì)數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)表與表之間的關(guān)系構(gòu)成了一個(gè)數(shù)據(jù)庫(kù)。這里我們用MicrosoftAccess創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)Student.mdb,其中包含兩個(gè)表xs和zy,如下表所示:表1:學(xué)生表(xs,及其表結(jié)構(gòu)學(xué)號(hào)(stuid)姓名(name)性別(sex)專(zhuān)業(yè)代號(hào)(profcode)990101李林男102001990102高山男102001990201王平男109003990202丁玲女109003續(xù)表1:序號(hào)字段名稱(chēng)數(shù)據(jù)類(lèi)型字段大小小數(shù)位字段含義1stuid文本6學(xué)號(hào)2name文本8姓名3sex文本2性別4profcode文本6專(zhuān)業(yè)代號(hào)
表2:專(zhuān)業(yè)代碼表(zy)及其表結(jié)構(gòu)專(zhuān)業(yè)代號(hào)(profcode)專(zhuān)業(yè)名稱(chēng)(profname)學(xué)制(stuyears)102001計(jì)算機(jī)科學(xué)與技術(shù)4102002計(jì)算機(jī)軟件技術(shù)3102003計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)3102004計(jì)算機(jī)軟件工程4109003計(jì)算機(jī)網(wǎng)絡(luò)工程4續(xù)表2:序號(hào)字段名稱(chēng)數(shù)據(jù)類(lèi)型 字段大小小數(shù)位字段含義1profcode文本 6專(zhuān)業(yè)代號(hào)2profname文本 12專(zhuān)業(yè)名稱(chēng)3stuyears數(shù)字 整型 自動(dòng)學(xué)制下面我們開(kāi)始用Access2003設(shè)計(jì)數(shù)據(jù)庫(kù):(1)開(kāi)機(jī)正常屏幕狀態(tài)T開(kāi)始T程序->MicrosoftOffice—MicrosoftOfficeAccess2003T新建文件—空數(shù)據(jù)庫(kù)—文件名處寫(xiě):student—點(diǎn)右邊的創(chuàng)建—新建—設(shè)計(jì)視圖—確定—出現(xiàn)表,你按上面的續(xù)表1即下面數(shù)據(jù)敲入即可:字段名稱(chēng)數(shù)據(jù)類(lèi)型(在下面改變)字段大小說(shuō)明stuid文本6學(xué)號(hào)name文本8姓名sex文本2性別profcode文本6專(zhuān)業(yè)代號(hào)(2)關(guān)閉此表—提問(wèn):你是否保存對(duì)表1的設(shè)計(jì)更改?—是—表名寫(xiě)xs—是—便在數(shù)據(jù)庫(kù)中建立了表xs(3)你雙擊xs出現(xiàn)設(shè)計(jì)視圖表,之后你按上面的表1即下面的數(shù)據(jù)敲進(jìn)去學(xué)號(hào)姓名性別專(zhuān)業(yè)代號(hào)990101李林男102001990102高山男102001990201王平男109003990202丁玲女1090034)接著你再點(diǎn)本界面上面的菜單新建—設(shè)計(jì)視圖—確定,重復(fù)(2)步驟再建表zy敲入續(xù)表2即下面數(shù)據(jù):字段名稱(chēng)數(shù)據(jù)類(lèi)型(在下面改變)字段大小說(shuō)明profcode文本6專(zhuān)業(yè)代號(hào)profname文本12專(zhuān)業(yè)名稱(chēng)stuyears文本整型學(xué)制(5)你雙擊zy出現(xiàn)設(shè)計(jì)視圖表,之后你按表2即下面的數(shù)據(jù)敲進(jìn)去專(zhuān)業(yè)代號(hào)專(zhuān)業(yè)名稱(chēng)學(xué)制102001計(jì)算機(jī)科學(xué)4102002計(jì)算機(jī)軟件技術(shù)3102003計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)3102004計(jì)算機(jī)軟件工程4109003計(jì)算機(jī)網(wǎng)絡(luò)工程42、創(chuàng)建ODBC的數(shù)據(jù)源用戶(hù)安裝VisualC++的同時(shí)也會(huì)裝上ODBC程序,但它不是出現(xiàn)在VisualC++程序組中,而是出現(xiàn)在系統(tǒng)的“控制面板”中,如書(shū)336頁(yè)圖8.1所示。桌面左下角T開(kāi)始T設(shè)置T控制面板T性能和維護(hù)->管理工具T雙擊ODBC圖標(biāo),進(jìn)入ODBC數(shù)據(jù)源管理器,在這里用戶(hù)可以設(shè)置ODBC數(shù)據(jù)源的一些信息,其中的“用戶(hù)DNS”頁(yè)面是用戶(hù)定義自己在本地計(jì)算機(jī)使用的數(shù)據(jù)源名(DNS)如書(shū)336頁(yè)圖8.2所示。(1) 單擊[添加]按鈕,彈出有一驅(qū)動(dòng)程序列表的“創(chuàng)建新數(shù)據(jù)源”對(duì)話(huà)框,如書(shū)336頁(yè)圖8.3所示(2) 在該對(duì)話(huà)框中選擇要添加用戶(hù)數(shù)據(jù)源的驅(qū)動(dòng)程序,這里選擇“MicrosoftAccessDriver”。單擊[完成]按鈕,進(jìn)入特定驅(qū)動(dòng)程序的安裝對(duì)話(huà)框。(3) 在對(duì)話(huà)框中,單擊[選?。莅粹o將前面創(chuàng)建的數(shù)據(jù)庫(kù)student調(diào)入,見(jiàn)下圖所示。(4)單擊[確定]按鈕,給剛才創(chuàng)建的用戶(hù)數(shù)據(jù)源起名“DatabaseExmpleForVC++”寫(xiě)在數(shù)據(jù)源名處,見(jiàn)書(shū)337頁(yè)圖8.4所示,單擊[確定]便使其添加在“ODBC數(shù)據(jù)源管理器”的“用戶(hù)數(shù)據(jù)源”列表中,如書(shū)337頁(yè)圖8.5所示。3、在MFCAppWizard中選擇數(shù)據(jù)源用MFCAppWizard(exe)可以很容易地創(chuàng)建一個(gè)支持?jǐn)?shù)據(jù)庫(kù)的SDI/MDI的應(yīng)用程序,過(guò)程如下:(1) 用MFCAppWizard(exe)創(chuàng)建一個(gè)單文檔應(yīng)用程序:數(shù)據(jù)庫(kù)(2) 在向?qū)У牡?步對(duì)話(huà)框中加入數(shù)據(jù)庫(kù)的支持,如書(shū)337頁(yè)圖8.6所示。在該對(duì)話(huà)框中用戶(hù)可以選擇對(duì)數(shù)據(jù)庫(kù)支持程序,其中各選項(xiàng)的區(qū)別如書(shū)表8.2所示。(3) 選中“數(shù)據(jù)庫(kù)查看使用文件支持Databaseviewwithfilesupport”項(xiàng),單擊[DataSource]按鈕,彈出“DatabaseOptions”對(duì)話(huà)框,如書(shū)338頁(yè)圖8.7所示。(4) 從中選擇你剛才起好名的ODBC的數(shù)據(jù)源“DatabaseExampleForVC++”,單擊[OK]按鈕,彈出如書(shū)338頁(yè)圖8.8所示的“SelectDatabaseTable”對(duì)話(huà)框,從中選擇要使用的表(選擇xs我們建的表名和書(shū)上的表名不一樣)。(5) 單擊[OK]按鈕,又回到了向?qū)У牡?步對(duì)話(huà)框,保留默認(rèn)設(shè)置,單擊[Finish]按鈕。(6) 編譯運(yùn)行結(jié)果如書(shū)339頁(yè)圖8.9所示。說(shuō)明:MFCAppWizard創(chuàng)建的“數(shù)據(jù)庫(kù)”應(yīng)用程序與一般默認(rèn)的單文檔應(yīng)用程序相比較,在類(lèi)結(jié)構(gòu)方面,有如下幾點(diǎn)不同:1)添加了一個(gè)CMySet類(lèi),它與上述過(guò)程中所選擇的數(shù)據(jù)表xs進(jìn)行數(shù)據(jù)綁
定,也就是說(shuō),CMySet對(duì)象的操作實(shí)質(zhì)上對(duì)數(shù)據(jù)表進(jìn)行操作。2) 將CMyView類(lèi)的基類(lèi)設(shè)置成CRecordView,由于CRecordView的基類(lèi)是CFormView,因此它需要與之相關(guān)聯(lián)的表單資源。3) 在CMyView類(lèi)中添加了一個(gè)全局的CMySet對(duì)象指針變量m_pSet,目的是在表單視圖和記錄集之間建立聯(lián)系,使得記錄集中的查詢(xún)結(jié)果能夠很容易地在表單視圖上顯示出來(lái)。4、設(shè)計(jì)瀏覽記錄界面在“數(shù)據(jù)庫(kù)”應(yīng)用程序中,MFC為用戶(hù)自動(dòng)創(chuàng)建了用于瀏覽數(shù)據(jù)表記錄的工具按鈕和相應(yīng)的“記錄”選單項(xiàng)。若用戶(hù)選擇這些瀏覽記錄命令,系統(tǒng)會(huì)自動(dòng)調(diào)用相應(yīng)的函數(shù)來(lái)移動(dòng)數(shù)據(jù)庫(kù)表的當(dāng)前位置。若在表單視圖CMyView中添加控件并與表的字段相關(guān)聯(lián),就可以根據(jù)表的當(dāng)前記錄位置顯示相應(yīng)的數(shù)據(jù)。(1)打開(kāi)“數(shù)據(jù)庫(kù)”應(yīng)用程序(2)切換到項(xiàng)目工作區(qū)窗口的ResourceView頁(yè)面,雙擊用于表單視圖CMyView的對(duì)話(huà)框資源IDD_MY_FORM.3)參看下圖1向?qū)υ?huà)框中添加下列控件:控件組框靜態(tài)文本編輯框靜態(tài)文本編輯框靜態(tài)文本編輯框靜態(tài)文本編輯框ID號(hào)標(biāo)題默認(rèn) 學(xué)生表控件組框靜態(tài)文本編輯框靜態(tài)文本編輯框靜態(tài)文本編輯框靜態(tài)文本編輯框ID號(hào)標(biāo)題默認(rèn) 學(xué)生表默認(rèn) 學(xué)號(hào):IDC_STU_ID ……默認(rèn) 姓名:IDC_STU_NAME …默認(rèn) 性別IDC_STU_SEX …默認(rèn) 專(zhuān)業(yè)代號(hào)IDC_PROF_CODE …..屬性默認(rèn)S3無(wú)標(biāo)盞-數(shù)番庫(kù)文件(日編輯(日記錄?查看世-nx幫助(出□Q口?卜1學(xué)生表學(xué)號(hào):1姓名:丨性別:丨專(zhuān)業(yè)代號(hào): 1就緒大寫(xiě)數(shù)字圖1:控件的設(shè)計(jì)(4)加數(shù)據(jù)成員:選擇“View”選單->“ClassWizard”命令或按快捷鍵Ctrl+W,彈出ClassWizard對(duì)話(huà)框,切換到MemberVaribles頁(yè)面,在Classname框中選擇
CMyView,為上述控件添加相關(guān)聯(lián)的數(shù)據(jù)成員。與以往添加數(shù)據(jù)成員不同的是,這里添加的數(shù)據(jù)成員都是由系統(tǒng)自動(dòng)定義的,并與數(shù)據(jù)庫(kù)表字段相關(guān)聯(lián)。例如,雙擊IDC_PROF_CODE,在彈出的“AddMemberVariable”對(duì)話(huà)框中的成員變量下拉列表中選擇要添加的成員變量名m_pSet->m_profcode,如340頁(yè)圖8.11:(5)按上步添加成員變量的方法將下列表中所列控件依次添加相關(guān)聯(lián)的數(shù)據(jù)成員。控件ID號(hào)變量類(lèi)型變量名字符長(zhǎng)度IDC_PROF_CODECString->m_profcode6IDC_STU_NAMECString->m_name8IDC_STU_IDCString->m_stuid6IDC_STU_SEXCString->m_sex2注意:字符長(zhǎng)度應(yīng)與上面建地?cái)?shù)據(jù)庫(kù)表1的字段大小相同(6)編譯并運(yùn)行,結(jié)果如下圖2所示:S3無(wú)標(biāo)題-數(shù)番庫(kù) -文件(日編輯記錄?查看世W口X孑助(出□Q冒?學(xué)生表學(xué) 號(hào):■1990101姓 名:李林性 別:1男專(zhuān)業(yè)代號(hào):102001I就緒圖2:瀏覽記錄結(jié)果8.1.3ODBC數(shù)據(jù)表綁定更新(改變與m_pSet關(guān)聯(lián)的表)上述過(guò)程雖沒(méi)有添加任何代碼,但卻能瀏覽表中的記錄內(nèi)容。特別需要說(shuō)明的是,在生成的CMyView類(lèi)中,包含一個(gè)指向CMySet對(duì)象的指針m_pSet。該指針與用戶(hù)的表(這里是xs)相關(guān)聯(lián),它是由MFCAppWizard建立的,目的是在表單視圖和記錄集之間建立聯(lián)系,使得記錄集中的查詢(xún)結(jié)果很容易地在表單視圖上顯示出來(lái)。當(dāng)然,m_pSet所關(guān)聯(lián)的表也可通過(guò)ClassWizard來(lái)改變。其方法如下:(1) 將ClassWizard對(duì)話(huà)框切換到“MemberVariables"頁(yè)面,在“Classname”的下拉列表中選擇“CMyCSet",此時(shí)ClassWizard對(duì)話(huà)框的[UpdateColumns](重新指定與CRecordset類(lèi)相關(guān)的表)和[BindAll](為表的字段定義默認(rèn)的成員變量)按鈕被激活,如341頁(yè)圖8.14:(2) 單擊[UpdateColumns]按鈕,將彈出“DatabaseOptions"對(duì)話(huà)框,如書(shū)341頁(yè)圖8.15所示(3) 從中選擇ODBC的數(shù)據(jù)源“DatabaseExampleForVC++”,單擊[OK]按鈕,彈出如下圖3所示,從中選擇要使用的表。單擊[OK]按鈕,回到ClassWizard界面。如341頁(yè)圖8.17若表中的各個(gè)字段還沒(méi)有相應(yīng)的數(shù)據(jù)成員,可單擊[BindAll]按鈕進(jìn)行自動(dòng)設(shè)置。SelectDatabaseTables ?X圖3:“SelectDatabaseTables"對(duì)話(huà)框&2MFC的ODBC應(yīng)用編程上述過(guò)程雖沒(méi)有添加任何代碼,但卻能瀏覽表中的記錄內(nèi)容,這些MFCAppWizard創(chuàng)建的功能。但在MFCAppWizard創(chuàng)建的數(shù)據(jù)庫(kù)處理的基本程序框架中,只提供了程序和數(shù)據(jù)庫(kù)記錄之間的關(guān)系映射,卻沒(méi)有操作的完整界面。如果要增加操作功能,還必須加入一些代碼。這時(shí)就需要使用MFC提供的ODBC類(lèi):CDatabase(數(shù)據(jù)庫(kù)類(lèi))、CRecordSet(記錄集類(lèi))和CRecordView(可視記錄集類(lèi)。CDatabase類(lèi)用于提供對(duì)數(shù)據(jù)源的連接,通過(guò)它可以對(duì)數(shù)據(jù)源進(jìn)行操作CRecordView類(lèi)用于控制并顯示數(shù)據(jù)庫(kù)記錄,該視圖是直接連到一個(gè)CRecordSet對(duì)象的表單視圖CRecordSet類(lèi)是用戶(hù)最關(guān)心的,它為用戶(hù)提供了對(duì)表記錄進(jìn)行操作的許多功能,如:查詢(xún)記錄、添加記錄、刪除記錄、修改記錄等,并能直接為數(shù)據(jù)源中的表映射一個(gè)CRecordSet類(lèi)對(duì)象,方便用戶(hù)的操作。CRecordSet類(lèi)對(duì)象提供了從數(shù)據(jù)源中提取出表的記錄集,并提供了2種操作形式:動(dòng)態(tài)行集(Dynasets)和快照集(Snapshots)o動(dòng)態(tài)行集能與其他用戶(hù)所進(jìn)行的更改保持同步,而快照集則是數(shù)據(jù)的一個(gè)靜態(tài)視圖。這2個(gè)形式在記錄集被打開(kāi)時(shí)都提供一組記錄。所不同的是:當(dāng)在一個(gè)動(dòng)態(tài)行集里滾動(dòng)一條記錄時(shí),由其他用戶(hù)或應(yīng)用程序中的其他記錄對(duì)該記錄所進(jìn)行的更改會(huì)相應(yīng)地顯示出來(lái),而快照集則不會(huì)。下面從顯示記錄總數(shù)和當(dāng)前記錄號(hào)、查詢(xún)記錄、編輯記錄和處理多個(gè)表等幾個(gè)方面討論MFCODBC數(shù)據(jù)庫(kù)編程的方法和技巧。8.2.1顯示記錄總數(shù)和當(dāng)前記錄號(hào)在“數(shù)據(jù)庫(kù)編程”的記錄瀏覽過(guò)程中,用戶(hù)并不能知道表中的記錄總數(shù)及當(dāng)前的記錄位置,這就造成了交互的不完善,因此必須將這些信息顯示出來(lái)。這時(shí)就需要使用CRecordset類(lèi)的成員函數(shù)GetRecordCount和GetStatus,它們分別用來(lái)獲得表中的記錄總數(shù)和當(dāng)前記錄的索引,其原型如下:longGetRecordCount()const;voidGetStatus(CRecordsetStatus&rStatus)const;其中:參數(shù)rStatus是指向下列的CRecordsetStatus結(jié)構(gòu)的對(duì)象:structCRecordsetStatus{longm_lCurrentRecord;//當(dāng)前記錄的索引,0表示第一個(gè)記錄1表示第二個(gè)記錄//依次類(lèi)推,但-1表示第一記錄之前,-2表示不確定BOOLm_bRecordCountFinal;〃記錄總數(shù)是否是最終結(jié)果};需注意的是,GetRecordCount函數(shù)所返回的記錄總數(shù)在表打開(kāi)時(shí)或調(diào)用Requery函數(shù)后是不確定的,因而必須經(jīng)過(guò)下列的代碼才能獲得最終有效的記錄總數(shù):while(!m_pSet->lsEOF()){m_pSet->MoveNext();m_pSet->GetRecordCount();}例:顯示記錄信息(總的記錄數(shù)和當(dāng)前記錄數(shù))調(diào)入前面的“數(shù)據(jù)庫(kù)”單文檔應(yīng)用程序打開(kāi)MainFrm.cpp文件,將原先的indicators數(shù)組修改如下:staticUINTindicators[]={ID_SEPARATOR, //statuslineindicator第一個(gè)信息行窗口ID_SEPARATOR, //statuslineindicator第二個(gè)信息行窗口ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,};用ClassWizard為CMyView類(lèi)添加OnCommand消息處理函數(shù),并增加下列代碼。該函數(shù)先獲得狀態(tài)欄對(duì)象的指針,然后調(diào)用SetPaneText函數(shù)更新第2個(gè)窗格的文本。CStringstr;CMainFrame*pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;CStatusBar*pStatus=&pFrame->m_wndStatusBar;if(pStatus){CRecordsetStatusrStatus;m_pSet->GetStatus(rStatus);//獲得當(dāng)前記錄信息str.Format(”當(dāng)前記錄:%d/總記錄:%d",l+rStatus.m_lCurrentRecord,m_pSet->GetRecordCount());pStatus->SetPaneText(1,str);//更新第2個(gè)窗格的文本}在CMyView的OnInitialUpdate函數(shù)處添加下列代碼:while(!m_pSet->IsEOF())m_pSet->MoveNext();m_pSet->GetRecordCount();}m_pSet->MoveFirst();(5)#include"MainFrm.h"(6)將MainFrm.h文件中的保護(hù)型變量m_wndStatusBar變成公共變量。(7)編譯并運(yùn)行,見(jiàn)下面的狀態(tài)欄中,你若向前翻頁(yè),它就變化。有數(shù)據(jù)庫(kù)總條數(shù),和你翻的頁(yè)數(shù)。8.2.2查詢(xún)記錄使用CRecordSet類(lèi)的成員變量m_strFilter、m_strSort和成員函數(shù)Open可以對(duì)表進(jìn)行記錄的查詢(xún)和排序。示例如下圖4所示:酸無(wú)標(biāo)鑒-數(shù)垂庫(kù)文件(日編輯⑥記錄?-□X查看⑷幫助(也□學(xué)生表學(xué) 號(hào):119901011姓 名:李林性 別:|男專(zhuān)業(yè)代號(hào):102001學(xué) 號(hào)查詢(xún)就緒§前記錄:1/總記圖4:添加查詢(xún)控件在上面項(xiàng)目中,你打開(kāi)資源欄,點(diǎn)開(kāi)Dialog,雙擊IDD_MY_FORM,在學(xué)生表下面,加一靜態(tài)控件寫(xiě):要查詢(xún)的學(xué)號(hào),接著再加一個(gè)編輯控件,ID為:IDC_EDIT_QUERY,再加一個(gè)按鈕控件,ID號(hào)為:IDC_BUTTON_QUERYCaption標(biāo)題處寫(xiě):查詢(xún)打開(kāi)MFCClassWizard對(duì)話(huà)框,為控件IDC_EDIT_QUERY添加CString類(lèi)型的關(guān)聯(lián)變量m_strQuery。在View類(lèi)中添加按鈕控件IDC_BUTTON_QUERY的BN_CLICKED消息映射,并加下列代碼:voidCMyView::OnButtonQuery(){//TODO:AddyourcontrolnotificationhandlercodehereUpdateData();m_strQuery.TrimLeft();if(m_strQuery.IsEmpty())MessageBox("要查詢(xún)的姓名不能為空");return;}if(m_pSet->IsOpen())m_pSet->Close();〃如果記錄集打開(kāi),則先關(guān)閉m_pSet->m_strFilter.Format("stuid='%s'",m_strQuery);//stuid是xs表的字段名,用來(lái)指定查詢(xún)條件m_pSet->m_strSort="name";//name是xs表的字段名,用來(lái)按name字段從小到大排序m_pSet->Open();if(!m_pSet->IsEOF())〃如果打開(kāi)記錄集,有記錄UpdateData(FALSE);//自動(dòng)更新表中控件顯示的內(nèi)容elseMessageBox("沒(méi)有找到你要查找的名字!");}其中:m_strFilter和m_strSort是CRecordSet的成員變量,用來(lái)執(zhí)行條件查詢(xún)和排序。m_strFilter稱(chēng)為"過(guò)濾字符串",相當(dāng)于SQL語(yǔ)句中WHERE后的條件串。m_strSort稱(chēng)為"排序字符串",相當(dāng)于SQL語(yǔ)句中ORDERBY后的字符串。若字段的數(shù)據(jù)類(lèi)型是文本,則需要在m_strFilter字符串中用單引號(hào)將查詢(xún)的內(nèi)容括起來(lái);對(duì)于數(shù)字,則不需要用單引號(hào)。需要注意的是:只有在調(diào)用Open函數(shù)之前設(shè)置m_strFilter和m_strSort才能保證查詢(xún)和排序有效。如果有多個(gè)條件查詢(xún),則可以使用AND、OR、NOT來(lái)組合,例如:m_pSet->m_strFilter="stuid>='990103'ANDstdio<='990101'";需要說(shuō)明的是,如果查詢(xún)的結(jié)果有多條記錄,則可以用CRecordSet類(lèi)的MoveNext(下移一個(gè)記錄)、MovePrev(上移一個(gè)記錄)、MoveFirst(定位到第一個(gè)記錄)和MoveLast(定位到最后一個(gè)記錄)等函數(shù)來(lái)移動(dòng)當(dāng)前記錄位置進(jìn)行操作。(4)編譯運(yùn)行8.2.3編輯記錄CRecordset類(lèi)為用戶(hù)提供了編輯記錄所需要的成員函數(shù),但在編程時(shí)還應(yīng)注意兩個(gè)方面的內(nèi)容:理解“刪除”CRecordset類(lèi)的成員函數(shù)Delete只是將記錄進(jìn)行“邏輯”刪除,而不是“物理”刪除。邏輯刪除的記錄還可以恢復(fù),而物理刪除則不能??丶c字段數(shù)據(jù)成員的相互影響。在MFC創(chuàng)建的數(shù)據(jù)庫(kù)處理的應(yīng)用程序框架中,表的字段總是和系統(tǒng)定義的默認(rèn)數(shù)據(jù)成員相關(guān)聯(lián),例如表xs字段stuid與CMySet的m_stuid相關(guān)聯(lián)。另外,在表單視圖CMyView中添加一些控件用于記錄的瀏覽,其中控件IDC_STU_ID的成員變量也是CMySet的m_stuid,因而控件數(shù)據(jù)成員與字段數(shù)據(jù)成員必然相互影響。合理利用這些影響能簡(jiǎn)化編程,例如下面的代碼是用來(lái)增加記錄的:m_pSet->AddNew(); //在表的末尾增加新記錄UpdateData(TRUE); //將控件中的數(shù)據(jù)傳給字段數(shù)據(jù)成員m_pSet->Update(); //將新記錄存入數(shù)據(jù)庫(kù)m_pSet->MoveLast(); //將當(dāng)前記錄位置定位到最后一個(gè)記錄UpdateData(FALSE); //將字段數(shù)據(jù)成員的數(shù)據(jù)傳給控件,即在控件中顯示上述的相互影響有時(shí)也給編程帶來(lái)不便,因?yàn)樯圆涣羯窬蜁?huì)產(chǎn)生錯(cuò)誤。因此,在修改和添加記錄數(shù)據(jù)之前,往往設(shè)計(jì)一個(gè)對(duì)話(huà)框用以獲得所需要的數(shù)據(jù),然后用該數(shù)據(jù)進(jìn)行當(dāng)前記錄的編輯。這樣就能避免它們的相互影響,且保證代碼的相對(duì)獨(dú)立性。1、增加記錄增加記錄是使用AddNew函數(shù),但要求數(shù)據(jù)庫(kù)必須是以“可增加”的方式打開(kāi)的。以下代碼是在表的末尾增加新記錄:m_pSet->AddNew();〃在表的末尾增加新記錄m_pSet->SetFieldNull(&(m_pSet->m_studentno),FALSE)〃設(shè)定m_studentno值不〃為空(NULL)m_pSet->m_studentno=”21010503”;….. //輸入新的字段值m_pSet->Update();//將新記錄存入數(shù)據(jù)庫(kù)m_pSet->Requery();〃刷新記錄集,這在快照集方式下是必須的2、 刪除記錄可以直接使用CRecordSet::Delete函數(shù)來(lái)刪除記錄。需要說(shuō)明的是,要使刪除操作有效,還需要移動(dòng)記錄函數(shù)。例如下列代碼:CRecordsetStatusstatus;〃建立記錄狀態(tài)對(duì)象m_pSet->GetStatus(status);〃獲取當(dāng)前記錄狀態(tài)m_pSet->Delete(); //刪除當(dāng)前記錄if(status.m_lCurrentRecord==0)//若當(dāng)前記錄索引號(hào)為0(0表示第1條記錄)則m_pSet->MoveNext(); //下移一個(gè)記錄elsem_pSet->MoveFirst(); //移到第1個(gè)記錄處UpdateData(FALSE);3、 修改記錄函數(shù)CRecordSet::Edit可以用于修改記錄,例如:m_pSet->Edit(); //修改當(dāng)前記錄m_pSet->m_name=”劉向東”;〃修改當(dāng)前記錄字段值m_pSet->Update();//將修改結(jié)果存入數(shù)據(jù)庫(kù)m_pSet->Requery();4、 撤消操作如果用戶(hù)在進(jìn)行增加或者修改記錄后,希望放棄當(dāng)前操作,則在調(diào)用CRecordSet::Update函數(shù)之前調(diào)用CRecordSet::Move(AFX_MOVE_REFRESH)來(lái)撤消操作,便可恢復(fù)在增加或修改操作之前的當(dāng)前記錄。在編寫(xiě)程序時(shí)應(yīng)注意控件與字段數(shù)據(jù)成員的相互影響。在MFC創(chuàng)建的數(shù)據(jù)庫(kù)處理的應(yīng)用程序框架中,表的字段總是和系統(tǒng)定義的默認(rèn)數(shù)據(jù)成員相關(guān)聯(lián)。例如:本程序中,表xs字段stuid(學(xué)號(hào))與CMySet指針的m_stuid相關(guān)聯(lián)。而且,在表單視圖CMyView添加用于記錄內(nèi)容顯示的一些控件中,在定義其控件變量時(shí),使用的也是m_pSet中的成員變量。例如編輯框IDC_STU_ID定義的控件變量是m_pSet的m_stuid。雖然,共用同一個(gè)成員變量能簡(jiǎn)化編程,但有時(shí)也給編程帶來(lái)不便,稍不留神就會(huì)產(chǎn)生誤操作。例如以下代碼是用于增加一條記錄:m_pSet->AddNew();〃在表的末尾增加新記錄UpdateData(TRUE);//將控件中的數(shù)據(jù)傳給字段數(shù)據(jù)成員m_pSet->Update();〃將新記錄存入數(shù)據(jù)庫(kù)m_pSet->MoveLast();//將當(dāng)前記錄位置定位到最后一個(gè)記錄UpdateData(FALSE);/將字段數(shù)據(jù)成員的數(shù)據(jù)傳給控件,即在控件中顯示。由于增加和顯示記錄在同一界面中出現(xiàn),容易造成誤操作。因此,在修改和添加記錄數(shù)據(jù)之前,往往設(shè)計(jì)一個(gè)對(duì)話(huà)框用于獲得所需要的數(shù)據(jù),然后用該數(shù)據(jù)進(jìn)行當(dāng)前記錄的編輯。這樣就能避免它們的相互影響,且保證代碼的相對(duì)獨(dú)立性。例:在表單視圖中增加3個(gè)按鈕:[添加記錄]、[修改記錄]、[刪除記錄],如下圖5(書(shū)345頁(yè)圖8.20)所示:。單擊[添加記錄]或[修改記錄]都將彈出一個(gè)如下圖6(書(shū)345頁(yè)圖8.21)所示的對(duì)話(huà)框,在對(duì)話(huà)框中可以進(jìn)行數(shù)據(jù)的添加或修改,單擊對(duì)話(huà)框的[確定]按鈕則數(shù)據(jù)有效。(1)用前面的單文檔應(yīng)用程序:數(shù)據(jù)庫(kù)(2)切換到項(xiàng)目工作區(qū)窗口的ResourceView頁(yè)面,打開(kāi)用于表單視圖CMyView的對(duì)話(huà)框資源IDD_MY_FORM。參看下面圖7向表中添加3個(gè)按鈕:添加記錄(IDC_REC_ADD)、修改記錄(IDC_REC_EDIT)和刪除記錄(IDC_REC_DEL)。58無(wú)標(biāo)題數(shù)據(jù)庫(kù) -口X文件(日編揖⑥記錄?查看㈣幫助?□卜卜1骨添加記錄修改記錄姓名:李林性別:|男刪除記錄專(zhuān)業(yè)代號(hào):102001就緒妥章詞的學(xué) 號(hào)查詢(xún)5前記錄:盯總記壽圖5:記錄編輯添加一個(gè)對(duì)話(huà)框資源,打開(kāi)屬性對(duì)話(huà)框?qū)⑵渥煮w設(shè)置為“宋體9號(hào)”,標(biāo)題定為“學(xué)生表”ID設(shè)為IDD_STU_TABLE(添加、修改、刪除都彈出此對(duì)話(huà)框)將圖7表單中的控件復(fù)制到剛添加的對(duì)話(huà)框中(參看下圖8),并將[OK]和[Cancel]按鈕的標(biāo)題分別改為“確定”和“取消”圖中具有3D效果的豎直線(xiàn)是用靜態(tài)圖片控件(屬性為Frame,Etched)構(gòu)造的。雙擊對(duì)話(huà)框模板或按Ctrl+W快捷鍵,為對(duì)話(huà)框資源IDD_STU_TABLE創(chuàng)建一個(gè)對(duì)話(huà)框類(lèi)CStuDlg。Dialog[學(xué)生表——X學(xué)號(hào):j|姓名:!確定|性別:取消專(zhuān)業(yè)代號(hào):圖6:“學(xué)生表”(5)打開(kāi)ClassWizard的MemberVariables標(biāo)簽,在Classname中選擇CStuDlg,選中所需的控件ID號(hào),雙擊鼠標(biāo)或單擊AddVariables按鈕,依次為上圖控件的ID按下表中形式增加成員變量??丶蘒D號(hào)變量類(lèi)型變量名字符長(zhǎng)度IDC_PROF_CODECStringm_ProfCode6IDC_STU_IDCStringm_StuID6IDC_STU_NAMECStringm_StuName8IDC_STU_SEXCStringm_StuSex2(6)切換到ClassWizard的MessageMaps標(biāo)簽頁(yè),為CStuDlg中的控件IDOK增加BN_CLICKED的消息映射,并添加代碼:UpdateData(TRUE);(7)用ClassWizard為CMyView類(lèi)中的3個(gè)按鈕:IDC_REC_ADD,IDC_REC_EDIT和IDC_REC_DEL增加BN_CLICKED的消息映射,并添加下列代碼:voidCMyView::OnRecAdd(){//TODO:AddyourcontrolnotificationhandlercodehereCStuDlgdlg;//以下語(yǔ)句沒(méi)有dlg.m_StuID=m_pSet->m_stuid;//從這開(kāi)始是另加的dlg.m_StuName=m_pSet->m_name;〃使加上的學(xué)號(hào)、姓名、性別、專(zhuān)業(yè)代號(hào)dlg.m_StuSex=m_pSet->m_sex;//傳送到各自的成員變量中dlg.m_ProfCode=m_pSet->m_profcode;//到這為止if(dlg.DoModal()==IDOK){m_pSet->AddNew();m_pSet->m_stuid=dlg.m_StuID;m_pSet->m_name=dlg.m_StuName;m_pSet->m_sex=dlg.m_StuSex;m_pSet->m_profcode=dlg.m_ProfCode;m_pSet->Update();m_pSet->Requery();}voidCMyView::OnRecEdit(){//TODO:AddyourcontrolnotificationhandlercodehereCStuDlgdlg;dlg.m_StuID=m_pSet->m_stuid;dlg.m_StuName=m_pSet->m_name;dlg.m_StuSex=m_pSet->m_sex;dlg.m_ProfCode=m_pSet->m_profcode;if(dlg.DoModal()==IDOK){m_pSet->Edit();m_pSet->m_stuid=dlg.m_StuID;m_pSet->m_name=dlg.m_StuName;m_pSet->m_sex=dlg.m_StuSex;m_pSet->m_profcode=dlg.m_ProfCode;m_pSet->Update();UpdateData(FALSE);}}voidCMyView::OnRecDel(){//TODO:AddyourcontrolnotificationhandlercodehereCRecordsetStatusstatus;m_pSet->GetStatus(status);m_pSet->Delete();if(status.m_lCurrentRecord==0)m_pSet->MoveNext();elsem_pSet->MoveFirst();UpdateData(FALSE);}(8)在CMyView.cpp最上面加:#include“StuDlg.h”(9)編譯運(yùn)行8.2.4處理多個(gè)表數(shù)據(jù)庫(kù)中表與表之間往往存在著一定的關(guān)系,例如前面的學(xué)生表(xs)中的專(zhuān)業(yè)代碼所代表的專(zhuān)業(yè)和學(xué)制需要通過(guò)專(zhuān)業(yè)代碼表(zy)才能得知。因此,在數(shù)據(jù)庫(kù)應(yīng)用程序中一般都要處理多個(gè)表。例:用MFC處理多個(gè)表View->ClassWizard或按快捷鍵Ctrl+W,彈出ClassWizard對(duì)話(huà)框。單擊[AddClass]按鈕,從下拉列表中選擇“New”
(3) 在彈出的“AddClass"對(duì)話(huà)框中指定一個(gè)CRecordSet的派生類(lèi)(例如:CCodeSet),如下圖7所示。(4) 單擊[OK]按鈕,彈出“DatabaseOptions”對(duì)話(huà)框,參看書(shū)338頁(yè)圖8.7,(5) 從中選擇ODBC的數(shù)據(jù)源“DatabaseExampleForVC++”,單擊[OK]按鈕彈出“SelectDatabaseTables"對(duì)話(huà)框(參看上面圖3),從中選擇要使用的表(例如:zy)(6) 單擊[OK]按鈕回到ClassWizard界面,單擊[OK]按鈕后,系統(tǒng)自動(dòng)為用戶(hù)生成CCodeSet類(lèi)所需要的代碼。以后在程序中就可以通過(guò)CCodeSet類(lèi)對(duì)象來(lái)處理表zy。以第2第3步同樣的方法,再建一個(gè)基類(lèi)為CRecordSet的派生類(lèi)(例如:CCodexSet),如下圖9所示(類(lèi)名處寫(xiě):CCodexSet),用來(lái)處理專(zhuān)業(yè)名稱(chēng)和學(xué)制。注意加此類(lèi)時(shí),它問(wèn)你數(shù)據(jù)源時(shí),你按你的數(shù)據(jù)源名來(lái)寫(xiě):xs7)將項(xiàng)目工作區(qū)窗口切換到ResourceView資源欄頁(yè)面,打開(kāi)對(duì)話(huà)框資源IDD_STU_TABLE。參看下圖10,向?qū)υ?huà)框再添加下表所示的控件:標(biāo)題專(zhuān)業(yè)名稱(chēng)和學(xué)制屬性默認(rèn)Staticedge標(biāo)題專(zhuān)業(yè)名稱(chēng)和學(xué)制屬性默認(rèn)Staticedge,其余默認(rèn)默認(rèn)靜態(tài)文本 默認(rèn)靜態(tài)文本 IDC_DISP列表框 IDC_LIST1^1NewClassJName:CCodeSetCancelFilename:CodeSet.cppChange...Baseclass:CRecordset 〒Thebaseclassdoesnotrequireadialogresource.rThebaseclassdoesnotsupportautomation.圖7:定義新的CRecordSet派生類(lèi)(8)打開(kāi)ClassWizard的MemberVariables標(biāo)簽,在Classname中選擇CStuDlg,選中所需的控件ID號(hào),雙擊鼠標(biāo)或單擊AddVariables按鈕,再為下表所列控件增加成員變量:控件ID號(hào) 變量類(lèi)型 變量名IDC_DISP CString m_DispIDC_LIST1 CListBox m_CodeList(9)切換到ClassWizard的MessageMaps標(biāo)簽頁(yè),為CStuDlg中增加WM_INITDIALOG的消息映射,并添加下列代碼:BOOLCStuDlg::OnInitDialog(){CDialog::OnInitDialog();//TODO:AddextrainitializationhereCCodeSetcodeSet;codeSet.Open();while(!codeSet.IsEOF()){m_CodeList.AddString(codeSet.m_profcode);codeSet.MoveNext();}codeSet.Close();if(!m_ProfCode.IsEmpty()){intindex=m_CodeList.FindString(-1,m_ProfCode);if(index!=LB_ERR){m_CodeList.SetCurSel(index);OnSelchangeList1();}}returnTRUE;//returnTRUEunlessyousetthefocustoacontrol//EXCEPTION:OCXPropertyPagesshouldreturnFALSE}(10)用ClassWizard為控件IDC_LIST1在StuDlg類(lèi)中增加LBN_SELCHANGE消息映射,并添加下列代碼:voidCStuDlg::OnSelchangeList1(){//TODO:Addyourcontrolnotificationhandlercodehereintindex=m_CodeList.GetCurSel();if(index!=LB_ERR){CStringstr;m_CodeList.GetText(index,str);CCodeSetcodeSet;codeSet.m_strFilter.Format("profcode='%s'",str);if(codeSet.Open()){m_Disp.Format("%s%d",codeSet.m_profname,codeSet.m_stuyears);//顯示專(zhuān)業(yè)名稱(chēng)和學(xué)制m_ProfCode=str;〃專(zhuān)業(yè)代號(hào)//從這開(kāi)始是另加的語(yǔ)句,用CodexSet來(lái)處理專(zhuān)業(yè)名稱(chēng)和學(xué)制CCodexSetcodexSet;codexSet.m_strFilter.Format("profcode='%s'",str);〃專(zhuān)業(yè)代號(hào)if(codexSet.Open()){m_StuID=codexSet.m_stuid;//將學(xué)號(hào)、姓名m_StuName=codexSet.m_name;〃和性別傳送到彈出的對(duì)話(huà)框上的//其相對(duì)應(yīng)的成員變量中,m_StuSex=codexSet.m_sex;}//到這為止UpdateData(FALSE);}codeSet.Close();}}在StuDlg.cpp文件的開(kāi)始處增加下列語(yǔ)句:#include“CodeSet.h”#include“CodexSet.h”編譯并運(yùn)行,結(jié)果如下圖8所示:圖8:“學(xué)生表”對(duì)話(huà)框8.4數(shù)據(jù)庫(kù)相關(guān)的ActiveX控件在前面的數(shù)據(jù)庫(kù)處理中,一次只能顯示一行記錄,且修改或添加操作不能可視化地進(jìn)行。為了彌補(bǔ)MFC的這種不足,在VisualC++6.0中允許用戶(hù)使用一些ActiveX控件更好地處理數(shù)據(jù),它們是:MSFlexGrid,RemoteData,DBGrid等。8.4.1使用MSFlexGrid控件MicrosoftFlexGrid(MSFlexGrid)控件可以顯示網(wǎng)格數(shù)據(jù),也可以對(duì)其進(jìn)行操作。它提供了高度靈活的網(wǎng)格排序、合并和格式設(shè)置功能,網(wǎng)格中可以包含字符串和圖片。利用MSFlexGrid可以將某個(gè)表的所有記錄顯示。下例說(shuō)明其使用過(guò)程。例:使用RemoteData和DBGrid控件1、將控件MSFlexGrid的類(lèi)添加到項(xiàng)目中要對(duì)添加的控件進(jìn)行編程,首先要將控件的類(lèi)添加到項(xiàng)目中,步驟如下:A、選擇'Project”-〉”AddToProject”->CommponentsandControls...”,彈出“ComponentsandControlsGallery”對(duì)話(huà)框,如下圖9所示:B、 雙擊“RegisteredActiveXControls"項(xiàng),將列出在Windows98系統(tǒng)中安裝的ActiveX控件。C、 在列表中找到MicrosoftFlexGridControl(見(jiàn)下圖10),在該控件雙擊鼠標(biāo)VisualC++會(huì)彈出一個(gè)對(duì)話(huà)框,向用戶(hù)詢(xún)問(wèn)是否將控件插入項(xiàng)目中。E、 單擊[確定]按鈕,彈出“ConfirmClasses"對(duì)話(huà)框。F、 單擊[OK]按鈕接受所有的類(lèi),看到該控件已添加到對(duì)話(huà)框編輯器的控件工具欄中。G、 單擊[Close]按鈕,關(guān)閉“ComponentsandControlsGallery"對(duì)話(huà)框2、向?qū)υ?huà)框添加MSFlexGrid控件向?qū)υ?huà)框添加MSFlexGrid控件與其它常用控件添加的方法一樣。MSFlexGrid控件也有自己的屬性,如:通用、樣式、字體、顏色、圖片等,下圖11所示。這些屬性不僅能設(shè)置控件的字體、顏色,而且能設(shè)置網(wǎng)格的行數(shù)和列數(shù)以及其它的功能,它的可視化程度一般都比VisualC++的常用控件要高得多。圖9:“ComponentsandControlsGallery”對(duì)話(huà)框^MicrosoftForms2國(guó)MicrosoftForms2MicrosoftForms2嗣MicrosoftForms2^MicrosoftForms2?MicrosoftForms2^MicrosoftForms2國(guó)MicrosoftForms2MicrosoftForms2嗣MicrosoftForms2^MicrosoftForms2?MicrosoftForms2MicrosoftForms2.0CheckBoxMicrosoftForms2.0ComboBoxMicrosoftForms2.0CommandButton|T||T|文件名(S):Micr0EuftFlexGridControl,versicm6.UInsertMicrosoftFlexGridControl6.0MoreInfoChooseacomponenttoinsertintoyourproject:查找范圍(X):pJKegisteredActiveXControlsTQ苣]MicrosoftDirectAnimationWindowedControl曹?MicrosoftFlatScrollbarControl6.0(5P4)i屈Pathtocontrol:C:\WINDOWS\system32\MSFLXGRD.OCX圖10:選中MicrosoftFlexGridControl圖11:MSFlexGrid控件的屬性對(duì)話(huà)框具體做法:先將你剛加到控件表中的MSFlexGrid控件,拖到對(duì)話(huà)框(ID_MY_FORM)中,ID為:IDC_MSFLEXGRID1,并在View類(lèi)加一個(gè)MSFlexGrid類(lèi)的成員變量m_MSFGrid,然后,在視圖類(lèi)(View)中的OnlnitialUpdate函數(shù)體中添加代碼:m_MSFGrid.SetCols(m_pSet->m_nFields+1);〃設(shè)置望格的最大列數(shù)m_MSFGrid.SetRows(m_pSet->GetRecordCount()+1);m_MSFGrid.SetColWidth(-1,1440);m_MSFGrid.SetRow(0);m_MSFGrid.SetCol(1);m_MSFGrid.SetText('學(xué)號(hào)“);m_MSFGrid.SetRow(0);m_MSFGrid.SetCol(2);m_MSFGrid.SetText("姓名“);m_MSFGrid.SetRow(0);m_MSFGrid.SetCol(3);m_MSFGrid.SetText("性別");m_MSFGrid.SetRow(0);m_MSFGrid.SetCol(4);m_MSFGrid.SetText('專(zhuān)業(yè)代號(hào)“);intiRow=1;while(!m_pSet->IsEOF()){CStringstr;str.Format("記錄%d",iRow);m_MSFGrid.SetRow(iRow);m_MSFGrid.SetCol(0);m_MSFGrid.SetText(str);m_MSFGrid.SetRow(iRow);m_MSFGrid.SetCol(1);m_MSFGrid.SetText(m_pSet->m_stuid);m_MSFGrid.SetRow(iRow);m_MSFGrid.SetCol(2);m_MSFGrid.SetText(m_pSet->m_name);m_MSFGrid.SetRow(iRow);m_MSFGrid.SetCol(3);m_MSFGrid.SetText(m_pSet->m_sex);m_MSFGrid.SetRow(iRow);m_MSFGrid.SetCol(4);m_MSFGrid.SetText(m_pSet->m_profcode);iRow++;m_pSet->MoveNext();}m_MSFGrid.SetRow(1);m_MSFGrid.SetCol(1);m_pSet->MoveFirst();}如上代碼的目的,是將m_pSet所關(guān)聯(lián)的表的記錄內(nèi)容顯示在MSFlexGrid控件上,結(jié)果下圖12所示:圖12:MSFlexGrid控件的結(jié)果8.4.2RemoteData和DBGrid控件MSFlexGrid控件提供界面友好的網(wǎng)格,使表的記錄內(nèi)容能全部地顯示出來(lái),但卻沒(méi)有表處理的常用功能,如添加記錄、修改記錄和刪除記錄等。而DBGrid控件就有這方面的功能,它不僅能顯示全部表的記錄內(nèi)容,而且能很好地支持常見(jiàn)的記錄操作。需注意的是DBGrid控件還必須用RemoteData控件來(lái)提供數(shù)據(jù)源,它最大的好處是不需要任何程序代碼就能實(shí)現(xiàn)表的處理。(1)RemoteData控件通過(guò)被綁定的控件存取存儲(chǔ)在遠(yuǎn)程O(píng)DBC數(shù)據(jù)源中的數(shù)據(jù)。RemoteData控件允許在某一記錄集的行與行之間移動(dòng),且允許顯示和操作來(lái)自于被綁定的控件各行里的數(shù)據(jù)。RemoteData控件在遠(yuǎn)程數(shù)據(jù)對(duì)象(RDO)和數(shù)據(jù)識(shí)別的被綁定的控件之間提供了接口。通過(guò)RemoteData控件,能夠:1) 建立起與基于其本身屬性的數(shù)據(jù)源的連接2) 創(chuàng)建RDO的結(jié)果集3) 把當(dāng)前的數(shù)據(jù)傳給相應(yīng)被綁定的控件4) 允許對(duì)當(dāng)前行指針進(jìn)行定位5) 將對(duì)被綁定的控件所做的任何更改反傳給數(shù)據(jù)源?向IDD_MY_FORM對(duì)話(huà)框添加RemoteData控件由于RemoteData控件一般不需要程序再控制,因此向一個(gè)對(duì)話(huà)框中添加RemoteData控件時(shí),只需要在IDD_MY_FORM對(duì)話(huà)框中右擊鼠標(biāo)T彈出快捷菜單T選擇“InsertActiveControl"命令T從“InsertActiveControl"對(duì)話(huà)框的
控件列表中選擇MicrosoftRemoteDataControl,version控件T單擊OK->見(jiàn)RemoteData控件出現(xiàn)在了對(duì)話(huà)框上(這種方法均適用于不需要程序控制的所有ActiveX控件,例如DBGridContrl控件).將RemoteData控件拖到右稍下適當(dāng)位置,拉長(zhǎng)并拖窄一些:1) 右鍵單擊RemoteData控件->propertiesT顏色T雙擊“自定義"T選“紅色”T確定。2) 右鍵單擊RemoteData控件TpropertiesT點(diǎn)“Control(控制)”->從“DataSource"的下拉列表中找到你起的數(shù)據(jù)源名(如:MydatabaseforVC)置好。并在“SQL”編輯框中鍵入SQL操作語(yǔ)句,例如:“SELECT*FROMxs"(是檢索學(xué)生表xs的所有記錄)。如下圖13所示:圖13:RemoteData控件的屬性對(duì)話(huà)框3)右鍵單擊RemoteData控件TpropertiesT點(diǎn)“ALL"T將出現(xiàn)的ALL頁(yè)面的“CursorDriver"欄下拉T置為“1-ODBCcursor”。由于RemoteData控件在這里是用于ODBC的聯(lián)結(jié),因此該控件必須使用ODBC的游標(biāo)驅(qū)動(dòng)程序(CursorDriver),使其置為1-ODBCcursor。如下圖圖14:RemoteData控件屬性“ALL”頁(yè)面的”ursorDriver設(shè)置設(shè)置DBGrid控件一旦上面添加在對(duì)話(huà)框的RemoteData控件的屬性設(shè)定后,那麼在同一個(gè)對(duì)話(huà)框的DBGrid控件就可以與RemoteData控件進(jìn)行數(shù)據(jù)綁定。?在IDD_MY_FORM對(duì)話(huà)框上加一個(gè)DBGrid控件在IDD_MY_FORM對(duì)話(huà)框中右鍵擊鼠標(biāo)T彈出快捷菜單T選擇“InsertActiveControl"命令T從“InsertActiveControl"對(duì)話(huà)框的控件列表中選擇DBGridContrl控件T單擊OKT見(jiàn)DBGrid控件出現(xiàn)在了對(duì)話(huà)框上。見(jiàn)下圖17。圖15:向IDD_MY_FORM對(duì)話(huà)框添加DBGridContrl控件將DBGridContrl控件拖到右上面適當(dāng)位置,拉大成方形。?右鍵單擊DBGrid控件Tproperties—顏色T雙擊“自定義”T選“黃色”T確定。?右鍵單擊DBGrid控件Tproperties—點(diǎn)“ALL”T將出現(xiàn)的ALL頁(yè)面T選中DataRource欄T右邊下拉,設(shè)置為IDC_REMOTEDATACTL1(RemoteData控件的ID標(biāo)識(shí)符,這時(shí)該2個(gè)控件就綁定了)。見(jiàn)下圖18:
圖16:DBGrid控件屬性“ALL”頁(yè)面的'DataSource”設(shè)置4)編譯運(yùn)行,結(jié)果見(jiàn)下圖17所示。圖17:最終結(jié)果界面8.5字段操作在前面的示例中,雖然可以通過(guò)CRecordSet對(duì)象中的字段關(guān)聯(lián)變量可以直接訪(fǎng)問(wèn)當(dāng)前記錄的相關(guān)字段值,但有時(shí)在處理多個(gè)字段時(shí)就不太方便了。CRecordSet類(lèi)中的成員變量m_nFields(用于保存數(shù)據(jù)表的字段個(gè)數(shù))和成員函數(shù)GetODBCFieldlnfo及GetFieldValue可以簡(jiǎn)化多字段的訪(fǎng)問(wèn)操作。GetODBCFieldlnfo函數(shù)用于數(shù)據(jù)表中的字段信息,其函數(shù)原型如下:voidGetODBCFieldInfo(shortnIndex,CODBCFieldInfo&fieldinfo);參數(shù):nIndex用于指定字段索引號(hào),0表示第1個(gè)字段,1表示第2個(gè)字段,…Fieldinfo是CODBCFieldlnfo結(jié)構(gòu)參數(shù),用于表示字段信息CODBCFieldInfo結(jié)構(gòu)體原型如下:StructCODBCFieldInfo{CStringm_strName; //字段名SWORDm_nSQLType;〃字段的SQL數(shù)組類(lèi)型(SWORD表示shortint短整形)UDWORDm_nPrecision;〃字段的文本大小或數(shù)據(jù)大小(UDWORD表示//unsignedlongint無(wú)符號(hào)長(zhǎng)整型)SWORDm_nScale; //字段的小數(shù)點(diǎn)位數(shù)SWORDm_nNullability;〃字段接受空值(NULL)能力};GetFieldValue函數(shù)用于獲取數(shù)據(jù)表當(dāng)前記錄中指定字段的值,其常用的函數(shù)原型如下:voidGetFieldValue(shortnIndex,CString&strValue);參數(shù):nIndex用于指定字段索引號(hào)strValue用于返回字段的內(nèi)容除了上述字段操作外CRecordSet類(lèi)的成員函數(shù)GetRecordCount和GetStatus還可分別用于獲得表中的記錄總數(shù)和當(dāng)前記錄的索引,其原型如下:longGetRecordCount()const;voidGetStatus(CRecordsetStatus&rStatus)count;參數(shù):rStatus是指向下列的CRecordsetStatus結(jié)構(gòu)的對(duì)象:StructCRecordsetStatus{longm」CurrentRecord;〃當(dāng)前記錄的索弓I,0表示第1個(gè)記錄,1表示第2個(gè)記錄,//依次類(lèi)推。-1表示在第1個(gè)記錄之前,-2表示不確定BOOLm_bRecordCountFinal;〃記錄總數(shù)是否是最終結(jié)果};GetRecordCount函數(shù)所返回的記錄總數(shù)在表打開(kāi)時(shí)或調(diào)用Requery函數(shù)后是不確定的,必須經(jīng)過(guò)下列代碼才能獲得最終有效的記錄總數(shù):while(!m_pSet->IsEOF()){m_pSet->MoveNext();m_pSet->GetRecordCount();}例:字段的編程操作用列表視圖來(lái)顯示一個(gè)課程信息表(見(jiàn)349表8.5)的全部記錄內(nèi)容,并在狀態(tài)欄中顯示記錄總數(shù)。1、為數(shù)據(jù)庫(kù)Studentf.mdb添加一個(gè)數(shù)據(jù)表course,下面我們開(kāi)始用Access2003設(shè)計(jì)數(shù)據(jù)庫(kù):(1)開(kāi)機(jī)正常屏幕狀態(tài)T開(kāi)始T程序->MicrosoftOffice—MicrosoftOfficeAccess2003T新建文件—空數(shù)據(jù)庫(kù)—數(shù)據(jù)庫(kù)名處寫(xiě):studentf—點(diǎn)右邊的創(chuàng)建—新建—設(shè)計(jì)視圖—確定—出現(xiàn)表,你按書(shū)349頁(yè)表8.5的下部分敲入數(shù)據(jù)即可。(2)關(guān)閉此表—提問(wèn):你是否保存對(duì)表1的設(shè)計(jì)更改?—是—表名寫(xiě)course—是—便在數(shù)據(jù)庫(kù)中建立了表course(3)你雙擊course表出現(xiàn)設(shè)計(jì)視圖表,之后你按書(shū)349頁(yè)表8.5上面部分敲進(jìn)數(shù)據(jù)即可2、為文檔應(yīng)用程序添加ODBC的支持建一個(gè)單文檔應(yīng)用程序名為:字段操作,在向?qū)У牡?步將View的基類(lèi)由默認(rèn)的CView選擇為CListView類(lèi)將項(xiàng)目工作區(qū)窗口切換到FileView頁(yè)面,展開(kāi)HeaderFiles所有項(xiàng),雙擊stdafx.h打開(kāi)該文件在stdafx.h中添加ODBC數(shù)據(jù)庫(kù)支持的頭文件包含#includevafxdb.h>如下:#endif//_AFX_NO_AFXCMN_SUPPORT#include<afxdb.h>3、創(chuàng)建數(shù)據(jù)表score的CRecordSet派生類(lèi)(1)View->ClassWizard->AddClass?…下拉->New(加新類(lèi))⑵在彈出的“AddClass"對(duì)話(huà)框中定義新的CRecordSet的派生類(lèi)CCourseSet,如書(shū)350頁(yè)圖8.23所示。(3)(4)cs.style&=~LVS_TYPEMASK;cs.style|=LVS_REPORT;CListCtrl&m_ListCtrl=GetListCtrl();〃獲取內(nèi)嵌在列表視圖中的列表控件CCourseSetcSet;cSet.Open();〃打開(kāi)記錄CODBCFieldInfofield;//創(chuàng)建列表頭for(UINTi=0;i<cSet.m_nFields;i++){cSet.GetODBCFieldInfo(i,field);m_ListCtrl.InsertColumn(i,field.m_strName,LVCFMT_LEFT,100);}//添加列表項(xiàng)intnItem=0;CStringstr;while(!cSet.IsEOF()){for(UINTi=0;i<cSet.m_nFields;i++){cSet.GetFieldValue(i,str);if(i==0)m_ListCtrl.InsertItem(nItem,str);elsem_ListCtrl.SetItemText(nItem,i,str);}nItem++;cSet.MoveNext();}cSet.Close();〃關(guān)閉記錄集在CMyView.cpp文件的前面加:#include“CourseSet.h”說(shuō)明:當(dāng)為數(shù)據(jù)源中的某個(gè)數(shù)據(jù)表映射一個(gè)CRecordSet類(lèi)時(shí),該類(lèi)對(duì)象一定先要調(diào)用CRecordSet::Open成員函數(shù),才能訪(fǎng)問(wèn)該數(shù)據(jù)表的記錄集,訪(fǎng)問(wèn)后還須調(diào)用CRecordSet::Close成員函數(shù)關(guān)閉記錄集。編譯運(yùn)行,結(jié)果見(jiàn)351頁(yè)圖8.244、在狀態(tài)欄中顯示當(dāng)前記錄號(hào)和記錄總數(shù)(1)在CMyView.cpp文件前面的#endif后加:voidDispRecNum(CCourseSet*pSet){CStringstr;CMainFrame*pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;〃獲得主框//架窗口的指針CStatusBar*pStatus=&pFrame->m_wndStatusBar;〃獲得主框架窗口中的狀態(tài)欄指針if(pStatus){CRecordsetStatusrStatus;pSet->GetStatus(rStatus);//獲得當(dāng)前記錄信息str.Format("當(dāng)前記錄:%d 總記錄:%d",l+rStatus.m」CurrentRecord,pSet->GetRecordCount());pStatus->SetPaneText(l,str);}}該函數(shù)先獲得狀態(tài)欄對(duì)象的指針,然后調(diào)用SetPaneText函數(shù)更新第2個(gè)窗格的文本。在前面CMyView.cpp的OnlnitialUpdate函數(shù)中剛才已經(jīng)加好的代碼最后一條語(yǔ)句前面加:::DispRecNum(&cSet);在CMyView.cpp文件的開(kāi)始處添加:’MainFrm.h”將MainFrm.h文件中的保護(hù)型變量m_wndStatusBar剪切到public:里編譯運(yùn)行,結(jié)果見(jiàn)353頁(yè)圖8.258.6多表處理(此例是以樹(shù)控件形式顯示學(xué)生成績(jī))數(shù)據(jù)庫(kù)中表與表之間往往存在著一定的關(guān)系,例如:要顯示一個(gè)學(xué)生的課程成績(jī)信息,包括學(xué)號(hào)、姓名、課程號(hào)、課程所屬專(zhuān)業(yè)、課程名稱(chēng)、課程類(lèi)別、開(kāi)課學(xué)期、課時(shí)數(shù)、學(xué)分、成績(jī),則要涉及前面的學(xué)生課程成績(jī)表(score)、課程表以及學(xué)生基本信息表。以下示例是在一個(gè)對(duì)話(huà)框中用2個(gè)控件來(lái)進(jìn)行學(xué)生課程成績(jī)信息的相關(guān)操作,如353頁(yè)圖8.26所示,其左邊是樹(shù)視圖,用于顯示學(xué)生成績(jī)、專(zhuān)業(yè)和班級(jí)號(hào)3個(gè)層次信息,單擊班級(jí)號(hào),所有該班級(jí)的學(xué)生課程成績(jī)信息將在右邊的列表視圖中顯示出來(lái)。例:多表處理1、為數(shù)據(jù)庫(kù)Student.mdb添加一個(gè)數(shù)據(jù)表:student和score雙擊MicrosoftOfficeAccess2003在右邊“打開(kāi)”(已有的數(shù)據(jù)庫(kù)名)的下面雙擊studentf(我們以上課里建好的數(shù)據(jù)庫(kù)),便出現(xiàn)一個(gè)對(duì)話(huà)框,你點(diǎn)“打開(kāi)”又出現(xiàn)一個(gè)“studentf:數(shù)據(jù)庫(kù)”對(duì)話(huà)框->你點(diǎn)新建->設(shè)計(jì)視圖->確定->開(kāi)始輸入數(shù)據(jù),你將書(shū)354頁(yè)表8.6的下表數(shù)據(jù)敲入到數(shù)據(jù)庫(kù)中,表的名字為:student這時(shí)在studentf數(shù)據(jù)庫(kù)中右出現(xiàn)一個(gè)student表(原來(lái)有個(gè)course表),你雙擊它便開(kāi)始敲入354頁(yè)表8.6的上表數(shù)據(jù)。以同樣的方法再建一個(gè)score表,該表的內(nèi)容為336頁(yè)表8.1(studentf里共有三個(gè)表,即:course、student、score)2、 創(chuàng)建并設(shè)計(jì)對(duì)話(huà)框應(yīng)用程序(1)創(chuàng)建一個(gè)基于對(duì)話(huà)框的應(yīng)用程序名為:處理多個(gè)表(2)(3)(4)(5)(6)3、 添加對(duì)MFCODBC的支持及記錄集(1)#include<afxdb.h>(2)4、 完善左邊樹(shù)控件的代碼(1)為CMyDlg類(lèi)添加一個(gè)成員函數(shù):ClassView->右鍵對(duì)準(zhǔn)CMyDlg單擊->AddMemberFunction->FunctionType處寫(xiě):HTREEITEM->FunctionDeclaration處寫(xiě)FindTreeItem(HTREEITEMhParent,CStringstr)用于查找指定結(jié)點(diǎn)下是否有指定結(jié)點(diǎn)文本的子結(jié)點(diǎn),函數(shù)代碼如下:并加如下代碼:HTREEITEMCMyDlg::FindTreeItem(HTREEITEMhParent,CStringstr){HTREEITEMhNext;CStringstrItem;hNext=m_treeCtrl.GetChildItem(hParent);while(hNext!=NULL){strItem=m_treeCtrl.GetItemText(hNext);if(strItem==str)returnhNext;elsehNext=m_treeCtrl.GetNextItem(hNext,TVGN_NEXT);}returnNULL;}(2)用右鍵對(duì)準(zhǔn)CMyDlg類(lèi),為CMyDlg類(lèi)加一個(gè)CImageList類(lèi)的成員變量m_ImageList(3)m_ImageList.Create(16,16,ILC_COLOR8|ILC_MASK,2,1);m_treeCtrl.SetImageList(&m_ImageList,TVSIL_NORMAL);SHFILEINFOfi;//定義一個(gè)文件信息結(jié)構(gòu)變量SHGetFileInfo("C:\\Windows",0,&fi,sizeof(SHFILEINFO),SHGFI_ICONISHGFI_SMALLICON);〃獲取文件夾圖標(biāo)m_ImageList.Add(fi.hIcon);SHGetFileIn
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 托兒所服務(wù)的危機(jī)管理和風(fēng)險(xiǎn)控制考核試卷
- 光纜生產(chǎn)自動(dòng)化與智能化技術(shù)考核試卷
- 樓房商用租賃合同范本
- 首付購(gòu)車(chē)合同范本
- 軸承成品采購(gòu)合同范本
- 水電承包勞務(wù)合同范本
- 酒店客房服務(wù)標(biāo)準(zhǔn)及流程制度
- 靜脈輸液的操作流程及操作規(guī)范
- 電商網(wǎng)站運(yùn)營(yíng)維護(hù)服務(wù)協(xié)議
- 共享經(jīng)濟(jì)平臺(tái)技術(shù)開(kāi)發(fā)合作協(xié)議
- 大學(xué)生就業(yè)指導(dǎo)教學(xué)-大學(xué)生就業(yè)形勢(shì)與政策
- 車(chē)路協(xié)同路側(cè)設(shè)備通信終端(RSU)測(cè)試技術(shù)要求(征求意見(jiàn)稿)
- TCAICC 001-2024 張家界莓茶質(zhì)量等級(jí)評(píng)價(jià)
- 冷鏈鄉(xiāng)村物流相關(guān)行業(yè)公司成立方案及可行性研究報(bào)告
- 6.《變色龍》省公開(kāi)課一等獎(jiǎng)全國(guó)示范課微課金獎(jiǎng)?wù)n件
- 股權(quán)架構(gòu)設(shè)計(jì)合同
- HJ1209-2021工業(yè)企業(yè)土壤和地下水自行監(jiān)測(cè)技術(shù)指南(試行)
- 《跨境電商英語(yǔ)》課程標(biāo)準(zhǔn)
- 2024年湖南電氣職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(kù)附答案
- 幼兒園衛(wèi)生保健工作匯報(bào)
- 第一課 追求向上向善的道德(課時(shí)1)(課件)
評(píng)論
0/150
提交評(píng)論