ActiveX插件下自定义菜单

    最近公司要求写一个OCX的插件,把那种多文档的整个框架界面全部都分装到插件里面,碰到的第一个问题就是不能正常的加载显示菜单,在网上找了相关的资料都说用按钮来替代菜单,于是本人本着这种思路自定义了一个菜单类,拿来与大家分享一下,封装的不是很到位,后来也懒得改,贴出来让大家看看,相互交流下经验

菜单的样式就是这样,下面说下具体思路

1.创建一个对话框,在对话框上动态的创建菜单

CRect RectMenu(ClineRect.left,ClineRect.top,ClineRect.right,ClineRect.top+120);
 m_pMenuDlg = new CDlgMenuCmd;
 BOOL bRet = m_pMenuDlg->CreateEx(NULL,NULL,_T(""),WS_CHILD|WS_VISIBLE,RectMenu,this,IDD_DLG_MENUCDM);
 if(!bRet)
 {
  AfxMessageBox(_T("创建失败!"));
 }

2.在菜单对话框的Oncreate函数里创建菜单

CRect rect(0,0,lpCreateStruct->cx,lpCreateStruct->cy);

 m_Menu.LoadMenu(IDR_KQVIEW_TMPL);//注:IDR_KQVIEW_TMPL是资源里创建的菜单,当然菜单分为下面10个大项,下面添加菜单的代码实际可以通过遍历m_Menu添加,因为懒所以没改了

 

 AddMenu(new CStaticMenu(_T("文件"),&m_Menu,0,IDC_STATIC_MENU0));
 AddMenu(new CStaticMenu(_T("编辑"),&m_Menu,1,IDC_STATIC_MENU1));
 AddMenu(new CStaticMenu(_T("视图"),&m_Menu,2,IDC_STATIC_MENU2));
 AddMenu(new CStaticMenu(_T("格式"),&m_Menu,3,IDC_STATIC_MENU3));
 AddMenu(new CStaticMenu(_T("公式"),&m_Menu,4,IDC_STATIC_MENU4));
 AddMenu(new CStaticMenu(_T("表页"),&m_Menu,5,IDC_STATIC_MENU5));
 AddMenu(new CStaticMenu(_T("数据"),&m_Menu,6,IDC_STATIC_MENU6));
 AddMenu(new CStaticMenu(_T("工具"),&m_Menu,7,IDC_STATIC_MENU7));
 AddMenu(new CStaticMenu(_T("窗口"),&m_Menu,8,IDC_STATIC_MENU8));
 AddMenu(new CStaticMenu(_T("帮助"),&m_Menu,9,IDC_STATIC_MENU9));

添加后创建菜单项

for (std::vector<CStaticMenu *>::iterator item=m_MenuVector.begin(); item != m_MenuVector.end(); item++)
 {
  CStaticMenu * pMenu = (CStaticMenu *)(*item);
  int cx = pMenu->GetTextCx();
  //nTotalX += cx;


  /*if (nTotalX > lpCreateStruct->cx)
  {
   nPreLeft = rect.left;
   nPreTop = lpCreateStruct->cy;
   nTotalX = 0;
   MoveWindow(0,0,lpCreateStruct->cx,lpCreateStruct->cy*2);
  }*/

  MenuRect.SetRect(nPreLeft,nPreTop,nPreLeft+cx,nPreTop + 23);
  nPreLeft = nPreLeft+cx;
  pMenu->Create(NULL,WS_CHILD|WS_VISIBLE|SS_CENTER|SS_NOTIFY,MenuRect,this,pMenu->m_StaticID);
 }

 

3.下面是CStaticMenu类的具体实现,当然这个类可以做其他的很多用途,熟悉c++的继承写起来当然是很简单的

头文件CStaticMenu.h

class CStaticMenu : public CStatic
{
 DECLARE_DYNAMIC(CStaticMenu)

public:
 //CStaticMenu();
 CStaticMenu(CString strText,CMenu * pMenu,int nMenuIndext,UINT StaticID);
 virtual ~CStaticMenu();

protected:
 DECLARE_MESSAGE_MAP()
private:
 COLORREF m_BgColor;//背景颜色
 COLORREF m_DefaultColor;
 COLORREF m_TextColor;//文本颜色
 CString  m_strText;
 int m_TextBold;//粗体
 CString strFontName;//字体名称
 BOOL m_TextUnderLine;//下划线
 BOOL m_TextItalic;//斜体
 int  m_FontSize;//字体大小
 UINT m_Format;//绘制位置

 BOOL m_bIsMouseEnter;//鼠标进入
 BOOL m_bIsLButtomDwon;//左键按下
 int  m_nMenuIndext;
public:
 void SetBgColor(COLORREF BgColor);
 void SetTextColor(COLORREF TextColor);
 void SetText(CString strText);

 void SetFontBold(BOOL bBold);
 void SetFontName(const CString& strFont);
 void SetFontUnderline(BOOL bSet);
 void SetFontItalic(BOOL bSet);
 void SetFontSize(int nSize);
 void SetFormat(UINT uFormat = DT_CENTER|DT_VCENTER);
 void SetDefaultBgColor();
 void SetAttrib(COLORREF BgColor,COLORREF TextColor,CString strText,BOOL bBold,CString strFont,BOOL bUnderLine,BOOL bItatc,int nSize);
 int  GetTextCx();
 CMenu * m_pMenu;
 UINT  m_StaticID;
public:
 afx_msg void OnPaint();
 afx_msg BOOL OnEraseBkgnd(CDC* pDC);
 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
 afx_msg void OnTimer(UINT_PTR nIDEvent);
 afx_msg void OnFormCell();//单元格设置
};

 

CStaticMenu.cpp文件的实现

IMPLEMENT_DYNAMIC(CStaticMenu, CStatic)

//CStaticMenu::CStaticMenu()
//{
// m_BgColor = RGB(173,185,205);
// m_TextColor = RGB(0,0,0);
// m_TextBold = 400;
// strFontName = _T("宋体");
// m_TextUnderLine = FALSE;
// m_TextItalic = FALSE;
// m_FontSize = 14;
// m_strText = _T("");
// m_Format = DT_LEFT |DT_VCENTER;
// m_bIsMouseEnter = FALSE;
// m_bIsLButtomDwon = FALSE;
// m_Menu.LoadMenu(IDR_MENU1);
//}

CStaticMenu::CStaticMenu(CString strText,CMenu * pMenu,int nMenuIndext,UINT StaticID)
{
 m_BgColor = RGB(173,185,205);
 m_DefaultColor = RGB(173,185,205);
 m_TextColor = RGB(0,0,0);
 m_TextBold = 400;
 strFontName = _T("宋体");
 m_TextUnderLine = FALSE;
 m_TextItalic = FALSE;
 m_FontSize = 14;
 m_strText = strText;
 m_Format = DT_CENTER |DT_VCENTER;
 m_bIsMouseEnter = FALSE;
 m_nMenuIndext = nMenuIndext;
 m_pMenu = pMenu;
 m_StaticID = StaticID;
}

CStaticMenu::~CStaticMenu()
{
}


BEGIN_MESSAGE_MAP(CStaticMenu, CStatic)
 ON_WM_PAINT()
 ON_WM_ERASEBKGND()
 ON_WM_MOUSEMOVE()
 ON_WM_LBUTTONDOWN()
 ON_WM_TIMER()
END_MESSAGE_MAP()

 

// CStaticMenu 消息处理程序

 


void CStaticMenu::OnPaint()
{
 CPaintDC dc(this); // device context for painting
 // TODO: 在此处添加消息处理程序代码
 // 不为绘图消息调用 CStatic::OnPaint()
 CRect rect;
 GetClientRect(rect);

 CBrush brush(m_BgColor);
 dc.FillRect(rect, &brush);

 if (!m_strText.IsEmpty())
 {
  CFont TempFont;
  TempFont.CreateFont(m_FontSize,0,0,0,m_TextBold,m_TextItalic,m_TextUnderLine,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,strFontName);
  CFont * pOldFont = dc.SelectObject(&TempFont);

  dc.SetBkColor(m_BgColor);
  int nOldMode = dc.SetBkMode(TRANSPARENT);
  dc.SetTextColor(m_TextColor);
  dc.DrawText(m_strText,rect,m_Format |DT_SINGLELINE |DT_NOPREFIX  );//| DT_SINGLELINE

  dc.SetBkMode(nOldMode);
  dc.SelectObject(pOldFont);
  TempFont.DeleteObject();
 }
}


BOOL CStaticMenu::OnEraseBkgnd(CDC* pDC)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 return TRUE;
 //return CStatic::OnEraseBkgnd(pDC);
}


void CStaticMenu::SetFormat(UINT uFormat)
{
 m_Format = uFormat;
 Invalidate();
}

void CStaticMenu::SetBgColor(COLORREF BgColor)
{
 m_BgColor = BgColor;
 Invalidate();
}

void CStaticMenu::SetTextColor(COLORREF TextColor)
{
 m_TextColor = TextColor;
 Invalidate();
}

void CStaticMenu::SetText(CString strText)
{
 m_strText = strText;
 Invalidate();
}

void CStaticMenu::SetFontBold(BOOL bBold)
{
 if (bBold == TRUE)
 {
  m_TextBold = 700;
 }
 else
 {
  m_TextBold = 400;
 }
 Invalidate();
}

void CStaticMenu::SetFontName(const CString& strFont)
{
 strFontName = strFont;
 Invalidate();
}

void CStaticMenu::SetFontUnderline(BOOL bSet)
{
 m_TextUnderLine = bSet;
 Invalidate();
}

void CStaticMenu::SetFontItalic(BOOL bSet)
{
 m_TextItalic = bSet;
 Invalidate();
}

void CStaticMenu::SetFontSize(int nSize)
{
 m_FontSize = nSize;
 Invalidate();
}

void CStaticMenu::SetAttrib(COLORREF BgColor,COLORREF TextColor,CString strText,BOOL bBold,CString strFont,BOOL bUnderLine,BOOL bItatc,int nSize)
{
 m_BgColor = BgColor;
 m_TextColor = TextColor;
 if (bBold == TRUE)
 {
  m_TextBold = 700;
 }
 else
 {
  m_TextBold = 400;
 }

 strFontName = strFont;
 m_TextUnderLine = bUnderLine;
 m_TextItalic = bItatc;
 m_FontSize = nSize;
 m_strText = strText;
 Invalidate();
}

int CStaticMenu::GetTextCx()
{
 HDC hdc = ::GetDC(NULL);
 CDC *pDC = CDC::FromHandle(hdc);
 if(pDC == NULL)
 {
  return 0;
 }
 CFont TempFont;
 TempFont.CreateFont(m_FontSize,0,0,0,m_TextBold,m_TextItalic,m_TextUnderLine,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,strFontName);
 CFont * pOldFont = pDC->SelectObject(&TempFont);
 CSize size = pDC->GetTextExtent(m_strText);
 pDC->SelectObject(pOldFont);
 ::ReleaseDC(NULL,hdc);
 return (size.cx+15);
}


void CStaticMenu::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 if(m_bIsMouseEnter == FALSE)
 {
  m_bIsMouseEnter = TRUE;
  m_BgColor = RGB(255,255,183);
  Invalidate();
  SetTimer(1,200,NULL);

  CRect rect;
  GetClientRect(rect);

 
 }

 CStatic::OnMouseMove(nFlags, point);
}

void CStaticMenu::OnLButtonDown(UINT nFlags, CPoint point)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 m_bIsLButtomDwon = TRUE;
 CRect rect;
 GetClientRect(rect);
 CPoint Menupoint(rect.left,rect.bottom);
 ClientToScreen(&Menupoint);//
 CMenu* pPopup = m_pMenu->GetSubMenu(m_nMenuIndext);
 CWnd * pParentWnd = this->GetParent();
 if (pParentWnd != NULL)
 {
  m_BgColor = RGB(255,255,183);
  Invalidate();
  pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, Menupoint.x, Menupoint.y, pParentWnd); //TPM_NONOTIFY
  m_BgColor = RGB(173,185,205);
  Invalidate();
 }
 
 CStatic::OnLButtonDown(nFlags, point);
}


void CStaticMenu::OnTimer(UINT_PTR nIDEvent)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 if (m_bIsMouseEnter)
 {
  // PostMessage(WM_MOUSEENTER...) or call some function.
  
  CPoint pt;
  CRect rect;
  GetCursorPos(&pt);
  GetWindowRect(rect);
  if (!PtInRect(&rect,pt))
  {
   m_BgColor = RGB(173,185,205);
   Invalidate();
   KillTimer(1); // kill self.
  }

  m_bIsMouseEnter = FALSE;
  SetTimer(1,200,NULL);

 }  
 CStatic::OnTimer(nIDEvent);
}

void CStaticMenu::SetDefaultBgColor()
{
 m_BgColor = m_DefaultColor;
 Invalidate();
}

这样整个菜单的实现就可以如上图所示那样,如有什么不懂的地方可以问,当然同时也欢迎支出代码的瑕疵地方,大家相互学习

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值