Go Back   Access World Forums > Microsoft Access Reference > Microsoft Access Tutorials

 
Closed Thread
 
Thread Tools Rate Thread Display Modes
Old 04-27-2012, 10:52 PM   #1
ChrisO
Newly Registered User
 
ChrisO's Avatar
 
Join Date: Apr 2003
Location: Brisbane, Australia
Posts: 3,202
Thanks: 7
Thanked 272 Times in 194 Posts
ChrisO is just really nice ChrisO is just really nice ChrisO is just really nice ChrisO is just really nice
Pointers in VBA.

Pointers in VBA.

Don’t get nervous, you use them all the time.

What is a Pointer? The answer needs some explanation.

Objects, such as Text Boxes, List Boxes, Recordsets, Forms etcetera, are much too large to go passing around an application efficiently. An example would be a Recordset which could be 500 MByte in size. We don’t want to move or copy such a large Object from A to B in memory just to ‘get at it’ at B. So we leave the Object where it is and just pass the memory address of the Object instead.

Over the years there has been an analogy to this. If we send a message to someone, through the mail, we can include a return street address to our house. We put the return street address of our house in the message not the house itself; makes it easier for the postman to carry it about. Similarly, when we pass an Object, we pass the memory address of that Object and not the Object itself.

But the memory address of an Object is still not a Pointer, it is the value held in that Pointer. In other words, the memory address of an Object is that which a Pointer contains. It is important to understand the difference between a Pointer and the content of a Pointer.

To explain this a little further we need some VBA code:-

Dim X As Object

What does that line of code mean?
From Access help…

Dim: Declares variables and allocates storage space.
X: The name of the storage space allocated.
Object: A data type that represents any Object reference. Object variables are stored as 32-bit (4-byte) addresses that refer to objects.

Let’s have a closer look at these…
X is the name of the storage space allocated but it does not specify the size of the storage space allocated.
Object specifies the size of the storage space allocated, which is 4 bytes for a memory address in a 32 bit system. That definition applies to all Objects in a 32 bit system. Objects vary in size but their address size remains the same…4 bytes.

Note then that the real line of code:-
Dim X As Object
Could just as well have been written as:-
Dim X As ObjectPointer
Or more simply as in:-
Dim X As Pointer

But Microsoft seems to have decided on the word Object and we need to go with that.
(However, the word Object is wrong and ObjectPointer, or just plain Pointer, would have been a better choice. )

But we must be clear here; X it is not an Object, Objects vary in size.
X is the name of a Pointer and that Pointer was allocated a fixed memory size, 4-bytes.

Note also that there is something else going on in the real line of code:-
Dim X As Object
The content of X is actually initialized to 0. The content of X is actually a Long 4-byte numerical value. All numerical values are initialized and reset to 0. The content of X is the address of an Object. The initial value of X is the address of a special Object called Nothing. We actually de-allocate a Pointer by setting its value to the Object Nothing and the memory address of that special Object Nothing is 0.

We can come back to that if need be; let’s just push on for the moment…

Dim X As Object
X is the name of a 4-byte contiguous storage allocation in memory.
Those 4-bytes contain the numerical value of an Object’s address.
Juxtaposition
Dim Y As Long
Y is the name of a 4-byte contiguous storage allocation in memory.
Those 4-bytes can contain the numerical value of any Object’s address.

How do we transfer the numerical value of a Pointer X (address of the Object) to the value of a Long Y?
How do we transfer the value of a Long Y back to the numerical value of a Pointer X (address of the Object) ?

Simple and fast…
Code:
Option Explicit
Option Compare Text

' API and constants from http://allapi.mentalis.org/apilist/apilist.php
Private Const POINTERSIZE As Long = 4
Private Const ZEROPOINTER As Long = 0

Private Declare Sub RtlMoveMemory Lib "kernel32" (ByRef Destination As Any, _
                                                  ByRef Source As Any, _
                                                  ByVal Length As Long)


Public Function GetPointerToObject(ByRef objThisObject As Object) As Long
    ' Purpose  : Return the value of a pointer.
    ' Argument : A pointer to an Object.
    
    Dim lngThisPointer As Long

    RtlMoveMemory lngThisPointer, objThisObject, POINTERSIZE
    GetPointerToObject = lngThisPointer

End Function


Public Function GetObjectFromPointer(ByVal lngThisPointer As Long) As Object
    ' Purpose  : Return a pointer to an Object.
    ' Argument : The value of a Pointer.
    
    Dim objThisObject As Object

    RtlMoveMemory objThisObject, lngThisPointer, POINTERSIZE
    Set GetObjectFromPointer = objThisObject
    RtlMoveMemory objThisObject, ZEROPOINTER, POINTERSIZE

End Function
Note here that the API call is bidirectional, low level, fast and documented.
It copies the content of one named variable to the content of another named variable.


Next, how can we use it?

The passing of Objects, which are really Object Pointers, can not be done through OpenArgs. However, OpenArgs uses the Variant data type and the Variant datatype supports the Long data type.

The method is, therefore…
Value of Object Pointer > value of Long > through OpenArgs > value of long > value of Object Pointer.

Note here as well…
This is a straight passing of an Object (Opject pointer) through OpenArgs by reference (ByRef).
Any modification done, via the received Pointer, will take effect immediately on the Object. Therefore there is no need to pass anything back to the caller.

The Pointer may point to a Collection which, in turn, contains other Pointers.

Some sample usage demonstrations are available in the link in my signature.

I have attached perhaps the simplest demo of this technique.
It passes the value of pointer to a Text box to another Form which allows direct write back to the caller.

It is possible to pass Objects (Object Pointers) through OpenArgs, imagination is the limit.

Have fun experimenting,
Chris.
Attached Files
File Type: zip TextBox_PassObject_A2003.zip (19.2 KB, 1003 views)

__________________
Access 2003, Win7, GMT +10,
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.

Last edited by ChrisO; 04-28-2012 at 02:27 PM.
ChrisO is offline  
The Following 7 Users Say Thank You to ChrisO For This Useful Post:
Fuse3k (02-01-2016), JudgieJ (11-13-2017), KenHigg (06-20-2014), NauticalGent (01-08-2016), npatel (09-30-2016), PaulaApcon (10-10-2014), srinivasan2081 (12-17-2014)
Closed Thread

Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Question need some pointers to get started.. sunset1215 General 6 05-08-2011 09:57 PM
need pointers on creating If statment Jon123 General 6 06-13-2009 11:49 AM
additional mouse pointers carpeneda Modules & VBA 2 03-05-2009 01:04 PM
[SOLVED] Access Pointers brian873 General 3 10-21-2004 01:24 AM
[SOLVED] A few pointers for a beginner, please... apophis General 4 04-29-2003 08:49 AM




All times are GMT -8. The time now is 02:58 PM.


Microsoft Access Help
General
Tables
Queries
Forms
Reports
Macros
Modules & VBA
Theory & Practice
Access FAQs
Code Repository
Sample Databases
Video Tutorials

Sponsored Links

How to advertise

Media Kit


Powered by vBulletin®
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
(c) copyright 2017 Access World