## 【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,
LPSTRlpCmdLine, int nCmdShow) {
から

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTRlpCmdLine, 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)）を呼ぶようにします。具体的には、

//特殊なメッセージ処理
boolOnOthers(UINT, WPARAM, LPARAM);
boolOnShellChange(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を使用することを推奨します。