Un selector TDateTime es un ComboBox donde la lista desplegable se reemplaza por un calendario. Uso XE2 VCL Styles y el cambio de estilo no afecta a TDateTimePicker Color & Color de fuente. He cambiado el estilo de calendario con este question pero la solución no está bien para el ComboBox, ¿alguna idea? Ahora planeo heredar un TComboBox para usarlo con un TMonthCalendar pero sabría si alguien tuviera una mejor solución.Propiedades de estilo para TDateTimePicker
Respuesta
Con el fin de utilizar la solución de la propiedad CalColors
, debe desactivar el tema de Windows en la caída de la ventana de la baja Componente TDateTimePicker, para eso debe usar el mensaje DTM_GETMONTHCAL
para obtener el identificador de ventana.
Comprobar esta muestra 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.
ACTUALIZA 1
Cambiar el color de fondo del "cuadro combinado" de la TDateTimePicker es una tarea limitada por el propio Windows, debido entre otros factores
- Este control no tiene la capacidad dibujada por el propietario ciudad,
- Y si se intenta utilizar la función
SetBkColor
no tiene efecto en este control porque el mensajeWM_CTLCOLOREDIT
no está a cargo de este control.
lo tanto, una posible solución es interceptar los mensajes WM_PAINT
y WM_ERASEBKGND
y escribió su propio código para pintar el control. Cuando utiliza los estilos de Vcl, puede usar un gancho de estilo para manejar estos mensajes.
Comprobar el código (sólo como una prueba de concepto)
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.
Nota: Este gancho estilo no saca los elementos enfocados (seleccionados) en el control de texto interno (cuadro combinado) de la TDateTimePicker, i deja esta tarea para ti.
ACTUALIZACIÓN 2
simplemente escribí un gancho estilo VCL que incluye toda la lógica para aplicar el estilo VCL adecuadamente al componente TDateTimePicker
, sin utilizar el evento OnDropDown o el evento OnCreate del formulario . Puede encontrar el gancho de estilo here VCL (como parte del proyecto vcl styles utils)
Para usarlo, hay que añadir la unidad Vcl.Styles.DateTimePickers a su proyecto y registrar el gancho de esta manera.
TStyleManager.Engine.RegisterStyleHook(TDateTimePicker, TDateTimePickerStyleHookFix);
Para el propio calendario ... Con base en su otra pregunta ...
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;
Necesito diseñar el combo, ¡no el calendario! – philnext
Entonces, creo que necesita heredar el componente y anular el método OnPaint para hacer esto ... veamos otros comentarios futuros ... – Whiler
Sí, considero heredar un TCustomComboBox con un calendario, pero pensé que alguien tenía un mejor solución. – philnext
- 1. Mostrar "vacío" TDateTimePicker
- 2. Propiedades de tema y estilo para imagen de fondo
- 3. Cómo configurar/obtener Gtk "Propiedades de estilo"
- 4. js propiedades de estilo devuelve en blanco
- 5. Cómo afectar las propiedades de control secundario de un estilo
- 6. ¿Tiene acceso a todas las propiedades de estilo css?
- 7. TDateTimePicker Estilos de VCL en XE2 que solo ocurre en el tema clásico de Windows
- 8. C# Acceso al estilo del indexador de propiedades del objeto
- 9. ¿Cómo establecer un valor predeterminado usando propiedades de "estilo corto" en VS2008 (Propiedades automáticas)?
- 10. Obtención de JavaScript para todas las propiedades
- 11. Establecer estilo de elemento para: estilo de desplazamiento usando jQuery
- 12. Guía de estilo para C#?
- 13. estilo de LINQ "para cada"
- 14. estilo personalizado para TabWidget
- 15. Plantillas de estilo CodeRush para ReSharper
- 16. ¿Cómo puedo acceder a las propiedades de estilo en objetos JavaScript que usan hojas de estilo externas?
- 17. Heredar propiedades de CSS
- 18. Convertir nombres de propiedades de estilo JSON en nombres de CamelCase de Java con GSON
- 19. ¿Cómo marca programáticamente una fecha en el calendario de TDateTimePicker de Delphi?
- 20. ¿Hay alguna manera de usar un creador de estilos para las propiedades de las propiedades?
- 21. Estilo personalizado para Bootstrap seleccione
- 22. OpenMP y estilo STL para
- 23. ¿Cómo accedo a las propiedades de estilo de los pseudo-elementos con jQuery?
- 24. Codificación de Normas de estilo para Android
- 25. Comprobador de estilo de codificación para C
- 26. Agregar estilo al Editor Para
- 27. Esquema para admitir propiedades dinámicas
- 28. ¿Cómo restablecer las propiedades de estilo a sus valores predeterminados de CSS en javascript?
- 29. ¿Hojas de estilo para el contenido?
- 30. ¿Estilo de codificación común para Python?
¿Qué quiere decir con "la solución no está bien para el componente"? –
@TOndrej En el TDateTimePicker tiene un ComboBox y cuando hace clic en él, el Calendario.Cambié el estilo del calendario pero no el combo. Mi pregunta no estaba clara: ¡la editaré! – philnext
'mientras no está asignado (RRUZ) do Refresh' :-) – TLama