Results 1 to 28 of 28

Thread: Typelib to add LongPtr type to VB6 for universal codebases

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Typelib to add LongPtr type to VB6 for universal codebases

    VB6LongPtr.tlb - Add LongPtr to VB6


    This is just a dead simple typedef but I didn't see anything like it readily available, so thought I'd post the one I made.

    While you can (and must) use compiler constants to declare APIs differently, it gets to be unwieldy fast when you want to have the rest of your code be compatible when you have variables and Type members that also must be LongPtr. So to create universal codebases, I made a simple typelib that adds a LongPtr alias for Long in VB6. You can declare variables, Type members, arguments, etc, as LongPtr, and VB6 will treat them identically to a Long, with which they're also interchangeable- you can pass a LongPtr variable to a function expecting a Long, and a Long to a function expecting a LongPtr.

    Add this only to your VB6 projects, not to VBA or twinBASIC projects.


    Code:
    //VB6LongPtr by fafalone
    //Simply uses an alias to make LongPtr a usable type in VB6 in order
    //to create universal codebases for VB6/VBA/twinBASIC. Include this 
    //typelib **only** with VB6 projects, as VBA/tB have a native LongPtr.
    //(Since VB6 is 32bit only, LongPtr *always* would resolve to Long)
    [
        uuid(D8EE61B0-8778-4A43-8F98-E7E1C2C08AD4),
        version(1.00),
        helpstring("VB6 LongPtr Support"),
        lcid(0x0)
    ]
    library VB6LongPtr {
    
    importlib("stdole2.tlb");
    
    typedef [public] long LongPtr;
    };
    Attached Files Attached Files

  2. #2
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,156

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    I've been using a similar hack with an empty enum for some time now

    Code:
    #Const HasPtrSafe = (VBA7 <> 0) Or (TWINBASIC <> 0)
    
    #If HasPtrSafe Then
    Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
    #Else
    Private Enum LongPtr
        [_]
    End Enum
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
    #End if
    Notice CopyMemory's last parameter is LongPtr in both declares in both x86 and x64 targets (i.e. bitness agnostic declare).

    This also allows declaring bitness agnostic UDTs (no conditional compilation) like this

    Code:
    Private Type SAFEARRAY1D
        cDims               As Integer
        fFeatures           As Integer
        cbElements          As Long
        cLocks              As Long
        pvData              As LongPtr
        cElements           As Long
        lLbound             As Long
    End Type
    cheers,
    </wqw>

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    The last param of CopyMemory is a SIZE_T, which like pointers is 4 bytes on 32bit, 8 on 64... it comes up in a few other places too; like the GlobalAlloc/LocalAlloc/HeapAlloc functions and their related calls.

    Btw twinBASIC has the VBA7 constant set, so I don't know if you need both just for PtrSafe. I use it for DeclareWide sometimes.

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    This is a fantastic idea. I do like the TypeLib approach better though, as it allows for the actual declaration of variables as LongPtr, which I have done before (which the Enum won't let you do). Anytime I have a memory pointer I'm declaring in the VBA, I use LongPtr. Now, I can make that code interchangeable between VB6 and VBA.

    Nice work, Fafalone.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,156

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Quote Originally Posted by Elroy View Post
    I do like the TypeLib approach better though, as it allows for the actual declaration of variables as LongPtr, which I have done before (which the Enum won't let you do)
    When is enum failing? Can you give some sample code?

    Quote Originally Posted by fafalone View Post
    Btw twinBASIC has the VBA7 constant set, so I don't know if you need both just for PtrSafe. I use it for DeclareWide sometimes.
    Good to know, thanks!

    cheers,
    </wqw>

  6. #6
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Quote Originally Posted by wqweto View Post
    When is enum failing? Can you give some sample code?
    I guess I just didn't think it through. I use all the time to declare function returns and also procedure arguments. I've just never used it to declare a stand-alone variable, but it obviously works fine.

    Code:
    
    Option Explicit
    
    Private Enum LongPtr
        [_]
    End Enum
    
    Private Sub Form_Load()
        Dim p As LongPtr
    End Sub
    
    
    I should have realized that it'd work, given that you can use it to declare arguments. My bad.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  7. #7
    Junior Member
    Join Date
    Jul 2015
    Location
    south bavaria germany
    Posts
    28

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Hi wqweto and fafalone,

    Of course we know, VB is capable of using Aliases through tlbs since "M.C.s-PowerVB". And moreover we can "kind of" use an Alias for Long by doing an empty Enum, and this is well known practice for decades now.
    I do not claim to be the only one who ever had the idea for using an empty enum as an Alias for LongPtr, however I posted the idea in 2021 in ActiveVB-forum:
    http://foren.activevb.de/forum/vba/t...C-als-a/#forum
    Also have a look at the english translation in my github:
    https://github.com/OlimilO1402/XL_VBanywhere

    I very much like to see this idea is used by many developers out there suddenly today

    instead of using a tlb I tend to use a Module named MPtr in which I collected all Ptr-related stuff in it
    https://github.com/OlimilO1402/Ptr_P...dules/MPtr.bas
    besides UDTPtr, of course also the empty LongPtr Enum

    As for now, all I want to say, LongPtr is not enough, if you want to make a code running everywhere in VBC and all VBA. Unfortunately we need to declare all our API-functions twice
    for VBA7(x64) with the keyword Ptrsafe and for VB6(x86) without the keyword Ptrsafe

    RtlMoveMemory:
    the last parameter (ByteLength) in x64 is a 64bit LongLong and in x86 it is a 32-bit Long
    even If we could use the same thing here, imho it would be a "crime" to use LongPtr if the variable is not a pointer
    all we need is a second Alias for this as well, even if LongLong is not 64-bit in x86

    a little example from MPtr:

    Code:
    #If VBA7 = 0 Then
        Public Enum LongPtr
            [_]
        End Enum
    #End If
    #If Win64 = 0 Then
        Public Enum LongLong
            [_]
        End Enum
    #End If
    #If Win64 Then
        Public Const SizeOf_LongPtr As Long = 8
    #Else
        Public Const SizeOf_LongPtr As Long = 4
    #End If
    #If VBA7 Then
        Public Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" (ByRef pDst As Any, ByRef pSrc As Any, ByVal BytLen As LongLong)
        Public Declare PtrSafe Sub RtlZeroMemory Lib "kernel32" (ByRef pDst As Any, ByVal BytLen As LongLong)
    #Else
        Public Declare Sub RtlMoveMemory Lib "kernel32" (ByRef pDst As Any, ByRef pSrc As Any, ByVal BytLen As LongLong)
        Public Declare Sub RtlZeroMemory Lib "kernel32" (ByRef pDst As Any, ByVal BytLen As LongLong)
    #End If
    
    Public Function StrArrPtr(ByRef strArr As Variant) As LongPtr
    'Attention, here 32bit-64bit-trap, so use only RtlMoveMemory to be variable in size of ptr
        RtlMoveMemory StrArrPtr, ByVal VarPtr(strArr) + 8, MPtr.SizeOf_LongPtr
    End Function
    using:
    Code:
    Private Sub BtnTestSAPtr_Click()
        
        ReDim sa(0 To 10) As String
        sa(0) = "one"
        sa(1) = "two"
        
        Dim saX() As String
        
        SAPtr(StrArrPtr(saX)) = SAPtr(StrArrPtr(sa))
        
        Debug.Print saX(0)
        
        MPtr.ZeroSAPtr StrArrPtr(saX)
        
    End Sub
    Cheers

  8. #8
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Personally, when coding in VBA, I'd never use LongPtr to declare a non-pointer LongLong. The reason why is simple. I might be in 32-bit, but I'm still doing some operations that are expecting a 64-bit variable, which isn't terribly unusual.

    So OlimilO, your point is well taken. Just an FYI, we actually do have the LongLong in VB6. We just have to use a Variant to do it, and there are some caveats to it.
    Last edited by Elroy; Oct 22nd, 2022 at 10:37 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  9. #9

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    I've thought about making all the internal aliases in oleexp public... it currently has LongPtr, LONG_PTR, BOOL, CHAR, KNOWNFOLDERID and REFERENCE_TIME/HNSTIME public... but I decided it might get confusing with dozens of types... might be too much for most VB people lol

    Code:
    typedef long            ULONG;
    typedef long            UINT;
    typedef long            UINT32;
    typedef long            HWND;
    typedef long            DWORD;
    typedef long            HKEY;
    typedef long            HMENU;
    typedef long            HICON;
    typedef long            HBITMAP;
    typedef long            HIMAGELIST;
    typedef long			HMODULE;
    typedef long            HDC;
    typedef long            HACCEL;
    typedef long            HTASK;
    typedef long            HPALETTE;
    typedef long            HANDLE;
    typedef long            COLORREF;
    typedef double			REFTIME;
    typedef long			HSEMAPHORE;
    typedef long			HEVENT;
    typedef long			DWORD_PTR;
    typedef long            ULONG_PTR;
    typedef long            LCID;
    typedef CURRENCY        ULONGLONG;
    typedef CURRENCY        UINT64;
    typedef UUID            *REFKNOWNFOLDERID;
    typedef UUID            FOLDERTYPEID;
    typedef	UUID            CLSID;
    typedef short           WORD;
    typedef short           VARIANT_BOOL;
    typedef CURRENCY        DWORDLONG;

    I'd agree with Elroy about LongLong... probably not a good idea since most usage isn't SIZE_T (maybe most if you count handles, which technically aren't pointers, but still there's a lot of platform-independent places where it's always an 8-byte type.

    What do you mean about LongLong in a Variant though? It's not like Decimal where there's half implemented support via CDec()... do you just mean the various ways of messing around with the Variant in memory where you can use *any* type, or there something I'm missing?

  11. #11
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Quote Originally Posted by fafalone View Post
    What do you mean about LongLong in a Variant though? It's not like Decimal where there's half implemented support via CDec()... do you just mean the various ways of messing around with the Variant in memory where you can use *any* type, or there something I'm missing?
    I've got to run to a party in about 5 minutes, and I'll find links when I get back. But yeah, there's no C...() for it like there is CDec(). But, if you force a Variant to be a LongLong, it works fairly well. You just can't use it as a Variant-byref (the pointer in the variant). If the LongLong is in the Variant as byval, it works in VB6. If I remember correctly, you can even add, subtract, multiply, and divide the things ... but I'd need to review to make sure.

    GTG
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  12. #12
    Junior Member
    Join Date
    Jul 2015
    Location
    south bavaria germany
    Posts
    28

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Handles are "like" Pointers, 32bit in x68 and 64bit in x64, so using the LongPtr Alias for all kinds of handles, imho would be OK, and should be considered as the way to go.
    Yes calculations with the datatype Decimal inside the Variant is slow, but so are all int64-operations in x86.
    Yes Decimal is an underrated datatype. It has in total 96bits and it can be an unsigned In64 and also act like a signed Int64, either way is possible.

  13. #13

  14. #14
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,156

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Quote Originally Posted by OlimilO View Post
    Of course we know, VB is capable of using Aliases through tlbs since "M.C.s-PowerVB". And moreover we can "kind of" use an Alias for Long by doing an empty Enum, and this is well known practice for decades now.
    Yes, it was one of your github projects I first saw this hack some time this year.

    We don't do x64 in VB6 land that often and only recently our interest has peaked in connection with TwinBASIC's imminent general availability (kind of but you get the point) so we are getting ready to port some major building blocks in VB6 land to x64 (i.e. becoming bitness agnostic) which will cross-pollinate VBA7 world as well with some quality efforts IMO.

    Who knows we might see x64 version of RC6 too :-))

    cheers,
    </wqw>

  15. #15
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Quote Originally Posted by The trick View Post
    i always use Currency for 64 bit operations. It's faster than one wrapped into a Variant variable.
    I actually do too. You can even do addition and subtraction with Currency, thinking of them as LongLong. But you can't do multiplication nor division, as that will work out differently.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  16. #16
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Quote Originally Posted by Elroy View Post
    I actually do too. You can even do addition and subtraction with Currency, thinking of them as LongLong. But you can't do multiplication nor division, as that will work out differently.
    You could use apis:
    Code:
    Option Explicit
    
    Private Declare Function allmul Lib "ntdll" _
                             Alias "_allmul" ( _
                             ByVal cMultiplicand As Currency, _
                             ByVal cMultiplier As Currency) As Currency
    Private Declare Function alldiv Lib "ntdll" _
                             Alias "_alldiv" ( _
                             ByVal cDivident As Currency, _
                             ByVal cDivisor As Currency) As Currency
                             
    Private Sub Form_Load()
        Debug.Print alldiv(5, 0.08) ' // 50000 / 800 = 62
        Debug.Print allmul(500, 8)  ' // 5000000 * 80000 = 400000000000
    End Sub

  17. #17

  18. #18
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    Quote Originally Posted by The trick View Post
    You could use apis:
    Code:
    Option Explicit
    
    Private Declare Function allmul Lib "ntdll" _
                             Alias "_allmul" ( _
                             ByVal cMultiplicand As Currency, _
                             ByVal cMultiplier As Currency) As Currency
    Private Declare Function alldiv Lib "ntdll" _
                             Alias "_alldiv" ( _
                             ByVal cDivident As Currency, _
                             ByVal cDivisor As Currency) As Currency
                             
    Private Sub Form_Load()
        Debug.Print alldiv(5, 0.08) ' // 50000 / 800 = 62
        Debug.Print allmul(500, 8)  ' // 5000000 * 80000 = 400000000000
    End Sub
    Very nice! That's good information. I've already saved the API declarations.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  19. #19
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,904

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    just asking: it can be the same for create the Pointers types?
    VB6 2D Sprite control

    To live is difficult, but we do it.

  20. #20

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    You can use them internally within a typelib where it will resolve to a ByRef when compiled, but no, VB has no true pointer type support. You can see this with oleexp; I accidentally left in the last time I tried it:

    typedef [public] long *vbLongPtr;

    You'll get an automation type not supported error if you try to actually use it in VB6.

  21. #21
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,904

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    thanks for all
    VB6 2D Sprite control

    To live is difficult, but we do it.

  22. #22
    Fanatic Member
    Join Date
    Mar 2023
    Posts
    832

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    What "I accidentally left in the last time I tried it?
    You have very accidenentally done so typedef [public] long *vbLongPtr
    WILL not be work with VB7 (Office 10) and Office 10 (VB7) Long_PTR
    This is very accidenentally because you WANT people to STICK to your TypeLib.

  23. #23

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    oleexp.tlb and vblongptr.tlb are 32-bit only typelibs. They do not work, at all, with 64bit hosts. I do not want people to use oleexp in those, because it's not intended for them. For 64bit twinBASIC, I offer WinDevLib (formerly tbShellLib), which is basically oleexp+thousands of additional APIs. When tB supports exporting .tlb from packages, I'll release it for 64bit VBA, and oleexp will be deprecated in favor of it. Frankly I don't care if people use it or not, and frequently point out alternatives, and instructions to convert things for use outside those libraries.

    Office doesn't have LONG_PTR, or vbLongPtr. Both of those are user-defined only. The only one built in is LongPtr. These typelibs *would* work with 32bit VBA7 though (and plenty of people use oleexp for it), since the built-in version will take precedence and you can implicitly convert between them.

    It's an accident in that I wanted to see what happened if I made such a def pubic, and intended to remove it from the public release when the answer was 'nothing good', but forgot. But again, now that this has been brought to my attention, the bug will be fixed in the next release. I fix my bugs, I don't dismiss people who point them out and defend blatantly wrong mistakes. Since I don't know everything like you, I appreciate any help someone is willing to offer me.

  24. #24
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,904

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    here you speak:
    - Currency, but VB6 don't have it;
    - fafalone you give us the LongPtr.... thanks, even i don't understand how can i get it... i just download the lib;
    - using 'Long' and the 'TypeDef', we can do 'HDC' and others handles.
    - fafalone if you can get the 'LongPtr', we can get, too, pointers(even change the name) for numbers, floats and strings.
    thanks for all
    VB6 2D Sprite control

    To live is difficult, but we do it.

  25. #25

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    -VB6 does have Currency

    -Add either this typelib or oleexp.tlb under Project->References

    -Yes you could add others like that but you'd have to modify the typelib.

    -In VB6 it's just a name change; it's not adding true pointer types. You could create aliases for those other types too, but again you have to modify the typelib; e.g. typedef [public] short ATOM; would add 'ATOM' as another name for 'Integer'.

  26. #26
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,904

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    fafalone: "-In VB6 it's just a name change; it's not adding true pointer types. You could create aliases for those other types too, but again you have to modify the typelib; e.g. typedef [public] short ATOM; would add 'ATOM' as another name for 'Integer'."
    Code:
    typedef [public] long PTR;
    typedef [public] long HANDLE;
    typedef [public] long SIZE_T;
    ok.. i can do:
    Code:
    typedef [public] long PTR;
    typedef [public] long HANDLE;
    typedef [public] long SIZE_T;
    typedef [public] long STRPointer;
    typedef [public] long LongPTR;
    but like you see nothing happens... only change the name.... why not like:
    Code:
    typedef [public] varptr(varname)  LongPTR;
    ???
    ok..i'ts an error, but you get the point
    VB6 2D Sprite control

    To live is difficult, but we do it.

  27. #27

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    You can see the consequences in the current oleexp version; it has

    typedef [public] long *vbLongPtr;

    which would make it a true pointer.

    When you try to use it in VB6, you get an error 'Automation type not supported'.

  28. #28
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,904

    Re: Typelib to add LongPtr type to VB6 for universal codebases

    understood.. thanks
    VB6 2D Sprite control

    To live is difficult, but we do it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width