第八講MFC程序開發(fā)概述_第1頁
第八講MFC程序開發(fā)概述_第2頁
第八講MFC程序開發(fā)概述_第3頁
第八講MFC程序開發(fā)概述_第4頁
第八講MFC程序開發(fā)概述_第5頁
已閱讀5頁,還剩108頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第八講第八講 MFC程序開發(fā)概述程序開發(fā)概述進一步的學習應用開發(fā):桌面應用、網絡與應用開發(fā):桌面應用、網絡與WebWeb編程、數據庫編程、嵌入式編程及驅動開發(fā)編程、數據庫編程、嵌入式編程及驅動開發(fā)進一步的學習n如何進一步學好編程技術n追求、志向與興趣n勤奮+實踐+思考n開放的心態(tài)、永遠學習的態(tài)度n學習知識的不同層次n運用知識:從課堂獲取知識并靈活應用n擴展知識:掌握學習的方法和獲取知識的手段,從而具備自行獲取知識的能力n創(chuàng)造知識:掌握知識背后的思想和原理,從而具備創(chuàng)造知識的能力MFC相關概念n類庫是一個可以在應用程序中使用的相互關聯的類的集合。nMFC (Microsoft Foundatio

2、n Classes)庫Microsoft 基本類庫是一個Windows應用程序框架,它定義了應用程序的結構,并實現了標準的用戶接口:n管理窗口、菜單、對話框,實現基本的輸入/輸出和數據存儲。MFC相關概念n應用程序框架是一種類庫的超集,是用于編寫最終軟件的一種“半成品”,其作用主要是:n提供應用軟件的規(guī)范化結構n提供與具體應用無關的基礎可復用代碼,提高軟件開發(fā)的效率n在程序運行時,基本流程的控制多數是由框架實現的。n應用MFC框架來構造應用程序時,程序員的角色就是提供應用程序專用的代碼,并指定這些代碼是用來響應哪些消息和命令的,以使框架能夠在消息和處理消息的代碼間建立聯系。MFC相關概念n學習

3、并使用MFC進行Windows應用程序開發(fā)需要以下基礎:nC+編程技術nWin32編程的基本概念n“Win32”指32位的Windows平臺nWin32編程是指運用C/C+語言直接(不使用MFC)在Win32平臺上進行Windows應用程序開發(fā)n“VC”指的是Visual C+,是一種用于Windows環(huán)境下C/C+編程、Win32編程、MFC應用程序開發(fā)和ATL(ActiveX Template Library)應用程序開發(fā)的集成開發(fā)環(huán)境(IDE, Integrated Development Environment )。MFC相關概念nWindows下的C+程序開發(fā)有以下幾種方式:n純粹的

4、C/C+程序n基于控制臺的Win32程序n基于窗口的Win32程序n基于MFC的應用程序n基于ATL的應用程序Windows編程模式n當用C來編寫MS-DOS應用程序時,最起碼要有一個main函數。當用戶運行該應用程序時,操作系統(tǒng)會自動調用main函數,從這一點上講,我們可以使用任何所需要的程序結構n當Windows操作系統(tǒng)運行程序時,它首先調用程序中的WinMain函數。因此,在Windows應用程序中一定要有WinMain函數nWinMain函數一般用來完成某些特殊的任務,其中最重要的任務就是要創(chuàng)建該應用程序的“主窗口”n“主窗口”中必須包含用來處理Windows所發(fā)送的消息的代碼Wind

5、ows編程模式nWinMain函數n初始化應用n初始化和創(chuàng)建應用窗口n進入應用程序的消息循環(huán)n窗口過程WndProc()n執(zhí)行窗口的消息處理:分析消息信息,決定應用程序如何處理消息或響應一個事件Windows編程模式n基于Windows的程序和基于MS-DOS的程序之間的一個最根本的差別在于:nMS-DOS程序是通過調用操作系統(tǒng)的功能來獲得用戶輸入的n而Windows程序則是通過操作系統(tǒng)發(fā)送的消息來處理用戶輸入的n消息是什么?n消息是包含一定參數的,用于在對象之間或操作系統(tǒng)和應用程序之間傳遞信息的特定對象Windows編程模式n許多Windows消息都經過了嚴格的定義,并且適用于所有的程序。例

6、如:n當窗口被創(chuàng)建時,系統(tǒng)就會發(fā)送WM_CREATE消息n當用戶按下鼠標左鍵時,系統(tǒng)就會發(fā)送WM_LBUTTONDOWN消息n當用戶敲一個字符鍵時,系統(tǒng)就會發(fā)送WM_CHAR消息n而當用戶關閉窗口時,系統(tǒng)又會發(fā)送WM_CLOSE消息n當用戶進行菜單選擇和對話框按鈕單擊等操作時,系統(tǒng)又會發(fā)送WM_COMMAND消息給適當的窗口n用戶不用擔心如何使這些消息與代碼聯系起來,因為這是應用程序框架完成的事情Windows編程模式nWindows系統(tǒng)是一個消息驅動的OSn消息的組成:一個消息由一個消息名稱(UINT),和兩個參數(WPARAM,LPARAM)組成。當用戶進行了輸入或是窗口的狀態(tài)發(fā)生改變時系

7、統(tǒng)都會發(fā)送消息到某一個窗口。例如當菜單選中之后會有WM_COMMAND消息發(fā)送,WPARAM的高字中(HIWORD(wParam))是命令的ID號,對菜單來講就是菜單ID。當然用戶也可以定義自己的消息名稱,也可以利用自定義消息來發(fā)送通知和傳送數據。 n誰將收到消息:一個消息必須由一個窗口接收。在窗口的過程(WNDPROC)中可以對消息進行分析,對自己感興趣的消息進行處理。例如你希望對菜單選擇進行處理那么可以定義對WM_COMMAND進行處理的代碼,如果希望在窗口中進行圖形輸出就必須對WM_PAINT進行處理。 n未處理的消息到那里去了:MS為窗口編寫了默認的窗口過程,這個窗口過程將負責處理那些

8、你不處理的消息。正因為有了這個默認窗口過程我們才可以利用Windows的窗口進行開發(fā)而不必過多關注窗口各種消息的處理。例如窗口在被拖動時會有很多消息發(fā)送,而我們都可以不予理睬讓系統(tǒng)自己去處理。 n窗口句柄:窗口對象的唯一標識Windows編程模式n消息機制n系統(tǒng)將會維護一個或多個消息隊列,所有產生的消息都會被放入或插入隊列中。系統(tǒng)會在隊列中取出每一條消息,根據消息的接收句柄將該消息發(fā)送給擁有該窗口的程序的消息循環(huán)。每一個運行的程序都有自己的消息循環(huán),在循環(huán)中得到屬于自己的消息并根據接收窗口的句柄調用相應的窗口過程。而在沒有消息時消息循環(huán)就將控制權交給系統(tǒng),所以Windows可以同時進行多個任務

9、。Windows編程模式Windows編程模式nWindows的圖形設備接口(GDI, Graphical Device Interface)nWindows針對多種不同的圖形輸出設備(如各種顯示卡、打印機等)提供了一致的抽象接口GDI,使得我們的程序可以不必關心與系統(tǒng)相連的顯示卡及打印機的類型。n圖中,DC(設備環(huán)境/設備上下文:Device Context)是物理設備(如顯示器、打印機等)的邏輯模型,GDI是DC和設備驅動程序之間的隔離層(或叫做抽象接口)。應用程序DCGDI設備驅動程序物理硬件圖形物理設備Windows編程模式n基于資源的程序設計n在MS-DOS下,為了實現數據驅動的程序

10、設計,必須將數據定義為初始化常量,或者提供單獨的數據文件供程序讀取。n而當進行Windows程序設計時,可以用一些特定的格式將這些數據存儲在資源文件中,這樣鏈接器就可以把由C+編譯器輸出的二進制代碼和二進制資源文件結合起來生成可執(zhí)行程序。n資源文件可以包含位圖、圖標、菜單定義、對話框設計和字符串,甚至可以包含用戶自定義的格式。Windows編程模式n動態(tài)鏈接庫(DLL, Dynamic Link Library)n在MS-DOS環(huán)境下,所有程序的目標模塊在創(chuàng)建過程中都被靜態(tài)地鏈接起來。n而Windows則允許動態(tài)地鏈接,即一些特定結構的庫可以在運行過程中被裝入和鏈接,并且多個應用程序可以共享同

11、一個動態(tài)鏈接庫,這樣可以大大節(jié)省內存和磁盤空間。nWin32應用程序編程接口(API, Application Program Interface)nWin32操作系統(tǒng)平臺提供的基礎編程接口,MFC實際上封裝了這些編程接口Windows編程模式開始執(zhí)行開始執(zhí)行初始化應用初始化應用初始化和創(chuàng)建初始化和創(chuàng)建應用窗口應用窗口進入消息循環(huán)并進入消息循環(huán)并從消息隊列得到從消息隊列得到一個消息一個消息當前消息是當前消息是否否“退出退出”? ?終止執(zhí)行終止執(zhí)行程序是否定義程序是否定義了對此消息的了對此消息的處理處理進行默認處理進行默認處理處理消息處理消息否否否否是是是是在在MFC程序開發(fā)中,程序開發(fā)中,Wi

12、ndows程序的基本結構被程序的基本結構被MFC應用程應用程序框架序框架所隱藏,程序員一般無法所隱藏,程序員一般無法直接看到直接看到Windows程序的基本結程序的基本結構,也看不到構,也看不到WinMain函數。函數。集成開發(fā)環(huán)境(IDE)n項目(Project)n項目是一些相互關聯的源文件的集合,這些源文件經過編譯、鏈接,然后被組合在一起形成可執(zhí)行的Windows應用程序或者是DLL。n資源編輯器n實現“所見即所得”的資源編輯nC/C+編譯器n對C/C+源文件進行編譯,形成目標代碼n資源編譯器n對資源文件進行編譯,形成二進制RES文件集成開發(fā)環(huán)境(IDE)n調試器n用于C/C+程序調試,實

13、現斷點、單步執(zhí)行、變量觀察等功能n應用程序向導(AppWizard)nAppWizard是一個代碼生成器,它會按照用戶通過對話框指定的特性、類名及源代碼文件名來產生Windows應用程序的工作架構。 AppWizard創(chuàng)建必要的基礎代碼,可以使用戶很快地開始一個新的應用程序。nClassWizardnClassWizard是一個編寫和生成類的工具,能夠給出原型、函數體以及將消息同應用程序框架相聯系的相應代碼。集成開發(fā)環(huán)境(IDE)n源程序瀏覽器n源程序瀏覽器能夠使我們從類或函數的角度來了解(和編輯)程序,而不是直接從文件入手。nDefinitions and References如果選擇任何函

14、數、變量、類型、宏定義或者類,都會馬上看到它是在項目中的什么地方定義,并且在哪些地方用到了它。nCall Graph/Caller Graph對于所選擇的函數,給出它的調用與被調用函數的圖示。nDerived Class Graph/Base Class Graph給出類層次關系的圖形表示。nFile Outline對于所選擇的文件,列出文件中的類、函數和數據成員。n聯機幫助MFC體系結構n頭文件預編譯n把一個工程(Project)中使用的一些MFC標準頭文件(如Windows.H、Afxwin.H)預先編譯,以后該工程編譯時,不再編譯這部分頭文件,僅僅使用預編譯的結果。這樣可以加快編譯速度,

15、節(jié)省時間。n預編譯結果文件是projectname.pch。n編譯器通過一個頭文件stdafx.h來使用預編譯頭文件。stdafx.h這個頭文件名是可以在project的編譯設置里指定的。n編譯器認為,所有在指令#include “stdafx.h”前的代碼都是預編譯的,它跳過#include “stdafx. h”指令,使用projectname.pch作為頭文件編譯這條指令之后的所有代碼。n因此,所有的MFC應用程序CPP實現文件第一條語句都是:n#include stdafx.hMFC體系結構n基于對話框nWindows附帶的計算器n基于單文檔(SDI, Single Document

16、Interface )nWindows附帶記事本n基于多文檔(MDI, Multiple Document Interface)nOffice中的WORDnAdobe PhotoshopMFC體系結構nMFC是個相當龐大的類庫,各個類間的繼承與派生關系較為復雜。 CObject類是MFC的基類,其它大部分類都是從CObject派生而來的。CObject類的派生類按功能可分為多個部分。下面簡要介紹部分常用的類的派生結構。n按照慣例,MFC庫類名用大寫字母“C”打頭MFC體系結構 圖:部分窗口類的繼承關系CObjectCCmdTargetCWndCFrameWndCViewCDialog控件類如C

17、ButtonMFC體系結構n其中,CCmdTarget(命令目標類)是MFC中擁有消息循環(huán)和消息處理機制的基類。nCWnd類是從CCmdTarget中派生出來的重要類,它是所有窗口類的基類。nCCmdTarget間接派生出了文檔/視圖結構中應用程序框架中的許多重要的類:CWinApp、CFrameWnd、CDocument、CView等(SDI應用程序框架的四個主要的類)。 MFC體系結構nCFrameWnd類是框架窗口類,由于框架窗口也是一種窗口,因此,框架窗口類CFrameWnd也繼承自窗口類CWnd,其具有一般窗口的所有特征,也可以在該類基礎上派生出具有一定特色的框架窗口類。n可以通過3

18、種方式來構造框架窗口,這3種方式分別是用Create直接構造、用LoadFrame直接構造和用文檔模板間接構造。MFC體系結構nCView類是視圖類,其基類是類CWnd。視圖主要用于顯示數據,充當文檔與用戶交互的媒介。n視圖是框架窗口的子窗口,它管理著框架窗口的客戶區(qū),一個框架窗口可能有多個視圖,一個文檔也可以有多個視圖,但是一個視圖只能有一個文檔,視圖類、框架窗口類和文檔類三者之間聯系的紐帶是CDocTemplate類。nCDialog類就是對話框類,其基類是類CWnd。對話框是一種特殊的窗口,一般用來提供與用戶進行交互的接口,其提供了對話框控件用來輸入輸出數據,并能對數據進行交換和校驗。M

19、FC體系結構n應用程序框架的核心是文檔視圖結構。MFC通過文檔視圖結構為應用程序提供一種將數據與視圖分離的存儲方式。n文檔類的作用是將應程序的數據保存在文檔類對象中,以及從磁盤文件中讀或向磁盤文件中寫數據。n視圖類的作用是顯示數據和編輯數據。MFC體系結構nCWinApp類是從CCmdTarget中派生出來的最重要的類,每個用MFC編寫的Windows程序必須有一個它的派生類的對象,它代表一個應用程序,整個程序的運行都由它負責。CWinApp類隱藏了Win32程序中WinMain函數。CObjectCCmdTargetCWinThreadCDocumentCWinAppCDocTemplate

20、MFC體系結構n每個MFC應用程序都有一個全局的應用程序類對象,默認是theApp,該應用程序類對象在其它對象構造之前構造,并且在WinMain函數調用之前就已經構造了。應用程序類對象提供了用于初始化和運行應用程序的成員函數。MFC體系結構nCDocument類是文檔類,其基類是類CCmdTarget,文檔類主要用于存儲數據n文檔類對象由文檔模板創(chuàng)建,文檔模板的基類是CDocTemplate類,文檔模板用于協調文檔、視圖和框架窗口的創(chuàng)建,三者之間構成了文檔/視圖結構。MFC體系結構n圖形繪制類的基類是CDC(設備環(huán)境類)。CDC類提供了基本的繪圖及文本輸出函數。CObjectCDCCClien

21、tDCCPaintDCCWindowDCMFC體系結構n繪圖對象類提供給CDC及其派生類在繪圖時所需的各種圖形對象,如畫筆、刷子、字體等。 CObjectCGdiObjectCPenCBrushCFontMFC體系結構nMFC除了支持C+的基本類型類,如string類、vector類和map類等,還自定義了一些簡單類型類,大大方便了用戶開發(fā)應用程序,使用戶在開發(fā)過程中不用考慮過細的粒度。這些簡單類型類主要有:nCPoint類:CPoint類是一個描述點坐標的類,這個點坐標自然就包含了橫坐標x值和縱坐標y值。該類封裝了點的一般操作,如判斷該點是否在某個矩形區(qū)域內等。nCRect類:CRect類是

22、描述矩形的類,這個矩形類唯一由左上角坐標和右下角坐標確定,并封裝了矩形的一般操作。nCSize類:CSize類是描述尺寸的類,主要的數據成員是長和寬。nCString類:CString類是MFC類庫中的字符串類。nCTime類:CTime類封裝了時間的行為,包括年月日和時分秒等信息,以及在時間上的一般操作。 MFC體系結構運行時,應用程序框架首先獲得控制權,依次執(zhí)行下面的步驟 1、構造唯一的應用類對象theApp,調用CWinApp類的構造函數。 2、調用WinMain()函數。 WinMain()函數的工作又可細分為: 1)獲得指向唯一應用類對象的指針。 2)進行一些內部初始化,若失敗,轉至

23、第5)步。 3)進行應用程序的初始化,即調用InitInstance()函數進行初始化.如果失敗,則調用應用類的ExitInstance ()函數,轉至5)。 4)調用應用類的Run()函數,其功能主要是進行消息循環(huán),不斷獲取消息和處理消息。一直到用戶關閉應用程序的窗口,產生WM_QUIT消息,調用ExitInstance()函數,準備退出。 5)進行應用程序的收尾工作,比如刪除注冊的窗口類等。 6)返回。 3、從WinMain()函數返回后,刪除應用程序的唯一應用類的對象,刪除時要調用其析構函數。 4、終止應用程序。程序框架中各個類對象的相互調用關系 1、視圖類對象對文檔類對象的調用 例:C

24、DrawDoc *pDoc=GetDocumen( ); GetDocument()的作用是得到指向文檔對象的指針。 2、在框架類對象中獲得當前的文檔和視圖對象指針 例:CDrawDoc* pDoc=(CDrawDoc *)GetActiveDocument(); CDrawView* pView=(CDrawView *)GetActiveView( ); 3、獲得應用類對象的指針 例:CDrawApp* pWinApp=(CDrawApp*)AfxGetApp(); 4、從應用類對象中獲得主框架類對象的指針 例:CMainFrame* pFrame= (CMainFrame*)(AfxGe

25、tApp()-m_pMainWnd);MFC應用程序消息處理機制的建立在MFC Windows應用程序中,必須正確地建立消息處理機制。n建立消息處理機制步驟建立消息處理機制步驟如下(可歸納為三步曲): 1、 聲明消息映射聲明消息映射 若希望能進行消息處理的類具有接收消息的能力,需要在該類的末尾加入消息映射說明。 格式: DECLARE_MESSAGE_MAP() 2、 建立消息與處理函數之間的映射建立消息與處理函數之間的映射 格式: BEGIN_MESSAGE_MAP(子類名,父類名)/消息映射宏定義消息映射宏定義或消息映射語句消息映射語句(根據使用消息的多少,一般有若干個) ON_(消息名或

26、控制號,處理函數名) END_MESSAGE_MAP()MFC應用程序消息處理機制的建立注:消息映射宏定義將一個消息與一個處理函數關聯起來,以便對消息作出響應。n 3、 在進行消息處理的類中定義各消息處理函數在進行消息處理的類中定義各消息處理函數 消息處理函數原型消息處理函數原型為:afx_msg 類型 函數名(WPARAM wParam,LPARAM lParam);例: MOUSE左鍵按下消息處理函數原型為: afx_msg void OnLButtonDown(UINT nFlags,CPoint point); MFC應用程序框架并沒有采用虛函數來處應用程序框架并沒有采用虛函數來處理理

27、Windows消息,相反,它通過一些宏來消息,相反,它通過一些宏來將特定的消息映射到派生類中相應的成員將特定的消息映射到派生類中相應的成員函數上。函數上。一個最簡單的MFC程序/mfc1.cpp/mfc1.cpp#include#include/MFC/MFC核心庫核心庫class CMainFrame:public CFrameWndclass CMainFrame:public CFrameWnd public:public: CMainFrame()CMainFrame() CString ch=MFC WindowsCString ch=MFC Windows程序程序; Create(

28、NULL,ch);Create(NULL,ch);/創(chuàng)建主窗口創(chuàng)建主窗口 protected:protected: afx_msg void OnLButtonDown(UINT nFlags,CPoint point);afx_msg void OnLButtonDown(UINT nFlags,CPoint point); DECLARE_MESSAGE_MAP()DECLARE_MESSAGE_MAP();class CMinApp:public CWinAppclass CMinApp:public CWinApp public:public: virtual BOOL InitIns

29、tance();virtual BOOL InitInstance();BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd) ON_WM_LBUTTONDOWN()ON_WM_LBUTTONDOWN()END_MESSAGE_MAP()END_MESSAGE_MAP()一個最簡單的MFC程序/Mouse/Mouse單擊處理單擊處理void CMainFrame:OnLButtonDown(UINT nFlags,CPoint point)void CMainFrame:OnLButtonDo

30、wn(UINT nFlags,CPoint point) CString str=CString str=馬到成功馬到成功!;!; MessageBox(str);MessageBox(str); CFrameWnd:OnLButtonDown(nFlags,point);CFrameWnd:OnLButtonDown(nFlags,point); BOOL CMinApp:InitInstance()BOOL CMinApp:InitInstance() m_pMainWnd=new CMainFrame;/m_pMainWnd=new CMainFrame;/生成主窗口對象指針生成主窗口對

31、象指針 m_pMainWnd-ShowWindow(SW_SHOWMAXIMIZED);m_pMainWnd-ShowWindow(SW_SHOWMAXIMIZED); m_pMainWnd-UpdateWindow();m_pMainWnd-UpdateWindow(); return TRUE;return TRUE; CMinApp MyApp;/CMinApp MyApp;/生成應用程序對象并執(zhí)行應用程序生成應用程序對象并執(zhí)行應用程序MFC程序示例1n什么是視圖?n用戶角度:“視圖”實際上是一個普通窗口n程序員角度:是一個從MFC庫中的Cview類所派生出的類的對象n正如任何C+對象一

32、樣,視圖對象的行為也完全由類(基類和派生類)的成員函數和數據成員所決定n視圖類的創(chuàng)建會導致相應窗口的顯示n按照C+程序設計的習慣,視圖類也被劃分為兩個源文件模塊頭文件(H)和源代碼文件(CPP)n單文檔界面(SDI)和多文檔界面(MDI)nSDI應用程序只有一個窗口nMDI應用程序則可以擁有和不同文檔相對應的多個“子窗口”MFC程序示例1n使用AppWizard產生MFC應用程序的基礎代碼選擇選擇“MFC應用程序應用程序”輸入項目名稱輸入項目名稱單擊單擊“確定確定”MFC程序示例1單擊單擊“下一步下一步”MFC程序示例1選擇選擇“單文檔單文檔”,其它不變其它不變單擊單擊“下一步下一步”MFC程

33、序示例1單擊單擊“下一步下一步”MFC程序示例1單擊單擊“下一步下一步”MFC程序示例1單擊單擊“下一步下一步”MFC程序示例1單擊單擊“下一步下一步”MFC程序示例1單擊單擊“下一步下一步”MFC程序示例1單擊單擊“完成完成”MFC程序示例1項目已經生成,觀項目已經生成,觀察一下項目文件察一下項目文件MFC程序示例1切換為切換為“類視圖類視圖”觀察項目的類結構觀察項目的類結構MFC程序示例1運行該程序的結果運行該程序的結果MFC程序示例1nCMFCExample1View 類的兩個最重要的基類是CView和CWndnCWnd提供了CMFCExample1View的“窗口屬性”nCView則提

34、供了它和應用程序框架其他部分之間的聯系nOnDraw是CView類中的一個虛成員函數,每當視窗需要被重新繪制時,應用程序框架都要調用OnDraw函數n應用程序框架自動調用:當用戶改變了窗口尺寸,或窗口需要重新恢復被遮蓋的部分n用戶觸發(fā)調用:如果視圖對應的數據發(fā)生了變化,則用戶需要調用從CView繼承的Invalidate (或InvalidateRect)成員函數來觸發(fā)對OnDraw的調用nWindows設備環(huán)境nMFC庫中,設備環(huán)境是由CDC類對象來表示的,該對象被作為參數(以指針的形式)傳遞給了OnDraw函數。通過這個設備環(huán)境指針,可以調用CDC類的成員函數來完成各種繪制工作。MFC程序

35、示例1雙擊雙擊OnDraw成員函數成員函數選擇選擇CMFCExample1ViewCMFCExample1View類類出現出現OnDraw成員函數成員函數的代碼的代碼void CMFCExample1View:OnDraw(CDCvoid CMFCExample1View:OnDraw(CDC* * / /* *pDCpDC* */ / pDCpDC) ) CMFCExample1DocCMFCExample1Doc* * pDoc = GetDocument(); pDoc = GetDocument();ASSERT_VALID(pDoc);ASSERT_VALID(pDoc);if (!

36、pDoc)if (!pDoc)return;return;/ TODO: / TODO: 在此處為本機數據添加繪制代碼在此處為本機數據添加繪制代碼/prints in default font & size, top left corner/prints in default font & size, top left cornerpDC-TextOutW(0,0,CString(Hello, world!);pDC-TextOutW(0,0,CString(Hello, world!);/selects a brush for the circle interior/sele

37、cts a brush for the circle interiorpDC-SelectStockObject(GRAY_BRUSH);pDC-SelectStockObject(GRAY_BRUSH);/draws a gray circle, 100 units in diameter /draws a gray circle, 100 units in diameter pDC-Ellipse(CRect(0, 20, 100, 120);pDC-Ellipse(CRect(0, 20, 100, 120); MFC程序示例1設置設備環(huán)境指針參數設置設備環(huán)境指針參數在設備環(huán)境中輸出在設

38、備環(huán)境中輸出文本字符串文本字符串在設備環(huán)境中選擇在設備環(huán)境中選擇灰色畫筆灰色畫筆在設備環(huán)境中在設備環(huán)境中畫一個橢圓畫一個橢圓(圓圓)CRect是是MFC中中表示矩形的類表示矩形的類MFC程序示例1新的運行結果新的運行結果MFC程序示例1雙擊雙擊rc文件文件嘗試使用資源編輯器嘗試使用資源編輯器MFC程序示例1學會使用幫助學會使用幫助單擊菜單單擊菜單“幫助幫助”-“目錄目錄”MFC程序示例2n消息映射n當用戶在視窗中按下鼠標左鍵時,Windows就會自動發(fā)送WM_LBUTTONDOWN消息給該視窗n如果程序需要對WM_LBUTTONDOWN消息有所反應的話,在視圖類中就必須包含如下類似的成員函數n

39、在類的頭文件中也必須包含相應的函數原型說明void CMFCExample1View:OnLButtonDown(UINT nFlags, CPoint point)void CMFCExample1View:OnLButtonDown(UINT nFlags, CPoint point) /event processing code here/event processing code here afx_msg void afx_msg void OnLButtonDown(UINT nFlags, CPoint point);OnLButtonDown(UINT nFlags, CPoin

40、t point);表明該原型說明是針對表明該原型說明是針對消息映射函數而言的消息映射函數而言的MFC程序示例2n消息映射n在代碼文件中還需要有一個消息映射宏,該消息映射宏用于將OnLButtonDown函數和應用程序框架聯系在一起n最后,在類庫頭文件中還需包含如下語句n如何能知道哪個函數和哪個Windows消息相對應呢?nMFC給出了基本的定義(參考Visual C+ 技術內幕(第4版)附錄A)n可以通過手工編制消息控制函數BEGIN_MESSAGE_MAP(CMFCExample1View, CView)BEGIN_MESSAGE_MAP(CMFCExample1View, CView)ON

41、_WM_LBUTTONDOWN()ON_WM_LBUTTONDOWN()/entry specifically for OnLButtonDown/entry specifically for OnLButtonDown/other message map entries/other message map entriesEND_END_MESSAGE_MAP()MESSAGE_MAP()DECLARE_MESSAGE_MAP()DECLARE_MESSAGE_MAP()MFC程序示例2n用視圖類的數據成員保存視圖的狀態(tài)nm_rectEllipse,為Crect類的對象,用來保存橢圓的當前外接

42、矩形nm_nColor,為一個整數,用來保存橢圓的當前顏色值n基于以上的視圖狀態(tài),可以設計一個消息映射成員函數,使得該橢圓的顏色(視圖的狀態(tài))在灰與白之間不斷地來回變化(通過單擊鼠標左鍵觸發(fā))nWindows的客戶區(qū)域n一個窗口具有一個矩形的“客戶區(qū)域”,它包括邊框、標題欄、菜單和貼邊工具欄,CWnd中的GetClient成員函數可以給出客戶區(qū)域的大小n正常情況下,不允許在客戶區(qū)域之外繪圖,并且大多數鼠標信息只有當鼠標指針落在客戶區(qū)域之內時才能夠接收到為什么不用全局變量來為什么不用全局變量來保存視圖的狀態(tài)呢?保存視圖的狀態(tài)呢?MFC程序示例2建立一個新的建立一個新的“MFC應應用程序用程序”項

43、目項目輸入項目名稱輸入項目名稱MFC程序示例2選擇選擇“單文檔單文檔”類型類型單擊單擊“完成完成”MFC程序示例2雙擊雙擊CMFCExample2ViewCMFCExample2View類定位到相應的代碼類定位到相應的代碼MFC程序示例2class CMFCExample2View : public CViewclass CMFCExample2View : public CView protected: / protected: / 僅從序列化創(chuàng)建僅從序列化創(chuàng)建CMFCExample2View();CMFCExample2View();DECLARE_DYNCREATE(CMFCExampl

44、e2View)DECLARE_DYNCREATE(CMFCExample2View)/ / 屬性屬性public:public:CMFCExample2DocCMFCExample2Doc* * GetDocument() const; GetDocument() const;private:private:int m_nColor;int m_nColor;CRect m_rectEllipse;CRect m_rectEllipse; 添加視圖類的成員變量添加視圖類的成員變量MFC程序示例2在構造函數中添加成員在構造函數中添加成員變量的初始化代碼變量的初始化代碼n定位到CMFCExampl

45、e2View的構造函數n定位到CMFCExample2View:OnDraw()函數void CMFCExample2View:OnDraw(CDCvoid CMFCExample2View:OnDraw(CDC* * / /* *pDCpDC* */ / pDCpDC) ) CMFCExample2DocCMFCExample2Doc* * pDoc = GetDocument(); pDoc = GetDocument();ASSERT_VALID(pDoc);ASSERT_VALID(pDoc);if (!pDoc)if (!pDoc)return;return;/ TODO: / TO

46、DO: 在此處為本機數據添加繪制代碼在此處為本機數據添加繪制代碼pDC-SelectStockObject(m_nColor);pDC-SelectStockObject(m_nColor);pDC-Ellipse(m_rectEllipse);pDC-Ellipse(m_rectEllipse); 設置設備環(huán)境指針參數設置設備環(huán)境指針參數選擇畫筆顏色選擇畫筆顏色繪制橢圓繪制橢圓CMFCExample2View:CMFCExample2View()CMFCExample2View:CMFCExample2View():m_rectEllipse(0,0,200,200):m_rectEllip

47、se(0,0,200,200) / TODO: / TODO: 在此處添加構造代碼在此處添加構造代碼m_nColor = GRAY_BRUSH;m_nColor = GRAY_BRUSH; MFC程序示例2n添加消息處理函數OnLButtonDown右鍵單擊視圖類右鍵單擊視圖類選擇彈出菜單中選擇彈出菜單中的的“屬性屬性”MFC程序示例2n添加消息處理函數OnLButtonDown右鍵單擊視圖類右鍵單擊視圖類選擇彈出菜單中選擇彈出菜單中的的“屬性屬性”在屬性窗口中選在屬性窗口中選擇擇“消息消息”標簽標簽尋找尋找WM_LBUTTONDOWN消消息,并點擊該消息右側的下拉息,并點擊該消息右側的下拉框

48、來添加框來添加OnLButtonDownOnLButtonDown函數函數MFC程序示例2出現出現OnLButtonDownOnLButtonDown函數代碼函數代碼MFC程序示例2void CMFCExample2View:OnLButtonDown(UINT nFlags, CPoint point)void CMFCExample2View:OnLButtonDown(UINT nFlags, CPoint point) / TODO: / TODO: 在此添加消息處理程序代碼和在此添加消息處理程序代碼和/ /或調用默認值或調用默認值if (m_rectEllipse.PtInRect(

49、point)if (m_rectEllipse.PtInRect(point) if (m_nColor = GRAY_BRUSH)if (m_nColor = GRAY_BRUSH) m_nColor = WHITE_BRUSH;m_nColor = WHITE_BRUSH; elseelse m_nColor = GRAY_BRUSH;m_nColor = GRAY_BRUSH; InvalidateRect(m_rectEllipse);InvalidateRect(m_rectEllipse); CView:OnLButtonDown(nFlags, point);CView:OnLB

50、uttonDown(nFlags, point); point代表鼠標的位置代表鼠標的位置n在OnLButtonDown函數中添加以下代碼判斷鼠標位置是否位判斷鼠標位置是否位于矩形之內于矩形之內對畫筆顏色進行反轉對畫筆顏色進行反轉通過設置無效區(qū)域來觸發(fā)通過設置無效區(qū)域來觸發(fā)對對OnDraw函數的調用函數的調用MFC程序示例2測試程序運行結果:測試程序運行結果:單擊單擊橢圓所在矩形橢圓所在矩形區(qū)域,區(qū)域,橢圓顏色會發(fā)生翻轉橢圓顏色會發(fā)生翻轉問題:問題:如何能精確地判定橢圓如何能精確地判定橢圓區(qū)域呢?區(qū)域呢?MFC程序示例2void CMFCExample2View:OnLButtonDown(U

51、INT nFlags, CPoint point)void CMFCExample2View:OnLButtonDown(UINT nFlags, CPoint point) / TODO: / TODO: 在此添加消息處理程序代碼和在此添加消息處理程序代碼和/ /或調用默認值或調用默認值CRgn rgn;CRgn rgn;rgn.CreateEllipticRgnIndirect(m_rectEllipse);rgn.CreateEllipticRgnIndirect(m_rectEllipse);if (rgn.PtInRegion(point)if (rgn.PtInRegion(poi

52、nt) if (m_nColor = GRAY_BRUSH)if (m_nColor = GRAY_BRUSH) m_nColor = WHITE_BRUSH;m_nColor = WHITE_BRUSH; elseelse m_nColor = GRAY_BRUSH;m_nColor = GRAY_BRUSH; InvalidateRect(m_rectEllipse);InvalidateRect(m_rectEllipse); CView:OnLButtonDown(nFlags, point);CView:OnLButtonDown(nFlags, point); n調整在OnLBut

53、tonDown函數中的代碼以精確地判定橢圓區(qū)域創(chuàng)建橢圓區(qū)域創(chuàng)建橢圓區(qū)域判斷鼠標位置是判斷鼠標位置是否在橢圓之內否在橢圓之內MFC程序示例3n設備坐標:以設備象素為單位,是基本的坐標系統(tǒng)(0,0)(0,0)X XY Y1000100010001000如果采用不同的分辨率,如果采用不同的分辨率,則圖形大小則圖形大小(物理尺寸物理尺寸)會發(fā)生變化會發(fā)生變化如何畫一個如何畫一個4厘米高、厘米高、4厘米寬的方塊呢?厘米寬的方塊呢?MFC程序示例3n邏輯坐標:不同映射模式下有不同單位(0,0)(0,0)X XY Y10001000-1000-1000注意,邏輯坐標中注意,邏輯坐標中y軸軸的方向不同于設備坐

54、標的方向不同于設備坐標映射種類映射種類映射模式映射模式邏輯單位邏輯單位固定比例映射MM_TEXT(缺省模式)設備像素MM_LOENGLISH0.01英寸MM_HIENGLISH0.001英寸MM_LOMETRIC0.1mmMM_HIMETRIC0.01mmMM_TWIPS1/1440英寸可變比例映射MM_ISOTROPIC隨窗口尺寸變化MM_ANISOTROPIC隨窗口尺寸變化即便在缺省模式下,邏輯即便在缺省模式下,邏輯坐標也不同于設備坐標坐標也不同于設備坐標(比比如有滾動條的情況如有滾動條的情況)縱橫比總是縱橫比總是1:1x和和y的比例因子可以獨的比例因子可以獨立地變化立地變化MFC程序示例

55、3n下面的OnDraw函數繪制一個橢圓,該橢圓隨窗口的大小而變化,正好能在窗口中放下void CMFCExample2View:OnDraw(CDCvoid CMFCExample2View:OnDraw(CDC* * / /* *pDCpDC* */ pDC)/ pDC) CMFCExample2DocCMFCExample2Doc* * pDoc = GetDocument(); pDoc = GetDocument();ASSERT_VALID(pDoc);ASSERT_VALID(pDoc);if (!pDoc)if (!pDoc)return;return;/ TODO: / TOD

56、O: 在此處為本函數添加繪制代碼在此處為本函數添加繪制代碼CRect rectClient;CRect rectClient;GetClientRect(rectClient);GetClientRect(rectClient);pDC-SetMapMode(MM_ANISOTROPIC);pDC-SetMapMode(MM_ANISOTROPIC);pDC-SetWindowExt(1000, 1000);pDC-SetWindowExt(1000, 1000);pDC-SetViewportExt(rectClient.right, -rectClient.bottom);pDC-SetV

57、iewportExt(rectClient.right, -rectClient.bottom);pDC-SetViewportOrg(rectClient.right/2, rectClient.bottom/2);pDC-SetViewportOrg(rectClient.right/2, rectClient.bottom/2);pDC-Ellipse(-500, -500, 500, 500);pDC-Ellipse(-500, -500, 500, 500); 獲取客戶區(qū)域的尺寸獲取客戶區(qū)域的尺寸設定設定“可變比例可變比例”映射模式映射模式設定邏輯坐標的范圍設定邏輯坐標的范圍設定邏輯

58、坐標范圍對應的設定邏輯坐標范圍對應的實際區(qū)域大小實際區(qū)域大小設定坐標原點設定坐標原點繪制橢圓繪制橢圓MFC程序示例3n坐標變換n一旦設置了設備環(huán)境的映射模式,對大多數(并不是所有的)CDC成員函數來說,可以以邏輯坐標作為其參數。n但是,從Windows的鼠標消息(如OnLButtonDown的point參數)所獲得的鼠標指針的坐標值卻是設備坐標。許多其他的MFC庫函數,尤其是Crect類的成員函數,則只能在設備坐標下才能正確工作。n在設置了設備環(huán)境的映射模式及相應的參數之后,CDC類的LPtoDP和DPtoLP函數可用來在邏輯坐標系和設備坐標系之間進行轉換n什么時候該使用什么樣的坐標系呢?n可

59、以認為CDC的大多數成員函數都以邏輯坐標作為其參數n可以認為CWnd的成員函數都以設備坐標作為其參數n所有選中測試(hit-test)操作都應該考慮設備坐標,區(qū)域的定義應采用設備坐標n將一些需要長期使用的值用邏輯坐標來保存MFC程序示例3n當用戶按下鼠標左鍵時,判斷鼠標指針是否落在某個矩形(用邏輯坐標表示的)之內,可用如下代碼void CMFCExample2View:OnLButtonDown(UINT nFlags, CPoint point)void CMFCExample2View:OnLButtonDown(UINT nFlags, CPoint point) CRect rect

60、= m_rect;CRect rect = m_rect;CClient dc(this);CClient dc(this);dc.SetMapMode(MM_LOENGLISH);dc.SetMapMode(MM_LOENGLISH);dc.LPtoDP(rect);dc.LPtoDP(rect);if (rect.PtInRect(point)if (rect.PtInRect(point) 建立建立m_rect的臨時拷貝的臨時拷貝獲取當前的設備環(huán)境獲取當前的設備環(huán)境設置映射模式設置映射模式將邏輯坐標轉換為將邏輯坐標轉換為設備坐標設備坐標判斷鼠標位置是否判斷鼠標位置是否在矩形之內在矩形之內MFC程序示例4

溫馨提示

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

評論

0/150

提交評論