【问题标题】:How to get the year when bolding month days in a TMonthCalendar?在 TMonthCalendar 中粗体月日时如何获取年份?
【发布时间】:2019-11-15 20:21:59
【问题描述】:

我有一个使用日历的日志,我想将记录信息的日期加粗。我将它们放在一个 3D 数组 TDiaryLog = array[1900..2399] of array[1..12] of array[1..31] of POneDay; 中。但是在OnGetMonthInfo 中,当我必须用粗体构建列表时,它只给我Month,而不是年份。如果我没有年份,我怎么知道我必须在哪一个月度过一天?当十二月在日历中显示为当前月份时,从明年一月开始显示几天!

procedure TMainForm.CalendarGetMonthInfo(Sender: TObject; Month: Cardinal;
  var MonthBoldInfo: Cardinal);
begin
end;

【问题讨论】:

  • 这是一个 TMonthCalendar 而不是 TCalendar。您可以从当前日期集获取它,但它似乎有时会滞后于导航到的内容。
  • OnGetMonthInfo 事件每个月触发 3 次。一个用于当前日期,另外两个用于前后一个月。而且我不知道哪个是当前的...
  • 所有三个调用的日期看起来都相同,但可以用于与给出的月份进行比较以确定年份。 memo1.Lines.Add(IntToStr(Month)+ ' ' + DateTimeToStr(MonthCalendar1.Date));
  • 使用 OnMonthGetBoldInfo 代替,它会传递年份和月份。 D2009有吗?
  • 感谢@TLama。不幸的是,看起来如此,如果您需要年份,OnGetMonthInfo 最终是无用的,如果您正在做的事情比文档中的示例更复杂一点,那就是这种情况 - 每个月的第 1 天和第 8 天都加粗!!

标签: delphi calendar delphi-2009


【解决方案1】:

我制作了一个新组件,在其中截获了MCN_GETDAYSTATE 消息,并从消息信息中提取了年份...它一直都在那里,但 Delphi 认为那一年没有用。

  TOnGetMonthInfoExEvent = procedure(Sender: TObject; Year, Month: Word;
    var MonthBoldInfo: LongWord) of object;

  TNewMonthCalendar = class(TMonthCalendar)
  private
    FOnGetMonthInfoEx: TOnGetMonthInfoExEvent;
    procedure CNNotify(var Msg: TWMNotifyMC); message CN_NOTIFY;
  published
    property OnGetMonthInfoEx: TOnGetMonthInfoExEvent read FOnGetMonthInfoEx write FOnGetMonthInfoEx;
  end;

procedure TNewMonthCalendar.CNNotify(var Msg: TWMNotifyMC);
var
  I: Integer;
  Month, Year: Word;
  DS: PNMDayState;
  CurState: PMonthDayState;
begin
 if (Msg.NMHdr.code = MCN_GETDAYSTATE) and Assigned(FOnGetMonthInfoEx) then begin
  DS:= Msg.NMDayState;
  FillChar(DS.prgDayState^, DS.cDayState * SizeOf(TMonthDayState), 0);
  CurState:= DS.prgDayState;
  for I:= 0 to DS.cDayState - 1 do begin
   Year:= DS.stStart.wYear;
   Month:= DS.stStart.wMonth + I;
   if Month > 12 then begin Inc(Year); Dec(Month, 12); end;
   FOnGetMonthInfoEx(Self, Year, Month, CurState^);
   Inc(CurState);
  end;
 end
 else inherited;
end;

奖金

而且,作为奖励,您需要它来更新您对当前月份视图的粗体信息所做的更改...因为它不适用于 Invalidate

procedure TNewMonthCalendar.RefreshDayState;
var N: Cardinal;
    Range: array[0..1] of TSystemTime;
    Year, Month: Word;
    States: array of TMonthDayState;
    I: Integer;
begin
 if not Assigned(FOnGetMonthInfoEx) then Exit;
 N:= SendMessage(Handle, MCM_GETMONTHRANGE, GMR_DAYSTATE, LPARAM(@Range));
 Year:= Range[0].wYear;
 Month:= Range[0].wMonth;
 SetLength(States, N);
 FillChar(States[0], N * SizeOf(TMonthDayState), 0);
 for I:= 0 to N-1 do begin
  FOnGetMonthInfoEx(Self, Year, Month, States[I]);
  Inc(Month);
  if Month > 12 then
   begin Dec(Month, 12); Inc(Year); end;
 end;
 SendMessage(Handle, MCM_SETDAYSTATE, N, LPARAM(@States[0]));
end;

【讨论】:

  • 这就是他们后来推出新活动OnMonthGetBoldInfo的原因。
猜你喜欢
  • 2021-12-16
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多