版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第十二章ActiveX控件的使用和創(chuàng)建
1a第十二章ActiveX控件的使用和創(chuàng)建1a近年來(lái),軟件產(chǎn)業(yè)已經(jīng)發(fā)生了一場(chǎng)革命性的變化。軟件的制作和打包方式已經(jīng)不再是所有的應(yīng)用程序都必須從源代碼編譯鏈接成一個(gè)完整的、很大的可執(zhí)行代碼文件,而是大多數(shù)應(yīng)用程序都可以由一些較小的構(gòu)件組成。這些小的構(gòu)件,通常稱(chēng)為組件。這些組件可以用多種不同的程序語(yǔ)言創(chuàng)建,且可以具有多種不同的的形式。最為流行的組件之一便是ActiveX控件。組件不但可以作為最終軟件產(chǎn)品提供給其他程序設(shè)計(jì)人員,而且在大型軟件開(kāi)發(fā)中,使用組件也是組織不同分工的程序設(shè)計(jì)人員共同完成整個(gè)軟件設(shè)計(jì)開(kāi)發(fā)的重要策略和方法。本章的學(xué)習(xí)目的是:2a近年來(lái),軟件產(chǎn)業(yè)已經(jīng)發(fā)生了一場(chǎng)革命性的變化。軟件的制掌握如何使用ActiveX控件,以便在軟件開(kāi)發(fā)中使用第三方提供的產(chǎn)品化組件和如何創(chuàng)建自己的ActiveX控件,以便開(kāi)發(fā)產(chǎn)品化組件,提供給其他程序設(shè)計(jì)者。本章的主要內(nèi)容包括:·什么是ActiveX控件以及它們是如何工作的?!と绾卧陧?xiàng)目工作區(qū)中添加ActiveX控件。·如何在VisualC++應(yīng)用程序中使用ActiveX控件。·如何調(diào)用與ActiveX控件相關(guān)聯(lián)的各種方法?!と绾翁幚碛葾ctiveX控件激活的事件。·如何用VisualC++AppWizard
建立ActiveX控件項(xiàng)目?!と绾斡肅lassWizard向ActiveX控件添加屬性和方法?!と绾斡肰isualC++提供的工具測(cè)試自己的ActiveX
控件。3a掌握如何使用ActiveX控件,以便在軟件開(kāi)發(fā)中使用第三12.1什么是ActiveX控件在介紹ActiveX控件之前有必要了解另外兩個(gè)編程技術(shù)概念:·OLE(ObjectLinkedandEmbeded)對(duì)象連接嵌入是Microsoft基于對(duì)象的技術(shù)。該技術(shù)用于跨越進(jìn)程和機(jī)器邊界的數(shù)據(jù)信息和操作方法的共享。不過(guò)最初的OLE僅僅允許把不同的應(yīng)用程序創(chuàng)建的文檔組合成一個(gè)單一文檔?!OM(ComponentObjectModel)組件對(duì)象模型是遵循OLE基本技術(shù)的對(duì)象模型。一個(gè)COM對(duì)象是一個(gè)對(duì)象定義的實(shí)例,該對(duì)象定義指定了該對(duì)象的數(shù)據(jù)和一個(gè)或多個(gè)作用于該對(duì)象的接口執(zhí)行方法??蛻?hù)程序與COM對(duì)象之間的相互作用只能通過(guò)COM對(duì)象的接口實(shí)現(xiàn)。4a12.1什么是ActiveX控件4aActiveX控件就是一組封裝在COM對(duì)象中的功能模塊。這個(gè)COM對(duì)象是獨(dú)立的,但并不能單獨(dú)運(yùn)行,而只能在ActiveX容器中運(yùn)行,如VisualC++或VisualBasic應(yīng)用程序,這一點(diǎn)很像在組合設(shè)備中插入具有特定功能的組件,例如在組合式音響中,插入一個(gè)DVD播放組件。5aActiveX控件就是一組封裝在COM對(duì)象中的12.1.1ActiveX和IDispatch接口每個(gè)COM對(duì)象都有一些標(biāo)準(zhǔn)接口,例如,IUnknown
接口,該接口用來(lái)詢(xún)問(wèn)是否找到了該組件所支持的其他接口。每個(gè)接口支持一組特定的功能,例如,可以用一個(gè)接口來(lái)處理控件的可視外觀,一個(gè)接口來(lái)控制控件外觀如何與插入該控件的應(yīng)用程序進(jìn)行交互,一個(gè)接口來(lái)觸發(fā)插入該控件應(yīng)用程序中的事件,等等。
ActiveX技術(shù)是建立在微軟的COM技術(shù)之上,并使用COM的接口和交互模型使ActiveX控件與插入控件的應(yīng)用程序進(jìn)行完全無(wú)縫的集成。COM技術(shù)奠定了構(gòu)建ActiveX
對(duì)象的方式及設(shè)計(jì)ActiveX接口的方法。ActiveX
技術(shù)定義了建立于COM
之上的層面、各種對(duì)象應(yīng)該支持什么樣的接口以及如何與不同類(lèi)型的對(duì)象交互。6a12.1.1ActiveX和IDispatch接口6
ActiveX控件的關(guān)鍵技術(shù)之一是自動(dòng)。所謂“自動(dòng)”可描述為:·將一個(gè)應(yīng)用程序中嵌入另一個(gè)應(yīng)用程序。·當(dāng)用戶(hù)的操作涉及到被嵌入者的功能時(shí),激活被嵌入者,并控制被嵌入者的用戶(hù)接口或文檔部分,同時(shí)進(jìn)行被嵌入者自身的更改?!ぎ?dāng)用戶(hù)將操作轉(zhuǎn)移到應(yīng)用程序中非嵌入程序的控制部分時(shí),被嵌入者自行關(guān)閉(例如在word應(yīng)用程序中自動(dòng)嵌入Excel電子表格應(yīng)用程序)。實(shí)現(xiàn)自動(dòng)工作的關(guān)鍵之一是特殊(調(diào)度)接口
IDispatch。7aActiveX控件的關(guān)鍵技術(shù)之一是自動(dòng)。所謂“自
ActiveX控件可以提供的所有方法有各自的唯一標(biāo)識(shí)值DISPID。這些標(biāo)識(shí)值被存放在用來(lái)查找特定方法的標(biāo)識(shí)列表中。IDispatch接口由一個(gè)指示方法的標(biāo)識(shí)列表和IDispatch接口提供的方法組成。當(dāng)獲取一個(gè)特定方法的DISPID之后,就可以將該方法的DISPID作為參數(shù),通過(guò)調(diào)用IDispatch接口的方法Invoke
來(lái)實(shí)現(xiàn)調(diào)用DISPID所標(biāo)識(shí)的指定方法。下圖示意性描述了IDispatch接口如何使用Invoke方法來(lái)運(yùn)行ActiveX
控件提供的方法,實(shí)現(xiàn)的ActiveX
控件的自動(dòng)化。8aActiveX控件可以提供的所有方法有各自的唯一DISPID1DISPID2DISPID3DISPID4DISPIDnActiveX對(duì)象IDispatchvtable客戶(hù)程序IDispatch::Invoke(DISPID)Invoke(){switch(DISPID3){case1:MethodX();case2:MethodY();case3:MethodZ();…}調(diào)度接口9aDISPID1ActiveX對(duì)象IDispatch客戶(hù)程序12.1.2ActiveX容器和服務(wù)器任何可以嵌入另一對(duì)象的ActiveX對(duì)象都是ActiveX
服務(wù)器,而無(wú)論它是一個(gè)完整的應(yīng)用程序或僅僅是一個(gè)ActiveX控件。任何可以包含其他被嵌入ActiveX服務(wù)器的ActiveX對(duì)象都是ActiveX容器。注意,不要把術(shù)語(yǔ)容器和服務(wù)器與上圖中的客戶(hù)程序混淆。客戶(hù)程序是指調(diào)用其嵌入對(duì)象的IDispatch接口的對(duì)象。容器和服務(wù)器都相互調(diào)用對(duì)方的IDispatch接口,因此它們相互成為對(duì)方的客戶(hù)程序。10a12.1.2ActiveX容器和服務(wù)器10a這兩種類(lèi)型的ActiveX對(duì)象并不互相排斥。ActiveX服務(wù)器同時(shí)也可以是ActiveX容器,例如,微軟的InternetExplorer
Web
瀏覽器中InternetExplorer是一個(gè)可以在ActiveX容器外殼中運(yùn)行的ActiveX服務(wù)器??梢赃\(yùn)行該服務(wù)器的ActiveX容器外殼還可以包含Word、Excel、Powerpoint
等其他應(yīng)用程序,同時(shí)這些應(yīng)用程序還可以作為其他應(yīng)用程序的ActiveX
服務(wù)器。
ActiveX控件是ActiveX
服務(wù)器的一個(gè)特例,即該
服務(wù)器不能自身運(yùn)行,必須被嵌入到ActiveX容器中。如果在AppWizard所創(chuàng)建的MFC應(yīng)用程序項(xiàng)目中,設(shè)置了使用ActiveX組件選項(xiàng),則該項(xiàng)目所創(chuàng)建的應(yīng)用程序就自動(dòng)成為一個(gè)ActiveX容器。11a這兩種類(lèi)型的ActiveX對(duì)象并不互相排斥。Ac
ActiveX容器和ActiveX控件之間的大多數(shù)交互操作是通過(guò)三個(gè)IDispatch接口完成(如下圖所示)。這些IDispatch接口中的一個(gè)位于控件中,通過(guò)該接口,容器可以調(diào)用控件的各種方法,為容器的功能提供服務(wù)。
容器也為控件提供兩個(gè)IDispatch接口。其中一個(gè)接口用于控件在容器中觸發(fā)事件。另一個(gè)接口用于容器為控件設(shè)置屬性,也就是說(shuō)ActiveX控件的大部分屬性實(shí)際上由是容器提供,而由控件實(shí)現(xiàn)的。當(dāng)設(shè)置屬性時(shí),容器調(diào)用控件中一個(gè)方法,以便通知控件從容器中讀取所提供的屬性。VisualC++創(chuàng)建了一系列關(guān)于ActiveX控件接口的C++類(lèi),用戶(hù)只與這些C++類(lèi)“暴露”給用戶(hù)的方法交互,而不需要直接調(diào)用控件的IDispatch接口,所以上述活動(dòng)中的大部分對(duì)用戶(hù)來(lái)說(shuō)是“透明”的。12aActiveX容器和ActiveX控件之間的大ActiveX容器ActiveX控件IDispatch(事件)IDispatch(屬性)IDispatch13aActiveX容器ActiveX控件IDispatch(事件12.2在應(yīng)用程序項(xiàng)目中添加和使用ActiveX控件使用VisualC++使得在應(yīng)用程序項(xiàng)目添加和使用ActiveX控件變得十分方便。下面通過(guò)實(shí)例詳細(xì)講述如何創(chuàng)建一個(gè)可以包含ActiveX控件的應(yīng)用程序項(xiàng)目;如何為這個(gè)項(xiàng)目添加ActiveX控件和如何在應(yīng)用程序中使用所添加的ActiveX控件。14a12.2在應(yīng)用程序項(xiàng)目中添加和使用ActiveX控件112.2.1創(chuàng)建一個(gè)可以包含ActiveX控件的應(yīng)用程序1創(chuàng)建一個(gè)MFC應(yīng)用程序
項(xiàng)目,命名為“ActiveX”。2選擇項(xiàng)目類(lèi)型為DialogBased,并在創(chuàng)建過(guò)程中注意選擇項(xiàng)目具有ActiveXControls支持狀態(tài),其他均可取默認(rèn)選擇。3刪除缺省對(duì)話(huà)框模板IDD_ACTIVEX_DIALOG中的所有缺省控件,添加一個(gè)命令按鈕:標(biāo)識(shí)為IDC_EXIT,標(biāo)題為E&XIT。4在缺省創(chuàng)建的CActiveXDlg類(lèi)中,為新添加命令按鈕IDC_EXIT
的BN_CLICKED通知消息建立消息映射
ON_BN_CLICKED(IDC_EXIT,OnExit)和定義消息處理函數(shù)OnExit的原型和定義
afx_msgvoidOnExit();
voidCActiveXDlg::OnExit(){OnOK();}15a12.2.1創(chuàng)建一個(gè)可以包含ActiveX控件的應(yīng)用程12.2.2注冊(cè)ActiveX控件在給應(yīng)用程序項(xiàng)目添加ActiveX控件之前,必須在系統(tǒng)中注冊(cè)控件。在系統(tǒng)中注冊(cè)ActiveX控件的方法有兩種。一種方法是運(yùn)行ActiveX控件的安裝程序,進(jìn)行自動(dòng)注冊(cè)。另一種方法是手工注冊(cè)ActiveX控件。手工注冊(cè)的步驟如下:1進(jìn)入DOS控制臺(tái)界面。2將當(dāng)前目錄改變到ActiveX控件文件所在的目錄中,例如:
Windows\system。16a12.2.2注冊(cè)ActiveX控件16a3執(zhí)行系統(tǒng)命令regsvr32,并指定ActiveX控件名為該命令的參數(shù)。例如要注冊(cè)一個(gè)文件名為MYCTL.OCX的ActiveX控件,假如該控件文件MYCTL.OCX在Windows\system目錄中,則可執(zhí)行如下命令:
C:\WINDOWS>cdsystem
C:\WINDOWS\SYSTEM>regsvr32myctl.ocx17a3執(zhí)行系統(tǒng)命令regsvr32,并指定ActiveX注意:·手工注冊(cè)可能會(huì)導(dǎo)致所注冊(cè)的控件缺少某些信息,從而在開(kāi)發(fā)中無(wú)法使用,所以建議使用控件所帶的安裝程序。·如果所使用的ActiveX控件在系統(tǒng)安裝時(shí)已經(jīng)被缺省注冊(cè)了,則不需要使用上述方法進(jìn)行控件的注冊(cè)。本例中要添加的控件就是這類(lèi)ActiveX控件。
ActiveX控件一旦在系統(tǒng)中注冊(cè)成功,就可以將它添加到應(yīng)用程序項(xiàng)目中。在VisualC++6.0中注冊(cè)和添加ActiveX控件的步驟如下:18a注意:18a1選擇Project->AddTo
Project->ComponentsandControls。2在彈出的“ComponentsandControlsGallery”對(duì)話(huà)框中,選擇“RegistedActiveXControls”文件夾:19a1選擇Project->AddToProject->C3在該文件夾中,查找并選中要添加的已注冊(cè)ActiveX控件,本例中選擇MicrosoftFlexGridControlversion6.0控件,雙擊被選中控件選項(xiàng),或按《Insert》按鈕。20a3在該文件夾中,查找并選中要添加的已注冊(cè)ActiveX控4在提示是否確實(shí)要添加該控件的對(duì)話(huà)框中,按《OK》按鈕。5在“ConfirmClasses”對(duì)話(huà)框中,單擊《OK》按鈕添加控件所包含的全部或部分C++類(lèi):21a4在提示是否確實(shí)要添加該控件的對(duì)話(huà)框中,按《OK》按鈕。26在“ComponentsandControlGallery”對(duì)話(huà)框中單擊《Close》按鈕完成為項(xiàng)目添加控件的工作。7控件FlexGird已經(jīng)被添加到資源編輯器的“ControlPalette”上:22a6在“ComponentsandControlGa8查看工作區(qū)的ClassView,發(fā)現(xiàn)項(xiàng)目中已自動(dòng)增加了與FlexGird控件相關(guān)的類(lèi):
CMSFlexGrid、COleFont、CRowCursor和CPicture,每個(gè)類(lèi)中都提供了相應(yīng)的方法。23a8查看工作區(qū)的ClassView,發(fā)現(xiàn)項(xiàng)目中已自動(dòng)增加在VisualC++.NET中注冊(cè)和添加ActiveX控件的步驟如下:1在Toolbox中,單擊鼠標(biāo)右鍵彈出的環(huán)境菜單中選擇菜單項(xiàng)“ChooseItems…”:24a在VisualC++.NET中注冊(cè)和添加Activ2在彈出的屬性表《ChooseToolboxItems》中,選擇屬性頁(yè)“COM
Components”,在該屬性頁(yè)中選擇所需的ActiveX控件“FlexGird” 后,按OK
按鈕。25a2在彈出的屬性表《ChooseToolboxItems3添加了ActiveX控件“FlexGird”后的Toolbox如下:注意,經(jīng)過(guò)上述操作后,并不會(huì)在項(xiàng)目中增加封裝“FlexGird”控件的類(lèi)CMsfgrid(相應(yīng)的定義文件和實(shí)現(xiàn)文件)。只有將控件從ToolBox中添加到對(duì)話(huà)框模板中,控件的類(lèi)CMsfgrid(相應(yīng)的定義文件和實(shí)現(xiàn)文件)才會(huì)被自動(dòng)添加到項(xiàng)目中。26a3添加了ActiveX控件“FlexGird”后的12.2.3在對(duì)話(huà)框模板中添加ActiveX控件
ActiveX控件添加到項(xiàng)目中之后,便可以像使用其他標(biāo)準(zhǔn)控件一樣,把它添加對(duì)話(huà)框模板中。本例中所添加的ActiveX控件FlexGird的主要屬性設(shè)置如下:控件名屬性設(shè)置值FlexGirdIDIDC_MSFGRIDRows20Cols4MergeCellsRestrictAllFormatString<Region|<Product|<Employee|<Sales27a12.2.3在對(duì)話(huà)框模板中添加ActiveX控件控件名在完成對(duì)控件所有屬性的設(shè)置之后,需要為該控件添加一個(gè)數(shù)值類(lèi)對(duì)象m_ctrlFGrid,以便能和代碼中的控件進(jìn)行交互。所添加的代碼如下:classCActiveXDlg:publicCDialog{ …public:
CActiveXDlg(CWnd*pParent=NULL); //standardconstructor … enum{IDD=IDD_ACTIVEX_DIALOG};
CMSFlexGrid m_ctrlFGrid; …};28a在完成對(duì)控件所有屬性的設(shè)置之后,需要為該控件添加一個(gè)數(shù)28a12.2.4在應(yīng)用程序中使用ActiveX控件與ActiveX控件進(jìn)行交互本例中將使用添加的FlexGrid控件生成一個(gè)產(chǎn)品銷(xiāo)售數(shù)字統(tǒng)計(jì)表,其中包括4個(gè)銷(xiāo)售人員在5個(gè)銷(xiāo)售區(qū)的銷(xiāo)售情況。要求能夠在屏幕上滾動(dòng)顯示數(shù)據(jù),這些數(shù)據(jù)應(yīng)按能區(qū)域或產(chǎn)品種類(lèi)分類(lèi),以比較各個(gè)銷(xiāo)售人員在每種產(chǎn)品上的銷(xiāo)售業(yè)績(jī)。為此,首先調(diào)用FlexGrid控件的方法SetTextArray將要處理、顯示的數(shù)據(jù)存入到控件的數(shù)組中,并將數(shù)組中數(shù)據(jù)將被載入表格的相應(yīng)單元格中。調(diào)用FlexGrid控件的內(nèi)置排序方法SetSort,使表格按升序排列。為了實(shí)現(xiàn)這些操作需要為CActiveXDlg類(lèi)添加如下成員函數(shù)定義:29a12.2.4在應(yīng)用程序中使用ActiveX控件29a1把數(shù)據(jù)載入控件添加一個(gè)私有成員函數(shù)將數(shù)據(jù)裝載到FlexGrid控件中,該函數(shù)命名為L(zhǎng)oadData,函數(shù)類(lèi)型為void,其定義代碼如下:voidCActiveXDlg::LoadData(){intliCount; //Thegridrowcount
CStringlsAmount; //Thesalesamount
//Initializetherandomnumbergenerator
srand((unsigned)time(NULL));
//CreateArrayinthecontrolfor(liCount=m_ctrlFGrid.GetFixedRows(); liCount<m_ctrlFGrid.GetRows();liCount++)30a1把數(shù)據(jù)載入控件30a{
//Generatethefirstcolumn(region)valuesm_ctrlFGrid.SetTextArray(GenID(liCount,0),RandomStringValue(0));
//Generatathesecondcolumn(product)valuesm_ctrlFGrid.SetTextArray(GenID(liCount,1),RandomStringValue(1));//Generatethethirdcolumn(employee)valuesm_ctrlFGrid.SetTextArray(GenID(liCount,2),RandomStringValue(2));
//GeneratathesalesamountvalueslsAmount.Format("%5d.00",rand());
//Populatethefourthcolumnm_ctrlFGrid.SetTextArray(GenID(liCount,3),lsAmount);}31a{31a//MergetheCommonsubsequentrowsinthesecolumns
m_ctrlFGrid.SetMergeCol(0,TRUE);m_ctrlFGrid.SetMergeCol(1,TRUE);m_ctrlFGrid.SetMergeCol(2,TRUE);
DoSort(); //Sortthegrid}32a//MergetheCommonsubseq代碼分析:·函數(shù)循環(huán)處理控件中所有行,給每個(gè)單元格中放入數(shù)據(jù)。通過(guò)調(diào)用控件的GetRows方法可獲得控件中總行數(shù),而調(diào)用控件的GetFixedRows方法可獲得有標(biāo)題行的編號(hào)。通過(guò)調(diào)用控件的SetTextArray方法可把數(shù)據(jù)添加到控件單元格中,調(diào)用該方法的兩個(gè)參數(shù)是由函數(shù)GetID獲取單元格的ID和使用函數(shù)RandomStringValue產(chǎn)生要放入控件單元格的數(shù)據(jù)。這兩個(gè)函數(shù)都是CActiveXDlg類(lèi)的新增成員函數(shù)?!ぐ褦?shù)據(jù)放入表格單元格后,調(diào)用控件的方法SetMergeCol,用于通知控件,如果相鄰行有著同樣的值,可以把前三列的單元格合并?!ぷ詈螅褂昧硪粋€(gè)CActiveXDlg類(lèi)的新增函數(shù)來(lái)完成單元格數(shù)據(jù)的排序。33a代碼分析:33a2計(jì)算單元格ID控件FlexGrid
的單元格按從左至右、從上至下編號(hào)。計(jì)算單元格ID的函數(shù)GetID
的訪(fǎng)問(wèn)權(quán)限為private,其定義代碼如下:intCActiveXDlg::GenID(intm_iRow,intm_iCol){intliCols=m_ctrlFGrid.GetCols(); //Getthenumberofcolumnreturn(m_iCol+liCols*m_iRow); //GenerateanID}3生成隨機(jī)數(shù)據(jù)實(shí)現(xiàn)這一功能的函數(shù)RandomStringValue將根據(jù)參數(shù)——單元格的當(dāng)前列號(hào)分別為第一列產(chǎn)生隨機(jī)的銷(xiāo)售區(qū)域名,為第二列產(chǎn)生隨機(jī)的銷(xiāo)售產(chǎn)品名,為第三列產(chǎn)生隨機(jī)的銷(xiāo)售人員名。該函數(shù)的訪(fǎng)問(wèn)權(quán)限也為private,其定義代碼如下:34a2計(jì)算單元格ID34aCStringCActiveXDlg::RandomStringValue(intm_iColumn){
CStringlsStr; //ThereturnstringintliCase; //ArandomvalueID//Whichcolumnarewegeneratingforswitch(m_iColumn){case0: //Thefirstcolumn(region)liCase=(rand()%5);//Generatearandomvaluebetween0and4
//Whatvaluewasgenerated?switch(liCase){case0: //0-Northwestregion lsStr="Northwest"; break;35aCStringCActiveXDlg::RandomStrcase1: //1-Southwestregion lsStr="Southwest"; break;case2: //2-Midwestregion lsStr="Midwest"; break;case3: //3-Northeastregion lsStr="Northeast"; break;case4: //4-Southeastregion lsStr="Southeast"; break;}break;case1: //Thesecondcolumn(product)liCase=(rand()%5);//Generatearandomvaluebetween0and4//Whatvaluewasgenerated?36acase1: //1-Southweswitch(liCase){ case0: //0-Dodads lsStr="Dodads"; break;case1: //1-Thingamajigs lsStr="Thingamajigs"; break;case2: //2-Whatchamacallits lsStr="Whatchamacallits"; break;case3: //3-RoundTuits lsStr="RoundTuits"; break;default: //4-Widgets lsStr="Widgets";}break;37aswitch(liCase)37acase2: //Thethirdcolumn(employee)liCase=(rand()%4);//generatearandomvaluebetween0and3//Whatvaluewasgenerated?switch(liCase){case0: //0-Dore lsStr="Dore"; break;case1: //1-Harvey lsStr="Harvey"; break;case2: //2-Pogo lsStr="Pogo"; break;default: //3-Nyra lsStr="Nyra"; }38acase2: //Thethirdcolumbreak;}
//ReturnthegeneratedstringreturnlsStr;}39abreak;39a4為控件中顯示數(shù)據(jù)排序?yàn)镃ActivexDlg類(lèi)定義私有成員函數(shù)DoSort用以調(diào)用FlexGrid控件的排序函數(shù)SetSort實(shí)現(xiàn)對(duì)控件的排序。排序的方式是升序還是降序取決于調(diào)用SetSort的參數(shù)。其定義代碼如下:voidCActiveXDlg::DoSort(){//Setthecurrentcolumntocolumn0m_ctrlFGrid.SetCol(0);
//Setthecolumnselectiontoallcolumnsm_ctrlFGrid.SetColSel((m_ctrlFGrid.GetCols()-1));
//GenericAscendingsort
m_ctrlFGrid.SetSort(1);}40a4為控件中顯示數(shù)據(jù)排序40a5修改CActiveXDlg::OnInitDialog在此函數(shù)中加入對(duì)函數(shù)LoadData的調(diào)用,實(shí)現(xiàn)對(duì)FlexGrid控件的初始化。BOOLCActiveXDlg::OnInitDialog(){
CDialog::OnInitDialog();…
LoadData(); //LoaddataintotheGridcontrol…returnTRUE;//returnTRUEunlessyousetthefocustoacontrol}6編譯運(yùn)行“ActiveX”41a5修改CActiveXDlg::OnInitDialog響應(yīng)控件事件運(yùn)行上面的程序,你會(huì)發(fā)現(xiàn)FlexGrid控件對(duì)任何輸入事件都沒(méi)有響應(yīng)。這是因?yàn)殡m然ActiveX控件為VisualC++應(yīng)用程序提供了多種事件,但大多數(shù)ActiveX
控件并沒(méi)有與可用事件相關(guān)聯(lián)的缺省功能,而必須告訴控件在每個(gè)事件發(fā)生時(shí)做些什么。在本例中,我們將添加兩個(gè)控件事件的響應(yīng),使用戶(hù)可以按住鼠標(biāo)左或右鍵選中列標(biāo)題并將它拖動(dòng)到另一個(gè)位置,從而重新安排列的順序。實(shí)現(xiàn)此功能,必須捕獲兩個(gè)控件事件:鼠標(biāo)左或右鍵被按下和被釋放?!ぴ谑髽?biāo)按鈕按下事件中:需要檢查用戶(hù)單擊了列標(biāo)題,如果是,應(yīng)捕獲所選中的列。42a響應(yīng)控件事件42a·在鼠標(biāo)按鈕釋放事件中:需要將所捕獲的列移動(dòng)到鼠標(biāo)被釋放時(shí)所處的列位置。要完成這項(xiàng)功能,還需要在CActiveXDlg
類(lèi)中增加一個(gè)私有數(shù)據(jù)成員,用于保存所捕獲列的列號(hào),所添加的代碼如下:…
private:
intm_iMouseCol;1捕獲所選列·使用ClassWizard為IDC_MSFGRID控件對(duì)象的MouseDown事件消息添加響應(yīng)函數(shù);·編寫(xiě)函數(shù)代碼如下:43a·在鼠標(biāo)按鈕釋放事件中:需要將所捕獲的列移動(dòng)到鼠標(biāo)被釋43avoidCActiveXDlg::OnMouseDownMsfgrid(shortButton,shortShift, longx,longy){//TODO:Addyourcontrolnotificationhandlercodehere//Didtheuserclickonadatarowandnottheheaderrow?if(m_ctrlFGrid.GetMouseRow()!=0){
//Ifso,thenzerooutthecolumnvariableandexitm_iMouseCol=0;return;}
//SavethecolumnClickedonm_iMouseCol=
m_ctrlFGrid.GetMouseCol();}44avoidCActiveXDlg::OnMouseDownM2把列移動(dòng)到鼠標(biāo)被釋放處·使用ClassWizard為IDC_MSFGRID
控件對(duì)象的MouseUp事件消息添加響應(yīng)函數(shù);·編寫(xiě)函數(shù)代碼如下:voidCActiveXDlg::OnMouseUpMsfgrid(shortButton,shortShift, longx,longy){//TODO:Addyourcontrolnotificationhandlercodehere//Iftheselectedcolumnwasthefirstcolumn,there'snothingtodoif(m_iMouseCol==0)return;m_ctrlFGrid.SetRedraw(FALSE); //Turnthecontrolredrawoffm_ctrlFGrid.SetColPosition(m_iMouseCol, m_ctrlFGrid.GetMouseCol());
//Changetheselectedcolumnposition45a2把列移動(dòng)到鼠標(biāo)被釋放處45aDoSort(); //Resortthegridm_ctrlFGrid.SetRedraw(TRUE); //Trunredrawbackon}這兩個(gè)事件消息的映射如下:BEGIN_EVENTSINK_MAP(CActiveXDlg,CDialog)
//{{AFX_EVENTSINK_MAP(CActiveXDlg)
ON_EVENT(CActiveXDlg,IDC_MSFGRID,-605/*MouseDown*/,
OnMouseDownMsfgrid,VTS_I2VTS_I2VTS_I4VTS_I4)
ON_EVENT(CActiveXDlg,IDC_MSFGRID,-607/*MouseUp*/,
OnMouseUpMsfgrid,VTS_I2VTS_I2VTS_I4VTS_I4)
//}}AFX_EVENTSINK_MAPEND_EVENTSINK_MAP()3編譯運(yùn)行“ActiveX”46aDoSort(); //Resorttheg12.3創(chuàng)建ActiveX控件本例通過(guò)制作一個(gè)能繪制涂鴉的控件實(shí)例,描述一個(gè)ActiveX控件的一般創(chuàng)建方法,并通過(guò)測(cè)試工具和一個(gè)應(yīng)用實(shí)例來(lái)驗(yàn)證該控件的設(shè)計(jì)功能?!た丶δ埽耗茉谝粋€(gè)可確定的矩形區(qū)域中通過(guò)點(diǎn)擊鼠標(biāo)或通過(guò)其他方法獲得模擬的鼠標(biāo)點(diǎn)擊事件,以便隨機(jī)繪制涂鴉,并且能將所繪制的涂鴉保存到一個(gè)磁盤(pán)文件中和能使用該磁盤(pán)文件所保存的數(shù)據(jù)恢復(fù)涂鴉。為實(shí)現(xiàn)這些功能,所設(shè)計(jì)的控件應(yīng)具有以下屬性、方法和事件:47a12.3創(chuàng)建ActiveX控件47a·控件屬性:屬性是指控件中可見(jiàn)的、容器應(yīng)用程序可修改的屬性數(shù)據(jù)。四種基本的屬性類(lèi)型是:
環(huán)境(ambient) 由容器應(yīng)用程序提供給控件,例如,背景 顏色或缺省字體,使控件看上去就像是容器應(yīng)用程序的
一部分;擴(kuò)展(extended) 由容器應(yīng)用程序提供并實(shí)現(xiàn)的屬性,控件 可以對(duì)這些屬性做一定擴(kuò)展;
庫(kù)存(stock) 由ActiveX控件開(kāi)發(fā)工具實(shí)現(xiàn),例如控件的 字體或控件的背景顏色;
定制(custom) 是最需要關(guān)注的屬性,因?yàn)檫@些屬性是所 設(shè)計(jì)的控件專(zhuān)有的,并且直接與控件的功能有關(guān)。 本例需要三個(gè)custom屬性:48a·控件屬性:屬性是指控件中可見(jiàn)的、容器應(yīng)用程序可修改的48a
NumberSquiggles 繪制涂鴉的最多段數(shù);
SquiggleLength 一段涂鴉的最大長(zhǎng)度;
KeepCurrentDrawing 是否保持當(dāng)前所繪制的涂鴉。為了能在容器應(yīng)用程序中訪(fǎng)問(wèn)和修改這些屬性還需要為每個(gè)屬性提供相應(yīng)的Get和Set
方法,即把這些屬性“暴露”給容器
應(yīng)用程序。·控件方法:是控件中的能被容器應(yīng)用程序調(diào)用的函數(shù)。在本控件中除了要提供三個(gè)屬性的訪(fǎng)問(wèn)和設(shè)置方法,以及顯示控件版本信息的方法外,還需要提供下列三個(gè)與控件功能密切相關(guān)的方法:
DoClick 用于模擬在控件區(qū)域內(nèi)鼠標(biāo)點(diǎn)擊操作;
SaveDrawing 用于保存當(dāng)前的涂鴉為一個(gè)磁盤(pán)文件;
LoadDrawing 使用磁盤(pán)文件中保存的數(shù)據(jù)恢復(fù)涂鴉。49a NumberSquiggles 繪制涂鴉的最多段數(shù);49a·控件事件:事件是控件發(fā)給容器應(yīng)用程序的通知消息。它們用于通知容器應(yīng)用程序某種事件已經(jīng)發(fā)生,以便容器應(yīng)用程序在需要時(shí)采取相應(yīng)的措施。從控件中可以觸發(fā)兩類(lèi)事件:
庫(kù)存事件 通過(guò)ActiveX控件開(kāi)發(fā)工具實(shí)現(xiàn),可以在控件內(nèi)以 函數(shù)調(diào)用的方式使用,也可以使你觸發(fā)容器應(yīng)用程序中 的鼠標(biāo)或鍵盤(pán)事件、錯(cuò)誤或狀態(tài)的變化。定制事件 這些事件與控件的特定功能相關(guān)聯(lián)。這類(lèi)事件可 以指定與事件一起傳遞給容器的參數(shù),使容器能得到所 需要的數(shù)據(jù),以便對(duì)事件消息作出反應(yīng)。本控件中定義了三個(gè)事件:
click
庫(kù)存事件,通知在控件區(qū)域中發(fā)生了鼠標(biāo)點(diǎn)擊;
FileStored
定制事件,通知當(dāng)前保存涂鴉已經(jīng)成功或失??;
FileLoaded
定制事件,通知當(dāng)前恢復(fù)涂鴉已經(jīng)成功或失敗。50a·控件事件:事件是控件發(fā)給容器應(yīng)用程序的通知消息。它們50a12.3.1創(chuàng)建控件外殼使用MFCActiveXControlWizard(控件創(chuàng)建向?qū)В橐獎(jiǎng)?chuàng)建的任何ActiveX控件建立一個(gè)“外殼”(“Squiggle”ActiveX控件項(xiàng)目)。它將生成所有必要的文件,并配置項(xiàng)目,這樣在編譯項(xiàng)目時(shí),編譯器就會(huì)建立一個(gè)ActiveX控件。在VisualC++6.0中,該項(xiàng)目創(chuàng)建的方法和操作步驟如下:51a12.3.1創(chuàng)建控件外殼51a52a52a創(chuàng)建此項(xiàng)目需要經(jīng)過(guò)下列兩步:1在“Step1of2”對(duì)話(huà)框中進(jìn)行如下操作:
53a創(chuàng)建此項(xiàng)目需要經(jīng)過(guò)下列兩步:53a·確定項(xiàng)目中包含幾個(gè)ActiveX控件,默認(rèn)的控件數(shù)為1?!ご_定所創(chuàng)建的控件是否需要運(yùn)行時(shí)許可證,這是一種防止控件的使用者在沒(méi)有購(gòu)買(mǎi)運(yùn)行時(shí)許可證的情況下使用控件進(jìn)行開(kāi)發(fā)的措施。默認(rèn)選擇為不需要運(yùn)行時(shí)許可證?!ご_定是否為程序源代碼生成注釋?zhuān)J(rèn)選擇為生成注解?!ご_定是否為控件生成幫助文件,默認(rèn)選擇為沒(méi)有幫助文件。本例中均使用默認(rèn)選擇。54a·確定項(xiàng)目中包含幾個(gè)ActiveX控件,默認(rèn)的控件數(shù)為12在“Step2of2”對(duì)話(huà)框中繼續(xù)進(jìn)行下列操作:·如果需要,可以選擇瀏覽或修改控件的類(lèi)名和文件名。組合列表框中包含了項(xiàng)目中所有要?jiǎng)?chuàng)建的ActiveX控件類(lèi)名。55a2在“Step2of2”對(duì)話(huà)框中繼續(xù)進(jìn)行下列操作·選擇所創(chuàng)建的控件具有的特性:①控件在可見(jiàn)時(shí)被激活(默認(rèn)特性);②運(yùn)行時(shí)不可見(jiàn);③在“InsertObject”對(duì)話(huà)框中可使用;④具有版本對(duì)話(huà)框“About”(默認(rèn)特性);⑤作用為一個(gè)簡(jiǎn)單的框架控件?!みx擇一種窗口類(lèi)(在組合列表框中列出的)作為所創(chuàng)建控件
的子類(lèi),例如,欲創(chuàng)建一個(gè)特殊的編輯框,以便對(duì)用戶(hù)輸入該編輯框的任何內(nèi)容進(jìn)行一些編輯,就可以選擇EDIT類(lèi)作為
控件的子類(lèi)。默認(rèn)選擇為不選擇任何窗口類(lèi),即none。56a·選擇所創(chuàng)建的控件具有的特性:56a·按Advanced按鈕可以進(jìn)行高級(jí)設(shè)置,但要求對(duì)ActiveX控件有相當(dāng)深入的了解,所以一般可以不做此項(xiàng)選擇。本例中均使用默認(rèn)選擇。3按《Finish》按鈕完成ActiveX控件外殼的創(chuàng)建。57a·按Advanced按鈕可以進(jìn)行高級(jí)設(shè)置,但要求對(duì)Ac在VisualC++.NET中,該項(xiàng)目創(chuàng)建的方法和操作步驟如下:1創(chuàng)建一個(gè)名為“Squiggle”ActiveX控件項(xiàng)目:58a在VisualC++.NET中,該項(xiàng)目創(chuàng)建的方法和操2保持該ActiveX控件項(xiàng)目不具有運(yùn)行許可證的缺省設(shè)置:59a2保持該ActiveX控件項(xiàng)目不具有運(yùn)行許可證的缺省設(shè)3保持該ActiveX控件項(xiàng)目的所有命名缺省設(shè)置:60a3保持該ActiveX控件項(xiàng)目的所有命名缺省設(shè)置:604保持該ActiveX控件項(xiàng)目的所有控件屬性缺省設(shè)置:5按《Finish》按鈕完成ActiveX控件外殼的創(chuàng)建。61a4保持該ActiveX控件項(xiàng)目的所有控件屬性缺省設(shè)置:12.3.2增加進(jìn)行繪制涂鴉的類(lèi)CLine和CModArt1CLine類(lèi)分解涂鴉的繪制操作是由一系列的隨機(jī)線(xiàn)段(線(xiàn)段的位置、長(zhǎng)度、顏色和線(xiàn)寬均隨機(jī)發(fā)生)組成的。因此,創(chuàng)建一個(gè)類(lèi)CLine,將描述這些線(xiàn)段的屬性和操作封裝在其中,并在整個(gè)涂鴉的繪制過(guò)程中,逐個(gè)隨機(jī)創(chuàng)建CLine類(lèi)對(duì)象。⑴定義CLine類(lèi)使用ClassWizard定義一個(gè)GenericClass類(lèi)CLine,并在Base
Class列表框的第一行輸入CObject作為基類(lèi),保留其public屬性。62a12.3.2增加進(jìn)行繪制涂鴉的類(lèi)CLine和CMod注意:①由于編譯器找不到CObject類(lèi)的定義,因此,會(huì)在確認(rèn)定義CLine類(lèi)時(shí),顯示如下信息框:63a63a你可以不必理會(huì)它,而按“確認(rèn)”按鈕完成CLine的創(chuàng)建。但如果你使用的基類(lèi)是比MFC類(lèi)層次更低的自定義類(lèi),則需要留意此信息,并將必須的頭文件包含(#include)到源代碼文件中。②在VisualC++.NET中,定義CLine時(shí)不會(huì)發(fā)生上述問(wèn)題。64a64a②為了使CLine類(lèi)具有持續(xù)性,需要在CLine類(lèi)的定義文件中加入宏: classCLine:publicCObject {
DECLARE_SERIAL(CLine) … };在實(shí)現(xiàn)文件中加入如下宏: …
IMPLEMENT_SERIAL(CLine,CObject,1) …65a②為了使CLine類(lèi)具有持續(xù)性,需要在CLi⑵為CLine類(lèi)增加描述線(xiàn)段的屬性classCLine:publicCObject{…private:
COLORREFm_crColor; //線(xiàn)段顏色
CPointm_ptFrom; //線(xiàn)段起點(diǎn)
CPointm_ptTo; //線(xiàn)段終點(diǎn)
UINTm_pnWidth; //畫(huà)筆寬度};66a⑵為CLine類(lèi)增加描述線(xiàn)段的屬性66a⑶增加一個(gè)能為線(xiàn)段屬性賦值的構(gòu)造函數(shù)CLine::CLine(CPointptFrom,CPointptTo, UINTpnWidth,COLORREFcrColor){
//Initializethefromandtopointsm_ptFrom=ptFrom;m_ptTo=ptTo;m_pnWidth=pnWidth;m_crColor=crColor;}67a⑶增加一個(gè)能為線(xiàn)段屬性賦值的構(gòu)造函數(shù)67a⑷定義繪制線(xiàn)段的成員函數(shù)Draw并為其編碼voidCLine::Draw(CDC*pDC){ //Createapen
CPenlpen(PS_SOLID,m_pnWidth,m_crColor); //Setthenewpenasthedrawingobject
CPen*pOldPen=pDC->SelectObject(&lpen); //Drawtheline pDC->MoveTo(m_ptFrom); pDC->LineTo(m_ptTo); //Resetthepreviouspen pDC->SelectObject(pOldPen);}68a⑷定義繪制線(xiàn)段的成員函數(shù)Draw并為其編碼68a⑸手工重載CObject的持續(xù)化虛成員函數(shù)Serialize并為其編碼voidCLine::Serialize(CArchive&ar){
CObject::Serialize(ar);if(ar.IsStoring())ar<<m_ptFrom<<m_ptTo<<(DWORD)m_crColor<<m_pnWidth;elsear>>m_ptFrom>>m_ptTo>>(DWORD)m_crColor>>m_pnWidth;}69a⑸手工重載CObject的持續(xù)化虛成員函數(shù)Seriali2CModArt類(lèi)創(chuàng)建此類(lèi)的目的就是要實(shí)現(xiàn)對(duì)一個(gè)完整涂鴉畫(huà)面的描述和圍繞繪制涂鴉所需要的所有操作。⑴定義CModArt
類(lèi)與定義CLine類(lèi)相似,使用ClassWizard創(chuàng)建一個(gè)GenericClass類(lèi)CModArt,并在BaseClass列表框的第一行輸入CObject作為基類(lèi),保留其public屬性。雖然CModArt類(lèi)也需要實(shí)現(xiàn)持續(xù)性,但不需要在類(lèi)定義文件和實(shí)現(xiàn)文件中加入實(shí)現(xiàn)持續(xù)性的宏,原因是CModArt的持續(xù)性可以通過(guò)CLine的持續(xù)性實(shí)現(xiàn)。70a2CModArt類(lèi)70a⑵為CModArt類(lèi)增加描述整幅涂鴉的屬性classCModArt:publicCObject{public:…CRectm_rDrawArea; //繪制涂鴉的區(qū)域
CObArraym_oaLines; //用于存放組成涂鴉的所有線(xiàn)段的數(shù)組…private:
intm_iLength; //組成一條涂鴉線(xiàn)的最多線(xiàn)段數(shù)
intm_iSegments; //組成整幅涂鴉畫(huà)面的最多涂鴉線(xiàn)數(shù)…};71a⑵為CModArt類(lèi)增加描述整幅涂鴉的屬性71a⑶為CModArt添加一些訪(fǎng)問(wèn)和修改屬性的公有成員函數(shù)intCModArt::GetLength(){
//Returnthecurrentvalueforthem_iLengthvariablereturnm_iLength;}voidCModArt::SetLength(intiLength){
//Setthecurrentvalueforthem_iLengthvariablem_iLength=iLength;}72a⑶為CModArt添加一些訪(fǎng)問(wèn)和修改屬性的公有成員函數(shù)intCModArt::GetSegments(){
//Returnthecurrentvalueforthem_iSegmentsvariablereturnm_iSegments;}voidCModArt::SetSegments(intiSegments){
//Setthecurrentvalueforthem_iSegmentsvariablem_iSegments=iSegments;}voidCModArt::SetRect(CRectrDrawArea){
//Setthedrawingarearectanglem_rDrawArea=rDrawArea;}73aintCModArt::GetSegments()73a⑷為CModArt添加生成一條涂鴉線(xiàn)的私有成員函數(shù)voidCModArt::NewLine(){intlNumLines,lCurLine;UINTnCurWidth;CPointpTo,pFrom;intcRed,cBlue,cGreen;
//Normalizetherectanglebeforedeterminingthewidthandheightm_rDrawArea.NormalizeRect();
//GettheareawidthandheightintlWidth=m_rDrawArea.Width();intlHeight=m_rDrawArea.Height();
//DeterminethenumberofpartstothissquigglelNumLines=rand()%m_iLength;
//Arethereanypartstothissquiggle?74a⑷為CModArt添加生成一條涂鴉線(xiàn)的私有成員函數(shù)74if(lNumLines>0){//DeterminethecolorcRed=rand()%256;cBlue=rand()%256;cGreen=rand()%256;
//DeterminethepenwidthnCurWidth=(rand()%8)+1;
//DeterminethestratpointforthesquigglepFrom.x=(rand()%lWidth)+m_rDrawArea.left;pFrom.y=(rand()%lHeight)+m_rDrawArea.top;
//Loopthroughthenumberofsegmentsfor(lCurLine=0;lCurLine<lNumLines;lCurLine++){ //Determinetheendpointofthesegment pTo.x=((rand()%23)-10)+pFrom.x; pTo.y=((rand()%23)-10)+pFrom.y;
//CreateanewClineobject
CLine*pLine=newCLine(pFrom,pTo,nCurWidth,
RGB(cRed,cBlue,cGreen));75aif(lNumLines>0)75a
try
//Addthenewlinetotheobjectarray m_oaLines.Add(pLine);
//Didwerunintoamemoryexception
catch(CMemoryException*perr) {//Displayamessgefortheuser,givinghimthebadnews
AfxMessageBox("Outofmemory",MB_ICONSTOP|MB_OK);
//Didwecreatealineobject? if(pLine)
deletepLine;pLine=NULL; //Deleteit perr->Delete(); //Deletetheexceptionobject } pFrom=pTo; //Setthestartingpointtotheendpoint}}}76a try//Addthenewlineto⑸為CModArt添加生成整幅涂鴉的公有成員函數(shù)voidCModArt::NewDrawing(){intlNumLines,lCurLine;
//DeterminehowmanylinestocreatelNumLines=rand()%m_iSegments;
//Arethereanylinestocreate?if(lNumLines>0){//Loopthroughthenumberoflinesfor(lCurLine=0;lCurLine<lNumLines;lCurLine++)
NewLine(); //Createthenewline}}77a⑸為CModArt添加生成整幅涂鴉的公有成員函數(shù)77a⑹修改CModArt的構(gòu)造函數(shù)CModArt::CModArt(){
//Initializetherandomnumbergenerator
srand((unsigned)time(NULL));
//Initializetheproptyvariablesm_iLength=200;m_iSegments=50;}78a⑹修改CModArt的構(gòu)造函數(shù)78a⑺為CModArt添加繪制整幅涂鴉的公有成員函數(shù)DrawvoidCModArt::Draw(CDC*pDC){//GetthenumberoflinesintheobjectarrayintliCount=m_oaLines.GetSize();intliPos;
//Aretheranyobjectsinthearray?if(liCount){//Loopthroughthearray,drawingeachobjectfor(liPos=0;liPos<liCount;liPos++) ((CLine*)m_oaLines[liPos])->Draw(pDC);}}79a⑺為CModArt添加繪制整幅涂鴉的公有成員函數(shù)Dr⑻為CModArt添加清除整幅涂鴉的公有成員函數(shù)ClearDrawingvoidCModArt::ClearDrawing(){//GetthenumberoflinesintheobjectarrayintliCount=m_oaLines.GetSize();intliPos;if(liCount) //Arethereanyobjectsinthearray{//Loopthroughthearray,deletingeachobjectfor(liPos=0;liPos<liCount;liPos++)
deletem_oaLines[liPos];m_oaLines.RemoveAll();//Resetthearray}}80a⑻為CModArt添加清除整幅涂鴉的公有成員函數(shù)Cl⑼為CModArt重載持續(xù)化函數(shù)SerializevoidCModArt::Serialize(CArchive&ar){//Passthearchiveobjectontothearraym_oaLines.Serialize(ar);}顯然,CModArt類(lèi)的持續(xù)化操作是通過(guò)數(shù)組中保存的CLine類(lèi)對(duì)象的持續(xù)化函數(shù)實(shí)現(xiàn)的。在控件類(lèi)CSquiggleCtrl中添加CModArt類(lèi)對(duì)象m_maDrawing,訪(fǎng)問(wèn)權(quán)限為私有。該對(duì)象成員用于在控件中調(diào)用CModArt的方法實(shí)現(xiàn)繪制涂鴉。注意在CSquiggleCtrl類(lèi)的定義文件中包含CModArt類(lèi)的頭文件。81a⑼為CModArt重載持續(xù)化函數(shù)Serialize812.3.3為控件添加屬性為了在使用控件時(shí)能訪(fǎng)問(wèn)和修改CModArt的屬性m_iLength
和m_iSegments,需要為CSquiggleCtrl添加相應(yīng)的屬性。1添加屬性SquiggleLength⑴在DSquiggle處,單擊鼠標(biāo)右鍵,彈出環(huán)境菜單,并選擇菜單項(xiàng)“AddProperty…”:82a12.3.3為控件添加屬性82a在VisualC++6.0中: 在VisualC++>NET中:83a在VisualC++6.0中: ⑵在“AddProperty”對(duì)話(huà)框中,將該屬性命名為
SquiggleLength, 并指定其類(lèi)型為short
或SHORT類(lèi)型。接受系統(tǒng)自動(dòng)為該屬 性命名的內(nèi)部變量名m_squiggleLength或m_SquiggleLength,以 及為該屬性自動(dòng)增加的通知函數(shù)OnSquiggleLengthChanged。保 持缺省的屬性實(shí)現(xiàn)類(lèi)型(Membervariable)。單擊《OK》或 《Finish》按鈕,完成該屬性的添加操作。 上述操作如下圖所示:84a⑵在“AddProperty”對(duì)話(huà)框中,將該屬性命名在VisualC++6.0中:85a在VisualC++6.0中:85a在VisualC++.NET中:86a在VisualC++.NET中:86a⑶為OnSquiggleLengthChanged添加執(zhí)行代碼:在VisualC++6.0中的代碼如下:shortCSquiggleCtrl::OnSquiggleLengthChanged(){m_maDrawing.SetLength(m_squiggleLength); //添加的代碼
SetModifiedFlag(); //缺省代碼}在VisualC++.NET中的代碼如下:voidCSquiggleCtrl::OnSquiggleLengthChanged(){
AFX_MANAGE_STATE(AfxGetStaticModuleState()); //缺省代碼m_maDrawing.SetLength(m_squiggleLength); //添加的代碼
SetModifiedFlag(); //
缺省代
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2031年中國(guó)全棉印花羅紋布行業(yè)投資前景及策略咨詢(xún)研究報(bào)告
- 2025至2030年中國(guó)被動(dòng)紅外夜視儀數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 技術(shù)服務(wù)成果轉(zhuǎn)化路徑與模式探索考核試卷
- 2025-2030年手工雕刻工具行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 2025-2030年商業(yè)智能垃圾分類(lèi)處理平臺(tái)行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 2025-2030年即食魚(yú)豆腐干企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報(bào)告
- 2025-2030年聲紋識(shí)別認(rèn)證技術(shù)企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報(bào)告
- 2025-2030年手工刺繡定制西裝套裝企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報(bào)告
- 2025-2030年商場(chǎng)智能停車(chē)引導(dǎo)行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢(xún)報(bào)告
- 2025-2030年手持式金屬探測(cè)器行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 2025年大慶職業(yè)學(xué)院高職單招語(yǔ)文2018-2024歷年參考題庫(kù)頻考點(diǎn)含答案解析
- 2025年中國(guó)南方航空股份有限公司招聘筆試參考題庫(kù)含答案解析
- 商務(wù)部發(fā)布《中國(guó)再生資源回收行業(yè)發(fā)展報(bào)告(2024)》
- 山東省濟(jì)南市2024-2024學(xué)年高三上學(xué)期1月期末考試 地理 含答案
- 2025年福建新華發(fā)行(集團(tuán))限責(zé)任公司校園招聘高頻重點(diǎn)提升(共500題)附帶答案詳解
- 實(shí)施彈性退休制度暫行辦法解讀課件
- 冷凍食品配送售后服務(wù)體系方案
- 江蘇省駕??荚嚳颇恳豢荚囶}庫(kù)
- 四川省成都市青羊區(qū)成都市石室聯(lián)合中學(xué)2023-2024學(xué)年七上期末數(shù)學(xué)試題(解析版)
- 中華護(hù)理學(xué)會(huì)團(tuán)體標(biāo)準(zhǔn)-氣管切開(kāi)非機(jī)械通氣患者氣道護(hù)理
- 曹晶《孫悟空大鬧蟠桃會(huì)》教學(xué)設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論