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

来源:互联网 发布:淘宝残疾人扶持 编辑:程序博客网 时间:2024/05/17 22:38

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.

Caution noteCaution

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