我在WinForms中启动了一个ColorDialog
组件,让用户选择一个特定的自定义控件图表的背景颜色和前景色。两个配置选项都在配置对话框的同一页面上,因此我想在对话框启动时将颜色对话框的标题设置为“背景颜色”以更改图表的背景,并将“网格颜色”设置为更改颜色的网格。这将提供一个有用的用户体验,如果用户不确定他们是否选择更改背景或网格颜色,用户将能够查看图表的标题。
不幸的是,文档似乎没有提及任何操纵ColorDialog
标题的方法。是否可以进行此更改?如果是这样,怎么样?
答案 0 :(得分: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);
}
}
答案 1 :(得分: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);
}
}
答案 2 :(得分:1)
假设ColorDialog公开了它的hWnd(我在这台机器上没有要检查的Visual Studio),你可以使用Win32 SetWindowText API。可以在PInvoke.net找到PInvoke签名。
答案 3 :(得分:0)
我发布此邮件是为了防止其他人在未来几年内遇到此问题。
在OnShow()事件中使用SetWindowText()函数可以正常工作。我不确定哪个版本的Delphi引入了TColorDialog.OnShow,但它至少可以追溯到XE2。
procedure TForm1.ColorDialog1Show(Sender: TObject);
begin
SetWindowText(ColorDialog1.Handle, MyTitle);
end;
出于我的目的,我为MyTitle使用了全局变量,并在调用ColorDialog1.Execute之前分配了适当的文本。