Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Komponente aus TDateTimePicker, OnDropDown überschreiben?


trm - Mo 05.12.16 21:40
Titel: Komponente aus TDateTimePicker, OnDropDown überschreiben?
Hallo,

ist es möglich das OnDropDown, welches meiner Recherche nach nur ein Porperty ist, als Procedure zu überschrieben, um dem Ereignis damit einige Merkmale (gaphischer Art) hinzuzufügen?


Delete - Mo 05.12.16 22:09

- Nachträglich durch die Entwickler-Ecke gelöscht -


trm - Mo 05.12.16 22:41

Hi nochmal, danke an Dich. Mit einiger Beharrlichkeit hat es nun geklappt. Leider warst Du schon etwas schneller als ich :-)


procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;

Diese Variante hatte mir gefehlt. Unten die vorläufige Komponente für Delphi. Die Modifikation für Windows Vista + habe ich hier gefunden:

http://barendgehrels.blogspot.de/2010/11/delphi-tdatetimepicker-with-weeknumber.html





Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
unit TRM_DateTimePicker;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Forms, ComCtrls, Dialogs, ExtCtrls, CommCtrl;

type
  TTRM_DateTimePicker = class(TDateTimePicker)
  private
    { Private declarations }
    FOnMouseLeave: TNotifyEvent;
    FOnMouseEnter: TNotifyEvent;

    procedure CMMouseEnter(var msg: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var msg: TMessage); message CM_MOUSELEAVE;

    procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
  protected
    { Protected declarations }
    procedure DoMouseEnter; dynamic;
    procedure DoMouseLeave; dynamic;

    procedure DoDropDown; dynamic;
  public
    { Public declarations }
  published
    { Published declarations }
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;

    property WeekNumbers;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('TRM', [TTRM_DateTimePicker]);
end;

{ TDateTimePicker_Leave }

procedure TTRM_DateTimePicker.CMMouseEnter(var msg: TMessage);
begin
  DoMouseEnter;
end;

procedure TTRM_DateTimePicker.CMMouseLeave(var msg: TMessage);
begin
  DoMouseLeave;
end;

procedure TTRM_DateTimePicker.CNNotify(var Message: TWMNotify);
begin
  if Message.NMHdr.code = DTN_DROPDOWN then
  begin
    if Self.WeekNumbers then
      DoDropDown;
  end;
  inherited;
end;

procedure TTRM_DateTimePicker.DoMouseEnter;
begin
  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TTRM_DateTimePicker.DoMouseLeave;
begin
  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TTRM_DateTimePicker.DoDropDown;
const
  MCM_GETMAXTODAYWIDTH = MCM_FIRST + 21;
var
  Style: LongInt;
  hDTP: THandle;
  r: TRect;
  intTodayWidth: Integer;

  cname: array [0 .. 256of Char;
begin

  inherited;

  // to get a handle of calendar
  hDTP := DateTime_GetMonthCal(Self.Handle);

  // change a style
  Style := GetWindowLong(hDTP, GWL_STYLE);
  SetWindowLong(hDTP, GWL_STYLE, Style or MCS_WEEKNUMBERS);

  // now we must change the width for calendar because week numbers shifted all strings
  // 1. to get the required rect
  r := Rect(0000);
  SendMessage(hDTP, MCM_GETMINREQRECT, 0, LongInt(@r));

  // 2. to get the maximum width of the "today" string
  intTodayWidth := SendMessage(hDTP, MCM_GETMAXTODAYWIDTH, 00);

  // 3. adjust rect width to fit the "today" string
  if intTodayWidth > r.Right then
    r.Right := intTodayWidth;

  // For Win7, the window (class=SysMonthCal32) is automatically inside
  // a parent-window (class=DropDown). Check this. If so, take the parent window.
  // If not so (class=TMainForm), take this window (for XP and lower)
  GetClassName(GetParent(hDTP), cname, sizeof(cname));
  if AnsiSameText(cname, 'DropDown'then
  begin
    hDTP := GetParent(hDTP);

    // To get it perfect (on my machines) is adding this code:
    inc(r.Right, 6);
    inc(r.Bottom, 6);
  end;

  // 4. to set new the height and width
  MoveWindow(hDTP, r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top, true);

end;

end.


Delete - Di 06.12.16 00:51

- Nachträglich durch die Entwickler-Ecke gelöscht -