今朝、フォールダーに入っているGDI+が書き込み処理可能な画像ファイル(注)のサイズをi一定の条件に沿って一括変換するResizerというソフトを書きあげました。

注:"image/bmp", "image/jpeg", "image/gif", "image/tiff", "image/png"の5つですね。

 

が、

 

昨日以来今朝に至るまで「Imageクラスインスタンスを作った段階でプログラムが落ちる」トラブルで頭を悩ませていました。そしてその原因が(頭の悪い私の)おかしな思い込みによるものであることが分かりました。

トラブルというのは、SkeltonWizardでつくったダイアログベースのスケルトンで、GDI+を使おうとして何の迷いもなく、

 

CMyWnd::CMyWnd() {         //コンストラクター

    //ワイド文字使用のためロケールの初期化(日本語)
    setlocale(LC_CTYPE, "JPN");
    //GDI+の開始
    GdiplusStartup(&m_gdiToken, &m_gdiSI, NULL);
}

CMyWnd::~CMyWnd() {         //デストラクター

    //GDI+の終了
    GdiplusShutdown(m_gdiToken);
}

 

とやってテストをすると落ちる、落ちる、落ちまくります。この為、色々なところに私特有のMessageBoxトラップをかけて全てGDI+関連のところで落ちていることを確認しますが、(自分ではちゃんと初期化を行っているつもりなので)「何故!?!?!?!」と考えてしまいます。最後にImageクラスポインターにnewでImageオブジェクトを作るところのファイル名(ワイド文字)を標示したら「setscaleを実施しているにもかかわらず」ファイル名がおかしい!ということで↑のコンストラクターとデストラクターにトラップを仕掛けると、デストラクターは働いていますが、コンストラクターはスルーされています。

 

???............!!!

 

BCCSkeltonの、SkeltonWizardで作成されるウィンドウ(ダイアログ)クラスは、宣言部で

class CMyWnd : public CDLG
{
public:    //以下はコールバック関数マクロと関連している
    //////////////
    //メンバー変数
    //////////////
    //2重起動防止用のMutex用ID名称
    CMyWnd(char* UName) : CDLG(UName) {}

と「文字列を渡すコンストラクター(注)」を宣言しています。

注:このコンストラクターは、派生元のCDLGクラスやCSDIクラス等のミューテックスを利用した排他処理の可否を問うIsOnlyOne関数の為にユニークな名称を文字列として与えるコンストラクターになっています。

従って、↑のような引数を与えないデフォルトコンストラクターを作っても、インスタンスを作るSkeltonWizardのコードは、

 

CMyWnd Resizer("Resizer");    //ウィンドウクラスインスタンスの生成
 

「文字列を引数に渡すコンストラクター」を使っており、実は全く呼ばれないのです。(20年も経ったので、自分で作ったものの、もはや忘れかけており、恥ずかしい限りです。)

 

ということで、教訓。

SkeltonWizardでつくったBCCSkeltonのコードを使う場合、(GDI+の「GdiplusStartup」や「GdiplusShutdown」のような)始めとお終いに必ず行う処理はOnCreateやOnInit、OnClose等のウィンドウ処理の「必ず通る関数」(注)に仕掛けた方がよいでしょう。

注:なおダイアログの場合、OnIdokやEscキーを押したときも想定してOnIdcancelに仕掛けても、ダイアログの「X]ボタンを押した際にはスルーされるので、必ずOnCloseに仕掛けるよう気を付けましょう。

 

追補:【ちょっといい話】

この話を書く際にウェブをチェックしていて、

デフォルトコンストラクタが呼ばれない

という記事を見つけました。ありがちな話ですよね?(忘れずに一番下のAkira Takahashiさんのアドバイスをお読みください。)

BCC55はC++11以前、BCC102はC++11適合なので実験してみても面白いと思います。

 

追々補:【ちょっといい話】

Resizerで、料理の写真(一辺が2~4000ピクセルで1枚5MB、全部で260MB程度)を纏めて「長い方の1辺を960ピクセルにしてオリジナルの縦横対比を変えない」ように縮小したら、解像度は十分ありながら1枚650KB、全部で24MB程度にダウンサイジングができました。おかげさまでAlbumもサクサク動いています。