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

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

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (3投票s)

2001年6月12日

2分钟阅读

viewsIcon

72182

downloadIcon

1596

一个自绘的 ATL/WTL 位图按钮

引言

最近,在我的一个项目中,我需要构建一个简单的用户界面,由对话框中的一系列位图按钮组成。一些简单且可能易于使用的东西。大约在同一时间,我偶然发现了 David Pizzolatocodeproject.com 上发表的关于皮肤按钮的非常好的文章,这引发了我的思考。整个努力的结果是 CAtlBitmapButton - 一个 ATL/WTL 自绘超类化位图按钮。该类实际上并不完整,代表了正在进行的工作。如果你们中的任何人发现它有用,我会很高兴 :-)。

CAtlBitmapButton 类非常友好,您可以立即学会使用它。最困难的部分可能是绘制位图(如果你和我一样在艺术方面有挑战!)。

现在让我们开始学习基础知识。我们将构建一个基于 ATL/WTL 对话框的应用程序,所以我假设您对 ATL/WTL 和 ATL Windowing 有一些了解。

         

如何使用

要构建客户端,启动 Visual C++ 并创建一个新的 Win32 应用程序。接下来,我们将为项目设置 ATL 支持。因为我们希望拥有 ATL 向导支持,所以只需逐步按照说明进行操作。如果您已经知道如何执行此操作,则可以跳过此部分。首先,在项目的 stdafx.h 文件中,替换

 #include &ltwindows.h>
#define RICHEDIT_VER 0x0100
#include &ltatlbase.h> 

extern CComModule _Module;
#include &ltatlcom.h> 

#include &ltatlwin.h>

#include &ltatlapp.h>

#include &ltatlctrls.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_BUTTON3IDC_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.

© . All rights reserved.