【MFC】定义XP风格的工具栏
生活随笔
收集整理的這篇文章主要介紹了
【MFC】定义XP风格的工具栏
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
00. 目錄
文章目錄
- 00. 目錄
- 01. 案例概述
- 02. 開發環境
- 03. 關鍵技術
- 04. 程序設計
- 05. 秘笈心法
- 06. 源碼下載
- 07. 附錄
01. 案例概述
網上的許多軟件都具有漂亮的工具欄,咱們模仿XP風格的工具欄,設計了一個自定義的工具欄按鈕,效果如下圖所示。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wrUKqxhg-1614937100041)(assets/image-20210305173744393.png)]
02. 開發環境
系統環境:Windows 10
開發環境:Visual Studio 2019
03. 關鍵技術
在MFC中,繪制工具欄、樹視圖、列表視圖等控件需要處理NM_CUSTOMDRAW通知消息。首先從CToolBarCtrl類派生一個子類,本例為CXPBar,在該類的消息映射部分添加反射消息映射宏ON_NOTIFY_REFLECT,代碼如下:
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnOwnerDraw)編寫NM_CUSTOMDRAW消息處理函數OnOwnerDraw,實現工具欄按鈕的繪制。
04. 程序設計
(1)創建基于對話框的應用程序。
(2)由CToolBarCtrl派生一個新類CXPBar。
#pragma once// XPBarclass XPBar : public CToolBarCtrl {DECLARE_DYNAMIC(XPBar)public:XPBar();virtual ~XPBar();public:COLORREF m_TextColor;COLORREF m_HotColor;COLORREF m_LineColor;BOOL m_IsDraw;public:void DrawButton(CDC* pDC, const RECT& rect, UINT uState);void OnOwnerDraw(NMHDR* pNotifyStruct, LRESULT* pResult);protected:DECLARE_MESSAGE_MAP() public:afx_msg void OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult); };// XPBar.cpp: 實現文件 //#include "pch.h" #include "5XPBar.h" #include "XPBar.h"// XPBarIMPLEMENT_DYNAMIC(XPBar, CToolBarCtrl)XPBar::XPBar() {//初始化m_HotColor = RGB(193, 210, 238);m_TextColor = RGB(0, 0, 255);m_LineColor = RGB(49, 106, 197);m_IsDraw = TRUE; }XPBar::~XPBar() { }void XPBar::DrawButton(CDC* pDC, const RECT& rect, UINT uState) {CPoint pt;GetCursorPos(&pt);ScreenToClient(&pt);CRect rect1;GetClientRect(rect1);if (rect1.PtInRect(pt)){if (uState & CDIS_HOT){CPen pen(PS_SOLID, 1, m_LineColor);CPen* pOldPen = pDC->SelectObject(&pen);CBrush brush(m_HotColor);CBrush* pOldBrush = pDC->SelectObject(&brush);pDC->Rectangle(&rect);pDC->SelectObject(pOldBrush);pDC->SelectObject(pOldPen);}} }void XPBar::OnOwnerDraw(NMHDR* pNotifyStruct, LRESULT* pResult) {NMTBCUSTOMDRAW* pCustomDraw = (NMTBCUSTOMDRAW*)pNotifyStruct;CDC dc;dc.Attach(pCustomDraw->nmcd.hdc);pCustomDraw->clrText = m_TextColor;switch (pCustomDraw->nmcd.dwDrawStage){case CDDS_PREPAINT:*pResult = CDRF_NOTIFYITEMDRAW;break;case CDDS_ITEMPREPAINT:DrawButton(&dc, pCustomDraw->nmcd.rc, pCustomDraw->nmcd.uItemState);*pResult = TBCDRF_NOEDGES; //不繪按鈕邊框break;}dc.Detach(); }BEGIN_MESSAGE_MAP(XPBar, CToolBarCtrl)ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, XPBar::OnNMCustomdraw) END_MESSAGE_MAP()// XPBar 消息處理程序void XPBar::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult) {LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);// TODO: 在此添加控件通知處理程序代碼*pResult = 0; }(3)添加CXPBar類的NM_CUSTOMDRAW消息的實現函數,實現代碼如下。
BOOL CMy5XPBarDlg::OnInitDialog() {CDialogEx::OnInitDialog();// 將“關于...”菜單項添加到系統菜單中。// IDM_ABOUTBOX 必須在系統命令范圍內。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != nullptr){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 設置此對話框的圖標。 當應用程序主窗口不是對話框時,框架將自動// 執行此操作SetIcon(m_hIcon, TRUE); // 設置大圖標SetIcon(m_hIcon, FALSE); // 設置小圖標// TODO: 在此添加額外的初始化代碼m_ImageList.Create(22, 22, ILC_COLOR24 | ILC_MASK, 1, 1);m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));m_ToolBar.Create(WS_CHILD | TBSTYLE_FLAT | WS_VISIBLE | CBRS_NOALIGN, CRect(0, 0, 0, 0), this, 111);m_ToolBar.SetImageList(&m_ImageList);TBBUTTON buttons[5];for (int i = 0; i < 5; i++){buttons[i].idCommand = 100 + i;buttons[i].iBitmap = i;buttons[i].fsStyle = TBSTYLE_FLAT;buttons[i].fsState = TBSTATE_ENABLED;buttons[i].iString = IDS_ABOUTBOX;}m_ToolBar.AddButtons(5, buttons);TBBUTTONINFO bInfo;bInfo.cbSize = sizeof(TBBUTTONINFO);bInfo.dwMask = TBIF_TEXT;bInfo.pszText = TEXT("系統登錄");BOOL ret = m_ToolBar.SetButtonInfo(100, &bInfo);bInfo.pszText = TEXT("商品銷售");m_ToolBar.SetButtonInfo(101, &bInfo);bInfo.pszText = TEXT("銷售查詢");m_ToolBar.SetButtonInfo(102, &bInfo);bInfo.pszText = TEXT("系統幫助");m_ToolBar.SetButtonInfo(103, &bInfo);bInfo.pszText = TEXT("關于");m_ToolBar.SetButtonInfo(104, &bInfo);m_ToolBar.SetButtonWidth(50, 80);m_ToolBar.MoveWindow(10, 10, 100, 50);return TRUE; // 除非將焦點設置到控件,否則返回 TRUE }05. 秘笈心法
反射消息的應用
實例中對反射消息的一次運用,反射消息是指子控件向父控件發送消息,而父控件并沒有處理該消息,而是把消息返回給子控件,讓子控件來處理這個消息,這就形成了一去一回的反射過程,映射宏中有幾個是帶REFLECT字樣的,都代表是反射類型。
06. 源碼下載
下載:【MFC】定義XP風格的工具欄.rar
07. 附錄
總結
以上是生活随笔為你收集整理的【MFC】定义XP风格的工具栏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【MFC】工具栏按钮的热点效果
- 下一篇: 【MFC】工具栏按钮单选效果