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 <afxtempl.h>
/////////////////////////////////////////////////////////////////////////////
// CTrueColorToolBar
class CTrueColorToolBar : public CToolBar
{
// Construction
public:
CTrueColorToolBar();
// Attributes
private:
BOOL m_bDropDown;
struct stDropDownInfo {
public:
UINT uButtonID;
UINT uMenuID;
CWnd* pParent;
};
CArray <stDropDownInfo, stDropDownInfo&> 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
下面繼續運行你的程序吧!