До Vista базовый элемент управления Win32 MonthCal , который TMonthCalendar
, не имеет вообще никаких представлений, поэтому вы не можете делать то, о чем просите в XP и ранее, если вы не найдете сторонний календарь, который поддерживает то, что вы хотите в этих версиях Windows.
Однако в Vista и более поздних версиях базовый элемент управления MonthCal учитывает представление (но само по себе TMonthCalendar
нет). Вы можете вручную отправить сообщение MCM_SETCURRENTVIEW
на TMonthCalendar
HWND
, чтобы установить его начальное представление на MCMV_YEAR
, и создать подкласс для его свойства WindowProc
для перехвата CN_NOTIFY
сообщений ( Оболочка VCL для WM_NOTIFY
) ищет уведомление 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
и TCalendarPicker
. Они оба имеют свойство DisplayMode
, которое можно установить на TDisplayMode::dmYear
для текущего представления, и событие On(Calendar)ChangeView
, чтобы реагировать на просмотр изменений пользователем.