VC中使用自定义资源
前言
在VC環境中除了我們所常用的Dialog、Menu和Bitmap等標準資源類型之外,它還支持自定義資源類型(Custom Resource),我們自定義資源類型能做些什么呢?呵呵,用處多多。
1.??????默認的皮膚壓縮包或語言包。一些支持換膚的軟件特別是一些媒體播放器常常有自定義的皮膚文件(你可以嘗試將Media Player或千千靜聽等軟件的Skins目錄下的文件的擴展名改為.zip,然后使用WinZip打開看一下),但為了防止Skin文件丟失導致軟件無 法顯示,他們常常會在EXE文件中內置一套Skin作為默認的皮膚文件。同樣,一些支持多語言的EXE文件中存在默認語言包也是這個道理(當然也可以使用 "String Table"資源類型);
2.??????做為一些病毒/木馬程序的寄生方式。如果不小心執行了帶有病毒/木馬的程序,它們會在你運行時釋放出病毒/木馬文件。當然許多病毒是將自身寫入PE文件頭來實現;
3.??????合并EXE與它所需要的DLL文件。出于某些原因程序作者有時可能需要將DLL文件嵌入到可執行的EXE文件中,這可以通過使用自定義資源來實現;
4.??????其它需要在程序中播放一個AVI動畫等等,都可以通過將二進制的數據文件作為自定義資源加入到可執行文件中來實現;
添加資源
添加資源時選擇自定義,IDE會為你生成一個新的二進制資源,然后你就可以將你已經存在的二進制文件作為自定義的資源類型導入到項目中來了。使用資源
要使用自定義資源,我們可能要用到的幾個API函數有FindResource、LoadResource和LockResource等,這里每一個函數的返回值分別作為下一個函數的參數,我來簡要介紹一下。FindResource用來在一個指定的模塊中定位所指定的資源: HRSRC FindResource (HMODULE hModule, //包含所需資源的模塊句柄,如果是程序本身,可以置為NULLLPCTSTR lpName, //可以是資源名稱或資源IDLPCTSTR lpType //資源類型,在這里也就是我們自己指定的資源類型 ); LoadResource用來將所指定的資源加載到內存當中; HGLOBAL LoadResource (HMODULE hModule, //模塊句柄,同上HRSRC hResInfo //需要加載的資源句柄,這里也就是FindResource的返回值 );LockResource用來鎖定內存中的資源數據塊,它的返回值也就是我們要使用的直系指向資源數據的內存指針; LPVOID LockResource (HGLOBAL hResData //指向內存中要鎖定的資源數據塊,這里也就是LoadResource的返回值 );
另外我們還需要用SizeofResource來確定資源的尺寸,我們在操作資源時要用到它。
函數原型:DWORD SizeofResource(HMODULE hModule,HRSRC hReslnfo); 參數: hModule:包合資源的可執行文件模塊的句柄,如果是程序本身,可以置為NULL hReslnfo:資源句柄。此句柄必須由函數FindResource或FindResourceEx來創建。 返回值:如果函數運行成功,返回值資源的字節數。如果函數運行失敗,返回值為零。若想獲得更多的錯誤信息,請調用GetLastError函數。
?在FindResource函數中經常用到宏MAKEINTERSOURCE來獲得資源名稱參數(LPCTSTR lpName),因為該參數需要LPCTSTR類型參數。MAKEINTERSOURCE是一個資源名轉換的宏,這個宏是把一個數字類型轉換成字符指針類型的宏,它不存在釋放的問題。
它僅僅是把一個"數字形ID",轉化為"字符串".但是執行前后,輸入的數據的內容和長度是不變的!它只不過就是C語言里面"強制類型轉換"而已.
用這個宏的主要原因是有的資源是用序號定義的,而不是字符串.所以要把數字轉換成字符串指針,然后再傳遞給LoadResource之類的函數,這樣才加載了資源.
(要釋放資源(用LoadResource加載的)可以調用FreeResource函數把LoadResource返回的指針傳遞給FreeResource.)
在資源使用完畢后我們不需要使用 UnlockResource和FreeResource來手動地釋放資源,因為它們都是16位Windows遺留下來的,在Win32中,在使用完畢后系統會自動回收。它們的使用很簡單,大致上是這個樣子的:
BOOL UseCustomResource() {//定位我們的自定義資源,這里因為我們是從本模塊定位資源,所以將句柄簡單地置為NULL即可HRSRC hRsrc = Findresource(null, MAKEINTRESOURCE(ITEMID), TEXT("MyType"));if (NULL == hRsrc)return FALSE;//獲取資源的大小DWORD dwSize = SizeofResource(NULL, hRsrc);if (0 == dwSize)return FALSE;//加載資源HGLOBAL hGlobal = LoadResource(NULL, hRsrc);if (NULL == hGlobal)return FALSE;//鎖定資源LPVOID pBuffer = LockResource(hGlobal);if (NULL == pBuffer)return FALSE;//我們用剛才得到的pBuffer和dwSize來做一些需要的事情。可以直接在內存中使//用,也可以寫入到硬盤文件。這里我們簡單的寫入到硬盤文件,如果我們的自定//義資源是作為嵌入DLL來應用,情況可能要復雜一些。BOOL bRt = FALSE;FILE* fp = _tfopen(_T("demo.exe"), _T("wb"));if (fp != NULL){if (dwSize == fwrite(pBuffer, sizeof(char), dwSize, fp))bRt = TRUE;fclose(fp);} //FreeResource(hGlobal);return bRt;
使用實例
功能:尋找軟件中的資源(type:HELP_FILE, ?Id:IDR_HELP_FILE1),并在本地臨時文件夾temp中生成對應資源的文件(涉及查找資源中文件、加載資源到內存、得到資源大小、將資源內存寫入文件),并打開文件
</pre><p><pre name="code" class="cpp">CString szPath, szDir; TCHAR buf[MAX_PATH]; szPath.Empty(); szDir.Empty();GetTempPath(MAX_PATH, buf); szDir = buf; szPath = szDir + _T("Help.pdf");if (GFun::ReleaseRes(szPath, (WORD)IDR_HELP_FILE1, _T("HELP_FILE")) == TRUE) {ShellExecute(NULL, _T("OPEN"), szPath, NULL, szDir, SW_SHOWNORMAL); }bool ReleaseRes(CString strFileName, WORD wResID, CString strFileType) {// 資源大小 DWORD dwWrite = 0;// 創建文件 HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE){return false;}// 查找資源文件中、加載資源到內存、得到資源大小 HRSRC hrsc = FindResource(NULL, MAKEINTRESOURCE(wResID), strFileType);HGLOBAL hG = LoadResource(NULL, hrsc);DWORD dwSize = SizeofResource(NULL, hrsc);// 寫入文件 WriteFile(hFile, hG, dwSize, &dwWrite, NULL);CloseHandle(hFile);return true; }
1、GetTempPath的功能是獲取系統當前用戶的臨時文件夾路徑,如:C:\Users\XXX\AppData\Local\Temp
2、ShellExecute的功能是運行一個外部程序(或者是打開一個已注冊的文件、打開一個目錄、打印一個文件等等),并對外部程序有一定的控制。
總結
以上是生活随笔為你收集整理的VC中使用自定义资源的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021年计算机一级b,2021年全国计
- 下一篇: 用MATLAB对平行板电容器与加盖导体槽