MFC制作位图按钮
前序
学习过MFC的读者应该都知道MFC自带的控件是相当丑陋的,我曾在自带按钮的基础上做了一些美化可总会遇到挺多问题,当然也是技术不过关的表现,我在原本的按钮上添加图标后,觉得按钮样式太丑了,想给MFC使用皮肤样式,但这时却出现了各种不兼容问题(图片显示不了了),之后我也没细细研究了。后来想着还是制作自己的按钮比较好看点,最近在看一个开源项目的时候发现了项目里面的按钮是使用位图制作的,于是我详读了下代码并自己手动实现了这位图按钮。
制作过程
先看看效果图:
温馨提示:链接:位图资源可以到我的百度云中下载:https://pan.baidu.com/s/1-lxPHqCAN2C_NAZ_BgKWoA 密码:xhv4
1、我们新建一个MFC程序,命名为MyButton。
2、添加我们要使用的位图:找到资源视图->右击MYButton->添加->资源(弹出一个添加资源对话框)->单击Bitmap->选择右边的导入->找到你要导入的位图
3、在资源视图下可以看到Bitmap这栏->双击打开我们刚刚添加的位图->右键选择属性->修改位图ID为:IDB_BITMAP_MAIN
4、我们现在有了位图,那么接下来还需要添加Toolbar,依旧是在资源视图上右键MyButton->添加->资源->单击Toolbar->右边选择新建
5、在资源视图中找到Toolbar下刚刚添加的Toolbar,并双击打开->右键属性修改ID为:IDR_TOOLBAR_MAIN
6、双击IDR_TOOLBAR_MAIN后你可以看到里面有一个方框->右键方框选择属性->设置Height跟Weight,这里我设置的都是48,这时我们需要对这个方框进行拷贝(位图中有几个图标我们一般就创建几个方框),点击第一个方框ctrl+c->在空白处ctrl+v,再点击第二个方框ctrl+c->空白处ctrl+v,一次类推,创建跟位图一样数量的方框
7、修改每个框的ID值,第一个为IDM_ONLINE_BUTTON1,其他框照着来,名字随意,每个框不同的ID就行了
到这里我们的准备工作算是做完了
我们来到解决方案资源管理器下,我们直接引用别人写好的TrueColorToolBar.h跟TrueColorToolBar.cpp添加到自己的项目中
TrueColorToolBar.h
/***=========================================================================
==== ====
==== D C U t i l i t y ====
==== ====
=============================================================================
==== ====
==== File name : TrueColorToolBar.h ====
==== Project name : Tester ====
==== Project number : --- ====
==== Creation date : 13/1/2003 ====
==== Author(s) : Dany Cantin ====
==== ====
==== Copyright ?DCUtility 2003 ====
==== ====
=============================================================================
===========================================================================*/
#ifndef TRUECOLORTOOLBAR_H_
#define TRUECOLORTOOLBAR_H_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include
/////////////////////////////////////////////////////////////////////////////
// CTrueColorToolBar
class CTrueColorToolBar : public CToolBar
{
// Construction
public:
CTrueColorToolBar();
// Attributes
private:
BOOL m_bDropDown;
struct stDropDownInfo {
public:
UINT uButtonID;
UINT uMenuID;
CWnd* pParent;
};
CArray m_lstDropDownButton;
// Operations
public:
BOOL LoadTrueColorToolBar(int nBtnWidth,
UINT uToolBar,
UINT uToolBarHot = 0,
UINT uToolBarDisabled = 0);
void AddDropDownButton(CWnd* pParent, UINT uButtonID, UINT uMenuID);
private:
BOOL SetTrueColorToolBar(UINT uToolBarType,
UINT uToolBar,
int nBtnWidth);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTrueColorToolBar)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CTrueColorToolBar();
// Generated message map functions
protected:
//{{AFX_MSG(CTrueColorToolBar)
afx_msg void OnToolbarDropDown(NMHDR * pnmh, LRESULT* plRes);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // TRUECOLORTOOLBAR_H_
TrueColorToolBar.cpp
/***=========================================================================
==== ====
==== D C U t i l i t y ====
==== ====
=============================================================================
==== ====
==== File name : TrueColorToolBar.cpp ====
==== Project name : Tester ====
==== Project number : --- ====
==== Creation date : 13/1/2003 ====
==== Author(s) : Dany Cantin ====
==== ====
==== Copyright ?DCUtility 2003 ====
==== ====
=============================================================================
===========================================================================*/
#include "stdafx.h"
#include "TrueColorToolBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTrueColorToolBar
CTrueColorToolBar::CTrueColorToolBar()
{
m_bDropDown = FALSE;
}
CTrueColorToolBar::~CTrueColorToolBar()
{
}
BEGIN_MESSAGE_MAP(CTrueColorToolBar, CToolBar)
//{{AFX_MSG_MAP(CTrueColorToolBar)
ON_NOTIFY_REFLECT(TBN_DROPDOWN, OnToolbarDropDown)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTrueColorToolBar message handlers
BOOL CTrueColorToolBar::LoadTrueColorToolBar(int nBtnWidth,
UINT uToolBar,
UINT uToolBarHot,
UINT uToolBarDisabled)
{
if (!SetTrueColorToolBar(TB_SETIMAGELIST, uToolBar, nBtnWidth))
return FALSE;
if (uToolBarHot) {
if (!SetTrueColorToolBar(TB_SETHOTIMAGELIST, uToolBarHot, nBtnWidth))
return FALSE;
}
if (uToolBarDisabled) {
if (!SetTrueColorToolBar(TB_SETDISABLEDIMAGELIST, uToolBarDisabled, nBtnWidth))
return FALSE;
}
return TRUE;
}
BOOL CTrueColorToolBar::SetTrueColorToolBar(UINT uToolBarType,
UINT uToolBar,
int nBtnWidth)
{
CImageList cImageList;
CBitmap cBitmap;
BITMAP bmBitmap;
if (!cBitmap.Attach(LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(uToolBar),
IMAGE_BITMAP, 0, 0,
LR_DEFAULTSIZE|LR_CREATEDIBSECTION)) ||
!cBitmap.GetBitmap(&bmBitmap))
return FALSE;
CSize cSize(bmBitmap.bmWidth, bmBitmap.bmHeight);
int nNbBtn = cSize.cx/nBtnWidth;
RGBTRIPLE* rgb = (RGBTRIPLE*)(bmBitmap.bmBits);
COLORREF rgbMask = RGB(rgb[0].rgbtRed, rgb[0].rgbtGreen, rgb[0].rgbtBlue);
if (!cImageList.Create(nBtnWidth, cSize.cy, ILC_COLOR24|ILC_MASK, nNbBtn, 0))
return FALSE;
if (cImageList.Add(&cBitmap, rgbMask) == -1)
return FALSE;
SendMessage(uToolBarType, 0, (LPARAM)cImageList.m_hImageList);
cImageList.Detach();
cBitmap.Detach();
return TRUE;
}
void CTrueColorToolBar::AddDropDownButton(CWnd* pParent, UINT uButtonID, UINT uMenuID)
{
if (!m_bDropDown) {
GetToolBarCtrl().SendMessage(TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_DRAWDDARROWS);
m_bDropDown = TRUE;
}
SetButtonStyle(CommandToIndex(uButtonID), TBSTYLE_DROPDOWN);
stDropDownInfo DropDownInfo;
DropDownInfo.pParent = pParent;
DropDownInfo.uButtonID = uButtonID;
DropDownInfo.uMenuID = uMenuID;
m_lstDropDownButton.Add(DropDownInfo);
}
void CTrueColorToolBar::OnToolbarDropDown(NMHDR * pnmtb, LRESULT *plr)
{
NMTOOLBARA * pnmtbb=(NMTOOLBARA *)pnmtb;
for (int i = 0; i < m_lstDropDownButton.GetSize(); i++) {
stDropDownInfo DropDownInfo = m_lstDropDownButton.GetAt(i);
if (DropDownInfo.uButtonID == UINT(pnmtbb->iItem)) {
CMenu menu;
menu.LoadMenu(DropDownInfo.uMenuID);
CMenu* pPopup = menu.GetSubMenu(0);
CRect rc;
SendMessage(TB_GETRECT, (WPARAM)pnmtbb->iItem, (LPARAM)&rc);
ClientToScreen(&rc);
pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,
rc.left, rc.bottom, DropDownInfo.pParent, &rc);
break;
}
}
}
接下来我们在解决方案资源管理器中
1、找到我们的MyButtonDlg.h->引入头文件#include "TrueColorToolBar.h"->在类里面添加CTrueColorToolBar m_ToolBar变量并新建函数为:VOID CreateToolBar();
2、实现CreateToolBar函数,代码如下
VOID CMyButtonDlg::CreateToolBar()
{
if (!m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_ToolBar.LoadToolBar(IDR_TOOLBAR_MAIN))
{
return;
}
m_ToolBar.LoadTrueColorToolBar(
48,
IDB_BITMAP_MAIN,
IDB_BITMAP_MAIN,
IDB_BITMAP_MAIN); // 控件关联位图
RECT Rect, RectMain;
GetWindowRect(&RectMain); // 获取窗口大小
Rect.left = 0;
Rect.top = 0;
Rect.bottom = 80;
Rect.right = RectMain.right - RectMain.left + 10;
m_ToolBar.MoveWindow(&Rect, TRUE);
m_ToolBar.SetButtonText(0, "Button1"); // 在位图的下面添加文件
m_ToolBar.SetButtonText(1, "Button2");
m_ToolBar.SetButtonText(2, "Button3");
}
3、最后一步:我们找到BOOL CMyButtonDlg::OnInitDialog()->找到// TODO: 在此添加额外的初始化代码->在下方添加CreateToolBar();调用我们刚刚编写的函数。
这是你可以运行程序了
但这时是不是发现点击后还没发响应,因为我们还没添加响应函数,下面我们来介绍如何响应。
1、打开MyButtonDlg.h,在类中添加afx_msg void OnOnlineButton1()函数。
2、打开MyButtonDlg.cpp,添加OnOnlineButton1()的实现类
void CMyButtonDlg::OnOnlineButton1()
{
MessageBox("哈哈!");
}
3、在MyButtonDlg.cpp中找到BEGIN_MESSAGE_MAP(CMyButtonDlg, CDialogEx) (别找错了!),在中间添加
ON_COMMAND(IDM_ONLINE_BUTTON1, &CRemoteSysDlg::OnOnlineButton1)
这里的IDM_ONLINE_BUTTON1就是我们上面Toolbar中给第一个框取的ID
下面继续运行你的程序吧!