SetProp() without RemoveProp()..?
Re: SetProp() without RemoveProp()..?
You should leave props that you didn't create alone, as they may still be needed during the destruction of the window (like some PB internal props)
quidquid Latine dictum sit altum videtur
Re: SetProp() without RemoveProp()..?
Indeed, should have mentioned that.
Check the property name in the enum proc before removing it. Remove it only if it begins with "CreatedProperty" etc.

Check the property name in the enum proc before removing it. Remove it only if it begins with "CreatedProperty" etc.
I may look like a mule, but I'm not a complete ass.
Re: SetProp() without RemoveProp()..?
*lpszString >> 16
sometimes *lpszString can be an atom(16bit value), so that needs.(Windows internal or not)
If not check that, PeekS() can raise an invalid memory access error.
Re: SetProp() without RemoveProp()..?
Out of curiosity, what method are SetGadgetData() and SetGadgetItemData() using to associate data with a control or its parts? They don't seem to use SetProp_() so I'm curious about what their alternative approach is... Anyone know?
Re: SetProp() without RemoveProp()..?
The value set with SetGadgetData() will invariably be held as one field of an internal structure (I think you can find it listed within these forums). Whether a window property points to this structure or not... I am unsure; I've never really looked.
The values set with SetGadgetItemData() will, under Windows, be held (where appropriate) within a structure pointed to by a value held by the control itself. For example, a ListIcon gadget, at the Windows level, allows us to store an arbitrary 32-bit value (Win 32) alongside each individual row. Purebasic uses this to point to a structure which stores information on individual rows, information including the value set with SetGadgetItemData() etc.
The values set with SetGadgetItemData() will, under Windows, be held (where appropriate) within a structure pointed to by a value held by the control itself. For example, a ListIcon gadget, at the Windows level, allows us to store an arbitrary 32-bit value (Win 32) alongside each individual row. Purebasic uses this to point to a structure which stores information on individual rows, information including the value set with SetGadgetItemData() etc.
I may look like a mule, but I'm not a complete ass.
Re: SetProp() without RemoveProp()..?
And what is it that connects the gadget itself with that internal structure, which presumably resides somewhere random in memory? Meaning when you call GetGadgetData(1), what does PB examine about Gadget number 1 that lets it know at what address to find the relevant internal structure that concerns Gadget 1 specifically, as opposed to any of the other gadgets in existence? Assuming it isn't a linked list of internal structures that has to be cycled through until the right gadget reference is found, like in my example earlier in this thread, what is used? Is there an arbitrary 32 bit integer stored with each Windows control itself as well, which points to this structure? Just as is the case with individual rows of ListIcons etc?srod wrote:The value set with SetGadgetData() will invariably be held as one field of an internal structure (I think you can find it listed within these forums). Whether a window property points to this structure or not... I am unsure; I've never really looked.
Re: SetProp() without RemoveProp()..?
Interesting... so then how does SetProp manage to create and associate a property value with a window, just by creating an atom? From my very limited understanding of atom tables, all they do is associate a frequently-used string value with an assigned 16-bit integer. Where is it that the other information like the relevant hWnd and hData value itself are stored and associated with that 16-bit atom? Some other table somewhere..?freak wrote:Yes, there is a leak. It will leak the global atom with the property name.
The reason is that you can manage properties either by atom (see GlobalAddAtom), or by string (in which case SetProp converts it to an atom for you). Internally all properties are managed by atom. Windows cannot just call GlobalDeleteAtom on all properties when the window closes because it does not know wether you created the atom and passed it directly or wether SetProp created it because you passed a string. Since atoms live past the lifetime of your process if you do not delete them, these will leak.
Re: SetProp() without RemoveProp()..?
How would i know that? What i wrote above is more or less an educated guess based on the documentation and what i read in various blogs on the subject.mesozorn wrote:Interesting... so then how does SetProp manage to create and associate a property value with a window, just by creating an atom? From my very limited understanding of atom tables, all they do is associate a frequently-used string value with an assigned 16-bit integer. Where is it that the other information like the relevant hWnd and hData value itself are stored and associated with that 16-bit atom? Some other table somewhere..?freak wrote:Yes, there is a leak. It will leak the global atom with the property name.
The reason is that you can manage properties either by atom (see GlobalAddAtom), or by string (in which case SetProp converts it to an atom for you). Internally all properties are managed by atom. Windows cannot just call GlobalDeleteAtom on all properties when the window closes because it does not know wether you created the atom and passed it directly or wether SetProp created it because you passed a string. Since atoms live past the lifetime of your process if you do not delete them, these will leak.
All this does not matter. These are implementation details that do not concern you. The docs say you should cleanup then you should clean up. That is all you need to know.
Same here. This is PureBasic internal stuff. We could change it all for the next version if we feel like it.mesozorn wrote:And what is it that connects the gadget itself with that internal structure, which presumably resides somewhere random in memory? Meaning when you call GetGadgetData(1), what does PB examine about Gadget number 1 that lets it know at what address to find the relevant internal structure that concerns Gadget 1 specifically, as opposed to any of the other gadgets in existence? Assuming it isn't a linked list of internal structures that has to be cycled through until the right gadget reference is found, like in my example earlier in this thread, what is used? Is there an arbitrary 32 bit integer stored with each Windows control itself as well, which points to this structure? Just as is the case with individual rows of ListIcons etc?srod wrote:The value set with SetGadgetData() will invariably be held as one field of an internal structure (I think you can find it listed within these forums). Whether a window property points to this structure or not... I am unsure; I've never really looked.
quidquid Latine dictum sit altum videtur
Re: SetProp() without RemoveProp()..?
As someone who doesn't believe in blindly following instructions without understanding why, the "just do it" brand of advice will always be lost on me. Besides, at this point I have moved past the question of whether or not to clean up when using the API SetProp, and am more trying to figure out how to replicate the SetProp function internally using a local atom table rather than a global one, so that the same speed efficiency is achieved but the leak resulting from GlobalAddAtom does not occur.freak wrote:How would i know that? What i wrote above is more or less an educated guess based on the documentation and what i read in various blogs on the subject.
All this does not matter. These are implementation details that do not concern you. The docs say you should cleanup then you should clean up. That is all you need to know.
If Microsoft can do it by some method then I should be able to do something similar, only slightly different.
I was merely curious about efficient methods of associating data with gadgets/controls in order to use those techniques as a jumping off point.. I wasn't intending to implement something that is dependent on the current PB method staying the same and never changing.freak wrote:Same here. This is PureBasic internal stuff. We could change it all for the next version if we feel like it.
Last edited by mesozorn on Thu May 06, 2010 12:43 am, edited 1 time in total.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: SetProp() without RemoveProp()..?
There is an unlimited number of ways you can associate data with a window (or other object). Window properties are provided by the OS as a quick-and-simple way of achieving it without having to use Window memory or reinvent the wheel. There's just the one proviso, the reason for which freak has explained well- if you set a property, you are responsible for removing it. If you do it as MSDN recommends, in response to the WM_NCDESTROY message received in the Window procedure, there is no possibility of its getting forgotten. If, as I begin to suspect, you were planning to use SetProp_() without properly setting up a callback or subclass, then I'd advise you to stay away from it and pick one of the thousand other ways, you'll be on safer ground.
Code: Select all
Procedure SubClassProc(hwnd, msg, wparam, lparam)
oldproc = GetProp_(hwnd, "oldproc")
Select msg
Case #WM_NCDESTROY
RemoveProp_(hwnd, "oldproc")
EndSelect
ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure
BERESHEIT
Re: SetProp() without RemoveProp()..?
Well, yes and no in terms of what I am doing. At present I am using the all-encompassing EnumChildWindows/EnumProps procedural combination at program end, to automatically go through and remove all properties that were set during runtime. That way I can SetProp as I like willy-nilly on any control that strikes my fancy, without having to subclass everything or remember what to remove when I'm done.netmaestro wrote:There is an unlimited number of ways you can associate data with a window (or other object). Window properties are provided by the OS as a quick-and-simple way of achieving it without having to use Window memory or reinvent the wheel. There's just the one proviso, the reason for which freak has explained well- if you set a property, you are responsible for removing it. If you do it as MSDN recommends, in response to the WM_NCDESTROY message received in the Window procedure, there is no possibility of its getting forgotten. If, as I begin to suspect, you were planning to use SetProp_() without properly setting up a callback or subclass, then I'd advise you to stay away from it and pick one of the thousand other ways, you'll be on safer ground.
I don't disagree with or dispute what Freak or MSDN say about removing properties, I'm just attempting to do it in what I consider to be a less tedious way.
Thanks..
Re: SetProp() without RemoveProp()..?
You're cutting your nose off to spite your face if you intend rolling your own atom table etc, and for what? Being peeved at having to remove the properties yourself does not really strike me as a good reason in itself. In fact I quite like this because it makes for tighter code. All properties I set, I have to remove. I like that balance.
Window properties are tried and tested and they can serve a whole host of purposes. I use them in just about all of my GUI programs and being told that it is my responisbility to clean then up is fine by me. Can't say as I have ever wondered why Windows will not tidy them up itself when a control is destroyed? I have better things to do than to question the advice given me by MS on that score!
If you must roll your own then I would recommend using a hash map.
Window properties are tried and tested and they can serve a whole host of purposes. I use them in just about all of my GUI programs and being told that it is my responisbility to clean then up is fine by me. Can't say as I have ever wondered why Windows will not tidy them up itself when a control is destroyed? I have better things to do than to question the advice given me by MS on that score!

If you must roll your own then I would recommend using a hash map.
I may look like a mule, but I'm not a complete ass.
Re: SetProp() without RemoveProp()..?
I suppose my resistance to removing properties manually comes from the fact that I'm used to not having to do so for any other program components. Within PB I can create hundreds of variables, arrays, structures, linked lists, images, gadgets/controls and what have you.. And when I'm finished all I have to do is end the program, and they're all magically swept away into oblivion for me behind the scenes, without my having to lift a finger or worry my pretty little head about it. I like this convenience, and I'll admit I've become too accustomed to it to ever want to have to use a more tedious method like cleaning things up myself. Call me lazy, spoiled, or anything else unflattering that accurately applies, but when I'm done with a program the only thing I want to have to type is "END"srod wrote:You're cutting your nose off to spite your face if you intend rolling your own atom table etc, and for what? Being peeved at having to remove the properties yourself does not really strike me as a good reason in itself. In fact I quite like this because it makes for tighter code. All properties I set, I have to remove. I like that balance. Window properties are tried and tested and they can serve a whole host of purposes. I use them in just about all of my GUI programs and being told that it is my responisbility to clean then up is fine by me. Can't say as I have ever wondered why Windows will not tidy them up itself when a control is destroyed? I have better things to do than to question the advice given me by MS on that score!![]()

In any case, I was only curious about how easy it would be to use a local atom table and replicate the API SetProp/GetProp function internally, but since I don't know where Windows stores the other relevant pieces of the property I probably won't take this too far. The only way I'd know of off hand is a linked list, as in my code earlier in this thread, which works fine but isn't as fast as the API version. For the moment though I'm reasonably satisfied with the universal property removal routine I'm using, which satisfies both Windows' requirement for individual removal and my own requirement for one-step ease of coding.
Then again, once I've had time to look into exactly what a hash map is and how to implement one, I may just change my mind and give it a try!If you must roll your own then I would recommend using a hash map.

Re: SetProp() without RemoveProp()..?
You don't have to implement hash maps; Purebasic has maps built in now. 

I may look like a mule, but I'm not a complete ass.
Re: SetProp() without RemoveProp()..?
You are approaching this in a too complicated way imho. There is no need for atom tables or the like. I posted a quite short code that shows how to mimic the SetProp functionality with PB stuff (requires PB 4.50) here:
http://www.purebasic.fr/english/viewtop ... 12&t=42141
This code will leak linked list memory if you destroy/recreate gadgets with properties on them without calling RemoveAllProps(), but if you have a rather static GUI and just want cleanup when the program ends like you want to do, then the linkedlist memory is cleaned up as well of course and there is no leak beyond that.
If you want this for arbitrary window handles and not just PB gadgets, you could modify it to use SetWindowLongPtr_(hWnd, #GWL_USERDATA, xxx) instead of the SetGadgetData() command to store the pointer. The GWL_USERDATA field is not used in by PB so it is free for you to store such data (the only exception is the WebGadget, for backward compatibility).
If you don't use 4.50 this can be done as well, but you have to implement the map in structure functionality yourself so it is more work.
http://www.purebasic.fr/english/viewtop ... 12&t=42141
This code will leak linked list memory if you destroy/recreate gadgets with properties on them without calling RemoveAllProps(), but if you have a rather static GUI and just want cleanup when the program ends like you want to do, then the linkedlist memory is cleaned up as well of course and there is no leak beyond that.
If you want this for arbitrary window handles and not just PB gadgets, you could modify it to use SetWindowLongPtr_(hWnd, #GWL_USERDATA, xxx) instead of the SetGadgetData() command to store the pointer. The GWL_USERDATA field is not used in by PB so it is free for you to store such data (the only exception is the WebGadget, for backward compatibility).
If you don't use 4.50 this can be done as well, but you have to implement the map in structure functionality yourself so it is more work.
quidquid Latine dictum sit altum videtur