Eine TDateTime-Auswahl ist eine ComboBox, in der die Dropdownliste durch einen Kalender ersetzt wird. Ich verwende XE2 VCL Styles und die Änderung des Styles hat keinen Einfluss auf TDateTimePicker Color & Schriftfarbe. Ich habe den Kalender-Stil mit dieser question ändern, aber die Lösung ist nicht OK für die ComboBox, keine Idee? Jetzt plane ich, eine TComboBox für die Verwendung mit einem TMonthCalendar zu erben, aber ich würde wissen, ob jemand eine bessere Lösung hätte.Stileigenschaften für TDateTimePicker
Antwort
Um die Umgehung der CalColors
Eigenschaft zu verwenden, können Sie die Windows-Theme in der Drop-Down-Fenster des deaktivieren muss TDateTimePicker-Komponente, für die Sie die DTM_GETMONTHCAL
Nachricht verwenden müssen, um das Fensterhandle zu erhalten.
prüfen diese Probe App
unit Unit15;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.StdCtrls, Vcl.ComCtrls;
type
TForm15 = class(TForm)
DateTimePicker1: TDateTimePicker;
procedure DateTimePicker1DropDown(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form15: TForm15;
implementation
{$R *.dfm}
uses
Winapi.CommCtrl,
Vcl.Styles,
Vcl.Themes,
uxTheme;
Procedure SetVclStylesColorsCalendar(DateTimePicker: TDateTimePicker);
Var
LTextColor, LBackColor : TColor;
begin
uxTheme.SetWindowTheme(DateTimePicker.Handle, '', '');//disable themes in the calendar
//get the vcl styles colors
LTextColor:=StyleServices.GetSystemColor(clWindowText);
LBackColor:=StyleServices.GetSystemColor(clWindow);
DateTimePicker.Color:=LBackColor;
//set the colors of the calendar
DateTimePicker.CalColors.BackColor:=LBackColor;
DateTimePicker.CalColors.MonthBackColor:=LBackColor;
DateTimePicker.CalColors.TextColor:=LTextColor;
DateTimePicker.CalColors.TitleBackColor:=LBackColor;
DateTimePicker.CalColors.TitleTextColor:=LTextColor;
DateTimePicker.CalColors.TrailingTextColor:=LTextColor;
end;
procedure TForm15.DateTimePicker1DropDown(Sender: TObject);
var
hwnd: WinAPi.Windows.HWND;
begin
hwnd := SendMessage(TDateTimePicker(Sender).Handle, DTM_GETMONTHCAL, 0,0);
uxTheme.SetWindowTheme(hwnd, '', '');//disable themes in the drop down window
end;
procedure TForm15.FormCreate(Sender: TObject);
begin
SetVclStylesColorsCalendar(DateTimePicker1);
end;
end.
UPDATE 1
Ändern Sie die Hintergrundfarbe des "Combobox" des TDateTimePicker ist eine Aufgabe, die Fenster selbst begrenzt, weil zwischen anderen Faktoren
- Dieses Steuerelement verfügt nicht über die vom Eigentümer gezeichnete Kapazität Stadt,
- Und wenn Sie versuchen, mit der
SetBkColor
Funktion hat keinen Effekt in diesem Steuerelement, weil dieWM_CTLCOLOREDIT
Nachricht wird nicht von diesem Steuerelement behandelt.
So eine mögliche Lösung ist abfangen der WM_PAINT
und WM_ERASEBKGND
Nachrichten und schrieb Ihren eigenen Code, um die Kontrolle zu malen. Wenn Sie die Vcl-Stile verwenden, können Sie einen Style-Hook verwenden, um diese Nachrichten zu verarbeiten.
Überprüfen Sie diesen Code (nur als Proof of Concept)
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.StdCtrls, Vcl.ComCtrls;
type
TForm15 = class(TForm)
DateTimePicker1: TDateTimePicker;
DateTimePicker2: TDateTimePicker;
procedure DateTimePicker1DropDown(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
end;
var
Form15: TForm15;
implementation
{$R *.dfm}
uses
Winapi.CommCtrl,
Vcl.Styles,
Vcl.Themes,
Winapi.uxTheme;
type
TDateTimePickerStyleHookFix= class(TDateTimePickerStyleHook)
private
procedure WMPaint(var Message: TMessage); message WM_PAINT;
procedure PaintBackground(Canvas: TCanvas); override;
public
constructor Create(AControl: TWinControl); override;
end;
TDateTimePickerStyleHookHelper = class helper for TDateTimePickerStyleHook
public
function GetButtonRect_: TRect;
end;
Procedure SetVclStylesColorsCalendar(DateTimePicker: TDateTimePicker);
Var
LTextColor, LBackColor : TColor;
begin
Winapi.uxTheme.SetWindowTheme(DateTimePicker.Handle, '', '');//disable themes in the calendar
//get the vcl styles colors
LTextColor:=StyleServices.GetSystemColor(clWindowText);
LBackColor:=StyleServices.GetSystemColor(clWindow);
DateTimePicker.Color:=LBackColor;
//set the colors of the calendar
DateTimePicker.CalColors.BackColor:=LBackColor;
DateTimePicker.CalColors.MonthBackColor:=LBackColor;
DateTimePicker.CalColors.TextColor:=LTextColor;
DateTimePicker.CalColors.TitleBackColor:=LBackColor;
DateTimePicker.CalColors.TitleTextColor:=LTextColor;
DateTimePicker.CalColors.TrailingTextColor:=LTextColor;
end;
procedure TForm15.DateTimePicker1DropDown(Sender: TObject);
var
hwnd: WinAPi.Windows.HWND;
begin
hwnd := SendMessage(TDateTimePicker(Sender).Handle, DTM_GETMONTHCAL, 0,0);
Winapi.uxTheme.SetWindowTheme(hwnd, '', '');//disable themes in the drop down window
end;
procedure TForm15.FormCreate(Sender: TObject);
begin
//set the colors for the TDateTimePicker
SetVclStylesColorsCalendar(DateTimePicker1);
SetVclStylesColorsCalendar(DateTimePicker2);
end;
{ TDateTimePickerStyleHookHelper }
function TDateTimePickerStyleHookHelper.GetButtonRect_: TRect;
begin
Result:=Self.GetButtonRect;
end;
{ TDateTimePickerStyleHookFix }
constructor TDateTimePickerStyleHookFix.Create(AControl: TWinControl);
begin
inherited;
OverrideEraseBkgnd:=True;//this indicates which this style hook will call the PaintBackground method when the WM_ERASEBKGND message is sent.
end;
procedure TDateTimePickerStyleHookFix.PaintBackground(Canvas: TCanvas);
begin
//use the proper style color to paint the background
Canvas.Brush.Color := StyleServices.GetStyleColor(scEdit);
Canvas.FillRect(Control.ClientRect);
end;
procedure TDateTimePickerStyleHookFix.WMPaint(var Message: TMessage);
var
DC: HDC;
LCanvas: TCanvas;
LPaintStruct: TPaintStruct;
LRect: TRect;
LDetails: TThemedElementDetails;
sDateTime : string;
begin
DC := Message.WParam;
LCanvas := TCanvas.Create;
try
if DC <> 0 then
LCanvas.Handle := DC
else
LCanvas.Handle := BeginPaint(Control.Handle, LPaintStruct);
if TStyleManager.SystemStyle.Enabled then
begin
PaintNC(LCanvas);
Paint(LCanvas);
end;
if DateMode = dmUpDown then
LRect := Rect(2, 2, Control.Width - 2, Control.Height - 2)
else
LRect := Rect(2, 2, GetButtonRect_.Left, Control.Height - 2);
if ShowCheckBox then LRect.Left := LRect.Height + 2;
IntersectClipRect(LCanvas.Handle, LRect.Left, LRect.Top, LRect.Right, LRect.Bottom);
Message.wParam := WPARAM(LCanvas.Handle);
//only works for DateFormat = dfShort
case TDateTimePicker(Control).Kind of
dtkDate : sDateTime:=DateToStr(TDateTimePicker(Control).DateTime);
dtkTime : sDateTime:=TimeToStr(TDateTimePicker(Control).DateTime);
end;
//draw the current date/time value
LDetails := StyleServices.GetElementDetails(teEditTextNormal);
DrawControlText(LCanvas, LDetails, sDateTime, LRect, DT_VCENTER or DT_LEFT);
if not TStyleManager.SystemStyle.Enabled then
Paint(LCanvas);
Message.WParam := DC;
if DC = 0 then
EndPaint(Control.Handle, LPaintStruct);
finally
LCanvas.Handle := 0;
LCanvas.Free;
end;
Handled := True;
end;
initialization
TStyleManager.Engine.RegisterStyleHook(TDateTimePicker, TDateTimePickerStyleHookFix);
end.
Hinweis: Diese Art Haken, nicht die fokussiert (ausgewählt) Elemente im Inneren Textsteuerung (Combobox) des TDateTimePicker zeichnen i Lass diese Aufgabe für dich.
UPDATE 2
Ich schrieb einen vcl Stil Haken, der die gesamte Logik beinhaltet die vcl Stil richtig an die TDateTimePicker
Komponente anzuwenden, ohne das Ereignis OnDropDown zu verwenden oder das OnCreate-Ereignis des Formulars . Sie können die vcl Stil Haken here (als Teil des vcl styles utils Projekt) finden
es nutzen zu können, müssen Sie die Vcl.Styles.DateTimePickers Einheit zu Ihrem Projekt hinzufügen und den Haken auf diese Weise registrieren.
TStyleManager.Engine.RegisterStyleHook(TDateTimePicker, TDateTimePickerStyleHookFix);
Für den Kalender selbst ... auf der Grundlage Ihrer anderen Frage ...
procedure SetVclStylesMonthCalColors(calColors: TMonthCalColors);
var
LTextColor, LBackColor : TColor;
begin
//get the vcl styles colors
LTextColor:=StyleServices.GetSystemColor(clWindowText);
LBackColor:=StyleServices.GetSystemColor(clWindow);
//set the colors of the calendar
calColors.BackColor:=LBackColor;
calColors.MonthBackColor:=LBackColor;
calColors.TextColor:=LTextColor;
calColors.TitleBackColor:=LBackColor;
calColors.TitleTextColor:=LTextColor;
calColors.TrailingTextColor:=LTextColor;
end;
Procedure SetVclStylesColorsCalendar(MonthCalendar: TMonthCalendar);
Var
LTextColor, LBackColor : TColor;
begin
uxTheme.SetWindowTheme(MonthCalendar.Handle, '', '');//disable themes in the calendar
MonthCalendar.AutoSize:=True;//remove border
SetVclStylesMonthCalColors(MonthCalendar.CalColors);
end;
procedure TForm1.dtp1DropDown(Sender: TObject);
var
rec: TRect;
begin
uxTheme.SetWindowTheme(DateTime_GetMonthCal(dtp1.Handle), '', '');
MonthCal_GetMinReqRect(DateTime_GetMonthCal(dtp1.Handle), rec);
SetWindowPos(GetParent(DateTime_GetMonthCal(dtp1.Handle)), 0, rec.Left, rec.Top, rec.Width, rec.Height,0);
SetWindowPos(DateTime_GetMonthCal(dtp1.Handle), 0, rec.Left, rec.Top, rec.Width, rec.Height,0);
SetVclStylesMonthCalColors(dtp1.CalColors);
end;
Ich muss die Combo stylen, nicht den Kalender! – philnext
Also, ich denke, Sie müssen die Komponente erben und die OnPaint-Methode überschreiben, um dies zu tun ... Lassen Sie uns andere zukünftige Kommentare sehen ... – Whiler
Ja, ich denke, eine TCustomComboBox mit einem Kalender zu erben, aber ich dachte, jemand hatte eine bessere Lösung. – philnext
- 1. BoldDays für TDateTimePicker?
- 2. Zeige "leer" TDateTimePicker
- 3. TDatetimePicker Format zeigt falsch
- 4. JavaScript nicht zurückgeben Stileigenschaften
- 5. Wie die Schaltfläche "Heute" in TDateTimePicker ausblenden?
- 6. Wie man TDateTimePicker Sprache manuell einstellt?
- 7. Wie ändern Sie die Stileigenschaften von HTML.Label?
- 8. Wie bekomme ich den Anfangswert von Stileigenschaften in Javascript?
- 9. Wie kann ich programmgesteuert alle Stileigenschaften von einem DOM-Element zu einem anderen
- 10. OL3: So erhalten Sie vorhandene Stileigenschaften (z. B. Füllfarbe, Strichfarbe usw.) von Vektorlayer
- 11. Wie setzen Sie die Stileigenschaften auf ihre CSS-Standardeinstellungen in Javascript zurück?
- 12. jquery animieren für Elementattribute nicht style
- 13. Fehler beim Festlegen von TDateTimePicker.Font.Style auf Kursiv in Delphi 5
- 14. Wrap Text in DataGridCell WPF
- 15. Wie setze ich Gtk "Style Eigenschaften"?
- 16. Wie kann ich einen Attributwert (keine Stileigenschaft) mit jQuery animieren?
- 17. Ermitteln der gemessenen Breite einer Schaltflächenbeschriftung
- 18. Wie bekomme ich die aktuelle fillColor von Google Maps Polygon?
- 19. Scala für() vs für {}
- 20. CSS aktiven Router Link Nehmen [Angular 2]
- 21. Verbindungszeichenfolge für Informix für .NET
- 22. Mindestanforderungen für Unity für Android?
- 23. Gruppe für Monat für Anwesenheitsliste
- 24. Modul für OneSignal für Appcelerator
- 25. Vorschlag für Vorlagenbuch für C++?
- 26. Alternative für BtsMSITask für BizTalk
- 27. Elmah für WCF für Ausnahmebehandlung
- 28. Beispiel für den Domain-Namen für mailgun be für nodejs?
- 29. Einstellung für Ländereinstellung für Java-Überschreibung für bestimmtes Gebietsschema
- 30. Implementieren von Bedingungsvariablen für CRITICAL_SECTIONs für WinThreads für XP
Was meinen Sie mit "die Lösung ist nicht OK für die Komponente"? –
@TOndrej Im TDateTimePicker hast du eine ComboBox und wenn du darauf klickst den Kalender.Ich habe den Kalenderstil geändert, aber nicht den Kombo-Stil. Meine Frage war nicht klar: Ich werde es bearbeiten! – philnext
'während nicht zugewiesen (RRUZ) aktualisieren ':-) – TLama