Declaring API functions in 64 bit Office
Introduction
With the introduction of Windows 7 and Office 2010 VBA developers face a new challenge: ensuring their applications work on both 32 bit and 64 bit platforms.
This page is meant to become the first stop for anyone who needs the proper syntax for his API declaration statement in Office VBA.
Most of the declarations placed here when I first wrote the article were figured out by Charles Williams of www.decisionmodels.com when he created the 64 bit version of our Name Manager (to be published soon).
Links
Of course Microsoft documents how to do this. There is an introductory article on Microsoft MSDN:
Compatibility Between the 32-bit and 64-bit Versions of Office 2010
That article describes the how-to's to properly write the declarations. What is missing is which type declarations go with which API function or sub.
Microsoft also published a tool to check your code for 64 bit related problems, called the Microsoft Office Code Compatibility inspector addin.
API functions that were added/modified in 64-bit Windows: http://msdn.microsoft.com/en-us/library/aa383663(VS.85).aspx
API Functions by Windows release:
http://msdn.microsoft.com/en-us/library/aa383687(VS.85).aspx
Declarations by API function
| Function name | Declarations (32 bit followed by 64 bit) |
| FindWindow | Private Declare Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr |
| getDC |
Private Declare Function GetDC Lib "USER32" (ByVal hWnd As Long) As Long
Private Declare PtrSafe Function GetDC Lib "USER32" (ByVal hWnd As LongPtr) As LongPtr |
| getDeviceCaps |
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As LongPtr, ByVal nIndex As Long) As Long |
| getFrequency |
Declare Function getFrequency Lib "kernel32" Alias "QueryPerformanceFrequency" (cyFrequency As Currency) As Long
Private Declare PtrSafe Function getFrequency Lib "kernel32" Alias "QueryPerformanceFrequency" (cyFrequency As Currency) As Long |
| GetKeyState |
Declare Function GetKeyState Lib "USER32" (ByVal vKey As Long) As Integer Declare PtrSafe Function GetKeyState Lib "USER32" (ByVal vKey As Long) As Integer |
| GetSystemMetrics |
Private Declare Function GetSystemMetrics Lib "USER32" (ByVal nIndex As Long) As Long
Private Declare PtrSafe Function GetSystemMetrics Lib "USER32" (ByVal nIndex As Long) As Long |
| getTickCount |
Private Declare Function getTickCount Lib "kernel32" Alias "QueryPerformanceCounter" (cyTickCount As Currency) As Long
Private Declare PtrSafe Function getTickCount Lib "kernel32" Alias "QueryPerformanceCounter" (cyTickCount As Currency) As Long ' |
| getTime |
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare PtrSafe Function timeGetTime Lib "winmm.dll" () As Long |
| GetWindowLongptr |
Private Declare Function GetWindowLongptr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long Private Declare PtrSafe Function GetWindowLongptr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr |
| IsCharAlphaNumericA |
Private Declare Function IsCharAlphaNumericA Lib "USER32" (ByVal byChar As Byte) As Long Private Declare PtrSafe Function IsCharAlphaNumericA Lib "USER32" (ByVal byChar As Byte) As Long |
| ReleaseDC |
Private Declare Function ReleaseDC Lib "USER32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
Private Declare PtrSafe Function ReleaseDC Lib "USER32" (ByVal hWnd As LongPtr, ByVal hDC As LongPtr) As Long |
| SetWindowLongPtr |
Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Declare PtrSafe Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr |
| timeGetTime |
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare PtrSafe Function timeGetTime Lib "winmm.dll" () As Long |
Other API functions
Have a function declaration which is not on this list? I invite you to send me your (working and tested!!!) declarations so I can add them here.
I also welcome comments and suggestions on improvements!




Comments
All comments about this page:
Comment by: Jan Karel Pieterse (5/21/2010 1:37:45 AM)Thanks Anders!!!
Comment by: Yuhong Bao (6/6/2010 12:23:09 AM)"Private Declare PtrSafe Function GetWindowLongptr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr"
"Private Declare PtrSafe Function GetWindowLongptr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr"
Wrong, sorry. I think the best bet here is to use Win64 instead of VBA7 and use Alias "GetWindowLongPtrA" and Alias "SetWindowLongPtrA". That is how it is defined in the headers.
Comment by: Jan Karel Pieterse (6/6/2010 11:09:30 PM)Hi Yuhong,
Thanks. Could you perhaps show the proper declarations in full?
Comment by: Yuhong Bao (6/6/2010 11:14:06 PM)Private Declare PtrSafe Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
Note that this Declare should be conditialized on Win64 instead of VB7, because Get/SetWindowLongPtr do not exist as an export on 32-bit Windows.
Comment by: Jan Karel Pieterse (6/7/2010 12:21:24 AM)Hi Yuhong,
Thanks!
Comment by: Yuhong Bao (6/7/2010 1:15:58 PM)The Declare for SetWindowLongPtr above is wrong. Here is the correct one:
Private Declare PtrSafe Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
Comment by: Clarence (7/14/2010 8:43:57 AM)What if your targeted users are using both 32 and 64 bit versions, do you need to create two versions of the document?
Comment by: Jan Karel Pieterse (7/14/2010 10:58:42 AM)Hi Clarence,
No, but you will need code like the following:
#If VBA7 Then
Declare PtrSafe Function GetKeyState Lib "USER32" (ByVal vKey As Long) As Integer
#Else
Declare Function GetKeyState Lib "USER32" (ByVal vKey As Long) As Integer
#End If
Have a question, comment or suggestion? Then please use this form.
If your question is not directly related to this web page, but rather a more general "How do I do this" Excel question, then I advise you to ask your question here: www.eileenslounge.com.