【MFC】工具栏左侧双线效果
生活随笔
收集整理的這篇文章主要介紹了
【MFC】工具栏左侧双线效果
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
00. 目錄
文章目錄
- 00. 目錄
- 01. 案例概述
- 02. 開發環境
- 03. 關鍵技術
- 04. 程序設計
- 05. 秘笈心法
- 06. 源碼下載
- 07. 附錄
01. 案例概述
由MFC向導創建的文檔視圖結構應用程序,其創建的工具欄左側只有一條豎線,實例實現將這一條豎線,改為兩條豎線。效果如下圖所示。
02. 開發環境
系統環境:Windows 10
開發環境:Visual Studio 2019
03. 關鍵技術
繪制普通線條使用CDC類的LineTo方法即可,如果是立體效果的線條就需要繪制多條不同顏色的線條,把一個線條看做是一個矩形區域,它的左邊緣和下邊緣使用COLOR_BTNSHADOW顏色,右邊緣和上邊緣使用COLOR_BTNHILIGHT顏色,這樣就可以實現線條突出的效果。
04. 程序設計
(1)新建一個基于單文檔視圖結構的應用程序。
(2)由CToolBar派生一個新類CMyToolBar。
(3)在新類CMyToolBar的DrawGripper函數中,實現雙線的繪制,實現代碼如下。
CMyToolBar.h
// CMyToolBarclass CMyToolBar : public CToolBar {DECLARE_DYNAMIC(CMyToolBar)public:CMyToolBar();virtual ~CMyToolBar();void Draw3dRect(CDC* pDC, CRect rc) const;protected:void DrawBorders(CDC* pDC, CRect& rect);void EraseNonClient(BOOL);void DrawGripper(CDC &dc) const;afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnNcPaint();DECLARE_MESSAGE_MAP() };CMyToolBar.cpp
// CMyToolBar.cpp: 實現文件 // #include "pch.h" #include "5Edit.h" #include "CMyToolBar.h" // CMyToolBar IMPLEMENT_DYNAMIC(CMyToolBar, CToolBar)CMyToolBar::CMyToolBar() {}CMyToolBar::~CMyToolBar() { }void CMyToolBar::DrawGripper(CDC& dc) const {// no gripper if floatingif (IsFloating()) {return;}if (m_dwStyle & CBRS_GRIPPER){CRect gripper;GetWindowRect(gripper);ScreenToClient(gripper);gripper.OffsetRect(-gripper.left, -gripper.top);if (m_dwStyle & CBRS_ORIENT_HORZ) {// gripper at leftgripper.DeflateRect(4, 3);gripper.right = gripper.left + 3;gripper.bottom += 1;Draw3dRect(&dc, gripper);}else {// gripper at topgripper.DeflateRect(3, 4);gripper.top -= 1;gripper.bottom = gripper.top + 3;Draw3dRect(&dc, gripper);}} } void CMyToolBar::DrawBorders(CDC* pDC, CRect& rect) {ASSERT_VALID(this);ASSERT_VALID(pDC);DWORD dwStyle = m_dwStyle;if (!(dwStyle & CBRS_BORDER_ANY))return;// prepare for dark linesASSERT(rect.top == 0 && rect.left == 0);COLORREF clr = GetSysColor(COLOR_3DSHADOW);if (dwStyle & CBRS_BORDER_RIGHT)pDC->FillSolidRect(rect.right - 1, 0, rect.right, rect.bottom, clr); //rightif (dwStyle & CBRS_BORDER_BOTTOM)pDC->FillSolidRect(0, rect.bottom - 1, rect.right, rect.bottom, clr); //bottomclr = GetSysColor(COLOR_3DHIGHLIGHT);if (dwStyle & CBRS_BORDER_TOP)pDC->FillSolidRect(0, 0, rect.right, 1, clr); //topif (dwStyle & CBRS_BORDER_LEFT)pDC->FillSolidRect(0, 0, 1, rect.bottom, clr); //leftif (dwStyle & CBRS_BORDER_TOP)rect.top++;if (dwStyle & CBRS_BORDER_RIGHT)rect.right--;if (dwStyle & CBRS_BORDER_BOTTOM)rect.bottom--;if (dwStyle & CBRS_BORDER_LEFT)rect.left++; } void CMyToolBar::Draw3dRect(CDC* pDC, CRect rc) const {static bool bDraw2nd = true;if (bDraw2nd == true) {rc.right -= 1;rc.bottom -= 1;}// Get a pen for hilite and shadow.CPen penHilite(PS_SOLID, 1, ::GetSysColor(COLOR_BTNHILIGHT));CPen penShadow(PS_SOLID, 1, ::GetSysColor(COLOR_BTNSHADOW));// Set up points for line draw.CPoint ptTopLeft(rc.left, rc.top);CPoint ptTopRight(rc.right, rc.top);CPoint ptBottomLeft(rc.left, rc.bottom);CPoint ptBottomRight(rc.right, rc.bottom);// Select the shadow pen, and draw the bottom right.pDC->SelectObject(&penShadow);pDC->MoveTo(ptTopRight);pDC->LineTo(ptBottomRight);pDC->LineTo(ptBottomLeft);// Select the hilite pen, and draw the top left.pDC->SelectObject(&penHilite);pDC->MoveTo(ptBottomLeft);pDC->LineTo(ptTopLeft);pDC->LineTo(ptTopRight);// Draw the second gripper line.if (bDraw2nd == true){bDraw2nd = false;if (m_dwStyle & CBRS_ORIENT_HORZ)rc.OffsetRect(3, 0);elserc.OffsetRect(0, 3);Draw3dRect(pDC, rc);bDraw2nd = true;} } void CMyToolBar::EraseNonClient(BOOL) {// get window DC that is clipped to the non-client areaCWindowDC dc(this);CRect rectClient;GetClientRect(rectClient);CRect rectWindow;GetWindowRect(rectWindow);ScreenToClient(rectWindow);rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);dc.ExcludeClipRect(rectClient); // draw borders in non-client area// draw borders in non-client arearectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);DrawBorders(&dc, rectWindow); // erase parts not drawndc.IntersectClipRect(rectWindow);SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC);DrawGripper(dc); }int CMyToolBar::OnCreate(LPCREATESTRUCT lpCreateStruct) {if (CToolBar::OnCreate(lpCreateStruct) == -1)return -1;SendMessage(TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS);ModifyStyle(0, TBSTYLE_FLAT); // flat with gripper.m_dwStyle |= CBRS_GRIPPER;//m_dwStyle CControlBar的成員變量return 0; }void CMyToolBar::OnNcPaint() {CControlBar::EraseNonClient();CWindowDC dc(this);CRect pRect;GetClientRect(&pRect);InvalidateRect(&pRect, TRUE);EraseNonClient(FALSE); }BEGIN_MESSAGE_MAP(CMyToolBar, CToolBar)ON_WM_CREATE()ON_WM_NCPAINT() END_MESSAGE_MAP()// CMyToolBar 消息處理程序MainFrm.cpp文件
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {if (CFrameWnd::OnCreate(lpCreateStruct) == -1)return -1;if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)){TRACE0("未能創建工具欄\n");return -1; // 未能創建}if (!m_wndStatusBar.Create(this)){TRACE0("未能創建狀態欄\n");return -1; // 未能創建}m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));// TODO: 如果不需要可停靠工具欄,則刪除這三行m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);return 0; }05. 秘笈心法
Draw3dRect方法的使用
CDC類Draw3dRect方法可以用來繪制區域,使用Draw3dRect方法可以繪制按鈕控件的效果,但該方法繪制不了線條,只能用在控件自繪的過程中,掌握Draw3dRect方法可以快速繪制突出效果的矩形區域。
06. 源碼下載
下載:【MFC】工具欄左側雙線效果.rar
07. 附錄
參考: 《Visual C++從入門到精通(項目案例版)》
總結
以上是生活随笔為你收集整理的【MFC】工具栏左侧双线效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【MFC】带组合框的工具栏
- 下一篇: 【MFC】状态栏随对话框的改变而改变