アナログ時計操作クラス

HomeC++ Class Library[LIB-006]

 Visual C++ MFC 版ダウンロード AnalogClockMFC.zip (2006/03/18) 
 一般 C++ Win32SDK 版ダウンロード  AnalogClockSDK.zip (2006/03/25) 
※ 2006/03/25 基本ウィンドウ汎用化変更版

時間を指定する場合、その多くはエディットボックスによる数値入力やスピンボックスであったりします。
良くできているものでもデジタルクロック形式のものでしょう。

そこで漢の浪漫シリーズ第二弾(笑)として皆様にお送りするのはアナログ時計です。
あ、いや、別にシリーズって訳じゃないのですが妙に格好良いじゃありませんか、アナログ的なものって。

さて上記の画像は本クラスの標準スタイルです。
針の形状、大きさ、色などは WinXP のコントロールパネル→日付と時刻で表示されるアナログ時計に似せてあります。
しかしながら、本クラスは、表示のカスタマイズ性をかなり柔軟に指定できるように設計いたしました。

下記の時計表示はいずれも本クラスの表示設定パラメータを変更しただけです。



針の長さ・太さ・色・表示の ON/OFF、ルーラーの大きさ・色・表示の ON/OFF、背景色の指定など、
およそ考えられる全ての項目を設定可能としました。
針の描画がポリゴンなので自由変形が可能になっています。ポリゴン描画とはいっても Win32API と MFC しか使用していません。
針を掴んだかどうかは PtInRegion で実装しました。多角形とポイントの当たり判定はこれが最もお手軽です。
設定項目が多いとプログラムが大変ですよね。
そこで、本クラスの設定情報をプログラムリストとして出力する機能をサンプルに付けました。

見て分かるとおり、本クラスで設定可能なパラメータの全てが編集可能となっています。
元々は、機能テストのために作ったのですが、設定項目が増えて使いにくいと感じたので急遽プログラム出力機能を付けたものです。

このツールのおかげで、単にアナログ時計を表示させるだけなら、MFC の新規プロジェクト作成から始まって 10分もあれば時計を完成させることが出来ました。
ダウンロードアーカイブにサンプルとして入っている PopupAnalogClock というプロジェクトがそれです。
※ 高速に作るのが目的でしたので、こちらのサンプルはまともにコメントは入っていません。


このツールが上記のスタイルを再現するために出力したプログラムリストは下記の通りです。
コメントも自動で出力されています。


    // 下記変数宣言はメンバ変数としてヘッダファイルに記載する
    CAnalogClock* m_pClock;

    // アナログ時計をインスタンスする
    m_pClock = new CAnalogClock(this);

    // 時針スタイルの設定
    m_pClock->EnableHour(TRUE);
    m_pClock->SetLengthScaleHour(2.00f);
    m_pClock->SetGirthScaleHour(2.46f);
    m_pClock->SetColorHour(RGB(255,0,0));

    // 分針スタイルの設定
    m_pClock->EnableMinute(TRUE);
    m_pClock->SetLengthScaleMinute(2.00f);
    m_pClock->SetGirthScaleMinute(3.44f);
    m_pClock->SetColorMinute(RGB(0,128,255));

    // 秒針スタイルの設定
    m_pClock->EnableSecond(TRUE);
    m_pClock->SetLengthScaleSecond(1.44f);
    m_pClock->SetColorSecond(RGB(0,0,160));

    // 盤面スタイルの設定
    m_pClock->EnableBigRuler(TRUE, 10);
    m_pClock->EnableSmallRuler(TRUE, 5);
    m_pClock->EnableShadow(TRUE);
    m_pClock->SetColorBoard(RGB(236,233,216));
    m_pClock->SetColorBigRuler(RGB(255,128,64));
    m_pClock->SetColorSmallRuler(RGB(0,128,64));
    m_pClock->SetScale(0.50f);
    m_pClock->SetWindowPos(NULL, 0, 0, 418, 418, SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);

    // 操作モードの設定
    m_pClock->SetDirectMode(CAnalogClock::ETargetHand(3));
    m_pClock->EnableAutoUpdate(TRUE);


どうでしょうか?
ここまで出力されれば組み込みはさほど苦ではないでしょう。
多少、SetWindowPos あたりは修正しなければいけないかもしれませんが、
本クラスを使いたい人なら全く問題なく対応できると思っています。

さて、本来の目的、時刻の設定ですが、2モード用意してあります。
針を掴むモード(GripMode)、向きを直接指定するモード(DirectMode)です。
どちらの方式も一長一短がありますので、使用目的に応じて使い分けると良いでしょう。

リファレンス

  1. アナログ時計オブジェクトの作成

        CAnalogClock* m_pClock;
        m_pClock = new CAnalogClock(this):

    第一引数に親のウィンドウを指定してください。
    デフォルトでは、この親のクライアントサイズいっぱいにアナログ時計が表示されます。
    CAnalogClock は CWnd から派生していますので、必要に応じて SetWindowPos 等でサイズを変更してください。

    ※ あるいはスタティックコントロールを親としても良いでしょう。


  2. スタイルの設定

        ※ 時針スタイルの設定
        EnableHour(BOOL);                // 時針を表示するか(TRUEで表示)
        SetLengthScaleHour(float);       // 時針の長さ(1.0fでシステム標準)
        SetGirthScaleHour(float);        // 時針の太さ(1.0fでシステム標準)
        SetColorHour(COLORREF);          // 時針の色

        ※ 分針スタイルの設定
        EnableMinute(BOOL);              // 分針を表示するか(TRUEで表示)
        SetLengthScaleMinute(float);     // 分針の長さ(1.0fでシステム標準)
        SetGirthScaleMinute(float);      // 分針の太さ(1.0fでシステム標準)
        SetColorMinute(COLORREF);        // 分針の色

        ※ 秒針スタイルの設定
        EnableSecond(BOOL);              // 秒針を表示するか(TRUEで表示)
        SetLengthScaleSecond(float);     // 秒針の長さ(1.0fでシステム標準)
        SetColorSecond(COLORREF);        // 秒針の色

        ※ ルーラー(大)スタイルの設定
        EnableBigRuler(BOOL, int);       // 表示するか, ルーラーサイズ
        SetColorBigRuler(COLORREF);      // 大ルーラーの色

        ※ 小ルーラースタイルの設定
        EnableSmallRuler(BOOL, int);     // 表示するか, ルーラーサイズ
        SetColorSmallRuler(COLORREF);    // 小ルーラーの色

        ※ 盤面スタイルの設定
        EnableShadow(BOOL);              // 影を表示するか
        SetColorBoard(COLORREF);         // 盤面(背景)の色
        SetScale(float);                 // 全体の表示拡大率


  3. スタイルの取得(調査)

        ※ 時針の情報を取得する
        IsEnableHour();                  // 時針は表示されているか
        GetLengthScaleHour();            // 時針の長さを取得する(倍率)
        GetGirthScaleHour();             // 時針の太さを取得する(倍率)
        GetColorHour();                  // 時針の色を取得する

        ※ 分針の情報を取得する
        IsEnableMinute();                // 分針は表示されているか
        GetLengthScaleMinute();          // 分針の長さを取得する(倍率)
        GetGirthScaleMinute();           // 分針の太さを取得する(倍率)
        GetColorMinute();                // 分針の色を取得する

        ※ 秒針の情報を取得する
        IsEnableSecond();                // 秒針が表示されているか
        GetLengthScaleSecond();          // 秒針の長さを取得する(倍率)
        GetColorSecond();                // 秒針の色を取得する

        ※ 盤面の情報を取得する
        IsEnableBigRuler();              // 大ルーラーが表示されているか
        GetBigRulerSize();               // 大ルーラーサイズを取得する
        GetSmallRulerSize();             // 小ルーラーサイズを取得する
        IsEnableShadow();                // 影が表示されているか
        GetColorBoard();                 // 盤面色(背景色)を取得する
        GetColorBigRuler();              // 大ルーラー色を取得する
        GetColorSmallRuler();            // 小ルーラー色を取得する
        GetScale();                      // 全体の表示倍率を取得する

    Is〜 と命名された関数の戻り値は BOOL です。
    Get〜 と命名された関数の戻り値は intfloat です。
    ※ 倍率とあれば float です。


  4. 操作その他

        ※ 操作モードの設定
        SetGripMode();                   // 針を掴む時間指定とする
        SetDirectMode(ETargetHand);      // ダイレクト時間指定とする
        SelectHand(ETargetHand);         // 時間設定する針を指定する

    ETargetHand は、CAnalogClock の public で宣言されています。
    そのため、使用するには、CAnalogClock スコープを使用してください。
    例えば、分針を操作対象とする場合は…

    m_pClock->SetDirectMode(CAnalogClock::eTARGET_MINUTE);

    …等と記述します。

        ※ 操作モードの確認
        IsGripMode();                    // 針を掴む時間設定モードか
        IsDirectMode();                  // ダイレクト時間設定モードか
        GetTergetHand();                 // 対象時計針番号を取得する

    IsGridMode() を not すると IsDirectMode() と同じ事になります。
    好きな方を使ってください。

        ※ 時間の操作
        EnableAutoUpdate(BOOL);          // 時間を自動的に更新させるか
        GetTime();                       // 設定されている時間を取り出す
        SetTime(CTime);                  // 時間を設定する


  5. アナログ時計オブジェクトの削除

        delete m_pClock;
        m_pClock = NULL;


 Copyright 2005 VALGUS. All Rights Reserved.