首页 > 学院 > 开发设计 > 正文

动态修改CMFCMenuBar及CMFCToolBar的文字及Prompt,ToolTip文字

2019-11-08 01:34:24
字体:
来源:转载
供稿:网友

1. 修改CMFCMenuBar菜单项的文字,分两种.

  A. 修改顶层有POP_UP属性的菜单文字,即类型单文档中的" 文件" ,"编辑","视图"等这类一直显示着的.

    因为CMFCMenuBar基类是CMFCToolBar,所以有有如下代码:   (特别注意: 在单文档中,此函数一定要在主窗口ShowWindow之后调用)

[cpp] view plain copy//更新菜单栏父项,即无ID的项.      CAdoString Str;      CMFCToolBarButton  *pButton = NULL;      int Index = 0;      do      {          pButton = m_wndMenuBar.GetMenuItem(Index);          if(pButton)          {              //由于无ID,就只能按索引来修改了,这里只修改了索引为0的菜单项,在单文档中是"文件"菜单项              if(Index == 0)              {                  Str.LoadString(TEXT("IDS_FILE"));                  pButton->m_strText = Str;              }            }          ++Index;      }      while( pButton != NULL );    B, 修改由顶层菜单弹出菜单的有ID的菜单项. 

      响应ON_UPDATE_COMMAND_UI 然后在其中修改,代码如下:

[cpp] view plain copyvoid CMainFrame::OnUpdateFileNew(CCmdUI *pCmdUI)  {      CAdoString Str;      Str.LoadString(TEXT("IDS_FILE_NEW"));        //加上如下判断,是只更新菜单中这个ID对应的串,而工具栏中对应的串,在其它地方修改,      //如果没有这个条件,工具栏上显示的文字将与菜单栏相同.      if(pCmdUI->m_pMenu != NULL)       {          pCmdUI->SetText(Str);      }        //特别注意: 如果这里调用这类的函数,可能导致工具栏不弹出ToolTip提示.      //m_wndToolBar.AdjustLayout();   }  如果相让菜单中显示的文字和工具栏上文字相同,则去掉 if(pCmdUI->m_pMenu !=NULL)这句.

2. 工具栏CMFCToolBar文字修改.

    A. 在ON_UPDATE_COMMAND_UI , 前面已经说过.

   B. 使用CMFCToolbar的方法修改. 代码如下:   (特别注意: 在单文档中,此函数一定要在主窗口ShowWindow之后调用)

[cpp] view plain copy//修改工具栏文字      UINT itemID = 0;      int nCount  = m_wndToolBar.GetCount();      for( int i=0 ;i<nCount; ++i)      {          if( TBBS_SEPARATOR != m_wndToolBar.GetButtonStyle(i) )//分隔栏没有文字          {              itemID = m_wndToolBar.GetItemID(i);//根据命令ID修改对应文字.              switch(itemID)              {              case ID_FILE_NEW:                  Str.LoadString(TEXT("TOOL_NEW"));                  m_wndToolBar.SetToolBarBtnText(i,Str);                  break;              case ID_FILE_OPEN:                  Str.LoadString(TEXT("TOOL_OPEN"));                  m_wndToolBar.SetToolBarBtnText(i,Str);                  break;              case ID_FILE_SAVE:                  Str.LoadString(TEXT("TOOL_SAVE"));                  m_wndToolBar.SetToolBarBtnText(i,Str);                  break;              case ID_FILE_PRINT:                  Str.LoadString(TEXT("TOOL_PRINT"));                  m_wndToolBar.SetToolBarBtnText(i,Str);                  break;              }          }        }  3. 修改Prompt信息.

    Prompt信息分成两段: 一般格式如下:  

        保存活动文档/n保存

    在编辑菜单项或者工具栏项时如果输入如上信息,则会被分成两段.   "保存活动文档" 和 " 保存".

    "保存活动文档" 这段会在你鼠标移动到菜单项上或者工具栏项上时,显示到 状态栏 中. 而 "保存"则作为菜单项和工具栏ToolTip的标题.  

    

   这两段字不能在同一个地方动态修改.

   要分为两次.

  A. 修改 /n 前的部分.即  "  保存活动文档/n保存 "   中的     "保存活动文档"  串.

  通过在主窗口类中重载虚函数: GetMessageString 实现修改,代码如下:

 

[cpp] view plain copyvoid CMainFrame::GetMessageString(UINT nID, CString& rMessage) const  {                CAdoString Str;        //根据菜单或者工具栏命令ID加载自己的串,否则调用基类函数      if( nID == ID_FILE_OPEN)      {           Str.LoadString(TEXT("IDS_TIP_FILE_OPEN"));           rMessage = Str;           return;      }      else if( nID == ID_FILE_NEW )      {          Str.LoadString(TEXT("IDS_TIP_FILE_NEW"));          rMessage = Str;          return;      }        CMDIFrameWndEx::GetMessageString(nID, rMessage);  }  

B. 修改 /n之后的部分, 即 "  保存活动文档/n保存 "   中的     "保存"  串.

   些串的修改,需要派生CMFCToolBar类, 并重载虚函数OnToolHitTest.  代码如下:

 

[cpp] view plain copyINT_PTR CMyMFCToolBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const  {      static CString strText;      CAdoString adoStr;      INT_PTR hInt = CMFCToolBar::OnToolHitTest(point,pTI);//先调用基类函数,再修改串.      strText = pTI->lpszText;      int Index = strText.Find('(');      if(Index > 0)      {          strText.Delete(0,Index);//去掉加速键前的文字,如 "New(Ctrl+N)前面的" new      }      else      {          strText.Empty(); //如果没有加速键文本,则全部清空.      }      if(pTI->uId == ID_FILE_NEW )      {          adoStr.LoadString(TEXT("TOOL_NEW"));                }      else if(pTI->uId == ID_FILE_OPEN )      {          adoStr.LoadString(TEXT("TOOL_OPEN"));      }      else if(pTI->uId == ID_FILE_SAVE)      {          adoStr.LoadString(TEXT("TOOL_SAVE"));      }      else      {          ((CString&)adoStr) = TEXT("Other");      }      strText = adoStr + strText; //重新组合成: New(Ctrl+N)形式.            //基类中会释放这个指针pTI->lpszText,但是由于我们要修改这个串,      //所以原来的空间不一定够,所以要释放掉原来的,并重新申请,      int len = strText.GetLength()*sizeof(TCHAR);      TCHAR *pBuf =(TCHAR*)malloc(len+10);      memset(pBuf,0,len+10);      _tcscpy_s(pBuf,strText.GetLength()+2,strText);      free(pTI->lpszText);       pTI->lpszText = pBuf;        return hInt;  }  

至此, 动态修改CMFCMenuBar及CMFCToolBar的文字及Prompt,ToolTip文字.就全部完成.

补充说明:  工具栏上的文字要使得修改后能马上看到效果,则要把如下函数多调用几次.

[cpp] view plain copym_wndToolBar.AdjustLayout();      m_wndToolBar.RecalcLayout();      m_wndToolBar.CalcFixedLayout(TRUE,FALSE);      m_wndToolBar.AdjustLayout();      m_wndToolBar.RecalcLayout();      m_wndToolBar.CalcFixedLayout(TRUE,TRUE);      m_wndToolBar.AdjustLayout();      m_wndToolBar.RecalcLayout();      m_wndToolBar.CalcFixedLayout(TRUE,TRUE);  

由于文字改变后,工具栏的重新计算每个工具栏按钮的宽度及整个工具栏的宽度. 所认有以上函数的调用. 至于为什么要调用多次才能正确,确是没有去深究他.

还有要注意,注册表里面保存有工具栏配置信息, 可能需要删除注册表项. 当然比较好的,还是在在CMFCToolBar的派生类中重载LoadState及SaveState函数,什么也不做,直接返回.

[cpp] view plain copyBOOL CMyMFCToolBar::LoadState(                         LPCTSTR lpszProfileName/*=NULL*/,                         int nIndex/*=-1*/,                         UINT uiID/*=(UINT)-1*/                          )  {      return TRUE;  }  

不知道微软的东西是越来越难用,还是因为不用之不得其道 ,总感觉这些新类除了好看, 用起真是难用之极啊.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表