新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > MFC和Win32技術(shù)應(yīng)用分析

MFC和Win32技術(shù)應(yīng)用分析

作者: 時間:2018-09-05 來源:網(wǎng)絡(luò) 收藏

本文引用地址:http://m.butianyuan.cn/article/201809/388505.htm

OnDraw(dc);

}

在棧中定義了CPaintDC類型的變量dc,隨著構(gòu)造函數(shù)的調(diào)用獲取了設(shè)備描述表;設(shè)備描述表使用完畢,超出其有效范圍就被自動地清除,隨著析構(gòu)函數(shù)的調(diào)用,其獲取的設(shè)備描述表被釋放。

如果希望在堆中創(chuàng)建,例如

CPaintDC *pDC;

pDC = new CPaintDC(this)

則在使用完畢時,用delete刪除pDC:

delete pDC;

直接使用CDC

需要注意的是:在生成CDC對象的時候,并不像它的派生類那樣,在構(gòu)造函數(shù)里獲取相應(yīng)的Windows設(shè)備描述表。最好不要使用::GetDC等函數(shù)來獲取一個設(shè)備描述表,而是創(chuàng)建一個設(shè)備描述表。其構(gòu)造函數(shù)如下:

CDC::CDC()

{

m_hDC = NULL;

m_hAttribDC = NULL;

m_bPrinting = FALSE;

}

其析構(gòu)函數(shù)如下:

CDC::~CDC()

{

if (m_hDC != NULL)

::DeleteDC(Detach());

}

在CDC析構(gòu)函數(shù)中,如果設(shè)備描述表句柄不空,則調(diào)用DeleteDC刪除它。這是直接使用CDC時最好創(chuàng)建Windows設(shè)備描述表的理由。如果設(shè)備描述表不是創(chuàng)建的,則應(yīng)該在析構(gòu)函數(shù)被調(diào)用前分離出設(shè)備描述表句柄并用::RealeaseDC釋放它,釋放后m_hDC為空,則在析構(gòu)函數(shù)調(diào)用時不會執(zhí)行::DeleteDC。當(dāng)然,不用擔(dān)心CDC的派生類的析構(gòu)函數(shù)調(diào)用CDC的析構(gòu)函數(shù),因為CDC::~CDC()不是虛擬析構(gòu)函數(shù)。

直接使用CDC的例子是內(nèi)存設(shè)備上下文,例如:

CDC dcMem; //聲明一個CDC對象

dcMem.CreateCompatibleDC(dc); //創(chuàng)建設(shè)備描述表

pbmOld = dcMem.SelectObject(m_bmBall);//更改設(shè)備描述表屬性

…//作一些繪制操作

dcMem.SelectObject(pbmOld);//恢復(fù)設(shè)備描述表的屬性

dcMem.DeleteDC(); //可以不調(diào)用,而讓析構(gòu)函數(shù)去刪除設(shè)備描述表

GDI對象

在討論設(shè)備描述表時,已經(jīng)多次涉及到GDI對象。這里,需強(qiáng)調(diào)一下:GDI對象要選入Windows 設(shè)備描述表后才能使用;用畢,要恢復(fù)設(shè)備描述表的原GDI對象,并刪除該GDI對象。

一般按如下步驟使用GDI對象:

Create or get a GDI OBJECT hNewGdi;

hOldGdi = ::SelectObject(hdc, hNewGdi)

……

::SelectObject(hdc, hOldGdi)

::DeleteObject(hNewGdi)

先創(chuàng)建或得到一個GDI對象,然后把它選入設(shè)備描述表并保存它原來的GDI對象;用畢恢復(fù)設(shè)備描述表原來的GDI對象并刪除新創(chuàng)建的GDI對象。

需要指出的是,如果hNewGdi是一個Stock GDI對象,可以不刪除(刪除也可以)。通過

HGDIOBJ GetStockObject(

int fnObject // type of stock object

);

來獲取Stock GDI對象。

MFC GDI對象

MFC用一些類封裝了Windows GDI對象和相關(guān)函數(shù),層次結(jié)構(gòu)如圖2-4所示:

CGdiObject封裝了Windows GDI Object共有的特性。其派生類在繼承的基礎(chǔ)上,主要封裝了各類GDI的創(chuàng)建函數(shù)以及和具體GDI對象相關(guān)的操作。

CGdiObject的構(gòu)造函數(shù)僅僅讓m_hObject為空。如果m_hObject不空,其析構(gòu)函數(shù)將刪除對應(yīng)的Windows GDI對象。MFC GDI對象和Windows GDI對象的關(guān)系如圖2-5所示。

使用MFC GDI類的使用

首先創(chuàng)建GDI對象,可分一步或兩步創(chuàng)建。一步創(chuàng)建就是構(gòu)造MFC對象和Windows GDI對象一步完成;兩步創(chuàng)建則先構(gòu)造MFC對象,接著創(chuàng)建Windows GDI對象。然后,把新創(chuàng)建的GDI對象選進(jìn)設(shè)備描述表,取代原GDI對象并保存。最后,恢復(fù)原GDI對象。例如:

void CMyView::OnDraw(CDC *pDC)

{

CPen penBlack; //構(gòu)造MFC CPen對象

if (penBlack.CreatePen(PS_SOLID, RGB(0, 0, 0)))

{

CPen *pOldPen = pDC->SelectObject(penBlack)); //選進(jìn)設(shè)備表,保存原筆

pDC->SelectObject(pOldPen); //恢復(fù)原筆

}else

{

}

}

和在SDK下有一點不同的是:這里沒有DeleteObject。因為執(zhí)行完OnDraw后,棧中的penBlack被銷毀,它的析構(gòu)函數(shù)被調(diào)用,導(dǎo)致DeleteObject的調(diào)用。

還有一點要說明:

pDC->SelectObject(penBlack)返回了一個CPen *指針,也就是說,它根據(jù)原來PEN的句柄創(chuàng)建了一個MFC CPen對象。這個對象是否需要刪除呢?不必要,因為它是一個臨時對象,MFC框架會自動地刪除它。當(dāng)然,在本函數(shù)執(zhí)行完畢把控制權(quán)返回給主消息循環(huán)之前,該對象是有效的。

關(guān)于臨時對象及MFC處理它們的內(nèi)部機(jī)制,將在后續(xù)章節(jié)詳細(xì)討論。

至此,Windows編程的核心概念:窗口、GDI界面(設(shè)備描述表、GDI對象等)已經(jīng)陳述清楚,特別揭示了MFC對這些概念的封裝機(jī)制,并簡明講述了與這些Windows Object對應(yīng)的MFC類的使用方法。還有其他Windows概念,可以參見SDK開發(fā)文檔。在MFC的實現(xiàn)上,基本上僅僅是對和這些概念相關(guān)的Win32函數(shù)的封裝。如果明白了MFC的窗口、GDI界面的封裝機(jī)制,其他就不難了。


上一頁 1 2 3 4 5 6 下一頁

關(guān)鍵詞:

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉