VC++6.0入門[第三章、MFC編程概述]_第1頁
VC++6.0入門[第三章、MFC編程概述]_第2頁
VC++6.0入門[第三章、MFC編程概述]_第3頁
VC++6.0入門[第三章、MFC編程概述]_第4頁
VC++6.0入門[第三章、MFC編程概述]_第5頁
已閱讀5頁,還剩38頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、VC+6簡明教程 # #第三章MFC應(yīng)用程序概述第章應(yīng)用程序概述VC+6簡明教程 # #第三章MFC應(yīng)用程序概述VC+6簡明教程 第三章MFC應(yīng)用程序概述MicrosoftWindows是微軟公司推出的一個(gè)應(yīng)用于微機(jī)上的具有圖形用戶界面的多任務(wù)和多窗口的操作系統(tǒng)。Windows應(yīng)用程序也稱為窗口應(yīng)用程序,所有的窗口應(yīng)用程序都有著相同的窗口風(fēng)格和菜單結(jié)構(gòu),用戶界面友好,方便用戶操作。本章從剖析窗口應(yīng)用程序的基本結(jié)構(gòu)入手,繼而介紹使用MFC類庫開發(fā)的應(yīng)用程序框架結(jié)構(gòu),并介紹窗口應(yīng)用程序運(yùn)行的核心機(jī)制消息映射。學(xué)習(xí)了本章,你將對MFC應(yīng)用程序框架結(jié)構(gòu)和運(yùn)行機(jī)制有個(gè)整體的了解,為后面進(jìn)入窗口應(yīng)用程序開

2、發(fā)打下良好的基礎(chǔ)。窗口應(yīng)用程序概述窗口應(yīng)用程序的開發(fā)一般采用可視化的面向?qū)ο蟮拈_發(fā),可選擇的窗口應(yīng)用程序開發(fā)語言有VisualC+、VisualBasic、VisualJava、Dephi等等。無論采用哪一種開發(fā)語言,首先要了解窗口應(yīng)用程序的基本機(jī)制。窗口編程基礎(chǔ)窗口應(yīng)用程序運(yùn)行于Windows操作系統(tǒng),Windows操作系統(tǒng)是一個(gè)多任務(wù)操作系統(tǒng),因此窗口應(yīng)用程序的組成,支持技術(shù),基本運(yùn)行機(jī)制等與DOS應(yīng)用程序有著本質(zhì)的區(qū)別。在學(xué)習(xí)開發(fā)窗口應(yīng)用程序之前,先要對窗口應(yīng)用程序有一個(gè)概念上的了解。1窗口窗口是應(yīng)用程序與用戶進(jìn)行交互的界面,應(yīng)用程序通過窗口傳遞信息給用戶,同樣用戶通過窗口輸入數(shù)據(jù),發(fā)布

3、命令給應(yīng)用程序。Windows界面包含了豐富的標(biāo)準(zhǔn)用戶界面元素,包括窗口、圖標(biāo)、菜單、滾動(dòng)條、對話框、控件和消息框等。用戶使用這些界面元素可以方便的與應(yīng)用程序進(jìn)行交互,一個(gè)典型的窗口外觀如圖3-1所示??蛻魠^(qū)標(biāo)題欄菜單欄最小化按鈕控制菜單欄水平滾動(dòng)條關(guān)閉按鈕最大化按鈕垂直滾動(dòng)條窗口邊界圖應(yīng)用程序窗口組成在Windows編程中,各種窗口、菜單、按鈕、對話框及程序模塊等Windows的規(guī)范部件是按“對象”來組織的。為了提高開發(fā)窗口應(yīng)用程序的效率,微軟公司為用戶提供了大量能創(chuàng)建上述標(biāo)準(zhǔn)元素的API函數(shù)和C+類,并且以WindowsAPI函數(shù)庫和C+類庫的形式提供給用戶,以充分滿足構(gòu)成應(yīng)用程序操作界面

4、的需要。因此,要編寫窗口應(yīng)用程序必須了解這些標(biāo)準(zhǔn)對象的屬性及方法,這樣程序員的大量工作簡化為創(chuàng)建對象和為對象屬性賦值。標(biāo)準(zhǔn)對象具有標(biāo)準(zhǔn)的形態(tài)及標(biāo)準(zhǔn)的操作方法,并且能夠?qū)κ髽?biāo)或鍵盤操作產(chǎn)生標(biāo)準(zhǔn)的消息響應(yīng)。在后面的章節(jié)中將會(huì)陸續(xù)介紹上述窗口界面元素的創(chuàng)建原理和創(chuàng)建方法。一個(gè)窗口應(yīng)用程序可能包含一個(gè)或多個(gè)窗口,應(yīng)用程序的運(yùn)行過程即是窗口內(nèi)部、窗口與窗口之間、窗口與系統(tǒng)之間進(jìn)行數(shù)據(jù)處理與數(shù)據(jù)交換的過程。2消息和消息隊(duì)列窗口應(yīng)用程序是利用消息(Message)與其它窗口應(yīng)用程序和操作系統(tǒng)進(jìn)行信息交換的。消息的作用是通知一個(gè)應(yīng)用程序某個(gè)確定的事件的產(chǎn)生,應(yīng)用程序會(huì)對該事件產(chǎn)生響應(yīng),響應(yīng)的方式已預(yù)先在應(yīng)用程

5、序中定義,即編寫了相應(yīng)的消息處理代碼。例如當(dāng)按下鼠標(biāo)左鍵時(shí),系統(tǒng)會(huì)產(chǎn)生WM_LBUTTONDOWN消息,并通知應(yīng)用程序窗口,應(yīng)用程序接到該消息后,會(huì)檢查是否已定義消息處理函數(shù)并作出響應(yīng)。Windows操作系統(tǒng)內(nèi)核基本元件USER為所有的用戶界面元素提供支持,它用于接收和管理所有輸入消息、系統(tǒng)消息,并把它們發(fā)送給相應(yīng)應(yīng)用程序的消息隊(duì)列。消息隊(duì)列是一個(gè)系統(tǒng)定義的內(nèi)存塊,用于臨時(shí)存儲消息,或是把消息直接發(fā)給窗口過程。每個(gè)應(yīng)用程序都維護(hù)著自己的消息隊(duì)列,并從中取出消息,利用窗口函數(shù)進(jìn)行處理。如圖3-2所示。窗口應(yīng)用程序接受系統(tǒng)隊(duì)列傳遞過來的消息的步驟如下:每個(gè)窗口應(yīng)用程序都有一個(gè)WinMain()函數(shù)

6、,在該函數(shù)中會(huì)定義一個(gè)窗口句柄,當(dāng)窗口應(yīng)用程序啟動(dòng)時(shí),會(huì)使用窗口句柄注冊,操作系統(tǒng)使用窗口句柄與窗口應(yīng)用程序通信。窗口應(yīng)用程序創(chuàng)建一個(gè)或多個(gè)窗口,每一個(gè)窗口都有一個(gè)窗口處理函數(shù)(WndProc),負(fù)責(zé)窗口顯示和響應(yīng)用戶輸入。消息映射(MessageLoop)負(fù)責(zé)從消息隊(duì)列中取消息,并送回窗口,由窗口處理函數(shù)選擇合適的消息處理函數(shù)響應(yīng)消息。若窗口處理函數(shù)中沒有給出該消息的處理代碼,將由DefWindowProc函數(shù)進(jìn)行默認(rèn)處理。消息機(jī)制是窗口應(yīng)用程序運(yùn)行的核心工作機(jī)制,消息往往用一個(gè)如下的結(jié)構(gòu)體MSG來表示,其定義如下:typedefstructtagMSGHWNDhwnd;UINTmessag

7、e;WPARAMwParam;LPARAMlParam;DWORDtime;POINTpt;MSG;其中結(jié)構(gòu)成員說明如下:hwnd該消息所在的窗口句柄,若此參數(shù)為null,則可檢索所有駐留在消息隊(duì)列中的消息。message消息值,每個(gè)Windows消息都有一個(gè)消息值,該值由Windows.h頭文件中的宏定義來標(biāo)識。wParam和lParam包含有關(guān)消息的附加信息,它隨消息的不同而不同。time指定消息送至隊(duì)列的時(shí)間。pt指定消息發(fā)送時(shí)屏幕光標(biāo)的位置,其數(shù)據(jù)類型POINT也是一個(gè)結(jié)構(gòu)體,其定義如下:typedefstructtagPOINTLONGx;LONGy;POINT;Windows應(yīng)用程

8、序的消息來源有以下4種:輸入消息由鍵盤和鼠標(biāo)操作產(chǎn)生輸入消息。這一類消息首先放在系統(tǒng)消息隊(duì)列中,然后由Windows操作系統(tǒng)將它們送入應(yīng)用程序消息隊(duì)列中,由應(yīng)用程序來處理消息??丶⒂脩舨僮鞔翱诘目丶ο髸r(shí)產(chǎn)生控件消息,例如當(dāng)用戶在列表框中改動(dòng)當(dāng)前選擇或改變了復(fù)選框的狀態(tài)時(shí)就會(huì)發(fā)出控件消息。這類消息一般不進(jìn)入應(yīng)用程序消息隊(duì)列,而是直接發(fā)送到控件對象所屬的對話框窗口。系統(tǒng)消息對程序化的事件或系統(tǒng)時(shí)鐘中斷做出反映。一些系統(tǒng)消息,象DDE消息(動(dòng)態(tài)數(shù)據(jù)交換消息)要通過Windows的系統(tǒng)消息隊(duì)列,而另一些系統(tǒng)消息則不通過系統(tǒng)消息隊(duì)列,而直接送入應(yīng)用程序的消息隊(duì)列,如創(chuàng)建窗口消息。用戶消息這是程序員

9、自己定義并在應(yīng)用程序中主動(dòng)發(fā)出的,一般由應(yīng)用程序的某一部分內(nèi)部處理。3事件驅(qū)動(dòng)的程序設(shè)計(jì)Windows操作系統(tǒng)下的窗口應(yīng)用程序采用事件驅(qū)動(dòng)的程序設(shè)計(jì),與DOS操作系統(tǒng)下的面向過程的程序設(shè)計(jì)有著明顯的不同。在DOS操作系統(tǒng)下,用戶在DOS提示符后輸入一行命令及參數(shù),啟動(dòng)應(yīng)用程序并按程序指定運(yùn)行。一個(gè)程序是一系列預(yù)先定義好的操作序列的集合。程序直接控制程序事件和過程的順序,并按照某種不可改變的模式進(jìn)行工作。在窗口應(yīng)用程序下,用戶首先啟動(dòng)應(yīng)用程序,然后窗口等待用戶通過對圖形界面上的元素的操作,傳遞信息和命令,如選擇一個(gè)菜單項(xiàng)或者單擊一個(gè)按鈕。窗口應(yīng)用程序不是按事先安排好的順序來執(zhí)行的,而是由事件的發(fā)

10、生來控制邏輯。事件的發(fā)生是隨機(jī)的、不確定的,這樣就允許用戶按各種合理的順序來安排程序的流程。例如,有這樣一個(gè)簡單的應(yīng)用程序,程序的功能是計(jì)算體操全能比賽項(xiàng)目運(yùn)動(dòng)成績管理,體操全能包括四個(gè)項(xiàng)目。在一個(gè)過程驅(qū)動(dòng)的程序中,要按照如下步驟完成應(yīng)用程序功能的實(shí)現(xiàn)。輸入第一項(xiàng)運(yùn)動(dòng)員的成績。輸入第二項(xiàng)運(yùn)動(dòng)員的成績。輸入第三項(xiàng)運(yùn)動(dòng)員的成績。輸入第四項(xiàng)運(yùn)動(dòng)員的成績。計(jì)算每個(gè)運(yùn)動(dòng)員的總分。按總分排名。在過程驅(qū)動(dòng)的程序中,程序執(zhí)行的順序是確定的,如圖3-3所示。圖3-3過程驅(qū)動(dòng)程序流程示例在這種過程驅(qū)動(dòng)的程序中,首先按事先安排好的順序把所有的成績輸入,然后再計(jì)算每一個(gè)運(yùn)動(dòng)員的總分,再進(jìn)行成績排名。事件驅(qū)動(dòng)的程序的邏

11、輯順序是按事件的產(chǎn)生而決定的,事件的產(chǎn)生不是預(yù)先定義的,有著隨機(jī)性。圖3-4給出了事件驅(qū)動(dòng)程序的流程示意圖。圖3-事4件驅(qū)動(dòng)程序流程示例事件驅(qū)動(dòng)的應(yīng)用程序啟動(dòng)后,每一個(gè)事件的發(fā)生將在對應(yīng)的消息隊(duì)列中放置一條消息,這樣基于事件產(chǎn)生的輸入沒有固定的順序,用戶可以隨機(jī)選取,以任何合理的順序來輸入數(shù)據(jù)。程序開始運(yùn)行時(shí),處于等待用戶輸入事件狀態(tài),然后取得消息并作出相應(yīng)反應(yīng),處理完畢又返回并處于等待事件狀態(tài)。在這種處理邏輯中,用戶可以按需要進(jìn)入不同的事件處理,例如,可以錄入任意一個(gè)比賽項(xiàng)目,某位運(yùn)動(dòng)員的成績,而不需要考慮錄入順序,隨時(shí)計(jì)算運(yùn)動(dòng)員當(dāng)前的總分和排名。體操比賽通常是幾個(gè)項(xiàng)目同時(shí)進(jìn)行,在比賽進(jìn)行中

12、,可以實(shí)時(shí)地輸入運(yùn)動(dòng)員的得分,隨時(shí)反映每個(gè)運(yùn)動(dòng)員的當(dāng)前得分和當(dāng)前總分排名情況。4資源管理資源可分為用戶自定義資源和系統(tǒng)資源兩種。用戶自定義資源是指窗口可視元素的映像,即在前面所提及的窗口所包含的標(biāo)準(zhǔn)元素。例如菜單、對話框、工具欄等,是由每一個(gè)應(yīng)用程序各自定義的。系統(tǒng)資源是由系統(tǒng)提供給各個(gè)應(yīng)用程序共享的,常見的系統(tǒng)資源包括:設(shè)備上下文,畫刷、畫筆、字體、通信端口等。由于Windows操作系統(tǒng)是一個(gè)多任務(wù)的操作系統(tǒng),多個(gè)應(yīng)用程序要共享系統(tǒng)資源,而不能象DOS程序獨(dú)占系統(tǒng)的全部資源。系統(tǒng)資源是有限的,窗口應(yīng)用程序使用資源的模式為:請求資源,使用資源,釋放資源。如果系統(tǒng)資源在使用后不能得到及時(shí)的釋放,

13、會(huì)影響其它應(yīng)用程序使用資源,最終造成死機(jī)。系統(tǒng)資源以句柄來標(biāo)識,使用系統(tǒng)資源要通過WindowsAPI函數(shù)來實(shí)現(xiàn)安全訪問。在窗口程序設(shè)計(jì)中,用戶自定義資源與程序是分開定義的,在DevelopStudio中提供了資源管理器用于用戶自定義資源的創(chuàng)建、修改和維護(hù)。用戶可以使用資源管理器提供的模板來設(shè)計(jì)資源,保存在資源文件中,資源文件通常以.RC為后綴名。每一個(gè)用戶自定義資源都有唯一的ID標(biāo)識,可以用一個(gè)自定義的整數(shù)或一個(gè)名稱來表示。資源編譯程序最終會(huì)將資源編譯為應(yīng)用程序所能讀取的對象的二進(jìn)制映像和具體的數(shù)據(jù)結(jié)構(gòu),并存放于應(yīng)用程序的可執(zhí)行文件中或動(dòng)態(tài)連接庫中,這樣減輕了程序設(shè)計(jì)中定義和管理資源的復(fù)雜性

14、。312Windows應(yīng)用程序組成在這一節(jié)中將分析一個(gè)簡單的Win32窗口應(yīng)用程序,MFC應(yīng)用程序是建立在Win32應(yīng)用程序設(shè)計(jì)的基礎(chǔ)上的,這將幫助更好地理解一個(gè)MFC應(yīng)用程序是如何初始化的,窗口是如何創(chuàng)建的,消息是如何處理的。所有的窗口應(yīng)用程序必須包含兩個(gè)基本函數(shù):應(yīng)用程序主函數(shù)WinMain()WinMain函數(shù)定義了窗口句柄,創(chuàng)建初始化窗口并啟動(dòng)一個(gè)消息循環(huán)。窗口處理函數(shù)WinProc()WinProc函數(shù)處理所有從操作系統(tǒng)傳遞到窗口的消息。每一個(gè)窗口,無論是簡單的或復(fù)雜的,都要有一個(gè)窗口處理函數(shù)?!纠?-1】創(chuàng)建一個(gè)簡單的窗口應(yīng)用程序示例。本例的目的在于說明創(chuàng)建Windows應(yīng)用程序的

15、方法及過程。在VC集成開發(fā)平臺,執(zhí)行菜單“File”下的菜單命令“New”,打開“New”對話框。在“New”對話框中的“Project”標(biāo)簽頁中選擇“Win32Application”,在右邊輸入工程名為:Exam3_1,并確定工程文件保存位置,單擊“OK”按鈕。在隨后的向?qū)Т翱赪in32Application-step1of1中,選擇“Anemptyproject”,單擊“Finish”按鈕。在出現(xiàn)的“NewProjectInformation”對話框中,單擊“OK”按鈕,完成工程的創(chuàng)建,并回到集成開發(fā)平臺。再執(zhí)行菜單“File”下的菜單命令“New”,添加一個(gè)新的C源文件(*.cpp),

16、程序名為Exam3_1。按程序清單3-1中的代碼實(shí)現(xiàn)Exam3_1.cpp文件。編譯運(yùn)行。程序清單:創(chuàng)建一個(gè)簡單的窗口程序代碼包含應(yīng)用程序中所需的數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)的定義#include/窗口函數(shù)說明LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);/以下初始化窗口類intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow)HWNDhwnd;MSGMsg;WNDCLASSwc;charszApplicationName=Exam3_1W

17、indow;/窗口標(biāo)題名/定義窗口類wc.style=CS_HREDRAW|CS_VREDRAW;/定義窗口類型為當(dāng)窗口大小變化時(shí)窗口重畫wc.lpfnWndProc=WndProc;/定義窗口處理函數(shù)wc.cbClsExtra=0;/窗口類無擴(kuò)展wc.cbWndExtra=0;/窗口實(shí)例無擴(kuò)展wc.hInstance=hInstance;當(dāng)前實(shí)例句柄wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);/窗口的最小化圖標(biāo)為缺省圖標(biāo)wc.hCursor=LoadCursor(NULL,IDC_ARROW);/窗口采用箭頭光標(biāo)wc.hbrBackground=(HBRU

18、SH)GetStockObject(WHITE_BRUSH);/窗口背景為白色wc.lpszMenuName=NULL;/窗口中無菜單wc.lpszClassName=szApplicationName;/定義應(yīng)用程序標(biāo)題/注冊窗口類RegisterClass(&wc);/創(chuàng)建窗口hwnd=CreateWindow(szApplicationName,/窗口類名szApplicationName,/窗口的標(biāo)題名WS_OVERLAPPEDWINDOW,/窗口的風(fēng)格/窗口左上角坐標(biāo)為缺省值/窗口的高和寬為缺省值/此窗口無父窗口/此窗口無主菜單/創(chuàng)建此窗口的應(yīng)用程序的當(dāng)前句柄CW_USEDEFAUL

19、T,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);/顯示窗口ShowWindow(hwnd,nCmdShow);/繪制用戶區(qū)UpdateWindow(hwnd);/消息循環(huán)while(GetMessage(&Msg,NULL,0,0)TranslateMessage(&Msg);DispatchMessage(&Msg);returnMsg.wParam;/消息循環(huán)結(jié)束即程序終止時(shí)將信息返回系統(tǒng)/窗口函數(shù)LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMw

20、Param,LPARAMlParam)switch(message)caseWM_DESTROY:PostQuitMessage(O);/調(diào)用PostQuitMessage發(fā)出WM_QUIT消息default:/缺省時(shí)采用系統(tǒng)消息缺省處理函數(shù)returnDefWindowProc(hwnd,message,wParam,lParam);return0;J上述程序的運(yùn)行結(jié)果如圖所示:1.WinMain函數(shù)和C語言中的main(結(jié)束而結(jié)束的。WinMainintWINAPIWinM;HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,i

21、ntnCmdShow);參數(shù)說明如下:hInstance系統(tǒng)分配的窗口所屬的應(yīng)用程序的實(shí)例句柄,標(biāo)識當(dāng)前進(jìn)程的實(shí)例,它實(shí)際上是進(jìn)程所占據(jù)的地址空間的首地址,這個(gè)實(shí)例句柄是程序的唯一標(biāo)識。hPrevInstance用做檢查是否有多個(gè)程序?qū)嵗\(yùn)行,這是16位Window的殘留物,在Win32應(yīng)用程序中,這個(gè)參數(shù)始終為NULL。lpCmdLine是一個(gè)指向字符串的指針,用來保存運(yùn)行程序時(shí)的命令行參數(shù),這同main()函數(shù)中的argv參數(shù)的作用類似。nCmdShow用來指明應(yīng)用程序的主窗口的顯示方式(最大化顯示,最小化顯示,一般化顯示)。該參數(shù)經(jīng)常被ShowWindow()函數(shù)作為顯示窗口的參數(shù)。Wi

22、nMain()函數(shù)的作用是完成以下三個(gè)任務(wù):注冊窗口類;倉U建并初始化窗口;倉U建消息循環(huán)。(1)注冊窗口類每個(gè)窗口都包含著一些基本的屬性,如:窗口邊框、窗口標(biāo)題欄文字、窗口大小和位置、鼠標(biāo)、背景色、處理窗口消息函數(shù)的名稱等等。注冊的過程就是將這些屬性告訴系統(tǒng)。窗口應(yīng)用程序使用結(jié)構(gòu)體WNDCLASS描述窗口類型,它描述了窗口的樣式、窗口消息處理函數(shù)、程序句柄、圖標(biāo)、光標(biāo)、背景刷、菜單以及描述本窗口類型的結(jié)構(gòu)的名稱。首先使用數(shù)據(jù)結(jié)構(gòu)WNDCLASS定義窗口的各個(gè)屬性,再使用Windows的API函數(shù)RegisterClass()注冊窗口類。結(jié)構(gòu)體WNDCLASS定義如下:typedefstruc

23、ttagWNDCLASSUNITstyle;/指定窗口格局的整型數(shù),WNDPROClpfnWndProc;/負(fù)責(zé)控制窗口、處理窗口消息的窗口函數(shù),intcbClsExtra;/為指定這個(gè)窗口類別結(jié)構(gòu)額外分配的字節(jié)數(shù),一般設(shè)為0。intcbWndExtra;/為指定這個(gè)窗口類別中所有窗口結(jié)構(gòu)額外分配的字節(jié)數(shù),一般設(shè)為0。HANDLEhInstance;/標(biāo)志要倉建的窗口所屬應(yīng)用程序的句柄。HICONhIcon;/指定窗口的最小化圖標(biāo)句柄。HCURSORhCursor;/窗口中所使用的光標(biāo)的句柄。HBRUSHhbrBackground;/用來畫窗口背景的畫刷的句柄。LPCWSTRlpszMenuN

24、ame;/標(biāo)志窗口中的菜單資源名字的字符串。LPCWSTRlpszClassName;/標(biāo)志該窗口類別的名字的字符串。WNDCLASS;RegisterClass()函數(shù)接收的是一個(gè)WNDCLASS結(jié)構(gòu)的指針。如果注冊成功,RegisterClass()返回TRUE,否則返回FALSE。只有注冊成功后,才能創(chuàng)建窗口。(2)倉建并初始化窗口HWNDCreateWindow(LPCTSTRlpszClassName,LPCTSTRlpszTitle,DWORDdwStyle,intx,y,intnWidth,nHeight,HWNDhwndParent,如果窗口類注冊成功,下一步,便可以使用該窗口

25、類創(chuàng)建窗口。CreateWindow()函數(shù)用于創(chuàng)建窗口,該函數(shù)進(jìn)一步定義了窗口的名稱,位置,尺寸等數(shù)據(jù)。如果倉建成功,則返回一個(gè)系統(tǒng)分配的窗口句柄否則返回0。CreateWindow()函數(shù)定義如下:窗口類名窗口標(biāo)題名創(chuàng)建窗口的樣式窗口左上角坐標(biāo)窗口寬度和度高該窗口的父窗口句柄HWENUhMenu,HINSTANCEhInstance,LPVOIDlpParam);窗口主菜單句柄創(chuàng)建窗口的應(yīng)用程序當(dāng)前句柄指向一個(gè)傳遞給窗口的參數(shù)值的指針窗口創(chuàng)建成功后并沒有顯示出來,還需要調(diào)用ShowWindow()和UpdateWindow()兩個(gè)函數(shù)來顯示窗口,這兩個(gè)函數(shù)定義如下:ShowWindow(h

26、wnd,nCmdShow);UpdateWindow(hwnd);ShowWindow()函數(shù)的作用是顯示或隱藏窗口,第一個(gè)參數(shù)是要顯示的窗口的句柄,第二個(gè)參數(shù)表示窗口的顯示樣式,如SW_SHOW表示正常顯示,SW_HIDE表示隱藏。UpdateWindow()函數(shù)的作用是更新當(dāng)前窗口顯示。(3)創(chuàng)建消息循環(huán)WinMain()函數(shù)最后使用while語句創(chuàng)建一個(gè)消息循環(huán),負(fù)責(zé)從消息隊(duì)列中獲取消息,并派送消息到相應(yīng)的處理位置。最簡單的消息循環(huán)由TranslateMessage()和DispatchMessage()函數(shù)組成,格式如下:while(GetMessage(&Msg,NULL,0,0)T

27、ranslateMessage(&Msg);DispatchMessage(&Msg);GetMessage()函數(shù)負(fù)責(zé)檢查應(yīng)用程序的消息隊(duì)列,一旦發(fā)現(xiàn)隊(duì)列中有消息,便取出一條消息,把它復(fù)制到MSG結(jié)構(gòu)體變量中,同時(shí)該函數(shù)返回TRUE。TranslateMessage()函數(shù)的作用是將來自鍵盤的命令翻譯為消息的ID字符表示。DispatchMessage()函數(shù)的作用是把每個(gè)消息分發(fā)給相應(yīng)的窗口函數(shù)。當(dāng)檢索到WM_QUIT消息時(shí),程序結(jié)束循環(huán)并退出。2窗口處理函數(shù)注冊窗口類的一個(gè)主要目的就是將一個(gè)窗口和一個(gè)窗口處理函數(shù)聯(lián)系起來,窗口處理函數(shù)決定窗口在它的客戶區(qū)中顯示什么,和窗口如何響應(yīng)用戶輸入

28、。窗口處理函數(shù)能夠按程序員預(yù)先定義的代碼處理消息,如果程序員沒有對該消息的處理作定義,則把此消息交給默認(rèn)窗口處理函數(shù)DefWindowProc()處理。函數(shù)DefWindowProc()是系統(tǒng)默認(rèn)的處理過程,以保證所有發(fā)送到該窗口的消息均得到處理。窗口函數(shù)定義如下:LRESULTCALLBACKWndProc(HWNDhwnd,UNITmessage,WPARAMwParam,LPARAMlParam)說明如下:LRESULT表示函數(shù)返回值為長整數(shù),由系統(tǒng)使用。CALLBACK表示該函數(shù)是回調(diào)函數(shù),由系統(tǒng)調(diào)用。hwnd該參數(shù)是接收消息的窗口句柄,它和CreateWindow()函數(shù)的返回值相同

29、。message該參數(shù)是用來標(biāo)識該消息的數(shù)字。wParam和IParam兩個(gè)參數(shù)是32位的消息參數(shù),用來提供消息的附加信息。在例3-1中窗口處理函數(shù)的名稱為WndProc,這個(gè)名稱可以由用戶自己在窗口類的lpfnWndProc屬性中指定,例如可改為MyWndProc。在窗口函數(shù)中,根據(jù)接收的消息信息(message,wParam和IParam)進(jìn)行判斷,然后分門別類地進(jìn)行處理。窗口函數(shù)中使用switch語句定義對應(yīng)用程序接收到的不同消息的響應(yīng),包含了對各種可能接收到的消息的處理過程。每一條case語句對應(yīng)一種消息,當(dāng)應(yīng)用程序接收到一個(gè)消息時(shí),相應(yīng)的case語句被激活并執(zhí)行相應(yīng)的響應(yīng)程序模塊。程

30、序員可以在switch語句中增加對各種消息的處理代碼。WM_DESTROY消息是關(guān)閉窗口時(shí)發(fā)出的,處理方法是調(diào)用函數(shù)PostQuitMessage()向應(yīng)用程序發(fā)出WM_QUIT消息,請求退出處理函數(shù)。MFC應(yīng)用程序是建立在窗口應(yīng)用程序開發(fā)模式的基礎(chǔ)上的,同樣MFC應(yīng)用程序也有一個(gè)WinMain()函數(shù),但程序員不用編寫該函數(shù),WinMain()函數(shù)由框架提供,當(dāng)應(yīng)用程序啟動(dòng)時(shí)被自動(dòng)調(diào)用。MFC有一個(gè)內(nèi)部的消息系統(tǒng)處理由類產(chǎn)生的絕大多數(shù)消息。當(dāng)一個(gè)消息不能被MFC所處理,應(yīng)用程序?qū)⑺唤o默認(rèn)窗口處理函數(shù)DefWindowProc()來處理。3.1.3應(yīng)用程序舉例【例3-2】分析使用生成的Win

31、32窗口程序示例,并對該程序作以下修改:修改輸出文本串“”為”。在視圖的中央輸出文本“”。添加一個(gè)對話框,并能使用菜單調(diào)用這個(gè)對話框。分析HelloWorld程序:在第一章的實(shí)踐2中已描述了使用AppWizard快速生成Win32窗口程序示例的步驟,下面對同樣方法生成的程序進(jìn)行分析:1.WinMain函數(shù)程序清單-中的函數(shù)intAPIENTRYWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnCmdShow)/TODO:Placecodehere.MSGmsg;HACCELhAccelTable;/初始化全

32、局字符串LoadString(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);LoadString(hInstance,IDC_EXAM3_2,szWindowClass,MAX_LOADSTRING);MyRegisterClass(hInstance);/注冊窗口類句柄/初始化應(yīng)用程序if(!InitInstance(hInstance,nCmdShow)/創(chuàng)建并顯示窗口returnFALSE;hAccelTable=LoadAccelerators(hInstance,(LPCTSTR)IDC_EXAM3_2);裝載快捷鍵/主消息循環(huán)whi

33、le(GetMessage(&msg,NULL,0,0)if(!TranslateAccelerator(msg.hwnd,hAccelTable,&msg)TranslateMessage(&msg);DispatchMessage(&msg);returnmsg.wParam;如程序清單3-2所示,WinMain()函數(shù)的構(gòu)成同樣包含三個(gè)主要過程:通過MyRegisterClass()函數(shù)定義窗口類句柄,并返回RegisterClassEx()函數(shù)結(jié)果;通過InitInstance()函數(shù)調(diào)用CreateWindow()創(chuàng)建窗口,并顯示更新窗口;創(chuàng)建消息循環(huán),接收消息并分發(fā)消息。LoadS

34、tring()函數(shù)的作用是加載字符串資源,字符串資源是在字符串表中定義的,如圖3-6所示,IDS_APP_TITLE表示應(yīng)用程序的名稱,加載到szTitle數(shù)組,IDC_EXAM3_2表示W(wǎng)indows默認(rèn)類的標(biāo)識名,加載到szWindowClass數(shù)組,在定義窗口和創(chuàng)建窗口的時(shí)候調(diào)用。IDValueCaptionIDS_APP_TITLE103Exam32IDS_HELLO106HelloWorld!jIDC_EXAM3_2109EXAM3_2|Table)中的字符器資源定義2.窗口函數(shù)WndProc程序清單:中的函數(shù)和函數(shù)LRESULTCALLBACKWndProc(HWNDhWnd,UI

35、NTmessage,WPARAMwParam,LPARAMlParam)intwmId,wmEvent;PAINTSTRUCTps;HDChdc;TCHARszHelloMAX_LOADSTRING;LoadString(hInst,IDS_HELLO,szHello,MAX_LOADSTRING);/分派窗口消息處理switch(message)caseWM_COMMAND:/處理菜單消息wmId=LOWORD(wParam);wmEvent=HIWORD(wParam);/Parsethemenuselections:switch(wmId)caseIDM_ABOUT:DialogBox(

36、hInst,(LPCTSTR)IDD_ABOUTBOX,hWnd,(DLGPROC)About);break;caseIDM_EXIT:DestroyWindow(hWnd);break;default:returnDefWindowProc(hWnd,message,wParam,lParam);break;caseWM_PAINT:/處理窗口重繪消息hdc=BeginPaint(hWnd,&ps);/TODO:Addanydrawingcodehere.RECTrt;GetClientRect(hWnd,&rt);DrawText(hdc,szHello,strlen(szHello),&

37、rt,DT_CENTER);EndPaint(hWnd,&ps);break;caseWM_DESTROY:/處理應(yīng)用程序退出消息PostQuitMessage(0);break;default:/啟動(dòng)默認(rèn)窗口處理函數(shù)returnDefWindowProc(hWnd,message,wParam,lParam);return0;/About對話框的消息處理函數(shù)LRESULTCALLBACKAbout(HWNDhDlg,UINTmessage,WPARAMwParam,LPARAMlParam)switch(message)caseWM_INITDIALOG:returnTRUE;caseWM_

38、COMMAND:if(LOWORD(wParam)=IDOK|LOWORD(wParam)=IDCANCEL)EndDialog(hDlg,LOWORD(wParam);returnTRUE;break;returnFALSE;如程序清單3-3所示,窗口函數(shù)WndProc()是處理各種消息,在這個(gè)例程中處理三類消息:WM_COMMANDWM_COMMAND是操作菜單項(xiàng)、加速鍵或工具按鈕發(fā)出的命令消息,其中窗口消息包包含的WParam字段的低16位為命令I(lǐng)D,變量wmId獲得命令I(lǐng)D后,使用switch語句繼續(xù)對不同的命令消息進(jìn)行處理。IDM_EXIT是菜單命令“Exit”的ID,處理方法是調(diào)用

39、DestroyWindow()函數(shù)了發(fā)出WM_DESTROY消息。IDM_ABOUT是菜單命令“About”的ID,處理方法是調(diào)用DialogBox()函數(shù),打開對話框窗口。在使用DialogBox()函數(shù)時(shí),需要指定對話框資源ID和對話框消息處理函數(shù)。在本例中,對話框資源IDD_ABOUTBOX,對話框消息處理函數(shù)是About()函數(shù)。對話框消息處理函數(shù)的構(gòu)造與窗口函數(shù)WndProc()類似,通過一個(gè)分情況語句響應(yīng)不同的消息。在About()函數(shù)中對對話框的初始化消息WM_INITDIALOG和命令消息WM_COMMAND進(jìn)行了處理。對話框運(yùn)行時(shí),單擊“OK”按鈕就發(fā)出消息IDOK,單擊“C

40、ancel”按鈕時(shí)發(fā)出IDCANCEL,系統(tǒng)定義的IDOK和IDCANCEL的消息處理中,都調(diào)用了EndDialog()函數(shù)關(guān)閉對話框窗口。WM_PAINTWM_PAINT是窗口重繪消息,當(dāng)窗口大小發(fā)生變化、移動(dòng)、滾屏、菜單覆蓋視圖、鼠標(biāo)掠過視圖等任何使視圖顯示改變的情況下,都會(huì)發(fā)出WM_PAINT消息。本例的處理是在調(diào)用DrawText()函數(shù)在視圖的頂部中央輸出文本串szHello,szHello的內(nèi)容是通過LoadString函數(shù)裝載的字符串資源IDS_HELLO。WM_DESTROY退出應(yīng)用程序的消息處理,調(diào)用PostQuitMessage()函數(shù),結(jié)束消息循環(huán),WinMain()函數(shù)

41、運(yùn)行結(jié)束。按要求修改示例程序:1修改輸出文本串“!”為”!” #第三章MFC應(yīng)用程序概述TOC o 1-5 h z展開工作區(qū)面板中的資源,雙擊打開。雙擊彈出對話框,在中修改字符串的內(nèi)容,即輸入。重新編譯運(yùn)行程序。在視圖的中央輸出文本“”在面板中展開文件夾雙擊文件打開,找到函數(shù)。在消息的處理中添加文本輸出函數(shù)語句如下:DrawText(hdc,st,rtingyourV,2C8,&+rt+,l,rning!DT_SINGLELINE|DT_CENTER|DT_VCENTER);(3重)新編譯運(yùn)行程序。添加一個(gè)對話框,并能使用菜單調(diào)用這個(gè)對話框執(zhí)行菜單命令,在彈出的對話框中選擇,單擊按鈕“”,系統(tǒng)

42、會(huì)添加一個(gè)新的對話框資源到面板中的文件夾中。雙擊打開對話框編輯器窗口,在窗口任意空白處右擊鼠標(biāo)鍵,在打開的快捷菜單中選擇,在彈出的窗口中的內(nèi)容修改為“”此即為修改后的對話框的標(biāo)題欄名稱。在工作區(qū)的面板中,展開菜單資源,雙擊打開菜單編輯器窗口,在菜單中添加一個(gè)菜單項(xiàng)。即雙擊菜單下的空白處,在打開的窗口中輸入,內(nèi)容為:號定義為:。在WndProc()函數(shù)對WM_COMMAND窗口消息的情況處理分支中添加對IDM_MYDIALOG菜單消息的處理代碼如下,調(diào)用DialogBox打開IDD_DIALOG1對話框:caseIDM_MYDIALOG:DialogBox(hInst,(LPCTSTR)IDD_

43、DIALOG1,hWnd,(DLGPROC)Mydialog);break;(5)在cpp文件的最后添加對話框消息處理函數(shù)Mydialog函數(shù),代碼如程序清單3-4所示。程序清單:對話框消息處理函數(shù)函數(shù)LRESULTCALLBACKMydialog(HWNDhDlg,UINTmessage,WPARAMwParam,LPARAMlParam)switch(message)caseWM_INITDIALOG:returnTRUE;caseWM_COMMAND:if(LOWORD(wParam)=IDOK|LOWORD(wParam)=IDCANCEL)EndDialog(hDlg,LOWORD(

44、wParam);returnTRUE;break;VC+6簡明教程VC+6簡明教程第三章MFC應(yīng)用程序概述returnFALSE;在cpp文件的頭部的函數(shù)聲明處添加函數(shù)聲明語句如下:LRESULTCALLBACKMydialog(HWNDhDlg,UINTmessage,WPARAMwParam,LPARAMlParam);重新編譯運(yùn)行程序,執(zhí)行菜單命令MyDialog,打開自定義的對話框。最后運(yùn)行效果如圖3-7所示。32MFC應(yīng)用程序框架利用WindowsAPI函數(shù)編制Windows應(yīng)用程序,程序員需要編寫大量的程序代碼。而利用MFC編寫實(shí)現(xiàn)同樣功能的程序,則要輕松得多。在第一章中我們學(xué)習(xí)了

45、使用AppWizard創(chuàng)建一個(gè)MFC單文檔應(yīng)用程序,不需要做任何額外的工作,直接運(yùn)行程序,一個(gè)具備常用工具欄、菜單欄、狀態(tài)欄的標(biāo)準(zhǔn)窗口應(yīng)用程序就已經(jīng)出現(xiàn)的屏幕上。MFC(MicrosoftFoundationClass)是由微軟編寫的一套專門用于Windows編程的C+基礎(chǔ)類庫,其內(nèi)容很廣泛,功能也相當(dāng)強(qiáng)大,VC編程基本上都是圍繞著MFC類庫來進(jìn)行的,它封裝了WindowsAPI的絕大多數(shù)功能,通過用戶開發(fā)Windows應(yīng)用程序建立了一個(gè)非常靈活的應(yīng)用程序框架。但習(xí)慣使用SDK編寫窗口應(yīng)用程序的程序員,初次接觸MFC編程時(shí)都會(huì)有這樣困惑:找不到WinMain函數(shù),應(yīng)用程序如何執(zhí)行?程序的執(zhí)行似

46、乎不在程序員的掌握之中。所以如何理解MFC應(yīng)用程序框架是學(xué)習(xí)VC的核心任務(wù)之一。3.2.1MFC類簡介MFC類庫中的各個(gè)類支持快速生成面向?qū)ο蟮膽?yīng)用程序,它們之間存在一定的關(guān)聯(lián),它們的集合構(gòu)成MFC應(yīng)用程序框架,如圖3-8所示。CObjectCCmdTargetVC+6簡明教程VC+6簡明教程 # 類的繼承關(guān)系CObject是MFC類庫的根類。從CObject派生的類都具有以下特點(diǎn):在程序運(yùn)行時(shí),可獲得對象的大小、類名、動(dòng)態(tài)創(chuàng)建類的實(shí)例。提供了把對象狀態(tài)轉(zhuǎn)儲給調(diào)試機(jī)制的能力,類似于判斷當(dāng)前對象的數(shù)據(jù)成員是否有效。具有把對象的數(shù)據(jù)存進(jìn)文件、或從文件中提取數(shù)據(jù)重建對象的能力。命令類CCmdTarg

47、et:是CObject的子類,它是MFC庫中所有具有消息映射屬性的基類。它的子類有CWinThread類,CWnd類、CDocument類,從CCmdTarget派生的類在程序運(yùn)行時(shí),能動(dòng)態(tài)創(chuàng)建對象,并能處理命令消息。應(yīng)用程序線程支持類CWinThread:MFC支持多線程,所有的應(yīng)用程序至少有一個(gè)線程。CWinThread是所有線程類的基類,封裝了操作應(yīng)用程序的多線程功能。應(yīng)用程序類CWinApp是CWinThread的子類,封裝了初始化、運(yùn)行、終止應(yīng)用程序的代碼。窗口類CWnd:提供了MFC中所有窗口類的基本功能。從CWnd派生的類可以擁有自己的窗口,并能對它進(jìn)行控制。框架窗口類CFram

48、eWnd和視圖類CView是CWnd類的兩個(gè)子類,前者提供和維護(hù)窗口的邊框、菜單欄、工具欄、狀態(tài)欄,負(fù)責(zé)顯示和搜索用戶命令,后者負(fù)責(zé)為文檔提供一個(gè)或幾個(gè)視圖。視圖的作用是為修改、查詢文檔等任務(wù)提供人機(jī)交互的界面。文檔類CDocument:負(fù)責(zé)裝載和維護(hù)文檔。文檔包括應(yīng)用程序的工作成果或環(huán)境設(shè)置數(shù)據(jù)等,或是程序需要保存的任何內(nèi)容。一個(gè)MFC應(yīng)用程序并不直接操作上述類,而是從上述類為基類派生新的類,構(gòu)建窗口應(yīng)用程序的基本框架。例如應(yīng)用程序Examl_l中的類與這些基類的派生如表3_1所示。表基類與派生類的關(guān)系類名稱基類說明CExam1_1AppCWinApp應(yīng)用程序類CMainFrameCFram

49、eWnd窗口框架類CExam1_1DocCDocument文檔類CExam11ViewCView視圖類3.2.2構(gòu)建窗口應(yīng)用程序的基本類利用VC+提供的AppWizard,可直接生成MFC應(yīng)用程序。但無法看到Windows程序結(jié)構(gòu)中的主函數(shù)WinMain和窗口函數(shù)WndProc,因?yàn)樗鼈儽环庋b在MFC類中了。在MFC類中,應(yīng)用程序類CWinApp和框架窗口類CFrameWnd替代了主函數(shù)WinMain和窗口函數(shù)WndProc的功能,負(fù)責(zé)程序的初始化,退出時(shí)必要的清理,窗口的創(chuàng)建和消毀,消息循環(huán)等功能。應(yīng)用程序類CWinApp和框架窗口類CFrameWnd是MFC應(yīng)用程序最基本的兩個(gè)類,所有的M

50、FC應(yīng)用程序都必須包含這兩個(gè)類,下面以第一章建立的應(yīng)用程序Exam1_1分析這兩個(gè)基本類的主要功能。1應(yīng)用程序類CExam1_1App在AppWizard生成的五個(gè)類中,CExaml_lApp代表的是應(yīng)用程序,它的基類CWinApp代表了Windows應(yīng)用程序,并把每一個(gè)程序都看做一個(gè)對象。應(yīng)用程序類將負(fù)責(zé)完成MFC應(yīng)用程序的一些例行初始化工作,另外,CWinApp的基類是CWinThread,因此它也要負(fù)責(zé)管理程序主線程的運(yùn)行。AppWizard聲明一個(gè)由CWinApp繼承的類CExam1_1App,在生成的實(shí)現(xiàn)文件中包含:應(yīng)用程序類的消息映射一個(gè)空的應(yīng)用程序類的構(gòu)造函數(shù)個(gè)CExam1_1A

51、pp類的全局對象theApp一個(gè)InitInstance函數(shù)的標(biāo)準(zhǔn)定義全局對象theApp,在WinMain()函數(shù)執(zhí)行之前初始化,在進(jìn)入MFC版本的WinMain()函數(shù)之后,theApp很快就獲得了管理權(quán),進(jìn)行Windows程序的一些例行初始化工作。CWinApp提供了四個(gè)函數(shù)管理實(shí)現(xiàn)MFC應(yīng)用程序的生命期,函數(shù)功能如表3_2所示,這四個(gè)函數(shù)都能被CWinApp的派生類CExam1_1App重載,其中只有InitInstance()函數(shù)是必須被重載的。表可重載的成員函數(shù)成員函數(shù)說明InitInstance負(fù)責(zé)應(yīng)用程序的初始化工作,創(chuàng)建文檔模板,文檔,視圖和主窗口,該函數(shù)是唯一一個(gè)必須重載的

52、函數(shù)Run初始化結(jié)束后,由函數(shù)調(diào)用處理消息循環(huán),一個(gè)文檔視圖應(yīng)用程序絕大多數(shù)時(shí)間處于函數(shù)的執(zhí)行過程中ExitInstance當(dāng)用戶退出程序的時(shí)候,該函數(shù)被調(diào)用OnIdle當(dāng)沒有窗口消息需要處理時(shí)由窗口框架調(diào)用,通常用于執(zhí)行后臺任務(wù)在CExam1_1App類中,InitInstance()函數(shù)首先調(diào)用AfxEnableControlContainer()函數(shù),允許程序使用ActiveX控件,接著又調(diào)用Enable3dControls()函數(shù)或Enable3dControlsStatic()函數(shù),允許程序使用具有3D效果的控件。SetRegistryKey()函數(shù)和LoadStdProfileSe

53、ttings()函數(shù)的作用是從注冊表中讀取與本程序有關(guān)的信息,這些信息在第一次運(yùn)行本程序時(shí)自動(dòng)建立,以后在需要時(shí)會(huì)自動(dòng)更新。接下來的幾條語句是為程序定義一種文檔模板類型,文檔模板把文檔類CExam1_1Doc、主框架類CMainFrame和視圖類CExam1_1View聯(lián)系在一起。ParseCommandLine()和ProcessShellCommand()兩個(gè)函數(shù)分別用于分析和處理命令行參數(shù),如果想讓程序支持自定義的命令行參數(shù),可以在此添加自己的處理代碼。最后兩條語句把程序唯一的主窗口顯示出來,并進(jìn)行更新。2.主框架類CMainFrameCMainFrame代表的是程序的主框架窗口,一個(gè)窗

54、口應(yīng)用程序除了白色部分的視圖(View)夕卜,程序主窗口的其它部分都?xì)wCMainFrame管理。視圖實(shí)際上是主框架窗口的子窗口,它的大小正好等于主框架窗口的客戶區(qū)的大小,當(dāng)運(yùn)行一個(gè)多文檔程序,例如Word,將所有的文檔窗口最小化,就會(huì)留下一個(gè)灰色背景的客戶區(qū),它也是主框架窗口的一部分。單文檔程序的主框架窗口是在調(diào)用ProcessShellCommand()函數(shù)時(shí)創(chuàng)建的,在主框架窗口被創(chuàng)建之前,CMainFrame:PreCreateWindow()函數(shù)將被自動(dòng)調(diào)用。在這個(gè)函數(shù)中可以更改主框架窗口的風(fēng)格,或者對窗口類的一些屬性進(jìn)行修改,此時(shí)窗口句柄還不可用。當(dāng)Windows通過Win32函數(shù)Cr

55、eateWindowEx()接收到創(chuàng)建主框架窗口的請求時(shí),它會(huì)在系統(tǒng)內(nèi)部為窗口分配資源,并進(jìn)行一些設(shè)置工作,此時(shí)窗口句柄就可以使用了,當(dāng)Windows從CreateWindowEx()函數(shù)返回之前,它向程序發(fā)送WM_CREATE消息,讓程序完成一些必要的初始化工作,CMainFrame:OnCreate()函數(shù)就是WM_CREATE消息的處理函數(shù),這個(gè)函數(shù)首先調(diào)用了基類的處理函數(shù), #讓基類完成初始化工作,然后為主框架窗口創(chuàng)建工具欄和狀態(tài)欄。CMainFrame的兩個(gè)成員變量m_wndToolBar和m_wndStatusBar分別對應(yīng)著程序主窗口中的工具欄和狀態(tài)欄。工具欄的創(chuàng)建方式很直接,C

56、ToolBar:LoadToolBar()函數(shù)負(fù)責(zé)裝載工具欄資源,而CToolBar:CreateEx()函數(shù)將負(fù)責(zé)工具欄的創(chuàng)建。狀態(tài)欄的使用需要一個(gè)數(shù)組來定義狀態(tài)欄類各個(gè)窗格的ID,這個(gè)數(shù)組就是indicators。CStatusBar:Create()函數(shù)負(fù)責(zé)工具欄的創(chuàng)建,CStatusBar:SetIndicators()函數(shù)負(fù)責(zé)設(shè)置狀態(tài)欄上的窗格。CMainFrame還有兩個(gè)成員函數(shù)AssertValid()和Dump(),它們只在調(diào)試版本中存在,可以利用它們來驗(yàn)證類的某些成員變量的值是否有效,以及向Output窗口中輸出對象的內(nèi)部狀態(tài)。很多從CObject派生出來的類都重載了這兩個(gè)函

57、數(shù),以幫助程序員調(diào)試程序。本章實(shí)踐與提高的實(shí)踐1中,描述了手工創(chuàng)建一個(gè)最小MFC應(yīng)用程序的過程,在這個(gè)應(yīng)用程序中僅包含應(yīng)用程序類和窗口框架類,說明只要包含這兩個(gè)基本類,就能成功地構(gòu)建一個(gè)窗口應(yīng)用程序。3.2.3文檔/視圖結(jié)構(gòu)文檔/視圖結(jié)構(gòu)是MFC應(yīng)用程序最核心的概念,它將應(yīng)用程序的數(shù)據(jù)和瀏覽、操縱數(shù)據(jù)的方法分離。簡單地說,文檔對象通常代表一個(gè)已經(jīng)打開的文件,而視圖對象表示文檔中數(shù)據(jù)的可視化表示,并提供可視化交互界面允許用戶查看、編輯數(shù)據(jù)。1文檔/視圖結(jié)構(gòu)圖3-9演示了一個(gè)MFC應(yīng)用程序中各個(gè)主要對象在文檔/視圖結(jié)構(gòu)中交互的途徑。應(yīng)用程序的數(shù)據(jù)存儲在文檔對象中,并可以顯示在視圖。文檔與視圖的關(guān)系

58、是1對多的關(guān)系,也就是說文檔中的數(shù)據(jù)可以以不同的方式顯示。例如:在一個(gè)Excel文件中,同樣的數(shù)據(jù)可以以表格的形式表示,也可以圖表的形式表示。在一個(gè)視圖中修改數(shù)據(jù),首先反映到文檔對象,刷新視圖,在各個(gè)視圖中反映所作的修改。一個(gè)MFC應(yīng)用程序開始運(yùn)行后,應(yīng)用程序?qū)ο筘?fù)責(zé)傳遞消息到窗口框架對象和視圖對象。文檔對象負(fù)責(zé)管理數(shù)據(jù),視圖對象按特定的方式反映當(dāng)前文檔對象中數(shù)據(jù),視圖和框架同時(shí)提供可視化的界面與用戶實(shí)現(xiàn)交互,用戶使用鼠標(biāo)和鍵盤操作應(yīng)用程序的菜單、工具欄及控件,發(fā)出命令消息,輸入信息,應(yīng)用程序接受消息,接受輸入數(shù)據(jù),并以預(yù)先定義的方式反映用戶的操作。文檔對象應(yīng)用程序?qū)ο蟠翱诳蚣軐ο骎C+6簡明

59、教程 #信息在視圖與文檔對象間雙向傳遞圖3-9文檔/視圖結(jié)構(gòu)2文檔類應(yīng)用程序中的文檔類是CDocument類的派生類,CDoument類主要的成員函數(shù)及功能如表3-3所示。表的成員函數(shù)成員函數(shù)說明OnNewDocument初始化一個(gè)新的文檔對象,當(dāng)創(chuàng)建一個(gè)新文檔時(shí),系統(tǒng)自動(dòng)調(diào)用,默認(rèn)重載。OnOpenDocument當(dāng)從磁盤打開一個(gè)文件時(shí)被系統(tǒng)自動(dòng)調(diào)用,可重載。DeleteContents刪除文檔對象的內(nèi)容。當(dāng)文檔被關(guān)閉時(shí)系統(tǒng)自動(dòng)調(diào)用,可重載。Serialize文檔序列化函數(shù)用于從一個(gè)文件中讀取內(nèi)容到文檔對象,或者將文檔對象的內(nèi)容保存到文件。默認(rèn)重載。UpdateAllView更新與文檔對象關(guān)

60、聯(lián)的所有視圖,該函數(shù)自動(dòng)調(diào)用每個(gè)視圖對象的函數(shù)實(shí)現(xiàn)更新操作。SetModifiedFlag設(shè)置或清除文檔的數(shù)據(jù)是否修改的標(biāo)志,該標(biāo)志決定執(zhí)行應(yīng)用程序關(guān)閉操作時(shí),是否會(huì)彈出對話框確認(rèn)是否需要保存文件。IsModified如果文檔對象包含未保存數(shù)據(jù)則返回一個(gè)非零值,否則返回一個(gè)零值。GetTitle返回表示文檔標(biāo)題的文本串,如果文檔沒有標(biāo)題返回空串GetFirstViewPosition返回一個(gè)類型的變量表示第一個(gè)視圖的位置。GetNextView返回一個(gè)類型的指針,指向當(dāng)前文檔對象相關(guān)的一組視圖中的下一個(gè)視圖GetPathName返回與文檔相關(guān)的文件的名稱和路徑AppWizard默認(rèn)重載了兩個(gè)虛

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論