316 lines
7.8 KiB
C++
316 lines
7.8 KiB
C++
|
// 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;
|
|||
|
}
|