vc++技術(shù)內(nèi)幕(第四版)筆記(第8章)最近很多朋友喜歡上設(shè)計(jì),但是大家卻不知道如何去做,別擔(dān)心有圖老師給你解答,史上最全最棒的詳細(xì)解說(shuō)讓你一看就懂。 第八章:使用ActiveX控件 1,ActiveX控件是一個(gè)直接插入到C++程序中的軟件模塊,以前常稱OLE控件(OCX),是基于MS-COM技術(shù)。 2,ActiveX控件與普通Windows控件比較: 相同點(diǎn):ActiveX控件也可看成是一個(gè)子窗口(可以看成這樣的)。 如果想在對(duì)話框上加入ActiveX控件,則只要在對(duì)話框編輯器中,把ActiveX控件放在適當(dāng)?shù)奈恢蒙?,并在資源模板中標(biāo)識(shí)該控件。如果要在運(yùn)行的過(guò)程中建立ActiveX控件,則可以調(diào)用響應(yīng)控件類的Create成員函數(shù),而且通常在父窗口的WM_CREATE消息控制函數(shù)中調(diào)用。 不同點(diǎn):屬性和方法。 ActiveX控件不像普通控件那樣發(fā)送以WM_打頭的通知消息給它的包容器窗口,而是激發(fā)事件。事件實(shí)際上是由控件調(diào)用包容器函數(shù)。像普通的控件通知消息一樣,事件并沒(méi)有返回值傳給ActiveX控件。事件如lick,KeyDown。但對(duì)于客戶來(lái)說(shuō)時(shí)間與控件的通知消息是一樣的。 3,在MFC庫(kù)中,ActiveX控件就像子窗口一樣,但在控件窗口和包容器窗口之間有一層重要代碼。實(shí)際上,ActiveX控件可能沒(méi)有窗口。當(dāng)調(diào)用Create函數(shù)時(shí),并不是直接建立控件窗口,而是把控件代碼載入進(jìn)來(lái),并激發(fā)一個(gè)“實(shí)地激活”(in-place activation)命令。然后ActiveX控件再建立它自己的窗口,通過(guò)MFC的CWnd類指針我們可以訪問(wèn)該窗口。不過(guò)客戶程序最好不要使用ActiveX控件的hWnd句柄。 4,通常ActiveX控件會(huì)保存在擴(kuò)展名為OCX的動(dòng)態(tài)連接庫(kù)中。包容器程序回根據(jù)Windows注冊(cè)表利用COM技術(shù)在需要的時(shí)候裝入動(dòng)態(tài)連接庫(kù)。 說(shuō)明: 1)暫時(shí)可以這樣認(rèn)為,如果使用了ActiveX控件,那么在運(yùn)行時(shí)候要裝入該ActiveX控件代碼。顯然在發(fā)布含有ActiveX控件的程序時(shí)候,必須要包含相應(yīng)的OCX文件,而且還得提供一個(gè)合適的安裝程序。 5,安裝ActiveX控件: 1)把找到的ActiveX控件動(dòng)態(tài)連接庫(kù)拷到硬盤(pán)上。 2)在WINDOWS注冊(cè)表中登記注冊(cè)。(可使用Regsvr32命令行命令) 3)在使用該控件的項(xiàng)目中安裝該控件。(選擇Project菜單,再選擇Add To Project,再選擇Components And Controls,再選擇Registered ActiveX Controls,這時(shí)列表框列出系統(tǒng)已經(jīng)注冊(cè)所有的ActiveX控件,選擇需要的控件INSERT即可。) 6,ActiveX控件包容器編程: 1)不管ActiveX控件是作為對(duì)話框控件,還是做為“子窗口”,MFC和ClassWizard都支持。 2)ActiveX控件編寫(xiě)者設(shè)計(jì)了ActiveX控件屬性供使用者在設(shè)計(jì)時(shí)訪問(wèn)。所有的ActiveX控件屬性(包括設(shè)計(jì)時(shí)屬性),在運(yùn)行時(shí)都是可以訪問(wèn)的,不過(guò)有些屬性可能被設(shè)計(jì)成只讀的。 3)當(dāng)在項(xiàng)目中插入ActiveX控件時(shí),ClassWizard就會(huì)產(chǎn)生相應(yīng)的CWnd的派生類C++類,來(lái)滿足對(duì)空間的方法和屬性進(jìn)行訪問(wèn)要求。控件的屬性和方法都有相應(yīng)的成員函數(shù),同時(shí)生成的類還有一個(gè)構(gòu)造函數(shù)可用以動(dòng)態(tài)創(chuàng)建ActiveX控件的事例。 4)當(dāng)在項(xiàng)目中插入ActiveX控件ClassWizard生成的CWnd的派生類C++類中,可以看到其成員函數(shù)的代碼中都有對(duì)InvokeHelper函數(shù)的調(diào)用,InvokeHelper函數(shù)的第一個(gè)參數(shù)都和對(duì)應(yīng)的屬性或方法在ActiveX控件中的分發(fā)(dispatch)ID(標(biāo)識(shí)ActiveX控件的方法或?qū)傩缘模┫鄬?duì)應(yīng)。通過(guò)查看ActiveX控件hlp文件可以發(fā)現(xiàn),ActiveX控件的方法在生存的C++類中都有同名的成員函數(shù)與之對(duì)應(yīng),ActiveX控件的屬性都有一組Get和Set函數(shù)對(duì)其操作,其中ActiveX控件的方法和屬性操作與生成的C++類成員函數(shù)相關(guān)聯(lián)都是通過(guò)InvokeHelper函數(shù)的調(diào)用來(lái)完成的,InvokeHelper函數(shù)的第一個(gè)參數(shù)是由Component Gallery(控件提供者)提供的。因?yàn)榻?jīng)過(guò)這樣的處理,所以我們?nèi)绻{(diào)用ActiveX控件的方法或?qū)ζ鋵傩赃M(jìn)行取和設(shè)置操作,只需調(diào)用生成的C++類對(duì)應(yīng)的成員函數(shù)便可。下面對(duì)InvokeHelper單獨(dú)說(shuō)明: CWnd::InvokeHelper 說(shuō)明: Call this member function to invoke the OLE control method or property specified by dwDispID, in the context specified by wFlags. wFlags:可以為下面些值,指明調(diào)用InvokeHelper的目的。 //[ DISPATCH_METHOD ] The member is invoked as a method. If a property has the same name, both this and the DISPATCH_PROPERTYGET flag may be set. vtRet: pvRet: pbParamInfo:一般都設(shè)置為NULL 5)AppWizard對(duì)ActiveX控件的支持是通過(guò)在生成的應(yīng)用程序類的成員函數(shù)InitInstance中插入(AfxEnableControlContainer();),同時(shí)在響應(yīng)項(xiàng)目文件的StdAfx.h文件中插入(#includeafxdisp.h)(原因可參考書(shū)P38一些說(shuō)明)。 如果項(xiàng)目中不包含這兩行,而又要加入ActiveX控件,則只要手工加入上面兩行代碼即可。 6)可以對(duì)話框編輯器來(lái)生成對(duì)話框的模板中加入一個(gè)或多個(gè)ActiveX控件,這樣我們可以在對(duì)話框模板生成的類中添加數(shù)據(jù)成員或事件控制函數(shù)來(lái)獲取ActiveX控件的屬性或?qū)ζ淇刂啤?/p> 注意:(詳細(xì)見(jiàn)書(shū)P159頁(yè)的[致WIN32程序員]) 實(shí)際上,資源模板并不是在對(duì)話框編輯器中所看的那樣。函數(shù)CDialog::DoModal在把對(duì)話框模板交給WINDOWS內(nèi)部的對(duì)話框過(guò)程之前,要先對(duì)模板進(jìn)行預(yù)處理,即:它先會(huì)去掉所有的ActiveX控件,有剩下的控件建立對(duì)話框窗口,然后再裝入ActiveX控件,激活它們并在正確的位置上創(chuàng)建它的窗口。 當(dāng)模式對(duì)話框運(yùn)行時(shí)候,MFC處理所有送給對(duì)話框消息時(shí),是不管是有普通控件發(fā)送的,還是ActiveX控件發(fā)送的。故ActiveX控件雖然不是對(duì)話框模板一部分,但用戶仍然可以用TAB鍵在所有的控件間切換。 7)調(diào)用UpdateData(FALSE)將會(huì)從所有的對(duì)話框控件中讀取所有屬性值。如果只需要得到ActiveX控件屬性的話,可以調(diào)用ActiveX控件生成的C++類中Get函數(shù)(同樣設(shè)置調(diào)用Set函數(shù)),這樣就提高了效率。 8)事例部分代碼對(duì)比說(shuō)明: 代碼一: CDataExchange dx(this,TRUE); 說(shuō)明一: CDataExchange類構(gòu)造函數(shù):(注,在MFC|SRC|AFXWIN.H中可以看到其構(gòu)造函數(shù)聲明,在MFC|SRC|WINCORE.CPP文件中可以看到其構(gòu)造函數(shù)的定義。) (本文來(lái)源于圖老師網(wǎng)站,更多請(qǐng)?jiān)L問(wèn)http://www./bianchengyuyan/)原型:CDataExchange::CDataExchange(CWnd* pDlgWnd, BOOL bSaveAndValidate); 定義: CDataExchange::CDataExchange(CWnd* pDlgWnd, BOOL bSaveAndValidate) //其中m_pDlgWnd和m_bSaveAndValidate是CDataExchange數(shù)據(jù)成員,可以通過(guò)這中方式給它們賦值。 說(shuō)明二: //CDataExchange does not have a base class. 代碼二:(是為了比較代碼一做些說(shuō)明的) (本文來(lái)源于圖老師網(wǎng)站,更多請(qǐng)?jiān)L問(wèn)http://www./bianchengyuyan/)void CActiveXDialog::DoDataExchange(CDataExchange* pDX) 來(lái)源:http://www./n/20160219/1611590.html 第二天:Microsoft基本類庫(kù)應(yīng)用程序框架 ◎MFC是C++的Microsoft Windows API,如果想要開(kāi)發(fā)WINDOWS的應(yīng)用程序當(dāng)然VC/MFC是開(kāi)發(fā)環(huán)境的首選。 這一章節(jié)主要介紹了MFC庫(kù)的優(yōu)點(diǎn),其實(shí)我本人認(rèn)為在某些特定環(huán)境下其實(shí)MFC不一定就象說(shuō)的那樣好。我想不會(huì)有人用純VC做MIS系統(tǒng)吧,太累了。我是這樣理解編程序的,如果把學(xué)編程看成學(xué)武的話,C/C++語(yǔ)言及編程思想(OOP)是內(nèi)功,API是基本功(編程思想是內(nèi)功、API是基本功這適用于任何WIN32編程,不論Visual C++、Delphi、C++Builder、VB......),VC/MFC應(yīng)該不同武功其中的一種,不同的學(xué)習(xí)方法效果不一樣,只要下工夫也都可以達(dá)到一定的境界。真正的高手是有著深厚的內(nèi)功,扎實(shí)的基本功,至于武功招數(shù)無(wú)所謂了,隨便一站不丁不八全無(wú)破綻,無(wú)招勝有招了。對(duì)不住扯遠(yuǎn)了。 C++可以通過(guò)類庫(kù)來(lái)進(jìn)行擴(kuò)展,我們除了可以使用隨編譯器提供的類庫(kù)外還可以很方便使用軟件公司銷(xiāo)售的類庫(kù)產(chǎn)品,甚至可以自己開(kāi)發(fā)。而應(yīng)用程序框架是一種類庫(kù)的超集,它定義了程序的結(jié)構(gòu)。 下面給出兩個(gè)示例程序(一個(gè)是書(shū)上的一個(gè)是我寫(xiě)的): 雷神建議: 雖然現(xiàn)在很多書(shū)都附CD,CD上有書(shū)中所有示例的源代碼,但還是應(yīng)該親自在VC6用手敲進(jìn)去。這樣可以加深印象以及感受一下編譯除錯(cuò)后程序正確運(yùn)行時(shí)的樂(lè)趣,因?yàn)槭羌兪止ご蛟?。自從我敲了近一百個(gè)代碼示例后,由于筆誤的BUG就很少了,打字速度也提高了。而且最好在原示例代碼的基礎(chǔ)上做些改動(dòng)例如別千篇一律的顯示HELLO WORLD!換點(diǎn)別的,這樣做也可以加深對(duì)示例程序的理解。 1、打開(kāi)VC++6從菜單選擇NEW,給項(xiàng)目命名為”MyApp01“。 2、選擇MFC AppWizard[exe] 選項(xiàng),除STEP 1選擇單文檔外其他STEP缺省。 3、在Class View選擇CMyApp01View類的OnDraw()成員函數(shù)雙擊會(huì)在C++編譯器看到以下內(nèi)容 書(shū)上的例子: 1、先建立一個(gè)Win32 Application的應(yīng)用程序。 2、選擇Project-Add to project-Files,分別創(chuàng)建一個(gè)名為MyApp.h和一個(gè)名為MyApp.cpp的文件。 3、添加代碼:(最好照敲以下代碼到編譯器,別用Ctrl+C/Ctrl+V) class CMyApp:public CWinApp //見(jiàn)下② class CMyFrame:public CFrameWnd //***************************************************** #include "afxwin.h" BOOL CMyApp::InitInstance () BEGIN_MESSAGE_MAP(CMyFrame,CFrameWnd) CMyFrame::CMyFrame(){ void CMyFrame::OnPaint () 5、再Ctrl+F5,哈成功了。 讓我們看看這個(gè)程序中的一些元素。 ①WinMain函數(shù):并非不存在只是已經(jīng)被隱藏在應(yīng)用程序框架內(nèi)部。 ②CMyApp類:CMyApp類的對(duì)象代表一個(gè)應(yīng)用程序,CWinApp基類決定它的大部分行為。 ③應(yīng)用程序的啟動(dòng):當(dāng)開(kāi)始運(yùn)行應(yīng)用程序時(shí)WINDOWS會(huì)調(diào)用WinMain函數(shù),WinMain會(huì)查找該應(yīng)用程序的全局對(duì)象theApp。 ④CMyApp::InitInstance成員函數(shù):發(fā)現(xiàn)theApp后自動(dòng)調(diào)用重載的虛函數(shù)InitInstance來(lái)完成主窗口的構(gòu)造和顯示工作。記住這個(gè)函數(shù)。 ⑤CWinApp::Run成員函數(shù):WinMain在調(diào)用InitInstance之后緊接著調(diào)用Run函數(shù),它被隱藏在基類中負(fù)責(zé)傳遞應(yīng)用程序的消息給相映的窗口。(我把它理解為好象SDK的窗口的過(guò)程函數(shù)不知對(duì)不對(duì)) ⑥CMyFrame類:此類的對(duì)象代表著應(yīng)用程序的主窗口。它的構(gòu)造函數(shù)調(diào)用基類CFrameWnd的Create函數(shù)創(chuàng)建具體的窗口結(jié)構(gòu)。 (本文來(lái)源于圖老師網(wǎng)站,更多請(qǐng)?jiān)L問(wèn)http://www./bianchengyuyan/)⑦CMyFrame::OnLButtonDown函數(shù):演示消息處理機(jī)制,當(dāng)鼠標(biāo)坐鍵被按下這一事件被映射到CMyFrame的OnLButtonDown函數(shù)上,如果你選擇F5進(jìn)行編譯運(yùn)行的話可以在調(diào)試窗口看到TRACE宏顯示的類似下面的信息 ⑧CMyFrame::OnPaint函數(shù):應(yīng)用程序每次重新繪制窗口都需要調(diào)用此函數(shù),將顯示"Hello World!"放在這里是因?yàn)槊看未翱诎l(fā)生變化時(shí)保證"Hello World!"被顯示,你可以試著將語(yǔ)句: 寫(xiě)在別出,例如寫(xiě)在 ⑧關(guān)閉應(yīng)用程序:用戶關(guān)閉應(yīng)用程序時(shí)會(huì)有一系列事件發(fā)生。首先CMyFrame對(duì)象被刪除,然后退出Run,進(jìn)而退出WinMain,最后刪除CMyApp對(duì)象。 通過(guò)上面的示例我們看見(jiàn)程序的大部分功能包含在基類CWinApp和CFrameWnd中,我們只寫(xiě)了很少的函數(shù),便可以完成很復(fù)雜的功能。所以應(yīng)用程序框架不僅僅是一種類庫(kù),它還定義了應(yīng)用程序的結(jié)構(gòu),除了基類外還包括WinMain函數(shù),以及用來(lái)支持消息處理、診斷、DLL、等都包含在應(yīng)用程序框架中。 來(lái)源:http://www./n/20160219/1602452.html |
|