MFC中,控制代碼和指標的關係

2021-07-12 06:35:03 字數 2471 閱讀 4253

1.引出控制代碼

cdc問題:

1.cdc dc;dc.lineto(point);無法執行

2.cdc *dc=getdc();dc->lineto(point);就可以執行了

mfc中有大量的控制代碼包裝類。顧名思義,所謂控制代碼包裝類,指的是這些類是封裝了系統物件的控制代碼(hwnd,hdc,hbitmap等等),並提供了一組成員函式作為訪問系統物件的介面。(這是一種資源封裝的理念的體現)。從這些控制代碼包裝類的意義上可以看出,乙個被完全構造好,處於良好狀態的mfc物件,其中的控制代碼成員(用以標誌乙個系統物件)必須是有效的(這是必要條件),才能正常使用那些成員函式來操作這個系統物件。所以一般的mfc控制代碼包裝類物件的構建要完成兩個任務:

第一,建立乙個控制代碼包裝類物件。(在堆或在棧中均可,視實際需要而定) 第二,初始化其中的系統物件控制代碼。大部分的包裝類物件的構建都通常分兩步進行:1.建立乙個物件,2.通過create等類似的成員函式建立系統物件並初始化物件中的控制代碼成員。當然這兩部也可以直接在建構函式中完成。(此時一般需要乙個系統物件控制代碼作為引數,或者另乙個被良好構造的控制代碼包裝類物件做引數,以在建構函式中就能初始化控制代碼成員。其他方法還有通過attach和detach將部分構造的物件和系統物件控制代碼繫結,或者通過fromhandle獲得乙個臨時的控制代碼包裝類物件等 )

現在問題就很清晰了:cdc dc;dc.lineto( point );無法執行,是因為dc這個物件僅僅被部分構建,其中的系統物件控制代碼成員並沒有賦值為乙個有效的繪圖裝置控制代碼,自然其後的lineto呼叫就會失敗。而:cdc *dc = getdc();dc->lineto( point );

通過呼叫視窗類的getdc()成員函式,將返回乙個被良好構造的cdc物件(即該物件中的裝置控制代碼成員已經被賦值為乙個有效的控制代碼),所以其後的lineto操作就沒問題。也就是問題的關鍵不在於物件建立於棧還是堆中,而在於是否完全構造好了乙個控制代碼包裝類物件。

2.控制代碼到底是什麼東東呢,指標呢?

其實,控制代碼並沒有什麼神奇之處,不管哪種控制代碼,實際都是乙個整數。它標識一種資源,如視窗、位圖等等。就象你找乙個人,必須知道它的位址一樣,如果你要操作一種資源,必須先獲得控制代碼。「取視窗控制代碼()」並不是只能取出視窗的控制代碼,所有視窗控制項,如編輯框、標籤等都可以用本命令取出自己的控制代碼,如:編輯框1.取視窗控制代碼()或標籤1.取視窗控制代碼()。控制項的控制代碼同樣,任何控制項都有它自身的特有屬性,控制代碼也就指它的特有屬性(包括共性)。

控制代碼英文譯作handle,handle的本意是把柄,把手的意思,是與作業系統打交道的東東。有人舉過比較通俗的例子:你考上了大學,入學後,學校(作業系統)會給你乙個學生證號。注意,這個號碼是學校指定的,你無法自選。有了這個號碼(學生證,假設一證多用)享受學校提供的服務:如你就可以去圖書館借書,去食堂吃飯,去教室上課等 等。但你不能到食堂裡買啤酒,因為學校不允許這種服務。而在計算機中系統提供的服務就是api呼叫了。當你有了handle,就可以理直氣壯地向系統提出呼叫api的服務。而指標的權力就大多了,有了指標你可以到處去喝酒,打架,學校(作業系統)管不著,所以控制代碼和指標的區別在於控制代碼只能呼叫系統提供的服務。而控制代碼雖然是乙個能相互區別的號碼,但與我們普通的id號又有區別,普通的id號是可以由程式設計師自己定義的,而控制代碼不行,它是物件生成時系統指定的,是為了區別系統中存在的各個物件,這個控制代碼不是由程式設計師賦給的。

可以引用csdn上乙個人的話來說明控制代碼,指標物件例項之間的關係:

牧童遙指杏花村。牧童的手為指標,杏花村的牌子為控制代碼,杏花村酒店為物件的例項。

3.深入**控制代碼

更透徹的說,控制代碼是一種指向指標的指標。大家都知道,所謂指標是一種記憶體位址。應用程式啟動後,組成這個程式的各物件是住留在記憶體的。如果簡單地理解,似乎我們只要獲知這個記憶體的首位址,那麼就可以隨時用這個位址訪問物件。但是,如果您真的這樣認為,那麼您就大錯特錯了。我們知道,windows是乙個以虛擬記憶體為基礎的作業系統。在這種系統環境 下,windows記憶體管理器經常在記憶體中來回移動物件,依此來滿足各種應用程式的記憶體需要。物件被移動意味著它的位址變化了。如果位址總是如此變化,我們該到**去找該物件呢? 為了解決這個問題,windows作業系統為各應用程式騰出一些內儲存位址,用來專門登記各應用物件在記憶體中的位址變化,而這個位址(儲存單元的位置)本 身是不變的。windows記憶體管理器在移動物件在記憶體中的位置後,把物件新的位址告知這個控制代碼位址來儲存。這樣我們只需記住這個控制代碼位址就可以間接地知道物件具體在記憶體中的哪個位置。這個位址是在物件裝載(load)時由系統分配給的,當系統解除安裝時(unload)又釋放給系統。控制代碼位址(穩定) ─→記載著物件在記憶體中的位址─→物件在記憶體中的位址(不穩定) ─→實際物件 本質:windows程式中並不是用實體地址來標識乙個記憶體塊,檔案,任務或動態裝入模組的,相反的,windows api給這些專案分配確定的控制代碼,並將控制代碼返回給應用程式,然後通過控制代碼來進行操作。 但是必須注意的是程式每次從新啟動,系統不能保證分配給這個程式的控制代碼還是原來的那個控制代碼,而且絕大多數情況的確不一樣的。假如我們把進入電影院看電影看 成是乙個應用程式的啟動執行,那麼系統給應用程式分配的控制代碼總是不一樣,這和每次電影院售給我們的門票總是不同的乙個座位是一樣的道理。

本文出處: 

mfc中id,控制代碼,指標

win32直接操作的是控制代碼handle,每個控制代碼就對應windows視窗,而vc對handle進行類封裝,間接操作的都是handle,現在控制代碼只是類的乙個成員變數。從控制代碼到指標 cwnd pwnd cwnd fromhandle hwnd a temporary cwnd objec...

MFC中指標和控制代碼的轉換

在mfc程式設計中,我感覺最讓人頭痛的就是資料的型別非常多,所以在對函式來進行呼叫時不得不進行資料型別的轉換,其中最認我感覺頭痛的是控制代碼和其指標的轉換。1。mfc視窗的控制代碼和指標的轉換 1 一般視窗物件都會有乙個其對應的控制代碼變數,所以我們可以 取此物件的m hwnd屬性來得到控制代碼。2...

MFC中的控制代碼

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