代码之家  ›  专栏  ›  技术社区  ›  Uwe Raabe

如何从TDateTimePicker的MonthCalendar子级接收MCN\u VIEWCHANGE通知?

  •  0
  • Uwe Raabe  · 技术社区  · 7 年前

    这个 控件创建一个 下拉时的子控件,在特写时释放。子控件的句柄可以通过 日期时间\u GetMonthCal

    是否可以从该子控件获取MCN\u VIEWCHANGE通知(如果可以,如何获取)?

    Date and Time Picker

    Month Calendar Control Reference

    1 回复  |  直到 7 年前
        1
  •  1
  •   Uwe Raabe    7 年前

    嗯,结果比预期的容易多了。我的印象是 MCN_VIEWCHANGE 通知被发送到子句柄的wndproc。相反,它被发送到DateTimePicker wndproc,但是使用MonthCalender子级的窗口句柄(这就是为什么我在第一次尝试中没有捕捉到它)。因此,对该通知实施适当的处理结果是直截了当的。下面是我在Delphi中扩展内置 TDateTimePicker

    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;