欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: MFC相關(guān)理解 [打印本頁]

作者: heise    時(shí)間: 2014-8-18 01:10
標(biāo)題: MFC相關(guān)理解
                        為了進(jìn)行繪圖操作,必須獲得一個(gè)設(shè)備描述表(或設(shè)備上下文)DC,當(dāng)構(gòu)造了一個(gè)GDI對(duì)象后,該對(duì)象并不會(huì)立即生效,必須選入設(shè)備描述表DC,它才會(huì)在以后的繪制操作中生效;利用SelectObject函數(shù)可以實(shí)現(xiàn)把GDI對(duì)象選入設(shè)備描述表DC中,并且該函數(shù)會(huì)返回指向先前被選對(duì)象的指針,這個(gè)指針主要是為了在完成當(dāng)前的繪制操作后,還原設(shè)備描述表用的。一般情況下,在完成繪圖操作后,要利SelectObject函數(shù)把先前的GDI對(duì)象選入設(shè)備描述表,以便使其恢復(fù)到先前的狀態(tài);
GDI  圖形設(shè)備接口(GDI:Graphics DeviceInterface)是Windows的子系統(tǒng),它負(fù)責(zé)在視訊顯示器和打印機(jī)上顯示圖形。正如您所認(rèn)為的那樣,GDI是Windows非常重要的部分。不只您為Windows編寫的應(yīng)用系統(tǒng)在顯示視覺信息時(shí)使用GDI,就連Windows本身也使用GDI來顯示使用者接口對(duì)象,諸如菜單、滾動(dòng)條、圖標(biāo)和鼠標(biāo)光標(biāo)。
GDI是C++中常用的一種圖形圖像工具,VB、Delphi等語言也移植了GDI ,.net的諸多語言甚至完全采用GDI作為繪制其界面。在Windows系統(tǒng)下,幾乎所有的API都是直接針對(duì)C語言的,除C/C++可直接使用這些API外,其它各種語言都必須移植這些API方法,而唯獨(dú)GDI,微軟提供的Gdiplus頭文件,從類型定義到方法接口,都是針對(duì)C++寫的,這就使得C語言沒法使用這些面向?qū)ο蟮姆椒ǎ词故荊DI提供的原始API,如果不重新定義其參數(shù)中眾多的數(shù)據(jù)類型,C語言也是沒法使用的。
也許是因?yàn)镃語言不適合編寫Windows界面應(yīng)用程序,所以至今沒有發(fā)現(xiàn)GDI的C版本(可能有,但沒發(fā)現(xiàn))。GDI沒C版本的一個(gè)可能的原因是:C版本中的眾多的重載函數(shù),缺省參數(shù),用C來寫卻是頭都大了,不知道用什么函數(shù)名才好(考慮GDI使用了這些年,新的函數(shù)名不應(yīng)與原函數(shù)名偏離太遠(yuǎn))。

void CDrawView::OnLButtonUp(UINT nFlags,  CPoint point){    CPen pen(PS_SOLID, 1,  RGB(255,0,0));    CClientDC  dc(this);    CPen  *pOldPen  = dc.SelectObject(&pen);    dc.MoveTo(m_ptOrigin);   dc.LineTo(point);   dc.SelectObject(pOldPen);   CView::OnLButtonUp(nFlags, point);}
void CDrawView::OnLButtonUp( UINT nFlags, CPoint point){    HDC hdc;   hdc = ::GetDC(m_hWnd);//獲取該窗口的設(shè)備描述表(上下文)   MoveToEx(hdc, m_ptOrigin.x,  m_ptOrigin.y, NULL);//移動(dòng)到線條的起點(diǎn)  LineTo(hdc, point.x, point.y); //通過hdc畫線 ::ReleaseDC(m_hWnd, hdc);//用后一定要釋放,因?yàn)镚etDC里面是申請(qǐng)了資源的}
在MFC中,所有的控件類都是由CWnd類派生的,因此控件實(shí)際上也是窗口;實(shí)際上,控件通常是作為對(duì)話框的子窗口而創(chuàng)建的。對(duì)話框的種類:對(duì)話框可分為:1.模態(tài)(Modal)對(duì)話框 2.非模態(tài)對(duì)話框(Modeless)模態(tài)(Modal)對(duì)話框:模態(tài)對(duì)話框是指當(dāng)其顯示時(shí),程序會(huì)暫停執(zhí)行,直到關(guān)閉這個(gè)模態(tài)對(duì)話框后,才能繼續(xù)執(zhí)行程序中其他人;模態(tài)對(duì)話框壟斷了用戶的輸入,當(dāng)一個(gè)模態(tài)對(duì)話框打開時(shí),用戶只能與該對(duì)話框進(jìn)行交互,而其他用戶界面對(duì)象接收不到輸入信息;我們平時(shí)所遇到的大部分對(duì)話框都是模態(tài)對(duì)話框;非模態(tài)對(duì)話框(Modeless):當(dāng)非模態(tài)對(duì)話框(Modeless)顯示時(shí),允許轉(zhuǎn)而執(zhí)行程序中其他的任務(wù),而不用關(guān)閉這個(gè)對(duì)話框。典型的例子是Windows提供的記事本程序中的“查找”對(duì)話框,該對(duì)話框不會(huì)壟斷用戶的輸入,打開“查找”對(duì)話框后,仍可以與其他用戶界面對(duì)象進(jìn)行交互,用戶可以一邊查找,一邊修改文章,這樣就大大方便了使用。
MFC為我們提供一個(gè)設(shè)備描述表的封裝類CDC,該類封裝了所有與繪圖相關(guān)的操作;該類提供了一個(gè)數(shù)據(jù)成員m_hDC,用來保存與CDC類相關(guān)的DC句柄。CDC是MFC的DC【設(shè)備上下文/設(shè)備描述表】的一個(gè)類;CDC中所有MFC的DC的基類.常用的CClientDC dc(this);就是CDC的子類(或稱派生類).CDC等設(shè)備上下分類,都含有一個(gè)類的成員變量:m_nHdc;即HDC類型的句柄.記住下面的一句話,會(huì)有助于你的理解:MFC的類,是在用window API語句開發(fā)出來的有一定功能的小程序.(也可稱為類).使用它的默認(rèn)方法,就是,記住它的名字與參數(shù)(可以用筆記,代替腦記).DC(設(shè)備上下文):設(shè)備上下文是一種包含有關(guān)某個(gè)設(shè)備(如顯示器或打印機(jī))的繪制屬性信息的 Windows數(shù)據(jù)結(jié)構(gòu)。所有繪制調(diào)用都通過設(shè)備上下文對(duì)象進(jìn)行,這些對(duì)象封裝了用于繪制線條、形狀和文本的 Windows API。設(shè)備上下文允許在Windows 中進(jìn)行與設(shè)備無關(guān)的繪制。設(shè)備上下文可用于繪制到屏幕、打印機(jī)或者圖元文件。

設(shè)備上下文是一種包含有關(guān)某個(gè)設(shè)備(如顯示器或打印機(jī))的繪制屬性信息的Windows 數(shù)據(jù)結(jié)構(gòu)。所有繪制調(diào)用都通過設(shè)備上下文對(duì)象進(jìn)行,這些對(duì)象封裝了用于繪制線條、形狀和文本的Windows API。設(shè)備上下文允許在 Windows 中進(jìn)行與設(shè)備無關(guān)的繪制。設(shè)備上下文可用于繪制到屏幕、打印機(jī)或者圖元文件。
CPaintDC 對(duì)象將 Windows 的常見固定用語進(jìn)行封裝,調(diào)用 BeginPaint 函數(shù),然后在設(shè)備上下文中繪制,最后調(diào)用EndPaint 函數(shù)。CPaintDC 構(gòu)造函數(shù)為您調(diào)用BeginPaint,析構(gòu)函數(shù)則調(diào)用EndPaint。該簡化過程將創(chuàng)建 CDC 對(duì)象、繪制和銷毀 CDC 對(duì)象。在框架中,甚至連這個(gè)過程的大部分也是自動(dòng)的。具體說來,框架給OnDraw 函數(shù)傳遞(通過 OnPrepareDC)準(zhǔn)備好的CPaintDC,您只需繪制到 CPaintDC 中。根據(jù)調(diào)用 OnDraw 函數(shù)的返回,CPaintDC 被框架銷毀并且將基礎(chǔ)設(shè)備上下文釋放給Windows。
CClientDC對(duì)象封裝對(duì)一個(gè)只表示窗口工作區(qū)的設(shè)備上下文的處理。CClientDC 構(gòu)造函數(shù)調(diào)用GetDC 函數(shù),析構(gòu)函數(shù)調(diào)用 ReleaseDC函數(shù)。CWindowDC 對(duì)象封裝表示整個(gè)窗口(包括其框架)的設(shè)備上下文。
CMetaFileDC 對(duì)象將繪制封裝到 Windows 圖元文件中。與傳遞給OnDraw 的 CPaintDC 相反,在這種情況下您必須自己調(diào)用 OnPrepareDC。
設(shè)備上下文(Device Context)DC
DC實(shí)際上是GDI內(nèi)部保存的數(shù)據(jù)結(jié)構(gòu)。
DC與特定的顯示設(shè)備(如顯示器或打印機(jī))相關(guān)。
對(duì)于顯示器,DC總是與顯示器上的特定視窗相關(guān)。
DC中的有些值是圖形「屬性」,這些屬性定義了GDI繪圖函數(shù)工作的細(xì)節(jié)。
例如,對(duì)於TextOut,DC的屬性確定了文字的顏色、文字的背景色、x坐標(biāo)和y坐標(biāo)映射到視窗的顯示區(qū)域的方式,以及顯示文字時(shí)Windows使用的字體。
MSDN的解釋:一個(gè)DC是一個(gè)結(jié)構(gòu),它定義了一系列圖形對(duì)象的集合以及它們相關(guān)的屬性,以及影響輸出效果的一些圖形模式。這些圖形對(duì)象包括一個(gè)畫線的筆,一個(gè)填充和painting的畫刷,一個(gè)用來向屏幕拷貝的位圖,一個(gè)定義了一系列顏色集合的調(diào)色板,一個(gè)用來剪裁等操作的區(qū)域,一個(gè)做painting和drawing操作的路徑。
一個(gè)應(yīng)用程序從不直接地訪問(access)dc,常見的取得dc的方式有以下幾種:
SDK's way:
1. BeginPaint
case WM_PAINT: HDC hdc = BeginPaint(hwnd, &ps);EndPaint(hwnd, &ps);
MSDN的解釋: BeginPaint函數(shù)自動(dòng)地設(shè)置dc的剪裁區(qū)域,這個(gè)剪裁區(qū)域,剪裁的是由InvalidateRect或 InvalidateRgn 函數(shù)觸發(fā)的窗口無效區(qū)域,或者是系統(tǒng)給出的無效區(qū)域,當(dāng)窗口被sizing,moving, creating, scrolling, or any other operation that affectsthe client area.
一個(gè)應(yīng)用程序從不調(diào)用BeginPaint,除了在收到一個(gè)WM_PAINT消息的時(shí)候;每一BeginPaint調(diào)用之后,需要調(diào)用EndPaint函數(shù)。
2.GetXXXDC
GetDC取得與窗口客戶區(qū)相關(guān)的dc,GetWindowDC取得與整個(gè)窗口(包括客戶區(qū)和非客戶區(qū))相關(guān)的dc。
還有一類重要的dc,內(nèi)存DC,是一個(gè)虛擬的內(nèi)存設(shè)備上下文,我們對(duì)它進(jìn)行繪圖等操作,不會(huì)顯示在屏幕或打印機(jī)上,而我們可以在它完成之后,拷貝到屏幕上或打印機(jī)上來輸出,這樣我們可以避免因?yàn)椴僮鞫o屏幕帶來的閃爍,對(duì)于打印機(jī)而言,打印只能是從上往下打,而我們?cè)贛EMDC中,可以隨意進(jìn)行操作,這樣可以輸出直接在打印機(jī)上輸出所達(dá)不到的效果.
在窗口上貼圖一般總是要用到內(nèi)存DC,將所有的繪制工作先繪制在內(nèi)存DC上,然活一次性拷貝到屏幕DC上,就是這樣了。
這里是使用mfc進(jìn)行的說明,對(duì)hdc進(jìn)行了封裝,但是道理是一樣的。
1.創(chuàng)建內(nèi)存DC
CDC m_MenDC; //聲明內(nèi)存DC
CDC m_MenDC2; //聲明內(nèi)存DC
CBitmap m_Bitmap1; //聲明一個(gè)位圖
m_MenDC.CreateCompatibleDC(GetDC());//創(chuàng)建內(nèi)存DC
m_MenDCMap.CreateCompatibleDC(GetDC());//創(chuàng)建內(nèi)存DC
m_Bitmap1.CreateCompatibleBitmap(GetDC(),1024,768);//創(chuàng)建一個(gè)兼容位圖,這是一個(gè)空的位圖,我們可以把它想象成一個(gè)屏幕,可以在上面畫線,輸出文字等,自己制作一個(gè)簡單的位圖。
m_hbmpBK =(HBITMAP)::LoadImage(AfxGetInstanceHandle(),path+"Bk4.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//我們也可以從硬盤導(dǎo)入一張位圖。
2,為內(nèi)存DC選入一張位圖,或兼容位圖。
m_MenDC.SelectObject(m_hbmpBK);
m_MenDC2.SelectObject(m_Bitmap1);
注意,想要在內(nèi)存dc上作圖,必須先為它選入一張位圖,或兼容位圖。想想前面,不管BeginPaint還是getDC都有一個(gè)相關(guān)的區(qū)域。這里的位圖就是相關(guān)區(qū)域。
3.接著我們就可以像在窗口上作圖一樣,使用gdi函數(shù)(drawline,textout...)在內(nèi)存dc上作圖了。同時(shí)也可以從一個(gè)內(nèi)存dc拷貝位圖到另一個(gè)內(nèi)存dc。
m_MenDC2.BitBlt(0,0,1024,768,&m_MenDC,0,0,SRCCOPY);
4,繪制結(jié)果的顯示,將這些東西拷到屏幕DC(getdc取得的dc)上
// 所謂的雙緩沖就是把所有的繪制工作都做在一個(gè)內(nèi)存DC上。
// 最后一次拷到屏幕DC上,只能有一次
dc.BitBlt(0,0,1024,768,&m_MenDC2,0,0,SRCCOPY);//這里的dc是通過getdc取得的屏幕或者某個(gè)窗口的dc。
這里所強(qiáng)調(diào)的“一次”;是不要連續(xù)將幾個(gè)內(nèi)存DC的內(nèi)容都拷到屏幕DC上,這樣沒有起到雙緩沖的效果。如果你搞了很多個(gè)內(nèi)存DC,想把這些東西都顯示出來,那你應(yīng)該先把這多個(gè)內(nèi)存DC的內(nèi)容同時(shí)拷到另外一個(gè)內(nèi)存DC上,再把這個(gè)內(nèi)存DC的內(nèi)容拷到屏幕DC上。

CPaintDC dc(this);MFC的CPaintDC類是從MFC的CDC類派生的,CDC類封裝了Windows設(shè)備環(huán)境,以及包含了繪制到屏幕、打印機(jī)和其他設(shè)備的幾十個(gè)成員函數(shù)
在MFC程序中,我們并不經(jīng)常直接調(diào)用Windows API,而是從MFC類創(chuàng)建對(duì)象并調(diào)用屬于這些對(duì)象的成員函數(shù).也就是說MFC封裝了Windows API 你說你喜歡C++而MFC換一種說法就是一個(gè)用C++寫的一個(gè)函數(shù)庫 然后你來調(diào)用 只不過這個(gè)類不是你寫的
           MFC提供數(shù)百個(gè)類,最重要的、也是編寫任何VC++應(yīng)用程序都必不可少的兩個(gè)類CWinApp和CFrameWnd,這兩個(gè)類是編寫復(fù)雜龐大應(yīng)用程序的基石。
1>封裝特性:構(gòu)成MFC框架的是MFC類庫而MFC類庫又是C++的一個(gè)類庫。這些類封裝WIN32應(yīng)用程序編程接口,OLE(Object Link Embed 對(duì)象鏈接嵌入)特性,ODBC和DAO數(shù)據(jù)訪問的功能。
2>繼承特性:MFC抽象出了眾多類的共同特性,并設(shè)計(jì)出一些基類作為實(shí)現(xiàn)其他類的基礎(chǔ),這些類中最重要的類是CObject類和CCmdTarget類,程序員可以從適當(dāng)?shù)腗FC類中派生出自己的類,實(shí)現(xiàn)特定的功能達(dá)到編程的目的。
3>虛擬和消息映射:MFC是以C++為基礎(chǔ),當(dāng)然支持虛函數(shù),但作為一個(gè)編程框架必須要解決的是效率問題:如果MFC僅僅通過虛函數(shù)來支持動(dòng)態(tài)約束必然會(huì)產(chǎn)生大量的虛函數(shù)表這樣編程框架過于臃腫而且消耗更多的內(nèi)存。但是MFC建立了消息映射機(jī)制這樣降低了內(nèi)存的使用卻大大提高了效率
消息映射是一個(gè)將消息和成員函數(shù)相互關(guān)聯(lián)的表,當(dāng)應(yīng)用程序的框架窗口接收到一個(gè)消息時(shí),MFC將搜索該窗口的消息映射,如果存在一個(gè)處理消息的處理程序,那么就調(diào)用該處理程序.
它通過宏來實(shí)現(xiàn)消息到成員函數(shù)的映射,而且這些函數(shù)不必是虛擬的成員函數(shù),這樣不需要為消息映射函數(shù)生成一個(gè)很大的虛擬函數(shù)表(V表),節(jié)省內(nèi)存。
MFC消息映射機(jī)制:
將消息與消息處理函數(shù)聯(lián)系起來,形成一一對(duì)應(yīng)的機(jī)制。
消息映射宏
聲明: DECLARE_MESSAGE_MAP
定義:
        BEGIN_MESSAGE_MAP
   ON_COMMAND
   ON_CONTROL
   ON_MESSAGE
       END_MESSAGE_MAP
MFC主要組成部分:類、宏和全局函數(shù)。
類是MFC中最主要的內(nèi)容。MFC類是以層次結(jié)構(gòu)方式組織起來的。MFC中的類分成兩部分,除了一些輔助類,大多數(shù)的MFC類是直接或間接從根類CObject派生而來。
MFC宏主要功能:消息映射、運(yùn)行時(shí)對(duì)象類型服務(wù)、診斷服務(wù)、異常處理。
MFC約定:全局函數(shù)以“Afx”為前綴,全局變量以“afx”為前綴
MFC類的層次關(guān)系
CObject項(xiàng)目類)->CCmdTarget(消息響應(yīng)類)->
{
CWinThread(線程類)->CWinApp(Window應(yīng)用程序類)
CDocument(文檔類)
CWnd(窗體類)->[
              CFrameWnd(框架類)
              CView(視圖類)
              ]
}

CObject類由于MFC中大部分類是從CObject類繼承而來的,CObject類描述了幾乎所有的MFC類的一些公共特性,CObject類為程序員提供了對(duì)象診斷、運(yùn)行時(shí)類型識(shí)別和序列化等功能。
CCmdTarget類由CObject類直接派生而來,它負(fù)責(zé)將消息發(fā)送到能夠響應(yīng)這些消息的對(duì)象。它是所有能進(jìn)行消息映射的MFC類的基類。
CWinApp類在任何MFC應(yīng)用程序中有且僅有一個(gè)CWinApp派生類的對(duì)象,它代表了程序中運(yùn)行的主線程,也代表了應(yīng)用程序本身。 CWinApp類取代了WinMain()主函數(shù)在SDK應(yīng)用程序中的地位。傳統(tǒng)SDK應(yīng)用程序WinMain()函數(shù)完成的工作。現(xiàn)在由類CWinApp的InitApplication(),InitInstance()和Run()三個(gè)成員函數(shù)承擔(dān)。
CWnd類由CCmdTarget類直接派生而來,該類及其派生類的實(shí)例是一個(gè)窗口。CWnd類代表了MFC中最基本的GUI對(duì)象,它是一個(gè)功能最完善、成員函數(shù)最多的MFC類。
CFrameWnd類是CWnd類的派生類,主要用來掌管一個(gè)窗口,它取代了SDK應(yīng)用程序中窗口函數(shù)WndProc()的地位。CFrameWnd類的對(duì)象是一個(gè)框架窗口,包括邊框、標(biāo)題欄、菜單、最大化按鈕、最小化按鈕和一個(gè)激活的視圖。
CDocument類在應(yīng)用程序中作為用戶文檔類的基類,它代表了用戶存儲(chǔ)或打開的一個(gè)文件。
CView類是MFC中一個(gè)很基本的類,它作為其它MFC視圖類和用戶視圖派生類的基類。
從API編程到MFC編程的過渡:
WinMain()
{  初始化WNDCLASS
    注冊(cè)窗體結(jié)構(gòu)
    創(chuàng)建窗口           ->>>>>>>>應(yīng)用程序類CWinApp
    顯示窗口
    消息循環(huán)
}

WndProc()
{ switch(…)            
           ->>>>>>>>>框架窗口類CFrameWnd
}

MFC Object和Windows Object的對(duì)應(yīng)關(guān)系:
描述                 Windows句柄       MFC Object
窗口                  HWND                    CWnd
設(shè)備上下文        HDC                      CDC
菜單                   HMENU                CMenu
筆                       HPEN                   CPen
刷子                   HBRUSH              CBrush
字體                   HFONT                 CFont
位圖                    HBITMAP            CBitmap
套接字                SOCKET              CSocket

三、手工創(chuàng)建一個(gè)MFC應(yīng)用程序:
注意:創(chuàng)建MFC程序,要?jiǎng)?chuàng)建一個(gè)Win32空項(xiàng)目,并要選擇項(xiàng)目屬性中的”在共享DLL文件中使用MFC,然后新建我們的文件
例子:在”hello.h”頭文件中添寫如下代碼:
class CMyApp:public CWinApp
{
public:
virtual BOOL InitInstance();//虛函數(shù)
};
class CMainWindow:public CFrameWnd
{
public:
CMainWindow();
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP();//聲明消息映射
};
在”hello.cpp”源文件中添寫如下代碼:
#include
#include “hello.h"
CMyApp myApp;
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMainWindow;

      m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()       //消息映射
CMainWindow::CMainWindow() //構(gòu)造函數(shù)初始化
{
    Create(NULL,“我的第一個(gè)MFC應(yīng)用程序”);//創(chuàng)建窗體
}
void CMainWindow::OnPaint()
{  CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
  dc.DrawText("Hello MFC",-1,&rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
CWinApp是應(yīng)用程序類,在MFC應(yīng)用程序中必須從這個(gè)類派生出一個(gè)類,該派生類是MFC應(yīng)用程序的入口
必須定義這個(gè)派生類的對(duì)象,并且只能有一個(gè)這個(gè)對(duì)象代表整個(gè)應(yīng)用程序。
成員函數(shù):InitInstance()
功能:初始化應(yīng)用程序?qū)嵗痛翱趯?shí)例,
虛函數(shù)CWinApp::InitInstance必須在派生類中重寫。在InitInstance函數(shù)中,編寫初始化代碼,如:
創(chuàng)建一個(gè)窗口
顯示一個(gè)窗口
CFrameWnd類
作用:為應(yīng)用程序提供一個(gè)窗口,同時(shí)實(shí)現(xiàn)消息處理功能。
成員函數(shù): Create()
功能:創(chuàng)建窗體,將之賦于CFrameWnd對(duì)象上。
BOOL Create(窗口類型, 窗口標(biāo)題,顯示風(fēng)格,顯示區(qū)域,符窗口句柄,菜單,擴(kuò)展顯示風(fēng)格,上下文對(duì)象)共有8個(gè)參數(shù),前兩個(gè)必須給出,后6個(gè)可以默認(rèn)。
MFC應(yīng)用程序的核心就是基于CWinApp類的應(yīng)用程序?qū)ο?CWinApp提供了消息循環(huán)來檢索消息并將消息調(diào)度給應(yīng)用程序的窗口.我們?cè)诰帉慚FC應(yīng)用程序時(shí),要包含afxwin.h,
一個(gè)MFC應(yīng)用程序可以有且僅有一個(gè)應(yīng)用程序?qū)ο?對(duì)象必須聲明為在全局范圍內(nèi)有效(也就是全局對(duì)象),以便它在程序開始時(shí)即在內(nèi)存中被實(shí)例化
我們的Hello MFC的應(yīng)用程序類被命名為CMyApp,它在hello.cpp中用如下語句進(jìn)行了實(shí)例化:
CMyApp myApp;
CMyApp的類聲明在hello.h中代碼如下:
class CMyApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
CMyApp沒有聲明任何的數(shù)據(jù)成員,只是重寫了一個(gè)從CWinApp類中繼承來的函數(shù),在應(yīng)用程序的生存期內(nèi)InitInstance的調(diào)用比較早,是在應(yīng)用程序開始運(yùn)行以后而窗口創(chuàng)建之前,除非InitIstance創(chuàng)建一個(gè)窗口,否則應(yīng)用程序是不會(huì)有窗口,這正是為什么即使最小的MFC應(yīng)用程序也必須從CWinApp派生出一個(gè)類并重寫CWinApp::InitIstance的原因
InitInstance函數(shù):CWinApp::InitInstance是一個(gè)虛函數(shù),其默認(rèn)操作僅包含一條語句:return TRUE;
InitInstance是用來執(zhí)行程序每次開始時(shí)都需要進(jìn)行的初始化工作最好的地方
在hello.cpp中,CMyApp的InitInstance通過實(shí)例化hello的CMainWindow類來創(chuàng)建hello窗口,語句:
m_pMainWnd = new CMainWindow;

構(gòu)造了一個(gè)CMainWindow對(duì)象指針,并將其地址復(fù)制到了應(yīng)用程序?qū)ο蟮膍_pMainWnd數(shù)據(jù)成員中,窗口創(chuàng)建以后,InitInstance就會(huì)通過CMainWindow指針調(diào)用ShowWindow和UpdateWindow函數(shù)顯示它:

m_pMainWnd->ShowWindow(m_nCmdShow);

m_pMainWnd->UpdateWindow();
ShowWindow和UpdateWindow是所有窗口對(duì)象共用的CWnd成員函數(shù)其中包括CFrameWnd類的對(duì)象,CMainWindow就是從CFrameWnd派生出來的.
要從MFC程序調(diào)用一個(gè)常規(guī)的Windows API函數(shù),需要在函數(shù)名稱前添加一個(gè)全局運(yùn)算符:: 例如:::UpdateWindow();
通過生成窗口對(duì)象并調(diào)用其Create函數(shù),MFC應(yīng)用程序可以創(chuàng)建一個(gè)窗口,在CMyApp::InitInstance中,hello創(chuàng)建了一個(gè)CMainWindow對(duì)象,CMainWindow的構(gòu)造函數(shù)生成在屏幕上看到的窗口:
Create(NULL,”我的第一個(gè)MFC應(yīng)用程序”);
CPaintDC dc(this);
MFC的CPaintDC類是從MFC的CDC類派生的,CDC類封裝了Windows設(shè)備環(huán)境,以及包含了繪制到屏幕、打印機(jī)和其他設(shè)備的幾十個(gè)成員函數(shù)

在MFC中如何處理消息呢?
在SDK中我們利用的是消息循環(huán)和窗口過程函數(shù)對(duì)消息進(jìn)行消息處理.
在MFC中我們用的是消息映射機(jī)制.
下面是將消息映射添加到一個(gè)類中需要做的全部工作.
1>通過將DECLARE_MESSAGE_MAP語句添加到類聲明中,聲明消息映射.
2>通過放置標(biāo)識(shí)消息的宏來執(zhí)行消息映射,相應(yīng)的類將在對(duì)BEGIN_MESSAGE_MAP和END_MESSAGE_MAP的調(diào)用之間處理消息
3>添加成員函數(shù)來處理消息
1、構(gòu)造CWinApp派生類的對(duì)象
2、系統(tǒng)調(diào)用WinMain()
3、WinMain調(diào)用InitInstance,在該函數(shù)中創(chuàng)建CFrameWnd派生類對(duì)象,調(diào)用Create函數(shù)創(chuàng)建窗口、調(diào)用ShowWindow函數(shù)顯示窗口。
4、之后內(nèi)部機(jī)制調(diào)用Run,接受用戶的消息,并將消息導(dǎo)向默認(rèn)的處理函數(shù)。當(dāng)接收到WM_QUIT消息時(shí),Run內(nèi)部調(diào)用ExitInstance,退出程序。
MFC采用消息映射(Message Map)機(jī)制取代C/C++語言中的switch-case結(jié)構(gòu)來處理消息。
消息映射:在MFC中把消息處理函數(shù)和它所要處理的特定的消息連接起來的一種機(jī)制。
它通過宏來實(shí)現(xiàn)消息到成員函數(shù)的映射,而且這些函數(shù)不必是虛擬的成員函數(shù),這樣不需要為消息映射函數(shù)生成一個(gè)很大的虛擬函數(shù)表(V表),節(jié)省內(nèi)存。
MFC消息映射機(jī)制包括一組消息映射宏。一條消息映射宏把一個(gè)Windows消息和其消息處理函數(shù)聯(lián)結(jié)起來。
MFC應(yīng)用程序框架提供了消息映射功能。
在類的實(shí)現(xiàn)源文件中用BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()宏來定義消息映射。
在類定義的結(jié)尾用DECLARE_MESSAGE_MAP()宏來聲明使用消息映射。
Hello的CmainWindow類只處理一種消息類型—WM_PAINT,因此其消息映射的實(shí)現(xiàn)如下所示:
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd);
ON_WM_PAINT()
END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP開始了消息映射,并標(biāo)識(shí)了消息映射所屬的類和該類的基類
END_MESSAGE_MAP()結(jié)束消息映射.
ON_WM_PAINT()在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP()之間,稱做消息條目,在MFC為100多種Window消息提供了宏.
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
afx_msg 醒目地暗示OnPaint是一個(gè)消息處理程序,
DECLARE_MESSAGE_MAP()聲明消息映射
MFC把消息主要分為三大類:
(1)、標(biāo)準(zhǔn)Windows消息(WM_XXX)
使用宏:ON_WM_XXX()          特點(diǎn):有默認(rèn)的消息處理函數(shù)
(2)、命令消息:(WM_COMMAND)
來自于菜單、工具條、按鈕等的消息
使用宏: ON_COMMAND(命令按鈕標(biāo)識(shí)符ID,消息處理函數(shù))
特點(diǎn):由用戶指定消息處理函數(shù)
3、”Notification消息” (通知消息) 由控件產(chǎn)生:
BOOL    布爾值,取值為TRUE或者FALSE
BSTR     32為字符指針
BYTE      8位整數(shù)無符號(hào)的
COLORREF     32位數(shù)值代表一個(gè)顏色值
DWORD    32位整數(shù)無符號(hào)的
LONG     32位整數(shù)帶符號(hào)的
LPCTSTR   32位指針,指向一個(gè)常字符串
LPVOID    32位指針,指向一個(gè)為指定類型的數(shù)據(jù)
MFC特有的數(shù)據(jù)類型:
1>POSITION :一個(gè)數(shù)值,代表數(shù)組或者鏈表中元素的位置,在MFC中常用于數(shù)據(jù)處理類
2>LPRECT:32位指針,指向一個(gè)不變的矩形區(qū)域結(jié)構(gòu)






歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1