Page 1 of 9 1234 ... LastLast
Results 1 to 40 of 358

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

  1. #1

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

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

    OLEEXP : Modern Shell Interfaces
    Current Version: 6.4 (Released 10 August 2023)
    Go to: Download | Notes | Changelog | New Interface List, or original olelib list | Related Projects

    About Project


    oleexp.tlb is a type library containing a vast collection of Windows shell interfaces and interfaces for a number of related features, forking an older project in order to bring in the expansive set of new interfaces introduced in Windows Vista, and including the smaller number introduced in Windows 7 through 10. It also includes virtually all structures, types, and enums used by these interfaces, and a limited set of related APIs. While some of the interfaces may be present in system libraries, these, and the original versions for everything from the SDK, often use variable types that are incompatible with VB5/6; all interfaces have been reviewed and modified to use variable types that ensure compatibility with VB5 and VB6.

    History

    oleexp is based on Edanmo's olelib, forked and expanded. It's a very strong foundation for any desktop application.
    Back in the day, E. Morcillo released the very comprehensive interface library olelib.tlb (Edanmo's OLE interfaces & functions). It contained a massive number of interfaces, enums, structs, etc. But after a point it was no longer updated and thus doesn't have any interfaces from Windows Vista or Windows 7. So I set out to bring these interfaces to VB, and quickly realized that so much would have to be duplicated and would then be conflicting, that the only sensible way to approach this would be to fork and expand olelib, particularly since anyone using oleexp would almost certainly be using olelib.

    If an interface isn't included that you would like to use, or you find a bug, let me know in this thread, or through a private message or e-mail (fafalone at gmail).

    This project is completely free to use and modify as you see fit, for any purpose, including commercial. All that's requested is an acknowledgement and if you're distributing a modified version publicly, to change the project GUID to avoid conflicts, found in oleexp.odl.

    Requirements and Installation / Setup


    Requirements
    oleexp can be used with any version of Windows. If you attempt to call an interface/API that is not present on the current OS version, an error will occur, but the presence of those definitions in the library do not effect the usage of any other interfaces/APIs.
    No other files are required. You do not need to add oleexpimp or mimelib unless you specifically want to use them. All of the addon modules are optional, but mIID is strongly recommended; it saves a ton of time by allowing direct IID_ / FOLDERID_ / etc usage without having to convert a string to a GUID.

    Installing oleexp
    oleexp.tlb (and oleexmpimp.tlb/mimelib.tlb if you're using them) should be placed in a permanent, common folder all your projects can access-- typically SysWow64 (or System32 on a 32-bit Windows install). You can register it manually, but I've never had trouble with the registration VB6 performs when you add it for the first time.
    IMPORTANT: oleexp is a common file, and you should only have one copy installed. Do not place multiple copies in the folders of projects that use it. Also, it's a direct replacement for olelib; a project should not have both.

    The add-on modules are updated too, so those and any other files you're keeping, should go in a common directory for your VB projects, not the system folder. E.g. all the sample projects point at ..\tl_ole by default, so if you keep your projects in C:\vb\Prj1 Prj2 etc, a good spot would be C:\vb\tl_ole.

    Setting up oleexp in your project
    oleexp.tlb is added via Project->References. As with any typelib, a sample project may reference a different location, if so, update the location if the References window says it's 'MISSING:'
    NOTE: Like all TLBs, oleexp is a dependency only for the IDE. Once your project is compiled, the TLB is no longer used. It does not need to be present on end user machines. See the 'File Size' section in post #2 for additional details.

    Upgrading from olelib
    If you're upgrading an existing project that uses the original olelib, the vast majority of those interfaces have not been modified, but a few have had minor changes to use different variable types. Explicit declares can be changed via Replace; just replace "As olelib.vartype" (or oleexp3.vartype if upgrading from oleexp 3.x) with "As oleexp.vartype". If you get an error or something has stopped working, check the variable type and if it's ByVal or ByRef.

    Sample Projects (56)


    NEW! [VB6, twinBASIC] DirectComposition Effects Demo - Shows a basic example of using DirectComposition/Direct2D in VB6 (and twinBASIC with 64bit compatibility!)

    NEW! [VB6/Win7+] Using the Windows UI Ribbon Framework - Take advantage of the fancy Ribbon seen in Explorer, Wordpad, and Paint (and very similar to Office) in your app. Brings the basic version of my twinBASIC series to VB6.
    IUIRibbonFramework, IUIApplication, IUISimplePropertySet, IUICommandHandler

    [VB6/Win8+] Displaying emojis with color - Using oleexp's recently added DirectX interfaces to render text with the emojis in color (where supported by the font).

    [VB6/twinBASIC] Code snippet: Close Explorer window by path - A simpler example of using IShellWindows to enumerate all open Explorer windows.

    [VB6] Code snippet: Run unelevated app from elevated app - By making Explorer do it.

    [VB6] Using IShellWindows to register for SHOpenFolderAndSelectItems - Register a path as a shell window, then apps using the API will pass the full names of files to be opened in it.
    IShellWindows, IServiceProvider, IWebBrowserApp, IShellView

    UPDATED 18 Jun 2022 [VB6] ucShellBrowse: A modern replacement for Drive/FileList w/ extensive features - A highly customizable UserControl for browsing the file system with all the modern shell features; customize from a simple Directory List / FileList control in VB through a full-fledged Explorer-like window, and everything in between.
    First use: IColumnManager, ICategoryProvider, ICategorizer, IPropertyStoreCapabilities, IPropertyEnumType, IPropertyEnumTypeList; dozens of others previously demonstrated.

    UPDATED 25 Jan 2022 [VB6] ucShellTree: Full-featured Shell Tree UserControl - A TreeView for navigating the shell like ucShellBrowse.

    [VB6, Vista+] Core Audio - Peak Meter - Check whether or not audio is playing on the default rendering device, and display the most recent peak volume level in a meter.
    IAudioMeterInfo, IMMDevice, IMMDeviceEnumerator

    [VB6] Write MP3 Album Art and other tags using the Windows Property System - You can use the Property Store interfaces to add cover art, and all the traditional tags, to your MP3 files.
    IPropertyStore, IShellItem2

    [VB6] Intro to the Windows Imaging Component (WIC): Scale and convert to JPG or PNG - Open a variety of image types then optionally scale and convert to PNG or JPG.
    IWICImagingFactory, IWICBitmapDecoder, IWICBitmapFrameDecode, IWICFormatConverter, IWICBitmapScaler, IWICBitmapSource, IWICBitmapEncoder, IWICStream, IWICBitmapFrameEncode, IPropertyBag2

    [VB6] Using Structured Queries to conduct a Windows Search by any property - Advanced Windows-provided file searching technique
    ISearchFolderItemFactory, IConditionFactory2, ICondition, IObjectCollection, IShellLibrary, IShellItemArray

    [VB6] Adding Custom Tasks and Items to the Jump List (Taskbar Right-click) - Shows how to use ICustomDestinationList to add items to the Jump List.
    ICustomDestinationList, IObjectCollection, IObjectArray, IShellLink, IPropertyStore

    [VB6] Virtual File Drag Drop - Virtual files are created from data that's only read when dropped, instead of beforehand. Uses some neat IDataObject tricks and also supports multiple files at once.
    IDataObject, IStream

    [VB6] Display search results or other custom file set in IExplorerBrowser - Display a set of files from anywhere in the system as if they were in one folder.
    IResultsFolder, IExplorerBrowser, IColumnManager

    [VB6, Win8+] Using the system spellchecker: Add spellcheck with only a few lines - A demo of Win8's new spellchecking feature.
    ISpellChecker, ISpellCheckerFactory, ISpellingError, IEnumSpellingErrors, IEnumString

    [VB6] Class to show a standard Explorer-style progress window - Use the IProgressDialog interface to show progress with an Explorer-style popup.
    IProgressDialog

    [VB6, Vista+] Enumerate, explore, and change all file associations - Use IQueryAssociations to get information about all registered file types.
    IQueryAssociations, IAssocHandler, IEnumAssocHandlers, IOpenControlPanel

    [VB6, Vista] List the Recycle Bin location(s) on a drive - Use folder class IDs to find the official folders.
    IPersist, IKnownFolderManager, IKnownFolder, IEnumShellItems, IShellItem

    [VB6] Dynamic Resize: Use a slider to change ListView icon/thumbnail size on the fly - Smooth and fast resizing without any quality loss.
    IImageList2, IShellItemImageFactory

    [VB6] Exclude file types from Open/Save Dialogs ('all except...'): IShellItemFilter - Instead of selecting which files to show, select which ones to hide.
    IShellItemFilter, IFileOpenDialog, IShellItem

    [VB6, Vista+] Finding and deleting invalid shortcuts with IShellLink and IShellItem Find and remove bad links with IShellLinkW and a new recursive file enumeration/search method using only IShellItem and IEnumShellItems.
    IShellLinkW, IPersistFile, IEnumShellItems, IShellItem, IFileOpenDialog

    [VB6, Vista+] Core Audio - Monitor for disabled/active, default, and property changes - Shows how to use IMMNotificationClient to be notified when audio hardware is added/removed, enabled/disabled, set as default, or had its properties change
    IMMDeviceEnumerator, IMMDevice, IMMNotificationClient, IPropertyStore

    [VB6, Vista+] Core Audio - Change the system default audio device - Uses an undocumented interface to change this much sought-after setting through code.
    IPolicyConfig, IMMDeviceEnumerator, IMMDeviceCollection, IMMDevice

    [VB6] SHBrowseForFolder - Custom filter for shown items: BFFM_IUNKNOWN/IFolderFilter - Shows what to do to actually implement a filter using that weird BFFM_IUNKNOWN message you've seen.
    IFolderFilter, IUnknown, IShellFolder, IShellItem

    [VB6, Vista+] Add the Windows Send To submenu to your popup menu - Uses shell interfaces to implement the Send To menu exactly as Explorer does.
    IShellItem, IShellItemImageFactory, IDataObject, IDropTarget, IEnumShellItems, IShellItemArray, IFileOpenDialog

    [VB6, Vista+] Direct access to the system-wide image thumbnail cache - Uses the LocalThumbnailCache object for advanced access.
    IThumbnailCache, ISharedBitmap, IThumbnailProvider, IShellItem

    [VB6, Vista+] Remember Open/Save state per-dialog instead of per-app (IFileDialog) - The .SetClientGuid method enables automatic saved states per-dialog.
    IFileDialog/IFileOpenDialog, IShellItem

    [VB6] Using IAutoComplete / IAutoComplete2 including autocomplete with custom lists - Shows using autocomplete and IEnumString with oleexp interfaces. Supports custom lists and multiple sources.
    IAutoComplete, IAutoComplete2, IAutoCompleteDropDown, IEnumString, IACList, IACList2, IObjMgr

    [VB6, Vista+] Advanced Thumbnail ListView: Icons, images, videos, framed small images Uses shell interfaces and GDI+ to make a top-tier thumbnail view that handles every type of file.
    IShellItemImageFactory, IExtractImage, IShellItem[2], IShellFolder, IShellIcon, IShellIconOverlay, IParentAndItem, IEnumShellItems, IImageList

    [VB6] Drag drop any format to other apps without custom IDataObject - Drag and drop CF_TEXT, CFSTR_PNG, and more without having to implement IDataObject. Now with sample project.
    IDataObject, IDragSourceHelper2

    [VB6] Register any control as a drop target that shows the Explorer drag image - With IDropTargetHelper, any XP+ app can now show the same drag image as any modern program.
    IDropTarget, IDropTargetHelper

    [VB6, Vista+] Core Audio Basics - Demonstrates the new Core Audio interfaces added in v3.6
    IMMDeviceEnumerator, IMMDeviceCollection, IMMDevice, IAudioEndpointVolume, IAudioEndpointVolumeCallback, ISimpleAudioVolume, IAudioSessionManager2, IAudioSessionControl, IAudioSessionControl2

    [VB6] Code Snippet: View shortcut path w/variables unexpanded: IShellLinkDataList, and
    [VB6] Code Snippet: Make your shortcuts request elevation with IShellLinkDataList - An introduction to the advanced flags and data blocks hidden behind IShellLink.
    IShellLink (IShellLinkW), IShellLinkDataList, IPersistFile

    [VB6] Code Snippet: Get file overlay (e.g. shortcut arrow), inc. customs like DropBox - There's way more to system icon overlays than shortcuts and shares, now you can easily find the other Windows ones and custom ones.
    IShellIconOverlay, IShellFolder

    [VB6] Get extended details about Explorer windows by getting their IFolderView - Get that interface and many more for highly detailed information about open Explorer windows and their items. Changing window settings and selections is also possible.
    IShellWindows, IFolderView, IFolderView2, IShellBrowser, IShellView, IEnumVARIANT, IShellItem, IDispatch

    [VB6, Vista+] List all file properties, locale/unit formatted, by modern PROPERTYKEY - Demonstrates use of the modern PROPERTYKEY/IPropertyStore system, with PROPVARIANT handling made simple. Update includes a new sample project attached displaying a ListView of properties and using IPropertySystem to create a property display management technique.
    See Also: A compact function to retrieve any property by name, which loads a property store directly by file name without IShellItem, and then displays a formatted string for anyone property name.
    IPropertyStore, IPropertyDescription, IPropertySystem, IShellItem2, IShellFolder2

    [VB6, Vista+] SHBrowseForFolder: Handling a choice of Libraries (or Library), Computer, or Network - Some objects aren't valid folders themselves, but contain valid folders, and the user probably expects those objects to be treated like any other parent folder. Shell interfaces to the rescue!
    IShellLibrary, IShellItem, IShellItemArray, IEnumShellItems

    [VB6] Easy image disp/edit; scale/rotate, show animated gifs, conv2JPG, +more; No GDI+/DLL - Shows off oleexp 3.1's new image interfaces, which make dealing with images and imagelists far easier. Scale, rotate, show animated GIFs, transcode to JPG/BMP, get image properties, resize an imagelist, all with mostly single-line calls.
    IShellImageData, IShellImageDataFactory, ITranscodeImage, IImageList, IImageList2, IShellItem, IFileOpenDialog, IShellItem, IShellItemArray, IEnumShellItems, IPersistFile, IExtractImage.

    [VB6] Code Snippet: Get/set/del file zone identifier (Run file from internet? source) - How does Explorer know to ask? Get the basics of Alternative Data Streams and see how to change this one extremely easily thanks to IZoneIdentifier and its coclass PersistentZoneIdentifier.
    IZoneIdentifier, IInternetSecurityManager

    [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based, and
    [VB6] Create a ZIP file without any DLL depends using IStorage and IDropTarget - Uses IStorage and IStream for basic zip functionality. Creating a Zip uses a neat trick with IDropTarget.
    IStorage, IStream, IEnumSTATSTG, IShellFolder, IDropTarget

    [Vista+] Code Snippet: Get and set the Rating (stars) of a file - Shows a practical example of using IShellItem/IPropertyStore to read/write properties with very few lines of code.
    IPropertyStore, IShellItem2

    [VB6] IPreviewHandler: Show non-image file previews from any reg'd preview handler - Don't limit your previews to just images anymore; documents, music, videos, PDFs, Powerpoint/Excel, and lots more have existing or available preview handlers you can access with IPreviewHandler.
    IPreviewHandler, IInitializeWithFile, IInitializeWithStream, IInitializeWithItem, IUnknown

    [VB6, Vista+] Code snippet: KnownFolders made easy with IKnownFolderManager - The KnownFolderManager coclass (a default implementation you can get with the New keyword) greatly simplifies all aspects of working with special folders, their locations, properties, names, and identifiers.
    IKnownFolderManager, IKnownFolder, IShellItem, IShellItemImageFactory

    [VB6, Vista+] Host Windows Explorer on your form: navigation tree and/or folder - Use IExplorerBrowser and INamespaceTreeControl as a simple way (they have default implementations-- you don't even need a ListView, the whole thing is automatically created right on your form) to add a full-fledged Explorer view to your form.
    IExplorerBrowser, IExplorerBrowserEvents, INamespaceTreeControl, INamespaceTreeControlEvents, IDataObject, IShellView, IShellItem

    [VB6] API File Drag from multiple paths w/o native OLE or dragsource, SHDoDragDrop - Create an IDataObject with SHCreateDataObject/SHCreateFileDataObject to initiate a drag operation with very low-level access to all elements of the drag operation. Later comments in the thread show the use of DragDropHelper coclass (IDragSourceHelper, IDragSourceHelper2).
    IDataObject, IDragSourceHelper2

    [VB6] Enhanced Tray Message w/ custom ToolTip icon and feedback, w/o ShellNotifyIcon - Uses the new IUserNotification2 interface (Vista+)
    IUserNotification2

    [VB6] List files by level from a folder in natural sorted order using INamespaceWalk - A unique way of listing files with it's own Windows-managed progress dialog.
    INamespaceWalk, INamespaceWalkCallback, IShellFolder

    [VB6] List/Execute File Handlers: IAssocHandler and IAssocHandlerInvoker (Vista+) - Get names, paths, and icons for all of a file type's handlers, and use it to show your own Open With menu.
    IAssocHandler, IAssocHandlerInvoker, IEnumAssocHandlers

    [VB6] Win7 Taskbar Features with ITaskbarList3 (overlay, progress in taskbar, etc) - Windows 7 allows you to add an overlay icon, turn the taskbar item into a progress bar, add buttons below the thumbnail, and more. See how to use the new ITaskbarList3 / 4 interface in VB with the TaskbarList object from oleexp.
    ITaskbarList4

    [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prompts - Also shows usage of IShellItem; now updated to show the Advise method in action- using a class module to implement an interface to get progress feedback.
    IFileOperation, IFileOperationProgressSink, IShellItem, IShellItemArray, IShellFolder

    [VB6] Using the new IFileDialog interface for customizable Open/Save (TLB, Vista+) - Has the benefit of allowing easy access to events from the dialog, as well as making it very easy to add your own controls.
    IFileDialog2, IFileDialogCustomize, IFileOpenDialog, IFileSaveDialog, IFileDialogEvents, IShellItem, IShellItemArray, IEnumShellItems

    [VB6] Working with Libraries (Win7+) - Uses the IShellLibrary interface to get all folders in a library, add more, get the default save location, get the icon, and even create a new library. Also shows the use of IEnumShellItems and IShellItemArray.
    IShellLibrary, IShellItem, IShellItemArray, IEnumShellItems

    ...more to come soon!


    64bit Support for twinBASIC



    oleexp now has a 64bit-compatible successor for use in twinBASIC: tbShellLib. It includes all interfaces, enums, types, and APIs from oleexp except a small bit of legacy Win9x stuff unusable on XP+. The twinpack format also allows all of the add-on modules to be built in. You can add this to your project via Settings->COM Type Library/ActiveX References->TWINPACK Packages->twinBASIC Shell Library (it's been uploaded to the online package repo, so no external download is needed).

    Eventually, twinBASIC will support exporting TLBs, and when that happens it will also be available for VBA7 64bit.

    [twinBASIC] tbShellLib - Shell Interface Library (x64-compatible successor to oleexp) :: VB Forums Project Thread :: Project GitHub Repository


    Add-Ons

    Add-ons are optional modules full of definitions related to a particular feature set, like a header #include in other languages. Like adding mPKEY.bas is exactly the same as '#include propkey.h' in a C/C++ project. Only the items you actually use get compiled into the .exe, so don't worry about a bloated executable containing unused GUIDs.

    mIID.bas (UPDATED with 6.4) - All IID_/BHID_/FOLDERID_/SID_ values, usable directly without CLSIDFromString, e.g. SHCreateItemFromIDList(pidl, IID_IShellItem, psi), never have to worry about converting a string. Strongly recommended for all oleexp projects.

    mPKEY.bas (UPDATED with 6.4) - All PROPERTYKEY's from propkey.h, directly usable.

    mCoreAudio.bas / mDirectShow.bas / mPortableDevices.bas / mWIC.bas / mDirectX.bas / mSpeech.bas / mUIA.bas - IIDs and functions used exclusively by those particular features.




    Included in the ZIP

    oleexp64.zip
    • oleexp.tlb v6.4
    • All addon modules
    • oleexpimp.tlb v2.6 - Expanded fork of olelib2.tlb, replaces olelib2.tlb; replace all 'olelib2.<type>' with 'oleexpimp.<type>'
    • Full changelog
    oleexp64-src.zip
    • Source for TLBs
    • Originals of modified olelib files
    • Compile shortcuts
    • mimelib.tlb - Original compiled against oleexp; won't work with it otherwise.
    • oleexpwmp.tlb - Remove wmp.dll depend from main TLB.
    Attached Files Attached Files
    Last edited by fafalone; Aug 20th, 2023 at 07:29 AM. Reason: New version

  2. #2

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

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

    (cont. from above due to post length limit)
    Known Issue
    NOTE: The latest releases (4.7+) inadvertently had a new GUID from 4.6, when it was meant to have the same. It's recommended that you follow the major version upgrade procedure if you're upgrading from v4.6 or earlier:
    Upgrading From Earlier Versions


    Versions 1.x and 2.x have the same typelib name as 4.x+ (oleexp) but a different GUID. To upgrade from these versions, you don't have to change anything in your code (except for a few interfaces that have updated definitions), just update the reference.
    1) Before opening any project, delete the old oleexp.tlb file, or oleexp3.tlb if upgrading from 3.x, assuming you correctly have it in a common location like SysWOW64. If you're updating the location you can ignore the old one. Copy the latest version of oleexp.tlb to the common location. Remember, oleexp.tlb is a common file, all projects must reference a single copy, they must not have their own.
    2) Now, open any project still referring to the old version. If you get a message about the missing TLB, just ignore it and close the dialog.
    3) Go to the Project->References... menu item. Uncheck the reference to oleexp.tlb, whether or not it says 'MISSING:'.
    4) Click OK, then reopen the same dialog.
    5) Click the Browse... button and choose the new version of oleexp.tlb. Click OK.
    -
    6) (Only if upgrading from version 3.x) Run a search and replace on your code to replace all instances of oleexp3 with oleexp

    And that's it! You're good to go.




    (oleexp 6.4 - Released 10 August 2023)
    -Added Sensor API and Location API. Sensor pkeys added to mPKEY.
    -Added IStorageProviderHandler
    -Added DirectSound8, courtesy of The trick/mossSOFT DSVBLib
    -Added Distributed Transaction Manager basic interfaces
    -Bug fix: Ribbon interfaces were not Implements-compatible and one used a custom UDT instead of a Variant.


    (oleexp 6.3 - Released 09 June 2023)
    -Added active scripting interfaces (ActivScp.h)
    -Completed Core Audio interfaces
    -Added Package Manager interfaces from msopc.idl/coclass OpcFactory
    -Added DirectComposition Presentation Manager interfaces.
    -Added some missing base OLE/COM interfaces: IDataAdviseHolder, IOleAdviseHolder, IDropSourceNotify, IEnterpriseDropTarget, IContinue, IQuickActivate, IAdviseSinkEx, IPointerInactive, IOleUndoManager, IEnumOleUndoUnits, IOleParentUndoUnit, IOleUndoUnit, IViewObjectEx, IOleInPlaceSiteWindowless, IOleInPlaceSiteEx, IOleInPlaceObjectWindowless.
    -ribbon.odl, UI Ribbon interfaces, had been sitting around in the source folder unfinished forever; it's now complete and added (source file renamed exp_ribbon.odl).
    -Added IContextCallback interface with coclass ContextSwitcher.
    -Added Disk Quota interfaces IDiskQuotaControl (with coclass DiskQuotaControl), IDiskQuotaUser, IDiskQuotaUserBatch, IEnumDiskQuotaUsers, and IDiskQuotaEvents.
    -Added missing Direct2D DrawText option flag to enable color fonts (e.g. colored emojis).
    -Updated WebView2 interfaces to version 1.0.1774.30
    -(oleexpimp) Added IAdviseSink and IAdviseSinkEx.
    -(Bug fix) VB6 did not play nice with Implements where one argument was an HRESULT.
    -(Bug fix) D3D11CreateDevice pFeatureLevels now As Any to allow passing ByVal 0.
    -(Bug fix) DirectComposition vtable ordering to correct undocumented vtable reversal.


    (oleexp 6.2 - Released 01 April 2023)
    -Added accessibility UI Automation interfaces and APIs.
    NOTE: This API had a number of *very* generically named enums, like FillMode and ToggleState; these have been prefixed with Uia_ to avoid conflicts. In most cases, the actual members were left alone, with the exception of LiveSetting (renamed Uia_LiveSetting), which had Off, Polite, and Assertive; these have been prefixed with Uia_ as well.
    NOTE: IUIAutomationAndCondition and IUIAutomationOrCondition have members that return a SAFEARRAY of IUIAutomationCondition... MKTYPLIB does not support this so these return a pointer you'll need to dereference.
    -Completed Media Foundation interfaces up through the most recent Windows 11 SDK. This includes the capture engine and other entirely new feature sets.
    -Added CoreAudio Spatial Audio interfaces (newer Win10 versions/Win11 only)
    -Added IActiveScript and all related ActiveX Script Host / Engine interfaces.
    -Added IPinnedList (Vista), IPinnedList2 (7 < Win10 1809), IPinnedList3 (>= Win10 1809), and coclass TaskBandPin. Added IStartMenuPin. Don't abuse these-- always ask user permission to pin.
    -Added ITrayNotify and INotificationCB, coclass TrayNotify
    -Added coclass TaskBand
    -Added IHandlerInfo2, IDeskBar, IDeskBarClient amd IShellFolderBand
    -Added IHostDialogHelper, coclass HostDialogHelper
    -Added IFileSearchBand, coclass FileSearchBand
    -Added IPropertyPage[2] and IPropertyPageSite interfaces.
    -Added ISimpleFrameSite interface
    -Added IDispatchEx interface and related interfaces IDispError, IVariantChangeType, IProvideRuntimeContext, IObjectIdentity, and ICanHandleException
    -Added misc. interfaces ICurrentWorkingDirectory, IPropertyKeyStore, ISortColumnArray, IBannerNotificationHandler, IDelayedPropertyStoreFactory, IStorageProviderCopyHook, IDesktopGadget/Coclass DesktopGadget, IQueryCodePage, IStreamUnbufferedInfo, IUserAccountChangeCallback, IOpenSearchSource (with Implements- version in oleexpimp), IDestinationStreamFactory, ICreateProcessInputs, and ICreatingProcess.
    -(mIID) Added EP_* GUIDs for IExplorerPaneVisibility
    -(mIID) Added some missing SID_ guids.
    -Bug fix: AUDCLNT_RETURNCODES were all incorrect.

    (oleexp 6.1 - Released 02 March 2023)
    Added ITrayBand, IDeskBand2, IDeskBandInfo, IBandHost, and IBandSite interfaces, IMenuBand, and coclasses TrayDeskBand, TrayBandSiteServices
    Added IRegTreeItem interface
    Added IPrintDialogCallback/IPrintDialogServices interfaces.
    Bug fix: Certain DirectWrite interface members had ByRef Long for strings where they should have had ByVal.
    Bug fix: SHELLSTATE had an extra member on the end (shouldn't have impacted use, but if MS changed the API to look for an exact size it would be an issue).
    Bug fix: Attempted to correct INameSpaceTreeControlEvents context menu crashing.

    (oleexp 6.0 - Released 26 February 2023)
    -Added WebView2 interfaces/types/enums.
    -Added Microsoft Speech APIs Version 5.4
    -Added IHttpNegotiate3, IObjectProvider, IEnumObjects, and IIOCancelInformation interfaces.
    -Added Vista+ PROPSHEETPAGE and PROPSHEETHEADER versions of these structs (use PROPSHEETPAGE_V4 and PROPSHEETHEADER_V2 on Vista+) and PropSheet/PropSheetW APIs. Also corrected wrong values for PSN_TRANSLATEACCELERATOR/PSN_QUERYINITIALFOCUS.
    -(Bug fix) StringFromGUID2 now uses a Long instead of LPWSTR since the latter was not working.


    (oleexp 5.6 - Released 16 February 2023)
    -Added all missing Direct2D interfaces/types/enums.
    -Added all Direct3D 11 and 12 interfaces/types/enums.
    -(mDirectX) Bug fix: Many functions not returning GUIDs.

    (oleexp 5.5 - Released 12 February 2023)
    -Added objidl.idl interfaces IAdviseSink2, IClientSecurity, IServerSecurity, IMallocSpy, IClassActivator, IProgressNotify, IStdMarshalInfo, IExternalConnection and IThumbnailExtractor (w/coclass ThumbnailFCNHandler).
    -Added undocmented hardware enum interfaces/coclasses.
    -Bug fix: ICreateTypeLib2 incorrectly extended IUnknown instead of ICreateTypeLib.


    Older version history can be found in the history.txt file included in the download.

    Version Archive
    I have zips of all previous versions, if you ever wanted an old version for any reason, just let me know in this thread, PM, or e-mail.

    -------------
    Any and all feedback is welcome. Many thanks to E. Morcillo for the olelib foundation, all the olelib source is all his code.




    Copyright/Redistribution
    OLEEXP is open and free. You may distribute the files however you want and release your own projects based on this work, including projects for the Code Bank here, even just about using a particular interface. If you compile a modified version, please use a different GUID and note that it's your own fork as I did with olelib-- but if it's a bugfix-type change you could also just let me know and I'll immediately update the master version here. Project provided as-is.

    Virus Scanners
    Due to some concerns raised, oleexp 4.5 and oleexpimp were checked against VirusTotal and triggered 0 of 59 AVs (about a dozen didn't examine .tlb files). So while it may be possible false positives result from actually using some of the low level APIs declared in the TLB, the TLB itself does not trigger false positives, and only declares used go into the exe, not the whole tlb or reference (see below). I can assess with high confidence that oleexp does not result in AV false positives.

    File Size
    While oleexp is a large file, when you compile your exe it only takes what is used; the entire TLB isn't compiled into your file, only a few KB in most cases. The same goes for the addons- with mIID, only IIDs that are used get compiled in. In addition, a compiled exe does not maintain a reference to the tlb file, so the tlb itself need only be on the development machine; it is not necessary to distribute tlb files with your application.

    Coclasses
    A coclass is provided when Windows provides a default implementation of the given interface, and allows instances to be created with the New keyword instead of the CLSID and CoCreateInstance API. For single-interface coclasses, you need only the name of the coclass: Dim psl As ShellLibrary : Set psl = New ShellLibrary. Note that when a coclass is present, the underlying interface is hidden, but still present. In the example, IShellLibrary, no longer appears in the Object Browser or Properties&Methods popup list- but it is still present and can be used normally, e.g. if you were using CoCreateInstance that will still work as-is; you can also still declare As IShellLibrary.
    For coclasses with multiple members, you will need to create a specific interface. Only one of the interfaces disappears from view, but it too is still there. Dim pIDSH As IDragSourceHelper[2] : Set pIDSH = New DragDropHelper Dim pIDTH As IDropTargetHelper : Set pIDTH = New DragDropHelper




    List of New Interfaces In OLEEXP (as of v5.01)
    IAccessible
    IAccessibleHandler
    IAccessibleWindowlessSite
    IAccIdentity
    IAccPropServer
    IAccPropServices; coclass CAccPropServices
    IApplicationAssociationRegistration*; coclass ApplicationAssociationRegistration
    IApplicationAssociationRegistrationUI*; coclass ApplicationAssociationRegistrationUI
    IApplicationDestinations
    IApplicationDocumentLists; coclass ApplicationDocumentLists
    IAppPublisher*
    IAssocHandler
    IAssocHandlerInvoker
    IAutoCompleteDropDown
    IBrowserFrameOptions
    IColumnManager
    ICommDlgBrowser*
    ICommDlgBrowser2*
    ICommDlgBrowser3*
    ICondition, coclass LeafCondition et al.
    ICondition2
    IConditionFactory; coclass ConditionFactory
    IConditionFactory2
    IConditionGenerator
    IContextMenu3
    IContextMenuCB
    ICurrentItem
    ICustomizeInfoTip
    ICreateObject
    ICustomDestinationsList; coclass DestinationList
    IDataObjectAsyncCapability‡
    IDefaultExtractIconInit
    IDefaultFolderMenuInitialize; coclass DefFolderMenu
    IDelegateFolder
    IDelegateItem
    IDisplayItem
    IDragSourceHelperr; coclass DragDropHelper
    IDragSourceHelper2r; coclass DragDropHelper
    IDropTargetHelperr; coclass DragDropHelper
    IEntity
    IEnumAssocHandlers
    IEnumerableView
    IEnumExplorerCommand
    IEnumFullIDList
    IEnumPublishedApps*
    IEnumReadyCallback
    IEnumResources*
    IEnumShellItems
    IExecuteCommand; coclasses ExecuteFolder, ExecuteUnknown, and AppShellVerbHandler
    IExecuteCommandHost
    IExplorerBrowser; coclass ExplorerBrowser
    IExplorerBrowserEvents
    IExplorerCommandProvider
    IExplorerCommandState
    IExplorerPaneVisibility*
    IFileDialog
    IFileDialog2
    IFileDialogControlEvents
    IFileDialogCustomize
    IFileDialogEvents
    IFileIsInUse
    IFileOpenDialog; coclass FileOpenDialog
    IFileOperation; coclass FileOperation
    IFileOperationProgressSink
    IFileSaveDialog; coclass FileSaveDialog
    IFileSystemBindData
    IFileSystemBindData2
    IFilterCondition
    IFolderView2
    IFolderViewOptions
    IFolderViewSettings
    IFrameworkInputPane; coclass FrameworkInputPane
    IFrameworkInputPaneHandler
    IHomeGroup; coclass HomeGroup
    IIdentityName
    IImageList; coclass ImageList***
    IImageList2
    IImageRecompress; coclass ImageRecompress
    IInertiaProcessor; coclass InertiaProcessor
    IInitializeCommand
    IInitializeNetworkFolder, coclass NetworkPlaces
    IInitializeWithBindCtx
    IInitializeWithFile
    IInitializeWithItem
    IInitializeWithPropertyStore
    IInitializeWithStream
    IInitializeWithWindow
    IInternetSecurityManagerEx
    IInternetSecurityManagerEx2
    IInternetZoneManagerEx
    IInternetZoneManagerEx2
    IInterval, coclass Interval
    IItemFilter
    IItemNameLimits
    IKnownFolder
    IKnownFolderManager; coclass KnownFolderManager
    IManipulationProcessor; coclass ManipulationProcessor
    IManipulationEvents
    IMessageFilter
    IMetaData
    IModalWindow
    IMultiQI
    INamedEntity
    INamedEntityCollector
    INamedPropertyStore
    INameSpaceTreeControl
    INameSpaceTreeControl2; coclass NamespaceTreeControl
    INameSpaceTreeControlAccessible
    INameSpaceTreeControlCustomDraw
    INameSpaceTreeControlDropHandler
    INameSpaceTreeControlEvents
    INameSpaceTreeControlFolderCapabilities
    INamespaceWalk
    INamespaceWalkCB
    INamespaceWalkCB2
    INewMenuClient
    INewWindowManager
    IObjectArray
    IObjectCollection; coclass EnumerableObjectCollection
    IObjectWithFolderEnumMode
    IObjectWithPropertyKey
    IObjMgr
    IOperationsProgressDialog
    IPersistFolder3
    IPreviewHandler
    IPreviewHandlerFrame
    IPreviewHandlerVisuals
    IPreviewItem
    IPreviousVersionsInfo; coclass PreviousVersions
    IProgressDialog
    IPropertyChange
    IPropertyChangeArray
    IPropertyDescription
    IPropertyDescription2
    IPropertyDescriptionAliasInfo
    IPropertyDescriptionList
    IPropertyDescriptionRelatedPropertyInfo
    IPropertyDescriptionSearchInfo
    IPropertyEnumType
    IPropertyEnumType2
    IPropertyEnumTypeList
    IPropertyStore
    IPropertyStoreCache
    IPropertyStoreCapabilities
    IPropertyStoreFactory
    IPropertySystem
    IPublishedApp*
    IPublishedApp2*
    IQueryParser, coclass QueryParser
    IQueryParserManager, coclass QueryParserManager
    IQuerySolution
    IRelatedItem
    IRelationship
    IResolveShellLink
    IResultsFolder
    IRichChunk*
    ISchemaLocalizerSupport
    ISchemaProvider
    ISearchBoxInfo*
    ISearchFolderItemFactory; coclass SearchFolderItemFactory
    ISharedBitmap
    ISharingConfigurationManager; coclass SharingConfigurationManager
    IShellApp*
    IShellChangeNotify
    IShellFolderViewCB*
    IShellIconOverlay
    IShellIconOverlayIdentifier*
    IShellIconOverlayManager; coclass CFSIconOverlayManager
    IShellImageDataFactory; coclass ShellImageDataFactory
    IShellImageData
    IShellImageDataAbort*
    IShellItem
    IShellItem2
    IShellItemArray
    IShellItemFilter
    IShellItemImageFactory
    IShellItemResources
    IShellLibrary
    IShellLinkDataList
    IShellMenu*
    IShellMenuCallback*
    IShellRunDll
    IShellTaskScheduler; coclass ShellTaskScheduler
    IShellWindows; coclass ShellWindows
    ISpellingError
    IStartMenuPinnedList
    IStreamAsync
    ISystemInformation; coclass SystemInformation
    ITaskbarList3
    ITaskbarList4; coclass TaskbarList
    ITaskService, coclass TaskS
    IThumbnailCache; coclass LocalThumbnailCache
    IThumbnailHandlerFactory
    IThumbnailProvider
    IThumbnailSettings
    ITokenCollection
    ITrackShellMenu; coclass TrackShellMenu
    ITranscodeImage; coclass ImageTranscode
    ITransferAdviseSink*
    ITransferDestination*
    ITransferMediumItem
    ITransferSource*
    IUri
    IUserNotification2; coclass UserNotification
    IUserNotificationCallback
    IUseToBrowseItem
    IViewStateIdentityItem
    IVirtualDesktopManager, coclass VirtualDesktopManager
    IVisualProperties
    IZoneIdentifier; coclass PersistentZoneIdentifier
    IZoneIdentifier2
    IZombie
    Task Manager
    IAction
    IActionCollection
    IBootTrigger
    IComHandlerAction
    IDailyTrigger
    IEmailAction
    IEventTrigger
    IExecAction
    IExecAction2
    IIdleSettings
    IIdleTrigger
    ILogonTrigger
    IMaintenanceSettings
    IMonthlyDOWTrigger
    IMonthlyTrigger
    INetworkSettings
    IPrincipal
    IPrincipal2
    IRegisteredTask
    IRegisteredTaskCollection
    IRegistrationInfo
    IRegistrationTrigger
    IRepetitionPattern
    IRunningTask
    IRunningTaskCollection
    ISessionStateChangeTrigger
    IShowMessageAction
    ITaskDefinition
    ITaskFolder
    ITaskFolderCollection
    ITaskHandler
    ITaskHandlerStatus
    ITaskNamedValueCollection
    ITaskNamedValuePair
    ITaskService; coclass TaskScheduler
    ITaskSettings
    ITaskSettings2
    ITaskSettings3
    ITaskVariables
    ITimeTrigger
    ITrigger
    ITriggerCollection
    IWeeklyTrigger
    Spell Checking
    IComprehensiveSpellCheckProvider
    IEnumSpellingError
    IOptionDescription
    ISpellChecker
    ISpellChecker2
    ISpellCheckerChangedEventHandler
    ISpellCheckerFactory; coclass SpellCheckerFactory
    ISpellCheckProvider
    ISpellCheckProviderFactory
    ISpellingError
    IUserDictionariesRegistrar
    ListView
    IDrawPropertyControl
    IListView
    IListViewFooter
    IListViewFooterCallback
    ILVRange
    IOwnerDataCallback
    IPropertyControl
    IPropertyControlBase
    IPropertyValue
    ISubItemCallback
    Shell Automation
    DFConstraint
    DShellFolderViewEvents, coclass ShellFolderViewOC
    Folder
    Folder2
    Folder3
    FolderItem
    FolderItem2, coclass FolderItem
    FolderItems
    FolderItems2
    FolderItems3
    FolderItemVerb
    FolderItemVerbs
    IFolderViewOC
    IShellFolderViewDual
    IShellFolderViewDual2
    IShellFolderViewDual3, coclass ShellFolderView
    IShellDispatch
    IShellDispatch2
    IShellDispatch3
    IShellDispatch4
    IShellDispatch5
    IShellDispatch6, coclass Shell
    IShellLinkDual
    IShellLinkDual2, coclass ShellLinkObject
    Core Audio
    IActivateAudioInterfaceAsyncOperation
    IActivateAudioInterfaceCompletionHandler
    IAudioAutoGainControl
    IAudioBass
    IAudioCaptureClient
    IAudioChannelConfig
    IAudioClient
    IAudioClient2
    IAudioClient3
    IAudioClock
    IAudioClock2
    IAudioClockAdjustment
    IAudioEndpointFormatControl
    IAudioEndpointLastBufferControl
    IAudioEndpointOffloadStreamMeter
    IAudioEndpointOffloadStreamMute
    IAudioEndpointOffloadStreamVolume
    IAudioEndpointVolume
    IAudioEndpointVolumeCallback
    IAudioEndpointVolumeEx
    IAudioInputSelector
    IAudioLfxControl
    IAudioLoudness
    IAudioMeterInformation
    IAudioMidrange
    IAudioMute
    IAudioOutputSelector
    IAudioPeakMeter
    IAudioRenderClient
    IAudioSessionControl
    IAudioSessionControl2
    IAudioSessionEnumerator
    IAudioSessionEvents
    IAudioSessionManager
    IAudioSessionManager2
    IAudioSessionNotification
    IAudioStreamVolume
    IAudioSystemEffects
    IAudioSystemEffects2
    IAudioTreble
    IAudioVolumeDuckNotification
    IAudioVolumeLevel
    IChannelAudioVolume
    IConnector
    IControlChangeNotify
    IControlInterface
    IDeviceSpecificProperty
    IDeviceTopology
    IHardwareAudioEngineBase
    IKsControl
    IKsFormatSupport
    IKsJackContainerId
    IKsJackDescription
    IKsJackDescription2
    IKsJackSinkInformation
    IMMDevice
    IMMDeviceActivator
    IMMDeviceCollection
    IMMDeviceEnumerator
    IMMEndpoint
    IMMNotificationClient
    IPart
    IPartsList
    IPolicyConfig
    IPerChannelDbLevel
    ISimpleAudioVolume
    ISubunit
    DirectShow**
    IAMAnalogVideoDecoder
    IAMAsyncReaderTimestampScaling
    IAMAudioInputMixer
    IAMAudioRendererStats
    IAMBufferNegotiation
    IAMCameraControl
    IAMCertifiedOutputProtection
    IAMChannelInfo
    IAMClockAdjust
    IAMClockSlave
    IAMCollection
    IAMCopyCaptureFileProgress
    IAMCrossbar
    IAMDecoderCaps
    IAMExtendedErrorInfo
    IAMExtendedSeeking
    IAMMediaContent
    IAMMediaContent2
    IAMNetShowConfig
    IAMNetShowExProps
    IAMNetShowPreroll
    IAMNetworkStatus
    IAMStats
    IBaseFilter, multiple coclasses
    IBasicAudio
    IBasicVideo
    IBasicVideo2
    ICaptureGraphBuilder
    ICaptureGraphBuilder2
    IDeferredCommand
    IEnumFilters
    IEnumMediaTypes
    IEnumPins
    IFileSinkFilter
    IFilterGraph, coclass FilterGraph
    IFilterGraph2
    IFilterGraph3
    IFilterInfo
    IGraphBuilder
    IMediaControl
    IMediaEvent
    IMediaEventEx
    IMediaFilter
    IMediaPosition
    IMediaSample
    IMediaSample2
    IMediaSample3
    IMediaTypeInfo
    IPin
    IPinInfo
    IQueueCommand
    IReferenceClock
    IRegFilterInfo
    ISampleGrabber, coclass SampleGrabber
    ISampleGrabberCB
    IVideoWindow
    Windows Imaging Component (WIC)ª
    IWICBitmap
    IWICBitmapClipper
    IWICBitmapCodecInfo
    IWICBitmapCodecProgressNotification
    IWICBitmapDecoder
    IWICBitmapDecoderInfo
    IWICBitmapEncoder
    IWICBitmapEncoderInfo
    IWICBitmapFlipRotator
    IWICBitmapFrameDecode
    IWICBitmapFrameEncode
    IWICBitmapLock
    IWICBitmapScaler
    IWICBitmapSource
    IWICBitmapSourceTransform
    IWICColorContext
    IWICColorTransform
    IWICComponentFactory
    IWICComponentInfo
    IWICDdsDecoder
    IWICDdsEncoder
    IWICDdsFrameDecode
    IWICDevelopRaw
    IWICDevelopRawNotificationCallback
    IWICEnumMetadataItem
    IWICFastMetadataEncoder
    IWICFormatConverter
    IWICFormatConverterInfo
    IWICImageEncoder
    IWICImagingFactory, coclass WICImagingFactory
    IWICImagingFactory2, coclass WICImagingFactory2
    IWICJpegFrameDecode
    IWICJpegFrameEncode
    IWICMetadataBlockReader
    IWICMetadataBlockWriter
    IWICMetadataHandlerInfo
    IWICMetadataQueryReader
    IWICMetadataQueryWriter
    IWICMetadataReader
    IWICMetadataReaderInfo
    IWICMetadataWriter
    IWICMetadataWriterInfo
    IWICPalette
    IWICPersistStream
    IWICPixelFormatInfo
    IWICPixelFormatInfo2
    IWICPlanarBitmapFrameEncode
    IWICPlanarBitmapSourceTransform
    IWICPlanarFormatConverter
    IWICProgressCallback
    IWICProgressiveLevelControl
    IWICStream
    IWICStreamProvider
    Portable Devices
    IEnumPortableDeviceConnectors****
    IEnumPortableDeviceObjectIDs
    IPortableDevice, coclasses PortableDevice, PortableDeviceFTM
    IPortableDeviceCapabilities
    IPortableDeviceConnector****
    IPortableDeviceContent
    IPortableDeviceContent2
    IPortableDeviceDispatchFactory, coclass PortableDeviceDispatchFactory
    IPortableDeviceEventCallback
    IPortableDeviceKeyCollection, coclass PortableDeviceKeyCollection
    IPortableDeviceManager, coclass PortableDeviceManager
    IPortableDeviceProperties
    IPortableDevicePropertiesBulkCallback
    IPortableDevicePropVariantCollection, coclass PortableDevicePropVariantCollection
    IPortableDeviceResources
    IPortableDeviceService, coclass PortableDeviceService
    IPortableDeviceServiceCapabilities
    IPortableDeviceServiceMethodCallback
    IPortableDeviceServiceMethods
    IPortableDeviceServiceOpenCallback
    IPortableDeviceValues, coclass PortableDeviceValues
    IPortableDeviceValuesCollection
    IPortableDeviceWebControl, coclass PortableDeviceWebControl
    IWpdSerializer, coclass WpdSerializer
    Net Connections
    IEnumNetConnection
    IEnumNetSharingEveryConnection
    IEnumNetSharingPortMapping
    IEnumNetSharingPrivateConnection
    IEnumNetSharingPublicConnection
    INetConnection
    INetConnectionConnectUi
    INetConnectionManager, coclass ConnectionManager
    INetConnectionProps
    INetSharingConfiguration
    INetSharingEveryConnectionCollection
    INetSharingManager, coclass NetSharingManager
    INetSharingPortMapping
    INetSharingPortMappingCollection
    INetSharingPortMappingProps
    INetSharingPrivateConnectionCollection
    INetSharingPublicConnectionCollection
    * - Under development; may not be 100% error free
    ** - The DirectShow interface set, for convenience, contains all interfaces and types/enums from quartz.dll. You do not need a reference to it when using oleexp.
    *** - Cannot be used with New keyword. IImageList can be created new (if you're making one from scratch instead of system IL) with ImageList_CoCreateInstance API.
    ‡ - IAsyncOperation was renamed to IDataObjectAsyncCapability. Changed some usage details.

    **** - Interface located in oleexpimp.tlb due to GUID conflict
    ª - WIC has numerous coclasses, too many to list clearly here. All the listed interfaces are present, so if you don't see one in the autocomplete list, don't worry it's there. See the CLSID values in mWIC for a coclass list (they're in the TLB as traditional coclasses for the New keyword, you don't need to use CoCreateInstance).



    All related structures and enums are also included.
    Last edited by fafalone; Aug 10th, 2023 at 04:33 AM. Reason: Updated version history

  3. #3
    Hyperactive Member
    Join Date
    Feb 2015
    Location
    Colorado USA
    Posts
    261

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

    Good work. Is it possible for you to recompile the TLB's in 64-bit version? I use VB6 but I also support both 32 and 64-bit Office VBA and it would be nice to use these with 64-bit Office. I don't have a version of Visual Studio that comes with a type library editor or compiler so I can't do it myself. Thanks.

  4. #4

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

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

    MORE SECTIONS FROM ABOVE NEEDED TO BE MOVED DOWN; THIS POST IS PART OF THE MAIN PROJECT POST ALONG WITH #1 and #2.

    Interfaces Included From Original OLELIB
    IACList
    IACList2
    IActionProgress
    IActionProgressDialog
    IActiveDesktop
    IAddressBarParser; coclass AddressBarParser
    IAdviseSink
    IAuthenticate
    IAutoComplete
    IAutoComplete2
    IBindCtx
    IBindHost
    IBinding
    IBindProtocol
    IBindStatusCallback
    ICallAddRelease
    ICallGION
    ICallInvoke
    ICallQI
    ICategorizer; multiple coclasses‡
    ICategoryProvider
    ICatInformation
    ICatRegister
    ICDBurn; coclass CDBurn
    IClassFactory
    IClassFactory2
    IColumnProvider
    IConnectionPoint
    IConnectionPointContainer
    IContextMenu
    IContextMenu2
    IContinueCallback
    ICopyHookA
    ICopyHookW
    ICreateErrorInfo
    ICreateTypeInfo
    ICreateTypeInfo2
    ICreateTypeLib
    ICreateTypeLib2
    ICustomDoc
    IDataObject†
    IDeskBand
    IDispatch
    IDocHostShowUI
    IDocHostUIHandler
    IDocHostUIHandler2
    IDockingWindow
    IDockingWindowFrame
    IDockingWindowSite
    IDropSource
    IDropTarget
    IEmptyVolumeCache
    IEmptyVolumeCache2
    IEmptyVolumeCacheCallBack
    IEnumACString
    IEnumCATEGORYINFO
    IEnumConnectionPoints
    IEnumConnections
    IEnumExtraSearch
    IEnumFORMATETC
    IEnumGUID
    IEnumHLITEM
    IEnumIDList†
    IEnumMoniker
    IEnumOleDocumentViews
    IEnumOLEVERB
    IEnumSTATDATA
    IEnumSTATPROPSETSTG
    IEnumSTATPROPSTG
    IEnumSTATSTG
    IEnumSTATURL
    IEnumString
    IEnumUnknown
    IEnumVARIANT
    IEnumWorkItems
    IErrorInfo
    IErrorLog
    IExtractIconA
    IExtractIconW
    IExtractImage
    IExtractImage2
    IFillLockBytes
    IFolderFilter
    IFolderFilterSite
    IFolderView
    IFolderViewHost; coclass FolderViewHost
    IHlink
    IHlinkBrowseContext
    IHlinkFrame
    IHlinkSite
    IHlinkTarget
    IHttpNegotiate
    IHWEventHandler
    IInputObject
    IInputObjectSite
    IInternetBindInfo
    IInternetHostSecurityManager
    IInternetPriority
    IInternetProtocol
    IInternetProtocolInfo
    IInternetProtocolRoot
    IInternetProtocolSink
    IInternetSecurityManager
    IInternetSecurityMgrSite
    IInternetSession
    IInternetZoneManager
    ILayoutStorage
    ILockBytes
    IMalloc
    IMarshal
    IMoniker
    INetCrawler; coclass NetCrawler
    INewShortcutHookA
    INewShortcutHookW
    IObjectSafety
    IObjectWithSite
    IOleCache
    IOleClientSite
    IOleCommandTarget
    IOleContainer
    IOleControl
    IOleControlSite
    IOleDocument
    IOleDocumentSite
    IOleDocumentView
    IOleInPlaceActiveObject
    IOleInPlaceFrame
    IOleInPlaceObject
    IOleInPlaceSite
    IOleInPlaceUIWindow
    IOleLink
    IOleObject
    IOleWindow
    IParseDisplayName
    IPerPropertyBrowsing
    IPersist
    IPersistFile; coclass ImageProperties
    IPersistFolder
    IPersistFolder2
    IPersistIDList
    IPersistMemory
    IPersistMoniker
    IPersistPropertyBag
    IPersistPropertyBag2
    IPersistStorage
    IPersistStream
    IPersistStreamInit
    IPrint
    IProfferService
    IProgressDialog
    IPropertyBag
    IPropertyBag2
    IPropertyNotifySink
    IPropertySetStorage
    IPropertyStorage
    IPropertyUI; coclass PropertiesUI
    IProvideClassInfo
    IProvideTaskPage
    IPublishingWizard; coclass PublishingWizard
    IQueryAssociations
    IQueryCancelAutoPlay; coclass QueryCancelAutoPlay
    IQueryContinue
    IQueryInfo
    IRecordInfo
    IRichEditOle
    IRichEditOleCallback
    IRootStorage
    IRunningObjectTable
    IScheduledWorkItem
    ISchedulingAgent
    ISearchContext
    ISequentialStream
    IServiceProvider
    IShellBrowser†
    IShellExecuteHookA
    IShellExecuteHookW
    IShellExtInit
    IShellFolder2†
    IShellFolder†
    IShellIcon
    IShellLinkA
    IShellLinkW; coclass ShellLinkW
    IShellPropSheetExt
    IShellView2†
    IShellView†
    ISpecifyPropertyPages
    IStorage
    IStream
    ISupportErrorInfo
    ITaskbarList
    ITaskbarList2
    ITask
    ITaskTrigger
    ITextDocument
    ITextFont
    ITextPara
    ITextRange
    ITextSelection
    ITextStoryRanges
    ITypeComp
    ITypeInfo
    ITypeInfo2
    ITypeLib
    ITypeLib2
    IUniformResourceLocatorA
    IUniformResourceLocatorW
    IUnknown
    IUrlHistoryStg
    IUrlHistoryStg2
    IURLSearchHook
    IURLSearchHook2
    IUserEventTimer; coclass UserEventTimer
    IUserEventTimerCallback; coclass UserEventTimerCallback
    IUserNotification
    IViewObject
    IViewObject2
    IWebWizardExtension; coclass WebWizardHost
    IWindowForBindingUI
    IWinInetHttpInfo
    IWinInetInfo
    IWizardExtension
    IWizardSite
    † - Interface specification has been modified from the original version of olelib.

    More Notes


    Variable Conflicts
    With TLBs, it's possible to have multiple instances of an interface, struct, or enum. For example, if you also had one of the many oleguids.tlb added, you might have two IShellFolder types, so if you have Dim psf As IShellFolder, VB isn't sure which one you mean, and will assign it based on the order in Project->References. Even worse, the high-priority default VB references contain hidden versions of IUnknown and IDispatch, which would take precedence despite being hidden.
    To ensure that your variable is defined as the correct version, declare your variables explicitly if there's a conflict:
    Dim pUnk As oleexp.IUnknown
    Dim psf As oleexp.IShellFolder

    and so on. It must always be done for IUnknown/IDispatch since they have built-in conflicts, but for other interfaces it only needs to be done if there's another place it might be defined.
    Note: This applies to declarations in VB project code as well for user types and enums. Be careful here: while with enums it might just result in not seeing a member in the member list that pops up, but if a user type differs, you'll get an error or invalid data if you pass the wrong one to an interface or API. Public ones, or Private ones in the current object, take precedence over ones defined in a typelib, so if you need to use the typelib version, make sure to declare it explicitly, Dim tStruct As oleexp.structname.

    Implements issues
    Most of the interfaces in this project are not meant to be implemented in class modules. Some of them are, and some of those expect data passed back. Anything given in the typelib as an HRESULT returning function is treated as a Sub in VB, making it impossible to pass a value either way. So to get those values, many things have been changed to LONG. This allows you to receive a value there, but VB does not allow anything other than an HRESULT when you're using Implements to create your own version. All interfaces where your own version is expected, at least in my project, are already all HRESULT's, but if one is not, you can either change it and compile it yourself, or let me know and I can make an Implements-compatible version. Only needing one version would be nice, but VB went out of it's way to break this: the second problem is that sometimes when you're implementing your own version of an interface, some functionality requires that data be returned by the function instead of in one of the arguments.
    To accomplish this, you'll need to swap the implementing sub in the library with a regular function. This is a little more complicated than it sounds.

    First, you need the swapping code (not written by me and reused so many places I can't find the appropriate original attribution):
    Code:
    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal ByteLen As Long)
    Public Declare Function VirtualProtect Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, ByRef lpflOldProtect As Long) As Long
    Public Const PAGE_EXECUTE_READWRITE As Long = &H40&
    
    Public Function SwapVtableEntry(pObj As Long, EntryNumber As Integer, ByVal lpfn As Long) As Long
    
        Dim lOldAddr As Long
        Dim lpVtableHead As Long
        Dim lpfnAddr As Long
        Dim lOldProtect As Long
    
        CopyMemory lpVtableHead, ByVal pObj, 4
        lpfnAddr = lpVtableHead + (EntryNumber - 1) * 4
        CopyMemory lOldAddr, ByVal lpfnAddr, 4
    
        Call VirtualProtect(lpfnAddr, 4, PAGE_EXECUTE_READWRITE, lOldProtect)
        CopyMemory ByVal lpfnAddr, lpfn, 4
        Call VirtualProtect(lpfnAddr, 4, lOldProtect, lOldProtect)
    
        SwapVtableEntry = lOldAddr
    
    End Function
    It's best to put that, and your new function, into a module, unless you're feeling really adventurous.
    To actually do the swap, this goes in the implementing class module:

    Code:
    Private m_pOldFunction As Long
    
    Private Sub Class_Initialize()
    Dim pVTable As ISomeInterface
    Set pVTable = Me
    m_pOldFunction = SwapVtableEntry(ObjPtr(pVTable), 4, AddressOf MyNewFunctionVB)
    End Sub
    
    Private Sub Class_Terminate()
    Dim pVTable As ISomeInterface
    Set pVTable = Me
    m_pOldFunction = SwapVtableEntry(ObjPtr(pVTable), 4, m_pOldFunction)
    End Sub
    The number 4 there, which is the EntryNumber argument, is critically important- it's the ordinal of the function you're replacing. This order is NOT alphabetical order, and not what order it's in in your class module, it's the order in the actual interface definition, and starts at 4 for interfaces that inherit directly from IUnknown, which contains the first 3. Refer to the .odl/.inc source files for the proper order.
    Now we're finally left with the new function itself, which now actually is a function that can return data!

    Code:
    Public Function MyNewFunctionVB(ByVal this As ISomeInterface, ByVal arg1 As Whatever, etc) As Long
    'Handling code here
    End Function
    Any code that was in ISomeInterface_MyNewFunction in the class module will not be executed, but the definition line must remain in place.

    The only bug is, and I've posted a discussion thread in the regular VB6 forum for ideas, is that if you run your program, then exit, and change the code in MyNewFunctionVB, then VB will crash next time the class module is created unless you exit and restart the IDE. Doesn't matter if you've swapped back and destroyed the objects, so for now just restart the IDE if you've run your program then later changed that function's code.

    Using QueryInterface

    The issue came up again for me today when I started using IShellItem2- one of the ways to get that interface by using .QueryInterface from an IShellItem object, which is actually from its parent IUnknown. Due to the way IUnknown was set up in this project, that function isn't visible on IShellItem or any other interface (they all inherit from IUnknown). They can be made visible by changing all the : stdole.IUnknown to just IUnknown, but I'm unsure of the consequences of such a change, and olelib is too massive to confirm there's no side effects.
    But fear not, if you need to access .QueryInterface, use the method in this routine that gets IShellItem2 from IShellItem

    Code:
    Dim psi As IShellItem
    Dim psi2 As IShellItem2
    Dim pUnk As oleexp.IUnknown 'should be explicitly typed since there's another hidden IUnknown in VB and it will cause errors
    
    Call SHCreateShellItem(0, 0, pidl, psi) 'pidl of whatever file/object you're working with, code omitted
    
    Set pUnk = psi
    pUnk.QueryInterface IID_IShellItem2, psi2
    And now you have a ready-to-go IShellItem2. This method is also used, for example, to get an IPropertyStore interface from an IShellLinkW.



    Undocumented ListView
    The shell's ListView common control has a number of interfaces that expose some cool undocumented features. These interfaces are maintained as a separate typelib called lvundoc.tlb rather than included in oleexp.
    Download ListView Interfaces TypeLib: lvundocsrc.zip
    Includes lvundoc.tlb, source, and template classes for callbacks.
    NOTE: All of the Undocumented ListView Typelib, and associated types and constants, are now also in oleexp.tlb. If you are using oleexp.tlb, you now no longer need lvundoc.tlb. The download will be left up for those who just need the LV stuff and not full-blown oleexp.

    Current Demos
    [VB6, Vista+] Undocumented ListView feature: Footer items - As seen when searching from an Explorer folder, allows a group of buttons at the bottom of a ListView.
    Interfaces: IListViewFooter, IListViewFooterCallback

    [VB6, Vista+] Undocumented ListView feature: Subsetted Groups (simple, no TLB) - Allows you to show only a given number of rows per group, with a hyperlink at the bottom the user can click to show the rest.

    [VB6, Vista+] Undocumented ListView feature: Groups in Virtual Mode - Group View officially isn't compatible when the LVS_OWNERDATA style is set, but with a little work it's actually possible.
    Interfaces: IListView, IOwnerDataCallback

    [VB6] Undocumented ListView feature: Highlight column - Set a background highlight color for an individual column.

    [VB6, Win7+] Undocumented ListView Feature: Multiselect in columns like Explorer - Start a selection rectangle by dragging from the whitespace next to the filenames (instead of that starting a drag/drop or doing nothing if DD disabled).

    Interfaces: IVisualProperties

    Future Work
    Subitem controls are very complex but offer incredible features. The drive display in My Computer, the Ratings stars, combo boxes, links, subitem label editing... these are all exposed through subitem controls. The type library includes the required interfaces and one closed-source VB project has succeeded, so I will figure it out at some point in the future. In the mean time, the TLB is set up to get started if you want to pursue it on your own.

    Common Controls 6.0/6.1 Definitions TLB
    Download Common Controls TypeLib: tl_comctl6.zip
    Includes CommCtrl.tlb, source, and template classes for ListView interfaces.

    Decided to give my favorite typelib author's CommCtrl.tlb an upgrade as well. In addition to upgrading what was in there for the latest Common Controls version:
    -Added the parts of the included controls that were defined in winuser.h. It made no sense to only include a small portion of the control definitions just because some defs were in another header.
    -The definitions for the ListView control include everything from lvundoc.tlb, including all undocumented messages and interfaces. If you're using this typelib, you do not need to also have lvundoc.
    Last edited by fafalone; Jun 30th, 2022 at 11:50 PM. Reason: Added new undocumented ListView demo.

  5. #5

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

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

    @MountainMan:

    I'll try but it looks like a nightmare. midl.exe is complaining about errors in oaidl.idl, which isn't part of the project, which couldn't be found until I copied it into my source folder despite running vcvarsall.bat, and comes straight from the SDK so why on earth would it have errors anyway?

    Code:
    C:\vb6\tl_ole\source>C:\PROGRA~2\MIA713~1\\Windows\v7.0A\Bin\midl.exe /nologo /e
    nv win64 /nocpp /tlb "olelib64.odl" olelib.odl
    64 bit Processing .\olelib.odl
    64 bit Processing .\oaidl.idl
    oaidl.idl(26) : error MIDL2025 : syntax error : expecting an interface name or D
    ispatchInterfaceName or CoclassName or ModuleName or LibraryName or ContractName
     or a type specification near "ifndef"
    oaidl.idl(27) : error MIDL2026 : cannot recover from earlier syntax errors; abor
    ting compilation
    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.

    Edit: So I installed 64-bit office, and definitely need more info about what part of the typlibs won't work. Note that olelib includes API calls, but I've had problems with these everywhere and strongly suggest always using your own declares in a module.
    This is what I tried, and it worked fine with the current versions. Note that IShellItem.GetDisplayname returns a pointer, but VBA doesn't know that thus the LongPtr type isn't needed. If you needed it down the road, there apparently is a CLngPtr() function built in.

    Code:
    Private Sub CommandButton1_Click()
    Dim pidl As Long
    Dim sp As String
    Dim psi As IShellItem
    Dim sb As String
    Dim pstr As Long
    
    sp = "C:\temp\tracks.jpg"
    pidl = ILCreateFromPathW(StrPtr(sp))
    
    'Both of these methods work
    'Call SHCreateShellItem(0&, 0&, pidl, psi)
    Call SHCreateItemFromIDList(pidl, IID_IShellItem, psi)
    
    psi.GetDisplayName SIGDN_FILESYSPATH, pstr
    MsgBox BStrFromLPWStr(pstr)
    
    Call ILFree(pidl)
    
    End Sub
    
    'module
    Public Declare PtrSafe Function SHCreateShellItem Lib "shell32" (ByVal pidlParent As Long, ByVal psfParent As Long, ByVal pidl As Long, ppsi As IShellItem) As Long
    Public Declare PtrSafe Function SHCreateItemFromIDList Lib "shell32" (ByVal pidl As Long, riid As UUID, ppv As Any) As Long
    Public Declare PtrSafe Function SHCreateShellItemArrayFromIDLists Lib "shell32" (ByVal cidl As Long, ByVal rgpidl As Long, ppsiItemArray As IShellItemArray) As Long
    Public Declare PtrSafe Function ILCreateFromPathW Lib "shell32" (ByVal pwszPath As LongPtr) As Long
    Public Declare PtrSafe Sub ILFree Lib "shell32" (ByVal pidl As Long)
    Public Declare PtrSafe Function SysReAllocString Lib "oleaut32.dll" (ByVal pBSTR As LongPtr, Optional ByVal pszStrPtr As Long) As Long
    Public Declare PtrSafe Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long) 
    
    Public Function BStrFromLPWStr(lpWStr As Long, Optional ByVal CleanupLPWStr As Boolean = True) As String
    SysReAllocString VarPtr(BStrFromLPWStr), lpWStr
    If CleanupLPWStr Then CoTaskMemFree lpWStr
    End Function
    
    
    Public Function IID_IShellItem() As UUID
    Static IID As UUID
    If (IID.Data1 = 0) Then Call DEFINE_UUID(IID, &H43826D1E, CInt(&HE718), CInt(&H42EE), &HBC, &H55, &HA1, &HE2, &H61, &HC3, &H7B, &HFE)
    IID_IShellItem = IID
    End Function
    Public Sub DEFINE_UUID(Name As UUID, l As Long, w1 As Integer, w2 As Integer, B0 As Byte, b1 As Byte, b2 As Byte, B3 As Byte, b4 As Byte, b5 As Byte, b6 As Byte, b7 As Byte)
      With Name
        .Data1 = l
        .Data2 = w1
        .Data3 = w2
        .Data4(0) = B0
        .Data4(1) = b1
        .Data4(2) = b2
        .Data4(3) = B3
        .Data4(4) = b4
        .Data4(5) = b5
        .Data4(6) = b6
        .Data4(7) = b7
      End With
    End Sub
    Last edited by fafalone; Sep 27th, 2015 at 03:56 AM.

  6. #6
    New Member
    Join Date
    Jan 2009
    Posts
    10

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

    Hallo there,
    I'm trying to use IFileDialog.
    I added a custom button as shown bellow:
    fdc.AddPushButton 1001, "Abandon"
    fdc.MakeProminent 1001 'Moves to by the open button; only checkboxes, buttons, combos, menus can be made prominent
    and I catch the click on it using the FD_ButtonClick event.
    Everything perfect so far. But when the user clicks it I need to return to the calling Form. How is it done? How do I quit the Dialog box just if the user clicked on Cancel button?

    Another question: is it possible to place the Dialog box in the position on the screen I desire?

    Appreciate your reply
    Slobodan Dijaković
    Casa Bustelli
    6864 Arzo
    Switzerland

  7. #7

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

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

    Answered in IFileDialog thread.

  8. #8

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

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

    Major project update to 2.0. Many new interfaces, sample projects, and bugfixes.

  9. #9
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

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

    Quote Originally Posted by fafalone View Post
    Major project update to 2.0. Many new interfaces, sample projects, and bugfixes.
    Switching from Edanmo's olelib.tlb to this version, generates 'method or data member not found' error, when using IDataObject.GetData call.

    olelib.tlb {3181A65A-CC39-4CDE-A4DF-2E889E6F1AF1}

    Code causing error.

    Code:
    Dim m_oSource As IDataObject
    Dim tFMT As FORMATETC
    Dim tSTGM As STGMEDIUM
    
     If m_oSource.GetData(tFMT, tSTGM) = S_OK Then
    Doublechecked referenced version and it's from oleexp 2.0RC.zip package.
    Reference=*\G{3181A65A-CC39-4CDE-A4DF-2E889E6F1AF1}#1.5e#0#olelib.tlb#Edanmo's OLE interfaces & functions v1.94 (modified for oleexp)

    Any idea what might cause this?
    Last edited by Tech99; Aug 3rd, 2015 at 07:18 AM.

  10. #10
    Fanatic Member
    Join Date
    Apr 2015
    Location
    Finland
    Posts
    679

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

    Quote Originally Posted by Tech99 View Post
    Switching from Edanmo's olelib.tlb to this version, generates 'method or data member not found' error, when using IDataObject.GetData call.

    olelib.tlb {3181A65A-CC39-4CDE-A4DF-2E889E6F1AF1}

    Code causing error.

    Code:
    Dim m_oSource As IDataObject
    Dim tFMT As FORMATETC
    Dim tSTGM As STGMEDIUM
    
     If m_oSource.GetData(tFMT, tSTGM) = S_OK Then
    Doublechecked referenced version and it's from oleexp 2.0RC.zip package.
    Reference=*\G{3181A65A-CC39-4CDE-A4DF-2E889E6F1AF1}#1.5e#0#olelib.tlb#Edanmo's OLE interfaces & functions v1.94 (modified for oleexp)

    Any idea what might cause this?
    Edit... variable declaration from integer to long seemed to resolve this.
    Code:
    Private CF_FILECONTENTS As Long 'Integer

  11. #11
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

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

    Μaybe mktyplib is better than MIDL2003..I have problem too with Edanmo Idispatch.tlb. I describe the solution here http://www.vbforums.com/showthread.p...an-handle-Word.
    GetIDsOfNames need an array of strings so a Long* (for pointer) and original Idispatch.tlb from Edanmo has LPSTR*
    So maybe there are more problems with that olelib.

    My question is...Can we use IFileDialog Like I use Word.Application? Can I later bind an object from IFileDialog?

  12. #12

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

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

    Quote Originally Posted by Tech99 View Post
    Edit... variable declaration from integer to long seemed to resolve this.
    Code:
    Private CF_FILECONTENTS As Long 'Integer
    Yeah that's mentioned in the release notes up top... it was changed because of its use with clipboard formats- and RegisterClipbaordFormat was returning larger values than the (signed) Integer type could hold, so it was changed to a Long. Every change the potentially breaks code is documented, and I'm very careful to only do it when absolutely necessary.

  13. #13

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

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

    Quote Originally Posted by georgekar View Post
    Μaybe mktyplib is better than MIDL2003..I have problem too with Edanmo Idispatch.tlb. I describe the solution here http://www.vbforums.com/showthread.p...an-handle-Word.
    GetIDsOfNames need an array of strings so a Long* (for pointer) and original Idispatch.tlb from Edanmo has LPSTR*
    So maybe there are more problems with that olelib.

    My question is...Can we use IFileDialog Like I use Word.Application? Can I later bind an object from IFileDialog?
    If you're talking about passing an array TO a typelib member, it's fairly straightforward, you just change the typelib to expect a LONG and pass a pointer to the first member. If you meant receiving an array... that's a bit more complicated.

    As for late-binding, I haven't really tried it. I'd imagine you probably could with objects that have default implementations like FileOpenDialog, but probably not normal interfaces, though I haven't tried. Why would you really want to?

  14. #14
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

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

    GetIDsOfNames now return an array of long values. As you can see I place an long array to pass names of function in first place and named arguments in other places, and I can get the number of function and the relative numbers of named arguments. I use that in M2000 interpreter.

  15. #15

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

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

    So what does the typelib entry look like now, and is there any special code like CopyMemory to retrieve the full array?

  16. #16
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

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

    This is a part of mdlIDispatch.cls you can find in the code in M2000 source in sign.
    Code:
            long _stdcall GetIDsOfNames(
                            [in] IID* riid, 
                            [in] long* rgszNames,                previous LPSTR* rgszNames,
                            [in] long cNames, 
                            [in] long lcid, 
                            [in, out] long* rgDispId);
    GetIDsOfNames expected pointers and i do the right think...Why there is a cNames? because from pointers there is no way to know how many items in the array used. So I pass the first item of an array as myptr(0). Inside that array I just put pointers to actual strings. I do a redim to varDISPID so after call I get in first place the number of function and on other places the numbers of relative parameter. The good news is that this method works..
    I make the routine to work with mixed types, some named arguments and some in right place, and for working properly in M2000 language you have to place named arguments as the last arguments.
    This is a line of the example as I post in the link above:
    try ok_doc { method doc, "add", "", DocumentType:=WdNewWebPage as doc1 }
    I call add on object doc (is word.application.documents) and i pass an empty string for the first parameter and a documenttype and I get an object the Document object.
    No any special copymemory done..GetIDsOfNames only read the strings (no conversion needed) and put in the provided array the results.

    With old typelib we have this LPSTR* rgszNames, so we place a string and the system place a pointer to one string, so it works but only for the ProcName not for named arguments. Before I found the solution I think to pass a safearray, but it isn't like this, it is more simple.

    Code:
       ReDim myptr(0 To fixnamearg)
                myptr(0) = StrPtr(pstrProcName)    ' this is the method to call
                For lngLoop = 1 To fixnamearg
                myptr(lngLoop) = StrPtr(pargs2(lngLoop))   'these are the names
                Next lngLoop
                    ReDim varDISPID(0 To fixnamearg)
                lngRet = IDsp.GetIDsOfNames(rIid, myptr(0), fixnamearg + 1, cLid, varDISPID(0))
     DISPID = varDISPID(0)

  17. #17

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

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

    varDISPID() is then filled correctly, so varDISPID(1, 2...etc) would have the correct values?

    cNames is the count of items in the array being passed... why wouldn't you know this value? It's just UBound(myptr) + 1 in the code in your post.

  18. #18

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

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

    On an unrelated note, I've been seriously considering combining olelib and oleexp, such that there's only a single file. So it would be more of a fork of olelib rather than an expansion. Of course all credits for the original would remain. Any objections to this?

  19. #19
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

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

    Sorry my English is poor. I know the size of input array. The output array has the same size. The problem for function is that these are not arrays like safe arrays where we found fields that describe the dimension and the size of it. We place the first address and in a variable the length as long items. So cNames is a size both for input and output array. Each array has a long for item, but in first array that long is a pointer to bstr. StrPtr return address of Bstr.
    In old version in typelib we can only provide a string after a convertion to unicode....because vb treat string as ansi, so do a reverse conversion and then put a long as pointer to bstr. There is no way to pass more strings in an array form. So I suspect from cNames that only a buffer of longs passed. Maybe a predefined big buffer can be used for any call to this function.

  20. #20
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

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

    Quote Originally Posted by fafalone View Post
    Using QueryInterface

    The issue came up again for me today when I started using IShellItem2- one of the ways to get that interface by using .QueryInterface from an IShellItem object, which is actually from its parent IUnknown. Due to the way IUnknown was set up in this project, that function isn't visible on IShellItem or any other interface (they all inherit from IUnknown). They can be made visible by changing all the : stdole.IUnknown to just IUnknown, but I'm unsure of the consequences of such a change, and olelib is too massive to confirm there's no side effects.
    But fear not, if you need to access .QueryInterface, use the method in this routine that gets IShellItem2 from IShellItem

    Code:
    Dim psi As IShellItem
    Dim psi2 As IShellItem2
    Dim pUnk As olelib.IUnknown 'should be explicitly typed since there's another hidden IUnknown in VB and it will cause errors
    
    Call SHCreateShellItem(0, 0, pidl, psi) 'pidl of whatever file/object you're working with, code omitted
    
    Set pUnk = psi
    pUnk.QueryInterface IID_IShellItem2, psi2
    And now you have a ready-to-go IShellItem2. This method is also used, for example, to get an IPropertyStore interface from an IShellLinkW.
    Manually invoking IUnknown's QueryInterface method isn't actually necessary in Visual Basic. The Set statement already does it for you.

    Quote Originally Posted by Guy Eddon and Henry Eddon
    QueryInterface: The Visual Basic Way

    . . . If you need access to the other (nondefault) interfaces supported by an object, you can execute a QueryInterface using the Set statement. If needed, the Set statement calls the IUnknown::QueryInterface method to cast the rvalue interface pointer to the type of the lvalue reference. For example, the following code snippet shows two references—MyRef1 and MyRef2. MyRef1 is declared as an IUnknown interface pointer; MyRef2 is a pointer to the IMyInterface interface. When MyRef2 is set to MyRef1, a QueryInterface call that requests the IMyInterface interface pointer from the object pointed to by MyRef1 takes place.

    Code:
    Dim MyRef1 As IUnknown
    Set MyRef1 = New MyObject
    
    Dim MyRef2 As IMyInterface
    Set MyRef2 = MyRef1 ' QueryInterface executed!
    Quote Originally Posted by Jose Mojica
    How Visual Basic COM+ Objects Work Internally

    . . .

    Why does every vtable need to have these three methods? By enforcing this rule, a client may navigate to any lookup table from any starting point. In other words, suppose that I have the following code:

    Code:
    Dim Checking As CChecking
    Set Checking = New CChecking
    
    Call Checking.OrderChecks(100, 132)
    
    Dim Acct As IAccount
    Set Acct = Checking
    
    Call Acct.MakeDeposit(500)
    
    Dim Checking2 As CChecking
    Set Checking2 = Acct
    The code begins by using the default lookup table, then needs to switch to using the IAccount lookup table (or vtable). The line that reads Set Acct = Checking basically calls the QueryInterface function in the default vtable. The resulting vptr is stored in the Acct variable. I can then use that lookup table to switch to any other interface. In the code above I have a second variable to store the default vtable, Checking2. Which interface can I use to switch to the default interface? I can use any other interface, because they all have the QueryInterface method first. In VB you never have to see the QueryInterface method call. However each time you change the interface you are talking to, you are basically telling VB to call QueryInterface on the particular interface to obtain a second vptr.
    These 2 lines of code can therefore be reduced to just 1:

    Code:
    'Set pUnk = psi
    'pUnk.QueryInterface IID_IShellItem2, psi2
    
    Set psi2 = psi
    The code can be simplified even further by taking advantage of the fact that the IShellItem2 interface inherits from IShellItem:

    Code:
    Call SHCreateShellItem(0, 0, pidl, psi2)
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  21. #21

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

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

    Good to know. I didn't know Set called QueryInterface internally, so had just been using the QueryInterface like I saw in the C++ examples I learned from, and just used Set for an inherited interfaces parent.

  22. #22

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

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

    Quote Originally Posted by georgekar View Post
    Sorry my English is poor. I know the size of input array. The output array has the same size. The problem for function is that these are not arrays like safe arrays where we found fields that describe the dimension and the size of it. We place the first address and in a variable the length as long items. So cNames is a size both for input and output array. Each array has a long for item, but in first array that long is a pointer to bstr. StrPtr return address of Bstr.
    In old version in typelib we can only provide a string after a convertion to unicode....because vb treat string as ansi, so do a reverse conversion and then put a long as pointer to bstr. There is no way to pass more strings in an array form. So I suspect from cNames that only a buffer of longs passed. Maybe a predefined big buffer can be used for any call to this function.
    The output array has the same number of items as the input array, so passed as in your code, the output array is filled for all items?

  23. #23
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

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

    That is the idea when you call a function with 2 named arguments you have 3 names and you get 3 numbers. First number is the number of function and the two others is the real position of the named arguments.

  24. #24

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

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

    Quote Originally Posted by Bonnie West View Post
    Manually invoking IUnknown's QueryInterface method isn't actually necessary in Visual Basic. The Set statement already does it for you.
    [...]
    The one problem I've had with this; if you just use the Set statement, and QueryInterface fails (a rare scenario, but one I just encountered*), then you get a Type Mismatch error which would have to go through your error handler or have its own on error resume next statement and then verification that the new object <> nothing. With the QueryInterface method, you can get the HRESULT without an error if it fails, then proceed accordingly.

    *The scenario popped up in using IPreviewHandler. To initialize it, an object may implement IInitializeWithFile, IInitializeWithStream, or IInitializeWithItem. Most only implement one of these, and there's no way to know beforehand (or if there is it's so obscure that every example still uses trial and error). There's sure to be other scenarios or true errors in QueryInterface calls.

  25. #25
    Lively Member
    Join Date
    Aug 2008
    Location
    Denmark
    Posts
    85

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

    Thanks - this is cool alone and with all the examples excellent!

  26. #26

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

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

    So I figured the most useful place to put it was an addon to this project, but this is of wider interest:

    There's a new attachment called mPKEY.zip that contains mPKEY.bas - a complete VB version of SDK 7.1's propkey.h, containing all the PROPERTYKEY variables. Like the IID module, these are set up to be used directly without conversion in any interface or API that asks for a PROPERTYKEY.

  27. #27
    New Member
    Join Date
    Mar 2015
    Posts
    4

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

    Hello Fafalone.
    Can you help me please to transform the old IBindStatusCallback_OnProgress Sub in a Function (as it should)?
    More precisely, it seems that all urlmon callback functions are defined by Morcillo as Sub instead of Functions. http://www.tek-tips.com/viewthread.cfm?qid=1626482
    I wan't waste your time, so if you give me basic steps to modify tlb, it's ok.

    Thank you in advance

    gigirex

  28. #28

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

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

    It's not E.M.'s fault; VB requires any Implements interface to use only Subs. (you can see one specific as a function; but you can only do that if you're returning a variable that's the last param and marked as [out]). A few things here and there have been changed to functions in oleexp, but those interfaces aren't used with Implements.

    In situations like this, where other implementations exist that rely on it being a sub, it's highly inadvisable to change the typelib (and in this specific case, impossible, since there are no [out] arguments, so the only thing to return is the HRESULT which VB doesn't allow). What you should do instead is simply swap out the function:

    In a module (bas), put the following, a routine to swap them, and the new function (i'll assume you already have CopyMemory declared, if not add it):
    Code:
    Public Declare Function VirtualProtect Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
    Public Const PAGE_EXECUTE_READWRITE As Long = &H40&
    
    Public Function SwapVtableEntry(pObj As Long, EntryNumber As Integer, ByVal lpfn As Long) As Long
    
        Dim lOldAddr As Long
        Dim lpVtableHead As Long
        Dim lpfnAddr As Long
        Dim lOldProtect As Long
    
        CopyMemory lpVtableHead, ByVal pObj, 4
        lpfnAddr = lpVtableHead + (EntryNumber - 1) * 4
        CopyMemory lOldAddr, ByVal lpfnAddr, 4
    
        Call VirtualProtect(lpfnAddr, 4, PAGE_EXECUTE_READWRITE, lOldProtect)
        CopyMemory ByVal lpfnAddr, lpfn, 4
        Call VirtualProtect(lpfnAddr, 4, lOldProtect, lOldProtect)
    
        SwapVtableEntry = lOldAddr
    
    End Function
    Public Function IBSCBOnProgress(ByVal this As IBindStatusCallback, ByVal ulProgress As Long, ByVal ulProgressMax As Long, ByVal ulStatusCode As BINDSTATUS, ByVal szStatusText As Long) As Long
    'all code for OnProgress goes here
    End Function
    You still need the prototype (Private Sub IBindStatusCallback_OnProgress...) in your class module, but all code should be relocated to the OnProgress in the module. In your class module which contains the 'Implements IBindStatusCallback' statement, add a module level variable:
    Private mOldOP As Long
    then in Class_Initialize, add:
    Code:
    Dim pVTable As IBindStatusCallback
    Set pVTable = Me
    mOldOP = SwapVtableEntry(ObjPtr(pVTable), 7, AddressOf IBSCBOnProgress)
    and in Class_Terminate, add:
    Code:
    Dim pVTable As IBindStatusCallback
    Set pVTable = Me
    mOldOP = SwapVtableEntry(ObjPtr(pVTable), 7, mOldOP)
    And now everything is redirected to the function version. for reference, the '7' is the entry number we're changing, we start at 4 (1-3 are for IUnknown), so that makes OnProgress 7th.
    Last edited by fafalone; Dec 8th, 2015 at 02:37 PM.

  29. #29
    New Member
    Join Date
    Mar 2015
    Posts
    4

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

    Woooow Fafalone!
    Really, ignorantly, I supposed that the solution was more simple than that you have skilfully exposed here.
    Thank you very much for the explanation. I'll test it in next days.

    Regards,
    Luigi Stilo

  30. #30

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

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

    It should be easy... it makes no sense at all that VB turns HRESULT-returning function into Subs. So don't feel bad at all about it, everyone is like 'what the heck????' the first they come across it, me included. And full disclosure, somebody else wrote the SwapVtable function; not sure of the original source tho, it's appeared all over code and in books forever.

  31. #31
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

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

    Quote Originally Posted by fafalone View Post
    ... it makes no sense at all that VB turns HRESULT-returning function into Subs.
    It's likely due to VB's goal of hiding as much complexity from the programmer as possible. All programmer-defined methods and properties in object modules (CLS, FRM, CTL, etc.) returns a hidden HRESULT, even Subs (the HRESULT contains the error code raised in the procedure, if any). A Function's programmer-defined return value is actually declared as the last parameter and it is passed ByRef. When VB sees that a TLB-declared Function returns an HRESULT, it treats that as a Sub, unless its last argument is passed ByRef and is given the attributes [out, retval], in which case, it is recognized as a Function.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  32. #32

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

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

    the HRESULT contains the error code raised in the procedure, if any
    You know.. I've seen this before but had always assumed it was just for handling inside VB... if you used the Err.Raise statement inside a class sub (under the circumstances here, where's it's a VB-implemented callback for a COM interface implemented outside of VB), will that return the value specified as the HRESULT to the main interface outside VB?

    Edit: Yes; but it causes a major app error where you'd have to have a custom error handler for the line it gets raised on. So SwapVtable is a better solution.
    Example: INamespaceWalkCB is a callback for an Explorer-implemented NamespaceWalker object. The only way to cancel a directory walk is to return ERROR_CANCELLED as the HRESULT for INamespaceWalkCB_EnterFolder. Using Err.Raise causes a runtime error on the NamespaceWalker.Walk method that initiated the walk. If continued from that line, the walk continues, but it does provide an opportunity to resume on the next line.
    Last edited by fafalone; Dec 9th, 2015 at 04:15 PM.

  33. #33
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

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

    Where is the download link to get the latest version this oleexp.tlb file? There's a very very very long description of what it can do in the opening thread, but I can't find the download link. It may be buried in the text somewhere, but I didn't manage to find it. Please post the link somewhere where I can find it. I'd really like to try this thing out.

  34. #34
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,401

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

    Look at the bottom of the first post in the Attached Files section for the download link.

  35. #35

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

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

    If I add a link at the top then it removes the icons/gray box at the bottom (could add another text link at the bottom too, but can't get the normal box with icons back).. and that I had thought would actually make it harder to find. But unless these manual plain text links are set up, the default download box is always at the bottom of the post.

    Also in case you're looking for a new version of "oleexp.tlb" exactly.. when the version numbers got to 3.0 a few months ago the project was combined with olelib into a single file with a new GUID, so now oleexp3.tlb replaces both olelib.tlb and oleexp.tlb (any variables declared like Dim x As olelib.Type or Dim x As oleexp.Type can be automatically replaced with Dim x As oleexp3.Type)

  36. #36
    Lively Member
    Join Date
    Apr 2009
    Posts
    64

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

    Hi all,

    I have been trying to make this following code work in Windows 64bit but without any success

    Any help anyone on how to make it work for Windows 64 bit ... Thanks

    Code:
    Public Declare Function VirtualProtect Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
    Public Const PAGE_EXECUTE_READWRITE As Long = &H40&
    
    Public Function SwapVtableEntry(pObj As Long, EntryNumber As Integer, ByVal lpfn As Long) As Long
    
        Dim lOldAddr As Long
        Dim lpVtableHead As Long
        Dim lpfnAddr As Long
        Dim lOldProtect As Long
    
        CopyMemory lpVtableHead, ByVal pObj, 4
        lpfnAddr = lpVtableHead + (EntryNumber - 1) * 4
        CopyMemory lOldAddr, ByVal lpfnAddr, 4
    
        Call VirtualProtect(lpfnAddr, 4, PAGE_EXECUTE_READWRITE, lOldProtect)
        CopyMemory ByVal lpfnAddr, lpfn, 4
        Call VirtualProtect(lpfnAddr, 4, lOldProtect, lOldProtect)
    
        SwapVtableEntry = lOldAddr
    
    End Function

  37. #37
    Hyperactive Member
    Join Date
    Feb 2015
    Location
    Colorado USA
    Posts
    261

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

    It depends on whether you mean you want to run a 32-bit program in Windows 64 or whether you want to make a 64-bit program and then run that in 64-bit Windows. If you are using Visual Basic 6 it can't make a 64-bit program so whatever you compile to will be 32-bit, in which case you don't have to make any changes. In the VB6 case, just compile and run the program because it is very common for 32-bit programs like what VB6 makes to run inside of Windows 64.

    The only way I know to make 64-bit code using VB or VBA is to run the code in VBA in a 64-bit version of Microsoft Office (not a 32-bit version running in 64-bit Windows). In this case you need to make the following changes:

    1) You have to change all of the "4" values to "8" because a memory address in Windows 64 is 8 bytes long, not 4 like it is in 32-bit Windows.

    2) Your pointer variables need to change to LongPtr from Long (note that LongPtr does not exist in VB6). It is somewhat confusing because in 32-bit code you use a Long variable to represent a pointer or an actual Long variable so you have to study the code a bit to figure out what are pointers that need to be changed to LongPtr. Note that LongPtr was introduced in Office 2010 and you can use it in 32 or 64 bit Office. In 32-bit Office LongPtr gets converted to Long automatically.

    3) You would have to execute the code below on a 64-bit Office program in VBA. Thee is a requirement if you do that you have to add the word PtrSafe into any Windows API declaration to show that you have thought through the necessary change in the WIndows function call.

    I haven't tested your code but I believe it should look like the following:

    Code:
    Public Declare PtrSafe Function VirtualProtect Lib "kernel32" (ByVal lpAddress As LongPtr, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As LongPtr) As Long
    Public Const PAGE_EXECUTE_READWRITE As Long = &H40&
    
    Public Function SwapVtableEntry(pObj As LongPtr, EntryNumber As Integer, ByVal lpfn As LongPtr) As LongPtr
    
        Dim lOldAddr As LongPtr
        Dim lpVtableHead As LongPtr
        Dim lpfnAddr As LongPtr
        Dim lOldProtect As LongPtr
    
        CopyMemory lpVtableHead, ByVal pObj, 8
        lpfnAddr = lpVtableHead + (EntryNumber - 1) * 8
        CopyMemory lOldAddr, ByVal lpfnAddr, 8
    
        Call VirtualProtect(lpfnAddr, 8, PAGE_EXECUTE_READWRITE, lOldProtect)
        CopyMemory ByVal lpfnAddr, lpfn, 8
        Call VirtualProtect(lpfnAddr, 8, lOldProtect, lOldProtect)
    
        SwapVtableEntry = lOldAddr
    
    End Function
    Now it starts getting interesting if you want to be able to run this code in 32-bit Office (what probably 99.9% of people use up to this point) AND to be able to run in 64-bit Windows without having to change code.

    The way we do that is to use a conditional compilation constant that tells the code compiler which version is trying to compile it and we'll have two sets of code and tell it to only use the code for the type (32 or 64 bit) that is running. I would do this like this:

    Code:
    #If Win64 Then
    Public Declare PtrSafe Function VirtualProtect Lib "kernel32" (ByVal lpAddress As LongPtr, _
       ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As LongPtr) As Long
    Public Const PAGE_EXECUTE_READWRITE As Long = &H40&
    
    Public Function SwapVtableEntry(pObj As LongPtr, EntryNumber As Integer, ByVal lpfn As LongPtr) As LongPtr
    
        Dim lOldAddr As LongPtr
        Dim lpVtableHead As LongPtr
        Dim lpfnAddr As LongPtr
        Dim lOldProtect As LongPtr
    
        CopyMemory lpVtableHead, ByVal pObj, 8
        lpfnAddr = lpVtableHead + (EntryNumber - 1) * 8
        CopyMemory lOldAddr, ByVal lpfnAddr, 8
    
        Call VirtualProtect(lpfnAddr, 8, PAGE_EXECUTE_READWRITE, lOldProtect)
        CopyMemory ByVal lpfnAddr, lpfn, 8
        Call VirtualProtect(lpfnAddr, 8, lOldProtect, lOldProtect)
    
        SwapVtableEntry = lOldAddr
    
    End Function
    
    #Else
    Public Declare Function VirtualProtect Lib "kernel32" (ByVal lpAddress As Long, _
        ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
    Public Const PAGE_EXECUTE_READWRITE As Long = &H40&
    
    Public Function SwapVtableEntry(pObj As Long, EntryNumber As Integer, ByVal lpfn As Long) As Long
    
        Dim lOldAddr As Long
        Dim lpVtableHead As Long
        Dim lpfnAddr As Long
        Dim lOldProtect As Long
    
        CopyMemory lpVtableHead, ByVal pObj, 4
        lpfnAddr = lpVtableHead + (EntryNumber - 1) * 4
        CopyMemory lOldAddr, ByVal lpfnAddr, 4
    
        Call VirtualProtect(lpfnAddr, 4, PAGE_EXECUTE_READWRITE, lOldProtect)
        CopyMemory ByVal lpfnAddr, lpfn, 4
        Call VirtualProtect(lpfnAddr, 4, lOldProtect, lOldProtect)
    
        SwapVtableEntry = lOldAddr
    
    End Function
    #End If
    There is obviously a lot of code overlap so if you are really adventuresome you could smush stuff together and do the following:

    Code:
    #If Win64 Then
    Public Declare PtrSafe Function VirtualProtect Lib "kernel32" (ByVal lpAddress As LongPtr, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As LongPtr) As Long
    #Else
    Public Declare Function VirtualProtect Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
    #End If
    ' I left the two declarations above the code because it allows you to put other Windows
    '  calls in there if your code has any.
    
    '
    '  Any other code you want to put here.
    '
    
    #If Win64 Then
    Public Function SwapVtableEntry(pObj As LongPtr, EntryNumber As Integer, ByVal lpfn As LongPtr) As LongPtr
    Const BytesPerAddr as Long = 8
    
        Dim lOldAddr As LongPtr
        Dim lpVtableHead As LongPtr
        Dim lpfnAddr As LongPtr
        Dim lOldProtect As LongPtr
    #Else
    Public Function SwapVtableEntry(pObj As Long, EntryNumber As Integer, ByVal lpfn As Long) As Long
    Const BytesPerAddr as Long = 4
    
        Dim lOldAddr As Long
        Dim lpVtableHead As Long
        Dim lpfnAddr As Long
        Dim lOldProtect As Long
    #End If
    
        CopyMemory lpVtableHead, ByVal pObj, BytesPerAddr
        lpfnAddr = lpVtableHead + (EntryNumber - 1) * BytesPerAddr
        CopyMemory lOldAddr, ByVal lpfnAddr, BytesPerAddr
    
        Call VirtualProtect(lpfnAddr, BytesPerAddr, PAGE_EXECUTE_READWRITE, lOldProtect)
        CopyMemory ByVal lpfnAddr, lpfn, BytesPerAddr
        Call VirtualProtect(lpfnAddr, BytesPerAddr, lOldProtect, lOldProtect)
    
        SwapVtableEntry = lOldAddr
    
    End Function
    What I did above is much harder to read unless you do this a lot (like I do) so you may be better off not combining the code and using the version above.

  38. #38
    Lively Member
    Join Date
    Apr 2009
    Posts
    64

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

    Thank you very much Mountainman,

    Based on your answer, I have successfully managed to override the CalculateFull Method of the Excel application object ... The CalculateFull Propery vtable offset happens to be 319 ... See code below :

    Proceedings : Run the HookCOMFunction first in order to hook the CalculateFull Propery and then run the Test macro

    Code:
    Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    Destination As Any, _
    Source As Any, _
    ByVal length As LongPtr _
    )
    
    Private Declare PtrSafe Function VirtualProtect Lib "kernel32" _
    (ByVal lpAddress As LongPtr, ByVal dwSize As LongPtr, _
    ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As Long
    
    
    Private Const PAGE_EXECUTE_READWRITE As Long = &H40&
    Private Const lFuncOffset = 319  'Excel Application.calculateFull Method VTable Offset
    Private pVTable As LongPtr
    Private bHooked As Boolean
    Private lOldAddr As LongPtr
    
    Sub HookCOMFunction()
        Dim lOldAddr As LongPtr
        Dim lpVtableHead As LongPtr
        Dim lpfnAddr As LongPtr
        Dim lOldProtect As LongPtr
        Dim pObj As LongPtr
        pObj = CLngPtr(ObjPtr(Application))
    
        CopyMemory lpVtableHead, ByVal pObj, 8
        lpfnAddr = lpVtableHead + (lFuncOffset) * 8
        CopyMemory lOldAddr, ByVal lpfnAddr, 8
    
        Call VirtualProtect(lpfnAddr, 8, PAGE_EXECUTE_READWRITE, lOldProtect)
        CopyMemory ByVal lpfnAddr, AddressOf OverrideFunction, 8
        Call VirtualProtect(lpfnAddr, 8, lOldProtect, lOldProtect)
    End Sub
    
    
    Private Function OverrideFunction(ByVal voObjPtr As Long, ByVal Param As Long) As Long
        MsgBox "Excel 'CalculateFull' Method has been Hooked !!"
    End Function
    
    
    Sub Test()
        Application.CalculateFull
    End Sub
    The only thing that i haven't managed to do is to restore CalculateFull Property back to its original vtable address ... the following code crashes the excel application :
    Code:
    Sub UnHookComFunction()
        CopyMemory lpfnAddr, ByVal lOldAddr, 8
    End Sub
    Also, (and this is my ultimate goal) is there a way to make this work when executing the CalculateFull Method via the excel user interface (ie via the excel menu) as opposed to the hook only working when the CalculateFull Method is excecuted via code as in the Test macro aboe ?

    Thanks for your help one more time

  39. #39
    Hyperactive Member
    Join Date
    Feb 2015
    Location
    Colorado USA
    Posts
    261

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

    I believe the problem is that you hve defined lOldAddr both in your HookCOMFunction procedure and also as a module level variable. When you first determined the value for lOldAddr you are doing it inside of the HookCOMFunction procedure but when that procedure goes out of focus you lose all of the procedure variables including lOldAddr. Normally this would cause a syntax error later when you tried to re-use it to re-set the address because in UnHookComFunction you don't have this variable. However, in this case another variable of the same name exists at the module level and although it has really never been used (i.e., it has a value of 0) your function uses it anyway which I am sure Windows doesn't like. My suggestion is to get rid of the lOldAddr variable in the HookCOMFunction procedure and only use the module-level variable of that name.

    BTW, I also suggest that you don't make all of your passed parameters to be LongPtr. It is true (I think) that in 64-bit Windows all parameters passed to a function or sub are passed as 64-bit values but it can cause you problems later. For example, you are calling the Windows API function VirtualProtect whose 2nd parameter is dwSize. When the Windows documentation shows a variable starting with "dw" it means it is a double word, a 32-bit value. If you pass a LongPtr it will go on the stack as a 64-bit value and VBA will pass the whole value. This means that if somehow you were to put a value larger than a Long to be passed that VBA would just pass it along but the function is really expecting the top 4 bytes to be 0 since it is only going to use the bottom 4 bytes. I prefer to list the parameter in the call as a Long (which is what the function expects) and I will count on VBA to make the top 4 bytes a 0 when it really puts it on the stack as a 64-bit number. That way I feel a lot better than a) I own't ever mess up and give it a value that is out-of-range of what the function wants by being too big and b) when we go to a 129-bit operating system I don't have to go back in and check each variable I am passing to make sure that it is the right size. What you have done though will work; I just think you are setting yourself up for problems down the road.

  40. #40

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

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

    Quote Originally Posted by RAFAAJ2000 View Post
    Also, (and this is my ultimate goal) is there a way to make this work when executing the CalculateFull Method via the excel user interface (ie via the excel menu) as opposed to the hook only working when the CalculateFull Method is excecuted via code as in the Test macro aboe ?
    Well in principle, you could subclass the process and intercept the menus WM_COMMAND message, but subclassing a 64-bit app might be challenging.

Page 1 of 9 1234 ... 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