今回はHelloWorldプロジェクトを使って、(プロジェクト名).hの解説を行います。

 

以下では実際にHelloWorld.hを見ながら、順に解説(以下「【解説-(解説文)】」)してゆきます。

 

//////////////////////////////////////////
// HelloWorld.h
// Copyright (c) 05/19/2021 by BCCSkelton
//////////////////////////////////////////

【解説-自動作成のタイトルです】
 

//BCCSkeltonのヘッダー-これに必要なヘッダーが入っている
#include    "BCCSkelton.h"
【解説-BCCSkeltonのマクロやクラスのすべてがこのヘッダーファイルから読み込まれます。開発環境では必ずpathを通してください。例:私のBCC Developperのプロジェクト設定におけるインクルードパスの画像です。】

 

//リソースIDのヘッダー
#include    "ResHelloWorld.h"

【解説-これはリソースの定数定義ファイルです。同じプロジェクトフォールダーにある前提でSkeltonWizardが""としています。】


//メッセージの定義
const LPSTR g_lpMsg = "Hello World!!";
【解説-これはマニュアルで追加したものです。何度も"Hello World!!"と書くのが面倒だし、他のメッセージに変えられるのでconst外部変数にしています。勿論constを外した単なる文字列(char*)の外部変数や#defineにしても結構です。】


/////////////////////////////////////////////////////////////////////
//CMyWndクラスをCDLGクラスから派生させ、メッセージ用の関数を宣言する
/////////////////////////////////////////////////////////////////////

【解説-いよいよ本題です。以下は↑のコメントの通り、メインのウィンドウ(ダイアログ)をクラス定義します。】

 

class CMyWnd : public CDLG

【解説-ウィンドウベースでもダイアログベースでもSkeltonWizardは定義するメインウィンドウをCMyWndとします。一方、他の補足的なダイアログの場合にはダイアログIDが"IDD_ETC"である場合、クラス名を"IDD_"以下の名称+大文字DLGで"ETCDLG"とし、作成するインスタンス名をクラス名の全小文字化によるetcdlgとしています。CMyWndではなく、IDD_HELLOWORLDだから、HELLOWORLDDLG、helloworlddlgにしたい、という場合には手作業で変更してください。】

 

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

【解説-これは前に触れましたが、BCCSkeltonが2重起動対応のためにミューテックスを作成しているのでSkeltonWizardが本ファイルのここと、cppファイルの冒頭にデフォルトで二重起動対応の記載があります。詳しくはミューテックスの記事、BCCSkeltonのCSDI、CMDI、CDLGのクラス定義をご参照ください。なお、ミューテックスを作成しているのですが、作成したミューテックスを破棄している記述が見当たらず、これら3クラスのデストラクターに破棄記述を追加しています。汗;本日「20年ぶり」訂正版をアップロードします。】

 

    //メンバー変数の追加

    RECT m_client;

【解説-これはメインダイアログのクライアントエリアを記録するために追加した変数です。一般にユーザーが使用する変数はその適用規模に応じて、「関数内のローカル変数(使い捨て)<クラス内のメンバー変数(私は"m_"接頭詞を付けます)<クラス全体およびpublicにすればクラス外からも参照可<名前空間内で自由にアクセスできる(その為バグの原因ともなる)グローバル変数(私は"g_"接頭詞を付けます)にしてください。


    //メニュー項目、ダイアログコントロール関連
    bool OnExit();
    bool OnDisp();
    bool OnTitle();
    bool OnStatusbar();
    bool OnVersion();
【解説-これはすべてメニュー割り込みに対応した関数の宣言です。】

 

    //ウィンドウメッセージ関連
    bool OnInit(WPARAM, LPARAM);
    bool OnLButtonDown(WPARAM, LPARAM);
    bool OnSize(WPARAM, LPARAM);
    bool OnPaint(WPARAM, LPARAM);
    bool OnClose(WPARAM, LPARAM);
    bool OnDestroy(WPARAM, LPARAM);

【解説-これはすべてウィンドウメッセージ割り込みに対応した関数の宣言です。なお、最初のOnInitはウィンドウベースの場合、OnCreateになります。】

};

////////////////////////////////////////////////////////////////////////
//派生させたCMyWndクラスのインスタンスとコールバック関数(マクロ)の作成
//主ウィンドウはダイアログと違い、コールバック関数は一つしか作れない
////////////////////////////////////////////////////////////////////////
CMyWnd HelloWorld("HelloWorld");    //ウィンドウクラスインスタンスの生成

【解説-これは上記で定義したクラスのインスタンス(実体)を生成するための宣言です。一般の変数宣言と同じですね。また、カッコ内の"HelloWorld"がミューテックスを作成するために使われます。】

 

BEGIN_MODELESSDLGMSG(ModelessProc, HelloWorld)    //コールバック関数名は主ウィンドウの場合ModelessProcにしている
    //メニュー項目、ダイアログコントロール関連
    ON_COMMAND(HelloWorld, IDM_EXIT, OnExit())
    ON_COMMAND(HelloWorld, IDM_DISP, OnDisp())
    ON_COMMAND(HelloWorld, IDM_TITLE, OnTitle())
    ON_COMMAND(HelloWorld, IDM_STATUSBAR, OnStatusbar())
    ON_COMMAND(HelloWorld, IDM_VERSION, OnVersion())
    //ウィンドウメッセージ関連
    //自動的にダイアログ作成時にOnInit()、終了時にOnClose()を呼びます
    ON_LBUTTONDOWN(HelloWorld)
    ON_SIZE(HelloWorld)
    ON_PAINT(HelloWorld)
    ON_DESTROY(HelloWorld)
END_DLGMSG
【解説-このBEGIN_MODELESSDLGMSG~END_DLGMSGがマクロによってコールバック関数に展開されます。モーダルダイアログの場合にはBEGIN_MODALDLGMSG~END_DLGMSG、ウィンドウベースの場合にはBEGIN_SDIMSG~END_WNDMSGやBEGIN_MDIMSG/BEGIN_MDICHILDMSG~END_MDIMSG/END_MDICHILDMSGとなります。なお、必ず使われる関数については予めマクロに入っていますが、その際には上のOnInit()、OnClose()のようにコメントで注意書きを入れています。】

 

///////////////////////
//ステータスバーの作成
///////////////////////
CSBAR SBar;
【解説-SkeltonWizardでステータスバーを含めるとこのように自動的に記述されます。】

/////////////////////////
//コモンダイアログクラス
/////////////////////////
CMNDLG cmndlg;
【解説-SkeltonWizardでコモンダイアログクラスを含めるとこのように自動的に記述されます。】

///////////////////////
//仮想ウィンドウの作成
///////////////////////
CANVAS cvs;
【解説-SkeltonWizardで仮想ウィンドウを含めるとこのように自動的に記述されます。】

///////////////////////////////////////////
// CDLGクラスからVERSIONDLGクラスを派生
// 複数の同一ダイアログ変数とダイアログも作
// れるが、一つのダイアログに一つの派生ダイ
// アログクラスを作成するのが基本
///////////////////////////////////////////
class VERSIONDLG : public CDLG {
public:
    bool OnIdok();
};

////////////////////////////////////////////////////////////////////////////
// VERSIONDLGクラスダイアログ変数の生成とそのコールバック関数(マクロ)を定義
// 複数同一クラスのダイアログを作成することを予期してコールバック関数を明記
////////////////////////////////////////////////////////////////////////////
VERSIONDLG versiondlg;
【解説-これが一般的なその他ダイアログのクラス記述(IDD_VERSION→VERSIONDLGクラス→versiondlgインスタンス)です。】
 

BEGIN_MODALDLGMSG(versiondlgProc, versiondlg)    //第1引数がコールバック関数の名前
【解説-カッコ内のコールバック関数のポインターは「インスタンス名+Proc」となっています。】
 

    ON_COMMAND(versiondlg, IDOK, OnIdok())
【解説-OKボタンの記述だけですが、IDOKはシステムで定義されており、ResHelloWorld.hファイルには#define定義されません。】
END_DLGMSG

 

スケルトンができたので、いよいよプログラムを仕上げてゆきます。

 

BCCForm and BCCSkeltonは、BCBのようにすべてWYSWYGのプラットフォームで完成させるのではなく、

 

(1)机の上での企画、仕様決定

(2)BCCFormによるリソース作成

(3)SkeltonWizardによるスケルトン(どんがらウィンドウ)の作成

(4)マニュアルによるプログラムの仕上げ

-①rcファイル、Res.hファイルの調整(通常何もしませんが、特殊なケースはいじる可能性があります。)

-②cppファイル(これはファイルいよるプログラムの起動や、二重起動処理を行う必要があり、必ずいじります。)

-③hファイル、Proc.hファイル(およびUser.hファイル)(これはプログラムの作動の実装部分であり、一番時間をかけていじります。)

 

というように、(4)からの本格的なプログラミングはマニュアルとなります。

 

今回のHelloWorldプロジェクトでは、(4)-①は特に何もすることがなく、BCCFormの出力そのままでよいでしょう。(私はRes.hファイルの#define値をきれいにしないと気が済まないのですが。)

 

では(4)-②のcppファイルについてみてみます。以下はSkeltonWIzardの出力したHelloWorld.cppです。

 

//////////////////////////////////////////
// HelloWorld.cpp
//Copyright (c) 05/19/2021 by BCCSkelton
//////////////////////////////////////////
#include    "HelloWorld.h"
#include    "HelloWorldProc.h"

////////////////
// WinMain関数
////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow) {

    //2重起動防止
    if(!HelloWorld.IsOnlyOne()) {
        //ここに2重起動時の処理を書く(下記は1例)
        //HWND hWnd = FindWindow("MainWnd", "HelloWorld");
        //if(IsIconic(hWnd))
        //    ShowWindow(hWnd, SW_RESTORE);
        //SetForegroundWindow(hWnd);
        //SendMessage(hWnd, WM_COMMAND, IDM_OPEN, 0);
        return 0L;
    }
 

    //モードレスダイアログを作成Create(hParent, DlgName, DlgProc);
    if(!HelloWorld.Create(NULL, hInstance, "IDD_MAIN", ModelessProc))
        return 0L;

    //メッセージループに入る
    return HelloWorld.Loop();
}

 

WinMain関数の中身を見ると、まず「//2重起動防止」のブロックが目に入ります。

これはメインウィンドウ(ダイアログ)とおなじID(注1)のウィンドウがあれば(即ち二重起動されれば)、if節が真となり、カッコ内が実行されます。「二重でも三重でもどんどんやってくれ」という場合にはこのブロックそのものを削除します。しかし、そうでない場合にはどうすべきでしょうか?コメントにしているSkeltonWizardの作成するデフォルトの出力は、「ウィンドウ登録名とタイトルから既に開かれている同一ウィンドウハンドルを取得し、(アイコン化されていれば開いて)前面に出し、「ファイルを開く」メニューの関数を呼ぶ」というものです。私は通常上4行のコメントを外し、5行目(SendMessage部分)は削除して、次のようにしています。

    //2重起動防止(修正版-コメントの以下例を参考に修正する)
    if(!HelloWorld.IsOnlyOne()) {
        HWND hWnd = FindWindow("MainWnd", "HelloWorld");
        if(IsIconic(hWnd))
            ShowWindow(hWnd, SW_RESTORE);
        SetForegroundWindow(hWnd);
        return 0L;
    }
注1:メインウィンドウ(ダイアログ)であるCMyWndクラスの宣言の最初に、

      //2重起動防止用のMutex用ID名称
      CMyWnd(char* UName) : CDLG(UName) {}
とありますが、これがID設定の部分です。詳しくは説明しませんが、興味のある方はCDLG.hのIsOnlyOne()関数を調べてみてください。

 

その次のブロックは、本プロジェクトがモードレスダイアログベースなので、ダイアログの作成、表示部分のみとなっています。ウィンドウベースのプログラムでは、この部分が登録と作成、表示の二つになります。

【参考-SDIのEZImageの該当部分】

    //ウィンドウ登録 - Init(ClassName, hInstance, WndProc, "IDM_MAIN",
    //                        (以下省略可)MAKEINTRESOURCE(IDI_ICON), IDC_ARROW, Brush)
    EZImage.Init("MainWnd", hInstance, SDIPROC, "IDM_MAINMENU", MAKEINTRESOURCE(IDI_ICON));
    //ウィンドウ作成と表示-Create(WindowTitle, (以下省略可)Style,
    //                        ExStyle, hParent, hMenu, x, y, w, h)
    if(!EZImage.Create("EZImage"))
        return 0L;
 

最後の「//メッセージループに入る」ブロックはコールバック関数を使ったメッセージ処理の部分です。ウィンドウベースでもこの部分は同じです。

【参考-SDIのEZImageの該当部分】

    //メッセージループに入る
    return EZImage.Loop();
 

なお、詳述しませんが、MDIプログラムはもっと複雑で、ウィンドウの登録と作成、表示部分のcppファイルは、アクセラレータも使った場合、次のようになります。ただし、コメントも含めてそのほとんどの部分が自動作成されます。

【参考-MDIのBCFEditorの該当部分】

    //ウィンドウ登録 - Init(ClassName, hInstance, WndProc, "IDM_MAIN",
    //                        (以下省略可)"IDI_ICON", IDC_ARROW, Brush)
    //MDI Child WindowとMDI Frame Windowの登録-MDIFrameWndを
    //作成するので必ずMDIChildWndから登録する(クラスネームを残す)
    BCFEditor.Init("MDIChildWnd", hInstance, MDICHILDPROC, NULL,
                "IDI_ICON", IDC_CROSS, (HBRUSH)(COLOR_3DFACE + 1));
    BCFEditor.Init("MDIFrameWnd", hInstance, MDIPROC, "MAIN_MENU",
                "IDI_ICON", IDC_ARROW, (HBRUSH)(COLOR_3DSHADOW + 1));

    //ウィンドウ作成と表示-Create(WindowTitle, (以下省略可)Style,
    //                        ExStyle, hParent, hMenu, x, y, w, h)
    if(!BCFEditor.Create("BCFEditor",
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN))
        return 0L;

    //アクセラレーター登録-InclAccel("(Accelerator ID)")
    BCFEditor.InclAccel("IDA_ACCEL");

    //メッセージループに入る(検索・置換ダイアログをモードレスダイアログで使う)
    return BCFEditor.Loop();
 

BCCSkeltonによる作業効率化はcppファイルが最も顕著であると言えますね。

BCCFormでリソースを作成した後は、SkeltonWizardの出番です。

SkeltonWizardはリソースファイル(rcファイル)を引数に与えなければ(注1)起動できません。

注1:MS-DOSの時代のコンソール入力では"C:\BCCForm_and_BCCSkelton\SkeltonWizard.exe (リソースファイル名).rc"のように書きます。

 

作成したHelloWorld.rcでSkeltonWizardを起動すると次のような画面になります。

今回のHelloWorldはSDIで開発してもよいのですが、ダイアログベースにしたので「ダイアログ」を選択し、下のドロップダウンメニューからメインダイアログを選択してください。また、その下の「ステータスバー」と「仮想ウィンドウ」にチェックを入れて、右のドロップダウンメニュー群の「メニュー」「アイコン」で作成したダイアログ用のメニューとアイコンを選択してください。

このようになります。(「コモンダイアログ(CMNDLGクラス)」は選択しなくても結構です。また、表示画像がSDIと違いますね?ウィンドウタイプをMDIにするとどういう画像になるでしょうか?いずれ試してみてください。)下の「次へ」ボタンを押してください。

このページはツールバーとステータスバーの設定画面です。今回ツールバーは使わないのでグレー(使用不可状態)になっています。

ステータスバーはセクションを二つ取り、プログラム名と任意文字列の表示を行いましょう。完了したら「次へ」を押します。

このページが、ユーザーがプログラミングで最も手を掛けることになる(プロジェクト名)Proc.hファイルが担当する、ウィンドウメッセージやメニューやコントロールによる割り込み処理を設定する画面です。

上段がウィンドウメッセージで「->」を押すと設定され、「<-」を押すと解除されます。

下段はメニュー、コントロールで同様に設定、解除します。

両方とも、ポイントは「設定せずに後で追加するよりも、余計に設定して後で削除する方が楽」ということでしょうか?なお、ここで「設定」すると、

(1) (プロジェクト名).hのメインウィンドウ(ダイアログ)およびその他ダイアログのクラス定義におけるメンバー関数の宣言

(2) (プロジェクト名).hの(クラスインスタンスの作成-実際の変数の宣言の下にある)「コールバック関数(マクロ)」(BEGIN_MODELESSDLGMSG/BEGIN_MODALDLGMSGとEND_DLGMSGで挟まれた)テーブル

(3) (プロジェクト名)Proc.hのメンバー関数の定義

が追加されます。実際に余計に作成し、確認してから削除してみてください。

完了したら「次へ」を押します。

これで完了しました。どのような開発プロジェクトとなるかの概要が表示されますのでよろしければ「完了」を押し、変更したい場合には「戻る」を押してください。(なお、WYSWYGにチェックを入れるとスケルトンウィンドウを起動させて、メニューやコントロールを押すとBCFEditorが該当関数定義を開く仕様でしたが、余り使い勝手が良くないのでお勧めしません。また、一旦ファイルを作成し、それを編集中にもう一度SkeltonWizardでファイルを作り直す場合の「CPPファイルを書き換えない」オプションもあまり使いませんね。笑)

 

以上で、BCCFormで作成したHelloWorld.rcとResHelloWorld.hに加え、今回のプロジェクト(HelloWorld)の次のファイルが作成されます。

(1) HelloWorld.bdp(BCC Developper用プロジェクト管理ファイル)

(2) HelloWorld.h(クラス定義、インスタンス作成、コールバック関数マクロテーブル)

(3) HelloWorldProc.h(ウィンドウクラスのメンバー関数定義-ウィンドウメッセージ、メニュー、コントロールによる実際の動作を記述する)

(4) HelloWorld.cpp(ウィンドウ登録、作成、メッセージループ-SKDプログラムでは長々欠かされるが、プログラミング上余り重要ではない)

 

なお、上記(1)のファイルはBCC DevelopperやBCFEditorを使わなければ使用しませんが、BCC Developperユーザーに対するスケルトン作成上の注意点を述べます。

(1) HelloWorld.bdpを開く

次のような画面になると思います。確認してください。

(2) 「プロジェクト設定」

デフォルトは"Debug"になります。(私はいつも"Release"で開発しますが、何か?)


Windowsアプリケーションになっているでしょうか?

ではこのままビルド(「再構築」)してください。するとリソースが全く反映していないアプリケーションが作成されるかもしれません。

これは「プロジェクト設定」の「リソース」タブの「リソーススクリプトファイル名」の引用符処理で'"'(ダブルクォテーション)が残るためです。

慌てず騒がず、この引用符を削除して再度ビルドしてください。すると

このようなウィンドウができます。しかし、マウスをクリックしたり、メニューを選択しても何もしません。これが「スケルトン」というものです。

 

今回はここまで。

BCCForm and BCCSkelton流のプログラミング作法は、最初に「資源(リソース)」を調達することです。

前回の企画とイメージに基づくと、

(1) メインウィンドウ(ダイアログ)

(2) メインダイアログ用のメニューとステータスバー

(3) プログラム用アイコン(私はBCC Developperのアイコンを使いました。)

(4) バージョンダイアログ(私は別にアイコンを用意しましたが、(3)の物でも結構です。)

を作成する必要があります。

 

まずアイコンを用意します。アイコンの作成にはBCCForm and BCCSkeltonのEZImageを使用します。以下は読込と編集の画像です。

【読込】

【編集】

 

次はメニューとステータスバー付のメインダイアログです。(今回は使用していませんが、ツールバーも付けられます。サンプルのBCCMakerなどがそうですね。)

次はバージョンダイアログです。作成したアイコンを使用しています。

アイコンは次のようにリソースに登録します。

 

BCCFormによるリソース作りが完了し、ファイルをセーブした後、BCCFormやBCFEditor等のテキストエディターで二つの出力ファイルを仕上げます。

【HelloWorld.rc】

//-----------------------------------------
//             BCCForm Ver 2.41
//    An Easy Resource Editor for BCC
//  Copyright (c) February 2002 by ysama
//-----------------------------------------
#include    "ResHelloWorld.h"

//----------------------------------
// ダイアログ (IDD_MAIN)
//----------------------------------
IDD_MAIN DIALOG DISCARDABLE 0, 0, 270, 180
EXSTYLE WS_EX_DLGMODALFRAME
STYLE WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_SETFONT | DS_CENTER
CAPTION ""
MENU IDM_FORM_MENU
FONT 8, "Times New Roman"
{
 CONTROL "", IDC_STATUSBAR, "MSCTLS_STATUSBAR32", WS_CHILD | WS_VISIBLE | CCS_TOP | CCS_NOMOVEY, 0, 168, 270, 12
}

//----------------------------------
// ダイアログで使用するメニュー
//----------------------------------
IDM_FORM_MENU MENU DISCARDABLE
{
    POPUP "ファイル(&F)"
    {
        MENUITEM "終了(&X)", IDM_EXIT
    }
    POPUP "表示(&V)"
    {
        MENUITEM "画面表示(&D)", IDM_DISP
        MENUITEM "ウィンドウタイトルの表示(&T)", IDM_TITLE
        MENUITEM "ステータスバーの表示(&S)", IDM_STATUSBAR
    }
    POPUP "ヘルプ(&H)"
    {
        MENUITEM "バージョン情報(&V)", IDM_VERSION
    }

}
//----------------------------------
// ダイアログ (IDD_VERSION)
//----------------------------------
IDD_VERSION DIALOG DISCARDABLE 0, 0, 232, 52
EXSTYLE WS_EX_DLGMODALFRAME
STYLE WS_POPUP | DS_MODALFRAME | WS_CAPTION | DS_SETFONT | DS_CENTER
CAPTION "バージョン情報"
FONT 9, "Times New Roman"
{
 CONTROL IDI_HELLOWORLD, 0, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY | SS_SUNKEN | SS_ICON | SS_CENTERIMAGE, 8, 8, 36, 36, WS_EX_CLIENTEDGE
 CONTROL "HelloWorld Ver 1.0\r\n(c) Copyright 2021 by ysama\r\nAll rights reserved", 0, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY | SS_SUNKEN | SS_CENTER, 56, 10, 120, 32, WS_EX_CLIENTEDGE
 CONTROL "OK", IDOK, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 184, 16, 40, 20
}

//----------------------------------
// ダイアログで使用するイメージ
//----------------------------------
IDI_HELLOWORLD    ICON    DISCARDABLE    "C:\Users\ysama\Programing\Borland C++\HelloWorld\HelloWorld.ico"

//--------------------------
// イメージ(IDI_ICON)
//--------------------------
IDI_ICON    ICON    DISCARDABLE    "C:\Users\ysama\Programing\Borland C++\HelloWorld\Icon.ico"
 

【ResHelloWorld.h】

//-----------------------------------------
//             BCCForm Ver 2.41
//   Header File for Resource Script File
//   Copyright (c) February 2002 by ysama
//-----------------------------------------
//---------------------
//  ダイアログリソース
//---------------------
// ダイアログ IDD_MAIN
#define    IDC_STATUSBAR        100
// ダイアログ IDD_VERSION

//---------------------
//  メニューリソース
//---------------------
// メニュー IDM_FORM_MENU
#define    IDM_EXIT                   200
#define    IDM_DISP                   201
#define    IDM_TITLE                  202
#define    IDM_STATUSBAR        203
#define    IDM_VERSION             204

//---------------------
//  イメージリソース
//---------------------
#define    IDI_ICON                    300
#define    IDI_HELLOWORLD       400

//---------------------
//  ストリングテーブル
//---------------------

//--------------------
//  アクセラレーター
//--------------------

//------------------
//  ヴァージョン情報
//------------------
 

今回はここまでです。

では定番の”Hello World!!"でプログラムを作ってみましょう。

WEBでBCCForm and BCCSkeltonを使用している方の質問箱を見たことがあるのですが、Borland C++ Builder(BCB)のように、WYSWIG(注1)環境で簡単にウィンドウプログラムが作りたい、という方が多く、またウィンドウにペタペタとコントロールを張り付けたい、という方も多いので、その線でプログラム企画を立てましょう。

 

1.プログラム企画(要求仕様)

(1)”Hello World!!"を(視覚的に)面白く表示する。

(2)視覚的に確認する形でプログラミングする。

2.ソリューション

(1)ウィンドウ上で複数の文字列表示を行う。

(2)ウィンドウデザインを視覚的にできるよう、BCCFormで作成するダイアログベースのプログラムとする。

3.具体仕様

(1)文字列表示は、ウィンドウタイトル、ウィンドウクライアントエリア、ダイアログ、メッセージボックス、ステータスバーとする。

(2)ダイアログはウィンドウの代わりになるメインダイアログと、バージョン情報ダイアログ(ここにも"Hello World!!"を表示したい)とする。

(3)表示はメニューで選択するが、マウスクリックで一挙に表示することもできるようにする。

 

アマチュアプログラマーでもこの程度の要求仕様の具体化は建て、開発推移で方針が変わってもその推移と変化が分かるようにしておくべきでしょう。また、プログラミングの成果物が具体的にイメージできるようになるまであーでもない、こーでもないと検討を行うことが必要でしょう。

 

 

2021年バージョンがVectorで今日から公開開始(注1)されたようです。(といいつつ、昨日CANVASクラスの関数を追加した差し替え版をアップロードしたりして。汗;)

注1:

 

今までBCCFormやBCCSkeltonの使用法を詳しく説明したことがなかったので、今回この場を借りてやってみようと思い、色々と考えたのですが、矢張り最初はカーニハンさんとリッチーさん(注2)に敬意を表して"Hello, World!!"にしましょう。

注2:「プログラミング言語C」の共同著者。このUNIX上のCプログラミングを紹介した本が、35年前、私がSharp MZ-2500の8ビットCP/Mで走るBDS-Cで初めてCプログラミングを行ったときの教本です。

 

しかし、単に文字列を出すだけではBCCSkelton風ではないので、(差し替え版をアップロードすることになったきっかけの)新しい関数紹介を兼ねて、「Hello World!!だらけ」プログラムにしましょう。

 

2002年当時私はシンガポールにおり、週に2~3回海外出張するので移動時間が長く、元々PCとプログラミングが好きだったことから会社のラップトップにもプログラミングソフト(Basic言語)を載せて遊んでいました。

 

従来の順次遂行型のコンソールプログラムと概念が大きく異なるWindowsの割り込みプログラミングを学習しているうちにはまり、インタープリターのBasicソフトに限界を感じるとともに、(20代のころからCに親しんいたこともあり)Borland(当時)からC++のコンパイラー(BCC)がフリーで提供されていることを知って、さっそく導入したのがBCCによるWin32プログラミングのきっかけです。

 

BCCはコンパイラーとリンカーのみで、開発環境は皆無でありました。テキストエディタ―のNotePadだけでWinMain(RegisterClass、CreateWindow、ShowWindow、GetMessage、TranslateMessage、DispatchMessage)とCALLBACK関数を繰り返して書くうちに、病膏盲、リソースエディターがなければこれを自作し、やたら同じようなコードを何度も書かせるウィンドウプログラミングをより簡潔に、(イメージとしてはBorland C++ Builder-BCBのような)WYSWYGに近い形で書ける環境を試行していって、リソースからSkeltonを自動作成するBCCSkeltonを自作、Vector社から公開しました。

 

その後、2004年に帰国、以降仕事が忙しくプログラミングから遠ざかっておりましたが、コロナ感染が始まった2019年に完全リタイアしたので、自粛と隠居のボケ防止にちょうど良いとプログラミングを再開しようと思いました。しかし、2017年にPCを変更した際、2000年代に蓄積した資料やコードを誤ってすべて消去してしまったので、まず自分のBCCForm and BCCSkeltonをVectorからダウンロードし、ユーザーとして再度端から仕切り直しすることになりました。


それから1年、やっとほぼ20年前の状況まで復旧できたと思われたのと、そろそろ老いで脳みそが限界にきたこともあり、2021年までの更新と今回学習、作成したサンプルをソース付きでVectorから再公開することにしました。(公開決定して一週間たちますが、未だ公開されていないようです汗;)

 

いずれにせよ、(当時余り理解されず、利用されなかった)BCCFormで作成したリソースからBCCSkeltonで始めるWin32APIプログラミングをこれからもう少し丁寧に説明していきたいと思っています。