日曜日にBCB!



Do It Yourselfでひとつプログラムでも作ってみませんか。


第12話「Digital Design Technologyらしく その2」

Digital Design Technologyアイコン前回で設定画面が出来ました。メイン画面から設定画面を呼出しメニュー、ツールバー、ステータスバーの表示/非表示、フォントの設定、次回起動時位置の選択ができます。では、メイン画面からの呼出しをプログラミングしましょう。


設定画面呼び出し

メイン画面から「ファイル」「ユニットを使う」メニューで設定画面を指定します。続いてメニュー、ツールバーの追加を行います。メインメニューを持つZipFinderドクターUnits/TEでは「編集」メニュー下に「設定」メニューを設けいています。寿分割ではまだ「編集」メニューがありません。設定メニューだけのために「編集」メニューを設けるのももったいないですから、ファイルメニューに追加します。

Caption Name 内容
「ファイル(F)」 FileMNU ファイル・寿分割全般に関するメニュー。
  「新規作成(N)」 NewMNU 分割ファイルをクリアする。分割ファイルを新規作成するわけではない。
  「開く(L)...」 LoadMNU 分割元ファイルを開く。
  「-」 SEP11 メニューを見やすくするセパレータ。
  「設定(S)...」 SetupMNU 寿分割を設定する
  「-」 SEP12 メニューを見やすくするセパレータ。
  「閉じる」 CloseMNU 寿分割を終了する。


メニュー 有効イメージ 無効イメージ コメント
設定 設定有効イメージ 設定無効イメージ 無効イメージは実際には表示されません


ツールバーに「設定」ボタンを追加します。 「設定」ツールバー追加

ここで設定ボタン以降のツールバーのImageIndexがひとつづつずれます。プログラム中でImageIndexを使用しているGoDivideMNUClick関数とOnDivideTRDTerminate関数に変更を加える必要があります。

改造GoDivideMNUClick関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::GoDivideMNUClick(TObject *Sender)
{
// 分割実行チェック
    :

// 分割リスト作成
    :

// 分割スレッド生成
    :

// 分割実行中画面設定
    GoDivideMNU->Caption = "分割中断(&D)";            // 分割実行→中断メニュー変更
    GoDivideMNU->OnClick = StopDivideMNUClick;        // 分割中断コールバック登録
    GoDivideBTN->ImageIndex = 4;                      // 分割実行→中断ボタン変更
    GoDivideBTN->OnClick = StopDivideMNUClick;        // 分割中断コールバック登録
    GoDivideBTN->Hint = "分割中断";                   // 分割中断ボタンヒント登録
    DividePRG->Position = 0;                          // 分割状況プログレスバー初期化
    DividePRG->Visible = true;                        // 分割状況プログレスバー表示
    StatusBAR->Visible = false;                       // ステータスバー非表示

// 分割スレッド実行
    :
}
//---------------------------------------------------------------------------

改造OnDivideTRDTerminate関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::OnDivideTRDTerminate(TObject *Sender)
{
// 分割完了報告
    :

// 分割開始画面設定
    ListVEW->Selected = NULL;                       // 分割中ファイル選択消去
    GoDivideMNU->Caption = "分割実行(&D)";          // 分割中断→開始メニュー変更
    GoDivideMNU->OnClick = GoDivideMNUClick;        // 分割実行コールバック登録
    GoDivideBTN->ImageIndex = 3;                    // 分割中断→実行ボタン変更
    GoDivideBTN->OnClick = GoDivideMNUClick;        // 分割実行コールバック登録
    GoDivideBTN->Hint = "分割実行";                 // 分割実行ボタンヒント登録
    DividePRG->Visible = false;                     // 分割状況プログレスバー非表示
    StatusBAR->Visible = StatusBarMNU->Checked;     // ステータスバー表示

    delete DivideFiles;                             // コピー分割ファイルリスト解放
    DivideFiles = NULL;                             // コピー分割ファイルリストなし
    DivideTRD = NULL;                               // 分割スレッドなし
}
//---------------------------------------------------------------------------

では、設定メニューおよび設定ボタンのコールバック関数をプログラミングします。コールバック関数では設定パラメータに設定項目をセットし、設定画面の実行関数を呼び出します。設定画面でOKボタンが押されると実行関数trueを返すので、設定パラメータに従ってそれぞれのコントロールを更新します。ここで、若干の注意が必要です。 メニュー、ツールバー、ステータスバーの表示更新を行うためには、それぞれのコールバック関数に対する機能追加が必要です。コールバック関数にはイベントが発生したコントロール(MenuMNU、ToolBAR、StatusBAR)がSenderとして引き渡されます。 とします。

SetupMNUClick関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::SetupMNUClick(TObject *Sender)
{
    KotoParam.ViewFont         = ListVEW->Font;         // 分割一覧フォント(オブジェクトポインタ)設定
    KotoParam.BGColor          = ListVEW->Color;        // 分割一覧背景色設定
    KotoParam.MenuVisible      = (MainWND->Menu!=NULL); // メニュー表示状態設定
    KotoParam.ToolBarVisible   = ToolBAR->Visible;      // ツールバー表示状態設定
    KotoParam.StatusBarVisible = StatusBAR->Visible;    // ステータスバー表示状態設定

    if (SetupDLG->Execute(this, &KotoParam)){                // 設定実行→OKボタンが押されたら
        ListVEW->Color = KotoParam.BGColor;                  // 背景色設定
        MenuMNU->Checked = KotoParam.MenuVisible;            // メニュー表示設定
        ToolBarMNU->Checked = KotoParam.ToolBarVisible;      // ツールバー表示設定
        MenuBarMNUClick(NULL);                               // メニュー・ツールバー表示更新
        StatusBarMNU->Checked = KotoParam.StatusBarVisible;  // ステータスバー表示設定
        StatusBarMNUClick(NULL);                             // ステータスバー表示更新
    }
}
//---------------------------------------------------------------------------

改造MenuBarMNUClick関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::MenuBarMNUClick(TObject *Sender)
{
    TMenuItem *MNU = (TMenuItem*)Sender;    // メニューオブジェクト取得
    if (Sender!=NULL){      // メニュー選択
        MNU->Checked = (!MNU->Checked);         // メニューチェックの反転
        if (!MNU->Checked){
            if (MNU->Name == "MenuMNU")    ToolBarMNU->Checked = true;
            if (MNU->Name == "ToolBarMNU") MenuMNU->Checked = true;
        }
    }
    if (MenuMNU->Checked) MainWND->Menu = MainMNU;    // メニュー表示切替え
    else                  MainWND->Menu = NULL;
    ToolBAR->Visible = ToolBarMNU->Checked;        // ツールバー表示切替え

    SeparateBVL->Visible = MenuMNU->Checked && ToolBarMNU->Checked;  // ツールバー区切り表示
}
//---------------------------------------------------------------------------

改造StatusBarMNUClick関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::StatusBarMNUClick(TObject *Sender)
{
    TMenuItem *MNU = (TMenuItem*)Sender;            // メニューオブジェクト取得
    if (MNU!=NULL) MNU->Checked = (!MNU->Checked);  // メニューが選択された場合はチェック反転
    StatusBAR->Visible = StatusBarMNU->Checked;     // ステータスバー表示切替え
}
//---------------------------------------------------------------------------
以上で設定に関するプログラミングは完了です。


設定状態の保存

メニュー、ツールバー、ステータスバーの表示状態、常に前に表示、表示フォントは再び寿分割を起動した時にも有効にすると便利です(有効にするのが当たり前です)。同時に起動位置の指定は再び寿分割を起動したときに有効にする設定項目です。起動位置指定の時も述べたように、私はなるべくレジストリを使わずに、初期化ファイルを使うようにしています。初期化ファイルと言ってもファイル操作をするのではなく、VCLでは専用のTIniFileクラスを利用します。

まず初期化ファイル構成を設計します。初期化ファイルはセクションとキーで分類された単純なテキストファイルです。寿分割の初期化ファイル構成は他のDDTソフトウェアの全くの転用です。DDTソフトウェアではセクション名はmain.hに定義しています。キー名はソフトウェアそれぞれの個所で個別に指定しています。

セクション キー 内容
View Menu 論理値 true=表示 / false=非表示
ToolBar 論理値 true=表示 / false=非表示
StatusBar 論理値 true=表示 / false=非表示
Font Charset 整数 文字コード
Name 文字列 フォント名
Size 整数 フォントサイズ
Style 文字列 フォントスタイル、'B'=ボールド、'I'=イタリック、'U'=下線、'S'=打ち消し、各文字の連結(0〜4文字)
Color 整数 文字色、-1=システム色、他=TColor値
BGColor 整数 背景色、-1=システム色、他=TColor値
Position Position 文字列 起動位置、'LU'=左上、'LL'=左下、'RU'=右上、'RL'=右下、'PP'=前回の位置、'NA'=管理しない
Width 整数 クライアント画面幅[pixel]
Height 整数 クライアント画面高さ[pixel]
Left 整数 画面左座標[pixel]
Top 整数 画面上座標[pixel]
OnTop 論理値 true=常に前に表示 / false=通常表示

初期化ファイル作成

寿分割の起動時にFormCreate関数内で初期化ファイルから設定状態を読み込み、終了時に設定状態を初期化ファイルに書き込みます。寿分割を初めて起動した場合には初期化ファイルはありませんので、自動作成します。初期化ファイルは標準に則りアプリケーションと同一フォルダに、アプリケーション名の拡張子を'ini'に変えて作成します。初期化ファイル名(パスを除く)とセクション名をmain.hに登録します。
#define dfIniFileName "kotocut.ini"
#define ViewSection "View"
#define FontSection "Font"
#define PositionSection "Position"

改造FormCreate関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::FormCreate(TObject *Sender)
{
// 初期設定
    AnsiString IniFilePath = ExtractFilePath(Application->ExeName) + dfIniFileName;  // 初期化ファイル名作成
    if (!FileExists(IniFilePath)) CreateIniFile(IniFilePath);   // 初期化ファイルがない場合は自動作成
    TIniFile *IniFile = new TIniFile(IniFilePath);              // 初期化ファイル取得
    StyleWindow(IniFile);        // ウィンド再現(フォント、位置、コントロール表示)
    delete IniFile;              // 初期化ファイル終了

    :
}
//---------------------------------------------------------------------------

初期化ファイル作成は画面の各コントロールの状態から初期化ファイルの各値を設定します。唯一次回の起動時位置だけは画面上のコントロールでは決まりませんので、デフォルトは「管理しない」としておきます。

CreateIniFile関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::CreateIniFile(AnsiString FileName)
{
    TIniFile *IniFile = new TIniFile(FileName);    // 初期化ファイル作成

    IniFile->WriteBool(ViewSection, "Menu", MenuMNU->Checked);            // メニュー表示・非表示設定
    IniFile->WriteBool(ViewSection, "ToolBar", ToolBarMNU->Checked);      // ツールバー表示・非表示設定
    IniFile->WriteBool(ViewSection, "StatusBar", StatusBarMNU->Checked);  // ステータスバー表示・非表示設定

    AnsiString FontStyle;               // フォントスタイル文字列('B'+'I'+'U'+'S')
    IniFile->WriteInteger(FontSection, "Charset", ListVEW->Font->Charset);       // 文字コード設定
    IniFile->WriteString(FontSection, "Name", (AnsiString)ListVEW->Font->Name);  // フォント名設定
    IniFile->WriteInteger(FontSection, "Size", ListVEW->Font->Size);             // フォントサイズ設定
    if (ListVEW->Font->Style.Contains(fsBold))      FontStyle += "B";        // ボールドフォントスタイル文字作成
    if (ListVEW->Font->Style.Contains(fsItalic))    FontStyle += "I";        // イタリックフォントスタイル文字作成
    if (ListVEW->Font->Style.Contains(fsUnderline)) FontStyle += "U";        // 下線フォントスタイル文字作成
    if (ListVEW->Font->Style.Contains(fsStrikeOut)) FontStyle += "S";        // 打ち消しフォントスタイル文字作成
    IniFile->WriteString(FontSection, "Style", FontStyle);                       // フォントスタイル設定
    int ColorValue;                    // 色値
    if (ListVEW->Font->Color==clWindowText) ColorValue = -1;                          // システムフォント色
    else                                    ColorValue = (int)ListVEW->Font->Color;   // カスタムフォント色
    IniFile->WriteInteger(FontSection, "Color", ColorValue);                              // フォント色値設定
    if (ListVEW->Color==clWindow) ColorValue = -1;                                    // システム背景色
    else                          ColorValue = (int)ListVEW->Color;                   // カスタム背景色
    IniFile->WriteInteger(FontSection, "BGColor", ColorValue);                            // 背景色値設定

    IniFile->WriteString(PositionSection, "Position", "NA");                  // ウィンド位置設定→管理しない
    IniFile->WriteInteger(PositionSection, "Width", MainWND->ClientWidth);    // ウィンド幅(クライアント幅)設定
    IniFile->WriteInteger(PositionSection, "Height", MainWND->ClientHeight);  // ウィンド高さ(クライアント高さ)設定
    IniFile->WriteInteger(PositionSection, "Left", MainWND->Left);            // ウィンド左位置設定
    IniFile->WriteInteger(PositionSection, "Top", MainWND->Top);              // ウィンド上位置設定
    IniFile->WriteBool(PositionSection, "OnTop", StayOnTopMNU->Checked);      // 常に前に表示設定

    delete IniFile;        // 初期化ファイル終了
}
//---------------------------------------------------------------------------

初期化ファイル読込み

初期化ファイルの設定情報を取得し、メイン画面に反映します。メニュー、ツールバー、ステータスバーの表示/非表示取得および更新、ウィンド位置の取得および更新、フォント情報の取得および更新を行います。

StyleWindow関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::StyleWindow(TIniFile *IniFile)
{
    MenuMNU->Checked      = IniFile->ReadBool(ViewSection, "Menu", MenuMNU->Checked);            // メニュー表示取得
    ToolBarMNU->Checked   = IniFile->ReadBool(ViewSection, "ToolBar", ToolBarMNU->Checked);      // ツールバー表示取得
    StatusBarMNU->Checked = IniFile->ReadBool(ViewSection, "StatusBar", StatusBarMNU->Checked);  // ステータスバー表示取得
    MenuBarMNUClick(NULL);          // メニュー・ツールバー表示更新
    StatusBarMNUClick(NULL);        // ステータスバー表示取得

    AnsiString WinPos;    // ウィンド位置文字列('LU'/'LL'/'RU'/'RL'/'PP'/'NA')
    WinPos = IniFile->ReadString(PositionSection, "Position", "NA");    // ウィンドスタイル文字列取得
    MainWND->ClientWidth  = IniFile->ReadInteger(PositionSection, "Width", MainWND->ClientWidth);     // ウィンド幅取得
    MainWND->ClientHeight = IniFile->ReadInteger(PositionSection, "Height", MainWND->ClientHeight);   // ウィンド高さ取得

    StayOnTopMNU->Checked = IniFile->ReadBool(PositionSection, "OnTop", StayOnTopMNU->Checked);       // 常に前に表示メニュー取得
    StayOnTopBTN->Down    = StayOnTopMNU->Checked;                 // 常に前に表示ボタン設定
    if (StayOnTopMNU->Checked) FormOnTop(MainWND->Handle);         // 常に前に表示
    else                       FormNonTop(MainWND->Handle);        // 通常表示

    if (WinPos=="NA") KotoParam.WinLocation = WL_NA;    // 管理しない
    if (WinPos=="PP") KotoParam.WinLocation = WL_PP;    // 前回の位置
    if (WinPos=="LU") KotoParam.WinLocation = WL_LU;    // 左上
    if (WinPos=="LL") KotoParam.WinLocation = WL_LL;    // 左下
    if (WinPos=="RU") KotoParam.WinLocation = WL_RU;    // 右上
    if (WinPos=="RL") KotoParam.WinLocation = WL_RL;    // 右下

    switch (KotoParam.WinLocation){
        case WL_PP:      // 前回の位置
            MainWND->Left = IniFile->ReadInteger(PositionSection, "Left", (Screen->Width - MainWND->Width)/2);  // ウィンド左位置取得
            MainWND->Top  = IniFile->ReadInteger(PositionSection, "Top", (Screen->Height - MainWND->Height)/2);  // ウィンド左位置取得
            break;
        case WL_LU:     // 左上
        case WL_LL:     // 左下
        case WL_RU:     // 右上
        case WL_RL:     // 右下
            MoveToCorner(KotoParam.WinLocation);    // 画面四隅ウィンド位置移動
            break;
    }

    AnsiString FontStyleStr;    // フォントスタイル文字列('B'+'I'+'U'+'S')
    TFont* StyleFont = new TFont;   // フォントオブジェクトインスタンス
    int ColorValue;                 // 色値

    StyleFont->Assign(ListVEW->Font);    // 分割ファイル一覧
    StyleFont->Charset = (TFontCharset)(IniFile->ReadInteger(FontSection,"Charset", ANSI_CHARSET));   // 文字コード取得
    StyleFont->Name = (TFontName)(IniFile->ReadString(FontSection, "Name", "Arial"));                 // フォント名取得
    StyleFont->Size = IniFile->ReadInteger(FontSection, "Size", 10);                                  // フォントサイズ取得
    TFontStyles FontStyles;         // フォントスタイルデータ
    FontStyles.Clear();             // フォントスタイルデータクリア
    FontStyleStr = IniFile->ReadString(FontSection, "Style", "");  // フォントスタイル文字列取得
    if (FontStyleStr.Pos("B")>0) FontStyles << fsBold;         // ボールドフォント取得
    if (FontStyleStr.Pos("I")>0) FontStyles << fsItalic;       // イタリックフォント取得
    if (FontStyleStr.Pos("U")>0) FontStyles << fsUnderline;    // 下線フォント取得
    if (FontStyleStr.Pos("S")>0) FontStyles << fsStrikeOut;    // 打ち消しフォント取得
    StyleFont->Style = FontStyles;  // フォントスタイル設定
    ColorValue = IniFile->ReadInteger(FontSection, "Color", -1);   // フォント色値取得
    if (ColorValue==-1) StyleFont->Color = clWindowText;       // システムフォント色
    else                StyleFont->Color = (TColor)ColorValue; // カスタムフォント色
    ListVEW->Font->Assign(StyleFont);                          // フォント割り当て
    SendMessage(ListVEW->Handle, WM_SETFONT, (WPARAM)StyleFont->Handle, MAKELPARAM(TRUE, 0));  // フォント更新

    ColorValue = (TColor)IniFile->ReadInteger(FontSection, "BGColor", -1);  // 背景色値取得
    if (ColorValue==-1) ListVEW->Color = clWindow;                      // システム背景色
    else                ListVEW->Color = (TColor)ColorValue;            // カスタム背景色
}
//---------------------------------------------------------------------------

ウィンド列挙情報を元に、ウィンド位置を画面四隅に移動します。

MoveToCorner関数

/---------------------------------------------------------------------------
void __fastcall TMainWND::MoveToCorner(enWINLOCATION WinLocation)
{
    RECT DeskTopRect;    // デスクトップ矩形領域
    int x, y;            // 移動先左上位置

// タスクバーを除くデスクトップ領域取得
    ::SystemParametersInfo(SPI_GETWORKAREA,0,&DeskTopRect,0);

// ウィンド位置
//  1=左上, 2=左下, 3=右上, 4=右下
    switch (WinLocation){
        case WL_LU:     // 左上
            x = DeskTopRect.left;
            y = DeskTopRect.top;
            break;
        case WL_LL:     // 左下
            x = DeskTopRect.left;
            y = DeskTopRect.bottom - MainWND->Height;
            break;
        case WL_RU:     // 右上
            x = DeskTopRect.right  - MainWND->Width;
            y = DeskTopRect.top;
            break;
        case WL_RL:     // 右下
            x = DeskTopRect.right  - MainWND->Width;
            y = DeskTopRect.bottom - MainWND->Height;
            break;
    }
    MainWND->Left = x;
    MainWND->Top  = y;
}
//---------------------------------------------------------------------------

初期化ファイル更新

寿分割の終了時に設定状態を初期化ファイルに書きこみます。

改造FormCloseQuery関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::FormCloseQuery(TObject *Sender, bool &CanClose)
{
    Application->HelpCommand(HELP_QUIT, 0);      // ヘルプを閉じる

    AnsiString IniFilePath = ExtractFilePath(Application->ExeName) + dfIniFileName;  // 初期化ファイル名作成
    TIniFile *IniFile = new TIniFile(IniFilePath);    // 初期化ファイル取得
    WriteIniFile(IniFile);      // 設定状態保存
    delete IniFile;             // 初期化ファイル終了
}
//---------------------------------------------------------------------------
初期化ファイルに設定状態を書きこみます。

WriteIniFile関数

//---------------------------------------------------------------------------
void __fastcall TMainWND::WriteIniFile(TIniFile *IniFile)
{
    IniFile->WriteBool(ViewSection, "Menu", MenuMNU->Checked);            // メニュー表示・非表示設定
    IniFile->WriteBool(ViewSection, "ToolBar", ToolBarMNU->Checked);      // ツールバー表示・非表示設定
    IniFile->WriteBool(ViewSection, "StatusBar", StatusBarMNU->Checked);  // ステータスバー表示・非表示設定

    AnsiString FontStyle;               // フォントスタイル文字列('B'+'I'+'U'+'S')
    IniFile->WriteInteger(FontSection, "Charset", ListVEW->Font->Charset);       // 文字コード設定
    IniFile->WriteString(FontSection, "Name", (AnsiString)ListVEW->Font->Name);  // フォント名設定
    IniFile->WriteInteger(FontSection, "Size", ListVEW->Font->Size);             // フォントサイズ設定
    if (ListVEW->Font->Style.Contains(fsBold))      FontStyle += "B";        // ボールドフォントスタイル文字作成
    if (ListVEW->Font->Style.Contains(fsItalic))    FontStyle += "I";        // イタリックフォントスタイル文字作成
    if (ListVEW->Font->Style.Contains(fsUnderline)) FontStyle += "U";        // 下線フォントスタイル文字作成
    if (ListVEW->Font->Style.Contains(fsStrikeOut)) FontStyle += "S";        // 打ち消しフォントスタイル文字作成
    IniFile->WriteString(FontSection, "Style", FontStyle);                       // フォントスタイル設定
    int ColorValue;                    // 色値
    if (ListVEW->Font->Color==clWindowText) ColorValue = -1;                          // システムフォント色
    else                                    ColorValue = (int)ListVEW->Font->Color;   // カスタムフォント色
    IniFile->WriteInteger(FontSection, "Color", ColorValue);                              // フォント色値設定
    if (ListVEW->Color==clWindow) ColorValue = -1;                                    // システム背景色
    else                          ColorValue = (int)ListVEW->Color;                   // カスタム背景色
    IniFile->WriteInteger(FontSection, "BGColor", ColorValue);                            // 背景色値設定

    AnsiString WinPos;    // ウィンド位置文字列('LU'/'LL'/'RU'/'RL'/'PP'/'NA')
    switch (KotoParam.WinLocation){
        case WL_NA: WinPos = "NA";  break;  // 管理しない
        case WL_PP: WinPos = "PP";  break;  // 前回の位置
        case WL_LU: WinPos = "LU";  break;  // 左上
        case WL_LL: WinPos = "LL";  break;  // 左下
        case WL_RU: WinPos = "RU";  break;  // 右上
        case WL_RL: WinPos = "RL";  break;  // 右下
    }
    IniFile->WriteString(PositionSection, "Position", WinPos);                // ウィンド位置設定
    IniFile->WriteInteger(PositionSection, "Width", MainWND->ClientWidth);    // ウィンド幅(クライアント幅)設定
    IniFile->WriteInteger(PositionSection, "Height", MainWND->ClientHeight);  // ウィンド高さ(クライアント高さ)設定
    IniFile->WriteInteger(PositionSection, "Left", MainWND->Left);            // ウィンド左位置設定
    IniFile->WriteInteger(PositionSection, "Top", MainWND->Top);              // ウィンド上位置設定
    IniFile->WriteBool(PositionSection, "OnTop", StayOnTopMNU->Checked);      // 常に前に表示設定
}
//---------------------------------------------------------------------------


「今すぐ移動」ボタン

設定画面からのウィンド移動

最後に、設定画面の「今すぐ移動」ボタンの処理をプログラミングします。既に設定画面でボタンが押された時のコールバック関数を作成しています。この関数からFDM_MOVETOCORNERメッセージが発行されますので、メイン画面側ではこのメッセージ処理関数を追加します。実際にウィンドを移動する処理は、既にMoveToCorner関数として作成済みですので、メッセージ処理関数はメッセージを解読し、この関数を呼び出すだけです。メッセージ構造体のWParamに位置情報が入っています。処理は1行で済みますので、メイン画面クラスのプライベート関数でインライン定義したいと思います。同時にメッセージハンドラにも追加します。
//---------------------------------------------------------------------------
class TMainWND : public TForm
{
    :
private:    // ユーザー宣言
    :
    void __fastcall OnMoveToCorner(TMessage &Message){ MoveToCorner((enWINLOCATION)Message.WParam); }
    :

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(FDM_REPORTDIVIDING, TMessage, OnReportDividing)
MESSAGE_HANDLER(FDM_NOWRITESPACE, TMessage, OnNoWriteSpace)
MESSAGE_HANDLER(FDM_MOVETOCORNER, TMessage, OnMoveToCorner)
MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, OnDropFiles)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------


バグ発見!

分割メニューを見ていてバグを発見しました。第3話のメニュー設計で「720K」と「分割実行」のホットキーが'D'と重複していました。「分割実行」のホットキーを'G'に変更し、バグを修正します。

Caption Name 内容
「分割(D)」 DivideMNU 分割操作に関するメニュー。
  :  
  「分割実行(G)」 GoDivideMNU 分割を実行。


もうひとつバグの様なものを発見しました。均等分割と分割実行の、分割メニューとツールバーの並びが違っています。バグだとも言い難いのですが、私自身が気にするタチですので、ツールバーを修正します。BCBのIDEでツールバー上のボタンをドラッグアンドドロップするだけで、バグ修正は完了です。
誤り:誤りツールバー

修正:修正ツールバー


11話と12話に渡ってDDTらしい機能を追加しました。実際は全ての機能がDDTソフトウェアの転用ですから、プログラムの修正は1時間程度で終わっています。ヘルプの修正も10分程度ですから、この空間に説明を書くのに費やした時間のほうがはるかに多いです。実際に説明を書いていても「こんなことにこんなに説明が必要なのか」と次分自身で改めて思いなおした程です。説明がわかりにくい点が多々あったと思いますが、ご勘弁ください。

こちらから今回作成したBCBのプロジェクト一式をダウンロードできます(ヘルプ一式は含みません)。プロジェクトダウンロード(31,421バイト) BCBのバージョン3、4、5でビルドできます。BCBバージョン5ではの修正を行ってください。ヘルププロジェクト一式のダウンロードはこちら。ヘルプダウンロード(16,690バイト) 参考にしてください。

次回は分割リカバー機能を追加したいと思います。フロッピーに分割したのに、転送先のPCでディスク読込みエラーが発生した。再度分割ファイルを作りたいけど、分割を最初からやり直すのは面倒だ。そんな時に分割リカバーを行います。分割リカバーとは指定した分割ファイルひとつや、それ以降の分割ファイルのみを分割先に作成する機能です。ポップアップメニューや分割スレッドに対する改造もありそうです。お楽しみに。

今回のプログラミング行数: 209行
今回までのプログラミング行数: 1,011行


目次に戻る目次に戻る トップに戻るトップに戻る