0

The DateTimePicker control in Windows creates a MonthCalendar child control during drop down, which is freed on close up. The handle of that child control can be retrieved with DateTime_GetMonthCal.

Is it possible to get the MCN_VIEWCHANGE notifications from that child control (and if yes, how)?

Date and Time Picker

Month Calendar Control Reference

Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130

1 Answers1

1

Well, it turned out to be much easier than expected. I had the impression that the MCN_VIEWCHANGE notification is sent to the wndproc of the child handle. Instead it is sent to the DateTimePicker wndproc, but with the window handle of the MonthCalender child (that's why I didn't catch it in my first tries). So implementing a suitable handling of that notification turned out to be straight forward. Here is my implementation in Delphi extending the built-in TDateTimePicker class:

const
  MCN_VIEWCHANGE = MCN_FIRST - 4; // -750

type
  tagNMVIEWCHANGE = record
    nmhdr: TNmHdr;
    dwOldView: DWORD;
    dwNewView: DWORD;
  end;
  PNMNMVIEWCHANGE = ^TNMNMVIEWCHANGE;
  TNMNMVIEWCHANGE = tagNMVIEWCHANGE;

type
  {$SCOPEDENUMS ON}
  TViewKind = (Month, Year, Decade, Century);
  {$SCOPEDENUMS OFF}

  TViewChange = procedure(Sender: TObject; OldView, NewView: TViewKind) of object;

type
  TDateTimePicker = class(Vcl.ComCtrls.TDateTimePicker)
  private
    FOnViewChange: TViewChange;
    procedure WMNotify(var Message: TWMNotify); message WM_NOTIFY;
  protected
    procedure ViewChange(OldView, NewView: TViewKind);
  public
  published
    property OnViewChange: TViewChange read FOnViewChange write FOnViewChange;
  end;

procedure TDateTimePicker.ViewChange(OldView, NewView: TViewKind);
begin
  if Assigned(FOnViewChange) then FOnViewChange(Self, OldView, NewView);
end;

procedure TDateTimePicker.WMNotify(var Message: TWMNotify);
var
  vwchg: PNMNMVIEWCHANGE;
begin
  if Message.Msg = WM_NOTIFY then begin
    vwchg := PNMNMVIEWCHANGE(Message.NMHdr);
    if vwchg.nmhdr.code = MCN_VIEWCHANGE then begin
      ViewChange(TViewKind(vwchg.dwOldView), TViewKind(vwchg.dwNewView));
    end;
  end;
  inherited;
end;
Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130
  • Yeah, I commented about the same to Andreas' [answer](https://stackoverflow.com/a/7211198/243614), for `MCN_GETDAYSTATE`. – Sertac Akyuz Dec 05 '18 at 14:57