{"id":35313,"date":"2005-06-15T09:02:30","date_gmt":"2005-06-15T09:02:30","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/06\/15\/displaying-the-dictionary-part-3-using-an-owner-data-listview\/"},"modified":"2005-06-15T09:02:30","modified_gmt":"2005-06-15T09:02:30","slug":"displaying-the-dictionary-part-3-using-an-owner-data-listview","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050615-30\/?p=35313","title":{"rendered":"Displaying the dictionary, part 3:  Using an owner-data listview"},"content":{"rendered":"<p>\nOwner-data listviews let you take over data management from the listview.\nThis is useful in our case since we have over twenty thousand dictionary\nentries, and creating even that many <em>blank<\/em> listview items takes\nan unacceptably long amount of time.\n<\/p>\n<p>\nLet&#8217;s convert our listview to an owner-data listview.\nBelieve it or not, this is quite easy to do\nonce we have the\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/06\/14\/428892.aspx\">\ntext callback technique from last time<\/a>.\nMake the following changes:<\/p>\n<p><pre>\nLRESULT RootWindow::OnCreate()\n{\n  m_hwndLV = CreateWindow(WC_LISTVIEW, NULL,\n                  WS_VISIBLE | WS_CHILD | WS_TABSTOP |\n                  LVS_NOSORTHEADER | <font COLOR=\"blue\">LVS_OWNERDATA |<\/font>\n                  LVS_SINGLESEL | LVS_REPORT,\n                  0, 0, 0, 0,\n                  m_hwnd,\n                  (HMENU)IDC_LIST,\n                  g_hinst,\n                  NULL);\n ...\n <font COLOR=\"blue\"><strike>\/\/ for (int i = 0; i &lt; Length(); i++) {\n \/\/  const DictionaryEntry&amp; de = Item(i);\n \/\/  LVITEM item;\n \/\/  item.mask = LVIF_TEXT;\n \/\/  item.iItem = i;\n \/\/  item.iSubItem = COL_TRAD;\n \/\/  item.pszText = const_cast&lt;LPWSTR&gt;(de.m_pszTrad);\n \/\/  item.iItem = ListView_InsertItem(m_hwndLV, &amp;item);\n \/\/  if (item.iItem &gt;= 0) {\n \/\/   item.iSubItem = COL_PINYIN;\n \/\/   item.pszText = const_cast&lt;LPWSTR&gt;(de.m_pszPinyin);\n \/\/   ListView_SetItem(m_hwndLV, &amp;item);\n \/\/   item.iSubItem = COL_ENGLISH;\n \/\/   item.pszText = const_cast&lt;LPWSTR&gt;(de.m_pszEnglish);\n \/\/   ListView_SetItem(m_hwndLV, &amp;item);\n \/\/  }\n \/\/ }<\/strike><\/font>\n return 0;\n}\n<\/pre>\n<p>\nThat&#8217;s right, we made things better by deleting code.\nIsn&#8217;t that satisfying?\n<\/p>\n<p>\nOwner-data is like the text callback mechanism in the extreme:\nThe listview doesn&#8217;t record <em>any<\/em> information about the contents\nof your items.\nWhenever it needs something, it always asks.\nTo create twenty thousand items, we just call\n<code>ListView_SetItemCount<\/code> and tell it that there are twenty\nthousand items.\n(There is also a <code>ListView_SetItemCountEx<\/code> macro which\nlets you pass flags, none of which are relevant here.)\n<\/p>\n<p>\nIn many owner-data cases, the data comes from an external source,\nin which case the\n<code>LVN_ODCACHEHINT<\/code> notification can be helpful.\nThe listview sends this notification to say,\n&#8220;I&#8217;m going to be asking a lot of questions about items in this range.\nYou might want to go work on them.&#8221;\nNote that the listview might ask questions about items outside the\nrange, too.  The notification is just a hint that most of the questions\nare likely to be in that range.\nIn our case, we have all the data ahead of time,\nso we have no need for the hint.\n<\/p>\n<p>\nNotice that with this change to an owner-data listview,\nthe program starts up almost instantly.\nRemember also\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/05\/19\/420038.aspx\">\nthe way we arranged the data in our string pool<\/a>:\nAll the strings for an item are adjacent, and strings for consecutive\nitems follow one another.\nThis means that all the data for one screenful of information\nresides in contiguous memory.\nResult: Better locality, fewer page faults.\nWe&#8217;ll see more benefits of the string pool later.\n<\/p>\n<p>\nThat&#8217;s all for this month.\nNext month, we&#8217;ll come back to filling in the second column of data:\nthe simplified Chinese characters.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Owner-data listviews let you take over data management from the listview. This is useful in our case since we have over twenty thousand dictionary entries, and creating even that many blank listview items takes an unacceptably long amount of time. Let&#8217;s convert our listview to an owner-data listview. Believe it or not, this is quite [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-35313","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Owner-data listviews let you take over data management from the listview. This is useful in our case since we have over twenty thousand dictionary entries, and creating even that many blank listview items takes an unacceptably long amount of time. Let&#8217;s convert our listview to an owner-data listview. Believe it or not, this is quite [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=35313"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35313\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=35313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=35313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=35313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}