如何以编程方式在Delphi的TDateTimePicker日历中标记日期?

时间:2011-08-26 21:05:54

标签: delphi datetimepicker

当用户点击DateTimePicker,设置为下拉日历时,我希望以某种方式突出显示各种日期(通过我创建的代码选择) - 彩色背景,粗体字体,彩色字体,无所谓。我只想要标记某些日期。 ......我该怎么做?

2 个答案:

答案 0 :(得分:12)

是的,你可以这样做。首先,您必须初始化控件:

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)。

然后您只需回复MCN_GETDAYSTATE通知即可。你可以创建自己的TDateTimePicker后代,也可以使用'拦截器类'。

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;

另一个例子:假设当前显示包含三个月,并且您只想选择“当前显示的月份”中的天数,即中间月份。假设您希望每隔三天选择一次,从选定日期开始。

然后你想使用位域

Month  Bitfield
0      00000000000000000000000000000000
1      01001001001001001001001001001001
2      00000000000000000000000000000000

Month  Bitfield
0      $00000000
1      $49249249
2      $00000000

以十六进制表示。所以你做了

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

答案 1 :(得分:4)

OnGetMonthInfo事件会查看BoldDays数组,以标记一个月内的日期。

从帮助中摘录:

  

使用BoldDays编码以粗体显示的当月的日期。       BoldDays返回的值可以分配给OnGetMonthInfo事​​件处理程序的MonthBoldInfo参数。   Days是一个无符号整数数组,对应于应为粗体的天数。

在帮助中查找。

编辑:

可以访问DateTimePicker.BoldDays。

在Delphi XE中不推荐使用OnGetMonthInfo,而是使用OnGetMonthBoldInfo。 仍然没有找到重新引入该事件的最佳方式。

编辑2: 我确实已经重新引入了这个事件,但似乎windows消息没有绑定在TDateTimePicker中。太糟糕了。 我想安德烈斯解决方案直接进入Windows消息api是最好的。