fast/Plugin/Driver/CEXVirtualListCtrl.cpp

316 lines
7.8 KiB
C++
Raw Normal View History

2025-01-20 10:30:01 +08:00
// CEXVirtualListDlg.cpp: 实现文件
//
#include "stdafx.h"
#include "PluginDriver.h"
#include "CEXVirtualListCtrl.h"
#include "afxdialogex.h"
#include <iostream>
#include <string>
#include <sstream>
//控件ID只需要在当前窗口中唯一这里随便写一个就好
#define ID_VIRTUAL_LIST_CTRL (1987)
IMPLEMENT_DYNAMIC(CEXVirtualListCtrl, CListCtrl)
CEXVirtualListCtrl::CEXVirtualListCtrl()
{
m_pQueueData = NULL;
m_lOldCount = 0;
}
CEXVirtualListCtrl::~CEXVirtualListCtrl()
{
}
BEGIN_MESSAGE_MAP(CEXVirtualListCtrl, CListCtrl)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, &CEXVirtualListCtrl::OnLvnGetdispinfo)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CEXVirtualListCtrl::OnNMCustomdraw)
ON_WM_ERASEBKGND()
ON_WM_TIMER()
END_MESSAGE_MAP()
/*
void CEXVirtualListCtrl::Initialize()
{
SetExtendedStyle(GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_OWNERDATA); // 确保设置了虚拟大小样式
SetItemCountEx((int)0);
// 添加列(这里假设列是固定的,可以在构造函数中或这里添加)
InsertColumn(0, _T("ID"), LVCFMT_LEFT, 80);
InsertColumn(1, _T("Value1"), LVCFMT_LEFT, 120);
InsertColumn(2, _T("Value2"), LVCFMT_LEFT, 100);
}
*/
void CEXVirtualListCtrl::SetData(CEXMemFileQueue* pQueue)
{
m_pQueueData = pQueue;
SetItemCountEx((int)m_pQueueData->GetItemCount());
}
std::string getSubString(const char* input, int index) {
std::vector<std::string> substrings;
std::stringstream ss(input);
std::string item;
// 使用逗号作为分隔符分割字符串
while (std::getline(ss, item, ',')) {
substrings.push_back(item);
}
// 检查索引是否有效
if (index < 0 || index >= substrings.size()) {
return "";
}
// 返回对应的子串
return substrings[index];
}
void CEXVirtualListCtrl::OnLvnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVDISPINFO* pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
LV_ITEM* pItem = &(pDispInfo)->item;
if (pItem->iItem >= 0 && pItem->iItem < static_cast<int>(m_pQueueData->GetItemCount()))
{
char acTemp[DATA_LINE_SIZE + 1] = { 0 };
int lIndex = m_pQueueData->ReadItem(acTemp, pItem->iItem); //pItem->iItem为行序号即数据索引
if (pItem->mask & LVIF_TEXT)
{
CString str;
int lTempValue = 0;
switch (pItem->iSubItem) //pItem->iSubItem为列编号可以逐单元格设置内容;
{
case 0://acSeq[10];
str= getSubString(acTemp, 0).c_str();
break;
case 1://acTime[12];
str = getSubString(acTemp, 1).c_str();
break;
case 2://cIndex; // 0或1
str = getSubString(acTemp, 2).c_str();
break;
case 3://acTxRx; // 0:send, 1:recv
lTempValue = atoi(getSubString(acTemp, 3).c_str());
str = lTempValue == 0 ? "send" : lTempValue == 1 ? "recv" : "-";
break;
case 4://acID[10];
str = getSubString(acTemp, 4).c_str();
break;
case 5://acFrame;//0:data, 1:remote
lTempValue = atoi(getSubString(acTemp, 5).c_str());
str = lTempValue == 0 ? "data" : lTempValue == 1 ? "remote" : "-";
break;
case 6:////0:standard, 1:extend
lTempValue = atoi(getSubString(acTemp, 6).c_str());
str = lTempValue == 0 ? "standard" : lTempValue == 1 ? "extend" : "-";
break;
case 7://cDlc;
str = getSubString(acTemp, 7).c_str();
break;
case 8://acData[32];
str = getSubString(acTemp, 8).c_str();
break;
}
lstrcpy(pItem->pszText, str);
}
}
*pResult = 0;
}
void CEXVirtualListCtrl::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
*pResult = CDRF_DODEFAULT;
switch (pLVCD->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
{
// 获取当前项和子项的索引
int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);
char acTemp[DATA_LINE_SIZE + 1] = { 0 };
m_pQueueData->ReadItem(acTemp, nItem);
int lId = atoi(acTemp);//测试数据每条数据的最前面是10进制的ID所以这里直接使用atoi了
// 根据需要修改颜色
if (lId % 10 == 0) // 根据需要设定行颜色
{
pLVCD->clrText = RGB(255, 0, 0); // 红色文本
pLVCD->clrTextBk = RGB(200, 200, 255); // 浅蓝色背景
//*pResult = CDRF_NEWFONT | CDRF_SKIPDEFAULT;
*pResult = CDRF_NOTIFYITEMDRAW;
}
}
break;
default:
break;
}
}
BOOL CEXVirtualListCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//return TRUE; //避免闪烁
return CListCtrl::OnEraseBkgnd(pDC);
}
#define TIMER_REFRESH_LIST_ID (18989)
void CEXVirtualListCtrl::StartAutoRefresh(int lMSecond)
{
SetTimer(TIMER_REFRESH_LIST_ID, lMSecond, NULL);
}
void CEXVirtualListCtrl::StopAutoRefresh()
{
KillTimer(TIMER_REFRESH_LIST_ID);
}
void CEXVirtualListCtrl::RefreshShow()
{
int lItemCount = m_pQueueData->GetItemCount();
if (m_lOldCount == lItemCount)
{
return;
}
SetItemCountEx(lItemCount, LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);
EnsureVisible(lItemCount - 1, FALSE);
m_lOldCount = lItemCount;
}
void CEXVirtualListCtrl::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (TIMER_REFRESH_LIST_ID == nIDEvent)
{
if (NULL != m_pQueueData)
{
RefreshShow();
}
}
else
{
//自定义定时器无需调用基类OnTimer否则定时器会被强制结束
CListCtrl::OnTimer(nIDEvent);
}
}
#if 0
// CEXVirtualListDlg 对话框
IMPLEMENT_DYNAMIC(CEXVirtualListDlg, CDialogEx)
CEXVirtualListDlg::CEXVirtualListDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_CEXVirtualListDlg, pParent)
{
m_pstVirtualList = new CEXVirtualListCtrl();
}
CEXVirtualListDlg::~CEXVirtualListDlg()
{
}
void CEXVirtualListDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
//DDX_Control(pDX, ID_VIRTUAL_LIST_CTRL, *m_pstVirtualList);
}
BEGIN_MESSAGE_MAP(CEXVirtualListDlg, CDialogEx)
ON_BN_CLICKED(IDOK, &CEXVirtualListDlg::OnBnClickedOk)
ON_BN_CLICKED(IDCANCEL, &CEXVirtualListDlg::OnBnClickedCancel)
ON_WM_SIZE()
END_MESSAGE_MAP()
// CEXVirtualListDlg 消息处理程序
void CEXVirtualListDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
//CDialogEx::OnOK();
//屏蔽按下回车导致列表隐藏
}
void CEXVirtualListDlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
//CDialogEx::OnCancel();
//屏蔽按下ESC导致列表隐藏
}
void CEXVirtualListDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
if (NULL != m_pstVirtualList && NULL != m_pstVirtualList->m_hWnd)
{
m_pstVirtualList->MoveWindow(0, 0, cx, cy);
}
}
BOOL CEXVirtualListDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
if (!m_pstVirtualList->Create(WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_OWNERDATA | LVS_EX_DOUBLEBUFFER, CRect(0, 0, 0, 0), this, ID_VIRTUAL_LIST_CTRL)) {
TRACE0("Failed to create MyVirtualListCtrl\n");
delete m_pstVirtualList;
m_pstVirtualList = nullptr;
return FALSE; // 返回 FALSE 以使框架知道未成功初始化
}
// 设置控件的扩展样式和其他属性:整行选中、
m_pstVirtualList->SetExtendedStyle(LVS_EX_GRIDLINES | LVS_REPORT/*LVS_EX_VIRTUALSIZE*/);
m_pstVirtualList->Initialize();
return TRUE;
}
void CEXVirtualListDlg::SetData(CEXMemFileQueue* pQueue)
{
m_pstVirtualList->SetData(pQueue);
}
#endif
BOOL CEXVirtualListCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此添加专用代码和/或调用基类
return CListCtrl::PreCreateWindow(cs);
}
BOOL CEXVirtualListCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
// TODO: 在此添加专用代码和/或调用基类
BOOL bRet = CListCtrl::Create(dwStyle, rect, pParentWnd, nID);
SetExtendedStyle(LVS_EX_GRIDLINES | LVS_REPORT/*LVS_EX_VIRTUALSIZE*/);
SetExtendedStyle(GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_OWNERDATA); // 确保设置了虚拟大小样式
SetItemCountEx((int)0);
return bRet;
}