In terms of saving or attaching object properties to objects in C based OOP there are the two possibilities of the WNDCLASSEX::cbWndExtra bytes and the SetProp()/GetProp()/RemoveProp() functions. I used the GetProp()/SetProp() functions in the code above just because all my other examples used the WNDCLASSEX::cbWndExtra bytes approach. One thing I might add is that in my previous examples of using the .cbWndExtra bytes I don't believe I ever stored more than one value using SetWindowLongPtr(). This technique is not limited to storing just one value there however. For example, if building in x64 where the native variable size is 8 bytes, one could specify something like so if one wanted to store 10 pointers or values ....
wcx.cbWndExtra = 80; // 10 * sizeof(void*)
In this case, bytes 0 through 7 would hold the 1st or 'zeroeth' value; bytes 8 through 15 the 2nd, etc., etc.
I tried to post about this before here but either I messed up the posting somehow that it didn't take, or the site administrator here removed my post. I'm thinking it might have been the latter because the 1st code I found illustrating doing this was PowerBASIC code - not C or C++ code, and maybe the powers that be here didn't like seeing PowerBASIC code, even though the coding is exactly like C or C++ SDK/API code. But anyway, here is how I keep track of what's stored where in WNDCLASSEX::cbWndExtra bytes where I have multiple values stored there. This is from around the WM_CREATE handler in some Dll code for a custom control of mine....
// EditGrid Data
// Offset Object
// 0 - 7 pHdls
// 8 - 15 pSizes
// 16 - 23 ptr data buffer
// 24 - 31 pMyScrollInfo
// 32 - 39 pNavData
// EditCell Data
// 0 - 7 pBuffer for text typed
// 8 - 15 cxChar - width of char
// 16 - 23 cyChar - height of char
// 24 - 31 cxClient - width of client area
// 32 - 39 cyClient - height of client area
// 40 - 47 Bytes Allocated in pBuffer-1; # chars that can be typed.
// 48 - 55 caret position in cxClient (zero based)
// 56 - 63 hGrid (EditGrid)
I make these little tables like above to help me keep track of what's stored where. In terms of how I access the values stored there I use code like so....
HBRUSH hBrush = NULL;
hBrush = (HBRUSH)GetWindowLongPtr(Wea.hWnd, 6*sizeof(void*));
...if I have an HBRUSH stored at bytes 48 through 55 in the WNDCLASSEX::cbWndExtra bytes. So the 1st (One Based) value would be in bytes 0 through 7 or 0*sizeof(void*), the 2nd at 1*sizeof(void*), the 3rd at 2*sizeof(void*), etc.
Seems contorted and twisted and overly complicated, nicht? A coding buddy of mine calls such data stored in this way as 'torture variables'. Very apt. I guess it shows the lengths some of us are willing to go to avoid global variables in a program.
Of course, if one uses the GetProp()/SetProp() functions, then one can associate alphanumeric labels to the data as in my example just above in storing a font.
You are right anachronon, you aren't very far from me. I'm right above the New Mexico border in Colorado, about 3 - 4 miles West of I-25's Exit 6. The Amarillo area is only a little more than 200 miles from here. Geez, I go almost that far for my doctoring. I'm out in the middle of nowhere in Colorado's largest and least populated county. My wife and I drive up to Pueblo or Colorado Springs for appointments and that's several hours of driving each way.
That snow was rough up here at 7500 feet. I figurred I'd have 'till end of September to get my masonry work done. Didn't expect winter storm in summer. But it happens. I was like a madman getting grouting work done so ice wouldn't break my stone work up.