Macros and CorelDRAW X6 (64-Bit)
Posted 25-03-2012 at 18:27 by shelbym
Introduction
The good news in most macros from previous versions of CorelDRAW should work great. The one exception to this are macros that use WinAPI calls. All previous macros that use WinAPI calls will need to be updated for CorelDRAW X6 (64-bit). This is only for the 64-bit version, if you are using the 32-bit version of CorelDRAW, even on a 64-bit version of Windows everything should run as expected.
Why the Change
VBA has used the Long data type to represent pointer values in WinAPI calls. The Long data type is a 32-bit Integer, on a 64-bit platform the pointers are 64-bit values. As they say, you cannot put a 64-bit value in a 32-bit bucket, it will not fit. VBA needs to pass 64-bit values to the parameters and return values, not 32-bit as in the past. If VBA where passed a 64-bit value it would be truncated to a 32-bit value when making the WinAPI call and most likely lead to a crash of the host application, in our case CorelDRAW.
The Solution
Microsoft has added support for 64-bit by creating the new data type, LongPtr in VBA 7. The LongPtr data type will work correctly on both 32 and 64-bit systems as it uses a 32-bit pointer size for 32-bit platforms and a 64-bit pointer size for 64-bit platforms, pretty smart huh.
VBA needs to know that you have reviewed the WinAPI calls and made the correct changes to the new LongPtr data type, so Microsoft added the keyword PtrSafe to VBA to add after the Declare statement. This way VBA know you have reviewed the call and made it safe. Without this keyword any function / subroutine with Declare will fail to compile.
Examples
Here is an example of the changes that will need to be made.
Let’s look at another example:
Here is an example that uses both data types:
Declaring API Functions In 64 Bit Office
Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support
Supporting Older Version
This all works great for CorelDRAW X6 and VB7, but does not work with older versions, this is because older versions of VBA to not understand the new PtrSafe keyword and LongPtr data type. If you want your macro to support older version we need to add an IF Else Statement. Ah, yes, one Macro to rule them all.
Here is an example:
Again, I want to point out that this change only affects the few macros that use WinAPI calls, and with a few simple changes you will be up and running on any version of CorelDRAW. If you have questions or need further examples please feel free to post on the forums.
The good news in most macros from previous versions of CorelDRAW should work great. The one exception to this are macros that use WinAPI calls. All previous macros that use WinAPI calls will need to be updated for CorelDRAW X6 (64-bit). This is only for the 64-bit version, if you are using the 32-bit version of CorelDRAW, even on a 64-bit version of Windows everything should run as expected.
Why the Change
VBA has used the Long data type to represent pointer values in WinAPI calls. The Long data type is a 32-bit Integer, on a 64-bit platform the pointers are 64-bit values. As they say, you cannot put a 64-bit value in a 32-bit bucket, it will not fit. VBA needs to pass 64-bit values to the parameters and return values, not 32-bit as in the past. If VBA where passed a 64-bit value it would be truncated to a 32-bit value when making the WinAPI call and most likely lead to a crash of the host application, in our case CorelDRAW.
The Solution
Microsoft has added support for 64-bit by creating the new data type, LongPtr in VBA 7. The LongPtr data type will work correctly on both 32 and 64-bit systems as it uses a 32-bit pointer size for 32-bit platforms and a 64-bit pointer size for 64-bit platforms, pretty smart huh.
VBA needs to know that you have reviewed the WinAPI calls and made the correct changes to the new LongPtr data type, so Microsoft added the keyword PtrSafe to VBA to add after the Declare statement. This way VBA know you have reviewed the call and made it safe. Without this keyword any function / subroutine with Declare will fail to compile.
Examples
Here is an example of the changes that will need to be made.
‘API definition the old wayI have bolded and underlined the changes to make them easy to see. We have changed the Long data type to LongPtr, and have said that WinAPI call is now safe by using the PtrSafe keyword.
Private Declare Function GetDC Lib "USER32" (ByVal hWnd As Long) As Long
‘API definition the new way
Private Declare PtrSafe Function GetDC Lib "USER32" (ByVal hWnd As LongPtr) As LongPtr
Let’s look at another example:
‘API definition the old wayNotice anything different? Here we only used the keyword PtrSafe but did not change the Long data type to LongPtr. This is because we only need to use the LongPtr data type if the function arguments or return values that are memory addresses, if they represent data you should still use the Long data type.
Declare Function GetKeyState Lib "USER32" (ByVal vKey As Long) As Integer
‘API definition the new way
Declare PtrSafe Function GetKeyState Lib "USER32" (ByVal vKey As Long) As Integer
Here is an example that uses both data types:
‘API definition the old wayIf you would like some examples of common WinAPI calls and the new syntax you can use the following links:
Public Declare Function SendMessageA Lib "user32" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
‘API definition the new way
Public Declare PtrSafe Function SendMessageA Lib "user32" (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As LongPtr
Declaring API Functions In 64 Bit Office
Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support
Supporting Older Version
This all works great for CorelDRAW X6 and VB7, but does not work with older versions, this is because older versions of VBA to not understand the new PtrSafe keyword and LongPtr data type. If you want your macro to support older version we need to add an IF Else Statement. Ah, yes, one Macro to rule them all.
Here is an example:
#If VBA7 ThenSummary
Private Declare PtrSafe Function GetDC Lib "USER32" (ByVal hWnd As LongPtr) As LongPtr
#Else
Private Declare Function GetDC Lib "USER32" (ByVal hWnd As Long) As Long
#End If
Again, I want to point out that this change only affects the few macros that use WinAPI calls, and with a few simple changes you will be up and running on any version of CorelDRAW. If you have questions or need further examples please feel free to post on the forums.
Total Comments 1
Comments
Total Trackbacks 0