深入解析MFC 控制代碼與物件的關係

2021-05-24 05:44:35 字數 1549 閱讀 5561

在windows體系中,很多物件都是以控制代碼的形式展示給開發人員的。比如視窗控制代碼(hwnd),繪圖裝置(hdc)等等。然後大部分的api函式則圍繞這些控制代碼做文章。比如showwindow,setwindowtext,textout等等。這些api函式的第乙個引數通常就是控制代碼了。但是在c++體系中,這種對於事物細節的訪問,往往是有違其封裝精神的。因此mfc做了很多的封裝類,來隱藏這些細節。應運而生就是cwnd,cdc等類。通過這些類暴露的方法,可以直接對控制代碼做操作,而又可以不去關心他。

不過,我們今天的主題不在這裡。以下才是真正的內容。

按照c++的理論,被封裝的控制代碼的建立和銷毀都應該由類本身來完成,外界不了解其中細節。但是在mfc中,真是這樣嗎?至少cwnd不是這樣,hwnd並不完全在cwnd的掌控之中。在前一章我提到過,mfc中有大量的全域性變數,其中乙個全域性變數是一張hwnd與cwnd的map表。這個map表的位置不好找,上章提到過全域性物件afx_module_state,他其中有乙個成員的型別是afx_module_thread_state,在afx_module_thread_state的內部,則有著一群map表,m_pmaphwnd正是其中乙個:

chandlemap m_pmaphwnd;

chandlemap* m_pmaphmenu;

chandlemap* m_pmaphdc;

chandlemap* m_pmaphgdiobj;

chandlemap* m_pmaphimagelist;

看到了嗎?找起來是比較麻煩,不過mfc提供了全域性函式afxmaphwnd,無論在哪個地方,呼叫這個函式都能輕鬆的獲得這個map表。

那麼,這個表到底有什麼作用呢?其實非常簡單,雖然在mfc中,都是物件在與物件打交道。但是mfc也要與windows系統打交道。windows給你的只有控制代碼,那麼如何通過這些控制代碼找到相對應的類呢?通過map表就能輕鬆的解決這個問題。

比如在windows的訊息機制中,當wndproc接收到乙個訊息的時候,只會得到乙個hwnd hwnd的目標視窗,如何找到匹配的類?從m_pmaphwnd中搜尋就行了。通過呼叫cwnd的靜態成員函式fromhandlepermanent,我們就能輕鬆的從map表中找到與hwnd相對應的cwnd類。

fromhandlepermanent的實現也非常簡單。首先通過afxmaphwnd找到m_pmaphwnd,然後通過m_pmaphwnd的成員函式lookuppermanent查詢與hwnd對應的cwnd指標,最後返回他。

m_pmaphwnd是什麼時候被建立的呢?在第乙個視窗被建立出來的時候,會呼叫cwnd的attach函式,下面是具體的函式實現:

bool cwnd::attach(hwnd hwndnew)

注意呼叫afxmaphwnd的傳入的引數為true,這表示當map不存在時,則建立他。再讓我們看看afxmaphwnd的實現:

chandlemap* pascal afxmaphwnd(bool bcreate)

return pstate->m_pmaphwnd; }

afxmaphwnd首先從我們前面說的地方找到這個指標,如果指標為空,並且bcreate為true,則建立乙個新的chandlemap。非常簡單,不是嗎?

Windows物件 控制代碼與MFC物件

windows物件是以控制代碼來標識的,對應的mfc類就是這些控制代碼的c 包裝。記憶體中的windows物件一定有唯一的控制代碼來標識,但不一定有對應的mfc類物件在記憶體中。當需要獲取windows物件的對應mfc類物件而記憶體中又沒有此物件時,系統會建立乙個臨時mfc類物件返回給使用者,並在之...

Windows物件 控制代碼與MFC物件

windows物件是以 控制代碼來標識的,對應的mfc類就是這些控制代碼的c 包裝 記憶體中的windows物件一定有唯一的控制代碼來標識,但 不一定有對應的mfc類物件在記憶體中 當需要獲取windows物件的對應mfc類物件而記憶體中又沒有此物件時,系統會建立乙個 臨時mfc類物件 返回給使用者...

核心物件與控制代碼的關係

一 乙個物件是不是核心物件,通常可以看建立此物件api的引數中是否需要 psecurity attributes 型別的引數。三 每個程序中有乙個控制代碼表 handle table 這個控制代碼表僅供核心物件使用,如下圖 四 解開此中的秘密 比如呼叫建立乙個執行緒的api handle hthre...