GDI+の初期化と終了
使う前には初期化、使い終わったら最後に終了処理を行います。
行わなかった場合はどうなるのでしょうか・・・。きっとgdiplus.dllが困るのでしょう。
初期化と終了の関数のプロトタイプです。
Status GdiplusStartup( ULONG_PTR token *token, const GdiplusStartupInput *input, GdiplusStartupOutput *output); void GdiplusShutdown( ULONG_PTR token);
GdiplusStartup関数で設定を渡して、トークンを受け取り、終了時にはそのトークンを渡す事になっているらしいです。
各パラメータについて説明。
- tokenは終了時にだけ必要なデータを受け取る変数のポインタ
- inputはGDI+に対する設定の構造体へのポインタ
- inputの型GdiplusStartupInputは構造体だけど、デフォルトコンストラクタが普通の設定をしてくれる
- outputはinputで特別な設定をした場合にだけ必要で、普通はNULL*1
流れとしてはWinMain関数の最初にGdiplusStartup関数を呼び出し、returnの直前でGdiplusShutdown関数を呼び出します。
初期化/終了処理に関する注意
GdiplusShutdownを呼び出す前に、全てのGDI+オブジェクト(*2)を解放しておく事です。
先ほど落とし穴にはまったのですが、C++の仕様なのか、staticな、あるいはグローバルなGDI+オブジェクトは、
WinMain関数が終わった後にデストラクタが呼ばれるようです。
これではエラーが出てしまうので(*3)、このようなオブジェクトを作りたいなら、
それへのポインタを作り、終了処理前にdeleteするといいです(*4)。
また、DllMain関数や、それが呼び出す関数などから初期化/終了をしてはいけない。
代わりにDLLのユーザーに初期化/終了をしてもらうか、各関数ごとに初期化/終了するなど。
この処理をもうちょっと楽にしたい
// GDI+の初期化クラス #pragma once #include <windows.h> #include <gdiplus.h> using namespace Gdiplus; class CGdiplusInit { private: ULONG_PTR gdiplusToken; public: // Initialize CGdiplusInit() { GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); } // O WA RI ~CGdiplusInit() { GdiplusShutdown(gdiplusToken); } };
ただしこれでは特殊な設定はできません。
追記(09/02/12)
上記のソースコードはMacro to initialize GDI+ in VC6.0 MFC projectsのコメント欄に、6年とひと月ほどの昔に出てました。いわゆるがい出ですね。
CGdiplusInitでググるといっぱい出てくる・・・。はずかしや。