openFramewroks 0.9.8+Win10でアイコン変更


たまにあるアプリ納品の時に「コンソールは出てきちゃうんですかね?」とか「消えない?」
って聞かれてコンソール消すと、せっかく作ったアイコンもなくなっちゃってがっかりするのでその回避方法。

https://forum.openframeworks.cc/t/switching-from-console-application-to-gui-application-loses-custom-icon/15279/5
内容的には上のリンクとほぼ同じだけどresource.hとかではまったのでメモ。
環境は
OpenFramewroks0.9.8 + VisualStudio2015 + windows10

下準備

1. resource.hを用意

しばらくresource.hとは何者かわからなくて躓いたし、これで正しいのかもよくわからない。
検索してみるとみんな思い思いのresource.hを作ってるっぽいのでこれで良いことにする。
最後の行は改行入れとけってだれかが書いてたので改行入ってる。

#define IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16) == 0)
#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))
#ifdef UNICODE
#define MAKEINTRESOURCE  MAKEINTRESOURCEW
#else
#define MAKEINTRESOURCE  MAKEINTRESOURCEA
#endif // !UNICODE

#define MAIN_ICON 102

2. アイコンの設定

icon.rcの#define MAIN_ICONを#include "resource.h"に変更
xxxxには自分で用意したアイコン名を入れる

xxxx.icoは、GIMPで512*512~16*16くらいのサイズのアイコン画像を
レイヤー分けして、icoファイルとして書出しで作れる。AIすごくてもアイコン一つ作ってくれないフォトショよりGIMP最強。

// Icon Resource Definition
#include "resource.h"

#if defined(_DEBUG)
MAIN_ICON               ICON                    "icon_debug.ico"
#else
MAIN_ICON               ICON                    "xxxx.ico"
#endif

ビルド

1.resource.hをicon.rcと同じ階層に配置

OFプロジェクトファイルとかを書き換えられればsrcフォルダとかでもよかったんだけど、普通にsrcフォルダに突っ込むと、icon.rcがreource.hを見つけてくれなくなる。

2.VS2015のプロパティを変更

下の図のLinkerオプションのSubSystem を Concole -> Window に変更。これでコンソールが消える。
ofログのファイルofLogToFile()とかで外部に書き出す設定とかに変えないとログは見られなくなる。coutは使えないので注意。
SubSystemを変えないとMSVCRT.libがないとかリンカーエラーが出てビルドエラーになっちゃう。

3. main.cppを書き変える

いつものメインの代わりにWINAPIを使う。
GLのバージョンとかはofで使えれば他の書き方でも問題ないっぽい。

#include "ofMain.h"
#include "ofApp.h"
#include "../resource.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{

    ofGLFWWindowSettings settings;
    settings.setGLVersion(4, 2);
    settings.width = 1920;
    settings.height = 1080;
    settings.decorated = true;
    ofCreateWindow(settings);

    HWND hwnd = ofGetWin32Window();
    HICON hMyIcon = LoadIconW(hInstance, MAKEINTRESOURCE(MAIN_ICON));
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hMyIcon);

    ofRunApp(new ofApp());
}

4. F5をターンッ!と打つ。

コンソールが出てこなくてもアイコンついてる!やった!

書いてみたら一瞬で終わるのにずいぶんと時間がかかった気がするのはなぜか。。
我ながら地味で目立たないところにこだわってますね。