Announcement

Collapse
No announcement yet.

GetProp/SetProp verses cbWndExtra Bytes

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • GetProp/SetProp verses cbWndExtra Bytes

    This question is kind of related to Chris Holbrook's current thread about SetProp/GetProp, but I'm wondering what might the advantages be of that technique for associating data with a window, as opposed to storing data (or pointers to data) in the cbWndExtra bytes of the window structure? Typically, I do the later, as for example in my little tid bit I put in Source Code the other day...



    The only advantage that comes to my mind is that if one is writting a custom control that others may use, one might want to keep the cbWndExtra bytes free for users?
    Fred
    "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

  • #2
    Hi Fred,

    I say, use whatever works for you. Personally I tend to go with Properties, but that's partly because I do a lot of code in VB and very rarely have control over the extra bytes.

    But to answer your question, according to MSDN:
    Advantages of Using Window Properties
    Window properties are typically used to associate data with a subclassed window or a window in a multiple document interface (MDI) application. In either case, it is not convenient to use the extra bytes specified in the CreateWindow function or class structure for the following two reasons:
    • An application might not know how many extra bytes are available or how the space is being used. By using window properties, the application can associate data with a window without accessing the extra bytes.
    • An application must access the extra bytes by using offsets. However, window properties are accessed by their string identifiers, not by offsets.
    Regards,

    Pete.

    Comment


    • #3
      I find the string identifiers somehow comforting. Maybe I wrote too many lines of COBOL. However, given the awkwardness of handling properties and this atom stuff I may revert to cbwndextra.

      Of course, with DDT I could also use DIALOG GET/SET USER, but only 8 x 32 bit values

      Comment


      • #4
        There is no written rule, but in my mind, the class bytes are for custom/superclassed controls and SetProp and SetWindowLong/GWL_USERDATA used by application-specific code for all windows. I make a point not to use these latter methods in custom controls or library code.

        In reality, if your data is large you only need one 32-bit value, as it could be used for a pointer to a larger structure.
        Last edited by Kev Peel; 16 Mar 2008, 07:30 PM.
        kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

        Comment


        • #5
          If I was designing DDT features I would be tempted to include a wrapper for EnumProps and the EnumPropProc to filter out inaccessible properties, maybe along the lines of DIR$.

          Comment


          • #6
            My impression is that the extra window bytes is better and faster than using properties. The extra window bytes are not for users (except for the GWL_USER area). They are for the window class itself. The window class determines how the bytes are used and not users.

            I haven't done any benchmarking, but I would guess that the window bytes are faster in access then properties. Properties have to be searched for in some kind of list in Windows. Using string names for properties is going to be a bit slower than using atoms. I prefer to use atoms.

            Properties are more user oriented in that you can add properties for any window. The extra window bytes are class defined so you can't just use them for your own user, unless you create the window class yourself (which is what they are intended for).
            Chris Boss
            Computer Workshop
            Developer of "EZGUI"
            http://cwsof.com
            http://twitter.com/EZGUIProGuy

            Comment


            • #7
              Thanks for the input Peter, Chris & Kev. Been thinking about that for some time. I tend to settle on one technique and kind of wear it out. That's what I do with extra window bytes. What I'm always doing is making myself little remmed out tables I copy from place to place in my apps to keep track of what I put there, e.g.,

              Code:
              'Offset   What's There
              '========================
              '0  -  3    ptrHandles
              '4  -  7    ptrSizes
              '8  -  11   ptrScrollInfo
              'etc
              I guess if I used window properties I'd be copying around string atom names instead.

              I recall studying code generated by Paul Squires FileFly and noted he made major use of properties for window data. I suppose I was concerned there might be some untoward consequences of which I was unaware in my continued use of cbWndExtra bytes.
              Fred
              "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

              Comment


              • #8
                Originally posted by Fred Harris View Post
                I recall studying code generated by Paul Squires FileFly and noted he made major use of properties for window data.
                Having run Peter Jinks' code to solve my original problem it appears that properties may be set by others (Windows? DDT?) as well as the developer. As one wouldn't know who set the properties when removing them in bulk, it would be best to remove them by name. It would be useful to know how Paul Squires does this, also to know whether DDT and or Windows is responsible for the other properties.

                Comment


                • #9
                  This is the way I do it using props for control info in rc Dialogs.

                  In WM_INITDIALOG I call EnumChildWindows

                  In the call back Function I allocate memory for a UDT that has all
                  my control info on my own Heap.


                  IF SetProp(hWnd,"CtlInfo",HeapAlloc(ghHeap,%HEAP_ZERO_MEMORY,LEN(ControlInfoType))) = 0 THEN
                  FUNCTION = 0
                  EXIT FUNCTION
                  END IF

                  Where ControlInfoType is the UDT of info I want to store

                  Then

                  lpCtlInfo = GetProp(hWnd,"CtlInfo")

                  where lpCtlInfo is a ControlInfoType PTR


                  Add my Info:

                  @lpCtlInfo.szClassName = SysAllocStringByteLen(szClassName,LEN(szClassName))

                  ....

                  In the Dialogs WM_DESTROY I again enumchildWindows to another call back to free the memory.

                  Code:
                  DIM lpCtlInfo         AS ControlInfoType PTR
                  
                  lpCtlInfo = GetProp(hWnd,"CtlInfo")
                  
                  RemoveProp hWnd,"CtlInfo"
                  
                      IF @lpCtlInfo.hFont THEN
                        IF ISFALSE @lpCtlInfo.StkFont THEN
                          DeleteObject @lpCtlInfo.hFont
                        END IF
                      END IF
                      IF @lpCtlInfo.hBkBrush THEN
                        DeleteObject @lpCtlInfo.hBkBrush
                      END IF
                      IF @lpCtlInfo.szTag THEN
                        SysFreeString @lpCtlInfo.szTag
                      END IF
                      IF @lpCtlInfo.szClassName THEN
                        SysFreeString  @lpCtlInfo.szClassName
                      END IF
                  
                     HeapFree ghHeap,0&,lpCtlInfo
                  James
                  Last edited by jcfuller; 17 Mar 2008, 08:26 AM.

                  Comment


                  • #10
                    Originally posted by jcfuller View Post
                    In the call back Function I allocate memory for a UDT that has all my control info on my own Heap.
                    Well, that was my instinct, too (see my initial post in other thread), to create a list of properties which I could use to remove all properties with a single call, but I thought there might be a neater way with Windows. At least I have all the tools and knowledge available to do it that way, whereas I do not know how to tell if a given property is one created by my app itself or created by WIndows, or maybe DDT, without using a lookup of windows I have created.

                    Comment


                    • #11
                      Originally posted by Chris Holbrook View Post
                      Well, that was my instinct, too (see my initial post in other thread), to create a list of properties which I could use to remove all properties with a single call, but I thought there might be a neater way with Windows. At least I have all the tools and knowledge available to do it that way, whereas I do not know how to tell if a given property is one created by my app itself or created by WIndows, or maybe DDT, without using a lookup of windows I have created.
                      No list just one "CtrlInfo" per (control) Window. That prop holds the PTR to my ControlInfo UDT. I doubt anyone is using that name for MY controls.

                      James

                      Comment


                      • #12
                        Originally posted by jcfuller View Post
                        No list just one "CtrlInfo" per (control) Window
                        You're right. It is more compact, and no more trouble than using getprop/setprop, and avoids EnumProps. That's quite a good outcome. Thanks!

                        Comment


                        • #13
                          ... developing James's theme but avoiding defining a UDT leads me to a set of functions with an underlying dynamic array or list which can be searched on the identifier string attribute. I'm assuming that all values are DWORDS but the approach could be modified for mixed types.
                          Code:
                              ....element of the array or list (or split over three arrays would be easiest)
                              Id                AS STRING
                              Value             AS DWORD
                              Destructor        AS DWORD ' index to destructor method
                          Code:
                          '--------------------------------------------------------------------------
                          ' Add a property to the list
                          ' retval is zero if an error has occurred, else = dwval
                          FUNCTION MyPropSet ( hD AS DWORD, id AS STRING, dwval AS DWORD, DestroyAction AS DWORD) AS LONG
                          END FUNCTION
                          '--------------------------------------------------------------------------
                          ' get the value of a property from the list
                          ' retval is property value
                          FUNCTION MyPropGet ( hD AS DWORD, id AS STRING) AS DWORD
                          END FUNCTION
                          '--------------------------------------------------------------------------
                          ' returns 1 if the property has been defined, 0 if not
                          FUNCTION MyPropIs ( hD AS DWORD, id AS STRING) AS LONG
                          END FUNCTION
                          '--------------------------------------------------------------------------
                          ' 2nd param is propertyname or "*" for all properties in current dialog
                          FUNCTION MyPropDestroy ( hD AS DWORD, id AS STRING) AS LONG
                          END FUNCTION
                          '--------------------------------------------------------------------------
                          ' a debugging fn to return all property ids and values for a dialog
                          FUNCTION MyPropS ( hd AS DWORD) AS STRING
                          END FUNCTION

                          Comment


                          • #14
                            fleshed out a bit and in the Source Code Forum

                            Comment

                            Working...
                            X