用弹出菜单模拟窗口的菜单

在加了Skin的不规则区域窗口,窗口菜单很难固定在原来的位置,无法用原来的方式实现。这里提供了一种用弹出菜单模拟窗口菜单的方法。

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

        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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
vb net模拟的操作系统 [主要功能] ●系统关机重启(不是关闭Windows) ●仿Windows任务栏(显示窗体) ●仿Windows系统托盘(暂不支持用户应用程序) ●资源管理器(文件操作 含 FileSystemWatcher 文件监听) ●快捷方式功能(桌面加载) ●命令提示符(支持文件操作) ●设置桌面图像(可自定义图像) ●记事本(编辑文本文档 txt) ●任务管理器(以窗口为单位进行管理) ●用户应用程序(开放接口) ●其他:显示桌面等 [感言] 写这个系统完全是于无聊 真的很无聊 无聊到蛋疼 运行一下看看这个系统实现的功能 几乎没有细节上的失误 除了无聊 我只能说我真的有强迫症 这个系统虽然说简单 但是也着实花了我不少心血 基本上功能都实现了 因为不是一次写成了 陆陆续续花了差不多半个月才写成如今这种规模 代码方面可能有点小混乱 不是很严格 最让我自豪的莫过于 [任务管理器] 和 [用户应用程序] 的实现了 这两部分可以说花了我最多的心血 这个系统可以加载不同应用(前提是有人提供) 这也算是这个系统最大的骄傲了吧 可以说部分做了智能系统的感觉 大家如果没事的话也可以自己写 OS snv 系统的应用程序 它实际上是一个动态链接库文件 只是改名为 sapp 文件了(偷笑) 接口在 [应用程序] [用户应用程序]中开放来了 如果大家有什么好的意见 可以发邮件到我邮箱 snvlongquan@163 com 哦 很乐意跟大家交流分享 嘿嘿 ">vb net模拟的操作系统 [主要功能] ●系统关机重启(不是关闭Windows) ●仿Windows任务栏(显示窗体) ●仿Windows系统托盘(暂不支持用户应用程序) ●资源管理器(文件操作 含 FileSystemWatcher 文件监听) ●快捷方式功能 [更多]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值