Who is owner of GWLP_USERDATA cell?

眉间皱痕 提交于 2021-02-08 13:43:07

问题


good known that GWLP_USERDATA can be used to associate some pointer size data with the specified window. but who has the right do it ? obviously if two piece of code independently do this - one piece is overwrite data of another - so there must only be one owner. but it must be clear determined a general rule - who is owner of GWLP_USERDATA cell ? whom it belong ?

can be two internally consistent agreements:

  1. code that created the window is owner. belong to the creator of the window
  2. code which implement window class. belong to the window class implementer

what of this two solutions must be used ?

1. from MSDN:

GWLP_USERDATA:

Sets the user data associated with the window. This data is intended for use by the application that created the window. Its value is initially zero.

how need understand This data is intended for use by the application that created the window ?

so code which call CreateWindowEx, CreateDialogParam, DialogBoxParam, etc - and only this code can use GWLP_USERDATA. from this also follows that window class implementer can not use GWLP_USERDATA. so huge number of examples where GWLP_USERDATA used for bind instance of class to the specified window is incorrect. Managing Application State - official MSDN example, where GWLP_USERDATA used for bind data structure to window is incorrect ?!

SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);

is error under this rule.

what can be said in favor of this version ? i check different windows versions (from xp to win10) - how i can see all windows built-in window classes ( WC_* and others) use

SetWindowLongPtr(hwnd, 0, (LONG_PTR)pThis);

for bind instance of class to the specified window. always index 0 used instead GWLP_USERDATA

many can say - so what ? even if now this is true, what about future windows versions ? but if think, what sense migrate from index 0 (really private implementer index in all senses) to GWLP_USERDATA ? change existing SetWindowLongPtr(hwnd, 0, (LONG_PTR)pThis); to SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis); what prize ? or additional begin use GWLP_USERDATA with index 0 too ? this already absolute senseless - one pointer is enough for bind window to data structure, all additional pointers must be (and in case windows code will be) in this structure already. so i personally can assume that this is not changed


also can note an error in the documentation for SetWindowLongPtr and GetWindowLongPtr here:

The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer

really minus the size of an pointer which 8 bytes on x64, when size of an integer always 4.


2. look at a reputable blog - The bonus window bytes at GWLP_USERDATA:

Note that this value, ..., belongs to the window class and not to the code that creates the window... only the window class implementer may read or write the values.

but exist also next two author remarks:

Interesting. I’m checking into that. But even if it does belong to the creator of the window, enough window class implementations use it that you still should stay away for safety’s sake.

and

I asked around and guidance is "unclear", though leaning slightly towards "it belongs to the person who called CreateWindow". For safety’s sake, then, you should just avoid it unless you can establish clear ownership

again look for Managing Application State MSDN example - window class implementer used GWLP_USERDATA !

look for ATL atlhost.h - AtlAxWindowProc used GWLP_USERDATA

//case WM_CREATE:
::SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD_PTR)pAxWindow);

again class implementer used GWLP_USERDATA

but under this agreement we can not use GWLP_USERDATA with CreateDialogParam, DialogBoxParam because here we not implementer (The DialogProc function is an application-defined callback function called from DefDlgProc - real class implementation code for dialogs - so only DefDlgProc can potential use GWLP_USERDATA cell)


so application that created the window or window class implementer is owner ?


if think - the variant application that created the window is more logical. window class implementer have two choice: can set cbWndExtra to sizeof(PVOID) and use index 0 or use GWLP_USERDATA index. when application that created the window - have no choice - only GWLP_USERDATA index or use another (less effective and more complex) way like SetProp, SetWindowSubclass, etc. so be logical if window class implementer use index 0 for bind self data to window and leave free GWLP_USERDATA for code that created the window. again how about CreateDialogParam, DialogBoxParam - most native way here for use data structure binds to dialog use GWLP_USERDATA index, but here we window creator, not dialog class implementer ! so can use GWLP_USERDATA or not ?

in all case need take to account that enough existing custom window class implementations use GWLP_USERDATA

my assumptions:

  • if we call CreateWindowEx for non windows core built-in class - we must not use GWLP_USERDATA here
  • if we call CreateDialogParam, DialogBoxParam - i assume that we can here use GWLP_USERDATA
  • if we call CreateWindowEx for windows built-in class (WC_* named) we also can use GWLP_USERDATA
  • if we window class implementer - the best choice - set cbWndExtra to sizeof(PVOID) and use index 0

来源:https://stackoverflow.com/questions/41521809/who-is-owner-of-gwlp-userdata-cell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!