fast/Plugin/Driver/CEXVirtualListCtrl.cpp
2025-01-20 10:30:01 +08:00

316 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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;
}