Selektor TDateTime to ComboBox, w którym lista rozwijana zastępowana jest kalendarzem. Używam stylów XCL VCL i zmiana stylu nie wpływa na kolor czcionki TDateTimePicker & Kolor czcionki. Zmieniłem styl kalendarza za pomocą tego question, ale rozwiązanie nie jest w porządku dla żadnego pomysłu na ComboBox? Teraz mam zamiar odziedziczyć TComboBox do użytku z TMonthCalendar ale wiem, czy ktokolwiek miał lepsze rozwiązanie.Właściwości stylu dla TDateTimePicker
Odpowiedz
w celu wykorzystania obejścia nieruchomości CalColors
, należy wyłączyć motyw Windows w rozwijanym oknie Komponent TDateTimePicker, do którego należy użyć komunikatu DTM_GETMONTHCAL
, aby uzyskać uchwyt okna.
Sprawdź to próbka 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
Zmiana koloru tła "combobox" z TDateTimePicker jest zadaniem ograniczone przez Windows, ponieważ między innymi czynnikami
- Ta kontrola nie ma wyciągniętego właściciela miasto,
- A jeśli spróbujesz użyć funkcji
SetBkColor
, nie ma to wpływu na tę opcję, ponieważ komunikatWM_CTLCOLOREDIT
nie jest obsługiwany przez tę kontrolkę.
Możliwe jest więc przechwycenie wiadomości WM_PAINT
i WM_ERASEBKGND
i napisanie własnego kodu, aby pomalować formant. Gdy używasz stylów Vcl, możesz użyć haka Style do obsługi tych wiadomości.
Sprawdź ten kod (tylko jako 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.
Uwaga: Ten hak styl nie wyciągnąć skupiony (wybrane) elementy kontroli wewnętrznej tekstu (combobox) w TDateTimePicker, i niech to zadanie dla ciebie.
UPDATE 2
Właśnie napisał hak styl VCL, który obejmuje całą logikę zastosować styl VCL odpowiednio do komponentu TDateTimePicker
, bez korzystania z OnDropDown zdarzenie lub onCreate zdarzenie formularza . Można znaleźć haka here stylu VCL (jako część projektu vcl styles utils)
Aby z niego skorzystać należy dodać jednostkę Vcl.Styles.DateTimePickers do projektu i zarejestrować hak w ten sposób.
TStyleManager.Engine.RegisterStyleHook(TDateTimePicker, TDateTimePickerStyleHookFix);
dla samego kalendarza ... w oparciu o inne pytanie ...
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;
Potrzebuję stylu combo, a nie kalendarza! – philnext
Myślę więc, że musisz dziedziczyć komponent i zastąpić metodę OnPaint, aby to zrobić ... zobaczmy inne przyszłe komentarze ... – Whiler
Tak, uważam, że dziedziczyłem TCustomComboBox z kalendarzem, ale myślałem, że ktoś ma lepsze rozwiązanie. – philnext
- 1. Właściwości motywu i stylu dla obrazu tła
- 2. Pokaż "pusty" TDateTimePicker
- 3. Uzyskaj dostęp do wszystkich właściwości stylu CSS?
- 4. Matplotlib: Nadpisywanie domyślnych właściwości stylu "ggplot"
- 5. Ustawianie właściwości dynamicznego stylu CSS obiektu Backbone.View
- 6. Korzystanie z właściwości stylu BasedOn na DynamicResources
- 7. Ustawianie właściwości TargetType stylu na klasę podstawową
- 8. LINQ stylu "dla każdego"
- 9. Przyciski stylu AlertDialog dla aktywności
- 10. Sprawdzanie stylu kodowania dla C
- 11. readystatechange przy użyciu metody addEventListener versus właściwości starego stylu?
- 12. Uzyskaj atrybuty stylu dla dziecka z definicji stylu rodzica.
- 13. Ustawianie stylu CSS dla węzłów potomnych w atrybucie stylu
- 14. Jak korzystać z załączonej właściwości w ramach stylu?
- 15. TDateTimePicker VCL Style glitch w XE2, który zdarza się tylko w Windows Classic Theme
- 16. Aktualizowanie niestandardowej właściwości dołączonej w stylu Wyzwalanie z ustawiaczem
- 17. Jak programowo zaznaczyć datę w kalendarzu Delate'a TDateTimePicker?
- 18. Jak ustawić wartość domyślną za pomocą właściwości "krótkiego stylu" w VS2008 (Właściwości automatyczne)?
- 19. Dziedziczenie stylu PPTX
- 20. Kompilacje dla różnych platform w stylu Maven
- 21. IDE autocompletion dla javascript AMD załadunku stylu
- 22. Wskazówki dotyczące stylu Pep-8 dla JavaScript
- 23. Aplikacja w stylu administratora Django dla Javy
- 24. Tryb Emacsa dla języka w stylu c
- 25. Orientacja stylu Scala dla podkreślników w identyfikatorach
- 26. Przewodnik po stylu dla wielowierszowego html
- 27. opcje stylu formatu clang dla enums
- 28. Drukowanie w stylu Numpy dla obiektów Pythona
- 29. CSS Alternatywy dla stylu = "display: none"
- 30. Tryb Emacs JS dla stylu npm
Co rozumiesz przez "rozwiązanie nie jest poprawne dla komponentu"? –
@TOndrej W TDateTimePicker masz ComboBox i po kliknięciu na nim Kalendarz.Zmieniłem styl kalendarza, ale nie kombi. Moje pytanie nie było jasne: będę je edytować! – philnext
'while not Assigned (RRUZ) do Refresh' :-) – TLama