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

被折叠的 条评论
为什么被折叠?



