IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 菜单项与CListBox项的自绘 -> 正文阅读

[C++知识库]菜单项与CListBox项的自绘

菜单项的自绘

菜单项的自绘

步骤:
1.将需要自绘菜单项加上MF_OWNERDRAW,使用ModeifyMenu函数比较适合
2.使用WM_MEASUREITEM 设置菜单项宽度与高度
3.使用WM_DRAWITEM 绘制菜单项

  • 获得菜单,菜单项加上MF_OWNERDRAW
CMenu*pMenu=pFrame->GetMenu();
ASSERT(pFrame!=NULL);
//ASSERT ()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。 如果表达式不为0,则继续执行后面的语句。 ... ASSERT 只有在Debug 版本中才有效,如果编译为Release 版本则被忽略
for(int i=0;i<5;i++)
	pMenu->ModifyMenu(IDM_COLOR_RED+i,MF_OWNERDRAW,IDM_COLOR_RED+i);
return TRUE;
  • 设置菜单项宽度与高度
void CMainFrame::OnMeasureItem(int nIDCtl,LPMEASUREITEMSTRUCT lpmis)
{
	lpmis->itemWidth=::GetSystemMetrics(SM_CYMENU)*4;
	lpmis->itemHeight=::GetSystemMetrics(SM_CYMENU);
}
  • 绘制菜单项

绘制菜单项步骤
1.实现高亮选中项pBrush->CreateSolidBrush(::GetSysColor((lpdis->itemState & ODS_SELECTED) ? COLOR_HIGHLIGHT : COLOR_WINDOW));
2.绘制选中项边框dc.FrameRect(&(lpdis->rcItem), pBrush);
3.BitBlt绘制左边选中标志(√),右边矩形填充颜色

void CMainFrame::OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpdis)
{
	BITMAP bm;
	CBitmap bitmap;
	bitmap.LoadOEMBitmap(OBM_CHECK);
	bitmap.GetObject(sizeof(bm),&bm);//int GetObject(int nCount,LPVOID lpObject) const;
	//CGdiObject::GetObject 用定义指定对象的数据填充缓冲区&bm
	//nCount :Specifies the number of bytes to copy into the lpObject buffer.
	//lpObject:Points to a user-supplied buffer that is to receive the information.
	//https://docs.microsoft.com/en-us/cpp/mfc/reference/cgdiobject-class?view=msvc-170
	CDC dc;
	dc.Attach(lpdis->hDC);
	CBrush* pBrush = new CBrush;
	//高亮选中菜单项
	pBrush->CreateSolidBrush(::GetSysColor((lpdis->itemState & ODS_SELECTED) ? COLOR_HIGHLIGHT : COLOR_WINDOW));
	//画边框
	dc.FrameRect(&(lpdis->rcItem), pBrush);
		if (lpdis->itemState & ODS_CHECKED)
	{
		CDC dcMem;
		dcMem.CreateCompatibleDC(&dc);
		CBitmap* pOldBitMap = dcMem.SelectObject(&bitmap);
		
		dc.BitBlt(lpdis->rcItem.left + 4, lpdis->rcItem.top + (((lpdis->rcItem.bottom - lpdis->rcItem.top) - bm.bmHeight) / 2), 
			bm.bmWidth, bm.bmHeight, &dcMem, 0, 0, SRCCOPY);
			/*
			BOOL BitBlt(
							    int x,
							    int y,
							    int nWidth,
							    int nHeight,
							    CDC* pSrcDC,
							    int xSrc,
							    int ySrc,
							    DWORD dwRop);
			*/
		dcMem.SelectObject(pOldBitMap);
	}
	pBrush=new CBrush(col[lpdis->itemID-ID_COLOR_RED]);
	CRect rect = lpdis->rcItem;
	rect.DeflateRect(6,4);//缩小宽度与高度,不移动top与left
	rect.left += bm.bmWidth;
	dc.FillRect(rect, pBrush);
	delete pBrush;
	dc.Detach();
	CFrameWnd::OnDrawItem(nIDCtl, lpdis);
}
  • 效果图
    在这里插入图片描述

CListBox项的自绘

步骤:
1.覆盖** CListBox::PreCreateWindow** 函数,确保cs style 包含** LBS_OWNERDRAWFIXED** 或** LBS_OWNERDRAWVARIABLE**
2.覆盖** CListBox::MeasureItem** 设置菜单项宽度与高度
3.覆盖** CListBox::DrawItem** 绘制菜单项

class CMyListBox :public CListBox
{
public:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

	int AddIcon(HICON hIcon);
	void ProjectImage(CDC* pDC, LPRECT pRect, COLORREF clrBackColor);


	DECLARE_MESSAGE_MAP()
	afx_msg void OnLbnSelchange();
};
  • 覆盖** CListBox::PreCreateWindow** 函数,确保cs style 包含** LBS_OWNERDRAWFIXED** 或** LBS_OWNERDRAWVARIABLE**
CIconListBox::PreCreateWindow(CREATESTRUCT& cs)
{

	cs.style |=LBS_OWNERDRAWFIXED;
	//表示不含LBS_OWNERDRAWFIXED|LBS_SORT
	cs.style &=~(LBS_OWNERDRAWFIXED|LBS_SORT);
}

  • 覆盖** CListBox::MeasureItem** 函数,设置listbox item 高度与宽度
void CIconListBox::MeasureItem(LPMEASUREITEMSTRUCT lpmis)
{
	lpmis->itemHeight = 32;
}

  • 覆盖** CListBox::DrawItem** 函数,开始绘制ListBox项
void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpdis)
{
    CDC dc;
    //加载DrawItem dc
    dc.Attach(lpdis->hDC);
    CRect rect = lpdis->rcItem;
    UINT nIndex = lpdis->itemID;
    //绘制选中的项高亮
    CBrush* pBrush = new CBrush(::GetSysColor(lpdis->itemState & ODS_SELECTED ? COLOR_HIGHLIGHT : COLOR_WINDOW));
    dc.FillRect(rect, pBrush);
    delete pBrush;
    //绘制焦点矩形
    if (lpdis->itemState&ODS_FOCUS)
    {
        dc.DrawFocusRect(rect);
    }
    if (nIndex!=(UINT)-1)
    {
        dc.DrawIcon(rect.left + 4, rect.top + 2, (HICON)GetItemData(nIndex));
    }
    /*
					BOOL DrawIcon(
			   int x,
			   int y,
			   HICON hIcon 
			          );
//Retrieves the application-supplied doubleword value associated with the specified list-box item. 
	       DWORD_PTR GetItemData(  int nIndex ) const;
	*/
    dc.Detach();
}
  • 设置ListBox项 图标
int CMyListBox::AddIcon(HICON hIcon)
{
    int nIndex=AddString(_T(""));
    if ((nIndex!=LB_ERR)&&(nIndex!=LB_ERRSPACE))
    {
        SetItemData(nIndex, (DWORD)hIcon);
    }
    return nIndex;
}
  • 显示在rcImage区域
void CMyListBox::ProjectImage(CDC* pDC, LPRECT pRect, COLORREF clrBackColor)
{
    CDC dcMem;
    dcMem.CreateCompatibleDC(pDC);
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(pDC, 32, 32);
    CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);
    CBrush* pBrush = new CBrush(clrBackColor);
    dcMem.FillRect(CRect(0, 0, 32, 32), pBrush);

    delete pBrush;

    int nIndex = GetCurSel();
    if (nIndex != LB_ERR)
        dcMem.DrawIcon(0, 0, (HICON)GetItemData(nIndex));
    pDC->StretchBlt(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, &dcMem, 0, 0, 32, 32, SRCCOPY);
    dcMem.SelectObject(pOldBitmap);

}
  • 效果图
    效果图
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-16 12:52:35  更:2022-02-16 12:55:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:30:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码