孙鑫VC++讲座-笔记补充(六)

时间:2022-06-10 09:44:05

1、完成对一个Menu Item 的标识:CheckMenuItem()

// CMainFrame::OnToggleTestMenuItem() is a menu command handler for
// "Test" menu item (whose resource id is ID_HELP_TEST). It toggles
// the checked or unchecked state of the "Test" menu item.
// CMainFrame is a CFrameWnd-derived class.

void CMainFrame::OnToggleTestMenuItem()
{
   // Get the popup menu which contains the "Test" menu item.
   CMenu* mmenu = GetMenu();
   CMenu* submenu = mmenu->GetSubMenu(3);

   // Check the state of the "Test" menu item. Check the menu item
   // if it is currently unchecked. Otherwise, uncheck the menu item
   // if it is not currently checked.
   UINT state = submenu->GetMenuState(ID_HELP_TEST, MF_BYCOMMAND);
   ASSERT(state != 0xFFFFFFFF);

   if (state & MF_CHECKED)
      submenu->CheckMenuItem(ID_HELP_TEST, MF_UNCHECKED | MF_BYCOMMAND);
   else
      submenu->CheckMenuItem(ID_HELP_TEST, MF_CHECKED | MF_BYCOMMAND);

在此,我们用的是GetMenuState()返回值为掩码的形式(Otherwise the return value is a mask (Boolean OR) of the values),然后把state它所包含的状态和我们所关心的状态作"&"操作,就可以看出我们所关心的状态在不在。

2、添加自定义的菜单

      (1)、自定义一菜单资源,或者采用资源编辑器,或者手动.

      (2)、定义一CMenu对象,后调用LoadMenu(ID);

      (3)、在框架类的OnCreate()中,SetMenu();

       CWnd::SetMenu():Sets the current menu to the specified menu. Causes the window to be redrawn to reflect  themenu change。

       如果为NULL,则是移除当前菜单。

3、加一个小插曲啊:在VC中将程序排版 Alt+F8

4、设置位图标题菜单:SetMenuItemBitmaps()

// The code fragment below shows how to associate bitmaps with the
// "Test" menu item. Whether the "Test" menu item is checked or
// unchecked, Windows displays the appropriate bitmap next to the menu
// item. Both IDB_CHECKBITMAP and IDB_UNCHECKBITMAP bitmaps are loaded
// in OnCreate() and destroyed in the destructor of CMainFrame class.
// CMainFrame is a CFrameWnd-derived class.

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
      return -1;

   // Load bitmaps from resource. Both m_CheckBitmap and m_UnCheckBitmap
   // are member variables of CMainFrame class of type CBitmap.
   ASSERT(m_CheckBitmap.LoadBitmap(IDB_CHECKBITMAP));
   ASSERT(m_UnCheckBitmap.LoadBitmap(IDB_UNCHECKBITMAP));

   // Associate bitmaps with the "Test" menu item.
   CMenu* mmenu = GetMenu();
   CMenu* submenu = mmenu->GetSubMenu(3);
   ASSERT(submenu->SetMenuItemBitmaps(ID_HELP_TEST, MF_BYCOMMAND,
      &m_CheckBitmap, &m_UnCheckBitmap));

   // ...
}

CMainFrame::~CMainFrame()
{
   // Destroy the bitmap objects if they are loaded successfully
   // in OnCreate().
   if (m_CheckBitmap.m_hObject)
      m_CheckBitmap.DeleteObject();

   if (m_UnCheckBitmap.m_hObject)
      m_UnCheckBitmap.DeleteObject();
}

 这个是MSDN上的例子程序,在使用SetMenuItemBitmaps()之前你要自己首先创建两个位图,定义CBitmap对象与资源关联,另外需注意的是你创建的位图大小的问题,这你必须参考GetSystemMetrics(),这个函数功能很丰富。

对与在析构函数中的操作,我是这样理解的:当我们调用LoadBitmap()是会把资源调入内存中,m_hObject 指向该资源,如果我们不把它选择进入设备描述表,我们就需要释放在内存中的资源。

一下为MSDN中的资料:

You can use the CGdiObject::DeleteObject function to delete bitmap loaded by the LoadBitmap function, or the CBitmap destructor will delete the object for you.

孙鑫VC++讲座-笔记补充(六)Caution

Before you delete the object, make sure it is not selected into a device context.