BoldDays for TDateTimePicker?
Asked Answered
G

2

1

I'm using Delphi7 and I'd like to bold some days of a TDateTimePicker control.

I've read that, originally, it's a descendant of TMonthCalendar, thus it should be possible.

I've also found some example code, but it's in C#: http://social.msdn.microsoft.com/Forums/en/winforms/thread/03527023-694d-41ab-bffb-18c59fca1fda

Please note that I don't want to use any third party DateTimePicker controls, I'd like to stay with the standard one.

Grimbal answered 19/11, 2010 at 8:29 Comment(0)
G
4

You are both right and wrong :-)

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

You are right that you can't set BoldDays under XP. But you are wrong because under Vista/Win7 you can!

Here is the modified code:

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;

Note: be sure to add a vista manifest to the file because otherwise it won't work!

The constants are from an updated commctrl.h file, found here: http://www.koders.com/cpp/fid6A6537D52B537D0920D7A760D2073F7B65ADE310.aspx?s=WM_CAP_DRIVER_CONNECT

Thanks for the help, you lead me to the solution! :-)

Grimbal answered 19/11, 2010 at 19:58 Comment(1)
Unfortunately this solution cannot and does not work. As soon as you change the view, like selecting a different month etc., you lose bold information. The month calendar requests that information when it needs it. As stated in MCM_SETDAYSTATE's documentation: An application can explicitly set day state information by sending this message, but the state will not persist when a different part of the calendar is scrolled into view.Event
R
2

You can't do what you want, because the MonthCalendar displayed in response of the dropDown button press in the DateTimePicker is a MonthCalendar that has no MCS_DAYSTATE style set. This is a Microsoft decision. It is not a VCL limitation, so there is nothing, to my knowledge, you can do to change it. The only thing would be not to use it and instantiate a real MonthCalendar of your own in response to the user press of the dropdown button; or use some of the custom components already available.

To prove it, here is a Pascal version of the same C# code you posted. It does not work and to my knowledge it never will. If you want to test it, hook it into the DropDown event of the 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;
Rowdyish answered 19/11, 2010 at 11:30 Comment(1)
+1 after playing with it for a while, I believe you are right.Dally

© 2022 - 2024 — McMap. All rights reserved.