MS-Access / Getting Started

Supporting Older Versions of Access

If you develop Access applications in Access 2010 for users with previous versions of Access, you still need to address one more issue. Versions of Visual Basic before Access 2010 do not understand the new data types and attributes and therefore generate errors. If the Visual Basic code you write for Access 2010 needs to run in previous versions of Access, then you must wrap the code in the new #If VBA7 construct and include the older format as well.

This new conditional compilation variable VBA7 is defined only for Visual Basic included with Access 2010. Using the example Declare statement we've been working on previously, you can write your code like the following:

#If VBA7 Then
    Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" _
      (ByVal Key As LongPtr, ByVal SubKey As String, _
      NewKey As LongPtr) As Long
#Else
    Declare Function RegOpenKeyA Lib "advapi32.dll" _
      (ByVal Key As Long, ByVal SubKey As String, _
      NewKey As Long) As Long
#End If

Note that there is also a Win64 conditional compilation variable, which can be useful if the Declare statement has other differences besides pointer size between 32-bit and 64-bit platforms. You write your code, in this case, like the following:

#If WIN64 Then
    Declare PtrSafe Function WindowFromPoint Lib "user32" Alias _
      "WindowFromPoint"(ByVal Point As LongLong) As LongPtr
#Else
    Declare PtrSafe Function WindowFromPoint Lib "user32" Alias _
      "WindowFromPoint"(ByVal xPoint As Long, ByVal yPoint As Long) As LongPtr
#End If

Many Access developers create Visual Basic code in their applications using Declare statements based on a text file called Windows API Declarations and Constants for Visual Basic-Win32API.txt-supplied by Microsoft. The Win32API.txt file includes around 1,500 examples of the most common Windows API calls. For Office 2010, Microsoft updated this reference file to include information about the new LongPtr data type and PtrSafe attribute, as outlined earlier. You can download this new reference file, called Win32API_PtrSafe.txt, from Microsoft's website at the following location:

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=035b 72a5-eef9-4baf-8dbc-63fbd2dd982b

Understanding Pointer Valued Functions and LongPtr Type Coercion

VarPtr, StrPtr, and ObjPtr are functions that return pointers to Visual Basic variables. You can use these functions to pass pointers to APIs, for example. In 32-bit Visual Basic, these functions return Long values as they always have, but when you use 64-bit VBA, these functions return LongPtr values. Although this seems correct on the surface, this can pose a problem with an unexpected result. Consider, for example, the following code:

Dim L as Long
Dim X as Long
L = VarPtr(X)

When you use 32-bit Visual Basic with the code sample here, your code should execute properly because L is a Long (32-bit) and VarPtr returns a Long (32-bit). However, if you use this code sample with 64-bit Visual Basic, L is a Long (32-bit), but VarPtr is a LongPtr (64-bit). In this case, we are assigning a possibly large value into a smaller variable. In most cases, Visual Basic handles this kind of conversion at run time. If the return value from VarPtr fits in 32 bits, then Visual Basic silently does the downsizing and you won't see a runtime error. Because pointer values are unpredictable, however, you might never encounter a run-time error while developing the application, and end users might only sporadically see a run-time error. These types of errors are hard to reproduce and very difficult to debug. To help alleviate this potential issue, 64-bit Visual Basic does not allow a LongPtr to be implicitly converted into a Long, even if the value being converted fits in the smaller variable. A LongPtr value can be explicitly converted by using the CLong() function.

[Previous] [Contents] [Next]