仅在数月和数年内使用TMonthCalendar

时间:2019-03-19 17:43:32

标签: c++builder vcl c++builder-xe3

我的意思是我想使日历始终保持在月份视图中,像这样:

预期的TMonthCalendar视图:

image

因此,当我单击一个月时,它不显示该月中的日期,而是停留在此屏幕中并调用该事件。

1 个答案:

答案 0 :(得分:2)

在Vista之前,Win32 MonthCal control包装的基础TMonthCalendar根本没有视图的概念,因此除非找到第3个,否则您将无法在XP和更早版本中完成您所要求的操作派对日历,可在这些Windows版本上支持您想要的内容。

但是,在Vista和更高版本中,基本的MonthCal控件具有视图感知功能(但TMonthCalendar本身不是)。您可以手动向TMonthCalendar的{​​{1}}发送MCM_SETCURRENTVIEW消息,以将其初始视图设置为HWND,并将其MCMV_YEAR属性子类化以拦截{{ 1}}消息(WM_NOTIFY的VCL包装器)在用户更改活动视图时寻找MCN_VIEWCHANGE通知。您不能将控件锁定到特定视图,但是可以对用户将活动视图从“年”视图更改为“月”视图时做出反应,然后根据需要将日历重置回“年”视图。

例如:

WindowProc

CN_NOTIFY

如果您使用的是C ++ Builder 10.1 Berlin或更高版本,请查看较新的TCalendarViewTCalendarPicker组件。它们都具有class TMyForm : public TForm { __published: TMonthCalendar *MonthCalendar1; ... private: TWndMethod PrevMonthCalWndProc; void __fastcall MonthCalWndProc(TMessage &Message); ... public: __fastcall TMyForm(TComponent *Owner) ... }; 属性,您可以将其设置为当前视图的#include "MyForm.h" #include <Commctrl.h> #ifndef MCM_SETCURRENTVIEW #define MCMV_MONTH 0 #define MCMV_YEAR 1 #define MCM_SETCURRENTVIEW (MCM_FIRST + 32) #define MCN_VIEWCHANGE (MCN_FIRST - 4) // -750 typedef struct tagNMVIEWCHANGE { NMHDR nmhdr; DWORD dwOldView; DWORD dwNewView; } NMVIEWCHANGE, *LPNMVIEWCHANGE; #endif __fastcall TMyForm(TComponent *Owner) : TForm(Owner) { if (Win32MajorVersion >= 6) { SendMessage(MonthCalendar1->Handle, MCM_SETCURRENTVIEW, 0, MCMV_YEAR); PrevMonthCalWndProc = MonthCalendar1->WindowProc; MonthCalendar1->WindowProc = MonthCalWndProc; } } void __fastcall TMyForm::MonthCalWndProc(TMessage &Message) { PrevMonthCalWndProc(Message); if (Message.Msg == CN_NOTIFY) { if (reinterpret_cast<NMHDR*>(Message.LParam)->code == MCN_VIEWCHANGE) { LPNMVIEWCHANGE lpNMViewChange = static_cast<LPNMVIEWCHANGE>(Message.LParam); if ((lpNMViewChange->dwOldView == MCMV_YEAR) && (lpNMViewChange->dwNewView == MCMV_MONTH)) { // do something ... SendMessage(MonthCalendar1->Handle, MCM_SETCURRENTVIEW, 0, MCMV_YEAR); } } } } ,还有一个DisplayMode事件以对用户的视图更改做出反应。