Win32編程API 基礎篇 -- 5.使用資源


使用資源

  你可能想參考教程結尾的附近,為了獲得跟VC++和BC++資源相關的信息。

  在我們講得更加深入之前,我將大致講解一下資源的主題,這樣在每個小節中我就不必再去重講一遍了。在這一小節中,你不需要編譯任何東西,這里的代碼只是個例子。

  資源是以二進制的格式存儲在你的可執行文件內部的預定義的數據,在資源腳本中我們創建資源,所謂的資源腳本就是有”.rc”擴展名的群文件,商業編譯器通常有一個視覺資源編輯器老讓你在不需要手動編輯的情況下創建資源,但很多時候手動這是唯一的創建資源的方法,如果你的編譯器沒有視覺編輯器的話,或者它很糟糕,不支持你所需要的具體功能。

  很不幸的是不同的編譯器套件處理資源的方式是不一樣的,我將竭盡所能來解釋一般情況下資源工作的共同特征。

  資源編輯器附帶MSVC++使它很難手動編輯資源,因為它執行一個專有格式,並且如果你手動創建了一個資源,整個文件都可能被完全損壞,所以一般情況下你不應該打擾資源文件的創建,但是明白如何手動修改它們有時又是很有用的。另一個比較蛋疼的就是MSVC++將默認資源頭文件的命名為“resuorce.h”即使你想使用其他命名。為了簡單起見我將以這個文檔中數據為基礎,但在附錄中會向您展示如何在編輯器中進行修改。

  首先,讓我們看一段非常簡單的資源腳本,一個圖標。

 

1 #include "resource.h"
2 
3 IDI_MYICON ICON "my_icon.ico"

 

  這是整個的文件,IDI_MYICON是資源標識符,ICON是類型,“my_icon.ico”包含資源文件的擴展名,在所有的編譯器中都應該生效。

  #include "resource.h"跟什么相關呢?嗯,你的程序需要一種定義圖標的方式,最好的方式就是分配一個唯一的ID(IDI_MYICON),我們可以通過創建一個“resource.h”文件然后在我們的資源腳本文件和源代碼文件中引入。

 

1 #define IDI_MYICON  101

 

  正如你所看到的,我們指定了IDI_MYICON的值為101,我們可以不使用定義直接使用101當引入圖標的時候,但是IDI_MYICON引入的寫法更加清爽,並且在大量引入資源文件的時候更容易記住。

  現在讓我們添加一個菜單資源:

 

 1 #include "resource.h"
 2 
 3 IDI_MYICON ICON "my_icon.ico"
 4 
 5 IDR_MYMENU MENU  6 BEGIN  7     POPUP "&File"
 8  BEGIN  9         MENUITEM "E&xit", ID_FILE_EXIT 10  END 11 END

 

  同樣的IDR_MYMENU是資源的名稱而MENU是資源類型。現在好點,看到了開始和結束了么?一些資源編輯器或編譯器使用“{”和“}”分別用來替代BEGIN和END,如果你的編譯器兩個都支持隨意選擇其中一種方式。如果它只支持其中一種或者其他方式,你需要進行必要的更換工作保證正常使用。

  我們也添加了一個新的標識符ID_FILE_EXIT,所以為了在我們的程序中使用,我們需要把它添加在我們的資源頭文件resource.h中。

 

1 #define IDI_MYICON  101
2 #define ID_FILE_EXIT    4001

 

  在大型的項目中生成和跟蹤這些ID是一件很蛋疼的事,這就是大多數人使用為你完成這些工作的視覺資源編輯器的原因。但它仍然會時不時弄糟,你可能最終會遇到多個項目相同ID或類似的問題,這時候手動調整有利於解決問題。

   現在下面有一個如何在你的程序中使用資源的栗子:

 

1 HICON hMyIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));

 

  LoadIcon和許多資源使用函數的第一個參數就是當前窗口實例的句柄(這個在我們的WinMain()中被給出了,同時也可以使用我們前面提到的GetModuleHandle()來得到這個句柄)第二個參數就是資源的標識符。

  你可能會想MAKEINTRESOURCE()是用來干嘛的,也可能會想當我們要傳遞給LoadIcon()資源ID參數時,為什么會取一個LPCTSTR類型的參數而不是用UINT。所有的MAKEINTRESOURCE()做的事情就是把一個整型的ID變成LPCTSTR類型,而這是LoadIcon想要的參數類型。這就引出了定義資源的第二種方式,就是直接使用字符串,幾乎不會有人再這樣做,所以在這里我們簡略說說,但是基本上如果你沒有用#define的方式為你的資源指定ID,那么這個資源名就會被解析成字符串,在你的程序中可以這樣子引用:

 

1 HICON hMyIcon = LoadIcon(hInstance, "MYICON");

 

  LoadIcon()和其他加載資源的API可以區分傳遞的是一個資源ID還是一個指向字符串的指針通過檢查這個值的高16位,如果高16位是0(整數的范圍是0到65535)將被認定為傳入的是一個資源ID,這很有效如果你限定你的資源ID在65535以下,這個應該夠用了除非你有超多資源,所以應該沒有問題;如果高16位不是0那么就會被認定為是一個指向字符串的指針,加載資源的函數就會通過資源名去查找資源。永遠不要依賴於API去實現這個除非它在文檔中被明確規定。

  例如,這並不適合像ID_FILE_EXIT菜單命令,因為他們只能是整數。

    PS.由於本人英文水平所限,只能翻譯到這個程度了,有紕漏還望多多指出,附上本篇翻譯的英文原版教程地址:http://www.winprog.org/tutorial/resources.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM