📄 owner_drawn_menu_2b.shtml
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Jaroslav Pisk">
<TITLE>Menu - Owner draw menu</TITLE>
</HEAD>
<body background="../fancyhome/back.gif" bgcolor="#FFFFFF" link="#B50029" vlink="#8E2323" alink="#FF0000" bgproperties="fixed">
<table WIDTH="100%"><tr WIDTH="100%"><td align=center><!--#exec cgi="/cgi/ads.cgi"--><td></tr></table>
<CENTER><H3><FONT COLOR="#AOAO99">Yet another owner draw menu</FONT></H3></CENTER>
<CENTER><H3><HR></H3></CENTER>
This macro was contributed by <A href="mailto:jerryiii@sprynet.com">Jaroslav Pisk</A> (Jerry)
<p>This menu is another modification of owner draw menus (#2 if you want to know). I have
corrected an error I found (use of uninitialized variable in DrawItem), change item measurement
(now the height is the bigger from icon height or menu height) and changed the menu concept from
using separate icons for each item to use of image list (CImageList) so all the icons are in one
bitmap. For more information see <A href="owner_drawn_menu2.shtml">original article by Ben Ashley</A></p>
<p><font face="Arial"><strong>Header file</strong></font></p>
<PRE><TT><FONT COLOR="#990000">
#ifndef __BITMAP_MENU_H__
#define __BITMAP_MENU_H__
class BMenuData
{
public:
BMenuData();
char menuText[32];
int menuIconNormal;
int menuIconSelected;
int menuIconDisabled;
UINT nID;
};
typedef enum {Normal,TextOnly} HIGHLIGHTSTYLE;
class CBitmapMenu : public CMenu // Derived from CMenu
{
public:
CBitmapMenu(CImageList* pList = NULL);
virtual ~CBitmapMenu();
protected:
CTypedPtrArray<CPtrArray, BMenuData*> m_MenuList; // Stores list of menu items
// When loading an owner-drawn menu using a Resource, CBitmapMenu must keep track of
// the popup menu's that it creates. Warning, this list *MUST* be destroyed
// last item first :)
CTypedPtrArray<CPtrArray, CBitmapMenu*> m_SubMenus; // Stores list of sub-menus
public:
virtual void DrawItem(LPDRAWITEMSTRUCT); // Draw an item
virtual void MeasureItem(LPMEASUREITEMSTRUCT); // Measure an item
void SetTextColor (COLORREF ); // Set the text color
void SetBackColor (COLORREF); // Set background color
void SetHighlightColor (COLORREF); // Set highlight Color
void SetHighlightStyle (HIGHLIGHTSTYLE ); // Set Highlight style
void SetHighlightTextColor (COLORREF); // Set Highlight text color
void SetImageList(CImageList* pList);
BOOL AppendODMenu(LPCTSTR lpstrText,
UINT nFlags = MF_OWNERDRAW,
UINT nID = 0,
int nIconNormal = -1,
int nIconSelected = -1,
int nIconDisabled = -1); // Owner-Drawn Append
BOOL ModifyODMenu(LPCTSTR lpstrText,
UINT nID = 0,
int nIconNormal = -1,
int nIconSelected = -1,
int nIconDisabled = -1); // Owner-Drawn Modify
virtual BOOL LoadMenu(LPCTSTR lpszResourceName); // Load a menu
virtual BOOL LoadMenu(int nResource); // ...
virtual BOOL DestroyMenu();
protected:
COLORREF m_crText;
COLORREF m_clrBack;
COLORREF m_clrText;
COLORREF m_clrHilight;
COLORREF m_clrHilightText;
LOGFONT m_lf;
CFont m_fontMenu;
UINT m_iMenuHeight;
BOOL m_bLBtnDown;
CImageList* m_pList;
CBrush m_brBackground,m_brSelect;
CPen m_penBack;
HIGHLIGHTSTYLE m_hilightStyle;
};
#endif //__BITMAP_MENU_H__
</FONT></TT></PRE>
<p><strong><font face="Arial">C++ file</font></strong></p>
<PRE><TT><FONT COLOR="#990000">
#include <afxwin.h>
#include <afxcmn.h>
#include <afxtempl.h>
#include <BitmapMenu.h>
BMenuData::BMenuData()
{
menuIconNormal = -1;
menuIconSelected = -1;
menuIconDisabled = -1;
nID=0;
}
CBitmapMenu::CBitmapMenu(CImageList* pList)
{
m_pList = pList;
m_clrText = GetSysColor(COLOR_MENUTEXT);
m_clrBack = GetSysColor(COLOR_MENU);
m_brBackground.CreateSolidBrush(m_clrBack);
m_penBack.CreatePen(PS_SOLID,0,m_clrBack);
m_crText = m_clrText;
m_bLBtnDown = FALSE;
m_hilightStyle = Normal;
m_clrHilight = GetSysColor(COLOR_HIGHLIGHT);
m_brSelect.CreateSolidBrush(m_clrHilight);
m_clrHilightText = GetSysColor(COLOR_HIGHLIGHTTEXT);
ZeroMemory((LPVOID)&m_lf,sizeof(LOGFONT));
NONCLIENTMETRICS nm;
nm.cbSize = sizeof(NONCLIENTMETRICS);
//Get the system metrics for the Captionfromhere
VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,0,&nm,0));
m_lf = nm.lfMenuFont;
m_iMenuHeight = nm.iMenuHeight;
m_fontMenu.CreateFontIndirect(&m_lf);
}
CBitmapMenu::~CBitmapMenu()
{
DestroyMenu();
}
BOOL CBitmapMenu::DestroyMenu()
{
// Destroy Sub menus:
int m;
for( m = m_SubMenus.GetUpperBound(); m >= 0; m-- )
delete(m_SubMenus[m]);
m_SubMenus.RemoveAll();
// Destroy brushes:
if( (HBRUSH)m_brBackground != NULL )
m_brBackground.DeleteObject();
if( (HFONT)m_fontMenu != NULL )
m_fontMenu.DeleteObject();
if( (HBRUSH)m_brSelect != NULL )
m_brSelect.DeleteObject ();
// Destroy menu data
int numItems;
numItems = m_MenuList.GetUpperBound();
for( m = 0; m <= numItems; m++ )
delete(m_MenuList[m]);
m_MenuList.RemoveAll();
// Call base-class implementation last:
return(CMenu::DestroyMenu());
}
/*
=================================================================================
void CBitmapMenu::DrawItem(LPDRAWITEMSTRUCT)
---------------------------------------
Called by the framework when a particular item needs to be drawn. We overide
this to draw the menu item in a custom-fashion, including icons and the 3D
rectangle bar.
=================================================================================
*/
void CBitmapMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(lpDIS != NULL);
CDC* pDC;
pDC = CDC::FromHandle(lpDIS->hDC);
CRect rect;
HICON hIcon;
int iconX;
int iconY;
COLORREF crText;
crText = m_crText;
// draw the colored rectangle portion
rect.CopyRect(&lpDIS->rcItem);
// draw the up/down/focused/disabled state
UINT action;
UINT state;
action = lpDIS->itemAction;
state = lpDIS->itemState;
CString strText;
LOGFONT lf;
lf = m_lf;
CFont dispFont;
CFont *pFont;
if( lpDIS->itemData != NULL )
{
int nIconNormal = (((BMenuData*)(lpDIS->itemData))->menuIconNormal);
int nIconSelected = (((BMenuData*)(lpDIS->itemData))->menuIconSelected);
int nIconDisabled = (((BMenuData*)(lpDIS->itemData))->menuIconDisabled);
strText = (((BMenuData*)(lpDIS->itemData))->menuText);
if(nIconNormal == -1)
hIcon = NULL;
else
{
hIcon = NULL;
// Obtain the IDs for the appropriate Icons:
if( state & ODS_SELECTED && !(state & ODS_GRAYED) )
{
// Selected (but not disabled)
if( nIconSelected != -1 )
{
IMAGEINFO ii;
if( m_pList->GetImageInfo(nIconSelected, &ii) )
{
hIcon = m_pList->ExtractIcon(nIconSelected);
iconX = ii.rcImage.right - ii.rcImage.left;
iconY = ii.rcImage.bottom - ii.rcImage.top;
}
}
}
else
{
if( state & ODS_GRAYED )
// Disabled (selected or not)
if( nIconDisabled != -1 )
{
IMAGEINFO ii;
if( m_pList->GetImageInfo(nIconDisabled, &ii) )
{
hIcon = m_pList->ExtractIcon(nIconDisabled);
iconX = ii.rcImage.right - ii.rcImage.left;
iconY = ii.rcImage.bottom - ii.rcImage.top;
}
}
}
// If we didn't manage to select a specific icon, we'll use the
// default (normal) one...
if( hIcon == NULL )
{
IMAGEINFO ii;
if( m_pList->GetImageInfo(nIconNormal, &ii) )
{
hIcon = m_pList->ExtractIcon(nIconNormal);
iconX = ii.rcImage.right - ii.rcImage.left;
iconY = ii.rcImage.bottom - ii.rcImage.top;
}
}
}
}
else
{
strText.Empty();
hIcon = NULL;
}
if( (state & ODS_SELECTED) )
{
// draw the down edges
CPen *pOldPen = pDC->SelectObject(&m_penBack);
// You need only Text highlight and thats what you get
if( m_hilightStyle != Normal )
pDC->FillRect(rect,&m_brBackground);
else
pDC->FillRect(rect,&m_brSelect);
pDC->SelectObject(pOldPen);
// This version provides a black-border:
//pDC->Draw3dRect(rect,GetSysColor (COLOR_3DHILIGHT),RGB(0,0,0));
//lf.lfWeight = FW_BOLD;
if( (HFONT)dispFont != NULL )
dispFont.DeleteObject();
dispFont.CreateFontIndirect(&lf);
crText = m_clrHilightText;
}
else
{
CPen *pOldPen = pDC->SelectObject(&m_penBack);
pDC->FillRect (rect,&m_brBackground);
pDC->SelectObject (pOldPen);
// draw the up edges
pDC->Draw3dRect (rect,m_clrBack,m_clrBack);
if( (HFONT)dispFont != NULL )
dispFont.DeleteObject();
dispFont.CreateFontIndirect(&lf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -