65.9K
CodeProject 正在变化。 阅读更多。
Home

自定义颜色对话框

starIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

1.00/5 (2投票s)

2007年6月8日

5分钟阅读

viewsIcon

30602

downloadIcon

307

通过重写窗口过程方法来自定义颜色对话框


引言

颜色对话框是 C#.NET 中的一个预定义对话框,我们可以用它来在运行时选择和更改控件的颜色。它允许我们通过有限的属性和可用的事件进行一些修改。

与其他窗口窗体一样,它没有 Paint 事件或 BackColor 属性来根据我们的需求进行更改。在我们的许多应用程序中,我们需要更改对话框的外观,但这并非直接可能。在这段代码中,我重写了 WinProc() 方法,从而跟踪窗口消息并将我自己的方法整合进来以绘制对话框。通过使用这段代码,任何人都可以根据自己的需求更改外观。

Screenshot - color.jpg

背景

有了基本的编程知识,应该对窗口过程、窗口消息和消息处理有很好的了解。我们可以通过捕获 WM_Paint 消息来整合我们自己的方法来绘制颜色对话框,我在这里使用了渐变画笔来绘制对话框的背景。


使用代码

您可以使用 zip 文件中提供的代码来更改颜色对话框的外观。通过遵循相同的步骤,可以更改任何其他对话框的外观。

可以使用 Visual Studio 附带的 WinSpy++ 来获取对话框上不同控件的窗口句柄和控件 ID。

以下是可以用于更改对话框外观的消息列表:

private const int WM_DESTROY = 0x0002;
private const int WM_PAINT = 0x000F;
private const int WM_INITDIALOG = 0x0110;
private const int WM_COMMAND = 0x0111;
private const int BN_CLICKED = 0;
private const int BN_PAINT = 0;
private const int WM_CTLCOLORBTN = 0x0135;
private const int WM_CTLCOLORSTATIC = 0x0138;
private const int WS_CHILD = 0x40000000;
private const int WM_CTLCOLORDLG = 0x0136;
private const int MSG_MOVETOTOPMOST = 0x00F2;
private const int WM_CTLCOLOREDIT = 0x0133;
private const int WM_DRAWITEM = 0x002B;
private const UInt32 WM_NCPAINT = 0x0085;
private const int WM_ERASEBKGND = 0x0014;
private const int WM_WINDOWPOSCHANGED = 0x0047;

对话框上不同控件的控件 ID 列表

private const int ID_OK = 1;
private const int ID_CANCEL = 2;
private const int DLG_COLOR = 10;
private const int NUM_BASIC_COLORS = 48;
private const int COLOR_SOLID_LEFT = 730;
private const int COLOR_SOLID_RIGHT = 731;
private const int COLOR_HUE = 703; // 编辑
private const int COLOR_SAT = 704; // 编辑
private const int COLOR_LUM = 705; // 编辑
private const int COLOR_RED = 706; // 编辑
private const int COLOR_GREEN = 707; // 编辑
private const int COLOR_BLUE = 708; // 编辑
private const int COLOR_CURRENT = 709;
private const int COLOR_RAINBOW = 710; //颜色渐变轮
private const int COLOR_ELEMENT = 716;
private const int COLOR_ADD = 712; // 按钮: "&添加自定义颜色"
private const int COLOR_MIX = 719; // 按钮: "&定义颜色 >>"
private const int COLOR_BOX1 = 720; // 静态: 基本颜色
private const int COLOR_CUSTOM1 = 721; // 静态: 自定义颜色
private const int COLOR_HUEACCEL = 723; // 标签编辑
private const int COLOR_SATACCEL = 724; // 标签编辑
private const int COLOR_LUMACCEL = 725; // 标签编辑
private const int COLOR_REDACCEL = 726; // 标签编辑
private const int COLOR_GREENACCEL = 727; // 标签编辑
private const int COLOR_BLUEACCEL = 728; // 标签编辑

控件被归类为“静态”、“编辑”、“按钮”等。有一个控件 ID 为 Color_RAINBOW 的颜色渐变轮,这是我们可以输入 RGB 值或色相、饱和度和亮度值来更改颜色的轮盘。

通过窗口过程,我们还可以更改颜色对话框的大小,并可以添加我们需要的控件显示在对话框上。所有这些都可以通过跟踪所需的修改的窗口消息来轻松完成。

除了窗口消息和控件 ID 之外,还应该从 User32.dll 导入必要的函数来实际提供窗口句柄并在对话框上进行操作。示例如下:

private static extern bool GetWindowRect(int hWnd, ref Rectangle lpRect);

[DllImport("user32.dll")]
private static extern int GetParent(int hWnd);

[DllImport("user32.dll")]
private static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);

[DllImport("user32.dll")]
static extern uint GetDlgItemInt(IntPtr hDlg, int nIDDlgItem, IntPtr lpTranslated, bool bSigned);

[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

[DllImport("user32.dll")]
private static extern int GetDlgCtrlID(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool repaint);

[DllImport("user32.dll")]
private static extern bool UpdateWindow(IntPtr hWnd);

[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool redraw);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int InvalidateRect(IntPtr hWnd, IntPtr rc, int bErase);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool SetWindowPos(IntPtr hWnd,IntPtr hWndInsertAfter, int x, int y, int Width, int Height, SetWindowPosFlags flags);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool LockWindowUpdate(IntPtr hWndLock);

[DllImport("gdi32.dll")]
static extern uint SetBkColor(IntPtr hdc, int crColor);

[DllImport("gdi32.dll")]
static extern int SetBkMode(IntPtr hdc, int iBkMode);

//[DllImport("user32.dll", CharSet = CharSet.Auto)]
//static bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);

[DllImport("gdi32.dll")]
static extern IntPtr GetStockObject(int fnObject);

//rotected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
        {
            switch (msg)
            {
                case WM_ERASEBKGND:
                    Graphics gfr = Graphics.FromHwnd(hWnd);
                    LinearGradientBrush lnrfr = new LinearGradientBrush(new Point(0, 0), new Point(400, 400), Color.CornflowerBlue, Color.White);
                    gfr.FillRegion(lnrfr, gfr.Clip);
                    break;
            
              
            }

            return base.HookProc(hWnd, msg, wparam, lparam);
        
        }
    }
}

//


关注点

MSDN 上提供了很多关于修改对话框的信息,但这次没有一个真正帮到我,尽管 MSDN 在其他情况下很有帮助。

© . All rights reserved.