【问题标题】:How do I change the title of ColorDialog?如何更改 ColorDialog 的标题?
【发布时间】:2009-04-17 20:08:42
【问题描述】:

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

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

【问题讨论】:

    标签: .net winforms colordialog


    【解决方案1】:

    很遗憾,无法更改常用颜色选择器对话框的标题。一种可能的解决方案是找到或创建一个颜色选择器控件,以专用形式托管,当然,您可以分配适当的标题。或者您可以以组合框的形式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);
        }
    }
    

    【讨论】:

    • 我几乎同时发现了同样的事情。不过,我不确定使用 titleSet 变量或仅将其设置在 WM_INITDIALOG (0x0110) 上是否更有意义。
    • 我实际上只是将代码混合在一起,没有考虑窗口消息。如果你问我,在 WM_INITDIALOG 上设置它是一个更好的解决方案。
    【解决方案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);
        }
    }
    

    【讨论】:

    • “SafeNativeMethods 无法访问”。该链接指向哪里?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      我发布这个以防其他人在未来几年遇到这个问题。

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-17
        • 2021-01-09
        • 2016-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-25
        相关资源
        最近更新 更多