Results 1 to 8 of 8

Thread: Using ObjPtr

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2000
    Location
    Sedgefield
    Posts
    337

    Question

    To retrieve an object from its pointer you need to MemCopy, but to MemCopy you need to know the size of your object.


    How can I find the size of an object? Is there an API route?

    IS there any route?




    Dan

  2. #2
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088
    Use LenB(...)

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2000
    Location
    Sedgefield
    Posts
    337

    Unhappy

    Tried it, it doesn't work.

    Code:
     With tvw
            Set nde = .Nodes.Add(, , "ROOT", "Root Node")
            ptr1 = ObjPtr(nde)
     End With
    
     length = LenB(nde)
    here length = 18, the byte size of the string "Root Node" which is the default property of a node object. I'd need to know the size of the node object to be able to copy it into a new node object....




    Dan

  4. #4
    Frenzied Member
    Join Date
    Mar 2000
    Posts
    1,089
    hmm, what are you trying to do with it exactly, Objects are quite complicated, you can't just copy them around with move memory, Post what you need to do, there should be another way around.

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2000
    Location
    Sedgefield
    Posts
    337

    Cool

    Sam,

    I don't know if you caught any of my recent posts, but I'm somewhat annoyed at the inadaquacies of the TreeView control. There doesn't seem to be a simple way of transferrring whole nodes from tree to tree. Essentially I'm trying to hack my way around the problem

    What I'd like to be able to do is load nodes into a tree as a storage item and display them in another tree. That way I can interrogate my storage tree (invisible) to see if my node is already loaded, load it if it isn't and then transfer it wholesale without having to traverse the whole node and use TreeView.Nodes.Add on every single node.

    I'm trying to save time loading the tree. As it stands I'm either going to have to write separate routines for loading the tree and for modifying it (I don't want to have to load the whole thing each time it gets modified), or I'm going to have to include a lot of 'KeyExists' booleans in my tree load code.

    I've done a bit of work with the 'KeyExists' solution, so I can use the same routines to do the initial tree load and to do modifications (i.e. add / delete nodes).
    The downside here being that I essentially have to check if the node exists before I try and create it - if the tree is large this could take a long time.

    Perhaps I should write different routines to add different types of node - I don't know.

    Why am I doing all this? Limitations of a different kind! Do you like the VB IDE project explorer? I think its crap - you certainly can't explore you project with it. So I'm trying to write an IDE add-in replacement for it. I intend to make all methods, properties, variables, events and constants visible in the tree, on demand. I'm also trying to determine their scope and have different icons for public/private/firend/global etc. I also want to make the View Code and View Object buttons 'check style' so it always does one or the other (how many times have you opened the form designer when you wanted to be at the code!)

    There should be another way around as you say. I'm not bothered about the method - I just want some quick code to display a TreeView, check if a node exists (I currently loop through all the indexes and check keys), and add and delete nodes at will. (I guess its also easier to try and rebuild the whole tree when things change, but that could be too slow).

    I suppose I could also lock the treeview control while its 'building' - would that make things quicker?



    Dan

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2000
    Location
    Sedgefield
    Posts
    337

    Talking

    Sam,

    Another thought ... I appreciate the complexity of copying an object - but it is possible isn't it? Otherwise drag and drop wouldn't work....






    Dan

  7. #7
    Lively Member
    Join Date
    Apr 2000
    Location
    Hell
    Posts
    89
    Get ready for a long winded explanation from a C++ programmer :) (I program in VB at work, in C++ at home.)

    If you understand pointers, skip down a bit past the next section :)

    [POINTERS]

    Since this is for you VB people, I'll make it somewhat VB-specific.

    Pointers, in essence, "point" to stuff. Pointers exist in C, C++, Pascal, and even Perl, but not in BASIC or Java (BASIC sort of supports them, but not the way C does). A pointer is a special Long variable that holds a memory address instead of a regular number. VB itself uses pointers to remember where all the variables you declared are in memory, since you can create them on the fly if you don't declare 'Option Explicit' (this is called "autovivification"). So if I say something is a pointer, it holds a memory location. If I say X points to Y, then X holds the memory address of Y, and by various tricks you can get to Y. Oh, and Y doesnt have to be another variable. It can be a function, too - you just can't do that in VB (yet).

    VarPtr(x) will return a pointer to x - in the form of a Long.

    [/POINTERS]

    Lets say you had a class myClass with the following methods and properties:

    MyAge as Integer

    MyClassRules() As Boolean
    YourClassRules() As Boolean

    You'd probably have MyClassRules() always return True and YourClassRules() always return False, but I digress.

    Lets say you instantiate your class and call a method:

    Code:
    Dim mc As MyClass
    
    Set mc = New MyClass
    
    mc.MyAge = 20
    mc.MyClassRules
    If you were able to get a look at what is going on here, you'd see something amazing go on. So, let's look at these lines one by one.

    Dim mc As MyClass

    -> A pointer named mc is created - in other words, mc is a Long that holds a memory address. Also, a special unknown type is now formed:

    Type MyClassVT
    Get_MyAge as Long
    Let_Myage as Long
    MyClassRules As Long
    YourClassRules as Long
    End Type

    Remember how I said that pointers can point to functions too? (Look up in the pointer intro if you don't). Well, when you create your new MyClass, VB silently puts together an unnamed Type consisting of a pile of Longs. Those longs are pointers to the functions in MyClass. This special type is called a 'vtable'.
    You probably noticed that there are two Longs named Get_MyAge and Let_MyAge, instead of one Integer named MyAge. This is because the vtable can only have function pointers - so VB sneaks in two functions that get/set the value for you, and puts those functions in the vtable (though I'm not sure if they end up first or last in the table, use a typelib viewer or something).

    Set mc = New MyClass

    -> This does, among some other initialization:

    Dim unNamedVariable as MyClassVT
    mc = VarPtr(unNamedVariable)

    mc.MyAge = 20

    -> VB looks up the Let_MyAge entry in the vtable and calls the function by its pointer, like this:
    Let_MyAge(pointer-value-in-MC, 20)

    mc.MyClassRules

    -> Here, VB will look up MyClassRules in the vtable and call the function pretty much the same way:

    MyClassRules(pointer-value-in-MC)

    Whew! That was pretty long. Is everybody still with me? Good :)

    Now, hopefully, you'll see why you can't possibly directly clone a tree view - You only have direct access to the vtable, none of the internal data of the object. If you do a raw CopyMemory, you'll end up having two copies of the same object, but officially you'll only have one. When you destroy the one, the memory gets recycled for other purposes, and the original copy of the object will go haywire when it gets used.

    Therefore, you'll have to use a loop of some sort to duplicate your tree. That oh-so-simple "drag and drop" you see is actually VERY complex beneath the surface...

    Some of you are probably wondering what ObjPtr() does then. Well, if you look up, you'll see that the functions were secretly passed the "pointer-value-in-MC", aka the address of the vtable. Well, that "pointer-value-in-MC" is the same value returned by ObjPtr.
    - Steve

    Real programmers use COPY CON PROGRAM.EXE

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Feb 2000
    Location
    Sedgefield
    Posts
    337

    Thumbs up

    Thanks for the explanation Stevie,

    But it honestly beggars belief....not that I should be surprised at the rubbishness of anything from MS BUT....

    why let people Dim Nodes as Nodes or Dim Node as Node if you aren't then going to let people

    TreeView.Add(Nodes) and TreeView.Nodes(i).Add(Node)

    for christ sake? If I can think of it in 2 minutes surely someone at MS could have come up with the idea in however long it took to design TreeView.

    RANT RANT RANT RANT RANT



    Dan

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width