## 【ECCSkelton について】

## August 10, 2022

Vector で公開している"BCCFormandBCCSkelton"に、"ECCSkelton"フォールダーを追加して、本日公開しました。（注意：Vector からダウンロードできる迄、一定お時間がかかります。また、ダウンロードできる URL は↑のものと異なるかもしれませんのでご注意ください。）

繰り返しになりますが、これを機会にもう一度 BCCFormandBCCSkelton のパッケージについて説明します。

１．背景

BCCForm→2000 年にフリーで利用できるようになった Borland（当時） C++ Compiler （bcc551）にリソースエディターがなかった為、2002 年に公開した（偶々当時駐在していたシンガポールで取得した bcc550 の）BRC32.exe でコンパイルできる Borland Resource Editor 準拠の独自リソースエディターです。（これはライブラリーなしで純粋に SKD だけで書かれていましたが、2018 年の PC 入替の時の事故でソースを失いました。）

BCCSkelton→当時 Win32 SKD のウィンドウ登録、作成、コールバック関数およびエントリーポイント関数のファイルを書いていましたが、毎回同じコードを書く馬鹿らしさに、自分なりの「Win32 SKD 省力、効率化ライブラリー」を作成し始め、リソース（*.rc）ファイルからウィザード（SkeltonWizard.exe－これは BCCSkelton で書かれましたが、2018 年の事故でソースを失いました）で 4 本のスケルトンファイルを作成する（IDE 迄には届きませんでしたが）ユーティリティを作成しました。ユーティリティにはイメージエディター、ツールバーエディター等を付けてリソース編集面を充実させていました。

２．ECCSkelton－"Embarcadero C++ Compiler"の時代の Skelton

ECCSkelton→BCCForm と BCCSkelton でつくるプログラムは当時（2001 年に XP がリリースされるまでは、Unicode を使わない Windows 98 が主流）を反映して文字列は基本的に ASCII（Shift-JIS）ベースであり、文字列を使わない限り差はないのですが、矢張り OS がユニコード（UTF-16 のワイド文字）をネイティブで使っているので、それにも対応しないとまずいでしょ、ということで「ちょこっと発展型」の BCCSkeltonWplus 等を考えましたが、矢張り二本立てには無理があり、文字列を扱う処理なら「UTF-16 ワイド文字一本やり」のライブラリーが欲しい、ということで"Embarcadero C++ Compiler"の時代の Skelton という意味で、BCCSkelton を一から見直しながら、SkeltonWizard の排出するコードに最小の手直しで対応できるライブラリーを目指しました。

３．BCCSkelton との相違～BCCSkelton ファイルからの移植

（１）文字列データ

Shitf-JIS の文字列データは 1 バイト（漢字は 2 バイト）の ASCII 文字データであり、これらを UTF-16 の２（または 4）バイト文字データに替える必要があります。

1 バイト変数（char、LPSTR、LPCSTR 等）は 2 バイト変数（ whar_t（WCHAR）、LPWSTR、LPCWSTR 等）に替えます。

1 バイト文字（列）定数（’A'、"abc"、NULL）も 2 バイト文字列定数（L’A'、L"abc"、L'\0'）に替えます。

また、Microsoft が"TCHAR 型"という「蝙蝠変数」（TCHAR、LPTSTR、TEXT(文字定数)の_T(文字定数) マクロ _TEXT(...)）を開発し、"UNICODE"フラグが定義されていることを条件に 1 バイト文字、2 バイト文字に自動振り分けを可能にしていますが、ECCSkelton では全て「WCHAR を基本型」（WCHAR、LPWSTR、L(文字列定数)）にしています。（例外的に 1 バイトデータを扱う（例：CICON.h）以外は char を使うことはない。）

具体的にはエディターの一括変換を利用して、

① "char” → "WCHAR”

②「（スペース）"」（～”） → 「（スペース）L"」（～”）

を行うと効率的です。

（２）ワイド文字対応関数

① Microsoft は Windows の Win32 API の関数について、Windows の UTF-16 対応の為に、文字(列）を引数で受け付け、処理し、または出力する関数に関しては 1 バイト文字用と 2 バイト文字用の二つを用意しており、「関数名」を"UNICODE"フラグが定義されていることを条件に「関数名 W」（TRUE）、「関数名 A」（FALSE）にマクロ定義しており、UNICODE（ECCSkelton.h で定義している）条件で自動的に振り替えられますが、ECCSkelton は明示的に（分かる限り）「関数名 W」を使用しています。

② 構造体も同様に"UNICODE"フラグで「構造体 W」（TRUE）、「構造体 A」（FALSE）等に自動的に振り替えていますが、ECCSkelton では明示的に（分かる限り）「構造体 W」を使用しています。

③ エントリーポイントは「関数名 W」のルールから外れており、

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
から

int WINAPI w WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {

へ変更します。（注）

注：BCC102 の bcc32c.exe でコンパイルする際には"-tU"オプション（ウィンドウプログラム（"-tWU"）、コンソールプログラム（"-tCU"））を使う必要があります。

④ マクロテーブルの変更

BCCSkelton では、外部コールバック関数をマクロで記述して CWND から CMyWnd クラスを派生してアプリケーションに使用していますが、ECCSkelton ではコールバック関数をクラス関数に替えた為、定型ウィンドウメッセージについてはマクロテーブルが不要になりましたが、

(i)WM_COMMAND メッセージの場合は、OnCommand(wParam, lParam);という関数を呼ぶよう宣言し、これを"CMDTABLE"というマクロにしました。また、この関数の定義もマクロ化し、

//CMyWnd クラスの OnCommand()関数定義
BEGIN_CMDTABLE(派生クラス名)
ON(メニュー・コントロール ID, On 関数名())
ON(IDM_VERSION, OnVersion()) //例示です
END_CMDTABLE
の様に記述することにしました。

SkeltonWizard が生成するコードは次のようになっていますので、ウィンドウメッセージ部分は削除して次の様に変更することが必要です。

BEGIN_MDIMSG(RTEditor) //ダイアログと違い、コールバック関数名を特定しない

→ BEGIN_CMDTABLE(派生クラス名)へ手書きで変更する。
//メニュー項目、ダイアログコントロール関連
ON_COMMAND(RTEditor, IDM_NEW, OnNew())
//SkeltonWizard ではこの様になっているので、

（１）ON_COMMAND(RTEditor, IDM_NEW, OnNew())

（２）ON(IDM_NEW, OnNew())

(2)にするために

"_COMMAND(RTEditor, " を

↓

"("

に一括変換します。）

（略）

//ウィンドウメッセージ関連→　ウィンドウメッセージ部分は削除
//MDIFrame 親ウィンドウは自動的に OnMDIFrameCreate()を呼ぶ
（略）

ON_CLOSE(RTEditor)
END_MDIMSG(RTEditor)
→ END_CMDTABLE へ手書きで変更する。

また、サンプルの FileHandler の様に既定外のウィンドウメッセージ（WM_SHELLCHANGE）がある場合、既定のメッセージ以外が処理される OnOthers 関数をオーバーライド処理し、そのメッセージの処理関数（OnShellChange(WPARAM, LPARAM)）を呼ぶようにします。具体的には、

//特殊なメッセージ処理
bool OnOthers(UINT, WPARAM, LPARAM);
bool OnShellChange(WPARAM, LPARAM);
のようなメンバー関数の宣言を行い、

//特殊なメッセージ処理(既定のメッセージ以外のメッセージの場合の処理)
bool CMyWnd::OnOthers(UINT Message, WPARAM wParam, LPARAM lParam){ //その他のメッセージ
if(Message == WM_SHELLCHANGE)
return OnShellChange(wParam, lParam);
}
のように OnOthers 関数を定義します。

以上の対応でまず 100%BCCSkelton で開発できるプログラムは ECCSkelton で開発できるので、BCCForm や SkeltonWizard も依然利用可能です。なお、プログラムのコンパイルには"-tU"オプションが使える、BCCSkelton で記述した BatchGood.exe を使用することを推奨します。