如何更改 ColorDialog 的标题?

发布于 2024-07-17 02:00:56 字数 438 浏览 8 评论 0原文

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

不幸的是,文档似乎没有提到任何操作 ColorDialog 标题的方法。 可以做出这样的改变吗? 如果是这样,怎么办?

I'm spinning up a ColorDialog component in WinForms to let the user select a particular custom control's chart's background color and foreground color. Both configuration options are on the same page of the configuration dialog, so I want to set the title of the color dialog to "Background Color" when the dialog is brought up to change the chart's background, and "Grid Color" to change the color of the grid. This will provide a useful UX where the user will be able to look at the title of the chart if they're not sure whether they chose to change the background or grid color.

Unfortunately, the docs don't seem to mention any way to manipulate the ColorDialog's title. Is it possible to make this change? If so, how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扬花落满肩 2024-07-24 02:00:56

不幸的是,无法更改通用颜色选择器对话框的标题。 一个可能的解决方案是找到或创建一个颜色选择器控件来托管在专用窗体中,当然,您可以分配适当的标题。 或者您可以以组合框的形式采用Office风格的颜色选择

编辑

受到罗布回答的启发,我找到了以下解决方案。 它涉及继承 ColorDialog,从 HookProc 方法并通过 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);
    }
}

Unfortunately, changing the title of the common color picker dialog is not possible. A possible solution is to find or create a color picker control to host in a dedicated form which, of course, you could assign the appropriate title. Or you could adopt the Office style of color picking in the form of a combo box.

EDIT

Inspired by Rob's answer, I found the following solution. It involves inheriting from ColorDialog, snatching the HWND from the HookProc method and calling SetWindowText through 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);
    }
}
浅听莫相离 2024-07-24 02:00:56

我将其发布作为我如何做到这一点的参考。 我使用了 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);
    }
}

I'm posting this as a reference for how I did it. I used WM_INITDIALOG (as referenced in my comment on Tormod's answer)

/// <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);
    }
}
桃酥萝莉 2024-07-24 02:00:56

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

Assuming the ColorDialog exposes its hWnd (I don't have Visual Studio on this machine to check), you could use the Win32 SetWindowText API. The PInvoke signature can be found at PInvoke.net.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文