So-net無料ブログ作成
検索選択

ポップアップするカレンダーコントロール [プログラミング]

何かのソフトで、日付を選択するコンボボックスって見たことないですか?
コンボボックスの[▼]ボタンを押すと、カレンダーが表示されるヤツ。

そんなのを作ってみました。
Visual C++ で 要MFC です。

コンボボックスに限らず、マウスの右ボタンクリックでも表示できるように、ポップアップ形式にしてあります。


// 【 PopupCalender.h 】
#pragma once

#include        <afxdtctl.h>

class PopupCalender : public CMonthCalCtrl
{
  protected:
    afx_msg void OnActivate(UINT, CWnd*, BOOL);
    afx_msg BOOL OnChange(NMHDR* pNotifyStruct, LRESULT* result);

  public:
    BOOL Create(CWnd*);
    void Popup(int, int);
    
    DECLARE_MESSAGE_MAP();
};
// 【 PopupCalender.cpp 】
#include        "PopupCalender.h"

BEGIN_MESSAGE_MAP(PopupCalender, CMonthCalCtrl)
    ON_WM_ACTIVATE()
    ON_NOTIFY_REFLECT_EX(MCN_SELECT, OnChange)
END_MESSAGE_MAP()

BOOL PopupCalender::OnChange(NMHDR* pNotifyStruct, LRESULT* result)
{
    ShowWindow(SW_HIDE);
    *result = 0;
    return FALSE;
}

void PopupCalender::OnActivate(UINT nState, CWnd*, BOOL)
{
    if (nState == WA_INACTIVE)
        ShowWindow(SW_HIDE);
}

BOOL PopupCalender::Create(CWnd* parent)
{
    ASSERT(!::IsWindow(m_hWnd));

    const BOOL result = CreateEx(0, MONTHCAL_CLASS, _T(""),
                                 WS_POPUP | WS_BORDER,
                                 CRect(0, 0, 0, 0), parent, NULL);
    // Createでは、WS_POPUP を指定できない

    if (result) {
        SizeMinReq(FALSE);
    }

    return result;
}

void PopupCalender::Popup(int x, int y)
{
    SetWindowPos(NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
}

使い方

カレンダーを表示したい画面のクラスCFrameWndCDialogの派生クラス)のメンバにPopupCalenderのインスタンスを追加する。

class MainForm : public CDialog
{
  private:
    PopupCalender calender_;

    (略)
};

OnCreateOnInitDialog辺りで、PopupCalenderCreateを呼び出す。引数は、カレンダーを表示したい画面(大抵は this

BOOL MainForm::OnInitDialog()
{
    (略)

    calender_.Create(this);

    (略)
}

マウスクリックかボタンクリックのイベントハンドラで、PopupCalenderPopupを呼び出す。引数は、カレンダーを表示したい座標(スクリーン座標で指定)

void MainForm::OnButton1()
{
    CPoint pos;
    ::GetCursorPos(&pos)

    calender_.Popup(pos.x, pos.y);
}

日付を選択した時のイベント用のハンドラを追加する。
この辺りは、CMonthCalCtrl のイベント通知ハンドラと一緒。

class MainForm : public CDialog
{
    (略)

    afx_msg void OnSelectCalender(NMHDR*, LRESULT*);

    // WM_NOTIFY メッセージ用のハンドラ
};
BEGIN_MESSAGE_MAP(MainForm, CDialog)
    (略)
    ON_NOTIFY(MCN_SELECT, 0, OnSelectCalender)
    // 2つ目の引数(コントロールIDを指定するところ)は、必ず「0」
    // 3つ目の引数(イベントハンドラのメソッド名)は、任意。
END_MESSAGE_MAP()

void MainForm::OnSelectCalender(NMHDR* hdr, LRESULT* result)
{
    NMSELCHANGE* item = reinterpret_cast(hdr);
    
    CTime time(item->stSelStart);
    // 選択した日付

    *result = 0;
}
[車(セダン)] 今日の一冊
ワルキューレ ヒトラー暗殺の二日間

ワルキューレ ヒトラー暗殺の二日間

  • 作者: スティ・ダレヤー
  • 出版社/メーカー: 原書房
  • 発売日: 2009/03/17
  • メディア: 単行本
誰もが思うけど、誰も言わないこと。
「この本を書いたのは『誰やー』」

タグ:VisualC++
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この記事のトラックバックURL:
※言及リンクのないトラックバックは受信されません。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。