Delphi TDateTimePicker的BoldDays?

Delphi TDateTimePicker的BoldDays?,delphi,delphi-7,datetimepicker,typography,monthcalendar,Delphi,Delphi 7,Datetimepicker,Typography,Monthcalendar,我使用的是Delphi7,我想对TDateTimePicker控件的某些天进行加粗 我读过,最初,它是TMonthCalendar的后代,因此它应该是可能的 我还发现了一些示例代码,但它是用C语言编写的: 请注意,我不想使用任何第三方DateTimePicker控件,我希望使用标准控件。您不能随心所欲,因为在DateTimePicker中按下下拉按钮时显示的MonthCalendar是一个没有MCS\u DAYSTATE样式设置的MonthCalendar。这是微软的决定。这不是一个VCL限制

我使用的是Delphi7,我想对
TDateTimePicker
控件的某些天进行加粗

我读过,最初,它是
TMonthCalendar
的后代,因此它应该是可能的

我还发现了一些示例代码,但它是用C语言编写的:


请注意,我不想使用任何第三方
DateTimePicker
控件,我希望使用标准控件。

您不能随心所欲,因为在DateTimePicker中按下下拉按钮时显示的MonthCalendar是一个没有MCS\u DAYSTATE样式设置的MonthCalendar。这是微软的决定。这不是一个VCL限制,所以据我所知,没有什么可以改变它。唯一的办法是不要使用它,而是根据用户按下的下拉按钮实例化一个真实的MonthCalendar;或者使用一些已经可用的自定义组件

为了证明这一点,这里有一个与您发布的C#代码相同的Pascal版本。它不起作用,据我所知,它永远不会起作用。如果要测试它,请将其挂接到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;

您无法执行所需操作,因为在DateTimePicker中响应下拉按钮按下而显示的MonthCalendar是未设置MCS_DAYSTATE样式的MonthCalendar。这是微软的决定。这不是一个VCL限制,所以据我所知,没有什么可以改变它。唯一的办法是不要使用它,而是根据用户按下的下拉按钮实例化一个真实的MonthCalendar;或者使用一些已经可用的自定义组件

为了证明这一点,这里有一个与您发布的C#代码相同的Pascal版本。它不起作用,据我所知,它永远不会起作用。如果要测试它,请将其挂接到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;

你是对的,也是错的:-)

见:

你是对的,你不能在XP下设置BoldDays。 但是你错了,因为在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文件,可在以下位置找到:


谢谢你的帮助,你带我找到了解决方案!:-)

你是对的,也是错的:-)

见:

你是对的,你不能在XP下设置BoldDays。 但是你错了,因为在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文件,可在以下位置找到:


谢谢你的帮助,你带我找到了解决方案!:-)

玩了一段时间后,我相信你是对的。+1玩了一段时间后,我相信你是对的。不幸的是,这个解决方案不能也不起作用。一旦更改视图,例如选择不同的月份等,就会丢失粗体信息。月历在需要时请求该信息。如MCM_SETDAYSTATE中所述:应用程序可以通过发送此消息来显式设置日期状态信息,但当滚动到日历的不同部分时,该状态将不会持续。不幸的是,此解决方案无法且不起作用。一旦更改视图,例如选择不同的月份等,就会丢失粗体信息。月历在需要时请求该信息。如MCM_SETDAYSTATE中所述:应用程序可以通过发送此消息来显式设置日期状态信息,但当日历的不同部分滚动到视图中时,状态将不会持续。