答案 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或更高版本,请查看较新的TCalendarView
和TCalendarPicker
组件。它们都具有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
事件以对用户的视图更改做出反应。