BoldDays для TDateTimePicker?

Я использую Delphi7, и я хотел бы выделить несколько дней элемента управления TDateTimePicker.

Я читал, что изначально это потомок TMonthCalendar, так что это должно быть возможно.

Я также нашел пример кода, но он на C#: http://social.msdn.microsoft.com/Forums/en/winforms/thread/03527023-694d-41ab-bffb-18c59fca1fda

Обратите внимание, что я не хочу использовать какие-либо сторонние элементы управления DateTimePicker, я хотел бы остаться со стандартным.


person Steve    schedule 19.11.2010    source источник


Ответы (2)


Вы оба правы и неправы :-)

См.: http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_23927552.html

Вы правы, что вы не можете установить BoldDays под XP. Но вы ошибаетесь, потому что под Vista/Win7 можно!

Вот измененный код:

procedure TForm1.DateTimePicker1DropDown(Sender: TObject);
const
  DTM_GETMCSTYLE = (DTM_FIRST + 12);
  DTM_SETMCSTYLE = (DTM_FIRST + 11);
  MCS_NOTRAILINGDATES = $0040;
  MCS_SHORTDAYSOFWEEK = $0080;
  MCS_NOSELCHANGEONNAV = $0100;
var
  monthCalHandle: THandle;
  boldDates: array[0..2] of integer;
  style, prevstyle: LResult;
begin
  style := SendMessage(DateTimePicker1.Handle, DTM_GETMCSTYLE, 0, 0);
  style := style or MCS_DAYSTATE; //or MCS_NOSELCHANGEONNAV or MCS_WEEKNUMBERS;
  prevstyle := SendMessage(DateTimePicker1.Handle, DTM_SETMCSTYLE, 0, style);

  monthCalHandle := SendMessage(dateTimePicker1.Handle, DTM_GETMONTHCAL, 0, 0);

  boldDates[0]:=$5a5a5a;
  boldDates[1]:=$5a5a5a;
  boldDates[2]:=$5a5a5a;
  SendMessage(monthCalHandle, MCM_SETDAYSTATE, 3, integer(@boldDates));
end;

Примечание: обязательно добавьте в файл манифест Vista, иначе он не будет работать!

Константы взяты из обновленного файла commctrl.h, который можно найти здесь: http://www.koders.com/cpp/fid6A6537D52B537D0920D7A760D2073F7B65ADE310.aspx?s=WM_CAP_DRIVER_CONNECT

Спасибо за помощь, вы привели меня к решению! :-)

person Steve    schedule 19.11.2010
comment
К сожалению, это решение не может и не работает. Как только вы измените представление, например, выберете другой месяц и т. д., вы потеряете информацию, выделенную жирным шрифтом. Месячный календарь запрашивает эту информацию, когда она ему нужна. Как указано в документации MCM_SETDAYSTATE: приложение может явно установить информацию о состоянии дня, отправив это сообщение, но состояние не будет сохраняться, когда другая часть календаря прокручивается в поле зрения. - person Sertac Akyuz; 27.10.2018

Вы не можете делать то, что хотите, потому что MonthCalendar, отображаемый в ответ на нажатие кнопки dropDown в DateTimePicker, представляет собой MonthCalendar, для которого не задан стиль MCS_DAYSTATE. Это решение Microsoft. Это не ограничение VCL, поэтому, насколько мне известно, вы ничего не можете сделать, чтобы его изменить. Единственное, что можно было бы сделать, это не использовать его и создать свой собственный собственный экземпляр MonthCalendar в ответ на нажатие пользователем кнопки раскрывающегося списка; или использовать некоторые из уже имеющихся пользовательских компонентов.

Чтобы доказать это, вот Pascal-версия того же кода C#, который вы опубликовали. Это не работает и, насколько мне известно, никогда не будет. Если вы хотите протестировать его, подключите его к событию DropDown объекта DateTimePicker.

procedure TForm1.DateTimePicker1DropDown(Sender: TObject);
 var
   monthCalHandle: THandle;
   boldDates: array[0..2] of integer;

 begin
  { obtain the MonthCalendar handle using the DTM_GETMONTHCAL message
    note that the handle returned changes for every time the
    drop down calendar is displayed. }
  monthCalHandle := SendMessage(dateTimePicker1.Handle, DTM_GETMONTHCAL, 0, 0);

  { Send the MCM_SETDAYSTATE message. This message takes an array of
    3 MONTHDAYSTATEs. Every MONTHDAYSTATE is a bit set that represents a month.
    Each bit (0 through 30) represents the state of a day. Whan a bit is on,
    its corresponding day is emphasized in the MonthCalendar }
  boldDates[0]:=$5a5a5a;
  boldDates[1]:=$5a5a5a;
  boldDates[2]:=$5a5a5a;
  SendMessage(monthCalHandle, MCM_SETDAYSTATE, 3, integer(@boldDates));
 end;
person PA.    schedule 19.11.2010
comment
+1 поиграв с ним какое-то время, я считаю, что вы правы. - person Lieven Keersmaekers; 19.11.2010