作者purpose (purpose)
看板C_and_CPP
標題Re: [問題] visual c++ win32 sdk語法載入圖片
時間Fri Nov 19 01:12:43 2010
※ 引述《steven70101 (老人)》之銘言:
: 遇到的問題: (題意請描述清楚)
: 想請問一下,目前是visual c++新手
: 接到case說要用win32的sdk來寫程式
: (其實不如說沒什麼視窗程式設計的經驗,win32這種傳統純語言比較容易上手)
: 只是查了theForger's Win32 API跟天藍工作室
: (學習win32 API的好網站0.0b),裡面所提的bitmap點陣圖載入卻一直執行不能
: 像天藍工作室所提的在resources script中(應該是指Resources.h檔案吧)寫入
: #define IDB_BITMAP1 1
: IDB_BITMAP1 BITMAP "some_path/some_bitmap_file.bmp"
: 結果執行都會一直失敗,不管是放在 主程式.cpp或是Resources.h
: 都會顯示
: error C2059: 語法錯誤 : '常數'
: 而theForger's Win32 API中「位图,设备上下文」部分
: HBITMAP g_hbmBall = NULL;
: case WM_CREATE:
: g_hbmBall = LoadBitmap(GetModuleHandle(NULL),
: MAKEINTRESOURCE(IDB_BALL));
: if(g_hbmBall == NULL)
: MessageBox(hwnd, "Could not load IDB_BALL!", "Error", MB_OK |
: MB_ICONEXCLAMATION);
: break;
: 則是卡在不懂IDB_BALL的含意
: 希望得到的正確結果:
: 希望有大大能提供一下可以正確讀取點陣圖檔的程式碼資料
: 程式跑出來的錯誤結果:
: error C2059: 語法錯誤 : '常數'
: 開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux)
: Visual C++ 2005
: 有問題的code: (請善用置底文標色功能)
: #define IDB_BITMAP1 1
: IDB_BITMAP1 BITMAP "some_path/some_bitmap_file.bmp"
: 補充說明:
: 有大大推薦哪本學習 Win32 Api 的參考用書嗎
: 書局找到的都是用表單再回去寫程式的
: 都沒找到以api為主教學的書
貼的東西不完整,錯誤訊息哪一行我不太清楚。
直接講原理
PE-COFF 格式的檔案 (*.exe, *.dll..),裡面有四大表,匯入、匯出、重定位、資源。
資源表裡面就是存放這些 Resource。
那他每個資源都有三個值:資源類型、資源的 LCID、資源名稱
直接看 RC 檔的記載,裡面
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
這代表記載的資源是屬於繁體中文,換言之,在資源表中記載 LCID = 1028。
你可以在 my.exe 中,建兩個資源類型都叫字串表,表格內各有一個字串名稱叫
country。於是繁體中文版的 country 字串資源,值為「中華民國」:英文版的
country 字串資源,值為「United States」。則在美國人電腦打開,就會載入
「United States」,在台灣人電腦打開,就會載入「中華民國」。
使用 VC 時,就是建兩個 RC 檔,分別設不同 Language,則執行檔就會有兩個
語言版本的資源。
資源類型跟資源名稱,就是在 RC 檔中的這種記錄
my BITMAP "D:\\Desktop\\aaa.bmp"
其中 BITMAP 代表設定此資源的類型為點陣圖。後面當然是檔案在硬碟的位置。
而 my 很顯然就是「資源名稱」,這東西比較麻煩。
如果是純數字當資源名稱,那你載入資源時,就是這樣寫
LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_BITMAP1));
裡面 IDB_BITMAP1 其實是巨集,會被取代成純數字,因為這個數字有一定編排
格式,所以先用 MAKEINTRESOURCE() 去處理一下,但處理完還是純數字。
那麼在 RC 檔就會這樣寫
IDB_BITMAP1 BITMAP "bitmap1.bmp"
而且最上方會有個標頭檔,通常名稱叫 Resource.h
這個標頭檔裡面會有個 #define IDB_BITMAP1 123,把他修正成純數字。
如果不是純數字,像上面的 my,那要載入資源就很簡單
LoadBitmap(GetModuleHandle(0), "TEXT("my"));
就直接傳字串當參數2就好,當然為了適應 UNICODE/MBCS,所以用 TEXT() 巨集
詳情可以 google。
在 VC 一般沒有注意,會以為資源名稱一定要搞個純數字,其實只要在屬性視窗
打名稱時,打 "my",別打 my,就可以用字串當資源名稱了。要改對應數字
則在 VC 屬性視窗打 IDB_BITMAP1=5566 按下 Enter,
VC 就會去更新 Resource.h 內記載的 IDB_BITMAP1 對應值。
那 PE-COFF 檔案的資源表內,會在取「資源名稱」的值時,檢查其最高位元
是否為 0,如果是0則資源名稱為純數字且長度只有2 bytes;
如果是1則是記載一個指標位址 wchar_t *name;
也就是說,純數字的資源名稱,最大只到 0x7FFF = 32767;
(
http://support.microsoft.com/kb/137248 )
字串版的資源名稱,長度隨便,而且是 Unicode 格式,可以打各國語言。
==================================
以下為修文。關於資源檔,補充更完整的建立資訊,順便改標題,及回答原PO問題:
==================================
用來建立 Windows rc 檔 (resource script) 的工具有:
(1) VC
(2) ResEdit (免費,推薦使用)
(3) ResEd (免費、RadASM 這套 IDE 就是用此)
而從 *.rc 檔去編譯 (rc compile) 出資源檔的工具有:
(1) VC 的 rc.exe (餵給 VC 的 link.exe 去連結出 PE-COFF 格式檔案)
(2) mingw 包含的 windres.exe (餵給 gcc 去連結出 PE-COFF 格式的檔案)
用 ResEdit 建資源很簡單,如果沒有 VC 推薦用這套,不要自己用手寫。
如果要用 rc.exe 建資源,用 ResEdit 建好 haha.rc 及 resource.h 後,接著執行如下
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
D:\Desktop>rc haha.rc
D:\Desktop>cl /c goo.c
D:\Desktop>link goo.obj haha.RES
D:\Desktop>goo
Hello World
然後可以用 Restorator 或 Resource Hacker 這類工具,檢驗 *.exe 及 *.res 是否
正確包含資源。參考資料:
http://www.mingw.org/wiki/MS_resource_compiler
如果要用 mingw 建資源,用 ResEdit 建好 haha.rc 跟 resource.h,接著執行如下
D:\Desktop>windres haha.rc haha.res
D:\Desktop>gcc goo.c haha.res
haha.res: file not recognized: File format not recognized
collect2: ld returned 1 exit status
D:\Desktop>windres haha.rc haha.res.o
D:\Desktop>gcc goo.c haha.res.o
這樣就可以了。
==================================
: #define IDB_BITMAP1 1
: IDB_BITMAP1 BITMAP "some_path/some_bitmap_file.bmp"
: error C2059: 語法錯誤 : '常數'
我寫了個 rc 檔叫 haha.rc 內容如下:
#include <windows.h>
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#define IDB_BITMAP1 1
IDB_BITMAP1 BITMAP "some_path/some_bitmap_file.bmp"
然後用 VC 命令提示字元,下指令 rc haha.rc 可以成功建立資源。
你試試看吧,建議不要自己寫 rc 檔,去用我上面說的那些圖形介面的工具。
: 有大大推薦哪本學習 Win32 Api 的參考用書嗎
: 書局找到的都是用表單再回去寫程式的
: 都沒找到以api為主教學的書
Programming Windows, 5th Edition, by Charles Petzold
英文版,中文版網路上隨便都找捯到,不然花錢買。
MSDN 或 google 也可以查到很多資訊。
書的話去書局挑,(1) 還在架上買得到 (2) 你看得懂覺得不錯的
我建議一本:貓也會的Windows程式設計-使用Visual C+
或者此書的最新中文版,改名叫「最新Windows程式設計實例入門-Visual C ++實作 增訂
第三版」
http://findbook.tw/book/9789862011805/price
推薦資料:
小木偶 Win32 的組合語言 Ch 06 加上選單
http://home.educities.edu.tw/wanker742126/win32asm/w32asm_ch06.html
--
02/18 補充例子於下
上文提到,資源有三個值:(1) 資源類型 (2) 資源的 LCID (3) 資源名稱
在 VC 用 MFC 精靈建立的 SDI 程式中,會有好幾個資源名稱都叫做 IDR_MAINFRAME
(實際是 128)。包含應用程式的圖示,應用程式的主選單,應用程式的加速鍵,
以及字串表 (String Table) 內的一筆字串。
在 theApp.InitInstance() 內,都會動態建立一個 CSingleDocTemplate 物件,如下
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMyProjDoc),
RUNTIME_CLASS(CMainFrame), // 主 SDI 框架視窗
RUNTIME_CLASS(CMyProjView));
透過把這些資源的名稱一律定為 IDR_MAINFRAME,使應用程式框架視窗生成時,
CFrameWnd::LoadFrame() 能夠載入這幾個資源。
雖然資源名稱相同,但這些資源彼此的「資源類型」不同,所以不會有衝突;
而前述的 country 例子,則是在「資源 LCID」上的不同。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 124.8.133.145
推 steven70101:抱歉沒寫清楚,前面文章已補充(努力吸收這段中) 11/19 01:16
推 VictorTom:推~~~~ 11/19 02:06
推 xatier:推 11/19 07:23
※ 編輯: purpose 來自: 124.8.130.242 (11/19 11:42)
※ 編輯: purpose 來自: 124.8.130.242 (11/19 12:08)
推 elfkiller:Push 11/20 00:40
推 Gaak:路過推~~ 11/21 23:22
※ 編輯: purpose 來自: 124.8.134.221 (02/18 03:09)
※ 編輯: purpose 來自: 124.8.134.221 (02/18 03:13)