Как мне изменить название ColorDialog?
Я раскручиваю ColorDialog
компонент в WinForms, позволяющий пользователю выбрать цвет фона и цвет переднего плана конкретного пользовательского элемента управления. Оба параметра конфигурации находятся на одной странице диалогового окна конфигурации, поэтому я хочу установить заголовок диалогового окна цвета на "Цвет фона", когда диалоговое окно вызывается для изменения фона диаграммы, и на "Цвет сетки" для изменения цвета сетки. Это обеспечит полезный UX, где пользователь сможет посмотреть на заголовок диаграммы, если он не уверен, что он решил изменить цвет фона или сетки.
К сожалению, в документах, похоже, не упоминается какой-либо способ манипулирования ColorDialog
название Можно ли сделать это изменение? Если так, то как?
4 ответа
К сожалению, изменение заголовка диалогового окна выбора цвета невозможно. Возможное решение состоит в том, чтобы найти или создать элемент управления для выбора цвета для размещения в выделенной форме, которой, конечно же, можно назначить соответствующий заголовок. Или вы можете выбрать стиль выбора цвета Office в виде поля со списком.
РЕДАКТИРОВАТЬ
Вдохновленный ответом Роба, я нашел следующее решение. Он включает в себя наследование от ColorDialog, отрыв HWND от метода HookProc и вызов SetWindowText через P/Invoke:
public class MyColorDialog : ColorDialog
{
[DllImport("user32.dll")]
static extern bool SetWindowText(IntPtr hWnd, string lpString);
private string title = string.Empty;
private bool titleSet = false;
public string Title
{
get { return title; }
set
{
if (value != null && value != title)
{
title = value;
titleSet = false;
}
}
}
protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
{
if (!titleSet)
{
SetWindowText(hWnd, title);
titleSet = true;
}
return base.HookProc(hWnd, msg, wparam, lparam);
}
}
Я публикую это как справку о том, как я это сделал. Я использовал WM_INITDIALOG (как указано в моем комментарии к ответу Тормода)
/// <summary>
/// The standard ColorDialog dialog box with a title property.
/// </summary>
public class ColorDialogWithTitle : ColorDialog
{
private const int InitDialogMessage = 0x0110; // WM_INITDIALOG
/// <summary>
/// Initializes a new instance of the ColorDialogWithTitle class.
/// </summary>
public ColorDialogWithTitle() :
base()
{
this.Title = Resources.ColorDialogWithTitle_DefaultTitle;
return;
}
/// <summary>
/// Gets or sets the title that will be displayed on the dialog when it's shown.
/// </summary>
[Browsable(true)]
[Category("Appearance")]
[Description("The title that will be displayed on the dialog when it's shown.")]
public string Title
{
get;
set;
}
/// <summary>
/// The hook into the dialog's WndProc that we can leverage to set the
/// window's text.
/// </summary>
/// <param name="hWnd">The handle to the dialog box window.</param>
/// <param name="msg">The message being received.</param>
/// <param name="wparam">Additional information about the message.</param>
/// <param name="lparam">More additional information about the message.</param>
/// <returns>
/// A zero value if the default dialog box procedure processes the
/// message, a non-zero value if the default dialog box procedure
/// ignores the message.
/// </returns>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
{
if (msg == InitDialogMessage)
{
// We'll ignore failure cases for now. The default text isn't
// so bad and this isn't library code.
SafeNativeMethods.SetWindowText(hWnd, this.Title);
}
return base.HookProc(hWnd, msg, wparam, lparam);
}
}
Предполагая, что ColorDialog предоставляет свой hWnd (у меня на этом компьютере нет Visual Studio для проверки), вы можете использовать Win32 SetWindowText API. Подпись PInvoke можно найти на PInvoke.net.
Я публикую это на случай, если другие столкнутся с этим в ближайшие годы.
Использование функции SetWindowText() в событии OnShow() работает нормально. Я не уверен, какая версия Delphi представила TColorDialog.OnShow, но она восходит по крайней мере к XE2.
procedure TForm1.ColorDialog1Show(Sender: TObject);
begin
SetWindowText(ColorDialog1.Handle, MyTitle);
end;
В своих целях я использую глобальную переменную для MyTitle и назначаю соответствующий текст перед вызовом ColorDialog1.Execute.