前のページ次のページ上に戻るホーム BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework UNIVERSE 5.0

9.13. ダイアログ(応用編)

最適な大きさの取得方法や、一定時間経過後に自動的にダイアログを閉じる方法などについて解説します。

9.13.1. ダイアログに最適な大きさを取得する

図 9.37. 動作例

動作例

SFZMessageDialog クラスと SFZQuestionDialog クラスでは、SFYResponder::GetSuitableBound 関数のうち、引数の矩形を指定しない関数が例外的な動作を行います。

これらのクラスでは内部に複数行のテキストを表示するために、高さまたは幅のどちらかを固定しなければ最適な大きさを求められません。そこで、設定されている実領域の幅をヒント値として利用し最適な大きさを計算します。

引数を指定する関数では通常の動作を行い、実領域をあらかじめ設定する必要はありません。

引数を指定する関数と指定しない関数では、指定した矩形で高さを制限するかしないかの違いがあります。

例 9.64. 宣言

SFMTYPEDEFCLASS(USRApplication)
class USRApplication : public SFYApplication {
    SFMSEALCOPY(USRApplication)
private:
    SFZMessageDialogSmp _dialog;

    ...
private:
    SFCError Make(Void);
};

例 9.65. 実装

SFCError USRApplication::Make(Void)
{
    SFXRectangle rectangle;
    SFCError error(SFERR_NO_ERROR);

    if ((_dialog = SFZMessageDialog::NewInstance(&error)) != null) {
        error = _dialog->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {
            error = _dialog->SetIconImage(SFXPath("resource.bar"), IMAGE_ID);
            if (error == SFERR_NO_ERROR) {
                error = _dialog->SetMessageText("hello world\n\n"
                                                "0          \n"
                                                " 1         \n"
                                                "  2        \n"
                                                "   3       \n"
                                                "    4      \n"
                                                "     5     \n"
                                                "      6    \n"
                                                "       7   \n"
                                                "        8  \n"
                                                "         9 \n"
                                                "          0");
                if (error == SFERR_NO_ERROR) {
                    error = _dialog->SetButtonText("OK");
                    if (error == SFERR_NO_ERROR) {

                        // ヒント値を設定する
                        _dialog->SetRealBound(GetLocalBound().Deflate(10, 10));

                        // 矩形を指定せずにダイアログの最適な領域のサイズを取得する
                        rectangle.Set(_dialog->GetSuitableBound());

                        // ダイアログの最適な領域を画面の中央に配置する
                        rectangle.SnapCenterMiddle(GetLocalBound().GetCenterMiddle());

                        // ダイアログの実領域を設定する
                        _dialog->SetRealBound(rectangle);


                        // ダイアログの状態を「可視+活性+操作可能+フォーカス」にまとめて設定する
                        _dialog->SetState(true, true, true, true);

                        // ダイアログを最前面に移動する
                        _dialog->ToFront();
                    }
                }
            }
        }
    }
    return error;
}

9.13.2. ダイアログのタイマーを使用する

図 9.38. 動作例

動作例

ダイアログに内臓されたタイマーを使用すると、無操作状態で一定時間経過後に自動的にダイアログを閉じることができます。

一旦開始されたタイマーは、取り消したり巻き戻すことができます。

例 9.66. 宣言

SFMTYPEDEFCLASS(USRApplication)
class USRApplication : public SFYApplication {
    SFMSEALCOPY(USRApplication)
private:
    SFZMessageDialogSmp _dialog;

    ...
private:
    SFCError Make(Void);
};

例 9.67. 実装

SFCError USRApplication::Make(Void)
{
    SFXRectangle rectangle;
    SFCError error(SFERR_NO_ERROR);

    if ((_dialog = SFZMessageDialog::NewInstance(&error)) != null) {
        error = _dialog->SetParent(GetThis());
        if (error == SFERR_NO_ERROR) {
            error = _dialog->SetIconImage(SFXPath("resource.bar"), IMAGE_ID);
            if (error == SFERR_NO_ERROR) {
                error = _dialog->SetMessageText("hello world");
                if (error == SFERR_NO_ERROR) {
                    error = _dialog->SetButtonText("OK");
                    if (error == SFERR_NO_ERROR) {
                        rectangle.Set(_dialog->GetSuitableBound(GetLocalBound().Deflate(10, 10)));
                        rectangle.SnapCenterMiddle(GetLocalBound().GetCenterMiddle());
                        _dialog->SetRealBound(rectangle);
                        _dialog->SetState(true, true, true, true);
                        _dialog->ToFront();

                        // タイマーを 10 秒に設定する
                        _dialog->ScheduleTimer(10000);
                    }
                }
            }
        }
    }
    return error;
}