Как мне изменить название ColorDialog? - PullRequest
3 голосов
/ 18 апреля 2009

Я запускаю компонент ColorDialog в WinForms, чтобы пользователь мог выбрать цвет фона и цвет переднего плана конкретного пользовательского элемента управления. Оба параметра конфигурации находятся на одной странице диалогового окна конфигурации, поэтому я хочу установить заголовок диалогового окна цвета на «Цвет фона», когда диалоговое окно вызывается для изменения фона диаграммы, и на «Цвет сетки» для изменения цвета сетки. Это обеспечит полезный UX, где пользователь сможет посмотреть на заголовок диаграммы, если он не уверен, что он решил изменить цвет фона или сетки.

К сожалению, в документах, похоже, не упоминается способ манипулирования заголовком ColorDialog. Можно ли сделать это изменение? Если да, то как?

Ответы [ 4 ]

6 голосов
/ 18 апреля 2009

К сожалению, изменение заголовка диалогового окна общего выбора цвета невозможно. Возможное решение состоит в том, чтобы найти или создать элемент управления для выбора цвета для размещения в выделенной форме, которой, конечно же, можно назначить соответствующий заголовок. Или вы могли бы принять стиль выбора цвета Office в виде поля со списком.

EDIT

Вдохновленный ответом Роба, я нашел следующее решение. Он включает в себя наследование от 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);
    }
}
2 голосов
/ 27 мая 2009

Я публикую это как справку о том, как я это сделал. Я использовал 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);
    }
}
1 голос
/ 18 апреля 2009

Предполагая, что ColorDialog предоставляет свой hWnd (у меня на этом компьютере нет Visual Studio для проверки), вы можете использовать Win32 SetWindowText API. Подпись PInvoke находится по адресу PInvoke.net .

0 голосов
/ 06 сентября 2018

Я публикую это на случай, если другие столкнутся с этим в ближайшие годы.

Использование функции SetWindowText () в событии OnShow () работает нормально. Я не уверен, какая версия Delphi представила TColorDialog.OnShow, но она, по крайней мере, восходит к XE2.

procedure TForm1.ColorDialog1Show(Sender: TObject);
  begin
  SetWindowText(ColorDialog1.Handle, MyTitle);
  end;

В своих целях я использую глобальную переменную для MyTitle и назначаю соответствующий текст перед вызовом ColorDialog1.Execute.

...