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

带XP主题的WTL颜色选择器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (21投票s)

2002 年 6 月 14 日

5分钟阅读

viewsIcon

197867

downloadIcon

4316

WTL应用程序的颜色选择器控件,包含可选的XP主题支持。

Sample Image - wtlcolorbutton.jpg

引言

我使用了 James White 的颜色拾取按钮,而 James White 又参考了 Chris Maunder 的Office 97 颜色拾取控件,并在此基础上创建了一个针对 Office XP 设计、用于 WTL 的更新的颜色拾取控件。

更改列表包括:

  1. 修改为 WTL 使用。
  2. 更新样式以更接近 Office XP 颜色拾取器。
  3. 可选支持 XP 主题。
  4. 控件使用 WM_NOTIFY 而非 WM_COMMAND
  5. 通过使用捕获消息循环来处理拾取器,最终解决了烦人的对话框栏焦点问题。
  6. 代码现在真的太棒了。真的太棒了。

注意:要获得此控件的全部功能,需要 VS.NET/ATL7/WTL7。它未经过 ATL3/WTL3 测试,但由于主题支持是可选的,因此很有可能工作正常。

将 CColorButton 添加到 WTL 应用程序。

  1. 第一步是将 CColorButton.h 和 CColorButton.cpp 复制到您的应用程序目录。
  2. 接下来,将这两个文件添加到您的项目中。
  3. 如果未正确定义 WINVER 和 _WIN32_WINNT,许多小功能将无法启用。您可以在 stdafx.h 中定义这些值。
  4. 如果您想要 XP 主题支持,请在您的 stdafx.h 文件中添加 "#include <atltheme.h>"。这应该放在所有其他 ATL include 之后。
  5. CColorButton 大量使用了 ATL 的辅助类型。您需要确保 "atltypes.h" 和 "atlgdi.h" 已包含在 stdafx.h 中。
  6. 使用资源编辑器在目标对话框中添加一个按钮。您无需对按钮进行任何样式调整。
  7. 编辑对话框类的定义。在消息映射中,添加 "REFLECT_NOTIFICATIONS ()"。
  8. 在对话框类定义之前添加 "#include "ColorButton.h""。
  9. 为对话框添加一个新的成员变量。类将是 "CColorButton",您可以任意命名。
  10. 在对话框的 OnInitDialog 中,添加一行以子类化控件。重要的是要进行子类化,而不仅仅是分配一个窗口句柄。

这是一个正确子类化控件的示例。

LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, 
                               LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	// center the dialog on the screen

	CenterWindow();

	m_btnMyColor1 .SubclassWindow (GetDlgItem (IDC_COLOR_1));
	m_btnMyColor2 .SubclassWindow (GetDlgItem (IDC_COLOR_2));
	m_btnMyColor3 .SubclassWindow (GetDlgItem (IDC_COLOR_3));

	m_btnMyColor2 .SetDefaultText (_T (""));
	m_btnMyColor2 .SetCustomText (_T (""));
	m_btnMyColor3 .SetDefaultText (_T ("My Default Text"));
	m_btnMyColor3 .SetCustomText (_T (""));
	return TRUE;
}

以下是各种功能由宏启用功能的列表。

启用的功能
_WIN32_WINNT 0x0501 主题支持
XP 扁平菜单支持
XP 下拉阴影支持
WINVER 0x0500 多显示器支持
XP 菜单高亮颜色支持
WINVER 0x0501 XP 菜单高亮颜色支持

对于大多数应用程序, _WIN32_WINNT WINVER 都应定义为 0x0501。 CColorButton 控件将自动降级,如果操作系统不提供 _WIN32_WINNTWINVER 启用的功能。

颜色拾取器如何处理颜色

颜色拾取器支持三种类型的颜色:默认、自定义和调色板。调色板颜色是用户看到的以小色块数组形式显示的颜色。默认颜色以顶部一个带有应用程序提供的文本的大按钮的形式显示给用户。此文本的默认值是 "Automatic"。自定义颜色以底部一个带有应用程序提供的文本的大按钮的形式显示给用户。此文本的默认值是 "Custom..."。

Chris 最初实现颜色拾取器的一个优点是,99% 的功能对应用程序开发人员来说是完全透明的。当应用程序与颜色拾取器交互时,它只需要关心当前选定的颜色。此颜色是标准的 COLORREF,可以使用 RGB(红、绿、蓝)宏轻松设置。当应用程序需要将颜色拾取器设置为特定值时,只需将 COLORREF 值传递给 SetColor 方法。当需要检索当前颜色时,只需调用 GetColor 方法。

除了处理默认颜色外。

处理默认颜色

默认颜色使用特殊 COLORREFCLR_DEFAULT 来处理。当此值传递给 SetColor 方法时,颜色按钮会识别它为一个特殊值。当实际显示拾取器时,将高亮显示默认选择。但是,当设置默认颜色时,颜色按钮必须知道要在按钮上显示什么颜色。此颜色可以通过使用 SetDefaultColor 方法设置。如果未设置此值,则颜色按钮将显示应用程序工作区背景的默认颜色。

当用户在颜色拾取器中选择默认颜色时,GetColor 方法将返回 CLR_DEFAULT。这允许应用程序区分用户选择了默认颜色,还是从调色板中选择了一个与实际默认颜色具有相同 RGB 值的颜色。

处理自定义颜色

自定义颜色对应用程序开发人员来说是完全透明的。无需特殊编程。

CColorButton 公共成员函数

// Return the currently selected color


COLORREF GetColor (void) const;

// Set the current color


void SetColor (COLORREF clrCurrent);

// Get the default color


COLORREF GetDefaultColor (void) const;

// Set the default color.  This value should be a real color value

// and not CLR_DEFAULT.


void SetDefaultColor (COLORREF clrDefault);

// Set the custom text.  Specify _T ("") to disable the custom 

// text button.


void SetCustomText (LPCTSTR pszText);

// Set the custom text via a resource string.  Specify a 0 to

// disable the custom text button.


void SetCustomText (UINT nID);

// Set the default text.  Specify _T ("") to disable the default 

// text button.


void SetDefaultText (LPCTSTR pszText);

// Set the default text via a resource string.  Specify a 0 to

// disable the default text buttom.


void SetDefaultText (UINT nID);

// Get the tracking flag


BOOL GetTrackSelection (void) const;

// Set the tracking flag.  When enabled, the application will be

// sent color change notifications as the user tracks around the

// picker.


void SetTrackSelection (BOOL fTrack);

// Set both strings from a resource


void SetText (UINT nDefault, UINT nCustom);

// Do we have custom text


BOOL HasCustomText () const;

// Do we have default text


BOOL HasDefaultText () const;

处理通知

通知使用标准的 WM_NOTIFY 消息发送。

#define CPN_SELCHANGE        0x8000	/* Colour Picker Selection change */
#define CPN_DROPDOWN         0x8001	/* Colour Picker drop down */
#define CPN_CLOSEUP          0x8002	/* Colour Picker close up */
#define CPN_SELENDOK         0x8003	/* Colour Picker end OK */
#define CPN_SELENDCANCEL     0x8004	/* Colour Picker end (cancelled) */

struct NMCOLORBUTTON
{
	NMHDR	hdr;
	BOOL	fColorValid;
	COLORREF	clr;
};

CPN_SELCHANGE 在用户更改当前选择后发送到父窗口。当用户在拾取器窗口中跟踪不同按钮时,也会发送此消息。如果用户在跟踪时取消拾取器,当颜色恢复到显示拾取器之前的选定颜色时,CPN_SELCHANGE 将发送到父窗口。当 CPN_SELCHANGE 作为跟踪的一部分发送时,通知结构中的 fColorValid 元素如果用户正在跟踪一个有效的颜色选择,则设置为 true。如果为 false,则表示鼠标已移出拾取器窗口。

CPN_DROPDOWN 在拾取器窗口显示之前发送到父窗口。

CPN_CLOSEUP 在拾取器窗口关闭后发送到父窗口。

CPN_SELENDOK 在拾取器窗口已关闭且选择有效(未取消)后发送到父窗口。

CPN_SELENDCANCEL 在拾取器窗口已关闭但被用户取消后发送到父窗口。

© . All rights reserved.