仅对月份和年份使用 TMonthCalendar
Use TMonthCalendar for months and years only
我的意思是我想让日历始终显示在月视图中,如下所示:
预期的 TMonthCalendar 视图:
所以当我点击一个月时,它不会显示该月的日期,而是停留在这个屏幕上并调用事件。
在 Vista 之前,底层 Win32 MonthCal control that TMonthCalendar
包装根本没有视图的概念,所以你不能做你在 XP 和更早版本中所要求的,除非你找到支持的第 3 方日历你想要那些 Windows 版本。
但是,在 Vista 及更高版本中,底层的 MonthCal 控件是视图感知的(但 TMonthCalendar
本身不是)。当用户更改活动视图时,您可以手动发送 MCM_SETCURRENTVIEW
message to the TMonthCalendar
's HWND
to set its initial view to MCMV_YEAR
, and subclass its WindowProc
property to intercept CN_NOTIFY
messages (the VCL's wrapper for WM_NOTIFY
) looking for the MCN_VIEWCHANGE
通知。您无法将控件锁定到特定视图,但您可以在用户将活动视图从年视图更改为月视图时做出反应,然后您可以根据需要将日历重置回年视图。
例如:
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);
}
}
}
}
如果您使用的是 C++Builder 10.1 Berlin 或更高版本,请查看较新的 TCalendarView
and TCalendarPicker
组件。它们都有一个 DisplayMode
属性,您可以为当前视图设置为 TDisplayMode::dmYear
,还有一个 On(Calendar)ChangeView
事件来响应用户的视图更改。
我的意思是我想让日历始终显示在月视图中,如下所示:
预期的 TMonthCalendar 视图:
所以当我点击一个月时,它不会显示该月的日期,而是停留在这个屏幕上并调用事件。
在 Vista 之前,底层 Win32 MonthCal control that TMonthCalendar
包装根本没有视图的概念,所以你不能做你在 XP 和更早版本中所要求的,除非你找到支持的第 3 方日历你想要那些 Windows 版本。
但是,在 Vista 及更高版本中,底层的 MonthCal 控件是视图感知的(但 TMonthCalendar
本身不是)。当用户更改活动视图时,您可以手动发送 MCM_SETCURRENTVIEW
message to the TMonthCalendar
's HWND
to set its initial view to MCMV_YEAR
, and subclass its WindowProc
property to intercept CN_NOTIFY
messages (the VCL's wrapper for WM_NOTIFY
) looking for the MCN_VIEWCHANGE
通知。您无法将控件锁定到特定视图,但您可以在用户将活动视图从年视图更改为月视图时做出反应,然后您可以根据需要将日历重置回年视图。
例如:
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);
}
}
}
}
如果您使用的是 C++Builder 10.1 Berlin 或更高版本,请查看较新的 TCalendarView
and TCalendarPicker
组件。它们都有一个 DisplayMode
属性,您可以为当前视图设置为 TDisplayMode::dmYear
,还有一个 On(Calendar)ChangeView
事件来响应用户的视图更改。