CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 25 of 25
  1. #16
    Join Date
    Aug 2006
    Posts
    515

    Re: Eliminate PumpMessage()

    Quote Originally Posted by GCDEF View Post
    There's more to it than that. It's been a while since I set one up so I don't remember the details, but from the sound of your problem, you don't have it implemented correctly.
    My implementation is that view receives data from read thread, adds it to the document and loads the list from document data. So I have all my data in one place in document class and I think it is quite in line with doc/view architecture. I would be interested to hear about anything in particular that might sound incorrect to you?

  2. #17
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Eliminate PumpMessage()

    Quote Originally Posted by zspirit View Post
    My implementation is that view receives data from read thread, adds it to the document and loads the list from document data. So I have all my data in one place in document class and I think it is quite in line with doc/view architecture. I would be interested to hear about anything in particular that might sound incorrect to you?
    I was talking about your implementation of your virtual list control. As I said, it's been a while since I set one up, but there shouldn't be any significant time involved in loading a lot of records into one.

  3. #18
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Eliminate PumpMessage()

    Check out the attached LVSelState project. It uses a virtual listview to display list items.

    The user can change the number of virtual items up to 1M items. The virtual list control gets it's data from a std::list and the list is populated from a 2nd thread.

    By default, the project waits until all the items are in the control until the control is refreshed, but you can change that behavior by commenting out the CWaitCursor and LockWindowUpdate calls.

    Code:
     
    HRESULT  Populate( CListCtrl& ctlList )
    {
      HRESULT hr = S_OK;
     
      // Add a wait cursor
      // CWaitCursor wait;
     
      long lIndex = 0;
      LVITEM lvitem = { 0 };
      int iItem = 0, iActualItem = 0;
    
      lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
     
      // Lock the List Control window so it doesn't look
      // like crap while filling
      // ctlList.LockWindowUpdate();
     
      // Lock the list
      CAutoLockT< CLVItemDataList > lock( &m_LVItemDataList );
     
      // Cycle through the list and add each item into the list control
      for(CLVItemDataList::iterator it = m_LVItemDataList.begin();
        it < m_LVItemDataList.end();
        it++)
      {
        CLVItemData* pLVItemData = (*it);
    
        lvitem.iItem = iItem;
        lvitem.iSubItem = 0;
        lvitem.lParam = reinterpret_cast<LPARAM>(pLVItemData);
     
        // Tell the list control to become 'Virtual' and request display
        // data from the lvitem.lParam.
        // See CLVSelStateDlg::OnLvnGetdispinfoList for where this happens
        lvitem.iImage = I_IMAGECALLBACK;
        lvitem.pszText = LPSTR_TEXTCALLBACK;
        lvitem.cchTextMax = MAX_LVITEMLEN;
     
        // Insert the item
        ctlList.InsertItem(&lvitem);
     
        // Set the text for each column (all virtual callbacks)
        ctlList.SetItemText(iItem, 0, LPSTR_TEXTCALLBACK);
        ctlList.SetItemText(iItem, 1, LPSTR_TEXTCALLBACK);
        ctlList.SetItemText(iItem, 2, LPSTR_TEXTCALLBACK);
        iItem++;
     
        // Check if user cancelled operation 
        if( WAIT_OBJECT_0 == WaitForSingleObject( GetShutdownEvent(), 0 ) )
        {
          return hr;
        }
     
        // Pump messages to allow cancel button click
        // during control filling. Populating the control
        // with thousands of records takes time, so we need
        // to process messages to handle the cancel button
        // and close messages
        if(!ProcessMessages( ))
        {
          return hr;
        }
    
        // Restore the wait cursor
        // (if you don't do this, the wait cursor may go
        // away after processing messages)
        // wait.Restore();
      }
     
      // Unlock the List control window
      // ctlList.UnlockWindowUpdate();
      return hr;
    }
    

    Attached Files Attached Files

  4. #19
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Eliminate PumpMessage()

    Quote Originally Posted by zspirit View Post
    My implementation is that view receives data from read thread, adds it to the document and loads the list from document data...
    Wait, you are not re-loading entire list after each record is read, are you?
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  5. #20
    Join Date
    Aug 2006
    Posts
    515

    Re: Eliminate PumpMessage()

    Quote Originally Posted by VladimirF View Post
    Wait, you are not re-loading entire list after each record is read, are you?
    Definitely not, when the latest record/row becomes available from file I add it to the document and to the view. There is no refilling of the already loaded data.

  6. #21
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Eliminate PumpMessage()

    The question is: do you or don't you use virtual list?

    (And if you don't, you should do. The regular list control hardly can bear thousand objects without performance impacted.)
    Best regards,
    Igor

  7. #22
    Join Date
    Aug 2006
    Posts
    515

    Re: Eliminate PumpMessage()

    Thanks for the great demo, really appreciate it!
    Quote Originally Posted by Arjay View Post
    The virtual list control gets it's data from a std::list and the list is populated from a 2nd thread.
    This caught my eye, I normally don't use std::list with listivew because link list can't be accessed via index unlike std::vector and your code indeed use std::vector as I expected.

    Quote Originally Posted by Arjay View Post
    Code:
     
        ctlList.SetItemText(iItem, 0, LPSTR_TEXTCALLBACK);
        ctlList.SetItemText(iItem, 1, LPSTR_TEXTCALLBACK);
        ctlList.SetItemText(iItem, 2, LPSTR_TEXTCALLBACK);
    

    I actually don't use this in my code because it is handled by LVN_GETDISPINFO handler anyways. I commented this in your project and works fine too without it.

    Quote Originally Posted by Igor Vartanov View Post
    The question is: do you or don't you use virtual list?
    I think I might be confused with terminology here, more on this below. I took the opportunity to compared my project performance with Arjay's demo project. Here are the results.

    My computer takes about 2 seconds to load/populate 7000 rows in Arjay's project.

    My own project takes about 2.5 seconds to load 7000 rows from a file I have on disk.

    Now the demo project as you see has only 3 columns and my listview has 35 columns. The demo project is not reading any disk file but I am also parsing 27MB file during this time. This makes me pretty happy about my results.

    My loading mechanism is actually very similar to Arjay's project but I keep all the list data in CPtrArray instead of std::vector. Makes me think if I am already using virtual list without really know the terminology? All I know is I am definetely not using owner drawn listview style.

  8. #23
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Eliminate PumpMessage()

    So what is the problem at this moment?
    You do not get a visual feedback from the list that it is being populated?
    Do you scroll your list to the bottom when new item is added? If not – the display is not going to change that much, just the scroll bar.
    You do not need to Invalidate(), but, as was noted in one of the firs few replies, you need to call UpdateWindow() to enforce the update.
    If it impairs performance, you can do it for every tenth, twenties or fiftieth update.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  9. #24
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Eliminate PumpMessage()

    Quote Originally Posted by zspirit View Post
    Thanks for the great demo, really appreciate it!

    This caught my eye, I normally don't use std::list with listivew because link list can't be accessed via index unlike std::vector and your code indeed use std::vector as I expected.


    I actually don't use this in my code because it is handled by LVN_GETDISPINFO handler anyways. I commented this in your project and works fine too without it.


    I think I might be confused with terminology here, more on this below. I took the opportunity to compared my project performance with Arjay's demo project. Here are the results.

    My computer takes about 2 seconds to load/populate 7000 rows in Arjay's project.

    My own project takes about 2.5 seconds to load 7000 rows from a file I have on disk.

    Now the demo project as you see has only 3 columns and my listview has 35 columns. The demo project is not reading any disk file but I am also parsing 27MB file during this time. This makes me pretty happy about my results.

    My loading mechanism is actually very similar to Arjay's project but I keep all the list data in CPtrArray instead of std::vector. Makes me think if I am already using virtual list without really know the terminology? All I know is I am definetely not using owner drawn listview style.
    It doesn't really matter which container you use. std::list would work as well as std::vector (and maybe even yield better performance). I say the container doesn't matter because the container items aren't reference by index in my project. I use the Set[Get]ItemData methods to store/retrieve the pointer to the item directly - the index isn't use.

    One thing to try for performance is to use a std::list and instead of having the list store a pointer to the item, try it with storing the actual item. You'll need to write a copy constructor for the items but it might be more performant that way.

  10. #25
    Join Date
    Aug 2006
    Posts
    515

    Re: Eliminate PumpMessage()

    Quote Originally Posted by VladimirF View Post
    So what is the problem at this moment?
    You do not get a visual feedback from the list that it is being populated?
    My original issue of feedback was resolved my cutting down on the number of messages I post to main thread. I was just following up on Arjay's demo and clearing some thoughts about virtual lists
    Quote Originally Posted by Arjay View Post
    It doesn't really matter which container you use. std::list would work as well as std::vector (and maybe even yield better performance). I say the container doesn't matter because the container items aren't reference by index in my project. I use the Set[Get]ItemData methods to store/retrieve the pointer to the item directly - the index isn't use.

    One thing to try for performance is to use a std::list and instead of having the list store a pointer to the item, try it with storing the actual item. You'll need to write a copy constructor for the items but it might be more performant that way.
    I agree the container doesn't matter as long as it is not CArray object because it could reallocates itself if expanded and the pointers stored in list could become old and invalid. std::list is a link list and is good to go!

    Thank you all guys, really appreciated it!

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured