有意見請不吝指教;有誤請不吝幹譙。

 

ˇ VC2008 / VC2010  IDE 操作,為 console 加入 icon

ˇ VC / gcc 範例

ˇ VC2008 / VC2010 建立較具通用之作法 - 新增連結參數

ˇ 動態載入 icon 方式

ˇ The better ?

VC IDE 操作

 

不是只有 Win32 程式才可以加 icon,一般的 console 也可這麼做,關鍵還是回到 resource compiler 產生 res。

避開命令列方式產生,現行 IDE 也予以不錯之支援,敘述以 vs2010 為例,方法使用靜態載入

1. 在方案總管之「資源檔」按右鍵 -> 加入 -> 資源

2. 選擇 Icon -> 匯入,並選擇執行檔要生成的 icon

3. 「檔案」-> 全部儲存,有對話框出來的話全按是 (或確定)

4. 沒意外的話會產生一 resource.h 及 ProjectName.rc,另會有一額外之 macro - IDI_ICON1。

5. 程式碼引入 windows.h 及 resource.h ,在程式碼一開始時輸入以下指令


 HICON   hIcon=LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_ICON1));
 HWND     hwnd=GetConsoleWindow();    
 SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)hIcon);

6. 直接編譯執行,大功告成。

 

VC / gcc 範例

 

hello.c

// hello.c
#include <stdio.h>

#include <windows.h>
#define IDI_MYICON 101 int main() {

 HICON   hIcon=LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_ICON1));
 HWND     hwnd=GetConsoleWindow();    
 SendMessage(hwnd,WM_SETICON,ICON_BIG,(LPARAM)hIcon);
    printf("Hello, World!!\n");
    getchar();
    return 0;
}

 

hello.rc

 /* filename : x.rc */
IDI_MYICON ICON "EdisonX.ico"

hello_vc.bat

REM compiler : CL.exe ( visual c++ )
rc.exe hello.rc
CL.exe hello.c hello.res user32.lib /Fe"hello_vc.exe"

hello_gcc.bat

 

gcc.exe -c hello.c &REM generate hello.o
windres.exe hello.rc hello_rc.o &REM generate hello_rc.o
gcc.exe hello.o hello_rc.o -o hello_gcc.exe &REM generate hello_gcc.exe

 

較具通用作法

 

對於 vc ide 慣用者,若每次都搞上面的六個步驟麻煩,可先將上面的 hello.rc ,編譯成 hello.res 出來,

再於 ide 中之 「專案」->「屬性」-> 「組態屬性」-> 「連結器」-> 命令列中,輸入 hello.res 即可。

注意的是,在 compiler / ide 中若有連結到 .res ,最後生成出來的執行檔本身就是 icon 圖示;

而程式在執行時會不會是 icon 圖示,取決於程式碼裡有沒有用到 LoadIcon、SendMessage(..WM_SETICON..),

產生之處不同,不該混為一談。

 

最後我的方法有點偷懶,生成一份 hello.res 後,會再把程式內的 LoadIcon、SendMessage 寫好,

直接複製 hello.res,貼到所需程式碼裡面。

動態載入 icon 方式

 

上述之方式為靜態載入,當 compiler 完成之後 icon 是跟著程式跑的,

若有需求要換 icon 的話可在 resource 多加上幾個 icon ,觸發時再做 LoadIcon、SendMessage,

所以可以一次把很多 icon 都加到 res 裡面去,下次要 LoadIcon 時就多了很多選擇,缺點是程式碼會變大。

 

動態載入 icon 方式用不到 resource compiler,即不會用到 .rc 檔案,一份原始碼參考如下

#include <stdio.h>
#include <windows.h>
int main()
{
    // using loadimage api and sendmessage
    const char* icon_name = "EdisonX.ico";
    HWND hwnd = GetConsoleWindow();
    HICON hIcon = LoadImage(NULL, icon_name, IMAGE_ICON, 32, 32, LR_LOADFROMFILE);    
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
    printf("Hello, World!!");
    getchar();
    return 0;
}

 

使用動態載入會有一麻煩之處,所使用之 icon 必須跟著程式跑。以上述例子而言,EdisonX.ico 就必須與執行檔放在同一目錄底下,在執行時才可正常顯示 icon。但平時靜止時,該執行檔之圖示與一般 console 程式之圖示沒兩樣。

 

The better ?

目前筆者想不到有什麼方法是真的可應付所有情況,

目前想法應是可包一個 function 出來,類似 bool SetIcon(const char* filename);

當呼叫此 function 時,可在連結期便把所需之 icon 塞到 res, 編成 .rc,一起連結進去,

但估這動作已需再寫一程式自動生成 res 與自動編成 rc,雖不甚難,但直覺實用上仍有待考驗。

 

 

arrow
arrow
    全站熱搜

    edisonx 發表在 痞客邦 留言(0) 人氣()