2014-02-09 22 views
1

我目前使用Delphi(专业版,7.0;建立4.453)创建一个程序。德尔福TDateTime与TMonthCalendar大胆的日子

最初,我想在TDateTimePicker下拉日历中加入一些日期;但我很快发现我不能 - 所以我试图在TDateTimePicker下拉日历的顶部重叠一个TMonthCalendar(可以用它来做大胆的日期)(简单吧?)

但是没有那么快:不知何故,TDateTimePicker下拉日历总是显示在我的TMonthCalendar的顶部。我希望将TMonthCalendar显示在顶部。

这是我想我可以做的:

  1. 位置TMonthCalendar的的TDateTimePicker下(其中其下拉列表通常会显示)
  2. 使可见TMonthCalendar上的TDateTimePicker的OnDropDown事件
  3. 隐藏TMonthCalendar在TDateTimePicker中的OnCloseUp事件

这里是正在发生的事情:

  1. 当我点击上TDateTimePicker中的下拉三角,在TMonthCalendar变得可见(耶!)
  2. 不过的TDateTimePicker下拉日历始终把先例(TMonthCalendar总是下拉下)
  3. 所以我可以”不要在TMonthCalendar中做任何事情,除非我在TDateTimePicker下拉列表中选择了一个日期(因为TMonthCalendar在下面,我甚至无法看到加粗的日期)。

这里是我试过:

  • TMonthCalendar.Show上TDateTimePicker的的OnDropDown事件(这能为我们带来什么是显示-ED顶部)。但是这没有任何作用。
  • 执行DateMode:dmDropDown - > DateMode:TDateTimePicker的OnDropDown上的dmUpDown(因此禁用下拉日历)。但是由于点击MonthCalendar上的任何地方(包括顶部任一侧的变化月份按钮)都会使MonthCalendar变得不可见(我在MonthCalendarOnClick中做了“如果MonthCalendar.Visible然后可见:= false”)

我知道解决方案可能很简单,但我想不出一种方法来做到这一点。到目前为止,我提出的几个想法是不工作:( 所以,如果你能想到一种方法来做我想做的事,请帮我。

谢谢你!:)

+0

不要走这条路。 'TMonthCalendar'是Win32月份日历控件的一个简单封装。 'TDateTimePicker'是Win32日期时间选择器控件的一个简单包装,它在需要时在内部创建一个月份日历控件。有可能(而不是全部很难)访问该内部月历控件,并随心所欲地做任何事情,包括使用TMonthCalendar所能做的所有事情。只要看一下'TMonthCalendar'是怎么做的,然后为你自己的控制做同样的事情。 (我会举一个例子,但我不在系统上,现在我可以测试它。) – hvd

+0

这种方法永远不会产生好的结果 –

+0

可能的重复,['你如何以编程方式在Delphi中标记日期TDateTimePicker的日历?'](http://stackoverflow.com/q/7210565/576719)。 –

回答

2

你的问题的整个前提是错误的。完全可以修改附加到日期时间选择器的月份日历的格式。

解决方法是响应MCN_GETDAYSTATE通知。只有拥有MCS_DAYSTATE样式的控件才会发送此通知。为了确保应用这种风格,即使面对窗口重新创建,您也需要将其应用于重写的CreateWnd方法。

例如,在这里我有一个插做到这一点:

type 
    TDateTimePicker = class(Vcl.ComCtrls.TDateTimePicker) 
    protected 
    procedure CreateWnd; override; 
    procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY; 
    end; 

procedure TDateTimePicker.CreateWnd; 
begin 
    inherited; 
    DateTime_SetMonthCalStyle(WindowHandle, DateTime_GetMonthCalStyle(WindowHandle) or MCS_DAYSTATE); 
end; 

procedure TDateTimePicker.WMNotify(var Message: TWMNotify); 
var 
    i: integer; 
    NMDayState: PNMDayState; 
begin 
    inherited; 
    case Message.NMHdr.code of 
    MCN_GETDAYSTATE: 
    begin 
     NMDayState := PNMDayState(Message.NMHdr); 
     for i := 0 to NMDayState.cDayState-1 do begin 
     NMDayState.prgDayState[i] := $FFFFFFFF; // every day is bold 
     end; 
    end; 
    end; 
end; 

enter image description here

或与$AAAAAAAA位掩码只有偶数天大胆:

enter image description here

+0

正如对其他问题的答案的评论(这个问题应该被关闭为一个重复的问题)中指出的那样,这在XP上不起作用。除了(而不是)使用'DateTime_SetMonthCalStyle'之外,通过获取包含的月份日历的窗口句柄并直接更改其样式,可以使其在XP上工作。 – hvd

+0

@hvd OK。我想我们很快就会开始忘记XP。值得庆幸的。 –

+2

我不会指望XP在MS停止支持它的那一刻死去。那是一些用户甚至会考虑升级的时候。他们实际上可能还需要几个月的时间,我希望它不会。 – hvd