Sì, puoi farlo. In primo luogo, si deve inizializzare il controllo:
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
).
Quindi è sufficiente rispondere alla notifica MCN_GETDAYSTATE
. O è possibile creare il proprio discendente TDateTimePicker
oppure è possibile utilizzare una "classe intercettore".
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;
Un altro esempio: Si supponga che la visualizzazione corrente è costituito da tre mesi, e che si desidera solo per selezionare giorni nel 'mese attualmente visualizzato', vale a dire, nel mese mezzo. Supponiamo che vogliate selezionare ogni terzo giorno, a partire da un giorno selezionato.
poi si desidera utilizzare i campi di bit
Month Bitfield
0 00000000000000000000000000000000
1 01001001001001001001001001001001
2 00000000000000000000000000000000
che sono
Month Bitfield
0 $00000000
1 $49249249
2 $00000000
in esadecimale. Così si fa
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;
Screenshot http://privat.rejbrand.se/datetimepick.png
Si noti che questo funzionerà solo su Windows Vista e versioni successive, ad es. poiché ['DTM_GETMCSTYLE'] (http://msdn.microsoft.com/en-us/library/bb761763 (VS.85) .aspx) è stato introdotto in Vista. –
Suppongo che il sistema operativo allochi e liberi il buffer 'prgDayState' ... La documentazione non è completamente chiara su questo punto. –
Bel lavoro Andreas. –