Using LongPtr Data Types
Before we update the Declare statement, let's recall what got us into this situation: lack of an official pointer data type and the subsequent overloading of Long to be the unofficial pointer data type. If Visual Basic had a pointer data type from the beginning, we could have written that Declare statement properly so that it runs correctly on both 32-bit and 64-bit versions of Visual Basic.
In Office 2010, Microsoft introduces a new data type for Visual Basic to fill this role as the official pointer data type-LongPtr. With 32-bit Visual Basic, LongPtr is a 32-bit quantity; and with 64-bit Microsoft Visual Basic for Applications (VBA), LongPtr is a 64-bit quantity.
Now, we can rewrite the previous Declare statement, which will work with both 32-bit and 64-bit Visual Basic, as follows:
Declare Function RegOpenKeyA Lib "advapi32.dll" _ (ByVal Key As LongPtr, ByVal SubKey As String, _ NewKey As LongPtr) As Long
You'll also need to update any Long sized pointers in User Defined Types (UDTs) that are passed to and from Declare procedures. Here's an example with the Windows process information structure:
Type PROCESS_INFORMATION hProcess As LongPtr hThread As LongPtr dwProcessId As Long dwThreadId As Long End Type
You need to remember that all Windows handlers are pointers and therefore need to be accordingly increased in size in your code. You can use LongPtr to hold and pass handles.
Using PtrSafe Attributes
As you're following along, you might be noticing that we have another problem: How can Visual Basic tell if a Declare statement's parameters and return value have been properly updated to handle pointers and are safe to use with both 32-bit and 64-bit Visual Basic? The answer, of course, is that it cannot. There are many Declare statements that quite legitimately pass or return Long values that are not pointers.
To address this issue, Microsoft introduced a new attribute for Declare statements called PtrSafe. This attribute tells Visual Basic that the Declare statement you're writing is safe to run with both 32-bit and 64-bit Visual Basic and that all pointer-sized values are properly handled. Without the PtrSafe attribute, 64-bit Visual Basic does not compile Declare statements. To maintain backward compatibility, 32-bit Visual Basic continues to compile Declare statements without the PtrSafe attribute. So, using the example we've been working through previously, the Declare statement is as follows:
Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" _ (ByVal Key As LongPtr, ByVal SubKey As String, _ NewKey As LongPtr) As Long
Microsoft recommends that all new Declare statements use LongPtr and PtrSafe.
In this tutorial:
- Visual Basic Fundamentals
- Visual Basic Development Environment
- Visual Basic Editor Window
- Relationship Between Access and Visual Basic
- Visual Basic Debugging Tools
- Working with the Watch Window
- Variables and Constants
- Variable and Constant Scope
- Declaring Constants and Variables
- Dim Statement
- Enum Statement
- Event Statement
- Private Statement
- Public Statement
- Static Statement
- Type Statement
- Collections, Objects, Properties, and Methods
- DAO Architecture
- ADO Architecture
- Referencing Collections, Objects, and Properties
- Use Exclamation Points and Periods
- Assigning an Object Variable-Set Statement
- Object Methods
- Manipulating Complex Data Types Using DAO
- Working with ADO Recordsets
- Functions and Subroutines
- Sub Statement
- Understanding Class Modules
- Property Let
- Property Set
- Controlling the Flow of Statements
- Do...Loop Statement
- For...Next Statement
- For Each...Next Statement
- If...Then...Else Statement
- RaiseEvent Statement
- Stop Statement
- With...End Statement
- Running Macro Actions and Menu Commands
- Executing an Access Command
- Trapping Errors
- Working with 64-Bit Access Visual Basic for Applications
- Using LongPtr Data Types
- Supporting Older Versions of Access
- Using LongLong Data Types