CAtlBitmapButton - ATL/WTL 自绘超类化位图按钮





3.00/5 (3投票s)
2001年6月12日
2分钟阅读

72182

1596
一个自绘的 ATL/WTL 位图按钮
引言
最近,在我的一个项目中,我需要构建一个简单的用户界面,由对话框中的一系列位图按钮组成。一些简单且可能易于使用的东西。大约在同一时间,我偶然发现了 David Pizzolato 在 codeproject.com 上发表的关于皮肤按钮的非常好的文章,这引发了我的思考。整个努力的结果是 CAtlBitmapButton - 一个 ATL/WTL 自绘超类化位图按钮。该类实际上并不完整,代表了正在进行的工作。如果你们中的任何人发现它有用,我会很高兴 :-)。
CAtlBitmapButton 类非常友好,您可以立即学会使用它。最困难的部分可能是绘制位图(如果你和我一样在艺术方面有挑战!)。
现在让我们开始学习基础知识。我们将构建一个基于 ATL/WTL 对话框的应用程序,所以我假设您对 ATL/WTL 和 ATL Windowing 有一些了解。


如何使用
要构建客户端,启动 Visual C++ 并创建一个新的 Win32 应用程序。接下来,我们将为项目设置 ATL 支持。因为我们希望拥有 ATL 向导支持,所以只需逐步按照说明进行操作。如果您已经知道如何执行此操作,则可以跳过此部分。首先,在项目的 stdafx.h 文件中,替换
#include <windows.h>用
#define RICHEDIT_VER 0x0100 #include <atlbase.h> extern CComModule _Module; #include <atlcom.h> #include <atlwin.h> #include <atlapp.h> #include <atlctrls.h>
现在向项目添加一个新的 IDL 文件,其中包含一个空白的库定义块,例如
library <Project Name> { };
现在,在类视图中,右键单击您刚刚添加的 IDL 文件,然后选择设置。在项目设置对话框的常规选项卡中,选中从生成中排除文件选项。
接下来,修改您的项目 .cpp 文件,使其如下所示
CComModule _Module; BEGIN_OBJECT_MAP(ObjectMap) END_OBJECT_MAP() int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. _Module.Init(0, hInstance); _Module.Term(); return 0; }
在设置好 ATL/WTL 支持后,转到插入->新建 ATL 对象。在杂项类别中,选择对话框,然后单击下一步。将短名称输入为对话框。
在对话框资源中,添加 4 个按钮 (IDC_BUTTON1,IDC_BUTTON2,IDC_BUTTON3 和 IDC_BUTTON4) 并将这些按钮的 Ownerdraw 属性设置为 true。您还需要向项目添加一些位图,以便每个按钮都有三种状态位图(选中、按下和悬停)。
将文件 CAtlBitmapButton.h 添加到项目中。在类视图中,右键单击对话框类,并向其添加四个 CAtlBitmapButton 类型的成员变量,例如
CAtlBitmapButton m_button1,m_button2,m_button3,m_button4;
在对话框的 OnInitDialog() 中,添加以下代码
m_button1.SubclassWindow(GetDlgItem(IDC_BUTTON1)); m_button1.LoadStateBitmaps(IDB_LOADU, IDB_LOADD, IDB_LOAD); m_button2.SubclassWindow(GetDlgItem(IDC_BUTTON2)); m_button2.LoadStateBitmaps(IDB_PLAYU, IDB_PLAYD, IDB_PLAY); m_button3.SubclassWindow(GetDlgItem(IDC_BUTTON3)); m_button3.LoadStateBitmaps(IDB_SAVEU, IDB_SAVED, IDB_SAVE); m_button4.SubclassWindow(GetDlgItem(ID_BUTTON4)); m_button4.LoadStateBitmaps(IDB_QUITU, IDB_QUITD, IDB_QUIT);
CAtlBitmapButton 有一个方法 LoadStateBitmaps() 来加载状态位图。最后要做的是将 ATL 宏 REFLECT_NOTIFICATIONS() 添加到对话框的消息映射,例如
BEGIN_MSG_MAP(CDialog) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) COMMAND_ID_HANDLER(IDOK, OnOK) COMMAND_ID_HANDLER(IDCANCEL, OnCancel) COMMAND_ID_HANDLER(ID_QUIT, OnQuit) REFLECT_NOTIFICATIONS() END_MSG_MAP()
生成并运行项目。检查按钮是否显示正确的状态位图。要处理按钮点击,请在消息映射中使用 ATL 宏 COMMAND_ID_HANDLER(),如上面的 OK 和 Cancel 按钮的代码所示。 OnCancel 看起来像
LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog(wID); return 0; }
就这样。万岁!
玩得开心。
致谢
David Pizzolato.