MFC各種控制代碼

2021-05-22 20:54:24 字數 4069 閱讀 3079

首先說一下什麼是dc(裝置描述表)

解:windows應用程式通過為指定裝置(螢幕,印表機等)建立乙個裝置描述表(device context, dc)在dc表示的邏輯意義的「畫布」上進行圖形的繪製。dc是一種包含裝置資訊的資料結構,它包含了物理裝置所需的各種狀態資訊。win32程式在繪製 圖形之前需要獲取dc的控制代碼hdc,並在不繼續使用時釋放掉。

在c++ 程式設計中常會見到hdc,cdc,cclientdc,cpaintdc,cwindowdc這樣的類

hdc是dc的控制代碼,api中的乙個類似指 針的資料型別.

cdc是mfc的dc的乙個類

cdc等裝置上下分類,都含有乙個類的成員變數:m_nhdc;即hdc型別的控制代碼.

cdc 及其派生類的繼承檢視:

cobject

public |------cdc

public |------|------cclientdc

public |------|------cpaintdc

public |------|------cwindowdc

public |------|------cmetafiledc

(注意: 除cmetafiledc以外的三個派生類用於圖形繪製.)

cdc類定義了乙個裝置描述表相關的類,其物件提供成員函式操作設 備描述表進行工作,如顯示器,印表機,以及顯示器描述表相關的視窗客戶區域。

通過cdc的成員函式可進行一切繪圖操作。cdc提供成員 函式進行裝置描述表的基本操作,使用繪圖工具,選擇型別安全的圖形裝置結構(gdi),以及色彩,調色盤。除此之外還提供成員函式獲取和設定繪圖屬性,映 射,控制視口,窗體範圍,轉換座標,區域操作,裁減,劃線以及繪製簡單圖形(橢圓,多邊形等)。成員函式也提供繪製文字,設定字型,印表機換碼,滾動, 處理元檔案。

其派生類:

1.paintdc: 封裝beginpaint和endpaint兩個api的呼叫。

(1)用於響應視窗重繪訊息(wm_paint)是的繪圖輸出。

(2)cpaintdc 在建構函式中呼叫beginpaint()取得裝置上下文,在析構函式中呼叫endpaint()釋放裝置上下文。endpaint()除了釋放裝置上下 文外,還負責從訊息佇列中清除wm_paint訊息。因此,在處理視窗重畫時,必須使用cpaintdc,否則wm_paint訊息無法從訊息佇列中清 除,將引起不斷的視窗重畫。

(3)cpaintdc也只能用在wm_paint訊息處理之中。

2.cclientdc(客 戶區裝置上下文): 處理顯示器描述表的相關的窗體客戶區域。

用於客戶區的輸出,與特定視窗關聯,可以讓開發者訪問目標視窗中客戶區,其構造函 數中包含了getdc,析構函式中包含了releasedc。

3.cwindowdc: 處理顯示器描述表相關的整個窗體區域,包括了框架和控 件(子窗體)。

(1)可在非客戶區繪製圖形,而cclientdc,cpaintdc只 能在客戶區繪製圖形。

(2)座標原點是在螢幕的左上角,cclientdc,cpaintdc下座標原點是在客戶區的左上角。

(3) 關聯一特定視窗,允許開發者在目標視窗的任何一部分進行繪圖,包含邊界與標題,這種dc同wm_ncpaint訊息一起傳送。

4.cmetafiledc: 與元檔案相關的裝置描述表關聯。

cdc提供兩個函式,getlayout和setlayout用於反轉裝置描述表的 布局。用於方便阿拉伯,希伯來的書寫文化習慣的設計,以及非歐洲表中的字型布局。

cdc 包含兩個裝置描述表,m_hdc和m_hattribdc對應於相同的裝置,cdc為m_hdc指定所有的輸出gdi呼叫,大多數的gdi屬性呼叫由 m_hattribdc控制。(如,gettextcolor是屬性呼叫,而settextcolor是一種輸出呼叫。)

下 麵用一些簡單的**看看如果使用這些類

hdc使用, 每次畫線等操作都不mfc封裝的類多了個hdc的引數

執行在哪個裝置描述表操作

hdc hdc=::getdc(m_hwnd);//m_hwnd == this->m_hwnd 即當前視窗控制代碼

movetoex(hdc,m_ptorigin.x,m_ptorigin.y,null);

lineto(hdc,point.x,point.y);

::releasedc(m_hwnd,hdc);//必須和getdc 配對

可以看到hdc的使用較麻煩, 而且如果::getdc和::releasedc不配對的話,會造成錯誤

cdc *pdc=getdc();

pdc->moveto(m_ptorigin);

pdc->lineto(point);

releasedc(pdc);

cclientdc dc(this);

dc.moveto(m_ptorigin);

dc.lineto(point);

cwindowdc dc(this);

cwindowdc dc2(getdesktopwindow());//獲得整個桌面的控制代碼, 一些桌面特效程式使用

dc.moveto(m_ptorigin);

dc.lineto(point);

cpaintdc dc(this);

dc.moveto(m_ptorigin);

dc.lineto(point);

可以看到 mfc 的類使用方便很多, 因為它們都在建構函式和析構函式呼叫了響應的函式進行dc的獲取和釋放.

下面說下一些細點的知識點

cclientdc,cwindowdc 區別不大, 可以說 cwindowdc包含了cclientdc 就拿記事本來說

cclientdc 就只是白白的我們可以編輯文字的那個區域是 客戶區

cwindowdc 除了上面說的白白區域, 還包括選單欄和工具欄等

cclientdc 和cwindowdc 與 cpaintdc 的區別大點

在dc的獲取方面 cclientdc和cwindowdc 使用的是並只能是 getdc 和 releasedc

cpaintdc 使用的是並只能是 beginpaint 和 endpaint

cpaintdc 只能用在響應 wm_paint 事件

cclientdc,cwindowdc 只能用在響應 非wm_paint 事件

關 於 wm_paint 事件

系統會在多個不同的時機傳送wm_paint訊息:當第一次建立乙個視窗時,當改變視窗的大小時,當把視窗從另乙個 視窗背後移出時,當最大化或最小化視窗時,等等,這些動作都是由系統管理的,應用只是被動地接收該訊息,在訊息處理函式中進行繪製操作;大多數的時候應用 也需要能夠主動引發視窗中的繪製操作,比如當視窗顯示的資料改變的時候,這一般是通過invalidaterect和invalidatergn函式來完 成的。invalidaterect和 invalidatergn把指定的區域加到視窗的update region中,當應用的訊息佇列沒有其他訊息時,如果視窗的update region不為空時,系統就會自動產生wm_paint訊息。

系 統為什麼不在呼叫invalidate時傳送 wm_paint訊息呢?又為什麼非要等應用訊息隊列為空時才傳送wm_paint訊息呢?這是因為系統把在視窗中的繪製操作當作一種低優先順序的操作,於 是盡可能地推後做。不過這樣也有利於提高繪製的效率:兩個wm_paint訊息之間通過invalidaterect和invaliatergn使之失效 的區域就會被累加起來,然後在乙個wm_paint訊息中一次得到更新,不僅能避免多次重複地更新同一區域,也優化了應用的更新操作。像這種通過 invalidaterect和invalidatergn來使視窗區域無效,依賴於系統在合適的時機傳送wm_paint訊息的機制實際上是一種非同步工 作方式,也就是說,在無效化視窗區域和傳送wm_paint訊息之間是有延遲的;有時候這種延遲並不是我們希望的,這時我們當然可以在無效化視窗區域後利 用sendmessage 傳送一條wm_paint訊息來強制立即重畫,但不如使用windows gdi為我們提供的更方便和強大的函式:updatewindow和redrawwindow。updatewindow會檢查視窗的update region,當其不為空時才傳送wm_paint訊息;redrawwindow則給我們更多的控制:是否重畫非客戶區和背景,是否總是傳送 wm_paint訊息而不管update region是否為空等。

MFC 控制代碼的理解

控制代碼只是從英文 handle 翻譯過來的,只問句是什麼意思難以解釋,這個是我從別人的空間收集的資訊,功能上的理解 什麼是 控制代碼 handle handle 的本意是把柄,把手的意思。是你與作業系統打交道的東東。舉個通俗的例子,比如你考上了大學,入學後,學校 作業系統 會給你乙個學生證號。注意...

MFC 視窗控制代碼獲取

控制代碼獲取方法 獲取該視窗的控制代碼後,即可向該視窗類類傳送訊息 處理程式 0。獲取所在類視窗的控制代碼 this m hwnd 1。主視窗的控制代碼 無論在主視窗類內,還是子視窗類內,獲取主視窗控制代碼的方法 afxgetmainwnd m hwnd,如 sendmessage afxgetma...

MFC中的控制代碼

1.引出控制代碼 cdc問題 1.cdc dc dc.lineto point 無法執行 2.cdc dc getdc dc lineto point 就可以執行了 mfc中有大量的控制代碼包裝類。所謂控制代碼包裝類,指的是這些類是封裝了系統物件的控制代碼,並提供了一組成員函式作為訪問系統物件的介面...