在MFC(Microsoft Foundation Classes)中,创建自定义控件是一种常见的需求,特别是在需要提供更丰富用户界面元素的商业项目中。本文将介绍如何创建一个带有图像的分割按钮(Split Button),这种按钮在用户点击主按钮部分时执行默认操作,而在点击下拉箭头时显示一个下拉菜单。
在开发一个商业项目时,需要添加一个“保存”按钮,该按钮允许以不同的文件格式保存数据。例如,点击“保存”按钮默认以Excel格式保存,同时用户也可以通过下拉菜单选择其他格式,如CSV或Excel。然而,未能找到实现这一功能的代码示例。
为了解决这个问题,创建了一个名为SGSplitImageButton的新类,它继承自CSplitButton。这个类允许在下拉菜单选项中插入不仅包含文本,还包含PNG图像的菜单项。
InsertMenu函数允许插入下拉菜单选项,这些选项可以包含文本和PNG图像。首先,需要在.rc文件中定义图像,如下所示:
<IMAGE ID> "PNG" <path to image file>
例如:
IDB_SAVESPLIT_XLS PNG "res\save_excel.png"
然后,调用InsertMenu函数时,imgId将是IDB_SAVESPLIT_XLS。
m_SaveWorksheet.InsertMenu(_T("Save Excel"), IDB_SAVESPLIT_XLS, WM_SAVE_XSL);
SetDropDown函数调用CSplitButton的SetDropDownMenu()函数。
按钮的初始化过程如下:
CPngImage btnImg;
btnImg.Load(IDB_MAINIMAGE, nullptr);
m_MySplit.SendMessageW(BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)btnImg.GetSafeHandle());
在这个例子中,使用了四张图像:
希望在用户选择菜单选项时收到通知。为此,为每个菜单选项定义了私有消息。使用WM_USER + 1, 2等。
#define WM_SAVE_XSL WM_USER + 5
#define WM_SAVE_CSV WM_USER + 6
或者:
#define WM_MENUOPTION1 WM_USER + 1
#define WM_MENUOPTION2 WM_USER + 2
#define WM_MENUOPTION3 WM_USER + 3
一般来说,当创建自定义或继承控件时,仍然希望使用资源编辑器,这可以在从资源视图中点击对话框时获得。
CSplitButton m_SaveWorksheet;
需要将其更改为:
SGSplitImageButton m_SaveWorksheet;
或者:
SGSplitImageButton m_MySplit;
需要包含"SGSplitImageButton.h"。
为了创建按钮的默认操作,并将其更改为上次选择的菜单,添加了以下成员函数。
void SGSplitImageButton::SetMainImage(int MenuImageNumber)
{
CPngImage btnImg;
if (m_ImageIDs.size() > MenuImageNumber)
{
btnImg.Load(m_ImageIDs[MenuImageNumber], nullptr);
this->SendMessageW(BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)btnImg.GetSafeHandle());
}
}