{"id":27703,"date":"2007-03-08T10:00:00","date_gmt":"2007-03-08T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/03\/08\/the-getdispinfo-notifications-tell-you-what-information-they-want\/"},"modified":"2007-03-08T10:00:00","modified_gmt":"2007-03-08T10:00:00","slug":"the-getdispinfo-notifications-tell-you-what-information-they-want","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070308-00\/?p=27703","title":{"rendered":"The GETDISPINFO notifications tell you what information they want"},"content":{"rendered":"<p>The <code>XXN_GETDISPINFO<\/code> notifications used by the common controls are used when the control asks its parent to generate information that had been marked as delay-rendered, either explicitly via values such as <code>LPSTR_TEXTCALLBACK<\/code> or implicitly by being an owner-data control, for example.\n In fact the control is really just the middle man between the code that requested information about an item (via a message like <code>LVM_GETITEM<\/code>) and the code that generates it (your <code>LVN_GETDISPINFO<\/code> handler). In other words, the code flow goes like this:\n Somebody interested in retrieving data from a list view creates a <code>LVITEM<\/code> structure and initializes the <code>LVITEM.mask<\/code> and other fields as necessary, based on the mask. (For example, if the <code>LVIF_TEXT<\/code> flag is set, then <code>LVITEM.pszText<\/code> and <code>LVITEM.cchTextMax<\/code> must also be set to the buffer and its size.) it then sends a <code>LVM_GETITEM<\/code> message to the list view control.\n The list view control looks at the <code>LVITEM.mask<\/code> to see what information needs to be filled in. Some of the information the list view can provide on its own. Other parts of the information require help from the list view control&#8217;s parent. For example, if the <code>LVITEM.mask<\/code> has the <code>LVIF_TEXT<\/code> flag set, and the item has its text set to <code>LPSTR_TEXTCALLBACK<\/code>, then the list view needs to consult its parent to get the text.\n The list view control sends the <code>LVN_GETDISPINFO<\/code> message to its parent, saying, &#8220;Hey, somebody is looking for information; please provide the information that is requested in the <code>LVITEM.mask<\/code> member.&#8221;\n After the parent handles the message, the results are returned back to the original caller.\n There&#8217;s a little bonus step that occurs just before the results are returned: If the parent set the <code>LVIF_DI_SETITEM<\/code> flag in the <code>LVITEM.mask<\/code>, then the returned values are also saved into the list view control as if you had sent a <code>LVM_SETITEM<\/code> message. For example, if you set the <code>LVIF_DI_SETITEM<\/code> flag in response to a request for <code>LVIF_TEXT<\/code>, then the text you return will be saved into the list view item, overwriting the previous value of <code>LPSTR_TEXTCALLBACK<\/code>. This is handy if you only want to compute the result once and let the list view cache the result from the on.\n Notice that throughout this process, the <code>LVITEM.mask<\/code> controls what information is being requested by the original caller of the list view as well as what is being requested by the list view of its parent. If you <a href=\"http:\/\/groups.google.com\/groups?selm=37C3DC97-DFD4-4C62-A6EA-2244F8A91A32@microsoft.com\"> make the mistake of changing the value of <code>LVITEM.mask<\/code><\/a> (aside from setting the <code>LVIF_DI_SETITEM<\/code> flag, as noted in the &#8220;bonus step&#8221;), then you interfere with this game of &#8220;pass the buck&#8221;.\n After the parent handles the message, the results are returned back to the original caller. But if you have modified the <code>LVITEM.mask<\/code>, then the results being returned back to the caller aren&#8217;t the same as the ones the caller requested! For example, if the list view sees the <code>LVIF_TEXT<\/code> flag set, then it will copy the string provided by the parent back into the caller&#8217;s buffer. But wait a second, if the parent is the one who set the <code>LVIF_TEXT<\/code> flag, that means that the original caller didn&#8217;t ask for the text. There is no buffer to copy the results back into. The list view copies the string to an unintialized pointer, and all sorts of memory corruption occurs as a result.<\/p>\n<p> Moral of the story: When responding to a <code>XXN_GETDISPINFO<\/code> notification, respect the <code>mask<\/code>. It&#8217;s the bookkeeping that specifies what information you&#8217;re being asked to provide (and therefore what information will be copied back to the original caller). If you change this bookkeeping, the original caller is in for a big surprise. It&#8217;s like being the cook in a restaurant modifying the customer&#8217;s order. &#8220;Oh, you didn&#8217;t want the salad; let me give you the veal instead.&#8221; <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The XXN_GETDISPINFO notifications used by the common controls are used when the control asks its parent to generate information that had been marked as delay-rendered, either explicitly via values such as LPSTR_TEXTCALLBACK or implicitly by being an owner-data control, for example. In fact the control is really just the middle man between the code that [&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-27703","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The XXN_GETDISPINFO notifications used by the common controls are used when the control asks its parent to generate information that had been marked as delay-rendered, either explicitly via values such as LPSTR_TEXTCALLBACK or implicitly by being an owner-data control, for example. In fact the control is really just the middle man between the code that [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/27703","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=27703"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/27703\/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=27703"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=27703"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=27703"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}