アクティベーションコンテキストのときのコードでは、SystemParametersInfo(SPI_GETNONCLIENTMETRICSでメッセージボックスの表示に使うフォントを取得していました。何のためと言えば、日本語Vistaでメイリオを使うためです(日本語XP以前ではMS UI Gothicが得られます、特に設定をいじっていなければ)。直接メイリオと指定するよりは、設定の値を読み取るほうがスマートです。XPでもメイリオを入れて設定している人もいれば、私みたいにそれ以外の人、日本語以外の人、いろんな人がいるというのが言い訳理由です。
それに関連して、今日は.NET Frameworkではどうやるという話です。
といっても、ずばりSystem.Drawing名前空間のSystemFonts.MessageBoxFontを読み取るだけです。これでFontインスタンスが得られます。これで話は終わってしまいました。
いえいえ、ここからが本題。さらにそこからLOGFONT構造体を取り出します。
それすらも簡単そうに思いました。何せ、ToLogFontメソッドを呼ぶだけです。ただし、引数がObjectなのが問題だったのです。.NET Frameworkの中でLogFont構造体でも用意すればよかったのにと思いますが、技術的に難しいのかもしれません。
ではどうするかというと、まず小さな改善とコンパイラの新機能、そして3.0への展望(連載:C# 2.0入門 最終回 - @IT)のように、自分で値型構造体を宣言するという手法もあります。しかし、C++/CLIなら<windows.h>のLOGFONTの宣言を使いまわしたい、というわけでやってみたのです。
結局、こうなりました。
#define WIN32_LEAN_AND_MEAN #define _WIN32_IE 0x0501 #include <windows.h> #include <shlwapi.h> #using <System.Drawing.dll> int main() { namespace dr = System::Drawing; dr::Font^ f = dr::SystemFonts::MessageBoxFont; if (IsOS(OS_WINDOWS)) //9xか否か { array<BYTE>^ a = gcnew array<BYTE>(sizeof (LOGFONTA)); f->ToLogFont(a); pin_ptr<LOGFONTA> plf = reinterpret_cast<interior_ptr<LOGFONTA> >(&a[0]); ::MessageBoxA(0, plf->lfFaceName, "", MB_OK); } else { array<BYTE>^ a = gcnew array<BYTE>(sizeof (LOGFONTW)); f->ToLogFont(a); pin_ptr<LOGFONTW> plf = reinterpret_cast<interior_ptr<LOGFONTW> >(&a[0]); ::MessageBoxW(0, plf->lfFaceName, L"", MB_OK); } return 0; } |
BYTEに違和感のある方は、unsigned charやSystem::Byteに読み変えるといいです。また、pin_ptr<logfontw> plf = reinterpret_cast<interior_ptr<LOGFONTW> >(&a[0]);は、C++/CLIに不慣れなら次のように読み変えるとよいかもしれません。
interior_ptr<LOGFONTW> iplf = reinterpret_cast<interior_ptr<LOGFONTW> >(&a[0]); pin_ptr<LOGFONTW> plf = iplf; |
マネージヒープにバイト配列を作って、それをToLogFontに渡し、それをLOGFONTにreinterpret_castしてpinしている、コードを読み上げるとそうなります。直接LOGFONT^ hlf = gcnew LOGFONT;とかけたらすごいのにと思いましたが、さすがに無理でした。
あと、9xだとLOGFONTAになるというのが盲点で、Windows 98で試しておいて正解でした。その判別に使ったIsOSはIE 5.01以上が必要です。ただし、.NET Framework [1.0/1.1/2.0]自体がIE 5.01以上を必要とするので、入っていないという心配は要りません。
それでも、判別処理は面倒のもとでしょうから、なるべくFontからLOGFONTへの変換は避けた方が楽だと思います。情報取得はFontのプロパティ、HFONTへはToHfontメソッドが使えます。もっとも、それで済むならこんなことするわけないですよね。
2011年9月11日:HTMLに一部誤りがあったので修正しました。
スポンサード リンク |