Page 6 of 9 FirstFirst ... 3456789 LastLast
Results 201 to 240 of 358

Thread: [VB6] Modern Shell Interface Type Library - oleexp.tlb

  1. #201
    New Member
    Join Date
    Dec 2021
    Posts
    2

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by fafalone View Post
    I got the paths problems fixed but the big issue now is the MIDL2003 redefinition problem. It gives that error whenever you define something that's already defined in Windows. Which is everything. If anyone has dealt with this before, let me know.

    Edit: What changes to the code itself would need to be made (what is the problem encountered when trying to use it in 64bit Office), assuming I can overcome the redefinition issue which might not be possible as every solution I've encountered says it's by design and to rename things.
    "oleexp.tlb" is very useful but not compatible with 64 Excel VBA.
    As you know, Handle and Pointer (memory address) have 8 bytes of data in 64-bit processes. Therefore, this TLB must be recompiled as 64-bit.

    E.g; User32.FindWindow function, which is one of the frequently used functions, throws an overflow exception because it returns a 64-bit number when using the existing 32-bit oleexp.tlb.

    As another example; The IDispatch.GetTypeInfo.AddressOfMember function must return a 64-bit integer.

    Since some structures and functions in TLB take the data type as ByRef, we cannot send type conversion functions such as CLngPtr.

    For these reasons 64-bit compilation is required.

    As a solution, if you describe how you overcome the "redefined" and "same uuid" errors that are printed on the screen when compiling the IDL content I have given as an example below with MIDL.EXE, everyone, especially me, can compile the interfaces they need.

    Simple IDL:

    Code:
    [
      uuid(035AE7E1-92D3-47F9-BACA-E9DF8FD28333),
      version(1.0),
      helpstring("Test type library")
    ]
    library test
    {    
        importlib("stdole2.tlb"); 
        
        interface IUnknown;   
    
        typedef struct UUID {
            LONG  Data1;
            SHORT Data2;
            SHORT Data3;
            BYTE  Data4[8];
        } UUID;
    
        [
            odl,
            uuid(00000000-0000-0000-C000-000000000046)
        ]
        interface IUnknown {
            LONG QueryInterface(
            [in, out] UUID *riid,
            [in, out] void *ppvObject);
            LONG AddRef();
            LONG Release();
        };
    
    };

  2. #202
    New Member
    Join Date
    Dec 2021
    Posts
    2

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Hello @fafalone, I solved the 64 bit compilation problem with MIDL.EXE. I worked with Visual Studio 2022.
    You can upgrade your project to new version with this.

    Example IDL and descriptions:

    Code:
    /*************************************************************************
     MIDL.EXE, can automatically add types inherited to the interface 
     or defined in the parameters of interface members to the "Type Library".
    
     However, it requires some modifications (before copy them your project dir) to the imported SDK IDL files.
     For example, if there is "<Unsupported variant type>" in Object Browser, 
     this indicates that it is not compatible with OLE automation. (UINT, ULONG.. etc).
     Or you may need to change/delete/add unwanted interface members.
     Microsoft has defined ITypeInfo members very differently in the IDL file in the SDK.
     You can delete them and rewrite them as they should be.
    
     The following IDL example will inject the types that the IDispatch and ITypeInfo2 interfaces
     are associated with. This includes Structures and Enumerations.
    
     You can give any UUID value to the "__NeededInjectionTypes" interface.
    
     Note that there is no import("stdole2.tlb") line. This line should not exist for automatic
     injection of types. If you use this line, you have to randomly assign the interface UUID value
     in the IDL files in the SDK. In our own IDL file, we need to write one by one with the
     original interface UUID value.
    
     For Handle and Pointer : LONG_PTR? __int3264?
    
     You can use "LONG_PTR" if you are designing Type Library for Office 2010 and above (VBE7).
     This will appear in Object Browser as "LongPtr" VBA type. The advantage of this is that
     you can use the TLB file that you will compile as 32-bit with in 64-bit Office.
    
     "__int3264" should be used if it is desired to be compatible for pre-Office 2010 as well.
     It directly converts the numeric type type to VBA "Long" type for 32 bit and VBA "LongLong" for 64 bit.
     This means making two separate TLB files for 32 and 64 bit Office.
    
     Best regards,
     Zeki Gürsoy
    
    Example commanline:
    REM ----------------------------------------------------------------
    CD "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64"
    
    REM For 64 bit:
    midl /no_warn ^
    /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um" ^
    /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" ^
    /cpp_cmd C:\PROGRA~1\MIB055~1\2022\PROFES~1\VC\Tools\MSVC\1430~1.307\bin\Hostx64\x64\cl.exe ^
    /tlb "D:TLBproject\test.tlb" "D:TLBproject\test.idl"
    
    REM For 32 bit (only need add /win32 switch):
    midl /no_warn /win32 ^
    /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um" ^
    /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" ^
    /cpp_cmd C:\PROGRA~1\MIB055~1\2022\PROFES~1\VC\Tools\MSVC\1430~1.307\bin\Hostx64\x64\cl.exe ^
    /tlb "D:TLBproject\test.tlb" "D:TLBproject\test.idl"
    REM --------------------------------------------------------------------------
    
    *************************************************************************/
    [
      uuid(902C3131-525C-4F45-AF75-4F1923DF0853),
      version(1.0),
      helpstring("Test type library")
    ]
    library test
    { 
        [odl,  restricted, hidden, uuid(00000000-0000-0000-0000-000000000001)]
        interface __NeededEnjectionTypes : IDispatch
        {
            /* You can declare another 'NeededTypes?' if parameters many. */
            HRESULT NeededTypes1(
                              [in] ITypeInfo2 *neededType1);
                           /* [in] ITypeLib2  *neededType2); */
        }; 
    
    };

  3. #203

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by vbLewis View Post
    Hi fafalone, I have taken the opportunity to optimize all the extra addon bas modules and some functions. Take a look if you wish, and i you feel like it could add value to your project feel free to use it, or reject , totally up to you.
    Definitely seems like a good option if performance is key, however one potential Con I'd like to point out, besides the added complexity of all the steps to use it, that method results in compiling the entirety of each used module into your exe/ocx. One of the reasons I used the old method, in addition to being the format used by notable shell projects before me for consistency's sake, is that it would only result in what you used being compiled into the binary; the compiler would prune the unused code. Here it's all used so all included.

    Also, where did dbg_enumstore come from? That's definitely not the oleexp modules unless maybe it got left in for a much older one? I checked 4.7 (current) and 4.62. It looks like something from my shell browser project.

  4. #204

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by drpatt View Post
    I found this library recently. Vey impressive.

    There is a slight bug in the call back function for pNotify.afChannelVolumes(1) in IAudioEndpointVolumeCallback_OnNotify(pNotify As AUDIO_VOLUME_NOTIFICATION_DATA)
    The afChannelVolumes array is limited to channel 0.

    I had a quick look at your source code.
    Perhaps the typedef structure should be float afChannelVolumes[2]; ?

    typedef struct AUDIO_VOLUME_NOTIFICATION_DATA
    {
    UUID guidEventContext; // Context associated with the originator of the event.
    BOOL bMuted;
    float fMasterVolume;
    UINT nChannels;
    float afChannelVolumes[1];

    I also found it quite a challange to return callback values to the main form.
    After much testing with subclassing and other over-complications..
    I overcame the crashes by copying to global values then enabling a 1ms Time control in the main form to process the global variables.
    Absolutely no crashing.

    I found I could enable callbacks for default speaker and microphone concurrently, with careful programming.
    However there appeared to be no way to differentiate the callback data by the device type that originated the callback.
    Is there a way?
    Does the secret lie in the pnotify.guidEventContext field ?
    What is the significance of the 4 parameters?

    Or to set up a second callback class with a different identity?

    David
    [2] would give it 3 channels; it's zero based.

    One of the demos uses that interface, did you look at [VB6, Vista+] Core Audio Basics

    Needless to say I had a difficult time getting it working too, but it did work out.

    I'm really not too familiar with whether you can get notifications in the same callback... can you print the guidEventContext and see if it's different depending on where you trigger an event? If so then there must be some way to associate the GUID with a device.

  5. #205

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by anemos_78 View Post
    Hello @fafalone, I solved the 64 bit compilation problem with MIDL.EXE. I worked with Visual Studio 2022.
    You can upgrade your project to new version with this.

    Example IDL and descriptions:

    Code:
    /*************************************************************************
     MIDL.EXE, can automatically add types inherited to the interface 
     or defined in the parameters of interface members to the "Type Library".
    
     However, it requires some modifications (before copy them your project dir) to the imported SDK IDL files.
     For example, if there is "<Unsupported variant type>" in Object Browser, 
     this indicates that it is not compatible with OLE automation. (UINT, ULONG.. etc).
     Or you may need to change/delete/add unwanted interface members.
     Microsoft has defined ITypeInfo members very differently in the IDL file in the SDK.
     You can delete them and rewrite them as they should be.
    
     The following IDL example will inject the types that the IDispatch and ITypeInfo2 interfaces
     are associated with. This includes Structures and Enumerations.
    
     You can give any UUID value to the "__NeededInjectionTypes" interface.
    
     Note that there is no import("stdole2.tlb") line. This line should not exist for automatic
     injection of types. If you use this line, you have to randomly assign the interface UUID value
     in the IDL files in the SDK. In our own IDL file, we need to write one by one with the
     original interface UUID value.
    
     For Handle and Pointer : LONG_PTR? __int3264?
    
     You can use "LONG_PTR" if you are designing Type Library for Office 2010 and above (VBE7).
     This will appear in Object Browser as "LongPtr" VBA type. The advantage of this is that
     you can use the TLB file that you will compile as 32-bit with in 64-bit Office.
    
     "__int3264" should be used if it is desired to be compatible for pre-Office 2010 as well.
     It directly converts the numeric type type to VBA "Long" type for 32 bit and VBA "LongLong" for 64 bit.
     This means making two separate TLB files for 32 and 64 bit Office.
    
     Best regards,
     Zeki Gürsoy
    
    Example commanline:
    REM ----------------------------------------------------------------
    CD "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64"
    
    REM For 64 bit:
    midl /no_warn ^
    /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um" ^
    /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" ^
    /cpp_cmd C:\PROGRA~1\MIB055~1\2022\PROFES~1\VC\Tools\MSVC\1430~1.307\bin\Hostx64\x64\cl.exe ^
    /tlb "D:TLBproject\test.tlb" "D:TLBproject\test.idl"
    
    REM For 32 bit (only need add /win32 switch):
    midl /no_warn /win32 ^
    /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um" ^
    /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" ^
    /cpp_cmd C:\PROGRA~1\MIB055~1\2022\PROFES~1\VC\Tools\MSVC\1430~1.307\bin\Hostx64\x64\cl.exe ^
    /tlb "D:TLBproject\test.tlb" "D:TLBproject\test.idl"
    REM --------------------------------------------------------------------------
    
    *************************************************************************/
    [
      uuid(902C3131-525C-4F45-AF75-4F1923DF0853),
      version(1.0),
      helpstring("Test type library")
    ]
    library test
    { 
        [odl,  restricted, hidden, uuid(00000000-0000-0000-0000-000000000001)]
        interface __NeededEnjectionTypes : IDispatch
        {
            /* You can declare another 'NeededTypes?' if parameters many. */
            HRESULT NeededTypes1(
                              [in] ITypeInfo2 *neededType1);
                           /* [in] ITypeLib2  *neededType2); */
        }; 
    
    };
    I haven't really worked with this at all... is there an automated way to handle this or would it be going through every single interface by hand?

    If it's just a question of returning 64-bit types, you can change them to do that with MKTYPLIB too; I was never able to get midl to work.

  6. #206
    New Member
    Join Date
    Dec 2021
    Posts
    4

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    The audio callback works with everything except pNotify.afChannelVolumes(1)
    pNotify.afChannelVolumes(0) returns the left channel volume correctly, pNotify.afChannelVolumes(1) produces subscript out of range.

    Debug output when the callback code runs:
    0.27
    Subscript out of range 1

    Code:
    Option Explicit
    
    Implements IAudioEndpointVolumeCallback
    
    Private Sub IAudioEndpointVolumeCallback_OnNotify(pNotify As AUDIO_VOLUME_NOTIFICATION_DATA)
    ' transfer to global variables
    Cmuted = pNotify.bMuted
    Cvol = pNotify.fMasterVolume
    Cchannels = pNotify.nChannels
    
    ' problem in oleexp.tlb - limited to channel 0
    On Error GoTo bad1
    Dim I As Integer
        If Cchannels > 1 Then
        I = 0
        Debug.Print (pNotify.afChannelVolumes(I))
        I = 1
        Debug.Print (pNotify.afChannelVolumes(I))
        End If
    
    ' enable data processing in main form using timer, if not already enabled
    ' use timer to create interrupt in form1 thread
    ' tried other methods: eg https://stackoverflow.com/questions/4169028/how-to-write-a-callback-in-vb6
    ' but this is simple and it works
    
        If Form1.Tcallback.Enabled = False Then Form1.Tcallback.Enabled = True
    Exit Sub
    
    bad1:
    Debug.Print Err.Description, I
    Err.Clear
    
    If Form1.Tcallback.Enabled = False Then Form1.Tcallback.Enabled = True
    End Sub
    If the array I suggested is the correct code point and is zero based, what else will be causing this issue?

    I tried trapping the pNotify.guidEventContext.Data
    All I got was a sequence of zero's, regardless of whether I used the speaker or microphone as the callback device.
    I would be interested to hear from anyone else applying the same test.

    Code:
    ' Store data in global variables for analysis using a timer event
    A(1) = pNotify.guidEventContext.Data1
    A(2) = pNotify.guidEventContext.Data2
    A(3) = pNotify.guidEventContext.Data3
    ' There are 7 bytes in data4
    Dim i As Byte
    For i = 0 To 7
    B(i) = pNotify.guidEventContext.Data4(i)
    Debug.Print i, pNotify.guidEventContext.Data4(i)
    Next i
    David

  7. #207

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Ok so changing it to 2 does give it the two channels, but presumably the number of channels would be greater than two with surround sound audio right?

    Core Audio is extremely finicky with callbacks and the two normal methods aren't working, so it'll take me some time to fix it for the general case, for now here's a version of the typelib with it defined as 2, I confirmed that gives values for both channels.
    Last edited by fafalone; Jun 3rd, 2022 at 10:15 PM.

  8. #208
    New Member
    Join Date
    Dec 2021
    Posts
    4

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by fafalone View Post
    Ok so changing it to 2 does give it the two channels, but presumably the number of channels would be greater than two with surround sound audio right?

    Core Audio is extremely finicky with callbacks and the two normal methods aren't working, so it'll take me some time to fix it for the general case, for now here's a version of the typelib with it defined as 2, I confirmed that gives values for both channels.
    I have both channels working with your patch. Thank you!
    I can see 2 possibilities with surround sound.
    1) More than 2 channels on the same device base
    2) Multiple bases for rear, side and sub woofer.
    I don't use surround sound so cannot tell you how this PC works.
    You are spot on with finicky. Absolutely no outside functions can be used in the callback.
    Even debug seems to cause failure.
    As does on error.
    After much experimenting I now have:

    Code:
    ' In a global module, for callback use
    Public Cvol As Single
    Public Cmuted As Long
    Public Cchannels As Long
    
    ' Patch worked 21/01/2022
    Public Cleft As Single
    Public Cright As Single
    
    Public A(1 To 3) As Long
    Public B(8) As Byte
    Public ShowContext As Boolean
    
    ' in cAudioEndpointVolumeCallback.cls
    Option Explicit
    
    Implements IAudioEndpointVolumeCallback
    
    Private Sub IAudioEndpointVolumeCallback_OnNotify(pNotify As AUDIO_VOLUME_NOTIFICATION_DATA)
        If Cdisable Then Exit Sub
    
    ' transfer to global variables
    Cmuted = pNotify.bMuted
    Cvol = pNotify.fMasterVolume
    Cchannels = pNotify.nChannels
    
        If ShowContext Then         ' copy Context variables
        A(1) = pNotify.guidEventContext.Data1
        A(2) = pNotify.guidEventContext.Data2
        A(3) = pNotify.guidEventContext.Data3
        Dim i As Byte
            For i = 0 To 7
            B(i) = pNotify.guidEventContext.Data4(i)
            Next i
        End If
        
    ' problem in oleexp.tlb - limited to channel 0
    ' Unless patched
    
    Cleft = -0.01
    Cright = -0.01
        If Cchannels > 1 Then
        Cleft = pNotify.afChannelVolumes(0)
        Cright = pNotify.afChannelVolumes(1)
        End If
        
        ' enable data processing in main form using timer, if not already enabled
        ' use timer to create interrupt in form1 thread
        If Form1.Tcallback.Enabled = False Then Form1.Tcallback.Enabled = True
    
    End Sub
    I can service the global callback data from a timer event fired by the callback.
    I used GUIDToString() in mIID.bas to process the context data, having assumed that the data was in the UUID structure format :

    Code:
        If ShowContext Then
        Dim i As Byte
        Dim context As UUID
        context.Data1 = A(1)
        context.Data2 = A(2)
        context.Data3 = A(3)
        
        msg = "Context: " + Str(A(1)) + "," + Str(A(2)) + "," + Str(A(3))
            For i = 0 To 7
            msg = msg + "," + Str(B(i))
            context.Data4(i) = B(i)
            Next i
        msg = msg + " : " + GUIDToString(context, True)
        showme msg       ' Write the data to the rich text box
        End If
    The context data is not particularly useful for speaker and microphone.
    I did get some consistant context field data from the advanced section of my Realteck digital output device.
    However, this hardly helps in differentiating between microphone and speaker callbacks.

    David
    Name:  coreaudio1.jpg
Views: 1295
Size:  64.4 KB
    Last edited by drpatt; Jan 22nd, 2022 at 03:00 AM.

  9. #209
    New Member
    Join Date
    Dec 2021
    Posts
    4

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by fafalone View Post
    Ok so changing it to 2 does give it the two channels, but presumably the number of channels would be greater than two with surround sound audio right?

    Core Audio is extremely finicky with callbacks and the two normal methods aren't working, so it'll take me some time to fix it for the general case, for now here's a version of the typelib with it defined as 2, I confirmed that gives values for both channels.
    I have now succeeded in creating a method to service input and output device callbacks running concurrently.
    Others might find this helpful.
    The callback context values are a red herring!
    My solution was to create a second class object duplicating the code in cAudioEndpointVolumeCallback, called MAudioEndpointVolumeCallback. (Watch out for the character limit in naming the class)
    A public variable Ccall is set to "m" for the input class and "s" for the speaker class

    Code:
    Option Explicit
    ' MAudioEndpointVolumeCallback
    ' for inputs
    
    Implements IAudioEndpointVolumeCallback
    
    Private Sub IAudioEndpointVolumeCallback_OnNotify(pNotify As AUDIO_VOLUME_NOTIFICATION_DATA)
        If CdisableM Then Exit Sub
    
    ' transfer to global variables
    Ccall = "m"
    Cmuted = pNotify.bMuted
    Cvol = pNotify.fMasterVolume
    Cchannels = pNotify.nChannels
    
        If ShowContext Then         ' copy Context variables
        A(1) = pNotify.guidEventContext.Data1
        A(2) = pNotify.guidEventContext.Data2
        A(3) = pNotify.guidEventContext.Data3
        Dim i As Byte
            For i = 0 To 7
            B(i) = pNotify.guidEventContext.Data4(i)
            Next i
        End If
        
    ' problem in oleexp.tlb - limited to channel 0
    ' Unless patched
    
    Cleft = -0.01
    Cright = -0.01
        If Cchannels > 1 Then
        Cleft = pNotify.afChannelVolumes(0)
        Cright = pNotify.afChannelVolumes(1)
        End If
        
        ' enable data processing in main form using timer, if not already enabled
        ' use timer to create interrupt in form1 thread
        If Form1.Tcallback.Enabled = False Then Form1.Tcallback.Enabled = True
    
    End Sub
    Variables used for input and output callback setup must be unique:

    Code:
    Private cVolCallback As cAudioEndpointVolumeCallback     ' speakers
    Private cVolCallbackM As MAudioEndpointVolumeCallback  ' mic
    
    Private callDefCaptureMM As IMMDevice                       ' Mic callback capture
    Private callVolMMM As IAudioEndpointVolume                 ' Mic callback volume
    
    Private callDefRenderMM As IMMDevice                        ' speakers callback render
    Private callVolMM As IAudioEndpointVolume                   ' speakers callback volume
    To read the callback data I use a 1mS delay Timer control in the main form:
    The timer is enabled by the callback.
    It first disables itself, then determines the callback source by examining the public variable Ccall.
    Name:  coreaudiov5.jpg
Views: 1249
Size:  142.8 KB

    David
    Last edited by drpatt; Jan 25th, 2022 at 04:42 AM.

  10. #210
    New Member
    Join Date
    Nov 2018
    Posts
    8

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Just an idea for oleexp.tlb:
    When using interfaces derived from IUnknown you are using stdole.IUnknown

    i.e.
    interface IObjectSafety : stdole.IUnknown

    This is of course the restricted version of IUnknown, where you can't use AddRef or Release functions in VB.
    Wouldn't it be possible to use the unrestricted version of olelib.IUnknown and to make AddRef and Release visible and useable?

  11. #211

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Have you tried setting it to the unrestricted version?

    Code:
    Dim pUnk As oleexp.IUnknown
    Set pUnk = whatever
    pUnk.AddRef/Release
    I don't recall if using Set will increment the reference counter, if that's an issue CopyMemory or vbaObjSet might be better.

    You also might be able to avoid an issue with reference counter increments in some scenarios by setting with vbaObjSetAddRef, which as the name suggests will set it and increment the reference counter.
    Last edited by fafalone; Feb 21st, 2022 at 02:01 AM.

  12. #212
    New Member
    Join Date
    Nov 2018
    Posts
    8

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Hi fafalone,

    I have tried it in example with

    Code:
        [
            odl,
            uuid(00020401-0000-0000-C000-000000000146),
        ]
        interface ITypeInfo : IUnknown {
    
    ...
    instead of

    Code:
        [
            odl,
            uuid(00020401-0000-0000-C000-000000000146),
        ]
        interface ITypeInfo : stdole.IUnknown {
    
    ...
    There I get in VB the unrestricted functions AddRef/Release/QueryInterface and I can obviously use them. With your standard implementation these functions are not browsable and restricted.

    It is much easier to have these functions available than making a query of IUnknown, when these functions are part of the queried interface anyway.
    I use as well the very good typelib of Michel Rutten (VBVM6Lib), which has abbreviations like MemLong(ptr As Long) (Let/Get) or AsLong(pVar As Any), which allows very nice code for direct memory manipulation

    Name:  Screenshot.png
Views: 1014
Size:  15.9 KB

  13. #213
    New Member
    Join Date
    Nov 2018
    Posts
    8

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    By the way: when I compile my version of your typelib ODLs (etc.) with MKTYPLIB I get an error in file tasksch.odl

    Maybe I have an old version of it. I skipped this file while compiling.

    C:\Projekt\Source\OLE Typelib Extension\oleexp47-source\source>cmd
    Microsoft Windows [Version 10.0.22000.493]
    (c) Microsoft Corporation. Alle Rechte vorbehalten.

    C:\Projekt\Source\OLE Typelib Extension\oleexp47-source\source>MKTYPLIB.exe oleexp.odl
    Microsoft (R) Type Library Generator Version 2.20.4054
    Copyright (c) Microsoft Corp. 1993-1995. All rights reserved.

    tasksch.odl (743) : fatal error M0001: Syntax error near line 743 column 21: Type is not OleAutomation-compatible

  14. #214

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    IIRC there were a few problems I ran into trying to inherit from the unrestricted IUnknown defined in the TLB, though I can't recall specifically what they were. Also I think if you do that you'd have to manually implement the IUnknown methods every time you used an interface with Implements. So that's unfortunately a non-starter as I shouldn't put out an update that breaks large amounts of existing code and requires major rewrites. But that's why open source is great, if that issue won't effect you, by all means compile an updated version! (But please remember to change the project GUID in oleexp.odl if you're going to post it publicly to avoid conflicts, probably a good idea to note the change in the title as well)

    Line 743 in tasksch.odl is just [in] SYSTEMTIME* pstStart,, so I have no idea why that would error, especially since that's near the end of the compiling order and it had to have run into systemtime numerous other times; although the version of mktyplib that comes with VS6 is indeed the later 2.20.4230, so that could well be the issue.
    Last edited by fafalone; Feb 21st, 2022 at 03:36 PM.

  15. #215
    Member
    Join Date
    Feb 2022
    Location
    Italy
    Posts
    56

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Hello to everyone.
    There is some video tutorial of this Interface?
    Best Regards

  16. #216

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    No I haven't made video tutorials for anything, but I'm not exactly sure what you videos could tell you that the posts don't, except perhaps the few samples that are snippets instead of full projects.

    If you're new to VB6 there's video tutorials for other projects that will acquaint you with the basics of starting a project and doing simpler things rather than jumping right into COM interfaces; just search vb6 on YouTube.

  17. #217
    Addicted Member
    Join Date
    Feb 2022
    Posts
    167

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Absolutely incredible work, thank you!

  18. #218

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Project Updated to Version 5.0

    I had meant to upload this a few weeks back due to major bugs with Core Audio interfaces, and just realized I hadn't. As the major version number suggests, there's also a lot of other updates:

    (oleexp 5.0 - Released 28 May 2022)
    -oleexp now includes all calls neccessary for TLB-based multithreading. Multithreading methods by The trick and Matthew Curland (PowerVB) have all calls included. For the latter, calls to the CreateThread API may need to be adjusted by pass ByVal, especially ByVal 0& for the LPSECURITY_ATTRIBUTES.
    Note: As with any multithreading with TLB project, you'll need to be careful you don't have any functions used by the multithreading code declared as Public in your project, as those will always have higher priority than a TLB.
    -Added IInertiaProcessor, IManipulationProcessor, and IManipulationEvents interfaces with coclasses InertiaProcessor and ManipulationProcessor (for advanced handling of touch input). While these types are already in an addable reference, one uses unsigned longs, making that version incompatible with VB.
    -Added interface IShellIconOverlayManager and coclass CFSIconOverlayManager
    -Added SysReAllocStringW alias for SysReAllocString that supports a StrPtr pointer to properly support Unicode, finally relieving the need for a separate API declare for the LPWStrToStr function ubiquitous in oleexp projects (provided you add the W; I didn't want to break backwards compatibility by replacing the original).
    -Added ILVRange undocumented ListView interface. This one was *really* undocumented; I was the first to publicly document it:
    https://www.vbforums.com/showthread....T-and-ILVRange
    -Added interface IShellRunDll; Implements-compatible.
    -Updated SIIGBF and various other enums with flags introduced in Windows 8 or 10
    -Created enum for SFVM_*... these were previously just commented out in source..
    -For CoreAudio, REFERENCE_TIME and HNSTIME are now a public type alias for Currency (take care when using it).
    -(Bug fix) Due to some trolling from Microsoft, IAudioClient has several members the public headers and topline documentation declare as WAVEFORMATEX. But in the fine print, you find this is a lie. They actually use WAVEFORMATEXTENSIBLE, and will not work on many systems without it. Since that was not included in the TLB, it's impossible to use. These methods now use As Any, so if the old way was working on your system, no changes are strictly neccessary (but if you're distributing it, your clients may run into it, so you should change it). This bug triggered releasing a new version now. IPolicyConfig, IPolicyConfigVista, IAudioClient2, and IAudioClient3 were also changed.
    -(Bug fix) AUDIO_VOLUME_NOTIFICATION_DATA only had a single array member for channel volume. It's set to 2 now to get two channel info, but this may change in the future if I figure out how to get 3+ channel info.
    -(Bug fix) Finally corrected built-in AssocCreate API from the olelib original. It was missing 4 bytes; a CLSID is 16, but it originally had long short short long, which is 12. Now BYTE[8].
    -(Bug fix) ULONG was defined as an unsigned long, but of course anyone trying to use it would get an error. It's now just an alias for a signed long. And no longer public.
    -(mPKEY) SCID_DateDeleted and SCID_OriginalLocation don't have PROPERTYKEY defs in the SDK, but can still be passed (and will be received from) any Recycle Bin property store.
    Last edited by fafalone; May 28th, 2022 at 07:48 PM.

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Btw, the code section above is completely unreadable. Might want to try putting this in a quote section instead.

    cheers,
    </wqw>

  20. #220
    Hyperactive Member
    Join Date
    Jan 2015
    Posts
    323

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    any one update this tlb for 64bit vba?

  21. #221

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    There was a post about it above in #202, but I don't know how reliable that is. A lot of types were changed from their original, and not all sizes doubled. I'd imagine it would likely have to be a top to bottom manual review, which there's just no way I have time for.

    Should just use 32bit Office. Are you really hitting the limits of it?

  22. #222
    Member Dragokas's Avatar
    Join Date
    Aug 2015
    Location
    Ukraine
    Posts
    740

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    hi, what am I doing wrong with Shell init? I assumed it's analogue.
    Code:
        'this works
        Dim objShell As Object
        Set objShell = CreateObject("Shell.Application")
        
        'this returning "Class does not support automation or does not support expected interface"
        Dim objShell As oleexp.Shell
        Set objShell = New oleexp.Shell
    Malware analyst, VirusNet developer, HiJackThis+ author || my CodeBank works

  23. #223

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    I'll have to look into it. I assumed it would work because it's an unmodified copy+paste of the source (which was already VB-compatible) I just put in to avoid conflicts.

    The original IShellDispatch it all inherits from... perhaps it should be specified as stdole.IDispatch instead of oleexp's unrestricted IDispatch which I think has priority (and why most objects inherit from stdole.IUnknown instead of oleexp.IUnknown; I know I've had some problems with that (see post 214 above).




    In other oleexp news, making it able to be compiled with midl (the first step to x64 versions) has been an unmitigated nightmare. midl force-includes oaidl.idl, which contains dozens of interfaces that need to redefined for VB compatibility, but midl doesn't allow redefinitions. Substituting a fake oaidl results in excluding *all* the built in types except for a few primitives (e.g. there is no LONG, you need typedef long LONG; and some of those are defined by absolute nightmares of C++ code that are nigh impossible to decipher. And then it looks like MS has put it deliberate efforts to prevent fake oaidls, because it rejects them if they're too small. After spending hours fixing that, midl has moved on to throwing obscure errors for which there is no solution I've found anywhere that won't cause serious compatibility problems with existing oleexp-using code.
    Last edited by fafalone; Aug 14th, 2022 at 12:44 PM.

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by fafalone View Post
    I'll have to look into it. I assumed it would work because it's an unmodified copy+paste of the source (which was already VB-compatible) I just put in to avoid conflicts.

    The original IShellDispatch it all inherits from... perhaps it should be specified as stdole.IDispatch instead of oleexp's unrestricted IDispatch which I think has priority (and why most objects inherit from stdole.IUnknown instead of oleexp.IUnknown; I know I've had some problems with that (see post 214 above).




    In other oleexp news, making it able to be compiled with midl (the first step to x64 versions) has been an unmitigated nightmare. midl force-includes oaidl.idl, which contains dozens of interfaces that need to redefined for VB compatibility, but midl doesn't allow redefinitions. Substituting a fake oaidl results in excluding *all* the built in types except for a few primitives (e.g. there is no LONG, you need typedef long LONG; and some of those are defined by absolute nightmares of C++ code that are nigh impossible to decipher. And then it looks like MS has put it deliberate efforts to prevent fake oaidls, because it rejects them if they're too small. After spending hours fixing that, midl has moved on to throwing obscure errors for which there is no solution I've found anywhere that won't cause serious compatibility problems with existing oleexp-using code.
    Btw, IDL is pretty simple language to parse and ICreateTypeLib interface is not so complicated too :-))

    cheers,
    </wqw>

  25. #225

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    C++ not so much, and cpp_quote makes that an issue. And the bigger problem is the way the midl compiler works. Do you have a solution besides all codebases depending on oleexp having to be updated to replace an unrestricted IUnknown with a new name?

    Like what's the simple solution I'm missing to this:

    midl\oleaut32.dll : error MIDL2020 : error generating type library : Could not add UUID, STDOLE2.TLB probably needs to be imported : IDispatch (0x800288C6)

    when importing that is literally the first line of code?

    Code:
    [
        uuid(f9015e81-caac-45c0-94e8-42b7da5d7558),
        version(5.03),
    	helpstring("OLEEXP - Modern Shell Interfaces for VB6, v5.03"),
    	lcid(0x0)
    ]
    library oleexp {
    
        // OLE Automation
        importlib("stdole2.tlb");
    Edit: And actually, renaming the oleexp versions breaks other things. For instance the unrestricted IDispatch can't inherit from the new IUnknownUnrestricted (even though that's how it worked with MKTYPLIB).

    interface IDispatchUnrestricted : IUnknownUnrestricted <- unresolved type declaration (yes, it's defined in a higher up file)

    interface IDispatchUnrestricted : oleexp.IUnknownUnrestricted <- syntax error : expecting { near "."

    If I forget about that and just let it inherit from stdole, I now arrive back at

    "midl\oleaut32.dll : error MIDL2020 : error generating type library : Could not add UUID, STDOLE2.TLB probably needs to be imported : IUnknown (0x800288C6)"

    *with no errors at all*, just a few warnings telling me optional params should be variants.

    This is simple for you? I hope so because I really need some help here.
    Last edited by fafalone; Aug 14th, 2022 at 06:19 PM.

  26. #226

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    FYI, if anyone wanted to pursue native 64bit development with code based on this project (or are just interested in migrating to IMO the future of the language), I have a successor project for twinBASIC that provides 64-bit compatible versions (using LongPtr so also still 32bit compatible), using the native language ability to define interfaces, as for the sake of my sanity I've given up with midl. tB will eventually support exporting TLBs, so there is a future expectation of VBA7 compatibility as well.

    [twinBASIC] tbShellLib - Shell Interface Library (x64-compatible successor to oleexp). Also on GitHub.

    It's compiled into a .twinpack file you can add as a reference much the same as a TLB. This format allows the add-on modules to be built in, since you can mix interface defs and regular code.

    There's not 100% coverage of everything in oleexp yet, as I have to double check a whole bunch of longs that aren't obviously/obviously not pointers against the SDK/MSDN (and unfamiliar types-- can be tricky, HREFTYPE-- you'd think that's a handle needing LongPtr right? Wrong.), and up until recently there was a lot of work in syntax conversion, but a great deal is already done, particularly things that are common, or I have a sample project about. The VBForums link above has tables showing which interfaces are available. For special sets, Task Manager, ListView, SpellCheck, Shell Automation (except dispinterface), CoreAudio, and PortableDevices are all 100% available (as far as what was in oleexp), but DirectShow, WIC, and NetCon have not been started. Importantly, for the kinds of shell extensions that still work on Windows 7+, I've also made those available so native x64 versions of those can be produced.

    The main incompatibilities are lack of coclass support, as a workaround, you can use CreateObject with the provided CLSID strings... e.g.
    Dim pExpBrowse As ExplorerBrowser
    Set pExpBrowse = New ExplorerBrowser

    would be replaced by
    Dim pExpBrowse As IExplorerBrowser = CreateObject(sCLSID_ExplorerBrowser)
    (all such CLSID strings are predefined for any implemented interface with a coclass)

    And also a lack of PreserveSig support... in the TLB, most things are defined as returning an HRESULT. VB drops this and turns it into a Sub. You can get around that by changing it to long; vb then recognizes it as a function and returns the HRESULT. This is not yet available in tB (for in-language defined interfaces, like coclasses it can consume TLBs with them). As a workaround, the HRESULT is available in Err.LastHResult:

    Dim pUnk As IUnknownUnrestricted
    Set pUnk = pShellItem
    hr = pUnk.QueryInterface(IID_IParentAndItem, upi)


    you would instead use

    pUnk.QueryInterface(IID_IParentAndItem, upi)
    hr = Err.LastHResult

  27. #227

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Project Updated

    Apparently I thought I posted 5.02 but didn't. Updated to 5.03/oleexpimp 2.12. This fixes a critical bug with oleexpimp.tlb causing error 32810; which I still don't fully understand as it indicates the defs didn't match, even though they were unchanged. It may be related to compiling against the wrong oleexp.tlb version. Numerous minor, obscure bug fixes, some dating back to olelib, were also applied as I went through everything for tbShellLib (see previous comment).

    This version now includes a LongPtr type usable in VB6, so projects using oleexp don't need my recent VB6LongPtr.tlb typelib to add it.

    Also added Implements-compatible versions of IPreviewHandler and related in oleexpimp.tlb, to implement a preview handler shell extension (demo coming soon).

    Full changelog:

    Code:
    (oleexp 5.03 - Released 20 October 2022)
    -Added IHWEventHandler2 and IDynamicHWHandler interfaces
    -(Bug fix) IShellTaskScheduler::CountTasks was incorrect and ::Status was missing.
    -Misc oscure bug fixes
    -(oleexpimp) Critical bug fix: Apparently, when oleeximp is compiled, MKTYPLIB favors the oleexp.tlb (imported) in SysWOW64 over the current directory. This resulted in a subtle mismatch causing 'Unexpected error (32810)' when implementing certain interfaces, even though the interface definitions themselves hadn't changed at all.
    
    (oleexp 5.02 - Released 13 September 2022)
    -Added missing oaidl interfaces ITypeMarshal, ITypeLibRegistration, ITypeLibRegistrationReader, ITypeChangeEvents, and ITypeMarshal.
    -ICategoryProvider.CanCategorizeOnSCID needs to provide return value when used as a consumer. The all-HRESULT version is now in oleexpimp.tlb for providers.
    -Added FILEOP_FLAGSEX with the FOFX_ values; this were already in the IFO_Flags enum with a custom prefix for displaying a combined enum for IFileOperation without showing them for SHFileOperation, but I thought they should also exist under the documented names.
    -A few misc bug fixes to rarely used interfaces.
    -Added a public LongPtr type; it's just an alias for Long but the idea is to enable writing code that can reused in 64bit VBA or twinBASIC.
    -(oleexpimp) Added Implements-compatible versions of IPreviewHandler, IInitializeWithStream, IInitializeWithItem, and IInitializeWithFile for use in creating preview handler shell extensions.

  28. #228

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Project Updated

    oleexp.tlb was missing some shell automation interfaces I could have sworn were in it; some were in oleexpimp.tlb, but some were in neither. Also added an expanded set of Windows Search interfaces, and some security page related interfaces.

    Code:
    (oleexp 5.1 - Released 05 November 2022)
    -Several interfaces from shell automation were missing or only located in oleexpimp
    -Added ISecurityInformation[2, 3, 4]/CreateSecurityPage API interfaces
    -Added Windows Search API interfaces

  29. #229
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    fafalone, there is a bug with CreateTypeLib declaration it should be:
    Code:
    HRESULT CreateTypeLib(
      SYSKIND        syskind,
      LPWSTR      szFile,
      ICreateTypeLib **ppctlib
    );
    the library definition:
    Code:
    HRESULT CreateTypeLib(
                    SYSKIND SYSKIND, 
                    LPWSTR* szFile, 
                    ICreateTypeLib** ppctlib);
    Also it would be good to change ICreateTypeLib::CreateTypeInfo to:
    Code:
    HRESULT _stdcall CreateTypeInfo(
                    [in] LPWSTR szName, 
                    [in] TYPEKIND tkind, 
                    [out, retval] ICreateTypeInfo** ppCTInfo);

  30. #230

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Thanks for letting me know. Should have an update out in the next day or two, was already finalizing 5.3 to match all the things I've added to the twinBASIC version (tbShellLib).

    I agree having it as a retval is better, but I'm hesitant to introduce breaking changes unless absolutely necessary.

  31. #231
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,319

    Red face Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    There's also a bug with the declaration of "HashData":

    Code:
    Sub HashData(pbData As Byte, cbData As Long, pbHash As Byte, cbHash As Long)
        ' Member of oleexp.shlwapi
    "pbData" and "pbHash" are both pointers, should be declared "As Long" or "As Any". "Byte" isn't working in any combination...

  32. #232

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    I believe it is declared properly;

    Code:
        [entry("HashData")]
        HRESULT HashData(
            [in] BYTE *pbData,
            [in] LONG cbData,
            [in] BYTE *pbHash,
            [in] LONG cbHash);
    They are both ByRef (pointers) and you would pass member 0 of an array of bytes of cbData and cbHash members.

    Code:
    Dim bData(100) As Byte
    Dim bHash(100) As Byte
    
    
    HashData bData(0), UBound(bData) + 1, bHash(0), UBound(bHash) + 1
    Or more to the point,

    Code:
    Dim bData(1) As Byte
    Dim bHash(3) As Byte
    Dim lHash As Long
    
    bData(0) = 12
    bData(1) = 24
    
    HashData bData(0), 2, bHash(0), 4
    CopyMemory lHash, bHash(0), 4
    Debug.Print "Hash=" & lHash
    prints Hash=1108899505
    Last edited by fafalone; Feb 4th, 2023 at 09:17 AM.

  33. #233

  34. #234
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,319

    Cool Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Indeed it's very convenient to have pointers declared "As Any". HashData produces variable-length hashes from 2 to 256 bytes (algorithm unknown but still very handy). I've made this custom function that can hash strings or byte arrays (user's choice), return a hexadecimal hash string and optionally store a 12-byte hash in a Decimal variant:

    Code:
    Private Function HashString(vInputData As Variant, Optional vHash As Variant, Optional lHashSize As Long = 12) As String
    Dim HashArray() As Byte, i As Long, byteInputData() As Byte
        ReDim HashArray(0 To lHashSize - 1)
        Select Case VarType(vInputData)
            Case vbString
                HashData CStr(vInputData), Len(vInputData), HashArray(0), lHashSize
            Case vbArray Or vbByte
                byteInputData = vInputData
                HashData VarPtr(byteInputData(0)), UBound(byteInputData) - LBound(byteInputData) + 1, HashArray(0), lHashSize
        End Select
        If Not IsMissing(vHash) Then
            vHash = CDec(0)
            Select Case lHashSize
                Case 1 To 8
                    CopyMemory ByVal VarPtr(vHash) + 8, HashArray(0), lHashSize
                Case 9 To 12
                    CopyMemory ByVal VarPtr(vHash) + 8, HashArray(0), 8
                    CopyMemory ByVal VarPtr(vHash) + 4, HashArray(8), lHashSize - 8
            End Select
        End If
        For i = UBound(HashArray) To LBound(HashArray) Step -1
            If HashArray(i) < 16 Then
                HashString = HashString & "0" & Hex$(HashArray(i))
            Else
                HashString = HashString & Hex$(HashArray(i))
            End If
        Next i
    End Function
    This is possible only with pointer declarations "As Any" (input data ByVal and output data ByRef):

    Code:
    Private Declare Function HashData Lib "shlwapi" (ByVal pbData As Any, ByVal cbData As Long, pbHash As Any, ByVal cbHash As Long) As Long
    To be honest I've become addicted to using typelibs for all API declarations. All my projects contain references to Bruce McKinney's Windows Unicode typelib, which is now very nicely complemented by your "OLEEXP". Of course there is still lots of room for improvement since there are still many missing useful declarations!

  35. #235

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Project Updated to Version 5.3

    Extensive additions to the new version. All of these additions have also been added to tbShellLib, the twinBASIC successor of this typelib, which supports both 32bit and 64bit usage (oleexp.tlb itself cannot be compiled for 64bit).

    Changelog:
    (oleexp v5.3 / oleexpimp v2.4 - Released 05 February 2023)
    • Integrated The trick's DirectWrite and Direct2D type libraries. The trick's dwvb_impl.tlb (DirectWrite for Implements) has been added to oleexpimp.tlb. Note: These had to be converted from MIDL to MKTYPLIB; this conversion may be imperfect. Please report any issues. You can build a version of oleexp without these by commenting out the #include statements for exp_dw.odl amd exp_d2d.odl in oleexp.odl.
    • New addon module mDirectX.bas contains IIDs for DirectWrite/Direct2D.
    • Added Sync Manager interfaces and coclasses (SyncMgr.h), including undocumented ITransferConfirmation/coclass TransferConfirmationUI.
    • Added windowless RichEdit related interfaces ITextServices, ITextServices2, ITextHost, ITextHost2.
    • Added interfaces IPersistSerializedPropStorage, IPersistSerializedPropStorage2, and IPropertySystemChangeNotify
    • Added missing propsys coclasses CLSID_InMemoryPropertyStore, CLSID_InMemoryPropertyStoreMarshalByValue, CLSID_PropertySystem
    • Added IShellUIHelper[2,3,4,5,6,7,8,9], IShellFavoritesNameSpace, IShellNameSpace, IScriptErrorList and related coclasses.
    • Added IDesktopWallpaper with coclass DesktopWallpaper
    • Added IAppVisibility and IAppVisibilityEvents
    • Added coclass AppStartupLink
    • Added IApplicationActivationManager with coclass ApplicationActivationManager
    • Added IContactManagerInterop, IAppActivationUIInfo, IHandlerActivationHost, IHandlerInfo, ILaunchSource*****erModelId, ILaunchTargetViewSizePreference, ILaunchSourceViewSizePreference, ILaunchTargetMonitor, IApplicationDesignModeSettings, IApplicationDesignModeSettings2, IExecuteCommandApplicationHostEnvironment, IPackageDebugSettings, IPackageDebugSettings2, IPackageExecutionStateChangeNotification, IDataObjectProvider, IDataTransferManagerInterop.
    • Added coclasses for above: PackageDebugSettings, SuspensionDependencyManager, ApplicationDesignModeSettings
    • Added interfaces IAccessibilityDockingService and IAccessibilityDockingServiceCallback with coclass AccessibilityDockingService
    • Added IListViewVista interface (Vista-only version of IListView)
    • Added interfaces IObjectWith*****erModelID, IObjectWithProgID, IObjectWithCancelEvent, IObjectWithSelection, and IObjectWithBackReferences.
    • Added interface IRemoteComputer
    • Added interface IUpdateIDList
    • Added Implements-compatible IFolderViewSettings to oleeximp.tlb.
    • Bug fix: CreateTypeLib definition incorrect (had LPWSTR* instead of LPWSTR)
    • (oleexmpimp) Bug fix: IFolderView2::SetViewProperty incorrectly had a ByVal VARIANT that should be ByRef.

  36. #236
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Something bad with ID2D1Geometry interface (its methods are counter from 0 like QueryInterface).
    It would be good to do:
    • ID2D1RenderTarget::DrawRectangle, ID2D1RenderTarget::DrawEllipse, ID2D1RenderTarget::DrawRoundedRectangle, ID2D1RenderTarget::DrawLine, ID2D1RenderTarget::DrawGeometry the strokeStyle parameter optional;
    • ID2D1RenderTarget::DrawLine strokeWidth parameter to do with 1 default value;
    • ID2D1RenderTarget::DrawBitmap paremeter opacity to do with default value 1 and interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR;
    • IWICImagingFactory::CreateBitmap to add [out, retval] attribute to the last parameter;
    • IWICBitmap::Lock change first parameter type to WICRect and add [out, retval] to the last parameter;
    • IWICBitmapLock::GetStride to add [out, retval] to the last parameter;
    • IWICImagingFactory::CreateStream to add [out, retval] to the last parameter;
    • IWICImagingFactory::CreateEncoder to change second parameter type to void**.

    It isn't all the notes just i can't compile all my examples due to this notes.

  37. #237

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Unfortunately oleexp cannot be compiled with midl (I've spent countless hours trying to work around the redefinition issues by substituting blank oaidl.idl and manually defining every derived type (e.g. typedef int long and eventually reached a point where midl refused to compile but wouldn't give any reason for the failure, searching was a dead end) and MKTYPLIB does not support optional or defaultvalue attributes, at least in enough scenarios I replaced them all after the first dozen errors. I checked most of the ones you mentioned and they all end in 'invalid attribute' errors if I add them back in.

    I believe the issue with ID2D1Geometry is due to the ID2D1Resource interface it inherits from being interpreted as inheriting from the unrestricted IUnknown in oleexp.tlb instead of stdole.IUnknown... this should not cause inheritance to fail, but it looks like it did. I've posted a new version that should correct this issue.

  38. #238
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by fafalone View Post
    Unfortunately oleexp cannot be compiled with midl (I've spent countless hours trying to work around the redefinition issues by substituting blank oaidl.idl and manually defining every derived type (e.g. typedef int long and eventually reached a point where midl refused to compile but wouldn't give any reason for the failure, searching was a dead end) and MKTYPLIB does not support optional or defaultvalue attributes, at least in enough scenarios I replaced them all after the first dozen errors. I checked most of the ones you mentioned and they all end in 'invalid attribute' errors if I add them back in..
    The time to make our own typelib generation tool ))

  39. #239
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,671

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    Quote Originally Posted by fafalone View Post
    I've posted a new version that should correct this issue.
    Seems doesn't work yet. I made small project that demonstrates the issue:
    Code:
    Option Explicit
    
    Private Declare Sub PutMem4 Lib "msvbvm60" ( _
                        ByRef pDst As Any, _
                        ByVal pSrc As Long)
    
    Sub Main()
        Dim lVtbl(4)    As Long
        Dim pVtbl       As Long
        Dim cObj        As ID2D1Geometry
        
        lVtbl(0) = FAR_PROC(AddressOf m_QueryInterface)
        lVtbl(1) = FAR_PROC(AddressOf m_AddRef)
        lVtbl(2) = FAR_PROC(AddressOf m_Release)
        lVtbl(3) = FAR_PROC(AddressOf m_GetFactory)
        lVtbl(4) = FAR_PROC(AddressOf m_GetBounds)
        
        pVtbl = VarPtr(lVtbl(0))
        
        PutMem4 cObj, VarPtr(pVtbl)
        
        cObj.GetBounds ByVal 0&
        
    End Sub
    
    Private Function FAR_PROC( _
                     ByVal pfn As Long) As Long
        FAR_PROC = pfn
    End Function
    
    Private Function m_QueryInterface( _
                     ByVal pObj As Long, _
                     ByVal pIID As Long, _
                     ByRef pRet As Long) As Long
        Debug.Print "QueryInterface"
    End Function
    Private Function m_AddRef( _
                     ByVal pObj As Long) As Long
        Debug.Print "AddRef"
    End Function
    Private Function m_Release( _
                     ByVal pObj As Long) As Long
        Debug.Print "Release"
    End Function
    
    Private Function m_GetFactory( _
                     ByVal pObj As Long) As Long
        Debug.Print "GetFactory"
    End Function
    
    Private Function m_GetBounds( _
                     ByVal pObj As Long, _
                     ByVal pTransform As Long, _
                     ByRef pRet As Long) As Long
        Debug.Print "GetBounds"
    End Function
    It shows QueryInterface instead GetBounds.

  40. #240

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

    Re: [VB6] Modern Shell Interface Type Library - oleexp.tlb

    The previous version showed AddRef/QI/Release in the object browser confirming the problem, but the new version I posted does not... the IDL source seemed to confirm it was fixed:

    Code:
        [
          odl,
          uuid(2CD906A1-12E2-11DC-9FED-001143A055F9),
          helpstring("Represents a geometry resource and defines a set of helper methods for manipulating and measuring geometric shapes. Interfaces that inherit from ID2D1Geometry define specific shapes.")
        ]
        interface ID2D1Geometry : ID2D1Resource {
            [helpstring("Compare how one geometry intersects or contains another geometry.")]
            HRESULT _stdcall CompareWithGeometry(
                            [in] ID2D1Geometry* inputGeometry, 
                            [in, out] void* inputGeometryTransform, 
                            [in] single flatteningTolerance, 
                            [out, retval] D2D1_GEOMETRY_RELATION* relation);
            [helpstring("Converts a geometry to a simplified geometry that has arcs and quadratic beziers removed.")]
            HRESULT _stdcall Simplify(
                            [in] D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, 
                            [in, out] void* worldTransform, 
                            [in] single flatteningTolerance, 
                            [in] ID2D1SimplifiedGeometrySink* geometrySink);
            [helpstring("Tessellates a geometry into triangles.")]
            HRESULT _stdcall Tessellate(
                            [in, out] void* worldTransform, 
                            [in] single flatteningTolerance, 
                            [in] ID2D1TessellationSink* tessellationSink);
            [helpstring("Performs a combine operation between the two geometries to produce a resulting geometry.")]
            HRESULT _stdcall CombineWithGeometry(
                            [in] ID2D1Geometry* inputGeometry, 
                            [in] D2D1_COMBINE_MODE combineMode, 
                            [in, out] void* inputGeometryTransform, 
                            [in] single flatteningTolerance, 
                            [in] ID2D1SimplifiedGeometrySink* geometrySink);
            [helpstring("Computes the outline of the geometry. The result is written back into a simplified geometry sink.")]
            HRESULT _stdcall Outline(
                            [in, out] void* worldTransform, 
                            [in] single flatteningTolerance, 
                            [in] ID2D1SimplifiedGeometrySink* geometrySink);
            [helpstring("Computes the area of the geometry.")]
            HRESULT _stdcall ComputeArea(
                            [in, out] void* worldTransform, 
                            [in] single flatteningTolerance, 
                            [out, retval] single* area);
            [helpstring("Computes the length of the geometry.")]
            HRESULT _stdcall ComputeLength(
                            [in, out] void* worldTransform, 
                            [in] single flatteningTolerance, 
                            [out, retval] single* Length);
            [helpstring("Computes the point and tangent a given distance along the path.")]
            HRESULT _stdcall ComputePointAtLength(
                            [in] single Length, 
                            [in, out] void* worldTransform, 
                            [in] single flatteningTolerance, 
                            [in, out] void* POINT, 
                            [in, out] void* unitTangentVector);
            [helpstring("Get the geometry and widen it as well as apply an optional pen style.")]
            HRESULT _stdcall Widen(
                            [in] single strokeWidth, 
                            [in, out] void* strokeStyle, 
                            [in, out] void* worldTransform, 
                            [in] single flatteningTolerance, 
                            [in] ID2D1SimplifiedGeometrySink* geometrySink);
        };
    
        [
          odl,
          uuid(2CD90691-12E2-11DC-9FED-001143A055F9),
          helpstring("Represents a Direct2D drawing resource.")
        ]
        interface ID2D1Resource : IUnknown {
            [helpstring("Retrieve the factory associated with this resource.")]
            void _stdcall GetFactory([out] ID2D1Factory** factory);
        };
    which matches the source in exp_d2d.odl:

    Code:
    [
        odl,
        uuid(2CD906A1-12E2-11DC-9FED-001143A055F9),
        helpstring("Represents a geometry resource and defines a set of helper methods for manipulating and measuring geometric shapes. Interfaces that inherit from ID2D1Geometry define specific shapes.")
    ]
    interface ID2D1Geometry : ID2D1Resource {
        [helpstring("Retrieve the bounds of the geometry, with an optional applied transform.")]
        HRESULT _stdcall GetBounds(
            [in, out] void* worldTransform,
            [out, retval] D2D1_RECT_F* bounds);
        [helpstring("Get the bounds of the corresponding geometry after it has been widened or have an optional pen style applied.")]
        HRESULT _stdcall GetWidenedBounds(
            [in] single strokeWidth,
            [in] ID2D1StrokeStyle* strokeStyle,
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [out, retval] D2D1_RECT_F* bounds);
        [helpstring("Checks to see whether the corresponding penned and widened geometry contains the given point.")]
        HRESULT _stdcall StrokeContainsPoint(
            [in] single pointX,
            [in] single pointY,
            [in] single strokeWidth,
            [in] ID2D1StrokeStyle* strokeStyle,
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [out, retval] long* contains);
        [helpstring("Test whether the given fill of this geometry would contain this point.")]
        HRESULT _stdcall FillContainsPoint(
            [in] single pointX,
            [in] single pointY,
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [out, retval] long* contains);
        [helpstring("Compare how one geometry intersects or contains another geometry.")]
        HRESULT _stdcall CompareWithGeometry(
            [in] ID2D1Geometry* inputGeometry,
            [in, out] void* inputGeometryTransform,
            [in] single flatteningTolerance,
            [out, retval] D2D1_GEOMETRY_RELATION* relation);
        [helpstring("Converts a geometry to a simplified geometry that has arcs and quadratic beziers removed.")]
        HRESULT _stdcall Simplify(
            [in] D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption,
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [in] ID2D1SimplifiedGeometrySink* geometrySink);
        [helpstring("Tessellates a geometry into triangles.")]
        HRESULT _stdcall Tessellate(
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [in] ID2D1TessellationSink* tessellationSink);
        [helpstring("Performs a combine operation between the two geometries to produce a resulting geometry.")]
        HRESULT _stdcall CombineWithGeometry(
            [in] ID2D1Geometry* inputGeometry,
            [in] D2D1_COMBINE_MODE combineMode,
            [in, out] void* inputGeometryTransform,
            [in] single flatteningTolerance,
            [in] ID2D1SimplifiedGeometrySink* geometrySink);
        [helpstring("Computes the outline of the geometry. The result is written back into a simplified geometry sink.")]
        HRESULT _stdcall Outline(
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [in] ID2D1SimplifiedGeometrySink* geometrySink);
        [helpstring("Computes the area of the geometry.")]
        HRESULT _stdcall ComputeArea(
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [out, retval] single* area);
        [helpstring("Computes the length of the geometry.")]
        HRESULT _stdcall ComputeLength(
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [out, retval] single* length);
        [helpstring("Computes the point and tangent a given distance along the path.")]
        HRESULT _stdcall ComputePointAtLength(
            [in] single length,
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [in, out] void* point,
            [in, out] void* unitTangentVector);
        [helpstring("Get the geometry and widen it as well as apply an optional pen style.")]
        HRESULT _stdcall Widen(
            [in] single strokeWidth,
            [in, out] void* strokeStyle,
            [in, out] void* worldTransform,
            [in] single flatteningTolerance,
            [in] ID2D1SimplifiedGeometrySink* geometrySink);
    };
    
    [
        odl,
        uuid(2CD90691-12E2-11DC-9FED-001143A055F9),
        helpstring("Represents a Direct2D drawing resource.")
    ]
    interface ID2D1Resource : stdole.IUnknown {
        [helpstring("Retrieve the factory associated with this resource.")]
        void _stdcall GetFactory([out] ID2D1Factory** factory);
    };

    Unfortunately while I can verify the problem exists I don't know how to resolve this when the IDL source is correct... any ideas?



    Quote Originally Posted by The trick View Post
    The time to make our own typelib generation tool ))
    twinBASIC is going to be able to generate typelibs soon... it already generates them internally from active-x DLLs. The end result wasn't VB compatible 6 months ago, but now that tB-generated active-x controls can be used in VB6, that is likely to have changed. There's a bug preventing me from building tbShellLib into a DLL to extract the typelib manually but that should be fixed in the next day or too, wayne was working on it.

    If it works, tbShellLib will replace oleexp for vb6 too.

    In fact, running your code on the tbShellLib version prints GetBounds. But twinBASIC also prints QI when using oleexp suggesting the problem does lie in the TLB.
    Last edited by fafalone; Feb 5th, 2023 at 01:29 PM.

Page 6 of 9 FirstFirst ... 3456789 LastLast

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