一个数据采集的数据显示程序,有个listctrl控件。当收到采集的数据会更新list里的数据。
数据比较多,会产生滚动条。
当拉滚动条看下面的数据时,刷新后又回到list的头。
采集的时间短,所以影响查看list。
这个问题该怎么解决好?

解决方案 »

  1.   


    LRESULT CMainDlg::OnTimer(UINT unID,TIMERPROC lpProc)
    {
    HANDLE hSnapshot = NULL;
    list<PROCESS_INFO> lstItem;
    list<PROCESS_INFO>::iterator lstBin;
    list<JThreadView*>::iterator ThBin;
    list<JModuleView*>::iterator ModuleBin;
    vector<UINT> vcDel; //废弃的Item索引
    PROCESS_INFO TmpInfo = { 0 };
    LPPROCESSINFO lpItemData = NULL;
    LONGLONG lCpuTime;
    UINT unCount = m_lstCtrl.GetItemCount();
    UINT unIndex = 0;
    CString szStr;
    CString szPID;
    DWORD dwPri = 0,nBreak = 0;
    try
    { m_SysInfo.ReleaseSnapshot(m_hProcessSnapshot);
    m_SysInfo.CreateSnapshot(m_SysInfo.QINFO_SNAPPROCESS,m_hProcessSnapshot,0);
    //更新List View
    while(0 == m_SysInfo.GetNextProcess(m_hProcessSnapshot,&TmpInfo))
    {
    lstItem.push_back(TmpInfo);
    }
    //
    for(;unIndex < unCount;unIndex++)
    {
    lpItemData = (LPPROCESSINFO)m_lstCtrl.GetItemData(unIndex);
    if(lpItemData == NULL)
    {
    szStr.Empty();
    m_lstCtrl.GetItemText(unIndex,0,szStr);
    MessageBox(szStr);
    break;
    }
    nBreak = lstItem.size();
    for(lstBin = lstItem.begin();lstBin != lstItem.end();)
    {
    if(lstBin->ProcessId == lpItemData->dwPID)
    {
    if(lstBin->ProcessId != 0)
    JADE::JW2AHelper(CP_ACP,lstBin->lpName,szStr.GetBuffer(MAX_PATH),MAX_PATH);
    else
    szStr = "System Idle Process";
    UpdateItem(&m_lstCtrl,unIndex,*lstBin,szStr);
    szStr.ReleaseBuffer();
    szStr.Empty();
    //删除它表示处理过
    lstBin = lstItem.erase(lstBin);
    break;
    }
    else
    {
    lstBin++;
    }
    }
    //长度相等说明改Item已废弃
    if(nBreak == lstItem.size())
    {
    //该进程已被移出则存入废弃列表
    vcDel.push_back(unIndex);
    }
    }
    //操作到最后剩下的部分则就应为向List View添加更新的部分
    //将标记为删除状态的Item更新为新的
    unCount = vcDel.size(); //废弃Item数量
    unIndex = 0;
    nBreak = 0;
    //删除废弃表中想关联的窗体
    for(;unIndex != unCount;unIndex++)
    {
    ThBin = m_lstThreadView.begin();
    while(ThBin != m_lstThreadView.end())
    {
    (*ThBin)->WhoYourProcess(nBreak);
    lpItemData = (LPPROCESSINFO)(m_lstCtrl.GetItemData(vcDel[unIndex]));
    if(lpItemData->dwPID == nBreak)
    {
    delete *ThBin;
    *ThBin = NULL;
    ThBin = m_lstThreadView.erase(ThBin);
    }
    else
    ThBin++;
    }
    ModuleBin = m_lstModuleView.begin();
    while(ModuleBin != m_lstModuleView.end())
    {
    (*ModuleBin)->WhoYourProcess(nBreak);
    lpItemData = (LPPROCESSINFO)(m_lstCtrl.GetItemData(vcDel[unIndex]));
    if(lpItemData->dwPID == nBreak)
    {
    delete *ModuleBin;
    *ModuleBin = NULL;
    ModuleBin = m_lstModuleView.erase(ModuleBin);
    }
    else
    ModuleBin++;
    }
    }
    unIndex = 0;
    nBreak = 0;
    for(lstBin = lstItem.begin();lstBin!=lstItem.end();lstBin++)
    {
    if(unIndex != unCount)
    {
    //取出一个废弃条目进行更新并关闭废弃条目相应的Thread View
    //更新名称
    //搜索是否打开了相应的Thread View
    UpdateItem(&m_lstCtrl,vcDel[unIndex],*lstBin,NULL);
    //被处理过删除掉
    lstBin = lstItem.erase(lstBin);
    unIndex++;
    }
    else
    {
    //废弃表用完需要追加
    AppendItem(m_lstCtrl,*lstBin);
    }
    }
    //
    for(;unIndex != unCount;unIndex++)
    {
    //说明废弃表有剩余则删除
    //搜索是否打开了相应的Thread View
    delete (LPPROCESSINFO)m_lstCtrl.GetItemData(vcDel[unIndex]);
    m_lstCtrl.DeleteItem(vcDel[unIndex]);
    }
    szStr.Empty();
    szStr.Format("进程总数:%d",m_lstCtrl.GetItemCount());
    m_StatusBar.SetText(0,szStr,0);}catch(...)
    {
    m_lstCtrl.GetItemText(unIndex,0,szStr);
    ExitProcess(1000);
    }
    return S_OK;
    }这是我的算法
      

  2.   

    放在ontimer中,直接用insertitem().当行数GetItemCount() > GetCountPerPage()时,进行一次DeleteAllItem();