When users click a DateTimePicker, set to drop down a calendar, I would like various dates (chosen via code I create) to highlighted in some way--colored background, bold fo
Yes, you can do this. First, you have to initialize the control:
const
DTM_GETMCSTYLE = DTM_FIRST + 12;
DTM_SETMCSTYLE = DTM_FIRST + 11;
...
SendMessage(DateTimePicker1.Handle,
DTM_SETMCSTYLE,
0,
SendMessage(DateTimePicker1.Handle, DTM_GETMCSTYLE, 0, 0) or MCS_DAYSTATE);
(uses CommCtrl).
Then you simply have to respond to the MCN_GETDAYSTATE notification. Either you can create your own TDateTimePicker descendant, or you can use an 'interceptor class'.
type
TDateTimePicker = class(ComCtrls.TDateTimePicker)
protected
procedure WndProc(var Message: TMessage); override;
end;
...
procedure TDateTimePicker.WndProc(var Message: TMessage);
var
i: integer;
begin
inherited;
case Message.Msg of
WM_NOTIFY:
with PNMDayState(Message.LParam)^ do
if nmhdr.code = MCN_GETDAYSTATE then
begin
// The first visible day is SystemTimeToDateTime(stStart);
// cDayState is probably three, because most often three months are
// visible at the same time. Of course, the second of these is the
// 'currently displayed month'.
// Each month is represented by a DWORD (32-bit unsigned integer)
// bitfield, where 0 means not bold, and 1 means bold.
// For instance, the following code will select all days:
for i := 0 to cDayState - 1 do
PMonthDayState(Cardinal(prgDayState) + i*sizeof(TMonthDayState))^ := $FFFFFFFF;
end;
end;
end;
Another example: Assume that the current display consists of three months, and that you only want to select days in the 'currently displayed month', that is, in the middle month. Assume that you want every third day to be selected, starting with a selected day.
Then you want to use the bitfields
Month Bitfield
0 00000000000000000000000000000000
1 01001001001001001001001001001001
2 00000000000000000000000000000000
which are
Month Bitfield
0 $00000000
1 $49249249
2 $00000000
in hexadecimal. So you do
for i := 0 to cDayState - 1 do
if i = 1 then
PMonthDayState(cardinal(prgDayState) + i*sizeof(TMonthDayState))^ := $49249249
else
PMonthDayState(cardinal(prgDayState) + i*sizeof(TMonthDayState))^ := $00000000;
