Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Actually... I think you're making a mistake. The value at <code>GWLP_USERDATA</code> and the space allocated according to <code>cbWndExtra</code> are two separate things...</p> <p>The <code>GWLP_USERDATA</code> value is part of the space Windows allocates for <em>every</em> window. It's so common for window classes to need a pointer-sized bit of storage that Windows just includes it in the base cost of a window, along with all of the other pre-defined "window words". Look at the documentation for the <code>nIndex</code> parameter to <a href="http://msdn.microsoft.com/en-us/library/ms633585.aspx" rel="nofollow noreferrer"><code>GetWindowLongPtr()</code></a>:</p> <blockquote> <p>Specifies the zero-based offset to the value to be retrieved. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer.</p> </blockquote> <p>So, <code>GetWindowLongPtr(hWnd, 0)</code> retrieves the first <code>sizeof(LONG_PTR)</code> bytes allocated in response to <code>cbWndExtra</code>, <code>GetWindowLongPtr(hWnd, sizeof(LONG_PTR))</code> gives you the next pointer-sized data, and so on. As its name implies, <code>nIndex</code> acts like an index into an array of bytes (though it always returns a pointer-sized value). Now take a look at the index values assigned to the pre-defined window data constants: they're all negative, including <code>GWLP_USERDATA</code>! In effect, <code>GetWindowLongPtr()</code> starts indexing into the middle of the window data, with the data common to all windows residing "before" the 0 index, and any window class specific data residing after it.</p> <p>Dialog windows are built on top of the baseline support provided for normal windows. Since they require more data than normal windows, you're required to specify at least <code>DLGWINDOWEXTRA</code> bytes in <code>cbWndExtra</code>. Like any other such data, it's accessed via a positive value passed to <code>GetWindowLongPtr()</code>.</p> <p>Therefore, when you ask for </p> <pre><code>GetWindowLongPtr(hWnd, GWLP_USERDATA + DLGWINDOWEXTRA + 0); </code></pre> <p>...you're actually getting the data at index <code>-21 + 30 + 0 = 9</code>: a value somewhere in the dialog manager's own data. Not what you want!</p> <p>By now you should realize, that when accessing data allocated via <code>cbWndExtra = DLGWINDOWEXTRA + extra</code> you only need to offset your request by <code>DLGWINDOWEXTRA</code>. So:</p> <pre><code>GetWindowLongPtr(hWnd, DLGWINDOWEXTRA + 0); </code></pre> <p>...will get you the first element of extra data. <code>GWLP_USERDATA</code> should be used <em>only</em> when you wish to get or set the one pointer of always-allocated user data associated with every window.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload