WTL - 按钮菜单






3.50/5 (2投票s)
2000年7月28日

113989

2190
使用 WTL 创建实现下拉菜单的简单按钮。
DevStudio 的“工具|自定义”菜单显示一个包含带有箭头按钮的对话框。按下按钮时,将显示一个下拉菜单。我需要在我的 ATL 应用程序中使用此功能,但不想使用 MFC 的开销,也不想处理 Win32 的复杂性。因此,我借鉴了 Norm Almond 出色的 Cool Push Menu Button 示例,并将其移植到 WTL,同时简化了其功能。我并不是暗示 Norm 开发的有什么问题……只是该控件的功能比我需要的要多。如果时间允许,我最终会将他的整个控件移植到 WTL。
注意事项
CButtonMenu
继承自 CButtonMenuImpl
。为了在按钮上绘制箭头,CButtonMenuImpl
需要设置 BS_OWNERDRAW 样式。但是,这将向 CButtonMenuImpl
的父窗口发送 WM_DRAWITEM 消息,而不是发送给 CButtonMenuImpl
本身。通过子类化父窗口的 HWND,CButtonMenuImpl
可以劫持该消息并单独处理它。为此,CButtonMenuImpl
具有一个私有成员变量 CContainedWindow
,用于子类化父窗口。然后,使用 ALT_MSG_MAP() 宏,我们可以捕获该消息
class CButtonMenuImpl : ...
{
CContainedWindow m_Parent;
public:
CButtonMenuImpl():
m_Parent(this,1){}
{other code}
protected:
typedef CWindowImpl<T, TBase, TWinTraits> baseClass;
BEGIN_MSG_MAP(CButtonMenuImpl)
other msgs
ALT_MSG_MAP(1)
MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
END_MSG_MAP()
{other code}
};
最后,为了简单地使用此控件,CButtonMenu
提供了一个运算符重载class CButtonMenu : public CButtonMenuImpl<CButtonMenu>
{
public:
DECLARE_WND_SUPERCLASS(_T("WTL_CButtonMenu"), GetWndClassName())
//ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
CButtonMenu& operator=(HWND hWnd)
{
if ( m_hWnd )
DestroyWindow();
if ( ::IsWindow(hWnd) )
SubclassWindow(hWnd);
return *this;
}
};
以下是如何使用对话框中已有的按钮初始化 CButtonMenu
的示例 // Member variable of dialog
CButtonMenu btnMenu;
// Somewhere in WM_INITDIALOG handler
btnMenu = GetDlgItem(IDC_BTN_ABOUT);
btnMenu.AddMenuItem(IDC_MNU_ONE,"Windows");
btnMenu.AddMenuItem(IDC_MNU_TWO,"Template");
btnMenu.AddMenuItem(IDC_MNU_THREE,"",MF_SEPARATOR);
btnMenu.AddMenuItem(IDC_MNU_FOUR,"Library");
当用户选择菜单项时,将向对话框发送一条消息。
不足之处