自定义Office XP风格菜单栏的实现

在现代的Windows应用程序中,用户界面的美观性越来越受到重视。Office XP风格因其简洁、现代的界面设计而受到许多开发者的青睐。本文将介绍如何使用C++MFC/ATL技术实现具有Office XP风格的自定义菜单栏。

概述

自定义菜单栏通常涉及到重写窗口消息处理函数,以及自定义绘制消息。在Office XP风格中,菜单栏的绘制需要考虑多种状态,如普通、高亮、选中等。此外,还需要处理菜单项的文本和图标的绘制。

实现步骤

实现自定义Office XP风格菜单栏的步骤可以分为以下几个部分:

首先,需要定义一个自定义菜单类,该类继承自MFCATL的菜单栏控件类。在这个类中,将重写消息映射和处理函数,以实现自定义绘制。

在自定义菜单类中,需要重写消息映射,以便捕获并处理与菜单绘制相关的消息。这包括父窗口消息、MDI客户窗口消息和消息钩子消息。

自定义绘制函数是实现Office XP风格菜单栏的关键。在这个函数中,将根据菜单项的状态(如高亮、选中等)来绘制菜单项的背景、文本和图标。

在自定义绘制函数中,还需要处理菜单项的文本和图标。这包括根据菜单项的状态选择正确的颜色,以及在需要时绘制图标。

代码示例

// 自定义菜单类的定义 template <class T, class TBase = CCommandBarCtrlBase, class TWinTraits = CControlWinTraits> class CCommandBarCtrlImplXP : public CCommandBarCtrlImpl<T, TBase, TWinTraits> { public: DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) // 消息映射和处理函数 typedef CCommandBarCtrlImplXP<T, TBase, TWinTraits> thisClass; typedef CCommandBarCtrlImpl<T, TBase, TWinTraits> baseClass; BEGIN_MSG_MAP(CCommandBarCtrlXP) CHAIN_MSG_MAP(baseClass) ALT_MSG_MAP(1) NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) CHAIN_MSG_MAP_ALT(baseClass, 1) ALT_MSG_MAP(2) CHAIN_MSG_MAP_ALT(baseClass, 2) ALT_MSG_MAP(3) CHAIN_MSG_MAP_ALT(baseClass, 3) END_MSG_MAP() LRESULT OnCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) { TCHAR sClass[128]; GetClassName(pnmh->hwndFrom, sClass, 128); if (_tcscmp(sClass, _T("WTL_CommandBarXP"))) { return CDRF_DODEFAULT; } NMCUSTOMDRAW* pCustomDraw = (NMCUSTOMDRAW*)pnmh; if (pCustomDraw->dwDrawStage == CDDS_PREPAINT) { // Request prepaint notifications for each item return CDRF_NOTIFYITEMDRAW; } if (pCustomDraw->dwDrawStage == CDDS_ITEMPREPAINT) { CDCHandle cDC(pCustomDraw->hdc); CRect rc = pCustomDraw->rc; TCHAR sBtnText[128]; ::SendMessage(pnmh->hwndFrom, TB_GETBUTTONTEXT, pCustomDraw->dwItemSpec, (LPARAM)sBtnText); if (pCustomDraw->uItemState & CDIS_HOT) { COLORREF crHighLight = ::GetSysColor(COLOR_HIGHLIGHT); CPenDC pen(cDC, crHighLight); CBrushDC brush(cDC, (pCustomDraw->uItemState & CDIS_SELECTED)? HLS_TRANSFORM(crHighLight, +50, -50) : HLS_TRANSFORM(crHighLight, +70, -57)); cDC.Rectangle(rc); cDC.SetTextColor((pCustomDraw->uItemState & CDIS_SELECTED)? ::GetSysColor(COLOR_HIGHLIGHTTEXT) : RGB(0, 0, 0)); } else { cDC.FillSolidRect(rc, HLS_TRANSFORM(::GetSysColor(COLOR_3DFACE), +20, 0)); cDC.SetTextColor(::GetSysColor(m_bParentActive ? COLOR_BTNTEXT : COLOR_3DSHADOW)); } cDC.SetBkMode(TRANSPARENT); cDC.SelectFont((HFONT)GetStockObject(DEFAULT_GUI_FONT)); cDC.DrawText(sBtnText, _tcslen(sBtnText), rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE); return CDRF_SKIPDEFAULT; } bHandled = FALSE; return CDRF_DODEFAULT; } };
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485