如何更改ColorDialog的标题?

问题描述 投票:3回答:4

我在WinForms中启动了一个ColorDialog组件,让用户选择一个特定的自定义控件图表的背景颜色和前景色。两个配置选项都在配置对话框的同一页面上,因此我想在对话框启动时将颜色对话框的标题设置为“背景颜色”以更改图表的背景,并将“网格颜色”设置为更改颜色的网格。这将提供一个有用的用户体验,如果用户不确定他们是否选择更改背景或网格颜色,他们将能够查看图表的标题。

不幸的是,文档似乎没有提及任何操纵ColorDialog标题的方法。是否可以进行此更改?如果是这样,怎么样?

.net winforms colordialog
4个回答
6
投票

遗憾的是,无法更改常用颜色选择器对话框的标题。一种可能的解决方案是找到或创建一个颜色选择器控件,以专用的形式托管,当然,您可以分配适当的标题。或者你可以以组合框的形式adopt the Office style of color picking

编辑

受Rob的回答启发,我找到了以下解决方案。它涉及从ColorDialog继承,从HookProc方法抢夺HWND并通过P / Invoke调用SetWindowText

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
投票

我发布这个作为我如何做的参考。我使用了WM_INITDIALOG(在我对Tormod的回答的评论中引用)

/// <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
投票

假设ColorDialog公开了它的hWnd(我在这台机器上没有Visual Studio来检查),你可以使用Win32 SetWindowText API。 PInvoke签名可以在PInvoke.net找到。


0
投票

我发布这封信以防其他人在未来几年遇到这种情况。

在OnShow()事件中使用SetWindowText()函数可以正常工作。我不确定哪个版本的Delphi引入了TColorDialog.OnShow但它至少回到了XE2。

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

为了我的目的,我使用MyTitle的全局变量,并在调用ColorDialog1.Execute之前分配适当的文本。

© www.soinside.com 2019 - 2024. All rights reserved.