今日のブログの二本目は、恥ずかしながら「バグ」報告です。
不良コードを書いたのではなく、書くべきコードを書き忘れた(従って実害はない)ので、「バグ」か否かはビミョーなんですが、BCCSkeltonとの互換性を失っているので潔く「バグ」とします。
当該箇所はCDLGの終了に関わるOnClose関数の処理についてです。
【BCCSkelton.h】
///////////////////////////////////
//ダイアログコールバック関数マクロ
///////////////////////////////////
//モーダルダイアログ書式=BEGIN_MODALDLGMSG(CDLG変数)
//又MODALDLGPROC(CDLG変数)がコールバック関数
#define BEGIN_MODALDLGMSG(_PROC_, _P_) BOOL CALLBACK _PROC_(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {\
.
.
.
if(Msg == WM_CLOSE) if((Done = _P_.OnClose(wParam, lParam))) _P_.EndModal(Done);\
//モードレスダイアログ書式=BEGIN_MODELESSDLGMSG(CDLG変数)
//又MODELESSDLGPROC(CDLG変数)がコールバック関数
#define BEGIN_MODELESSDLGMSG(_PROC_, _P_) BOOL CALLBACK _PROC_(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {\
.
.
.
if(Msg == WM_CLOSE) if((Done = _P_.OnClose(wParam, lParam))) _P_.Destroy();\
(解説)BCCSkeltonではウィンドウやダイアログのコールバック関数を外部関数にしてマクロで処理をしています。
モーダルダイアログとモードレスダイアログは共にWM_CLOSEメッセージでOnClose関数を呼び、その戻り値(Done)がTRUEであれば「モーダルダイアログはEndModal関数を、モードレスダイアログはDestory関数」を呼びだします。
【ECCSkeltonのCDLG.h】
//本来のコールバック関数(仮想関数)
BOOL CALLBACK CDLG::DlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
bool Done = FALSE;
switch(Message) {
.
.
.
case WM_CLOSE:
Done = OnClose(wParam, lParam);
break;
.
.
.
}
return Done;
}
(解説)ECCSkeltonではコールバック関数をクラスのメンバー関数にし、ウィンドウメッセージの処理関数は仮想関数にしており、WM_CLOSEの場合はOnClose関数を呼び出すだけになっていました。
しかし、本来BCCSkeltonの様にDone==TRUEの場合、「モーダルダイアログはEndModal関数を、モードレスダイアログはDestory関数」を呼びださなければBCCSkeltonとの互換性が取れなくなるため、今回以下の通り「m_Modeというモーダルダイアログ、モードレスダイアログの区分フラグを追加して」修正しました。(m_ModeフラグはDoModal関数とCreate関数で決定します。)
case WM_CLOSE:
Done = OnClose(wParam, lParam);
if(Done) { //終了ならば
if(m_Mode) //TRUE-Modal ダイアログ
EndModal(Done);
else //FALSE-Modeless ダイアログ
Destroy();
}
今回ダイアログベースでBCC2ECCプロジェクトを作っていてダイアログを閉じてもプログラムが終了しないことから今回の不具合に気が付きました。修正の後、BCC2ECCのみならず、ダイアログベースのECCSkeltonサンプルを再コンパイルして正常に動作していることを確認しています。(注)
注:サンプルにはモーダルダイアログベースのFileListと、モードレスダイアログベースのTextToSpeechがあり、「どうやって動作させていたのだろうか?」と確認をしたら、OnClose関数の中でFileListはEndModal関数を、TextToSpeechはDestory関数を別途呼んでいました。そういう意味で、分かっている(注2)なら問題は生じないのですが、矢張りBCCSkeltonと互換性が無いのは不味であり、告知の上、修正版をアップロードします。
注2:これら二つのダイアログベースのプログラムをECCSkeltonに移植する際に、適切なコードを書いたにせよ、OnClose関数でプログラムが終了しないことは分かっていて、BDDSkeltonとの互換性欠如に気が付かなかったことは、矢張りボケが進行していると考えるべきなのでしょうか?ナンマイダブ。