分享

模拟菜单栏

 9loong 2013-09-05

最近需要做了菜单栏,替换多文档试图结构的菜单栏。最后需模拟一个,参照了网上的资料,完成了所需菜单栏,谢谢goodboyws在论坛的帖子,

展示如下:

首先在窗口的任意一个区域画出菜单的效果,这个区域我们称为菜单区,我们把每个菜单项在窗口中的位置保存下来

        CRect m_rcMenu[3];

       程序主要要处理三个消息: WM_LBUTTONDOWN、WM_MOUSEMOVE、WM_ENTERIDLE

       BEGIN_MESSAGE_MAP(CMyDlg, CDialog) 
              //{{AFX_MSG_MAP(CMyDlg)
                    ON_WM_LBUTTONDOWN( ) 
                    ON_WM_MOUSEMOVE() 
                    ON_WM_ENTERIDLE()
              //}}AFX_MSG_MAP
       END_MESSAGE_MAP()

        当鼠标在菜单区内按下的时候,开始用弹出菜单模拟窗口菜单。

        void CMyDlg::OnLButtonDown(UINT nFlags, CPoint ptStart) 
        {
              for (i=0 ;i<3; i++)
              {
                     if (PtInRect(m_rcMenu[i], point))
                     {
         
                            if (!PtInRect(m_rcMenu[m_iMenuIndex], point))
                            {
                                   InvalidateRect(&m_rcMenu[m_iMenuIndex], TRUE);
                                   UpdateWindow();
                           }

                           //这个是菜单索引,用它来标示显示那个菜单
                           m_iMenuIndex = i;
                          m_bShowMenu = TRUE;


                          //菜单显示,如果m_bMenuContinue为TRUE, 不断显示新的菜单,旧的在WM_ENTERIDLE中清除,之所以做这样的处理,是因为窗口菜单要求当菜单弹出时,随着鼠标在菜单区的移动,菜单变更为相应的子菜单


                         do 
                         {

                                   //画菜单的按下效果
                                    CDC* pDC = GetDC();
                                    pDC->Draw3dRect(&m_rcMenu[m_iMenuIndex], RGB(100, 100, 100), RGB(160, 160, 160));
                                    ReleaseDC(pDC);
                                    m_bMenuContinue = FALSE;
                                    ShowMenu(); 
                          } while(m_bMenuContinue);   
                          InvalidateRect(&m_rcMenu[m_iMenuIndex], TRUE);
                          UpdateWindow();
                           m_bShowMenu = FALSE;
                           CWnd::OnLButtonDown(nFlags, point); 
                           return;
                    }
               }
               if ( i== 3)
                      m_iMenuIndex = -1;
               CDialog::OnLButtonDown(nFlags, point); 

           }

           然后在OnMouseMove里更新菜单索引

           void CMyDlg::OnMouseMove(UINT nFlags, CPoint point) 
           {
                   // TODO: Add your message handler code here and/or call default
 
                   //把原来的菜单按下效果清除掉
                   if (m_iMenuIndex != -1)
                   {
                             if (!PtInRect(m_rcMenu[m_iMenuIndex], point))
                                       InvalidateRect(&m_rcMenu[m_iMenuIndex], TRUE); 

                   }

                  UpdateWindow();

                   m_iMenuIndex = -1;
                   for (i=0 ;i<3; i++)
                   {
                            if (PtInRect(m_rcMenu[i], point))
                            {
                                   //确定当前菜单索引
                                  m_iMenuIndex = i;
                                  //画菜单的抬起效果
                                  CDC* pDC = GetDC();
                                  pDC->Draw3dRect(&m_rcMenu[i], RGB(160, 160, 160), RGB(100, 100, 100));
                                  ReleaseDC(pDC);
                                  break;
                              }
                    }

                    CDialog::OnMouseMove(nFlags, point);
            }

           在OnEnterIdle将菜单取消并重新显示

           void CGameBoxShell::OnEnterIdle(UINT nWhy, CWnd* pWho) 
          {
                  CWnd::OnEnterIdle(nWhy, pWho);
 
                  // TODO: Add your message handler code here
                  if (nWhy == MSGF_MENU)
                  {

                        if (!m_bShowMenu)
                                return;
                         CPoint point;
                         GetCursorPos(&point);
                         ScreenToClient(&point);
 
                         for (int i=0 ;i<3; i++)
                         {
                                   if (PtInRect(m_rcMenu[i], point))
                                   {
                                             if (m_iMenuIndex != i)
                                             {
                                                      if (m_iMenuIndex != -1)
                                                      {
                                                                if (!PtInRect(m_rcMenu[m_iMenuIndex], point))
                                                                {
                                                                       InvalidateRect(&m_rcMenu[m_iMenuIndex], TRUE);
                                                                       UpdateWindow();
                                                                }
                                                      }
                                                      m_iMenuIndex = i;
                                                      m_bMenuContinue = TRUE;
                                                      SendMessage(WM_CANCELMODE);
                                               }
                                               break;
                                     }
                           }

                 }
         }

         最后,把显示菜单的代码补充完整
          void CMyDlg::ShowMenu()
         {
                     if (m_PopupMenu.GetSafeHmenu())
                               m_PopupMenu.DestroyMenu();
                     m_PopupMenu.LoadMenu(IDR_POPUP);
                     CMenu* pSub = m_PopupMenu.GetSubMenu(m_iMenuIndex);
                     CPoint pt(m_rcMenu[m_iMenuIndex].left, m_rcMenu[m_iMenuIndex].bottom+2);
                    ClientToScreen(&pt);
                     TrackPopupMenu(pSub->GetSafeHmenu(), TPM_LEFTALIGN |
                                    TPM_LEFTBUTTON, pt.x, pt.y, NULL, m_hWnd, NULL);
      }


(###)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多