2014-02-09 3 views
1

В настоящее время я создаю программу с Delphi (Professional, Version 7.0; Build 4.453).Delphi TDateTime Смелые дни с TMonthCalendar

Первоначально, я хотел бы выделить некоторые даты в раскрывающемся календаре TDateTimePicker; но я быстро обнаружил, что не могу - поэтому я пытаюсь пересечь TMonthCalendar (с которым вы можете делать смелые даты) поверх раскрывающегося календаря TDateTimePicker (просто, правильно?)

Но не так быстро : каким-то образом, раскрывающийся календарь TDateTimePicker всегда отображается в верхней части моего TMonthCalendar. Я бы хотел, чтобы на экране появился TMonthCalendar.

Вот что я понял, что я мог сделать:

  1. Позиция TMonthCalendar под TDateTimePicker (где его выпадающий обычно показывают)
  2. сделать видимым TMonthCalendar на OnDropDown событии TDateTimePicker в
  3. Скрыть TMonthCalendar на OnCloseUp событии TDateTimePicker в

Вот что происходит:

  1. Когда я нажимаю на ниспадающего треугольник на TDateTimePicker, то TMonthCalendar становится видимым (яй!)
  2. Но календарь TDateTimePicker выпадающий всегда превалирует (TMonthCalendar всегда под выпадающего меню)
  3. Поэтому я могу» t ничего не делайте с TMonthCalendar, пока я не выбрал дату в выпадающем списке TDateTimePicker (я даже не вижу полужирных дат, потому что TMonthCalendar находится внизу).

Вот что я пробовал:

  • TMonthCalendar.Show на OnDropDown случае TDateTimePicker (это должно принести все, что шоу-е изд к началу). Но это ничего не делает.
  • Do DateMode: dmDropDown -> DateMode: dmUpDown на OnDropDown от TDateTimePicker (таким образом отключив раскрывающийся календарь). Но у этого есть проблемы, так как нажатие в любом месте MonthCalendar (включая кнопки «Месяц изменения по обе стороны») сделает MonthCalendar невидимым (я делаю «если MonthCalendar.Visible, то видимо: = false» в MonthCalendarOnClick)

Я знаю, что решение, вероятно, простое, но я не могу придумать, как это сделать. Пока что несколько идей, которые я придумал, не работают :( Итак, если вы можете придумать способ сделать то, что я хочу, пожалуйста, помогите мне.

Спасибо заранее! :)

+0

Не идите по этой дороге. «TMonthCalendar» - это тонкая оболочка вокруг календаря Windows32. 'TDateTimePicker' - это тонкая оболочка вокруг элемента управления выбора времени даты Win32, который внутренне создает календарь в месяц, когда это необходимо. Возможно (и не все так сложно) получить доступ к этому внутреннему календарю месяца и делать с ним все, что вы хотите, включая все, что вы можете сделать с помощью «TMonthCalendar». Просто посмотрите, как это делает «TMonthCalendar», а затем сделайте то же самое для своего собственного контроля. (Я бы опубликовал пример, но я не в системе, где я мог бы проверить его прямо сейчас.) – hvd

+0

Этот подход никогда не даст хороших результатов –

+0

Возможный дубликат, ['Как вы программно отмечаете дату в Delphi's Календарь TDateTimePicker? '] (Http://stackoverflow.com/q/7210565/576719). –

ответ

2

Вся посылка на ваш вопрос неверна. Вполне возможно изменить форматирование календаря месяца, прикрепленного к элементу выбора даты.

Решение должно отвечать на уведомление MCN_GETDAYSTATE. Это уведомление отправляется только элементам управления, которые имеют стиль MCS_DAYSTATE. Чтобы убедиться, что этот стиль применяется, даже перед воссозданием окна, вам необходимо применить его в переопределенном методе CreateWnd.

Например, здесь я делаю это с вставкой:

type 
    TDateTimePicker = class(Vcl.ComCtrls.TDateTimePicker) 
    protected 
    procedure CreateWnd; override; 
    procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY; 
    end; 

procedure TDateTimePicker.CreateWnd; 
begin 
    inherited; 
    DateTime_SetMonthCalStyle(WindowHandle, DateTime_GetMonthCalStyle(WindowHandle) or MCS_DAYSTATE); 
end; 

procedure TDateTimePicker.WMNotify(var Message: TWMNotify); 
var 
    i: integer; 
    NMDayState: PNMDayState; 
begin 
    inherited; 
    case Message.NMHdr.code of 
    MCN_GETDAYSTATE: 
    begin 
     NMDayState := PNMDayState(Message.NMHdr); 
     for i := 0 to NMDayState.cDayState-1 do begin 
     NMDayState.prgDayState[i] := $FFFFFFFF; // every day is bold 
     end; 
    end; 
    end; 
end; 

enter image description here

Или с битовой маской $AAAAAAAA иметь только четные дни полужирный:

enter image description here

+0

Как отмечалось в комментариях к ответу на другой вопрос (вопрос о том, что этот вопрос должен быть закрыт как дубликат), это не будет работать на XP. Можно заставить его работать на XP, получив дескриптор окна для содержащегося месячного календаря и изменив его стиль напрямую, в дополнение к (не вместо), используя 'DateTime_SetMonthCalStyle'. – hvd

+0

@ hvd ОК. Я думаю, что мы скоро начнем забывать о XP. К счастью. –

+2

Я не буду рассчитывать на то, что XP умрет, когда MS перестанет его поддерживать. Это просто, когда некоторые пользователи даже рассмотрят возможность обновления. Им может потребоваться несколько месяцев, чтобы они действительно это сделали, и я бы этого не хотел. – hvd

Смежные вопросы