Simple bitmap menu
This article was originally selected by Burchak Alexander.
Sometimes the application uses dynamically created toolbars. Why do I want to create toolbar resources for the bitmap menu? (View Iuri Apollonio Article)
I propose to use a standard bit chart when assembling the menu map. The advantage of this class is that bitmaps and toolbar images can be distinguished by size and viewing. Such a pop-up menu in the SDI and MDI user interfaces. If you find BUGS, please ask.
All you have to do for class CBitmapmenu is:
1. Add an instance of the CBitmapMenu class to the CMAINFRAME class:
CBITMAPMENU M_MENU;
2. Add a CImageList object. For example, add its Static member to the CMAINFRAME class:
CIMAGELIST M_IMGLIST;
At the point you have in masfrm.h:
#include "bitmapmenu.h"
Class CMAINFRAME: PUBLIC CMDIFRAMEWND
{
...
PUBLIC:
CBITMAPMENU M_MENU;
Static Cimagelist M_Imglist;
...
}
Add: in mainfrm.cpp:
#include "mainfrm.h"
CIMAGELIST CMAINFRAME :: m_imglist;
3. Add n image resources to this project. One of them as CHECKMARK.
4. Add a set of CitembitMap objects to the menu item (such as adding to mainfrm.cpp), which will display the bitmap.
Citembitmap g_ibs [] =
{
Citembitmap (id_file_new, & cmainframe :: m_imglist, 0),
Citembitmap (ID_FILE_OPEN, & Camp; Mainframe :: m_imglist, 1),
Citembitmap (ID_help_contents, & cmainframe :: m_imglist, 19),
Citembitmap (-1, null, 0, & cmainframe :: m_imglist, 27)
}
Citembitmap class has 2 constructors:
Citembitmap (uint uid, cimagelist * pilnormal, uint upsNORMAL);
Citembitmap (uint uid, cimagelist * pilnormal, uint uposnormal, cimagelist * pilchecked, uint uposchecked);
among them,
UID --- Menu Item ID,
Pilnormal --- CIMAGELIST object pointer, uses a bitmap as the "normal" menu item,
PilChecked --- CImageList object pointer, uses a bitmap as the "Check" menu item,
Uposnormal --- Image index in the PilNormal image list,
Uposchecked --- Image index in the PilChecked image list,
The last Citembitmap object in the list is used to save the Checkmark image information.
This CBitmapMenu class is used to draw a menu item for the Checked state.
5. Treated in the cmainframe :: oncreate () function as follows:
M_Menu.initialize (idR_mainframe, this);
m_menu.addbitmaps (g_ibs, sizeof (g_ibs) / sizeof (citembitmap);
6. Add WM_MEASUREITEM, WM_DRAWITEM, and WM_INITMENUPOPUP message processing functions in the CMAINFRAME class. Add the message mapping of the CMAINFRAME class:
ON_WM_MEASUREITEM ()
ON_WM_DRAWITEM ()
ON_WM_INITMENUPOPUP ()
Add a next function to the CMAINFRAME class:
Void CMAINFRAME :: OnMeasureItem (int Nidctl, LpMeasureItemstruct LPMITEMSTRUCT LPMITE)
{
IF (lpmis-> CTLTYPE == ODT_MENU)
m_menu.measureItem (lpmis);
Else
CmdiframeWnd :: OnMeasureItem (Nidctl, lpmis);
}
Void CMAINFRAME :: OnDrawItem (int Nidctl, LPDrawItemstruct LPDIS)
{
IF (LPDIS-> CTLTYPE == ODT_MENU)
m_menu.drawitem (lpdis);
Else
CmdiframeWnd :: OnDrawItem (NidctL, LPDIS);
}
Void CMAINFRAME :: OnNitMenupopup (cmenu * Ppopup, uint nindex, bool bsysmenu)
{
CmdiframeWnd :: OnNIitMenupopup (PPOPUP, NINDEX, BSYSMENU);
IF (! BSYSMENU)
CBitmapMenu :: Synchronize (PPOPUP);
}
6. Optional: If you want to use the pop-up bitmap menu in the view class, you can follow:
CMenu Menu;
Verify (Menu.LoadMenu (some_popup_menu_resource_id);
CMenu * pmenu = (cmenu *) Menu.getsubmenu (0);
Assert (pmenu! = Null);
PMenu-> TrackPopupmenu (TPM_LEFTALIGN | TPM_LEFTBUTTON, X, Y, AFXGETMAINWND ());
We use AFXGETMAINWND () in TRACKPOPUPMENU () to let the main framework update the menu item. If you want to use "this" as a parent class that pops up menu, there will be two questions:
1. You need to manually check / gray / enable / disable menu items.
2. You need to add the following three message processing functions for the appropriate drawing menu.
I didn't provide a solution to the first question. The second question is to add a process function for the same message in the CMAINFRAME class:
ON_WM_MEASUREITEM ()
ON_WM_DRAWITEM ()
ON_WM_INITMENUPOPUP ()
The processing body is as follows:
Void CMYEDITVIEW :: OnMeasureItem (int Nidctl, LpMeasureItemstruct LPMITEMSTRUCT LPMITE)
{
IF (lpmis-> CTLTYPE == ODT_MENU)
((CMAINFRAME *) AFXGETMAINWND ()) -> m_menu.measureItem (lpmis);
Else
CEDITVIEW :: OnMeasureItem (Nidctl, LPMIS);
}
Void CMYEDITVIEW :: OnDrawItem (int Nidctl, LPDrawItemstruct LPDIS)
{
IF (LPDIS-> CTLTYPE == ODT_MENU) ((cmainframe *) AFXGETMAINWND ()) -> m_menu.drawitem (lpdis);
Else
CEDITVIEW :: OnDrawItem (Nidctl, LPDIS);
}
Void CMYEDITVIEW :: OnIitMenupopup (cmenu * Ppopup, uint nindex, bool bsysmenu)
{
CEDITVIEW :: OnNitMenupopup (PPOPUP, NINDEX, BSYSMENU);
IF (! BSYSMENU)
CBitmapMenu :: Synchronize (PPOPUP);
}
Full text.