2014年09月04日

FLTK

必要最低限の機能を押さえていて、インストール&ビルドが楽、ということで最近 FLTK 1.3 をテストしています。
ボタンやツリービュー、メニュー、タブなど一通りのコントロールがそろっていて、なによりも無改造で日本語に対応している点がよいですね!
フォントを変更する必要すらありません。FLTK は文字列を utf-8 で扱っているので(wchar_t ではなく、マルチバイト文字列であることに注意)、それさえ気を付ければ簡単に日本語を表示する事ができます。

まず普通にアルファベットを表示したりするときは

Fl_Window *wnd = new Fl_Window(0, 0, 320, 240, “HELLO”);

のようにします。日本語で表示させたい時はまず UTF8 に変換する必要がありますから、

std::string utf8(const std::string &s);

とかいう適当な変換関数を用意して、

Fl_Window *wnd = new Fl_Window(0, 0, 320, 240, utf8(“ウィンドウ”).c_str());

のようにすればいいです…といいたいところですが、これはうまく行きません。
Fl_Window をはじめとして FLTK のコントロールはコンストラクタで渡された文字列ポインタをそのまま保持しているみたいです。
そのため文字列の実体がずっと存在することが前提となっているんですね。
ところが上記のような指定方法だと、文字列の実体は初期化式を抜けた時に破棄されてしまい、ウィンドウのタイトルとして不正な文字列が使われてしまいます。

これを回避するには、単純に static な文字列を指定するか、あるいは文字列引数を省略して(コンストラクタでの文字列指定はオプション引数になっている)
とりあえず生成してしまい、あとから copy_label でタイトルを指定する必要があります。

Fl_Window *wnd = new Fl_Window(0, 0, 320, 240);
wnd->copy_label(utf8(“ウィンドウ”).c_str());


コンストラクタ以外でタイトルを指定するには label() と copy_label() があるのですが、
label() だとコンストラクタで指定するのと同じで文字列のポインタがそのまま保持されるだけになってしまい、ダメです。
copy_label() ならその名の通り文字列のコピーを保持するようになるため、安心して扱う事が出来ます

ちなみに 文字コード変換の関数はこんな感じで作れます

static std::wstring ToWide(int codepage, const std::string &s) {
if (s.empty()) return std::wstring();
int len = MultiByteToWideChar(codepage, 0, &s[0], -1, NULL, 0);
len--; // 終端の\0は不要
if (len <= 0) return std::wstring();
std::wstring ws(len, L'\0');
MultiByteToWideChar(codepage, 0, &s[0], -1, &ws[0], ws.length());
return ws;
}

static std::string ToMBSC(int codepage, const std::wstring &ws) {
if (ws.empty()) return std::string();
int len = WideCharToMultiByte(codepage, 0, &ws[0], -1, NULL, 0, NULL, NULL);
len--; // 終端の\0は不要
if (len <= 0) return std::string();
std::string s(len, '\0');
WideCharToMultiByte(codepage, 0, &ws[0], -1, &s[0], s.length(), NULL, NULL);
return s;
}

std::string utf8(const std::string &s) {
const int SJIS = 932;
std::wstring ws = ToWide(SJIS, s)
return ToMBSC(CP_UTF8, ws);
}

FLTK 2.0 もためしてみようかな


posted by JUNOSOFT at 06:38| Comment(0) | プログラミング
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。