Здравствуйте, adontz, Вы писали:
A>Как установить цвет показанный как жёлтый? Состояние выпадающего Month не принципиально.
Не знаю как в .NET, а в WinAPI по шагам это можно сделать так:
Создать кисть желтого цвета — CreateSolidBrush
Подменить оконную процедуру пикера и сохранить старую — SetWindowLong, GWL_WNDPROC. В-общем засабклассить
В его новой оконной процедуре перехват сообщения WM_PAINT, в нем:
BeginPaint
Заливка клиентской области желтой кистью
EndPaint
Инвалидировать заново всю клиентскую область — InvalidateRect
Вызвать старую оконную процедуру
Ну и не забыть в конце вернуть старую оконную процедуру и удалить кисть
Проверено в Delphi — работает.
Вот код на всякий случай, не думаю, что тут сам язык какое-то значение имеет:
using System;
using System.Windows.Forms;
using System.Drawing;
class Demo
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
public class MainForm : Form
{
private DateTimePicker2 dtp;
public MainForm()
{
this.Name = "MainForm";
this.Text = "Demo";
this.Size = new Size(400, 350);
dtp = new DateTimePicker2();
dtp.Location = new Point(12,12);
//скрытое свойство
dtp.BackColor = Color.Yellow;
this.Controls.Add(this.dtp);
}
}
internal class DateTimePicker2 : DateTimePicker
{
public DateTimePicker2()
{
}
protected override void WndProc(ref Message m)
{
// Check to see if message being send is WM_ERASEBKGND.
// The hex value of this message is hex 14.
// This message is sent when the background of the
// object needs to be erased. In our case though, instead of
// erasing it, we will paint a rectangle over itif(m.Msg == 0x14 && Enabled) // Then ' WM_ERASEBKGND
{
using(Graphics g = Graphics.FromHdc(m.WParam))
{
g.FillRectangle(new SolidBrush(BackColor), ClientRectangle);
}
return;
}
base.WndProc(ref m);
}
}
}
Здравствуйте, ekamaloff, Вы писали:
E>В его новой оконной процедуре перехват сообщения WM_PAINT, в нем: E> BeginPaint E> Заливка клиентской области желтой кистью E> EndPaint E> Инвалидировать заново всю клиентскую область — InvalidateRect E> Вызвать старую оконную процедуру
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, Indifferent, Вы писали:
A>Мне новый DateTime не подходит. Мне надо у уже существующих. но если другого пути нет...
... в руках у нас ...
механизм Subclassing'a, при котором подменяется оконная процедура и следовательно все сообщения сначала приходят в новую процедуру, а затем (по усмотрению) уже в оригинальную. В .NET такая функциональность обеспечивается при помощи наследования от класса System.Windows.Forms.NativeWindow
using System;
using System.Windows.Forms;
using System.Drawing;
class Demo
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
public class MainForm : Form
{
private DateTimePicker dtp1;
public MainForm()
{
this.Name = "MainForm";
this.Text = "Demo";
this.Size = new Size(400, 350);
dtp1 = new DateTimePicker();
dtp1.Location = new Point(12,12);
dtp1.BackColor = Color.Aqua;
this.Controls.Add(this.dtp1);
dtpNativeWindow myNativeWindow = new dtpNativeWindow(dtp1);
}
}
class dtpNativeWindow : NativeWindow
{
private Control _control = null;
public dtpNativeWindow(Control control)
{
_control = control;
control.HandleCreated += new EventHandler(OnHandleCreated);
control.HandleDestroyed += new EventHandler(OnHandleDestroyed);
}
void OnHandleCreated(object sender, EventArgs e)
{
AssignHandle(((Control)sender).Handle);
}
void OnHandleDestroyed(object sender, EventArgs e)
{
ReleaseHandle();
}
const int WM_ERASEBKGND = 0x14;
protected override void WndProc(ref Message m)
{
if(m.Msg == WM_ERASEBKGND && _control.Enabled)
{
using(Graphics g = Graphics.FromHdc(m.WParam))
{
g.FillRectangle(new SolidBrush(_control.BackColor), _control.ClientRectangle);
}
return;
}
base.WndProc(ref m);
}
}
}
Дак вот нет....
Смотрю внимательно System.Windows.Forms.DateTimePicker
Setting the BackColor has no effect on the appearance of the DateTimePicker. To set the background color for the drop-down calendar of the DateTimePicker, see the CalendarMonthBackground property.
В PropertyGrid его нет вообще, видимо отфильтрован...
Здравствуйте, adontz, Вы писали:
A>Почему не работает? У меня всё работает. Вот код.
A> private class BackColorWorkaroundSubclass : NativeWindow
A> {
…
A> private void OnHandleDestroyed(object sender, EventArgs e)
A> {
A> Detach();
A> }
A> public BackColorWorkaroundSubclass(Control control)
A> {
A> Attach(control);
A> }
A> public void Attach(Control control)
A> {
A> this._control = control;
A> this._brush = new SolidBrush(this._control.BackColor);
A> AssignHandle(this._control.Handle);
A> this._control.HandleDestroyed += new EventHandler(OnHandleDestroyed);
A> }
A> public void Detach()
A> {
A> ReleaseHandle();
A> this._brush = null;
A> }
…
A> }
Occurs when the control's handle is in the process of being destroyed.
… Remarks
During the HandleDestroyed event, the control is still a valid Windows control and the Handle can be recreated by calling the RecreateHandle method.
Здравствуйте, davkos, Вы писали:
D>Смотрю внимательно System.Windows.Forms.DateTimePicker D>Setting the BackColor has no effect on the appearance of the DateTimePicker. To set the background color for the drop-down calendar of the DateTimePicker, see the CalendarMonthBackground property. D>В PropertyGrid его нет вообще, видимо отфильтрован...
Так потому и писался Workaround чтобы самим сделать это свойство осмысленным.