问题
I'm trying to design a custom type that can be used in APIs which need window handles or other kinds of pointers, and which will work for all systems VBA can run on. Here's what I've got:
#If (Win64 = 1) And (VBA7 = 0) Then
Public Type LongLong '64-bit systems pre-VBA7 wouldn't have had LongLong
LoPart As Long
HiPart As Long
End Type
#End If
Public Type Pointer 'could alternatively make a LongPtr type for pre VBA7 systems only
#If VBA7 Then
Address As LongPtr 'should always be correct right?
#ElseIf Win64 Then
Address As LongLong 'should never exist as VBA6 and lower are 32 or 16 bit
#ElseIf Win16 Then
Address As Integer '16 bit address, is this correct?
#Else
Address As Long '32 Bit pre-VBA7 system
#End If
End Type
The logic goes:
- Only the bitness of the Office host matters, not of the operating system. Is this definitely correct, I'm not sure?
Win64/32/16
misleadingly refer to that the version of Office (not the version of Windows - the OS - as the name may suggest).
- VBA7 introduced the
LongPtr
type which evaluates toLongLong
in 64 bit hosts,Long
in 32 bit hosts - Mac or Windows it should just work (I don't know what it does on a 16 bit host, but can VBA7 even be run on that?). So that's the first check- VBA7 is the last edition of VBA so no need to check for more modern than that. But out of interest, is there a way I could?
- Next I check for bitness of a pre-VBA7 host; I don't think it can ever be 64, but just in case, that requires a custom
LongLong
type (since that's only defined in VBA7)- Interestingly
Win64
works on Macs too - the name really is misleading
- Interestingly
- Similar checks take place 16 and 32 bit - only they don't need custom types (I assume
Integer
was defined in 16-bit VBA, and that it's the right datatype to use - I've never come across it so I can't really check)
Now one issue is that the LongLong
type flags an error in 64-bit VBA7 systems; I assume because LongLong
already exists on those systems so is not a valid name for a type. But the #If Win64 And VBA7 = 0
check should rule out the entire definition in such systems so I don't really know why it's a problem - I've asked a question about that.
Either way the code still runs as expected; any variable of type LongLong
just defaults to the builtin rather than mine in VBA7 - I just get Public Type LongLong
highlighted red in the editor which is a bit of a pain. Workarounds would be to rename it and avoid clashes (but also change the semantic meaning, and would mean that LongLong
couldn't be used elsewhere). Alternatively redefine pointer as
Public Type Pointer
#If VBA7 Then
Address As LongPtr 'should always be correct right?
#ElseIf Win64 Then
AddressLo As Long
AddressHi As Long
#ElseIf Win16 Then
Address As Integer '16 bit
#Else
Address As Long '32 Bit
#End If
End Type
which would change the interface a little.
So is this type going to work for all systems, Mac Windows, 32 64 bit, VBA7 VBA6 etc?
来源:https://stackoverflow.com/questions/56827443/is-this-pointer-type-watertight