Windows中的控制代碼(handle)

來源:互聯網
上載者:User

1.控制代碼是什嗎?
   在windows中,控制代碼是和對象一一對應的32位不帶正負號的整數值。對象可以映射到唯一的控制代碼,控制代碼也可以映射到唯一的對象。
2.為什麼我們需要控制代碼?
   更準確地說,是windows需要控制代碼。windows需要向程式員提供必要地編程介面,在這些介面中,允許程式員訪問、建立和銷毀對象。但是,出於封裝地考慮,windows並不想向程式員返回指標。指標包含了太多的資訊。首先指標給出了Object Storage Service的確切位置;其次,要操作一個指標,程式員必須知道指標所指對象的內部結構特徵,也即,windows必須向程式員暴露相應的資料結構,而這些資料結構也許是作業系統想向程式員隱藏的。
   如果說COM技術向使用者隱藏了資料,只暴露了介面並只允許按介面定義的方法操
作資料的話,控制代碼這種方式則允許你按自己的方式直接操作資料,但windows又不向
你直接暴露資料。直接操作資料是程式員需要的,不暴露資料是windows所需要的,
控制代碼封裝方式實現了各取所需。
3.控制代碼如何與對象映射?
   封裝背後,必須有一個地方可以實現解碼,以實現控制代碼和對象的相互轉換。在
windows中,存在兩種映射方式:
   a. 全等映射。也即,控制代碼本身就是一個指標。映射在這裡只是類型轉換而已。
這種情況有,進程執行個體控制代碼或模組控制代碼,以及資源控制代碼等等。
   b. 基於表格的映射。這是對象指標與控制代碼之間最普通的映射機制。作業系統創
建表格,並儲存所有要考慮的對象。需要建立新對象時,要先在表格中找到空入口
,然後把表示對象的資料添入其中。當對象被刪除時,它的資料成員和其在表中的
入口被釋放。
4.控制代碼的定義和實現
   我們以GDI對象為例進行討論。建立了GDI對象,就會得到該對象的控制代碼。控制代碼
的對象可能是HBRUSH、HPEN、HFONT或HDC中的一種,這依賴於你建立 的GDI對象類
型。但是最普通的GDI物件類型是HGDIOBJ。HGDIOBJ被定義成null 指標。
   HPEN的實際編譯類型定義隨編譯時間宏STRICT的不同而不同。如果STRCIT已經
被定義了,HPEN是這樣的:
   struct HPEN__ {int unused};
   typedef struct HPEN__* HPEN;
   如果STRICT沒有定義,HPEN是這樣定義的:
   typedef void *HANDLE;
   typedef HANDLE HPEN;
   上面這段代碼是一個注重細節的程式員最接近控制代碼的地方,因此我們重點分析
一下。這裡有一點點技巧。如果定義了STRICT宏,HPEN是指向有單個未使用欄位的
結構的指標,否則HPEN是null 指標。C/C++編譯器允許把任何類型的指標作為空白指什傳
遞,反之則不可以。兩個不同類型的非null 指標是互不相容的。在STRICT版本中,編
譯對GDI物件控點的不正確混用將給出警告,對於非GDI控制代碼,如HWND、HMENU的不正
確混用也會給出警告,從而使程式在編譯器得到更STRICT的檢查。
   接下來的分析可能不那麼令你感興趣,但它更深刻地揭示了控制代碼。對GDI控制代碼來
說,儘管windows標頭檔把它定義成指標,但如果你仔細檢查這些控制代碼的值,它根本
就不像指標,這也是為什麼我說它只是一個32位無符整數值的原因。對控制代碼就是指
針的情況,這句話也仍然適用。讓我們隨意地產生一些控制代碼,比如你用GetStockOb
ject()以得到一些控制代碼,你會發現,它們的值總在區間0x01900011到0xba040389。
前者指向使用者區中的未分配的無效地區,後者指向核心地址空間。另外你可能發現
,兩個控制代碼之間的值可能只差數值1,這也說明GDI控制代碼不是指標。
   和多數人想象的不一樣,控制代碼也不是一個單純的索引值。對GDI物件控點來說,
GDI控制代碼由8位 、1位堆對象標記(表明對象是否建立在堆中)、7位物件類型資訊和
高4位為0的16位索引組成,
3 3 2 2 2 2 2 2  2  2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
1 0 9 8 7 6 5 4  3  2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|  8 位引用計數 |堆 |  物件類型7  |            16位索引           |
                標
                記

在這裡你可以看到,對GDI來說,它只使用了16位作為索引。這意味著一個進程最多隻
可以建立小於64K個控制代碼,實際上受其他一些限制,整個windwos系統中大概可以容納約
16384(0x4000)個GDI對象。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.