实现一个展示数据Demo--- 渣渣级别

本文介绍了一种自定义编辑控件的实现方法,通过创建一个可以动态展示数据的控件,实现数据表格化显示,并支持鼠标悬停时显示完整数据。文章详细描述了控件的创建过程、数据展示逻辑及鼠标事件处理。

实现一个展示数据Demo--- 渣渣级别

效果图:

                                                    

思维:

OPaint :

                   画 Rows X Cols 行列(自定义:使用二维动态数组 http://blog.youkuaiyun.com/singebogo/article/details/70477737),自定义行列间隔,计算坐标,插入字符串,展示数据大于列间隔则截断显示。

                  鼠标移动MouseMove 判断鼠标所在行列,获取该行列的字符串,则显示所在行列的字符串.

关键代码:

      如何调用

m_edit.Create(8, 16, WS_CHILD | WS_VISIBLE, CRect(200, 200, 200, 60), this, 125);
	//m_edit.Create(nullptr, nullptr, WS_CHILD | WS_VISIBLE, CRect(200, 200, 200, 60), this, 125);
	m_edit.ShowWindow(SW_SHOW);
	
	m_edit.SetEditBkGrdColor(ViewDef::CORE_HexToRGB(L"FFFFFF"));
	m_edit.SetFontBkGrdColor(ViewDef::CORE_HexToRGB(L"000000"));
	m_edit.SetFontColor(RGB(255,255,255));
	m_edit.SetCaptionRectangleBkgrd(BLACK_BRUSH);

	m_edit.strCaption = L"Caption: -----CPU HardInformation--------";


	// 数组初始化
	m_edit.strMsgArray[0][0] = L"AddressWidth";
	m_edit.strMsgArray[0][1] = L"Architecture";
	m_edit.strMsgArray[0][2] = L"Availability";
	m_edit.strMsgArray[0][3] = L"Caption";
	m_edit.strMsgArray[0][4] = L"ConfigManagerErrorCode";
	m_edit.strMsgArray[0][5] = L"ConfigManagerUserConfig";
	m_edit.strMsgArray[0][6] = L"CpuStatus";
	m_edit.strMsgArray[0][7] = L"CreationClassName";
	m_edit.strMsgArray[0][8] = L"CurrentClockSpeed";
	m_edit.strMsgArray[0][9] = L"CurrentVoltage";
	m_edit.strMsgArray[0][10] = L"DataWidth";

Opaint

void COwnEditCtrl::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO:  在此处添加消息处理程序代码
	// 不为绘图消息调用 CWnd::OnPaint()

	// 如何动态画图 COL ROW 确定 m_RowCount | m_ColCount 参数化
	// 数据填充自动化  行列间隔  1、行确定 列多次  2、 行长度 列确定

	CRect ClientRect;
	GetClientRect(ClientRect);

	ULONG width = ClientRect.Width();
	ULONG height = ClientRect.Height();

	ULONG GrdHeight = height - CAPTIONHEIGHT;					// 画格高度
	ULONG GrdWidth = width;										// 画格宽度

	m_GrdHeight = GrdHeight;
	m_GrdWidth = GrdWidth;

	// 画格的开始起点坐标
	POINT postion;
	postion.x = 0;
	postion.y = CAPTIONHEIGHT;

	// 行间隔
	ULONG RowQuealPart = GrdHeight / m_RowCount;
	// 列间隔
	ULONG ColQuealPart = GrdWidth / m_ColCount;

	// 行间隔
	m_RowQuealPart = RowQuealPart;
	// 列间隔
	m_ColQuealPart = ColQuealPart;

	// 字体结构tm声明
	TEXTMETRIC tm;
	GetTextMetrics(dc, &tm);

	// 字体的宽度
	ULONG cxChar = tm.tmAveCharWidth;

	// 字体的高度
	ULONG LocyChar = tm.tmHeight + tm.tmExternalLeading;

	// 设置字体背景颜色
	dc.SetBkColor(m_ftbnkgrdrgb);

	// 设置字体颜色
	dc.SetTextColor(m_ftrgb);

	// 画标题栏
	dc.FillRect(CRect(0, 0, width, CAPTIONHEIGHT), (CBrush *)dc.SelectStockObject(m_BrushCaptionRectangle));
	dc.Rectangle(0, 0, width, CAPTIONHEIGHT);

	// 坐标栏填充字体  CAPTIONHEIGHT - LocyChar - 1 : 标题栏高度 - 字体高度 - 1 减一原因是字体覆盖下端线
	dc.TextOut(width / 3, CAPTIONHEIGHT - LocyChar - 1, strCaption);

	// 画行 m_RowCount行 m_RowCount+1 条线
	for (UINT i = 0; i <= m_RowCount; i++)
	{
		dc.MoveTo(0, RowQuealPart * i + CAPTIONHEIGHT);
		dc.LineTo(GrdWidth, RowQuealPart * i + CAPTIONHEIGHT);
	}

	// 画列 m_ColCount 列 m_ColCount+1 条线
	for (UINT i = 0; i <= m_ColCount; i++)
	{
		// 对齐最后一列
		if (i == m_ColCount)
		{
			dc.MoveTo(GrdWidth - 1, CAPTIONHEIGHT);
			dc.LineTo(GrdWidth - 1, RowQuealPart * m_RowCount + CAPTIONHEIGHT);
		}
		else
		{
			dc.MoveTo(ColQuealPart*i, CAPTIONHEIGHT);
			dc.LineTo(ColQuealPart*i, RowQuealPart * m_RowCount + CAPTIONHEIGHT);
		}
	}

	// 字体离上边界距离 = (行宽 - 字体高度) / 2  居中
	ULONG FontMarginUp = (RowQuealPart - LocyChar) / 2;
	// 字体离左边界距离 = 字体的宽度
	ULONG FontMarginLeft = cxChar;
	//清理坐标点数组??

	// 获取输出文本的坐标点
	for (UINT i = 0; i < m_ColCount; i++)
	{
		for (UINT j = 0; j < m_RowCount; j++)
		{
			// 列坐标
			PointArray[i][j].x = ColQuealPart * i;

			// 行坐标
			PointArray[i][j].y = RowQuealPart * j + CAPTIONHEIGHT;

			// 数据截断
			CString strtextout = nullptr;
			// 字符串的长度 = 字符长度 * 字体宽度
			UINT nlen = strMsgArray[i][j].GetLength();
			nlen = nlen * cxChar;
			// 字体长度大于列宽度则截断显示
			if ((UINT)ColQuealPart < nlen)
			{
				// 超出范围则对半截断显示+“...”标识截断

				strtextout = strMsgArray[i][j].Left((int)((ColQuealPart / cxChar) / 2));
				strtextout += L"...";
			}
			else
			{
				strtextout = strMsgArray[i][j];
			}
			// 偶数行进行填充
			if (i % 2 == 0)
			{
				dc.TextOut(PointArray[i][j].x + FontMarginLeft, PointArray[i][j].y + FontMarginUp, strtextout);
			}
			else
			{
				// 奇数行显示
				dc.TextOut(PointArray[i][j].x + FontMarginLeft, PointArray[i][j].y + FontMarginUp, strtextout);
			}
		}
	}
}

OnMouseMove

void COwnEditCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO:  在此添加消息处理程序代码和/或调用默认值
	// 鼠标移动
	// 计算在哪行那列
	// 对该行进行判断处理
	// 是省略的行列 则显示改行

	// 在行列范围内计算出 i = x / RowQuealPart j = (y - CaptionHeight)/ ColQuealpart
	// 获取行列的数据
	// 显示该行列的文本数据 TextOut(x,y,CString)
	// 消除影子R2_NOTXORPEN  获取要绘制之前的图 将其透明 再画现在的图
	// 原来行列画出 ,消除 1、先判断是不是已经出行列 2、出行列这消除上一个行列,3、显示下一个行列

	// 有效区间

	if (point.x > (UINT)0 && point.y > CAPTIONHEIGHT && point.x < m_GrdWidth && point.y < m_GrdHeight)
	{
		// 获取对应行列
		UINT i = point.x / m_ColQuealPart;
		UINT j = (point.y - CAPTIONHEIGHT) / m_RowQuealPart;
		// 不是规定行列 则返回
		if (i >= m_ColCount || j >= m_RowCount)
		{
			return;
		}
		//获取设备管理区
		CDC* cdc = GetDC();
		HDC hdc = cdc->GetSafeHdc();

		// 获取字体信息
		// 字体结构tm声明
		TEXTMETRIC tm;
		GetTextMetrics(cdc->GetSafeHdc(), &tm);

		// 字体的宽度
		ULONG cxChar = tm.tmAveCharWidth;
		// 字体的高度
		ULONG LocyChar = tm.tmHeight + tm.tmExternalLeading;

		// 字体离上边界距离 = (行宽 - 字体高度) / 2  居中
		ULONG FontMarginUp = (m_RowQuealPart - LocyChar) / 2;

		// 上一次图形处理,局部刷新
		// 判断鼠标是不是已经不再old上次的行列, 在则不进行处理,本次画则放弃,不在则进行上次图形刷新,
		CRect rect;
		rect.left = PointArray[m_oldi][m_oldj].x;
		rect.top = PointArray[m_oldi][m_oldj].y;
		rect.right = rect.left + m_ColQuealPart;
		rect.bottom = rect.top + m_RowQuealPart;

		// 判断是不是在old行列范围内
		if (point.x >= rect.left && point.x <= rect.right && \
			point.y >= rect.top && point.y <= rect.bottom)
		{
			cdc->DeleteDC();
			CWnd::OnMouseMove(nFlags, point);
			return;
		}
		else
		{
			rect.right = rect.left + m_ColQuealPart + cxChar * strMsgArray[m_oldi][m_oldj].GetLength();
			InvalidateRect(rect);
		}

		// 本次图形处理
		// 行列 坐标
		cdc->TextOut(PointArray[i][j].x, PointArray[i][j].y + FontMarginUp, strMsgArray[i][j]);

		// 删除设备管理器
		cdc->DeleteDC();
		m_oldi = i;
		m_oldj = j;
	}
	CWnd::OnMouseMove(nFlags, point);
}



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值