CColourPickerXP - 一个主题感知颜色选择器,带 2 种样式。






4.92/5 (45投票s)
2003年2月3日
5分钟阅读

181004

6353
一个主题感知的 MFC 颜色选择器控件,它结合了 CodeProject 上其他颜色选择器的功能,并添加了一些新功能。
![]() 按钮样式 |
|
![]() 组合框样式 |
![]() ![]() 当然,还有经典的样式... |
引言
最近,我需要一个颜色选择器来做一个项目。我在 CodeProject 上找到了三篇相关的文章,我以此为基础创建了自己的控件。
因为我需要一个主题感知的 MFC 控件,所以这些文章中的控件都不能完全满足我的需求。于是我决定创建自己的控件,并加入了以下功能:
- XP 主题支持
- 2 种样式:按钮和组合框。
- 将 16 种自定义颜色存储在注册表中。也提供静态版本。
- 从资源加载颜色名称。
- (仅组合框样式) 显示 RGB 值。
- 子类化可能性 (虚拟绘制函数)。
- 使用内存 DC 防止闪烁。
对于主题支持,我使用了 Pål Kristian Tønder 的 `CXPTheme` 类。内存 DC 是通过 Keith Rule 的 `CMemDC` 类实现的。
使用代码
要使用此控件,请遵循以下步骤:
- 将这五个文件复制到您的项目目录中,并将其添加到您的项目中。
- 在您的对话框中添加一个按钮,并使用类向导添加一个变量。
- 在对话框的头文件中添加
#include "ColourPickerXP.h"
。 - 在按钮定义中,将 `CButton` 改为 `CColourPickerXP`。
- 您可以在对话框类的 `OnInitDialog` 函数中修改选择器的参数。
要启用多显示器支持,您需要在 *stdafx.h* 中将 `WINVER` 宏设置为至少 0x0500
。
属性和函数
__declspec(property(get=GetColor,put=SetColor)) COLORREF Color; virtual COLORREF GetColor(void) const; virtual COLORREF GetColor(BOOL bTranslateDefault) const; virtual void SetColor(COLORREF Color);
获取或设置活动颜色。
使用 `CLR_DEFAULT` 表示默认颜色。当使用 `GetColor(TRUE)` 时,默认颜色会转换为 `SetDefaultColor` 设置的颜色。
__declspec(property(get=GetDefaultColor,put=SetDefaultColor)) COLORREF DefaultColor; virtual COLORREF GetDefaultColor(void) const; virtual void SetDefaultColor(COLORREF Color);
获取或设置默认颜色。
当用户选择默认颜色时,将显示此颜色。当使用 `GetColor(TRUE)` 且用户选择了默认颜色时,也将返回此颜色。
__declspec(property(get=GetTrackSelection,put=SetTrackSelection)) BOOL TrackSelection; virtual BOOL GetTrackSelection(void) const; virtual void SetTrackSelection(BOOL bTrack);
获取或切换跟踪选择。
__declspec(property(put=SetCustomText)) LPCTSTR CustomText; virtual void SetCustomText(LPCTSTR tszText);
设置自定义颜色框的文本。
默认为“更多颜色...” 。
使用 "" 来隐藏自定义颜色框。
__declspec(property(put=SetDefaultText)) LPCTSTR DefaultText; virtual void SetDefaultText(LPCTSTR tszText);
设置默认颜色框的文本。
默认为“自动”。
使用 "" 来隐藏默认颜色框。
__declspec(property(put=SetColoursName)) UINT ColoursName; static void SetColoursName(UINT nFirstID = 0);
从资源加载颜色名称。nFirstID
是第一个颜色 (即黑色) 的资源 ID。
如果 `nFirstID` 为 0,则加载默认的英文名称。
__declspec(property(put=SetRegSection)) LPCTSTR RegSection; __declspec(property(put=SetRegSectionStatic)) LPCTSTR RegSectionStatic; virtual void SetRegSection(LPCTSTR tszRegSection = _T("")); static void SetRegSectionStatic(LPCTSTR tszRegSection = _T(""));
设置用于保存颜色选择对话框的 16 种自定义颜色的注册表项。
使用 "" 来禁用。
如果存在非静态版本,将使用它。否则将使用静态版本。如果两者均未定义,颜色将不会被保存。
注意:请确保 (尤其是在对话框项目中) 您已在 `CWinApp::InitInstance` 中使用 `SetRegistryKey(_T("Your registry key here"));` 设置了注册表项。
__declspec(property(get=GetStyle,put=SetStyle)) BOOL Style; virtual BOOL GetStyle(void) const; virtual void SetStyle(BOOL bComboBoxStyle);
获取或设置控件的样式: `FALSE` 表示按钮,`TRUE` 表示组合框。
切换到组合框样式时,高度将根据文本高度进行设置。
__declspec(property(put=SetRGBText)) LPCTSTR RGBText; virtual void SetRGBText(LPCTSTR tszRGB = _T("RGB"));
(仅组合框样式)
设置用于显示 RGB 值的三个字母。
如果输入的文本少于 3 个字母,则用空格替换缺失的字母。
__declspec(property(get=GetAlwaysRGB,put=SetAlwaysRGB)) BOOL ShowRGBAlways; virtual BOOL GetAlwaysRGB(void) const; virtual void SetAlwaysRGB(BOOL bShow);
(仅组合框样式)
当颜色名称已知时,在括号中显示 RGB 值。当颜色名称未知时 (例如,用户选择了自定义颜色),即使您在此处设置为 `FALSE`,RGB 值也始终显示。
CFont* GetFont() const; void SetFont(CFont* pFont, BOOL bRedraw = TRUE);
(仅组合框样式)
获取或设置字体。
弹出窗口不使用此字体。
调用 `SetStyle` 以调整控件的高度,以匹配新设置的字体。
有关更多信息,请参阅 `CWnd` 类的相应函数。
消息
为了处理 `CColourPickerXP` 控件生成的 Tmessage,您需要手动将消息处理程序添加到您的消息映射中。
ON_MESSAGE( Message, MessageFn)
MessageFn
的形式为:afx_msg LONG MessageFn(UINT lParam, LONG wParam);`lParam` 指示颜色,`wParam` 返回控件 ID。
对于 `Message`,您可以从以下选项中选择:
Message | 描述 |
CPN_SELCHANGE |
颜色选择器选择更改 |
CPN_DROPDOWN |
颜色选择器下拉 |
CPN_CLOSEUP |
颜色选择器关闭 |
CPN_SELENDOK |
颜色选择器确定结束 |
CPN_SELENDCANCEL |
颜色选择器取消结束 |
关注点
如果您查看 Windows XP 中找到的颜色按钮,您会注意到一些“不完美之处”:
- 没有鼠标悬停支持。
- 焦点矩形放置得不太好。
- 弹出窗口使用的是旧的 Windows 95 样式。
- 有时,您会看到一个难看的边框。我遇到了同样的问题,但通过发送一个 `WM_ERASEBKGND` 消息并将内存 DC 作为参数来解决了它。
致谢
- Chris Maunder 的原始 `CColourPicker` 控件
- James White 对 `CColorButton` 的修改
- Tim Smith 的 WTL 颜色按钮
- Pål Kristian Tønder 的主题包装器
- Keith Rule 的 `CMemDC` 类
- 其他人 (参见下文的“历史记录”部分)
历史
版本 | 详细说明 |
版本 1.4 | 修复:由于绘制弹出窗口后未恢复 DC 而出现的“需要资源”对话框 (感谢 Kris Wojtas, KRI Software)。 |
当禁用平面菜单时,在弹出窗口中使用旧样式选择矩形。 | |
现在,当用户按下 F4 键或向下箭头键时,弹出窗口会弹出。 | |
修改:当弹出窗口中没有选择颜色时,可以使用箭头键进行移动。 | |
版本 1.3 | 弹出窗口在屏幕上显示时,父窗口仍然保持活动状态 (感谢 Damir Valiulin)。 |
当使用跟踪选择时,对于无效选择,将显示初始颜色而不是黑色。 | |
添加:`GetColor` 中的 `bTranslateDefault` 参数。 | |
版本 1.2 | 修复:在发布配置中,当没有“自动”或“自定义”标签时,弹出窗口将无法工作。 |
禁用的组合框现在已正确绘制。 | |
组合框的高度现在取决于文本大小。 | |
字体支持:使用 `SetFont` 和 `GetFont`。对于组合框样式,在更改字体后调用 `SetStyle`。 | |
版本 1.1 | 修复了 VC6 中的一些编译错误。 |
除了多显示器支持外,不再需要更改 *stdafx.h* 中的定义。 | |
版本 1.0 | 首次发布。 |