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 has provided an updated version of the Win32API.txt with all proper declarations available for download here:
Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support
When you run the installer after downloading the file form
the link above, it does not tell you where it installed the information.
Look in this -new- folder on your C drive:
C:\Office 2010 Developer Resources\Documents\Office2010Win32API_PtrSafe
You can find a list of the old Win32 API declarations here:
Visual Basic Win32 API Declarations
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) |
| CreateProcess | We start off with a complicated one because it has a lot of
arguments. A fully functional example is included below the
example declaration lines. Courtesy: The example code was taken from this page Declare Function
CreateProcess Lib "kernel32" _
Alias "CreateProcessA" (ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ lpProcessAttributes As SECURITY_ATTRIBUTES, _ lpThreadAttributes As SECURITY_ATTRIBUTES, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ lpEnvironment As Any, _ ByVal lpCurrentDriectory As String, _ lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As Long Declare PtrSafe Function CreateProcess Lib "kernel32" _ Alias "CreateProcessA" (ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ lpProcessAttributes As SECURITY_ATTRIBUTES, _ lpThreadAttributes As SECURITY_ATTRIBUTES, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ lpEnvironment As Any, _ ByVal lpCurrentDriectory As String, _ lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As LongPtr 'Full example shown below, including the necessary structures
#If VBA7 Then
Declare PtrSafe Function CreateProcess Lib "kernel32" _ Alias "CreateProcessA" (ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ lpProcessAttributes As SECURITY_ATTRIBUTES, _ lpThreadAttributes As SECURITY_ATTRIBUTES, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ lpEnvironment As Any, _ ByVal lpCurrentDriectory As String, _ lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As LongPtr Const INFINITE = &HFFFF Const STARTF_USESHOWWINDOW = &H1 Private Enum enSW SW_HIDE = 0 SW_NORMAL = 1 SW_MAXIMIZE = 3 SW_MINIMIZE = 6 End Enum Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End Type Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Byte hStdInput As LongPtr hStdOutput As LongPtr hStdError As LongPtr End Type Private Type SECURITY_ATTRIBUTES nLength As LongPtr lpSecurityDescriptor As LongPtr bInheritHandle As Long End Type Private Enum enPriority_Class NORMAL_PRIORITY_CLASS = &H20 IDLE_PRIORITY_CLASS = &H40 HIGH_PRIORITY_CLASS = &H80 End Enum #Else Declare Function CreateProcess Lib "kernel32" _ Alias "CreateProcessA" (ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ lpProcessAttributes As SECURITY_ATTRIBUTES, _ lpThreadAttributes As SECURITY_ATTRIBUTES, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ lpEnvironment As Any, _ ByVal lpCurrentDriectory As String, _ lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As Long Const INFINITE = &HFFFF Const STARTF_USESHOWWINDOW = &H1 Private Enum enSW SW_HIDE = 0 SW_NORMAL = 1 SW_MAXIMIZE = 3 SW_MINIMIZE = 6 End Enum Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End Type Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Byte hStdInput As Long hStdOutput As Long hStdError As Long End Type Private Type SECURITY_ATTRIBUTES nLength As Long lpSecurityDescriptor As Long bInheritHandle As Long End Type Private Enum enPriority_Class NORMAL_PRIORITY_CLASS = &H20 IDLE_PRIORITY_CLASS = &H40 HIGH_PRIORITY_CLASS = &H80 End Enum #End If Private Function SuperShell(ByVal App As String, ByVal WorkDir As String, dwMilliseconds As Long, _ ByVal start_size As enSW, ByVal Priority_Class As enPriority_Class) As Boolean Dim pclass As Long Dim sinfo As STARTUPINFO Dim pinfo As PROCESS_INFORMATION 'Not used, but needed Dim sec1 As SECURITY_ATTRIBUTES Dim sec2 As SECURITY_ATTRIBUTES 'Set the structure size sec1.nLength = Len(sec1) sec2.nLength = Len(sec2) sinfo.cb = Len(sinfo) 'Set the flags sinfo.dwFlags = STARTF_USESHOWWINDOW 'Set the window's startup position sinfo.wShowWindow = start_size 'Set the priority class pclass = Priority_Class 'Start the program If CreateProcess(vbNullString, App, sec1, sec2, False, pclass, _ 0&, WorkDir, sinfo, pinfo) Then 'Wait ' WaitForSingleObject pinfo.hProcess, dwMilliseconds SuperShell = True Else SuperShell = False End If End Function Sub Test() Dim sFile As String 'Set the dialog's title sFile = Application.GetOpenFilename("Executables (*.exe), *.exe", , "") SuperShell sFile, Left(sFile, InStrRev(sFile, "\")), 0, SW_NORMAL, HIGH_PRIORITY_CLASS End Sub |
| 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 |
| FindWindowEx |
Private Declare
Function FindWindowEx
Lib "USER32" _
Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, _ ByVal lpsz1 As String, ByVal lpsz2 As String) As Long Private Declare PtrSafe Function FindWindowEx Lib "USER32" _ Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, _ ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr |
| GetClassName |
Public Declare
Function GetClassName
Lib "USER32" Alias "GetClassNameA"
_
(ByVal hWnd As Long, ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Public Declare PtrSafe Function GetClassName Lib "USER32" Alias "GetClassNameA" _ (ByVal hWnd As LongPtr, ByVal lpClassName As String, _ ByVal nMaxCount As LongPtr) As Long |
| 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 |
| GetDesktopWindow |
Public Declare
Function GetDesktopWindow
Lib "USER32" ()
As Long
Public Declare PtrSafe Function GetDesktopWindow Lib "USER32" () 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 |
| GetDriveType |
Private Declare
Function GetDriveType
Lib "kernel32" Alias _
"GetDriveTypeA" (ByVal sDrive As String) As Long Private Declare PtrSafe Function GetDriveType Lib "kernel32" Alias _ "GetDriveTypeA" (ByVal sDrive As String) As LongPtr |
| GetForegroundWindow |
Declare Function
GetForegroundWindow Lib "user32.dll"
() As Long
Declare PtrSafe Function GetForegroundWindow Lib "user32.dll" () As LongPtr |
| 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 |
| GetLastInputInfo |
#If VBA7 Then
Private Type LASTINPUTINFO cbSize As LongPtr dwTime As LongPtr End Type Private Declare PtrSafe Sub GetLastInputInfo Lib "USER32" (ByRef plii As LASTINPUTINFO) #Else Private Type LASTINPUTINFO cbSize As Long dwTime As Long End Type Private Declare Sub GetLastInputInfo Lib "USER32" (ByRef plii As LASTINPUTINFO) #End If |
| 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 |
| GetTempPath |
Declare Function
GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _ ByVal lpbuffer As String) As Long Declare PtrSafe Function GetTempPath Lib "kernel32" _ Alias "GetTempPathA" (ByVal nBufferLength As longptr, _ ByVal lpbuffer As String) 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 |
| GetWindow |
Public Declare
Function GetWindow
Lib "USER32" _
(ByVal hWnd As Long, ByVal wCmd As Long) As Long Public Declare PtrSafe Function GetWindow Lib "USER32" _ (ByVal hWnd As LongPtr, ByVal wCmd As LongPtr) As LongPtr |
| GetWindowLong |
Private Declare
Function GetWindowLong
Lib "USER32" Alias "GetWindowLongA"
(ByVal hWnd As
Long, ByVal
nIndex As Long)
As Long
Private Declare PtrSafe Function GetWindowLong Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr |
| GetWindowsDirectory |
Declare Function
GetWindowsDirectory& Lib "kernel32"
Alias _
"GetWindowsDirectoryA" (ByVal lpbuffer As String, _ ByVal nSize As Long) Declare PtrSafe Function GetWindowsDirectory& Lib "kernel32" Alias _ "GetWindowsDirectoryA" (ByVal lpbuffer As String, _ ByVal nSize As LongPtr) |
| GetWindowText |
Public Declare
Function GetWindowText
Lib "USER32" Alias "GetWindowTextA"
_
(ByVal hWnd As Long, ByVal lpString As String, _ ByVal cch As Long) As Long Public Declare PtrSafe Function GetWindowText Lib "USER32" Alias "GetWindowTextA" _ (ByVal hWnd As LongPtr, ByVal lpString As String, _ ByVal cch As LongPtr) As Long |
| InternetGetConnectedState |
Public Declare
Function InternetGetConnectedState
_
Lib "wininet.dll" (lpdwFlags As Long, _ ByVal dwReserved As Long) As Boolean Public Declare PtrSafe Function InternetGetConnectedState _ Lib "wininet.dll" (lpdwFlags As LongPtr, _ ByVal dwReserved As long) As Boolean |
| 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 |
| SendMessage |
Public Declare
Function SendMessageA
Lib "user32" (ByVal
hWnd As Long,
ByVal wMsg As
Long, _
ByVal wParam As Long, lParam As Any) As Long
Public Declare
PtrSafe Function SendMessageA
Lib "user32" (ByVal
hWnd As LongPtr,
ByVal wMsg As
Long, _
ByVal wParam As Long, lParam As Any) As LongPtr |
| SetActiveWindow |
Declare Function
SetActiveWindow Lib "user32.dll" (ByVal
hWnd As Long)
As Long
Declare PtrSafe Function SetActiveWindow Lib "user32.dll" (ByVal hWnd As LongPtr) As LongPtr |
| SetCurrentDirectory |
Private Declare
Function SetCurrentDirectoryA
Lib "kernel32" (ByVal
lpPathName As String)
As Long
Private Declare PtrSafe Function SetCurrentDirectoryA Lib "kernel32" (ByVal lpPathName As String) 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 |
| SHBrowseForFolder |
#If VBA7 Then
Private Type BROWSEINFO hOwner As LongPtr pidlRoot As Longp pszDisplayName As String lpszTitle As String ulFlags As Long lpfn As LongPtr lParam As LongPtr iImage As Long End Type Private Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _ (lpBrowseInfo As BROWSEINFO) As LongPtr #Else Private Type BROWSEINFO hOwner As Long pidlRoot As Long pszDisplayName As String lpszTitle As String ulFlags As Long lpfn As Long lParam As Long iImage As Long End Type Private Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _ (lpBrowseInfo As BROWSEINFO) As Long #End If Private Const BIF_RETURNONLYFSDIRS = &H1 |
| ShellExecute |
Private Declare
Function ShellExecute
Lib "shell32.dll" Alias "ShellExecuteA"
( _
ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _ ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _ ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, _ ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr |
| SHFileOperation |
#If VBA7 Then
Type SHFILEOPSTRUCT hWnd As LongPtr wFunc As Long pFrom As String pTo As String fFlags As Integer fAborted As Boolean hNameMaps As Longptr sProgress As String End Type Declare PtrSafe Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" _ (lpFileOp As SHFILEOPSTRUCT) As LongPtr #Else Type SHFILEOPSTRUCT hWnd As Long wFunc As Long pFrom As String pTo As String fFlags As Integer fAborted As Boolean hNameMaps As Long sProgress As String End Type Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" _ (lpFileOp As SHFILEOPSTRUCT) As Long #End If |
| SHGetPathFromIDList |
Private Declare
Function SHGetPathFromIDList
Lib "shell32.dll" Alias "SHGetPathFromIDListA"
_
(ByVal pidl As Long, ByVal pszPath As String) As Boolean Private Declare PtrSafe Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _ (ByVal pidl As LongPtr, ByVal pszPath As String) As Boolean |
| timeGetTime |
Private Declare
Function timeGetTime
Lib "winmm.dll" ()
As Long
Private Declare PtrSafe Function timeGetTime Lib "winmm.dll" () As Long |
Which Longs should become LongPtr?
It's actually pretty easy to determine what requires LongPtr and what can stay as Long. The only things that require LongPtr are function arguments or return values that represent addresses in memory. This is because a 64-bit OS has a memory space that is too large to hold in a Long data type variable. Arguments or return values that represent data will still be declared Long even in 64-bit.
The SendMessage API is a good example because it uses both types:
32-bit:
ByVal wParam As Long, lParam As Any) As Long
64 bit:
ByVal wParam As Long, lParam As Any) As LongPtr
The first argument -hWnd- is a window handle, which is an address in memory. The return value is a pointer to a function, which is also an address in memory. Both of these must be declared LongPtr in 64-bit VBA. The arguments wMsg and wParam are used to pass data, so they can be Long in both 32-bit and 64-bit.
How to determine what is a memory address and what is data? You just have to read the MSDN documentation for the API functions (the C++ version) and it will tell you. Anything called a handle, pointer, brush or any other object type will require a LongPtr in 64-bit. Anything that is strictly data can stay as Long.
Conditional compiling
If your code needs to run on both 32 bit and 64 bit Excel, then another thing to do is add conditional compilation to your VBA.
Microsoft devised two compile constants to handle this:
VBA7: True if you're using Office 2010, False for older versions
WIN64: True if your Office installation is 64 bit, false for 32 bit.
Since the 64 bit declarations also work on 32 bit Office 2010, all you have to test for is VBA7:
Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As LongPtr, ByVal nIndex As Long) As Long
#Else
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal nIndex As Long) As Long
#End If
And then in the routine where this function is put to use:
Dim hDC As LongPtr
#Else
Dim hDC As Long
#End If
Dim lDotsPerInch As Long
'Get the user's DPI setting
lDotsPerInch = GetDeviceCaps(hDC, LOGPIXELSX)
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
Showing last 8 comments of 70 in total (Show All Comments):Comment by: enzo (11/21/2011 4:16:47 AM)(working and tested!!!) ChooseColor function??
here a sample already modified for 64 bit but crash al line:
CC.lpCustColors = StrConv(aCustomColors, vbUnicode)
(Version 32 bit works properly)
*** ERROR: Runtime 13 Conversion type error
#If VBA7 Then
Dim lReturn As LongLong
Dim aCustomColors(0 To 16 * 4 - 1) As Long
Dim i As Integer
Dim lpCC As LongPtr
For i = LBound(aCustomColors) To UBound(aCustomColors)
aCustomColors(i) = 0
Next i
lpCC = StrConv(aCustomColors, vbUnicode)
Dim CC As CHOOSECOLOR
CC.lStructSize = CLng(Len(CC))
CC.hWndOwner = Application.hwnd
CC.hInstance = CLng(0)
CC.lpCustColors = StrConv(aCustomColors, vbUnicode)
CC.flags = CLng(0)
lReturn = ChooseColor(CC)
If lReturn <> 0 Then
Me.Caption = "RGB Value User Chose: "& str$(CC.rgbResult)
Me.idColore = CC.rgbResult
Else
MsgBox "No color selected"
End If
#Else
Dim CC As CHOOSECOLOR
Dim lReturn As Long
Dim aCustomColors(0 To 16 * 4 - 1) As Byte
Dim i As Integer
For i = LBound(aCustomColors) To UBound(aCustomColors)
aCustomColors(i) = 0
Next i
CC.lStructSize = Len(CC)
CC.hWndOwner = Me.hwnd
CC.hInstance = 0
CC.lpCustColors = StrConv(aCustomColors, vbUnicode)
CC.flags = 0
lReturn = ChooseColor(CC)
If lReturn <> 0 Then
Me.Caption = "RGB Value User Chose: " & str$(CC.rgbResult)
Me.idColore = CC.rgbResult
Else
MsgBox "No color selected"
End If
#End If
Comment by: Jan Karel Pieterse (11/21/2011 4:56:46 AM)Hi enzo,
Why are you declaring aCustomColors as a Long in the VBA7 case? I'd expect both declares should be of type Byte.
Since I see no differences in the VBA7 case or the Else pare, the entire conditional compilation is not needed?
Comment by: ENZO (11/21/2011 8:35:22 AM)ok thanks for the answer.
You are right I've changed type to Long for #VA7
The difference is in function and TYPE CHOOSECOLOR declarations (not wrote above)
here are the two different declarations:
if #Vba7 then
Type CHOOSECOLOR
lStructSize As Long
hWndOwner As LongPtr
hInstance As LongPtr
rgbResult As Long
lpCustColors As LongPtr
flags As Long
lCustData As LongPtr
lpfnHook As LongPtr
lpTemplateName As String
End Type
Declare PtrSafe Function ChooseColor Lib "comdlg32.dll" Alias "ChooseColorA" (pChoosecolor As CHOOSECOLOR) As Long
#else
Type CHOOSECOLOR
lStructSize As Long
hWndOwner As Long
hInstance As Long
rgbResult As Long
lpCustColors As Long
flags As Long
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
Declare Function ChooseColor Lib "comdlg32.dll" Alias "ChooseColorA" (pChoosecolor As CHOOSECOLOR) As Long
#end if
Comment by: Jan Karel Pieterse (11/21/2011 10:16:53 AM)Hi Enzo,
I still think the aCustomeColors array should remain an array of type Byte.
Comment by: enzo (11/21/2011 11:33:06 AM)OK, changed in byte, but the problem is on instruction:
CC.lpCustColors = StrConv(aCustomColors, vbUnicode)
Color dialog box don't appears
Comment by: Jan Karel Pieterse (11/21/2011 10:21:44 PM)Can you email me a copy of your file?
Comment by: enzo (12/9/2011 3:49:36 AM)
' 32 BIT VERSION works properly (under 32 bit):
Option Compare Database
Option Explicit
Declare Function ChooseColor Lib "comdlg32.dll" _
Alias "ChooseColorA" (pChoosecolor As CHOOSECOLOR_TYPE) _
As Long
Type CHOOSECOLOR_TYPE
lStructSize As Long
hwnd As Long
hInstance As Long
rgbResult As Long
lpCustColors As String
Flags As Long
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
' ===============================================
Sub TestGetColor()
Dim c
c = GetColor()
If c > 0 Then
MsgBox "SELECTED COLOR: " & c
Else
MsgBox "NO COLOR SELECTED"
End If
End Sub
Function GetColor()
Dim CustomColors() As Byte ' dynamic (resizable) array holds the RGB values
Dim cc As CHOOSECOLOR_TYPE ' structure to pass/receive information
Dim getC As Long ' return value of function
Dim rVal As Long ' return value of function
ReDim CustomColors(0 To 16 * 4 - 1) As Byte ' resize the array
Dim i As Integer ' counter variable
For i = LBound(CustomColors) To UBound(CustomColors)
CustomColors(i) = 0 ' set all custom color choices to black (RGB = 0,0,0)
Next i
cc.hwnd = Application.hWndAccessApp
cc.lpCustColors = StrConv(CustomColors, vbUnicode) ' convert custom color array
cc.Flags = &H80
cc.lStructSize = Len(cc) ' the size of the structure
getC = ChooseColor(cc) ' open the dialog box
If getC <> 0 Then ' if the user successfully chose a color
CustomColors = StrConv(cc.lpCustColors, vbFromUnicode) ' save custom colors
rVal = cc.rgbResult
Else
rVal = -1
End If
GetColor = rVal
End Function
Comment by: Jan Karel Pieterse (12/9/2011 5:18:43 AM)Hi Enzo,
Thanks.
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.