自定义MFC控件:带图像的分割按钮

MFC(Microsoft Foundation Classes)中,创建自定义控件是一种常见的需求,特别是在需要提供更丰富用户界面元素的商业项目中。本文将介绍如何创建一个带有图像的分割按钮(Split Button),这种按钮在用户点击主按钮部分时执行默认操作,而在点击下拉箭头时显示一个下拉菜单。

在开发一个商业项目时,需要添加一个“保存”按钮,该按钮允许以不同的文件格式保存数据。例如,点击“保存”按钮默认以Excel格式保存,同时用户也可以通过下拉菜单选择其他格式,如CSV或Excel。然而,未能找到实现这一功能的代码示例。

SGSplitImageButton类

为了解决这个问题,创建了一个名为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());

在这个例子中,使用了四张图像

  • IDB_MAINIMAGE:将出现在按钮旁边,紧挨着其文本。
  • IDB_MENU1:将出现在第一个菜单选项旁边,紧挨着其文本。
  • IDB_MENU2:将出现在第二个菜单选项旁边,紧挨着其文本。
  • IDB_MENU3:将出现在第三个菜单选项旁边,紧挨着其文本。

接收每个菜单选项的消息

希望在用户选择菜单选项时收到通知。为此,为每个菜单选项定义了私有消息。使用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

创建和使用自定义控件的提示

一般来说,当创建自定义或继承控件时,仍然希望使用资源编辑器,这可以在从资源视图中点击对话框时获得。

  1. 创建一个普通的CSplitButton并将其放置在对话框上。
  2. 在属性标签中给控件一个有意义的ID。
  3. 右键单击控件并按“添加变量”。给控件一个变量名。
  4. 在对话框的头文件中搜索给出的变量名。
  5. 资源编辑器将添加以下行:
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()); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485