菜单自绘加图标怎么实现
菜单自绘加图标如何实现?
rt
------解决方案--------------------
参考:http://www.copathway.com/vchelp/source/submit/rcoolmenu.zip
另外www.codeguru.com的menu的链接中有有源码。
这个的原理就是利用BitBlt在DrawItem中
将竖着的位图传送到菜单项中,
其实VC中的菜单上加图标也是这么做的,
比如使用工具栏的位图,用BitBlt传到菜单项上,
只不过这个要求你位图和菜单项大小要恰好合适,否则就对偏了。
------解决方案--------------------
自绘例子,修改一下就可以了
// XPMenu.h: interface for the CXPMenu class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_XPMENU_H__EE2550C4_41A5_4313_8B33_186F4476AD69__INCLUDED_)
#define AFX_XPMENU_H__EE2550C4_41A5_4313_8B33_186F4476AD69__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// informations for menu items
class CItemInfo
{
public:
UINT uIdNormal;
UINT uIdSelect;
CString sText;
};
class CXPMenu : public CMenu
{
public:
// construction / destruction
CXPMenu();
virtual ~CXPMenu();
// general functions
void DrawBgClr(CDC* pDC, CRect rect, BOOL bSelected);
void DrawIcon(CDC* pDC, CRect rect, UINT uIdNormal, UINT uIdSelect, BOOL bSelected);
void DrawText(CDC* pDC, CRect rect, CString sText);
// virtual functions
virtual void DrawItem(LPDRAWITEMSTRUCT);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS);
};
#endif // !defined(AFX_XPMENU_H__EE2550C4_41A5_4313_8B33_186F4476AD69__INCLUDED_)
// XPMenu.cpp: implementation of the CXPMenu class.
#include "stdafx.h "
#include "XPMenu.h "
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#ifndef GRAY_AREA_LENGTH
#define GRAY_AREA_LENGTH 0x00000019
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXPMenu::CXPMenu()
{}
CXPMenu::~CXPMenu()
{}
// draw the menu with XP styles
void CXPMenu::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
// get dc
CDC* pDC = CDC::FromHandle(lpDIS-> hDC);
VERIFY(pDC);
pDC-> SetBkMode(TRANSPARENT);
// get position
CRect rcItem = lpDIS-> rcItem;
// get states
UINT uState = lpDIS-> itemState;
// the data of menu item is NULL then return
if(lpDIS-> itemData == NULL)
return;
// get item informations
UINT uIdNormal = ((CItemInfo*)(lpDIS-> itemData))-> uIdNormal;
UINT uIdSelect = ((CItemInfo*)(lpDIS-> itemData))-> uIdSelect;
CString sText = ((CItemInfo*)(lpDIS-> itemData))-> sText;
// get icon position and text position
CRect rcIcon(rcItem);
rcIcon.right = rcIcon.left + GRAY_AREA_LENGTH;
CRect rcText(rcItem);
rcText.left = rcIcon.right;
// draw background and icon
if(uState & ODS_SELECTED)
{
DrawBgClr(pDC, rcItem, TRUE);
DrawIcon(pDC, rcIcon, uIdNormal, uIdSelect, TRUE);
}
else
{
DrawBgClr(pDC, rcItem, FALSE);
DrawIcon(pDC, rcIcon, uIdNormal, uIdSelect, FALSE);
}
// draw text
DrawText(pDC, rcText, sText);
}
// draw background color
void CXPMenu::DrawBgClr(CDC* pDC, CRect rect, BOOL bSelected)
{
if(bSelected)
{
// draw frame
pDC-> SelectStockObject(NULL_BRUSH);
pDC-> SelectStockObject(BLACK_PEN);
rt
------解决方案--------------------
参考:http://www.copathway.com/vchelp/source/submit/rcoolmenu.zip
另外www.codeguru.com的menu的链接中有有源码。
这个的原理就是利用BitBlt在DrawItem中
将竖着的位图传送到菜单项中,
其实VC中的菜单上加图标也是这么做的,
比如使用工具栏的位图,用BitBlt传到菜单项上,
只不过这个要求你位图和菜单项大小要恰好合适,否则就对偏了。
------解决方案--------------------
自绘例子,修改一下就可以了
// XPMenu.h: interface for the CXPMenu class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_XPMENU_H__EE2550C4_41A5_4313_8B33_186F4476AD69__INCLUDED_)
#define AFX_XPMENU_H__EE2550C4_41A5_4313_8B33_186F4476AD69__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// informations for menu items
class CItemInfo
{
public:
UINT uIdNormal;
UINT uIdSelect;
CString sText;
};
class CXPMenu : public CMenu
{
public:
// construction / destruction
CXPMenu();
virtual ~CXPMenu();
// general functions
void DrawBgClr(CDC* pDC, CRect rect, BOOL bSelected);
void DrawIcon(CDC* pDC, CRect rect, UINT uIdNormal, UINT uIdSelect, BOOL bSelected);
void DrawText(CDC* pDC, CRect rect, CString sText);
// virtual functions
virtual void DrawItem(LPDRAWITEMSTRUCT);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS);
};
#endif // !defined(AFX_XPMENU_H__EE2550C4_41A5_4313_8B33_186F4476AD69__INCLUDED_)
// XPMenu.cpp: implementation of the CXPMenu class.
#include "stdafx.h "
#include "XPMenu.h "
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#ifndef GRAY_AREA_LENGTH
#define GRAY_AREA_LENGTH 0x00000019
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXPMenu::CXPMenu()
{}
CXPMenu::~CXPMenu()
{}
// draw the menu with XP styles
void CXPMenu::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
// get dc
CDC* pDC = CDC::FromHandle(lpDIS-> hDC);
VERIFY(pDC);
pDC-> SetBkMode(TRANSPARENT);
// get position
CRect rcItem = lpDIS-> rcItem;
// get states
UINT uState = lpDIS-> itemState;
// the data of menu item is NULL then return
if(lpDIS-> itemData == NULL)
return;
// get item informations
UINT uIdNormal = ((CItemInfo*)(lpDIS-> itemData))-> uIdNormal;
UINT uIdSelect = ((CItemInfo*)(lpDIS-> itemData))-> uIdSelect;
CString sText = ((CItemInfo*)(lpDIS-> itemData))-> sText;
// get icon position and text position
CRect rcIcon(rcItem);
rcIcon.right = rcIcon.left + GRAY_AREA_LENGTH;
CRect rcText(rcItem);
rcText.left = rcIcon.right;
// draw background and icon
if(uState & ODS_SELECTED)
{
DrawBgClr(pDC, rcItem, TRUE);
DrawIcon(pDC, rcIcon, uIdNormal, uIdSelect, TRUE);
}
else
{
DrawBgClr(pDC, rcItem, FALSE);
DrawIcon(pDC, rcIcon, uIdNormal, uIdSelect, FALSE);
}
// draw text
DrawText(pDC, rcText, sText);
}
// draw background color
void CXPMenu::DrawBgClr(CDC* pDC, CRect rect, BOOL bSelected)
{
if(bSelected)
{
// draw frame
pDC-> SelectStockObject(NULL_BRUSH);
pDC-> SelectStockObject(BLACK_PEN);