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

自定义颜色对话框

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.91/5 (5投票s)

2007年6月8日

5分钟阅读

viewsIcon

25595

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.