Results 1 to 13 of 13

Thread: Implementing interfaces that inherit from IDispatch

  1. #1

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

    Implementing interfaces that inherit from IDispatch

    I'm trying to take a look into what it might take to register as a shell window with IShellWindow.Register and be in a position to respond to the SHOpenFolderAndSelectItems API, which will be looking for the IShellFolderViewDual and IWebBrowserApp interfaces, which both inherit from IDispatch.

    Does anyone here have any experience with implementing such interfaces in a class? Really looking for anything that inherits from IDispatch, just for the general structure, since I've never tried to implement IDispatch before, or anything not inheriting directly from IUnknown. Googled a bit and couldn't find much.

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

    Re: Implementing interfaces that inherit from IDispatch

    Inheritance from IDispatch is normal. All VB6 classes inherit from IDispatch so when you implement these you are actually implementing interfaces that inherit from IDispatch

    All dual interfaces inherit from IDispatch too. Not inheriting from IDispatch is rare in VB-land.

    You don't see IDispatch methods in the IDE the way you don't see IUnknown ones too.

    cheers,
    </wqw>

  3. #3
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: Implementing interfaces that inherit from IDispatch

    What does IDispatch do anyway? I swear I've read about it a thousand times for years and I still don't know what it really does. COM is just so damn complicated lol....

    EDIT:

    More importantly, how does it relate to the IUknown interface. Like how do these interfaces work together to make objects function in VB6/VBA? I've never been able to figure that out.
    Last edited by Niya; Jan 14th, 2022 at 01:50 PM.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  4. #4

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

    Re: Implementing interfaces that inherit from IDispatch

    Quote Originally Posted by wqweto View Post
    Inheritance from IDispatch is normal. All VB6 classes inherit from IDispatch so when you implement these you are actually implementing interfaces that inherit from IDispatch

    All dual interfaces inherit from IDispatch too. Not inheriting from IDispatch is rare in VB-land.

    You don't see IDispatch methods in the IDE the way you don't see IUnknown ones too.

    cheers,
    </wqw>
    Right but when you implement an interface that inherits from IUnknown, when you want to swap vtable entries you start from 4 in an object using Implements. Since IDispatch inherits from IUnknown, how could it be the same? Are you saying that if I have an interface that inherits from IDispatch, e.g. my IShellFolderViewDual, I'm able to just do a standard Implements IShellFolderViewDual without having to also implement IDispatch manually? I'm going to need to swap vtable entries, would I just start at 8?

  5. #5
    PowerPoster PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Pontypool, Wales
    Posts
    2,474

    Re: Implementing interfaces that inherit from IDispatch

    Quote Originally Posted by Niya View Post
    What does IDispatch do anyway? I swear I've read about it a thousand times for years and I still don't know what it really does. COM is just so damn complicated lol....

    EDIT:

    More importantly, how does it relate to the IUknown interface. Like how do these interfaces work together to make objects function in VB6/VBA? I've never been able to figure that out.
    https://docs.microsoft.com/en-gb/win...ectedfrom=MSDN

    IUnknown is pretty much the fundamental COM interface, everything inherits from this. IDispatch is pretty much what all the automation side of COM is built on top of.

    That is a very simplified view, but those two interface underpin COM.

  6. #6
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: Implementing interfaces that inherit from IDispatch

    Quote Originally Posted by PlausiblyDamp View Post
    https://docs.microsoft.com/en-gb/win...ectedfrom=MSDN

    IUnknown is pretty much the fundamental COM interface, everything inherits from this. IDispatch is pretty much what all the automation side of COM is built on top of.

    That is a very simplified view, but those two interface underpin COM.
    I know that they are important and I have a very general idea of what they do but like I don't really know what they actually do. Like for example, when you use objects in VB6, what parts do these interfaces play? What specifically are the doing? What methods on which interfaces get called and for what actions performed on or performed by objects in VB6 would these methods get called? You know stuff like that. I never understood exactly how they play a part in VB6, VBA and VBScript code.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  7. #7

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

    Re: Implementing interfaces that inherit from IDispatch

    Code:
        [
            uuid(E7A1AF80-4D96-11CF-960C-0080C7F4EE85), // IID_IShellFolderViewDual
            helpstring("definition of interface IShellFolderViewDual"),
            oleautomation,
            hidden,
            dual
        ]
        interface IShellFolderViewDual : IDispatch
        {
            [propget, helpstring("Get Application object")]
            HRESULT Application([out, retval] IDispatch **ppid);
    I'm using the shell32 object at this point, haven't attempted change anything or put it in my typelib.

    Code:
    Implements Shell32.IShellFolderViewDual
    
    
    Private Property Get IShellFolderViewDual_Application() As stdole.IDispatch
    
    End Property
    Gives me a 'marked as restricted or unsupported automation type' error. I was thinking of stripping it down and putting it in my typelib... I'm not sure if it's the IDispatch return type or the 'oleautomation'/'dual' properties.

    I switched it to oleexp.IDispatch (my tlb defines it manually), and that *temporarily* prevented the error... once I corrected everything else, it went right back to erroring, this time with 'marked as restricted or unsupported automation type'.

    Could be I have to re-do everything with long pointers for objects, but really hoping someone has done this with *any* IDispatch based interface.
    Last edited by fafalone; Jan 14th, 2022 at 09:29 PM.

  8. #8
    Lively Member vbLewis's Avatar
    Join Date
    Feb 2009
    Location
    USA
    Posts
    126

    Re: Implementing interfaces that inherit from IDispatch

    Im no com expert, but i do know that IDispatch is the interface used to access an object with late-binding, i.e Createobject() and friends... Im guessing the IDispInvoke interface is then used to call methods
    learned through IDispatch.
    When you create a reference in VB via the references dialog, the objects type library is used to get information for early-binding/direct-call same as classes/controls you create in VB in your project.

  9. #9

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

    Re: Implementing interfaces that inherit from IDispatch

    Niya, IDispatch is used for late-binding calls (not vtable-based, but ID-based). There are also Dual interfaces which supports both - ID-based and VTable-based calls. All the ID-based calls / dual-interfaces are automation-compatible so Universal marshaller is used to marshal data if need. ID-based interfaces are very flexible because allow to implement dynamic interfaces. For example you can create an object based on JSON-request. There are also dispinterfaces which describes members which have the fixed-id values so your code can call ID-based method without name-binding mechanism (VB6 have some). Dispinterfaces also can be extensible or non-extensible.

  11. #11

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

    Re: Implementing interfaces that inherit from IDispatch

    Initially I had simply added a reference to shell32.dll, so I'm not sure what was triggering the error or not.

    Later I put it in my oleexp.tlb project, which I compile with MKTYPLIB.EXE that comes with Visual Studio 6.0. I've never had any luck using a newer compiler. It just spams errors about files it can't find until I give up.

    I rewrote the interface to a form that switched IDispatch to long, to pass ObjPtr, which I use with some interfaces. But, it didn't give an error and successfully compiled the prototypes. Though I'm unsure if it will work the same.

    On the left is the definition from the SDK, on the right it what I rewrote it as.
    Code:
        [
            uuid(E7A1AF80-4D96-11CF-960C-0080C7F4EE85), // IID_IShellFolderViewDual
            helpstring("definition of interface IShellFolderViewDual"),
            oleautomation,
            hidden,
            dual
        ]
        interface IShellFolderViewDual : IDispatch
        {
            [propget, helpstring("Get Application object")]
            HRESULT Application([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get Parent object")]
            HRESULT Parent([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get the folder being viewed")]
            HRESULT Folder([out, retval] Folder **ppid);
    
            [helpstring("The collection of Selected Items in folder")]
            HRESULT SelectedItems([out, retval] FolderItems **ppid);
    
            [propget, helpstring("The currently focused item in the folder")]
            HRESULT FocusedItem([out, retval] FolderItem **ppid);
    
            [helpstring("Select the item")]
            HRESULT SelectItem([in]VARIANT *pvfi, [in] int dwFlags);
    
            [helpstring("Show items menu and return command selected")]
            HRESULT PopupItemMenu([in]FolderItem *pfi, [in, optional]VARIANT vx, [in, optional]VARIANT vy, [out, retval] BSTR *pbs);
    
            [propget, helpstring("Returns the scripting automation model."), helpcontext(0x0000)]
            HRESULT Script([out,retval] IDispatch** ppDisp);
    
            [propget, helpstring("Returns the view options for showing a folder."), helpcontext(0x0000)]
            HRESULT ViewOptions([out,retval] long * plViewOptions);
        }
    Code:
    [
    	odl,
    	uuid(E7A1AF80-4D96-11CF-960C-0080C7F4EE85), // IID_IShellFolderViewDual
    	helpstring("definition of interface IShellFolderViewDual"),
    ]
    interface IShellFolderViewDual : stdole.IDispatch
    {
    	[propget, helpstring("Get Application object")]
    	HRESULT Application([out, retval] long *ppid);
    
    	[propget, helpstring("Get Parent object")]
    	HRESULT Parent([out, retval] long *ppid);
    
    	[propget, helpstring("Get the folder being viewed")]
    	HRESULT Folder([out, retval] long *ppid);
    
    	[helpstring("The collection of Selected Items in folder")]
    	HRESULT SelectedItems([out, retval] long *ppid);
    
    	[propget, helpstring("The currently focused item in the folder")]
    	HRESULT FocusedItem([out, retval] long *ppid);
    	
    	[helpstring("Select the item")]
    	HRESULT SelectItem([in]VARIANT *pvfi, [in] int dwFlags);
    
    	[helpstring("Show items menu and return command selected")]
    	HRESULT PopupItemMenu([in] long pfi, [in] VARIANT vx, [in]VARIANT vy, [out, retval] BSTR *pbs);
    
    	[propget, helpstring("Returns the scripting automation model."), helpcontext(0x0000)]
    	HRESULT Script([out, retval] long *ppDisp);
    
    	[propget, helpstring("Returns the view options for showing a folder."), helpcontext(0x0000)]
    	HRESULT ViewOptions([out, retval] long * plViewOptions);
    }

    And then wrote the following prototypes:

    Code:
    Implements oleexp.IShellFolderViewDual
    
    Private Sub IShellFolderViewDual_Application(ppid As Long)
    
    End Sub
    Private Sub IShellFolderViewDual_Parent(ppid As Long)
    
    End Sub
    Private Sub IShellFolderViewDual_Folder(ppid As Long)
    
    End Sub
    Private Function IShellFolderViewDual_SelectedItems() As Long
    
    End Function
    Private Function IShellFolderViewDual_FocusedItem() As Long
    
    End Function
    Private Sub IShellFolderViewDual_SelectItem(pvfi As Variant, ByVal dwFlags As Long)
    
    End Sub
    Private Function IShellFolderViewDual_PopupItemMenu(ByVal pfi As Long, ByVal vx As Variant, ByVal vy As Variant) As String
    
    End Function
    Private Sub IShellFolderViewDual_Script(ppDisp As Long)
    
    End Sub
    Private Function IShellFolderViewDual_ViewOptions() As Long
    
    End Function
    This is compiling without error.

    Some questions:

    -Does this seem sound in general? Propgets work in this sort of scenario?

    -Returning stdole.IDispatch from the propgets triggered the 'automation type not supported' error. It's the same case if I convert it to a function. Which is odd, because other interfaces in the TLB can be returned like that. I can't point it at oleexp.IDispatch, the compiler doesn't recognize that as an IDispatch.

    -I can't mark the interface as dual. MKTYPLIB raises fatal error M0001: Syntax error near line 4772 column 41: Base interface of Dual interface must be IDispatch, or an interface that derives from IDispatch. However as you can see from above, it is indeed inheriting from IDispatch. If I make it inherit from the version of IDispatch in the TLB, does that matter? Does this even matter to Windows?

    The context is eventually registering it as a shell window and having it passed to a function inside shell32.dll that calls IShellWindows.FindWindowSW, from which it calls QueryInterface for IWebBrowserApp, then eventually IShellFolderViewDual...

    Code:
    SHSTDAPI SHOpenFolderAndSelectItems(LPCITEMIDLIST pidlFolder, UINT cidl, LPCITEMIDLIST *apidl, DWORD dwFlags)
    {
        HRESULT hr;
        if (0 == cidl)
        {
            // overload the 0 item case to mean pidlFolder is the full pidl to the item
            LPITEMIDLIST pidlTemp;
            hr = SHILClone(pidlFolder, &pidlTemp);
            if (SUCCEEDED(hr))
            {
                ILRemoveLastID(pidlTemp); // strip to the folder
                LPCITEMIDLIST pidl = ILFindLastID(pidlFolder);
    
                hr = SHOpenFolderAndSelectItems(pidlTemp, 1, &pidl, 0); // recurse
    
                ILFree(pidlTemp);
            }
        }
        else
        {
            IShellFolderViewDual *psfv;
            hr = OpenFolderAndGetView(pidlFolder, &psfv);
            if (SUCCEEDED(hr))
            {
                DWORD dwSelFlags = SVSI_SELECT | SVSI_FOCUSED | SVSI_DESELECTOTHERS | SVSI_ENSUREVISIBLE;
                for (UINT i = 0; i < cidl; i++)
                {
                    hr = SelectPidlInSFV(psfv, apidl[i], dwSelFlags);
                    dwSelFlags = SVSI_SELECT;   // second items append to sel
                }
               psfv->Release();
            }
        }
        return hr;
    }
    
    HRESULT SelectPidlInSFV(IShellFolderViewDual *psfv, LPCITEMIDLIST pidl, DWORD dwOpts)
    {
        VARIANT var;
        HRESULT hr = InitVariantFromIDList(&var, pidl);
        if (SUCCEEDED(hr))
        {
            hr = psfv->SelectItem(&var, dwOpts);
            VariantClear(&var);
        }
        return hr;
    }
    
    HRESULT OpenFolderAndGetView(LPCITEMIDLIST pidlFolder, IShellFolderViewDual **ppsfv)
    {
        *ppsfv = NULL;
    
        IWebBrowserApp *pauto;
        HRESULT hr = SHGetIDispatchForFolder(pidlFolder, &pauto);
        if (SUCCEEDED(hr))
        {
            HWND hwnd;
            if (SUCCEEDED(pauto->get_HWND((LONG_PTR*)&hwnd)))
            {
                // Make sure we make this the active window
                SetForegroundWindow(hwnd);
                ShowWindow(hwnd, SW_SHOWNORMAL);
            }
    
            IDispatch *pdoc;
            hr = pauto->get_Document(&pdoc);
            if (S_OK == hr) // careful, automation returns S_FALSE
            {
                hr = pdoc->QueryInterface(IID_PPV_ARG(IShellFolderViewDual, ppsfv));
                pdoc->Release();
            }
            else
                hr = E_FAIL;
            pauto->Release();
        }
        return hr;
    }
    
    // WARNING:: this assumes not rooted
    STDAPI SHGetIDispatchForFolder(LPCITEMIDLIST pidl, IWebBrowserApp **ppauto)
    {
        HRESULT hr = E_UNEXPECTED;
    
        if (ppauto)
        {
            *ppauto = NULL;
        }
    
        if (!pidl)
            return E_POINTER;
    
        // Try a cached psw if we don't need ppauto
        IShellWindows* psw = WinList_GetShellWindows(ppauto != NULL);
        if (psw)
        {
            VARIANT var;
            hr = InitVariantFromIDList(&var, pidl);
            if (SUCCEEDED(hr)) 
            {
                LONG lhwnd;
                IDispatch* pdisp;
                hr = psw->FindWindowSW(&var, PVAREMPTY, SWC_BROWSER, &lhwnd,
                        ppauto ? (SWFO_NEEDDISPATCH | SWFO_INCLUDEPENDING) : SWFO_INCLUDEPENDING,
                        &pdisp);
                if ((hr == E_PENDING) || (hr == S_FALSE))
                {
                    HRESULT hrOld = hr;
                    hr = E_FAIL;
                    CWaitForWindow *pdfwait = new CWaitForWindow();   // Setup a wait object...
                    if (pdfwait)
                    {
                        if (pdfwait->Init(psw, pidl, 0))
                        {
                            if (hrOld == S_FALSE)
                            {
                                // Startup opening a new window
                                SHELLEXECUTEINFO sei = {sizeof(sei)};
    
                                sei.lpIDList = (void *)pidl;
    
                                //
                                //  WARNING - old versions of ShellExec() didnt pay attention - ZekeL - 30-DEC-98
                                //  to whether the hwnd is in the same process or not, 
                                //  and so could fault in TryDDEShortcut().
                                //  only pass the hwnd if the shell window shares 
                                //  the same process.
                                //
                                sei.hwnd = GetShellWindow();
                                DWORD idProcess;
                                GetWindowThreadProcessId(sei.hwnd, &idProcess);
                                if (idProcess != GetCurrentProcessId())
                                {
                                    sei.hwnd = NULL;
                                }
    
                                // Everything should have been initialize to NULL(0)
                                sei.fMask = SEE_MASK_IDLIST | SEE_MASK_FLAG_DDEWAIT;
                                sei.nShow = SW_SHOWNORMAL;
    
                                hr = ShellExecuteEx(&sei) ? S_OK : S_FALSE;
                            }
    
                            while ((hr = psw->FindWindowSW(&var, PVAREMPTY, SWC_BROWSER, &lhwnd,
                                    ppauto ? (SWFO_NEEDDISPATCH | SWFO_INCLUDEPENDING) : SWFO_INCLUDEPENDING,
                                    &pdisp)) != S_OK)
                            {
                                if (FAILED(pdfwait->WaitForWindowToOpen(20 * 1000)))
                                {
                                    hr = E_ABORT;
                                    break;
                                }
                            }
                        }
                        pdfwait->CleanUp();   // No need to watch things any more...
                        pdfwait->Release(); // release our use of this object...
                    }
                }
    
                if (hr == S_OK && ppauto) 
                {
                    // if this fails this is because we are inside SendMessage loop
                    hr = pdisp->QueryInterface(IID_PPV_ARG(IWebBrowserApp, ppauto));
                }
    
                if (pdisp)
                {
                    pdisp->Release();
                }
    
                VariantClear(&var);
            }
            psw->Release();
        }
        return hr;
    }
    That's a guess (winkwink) at what the code I'm trying to pass my class to is.

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

    Re: Implementing interfaces that inherit from IDispatch

    Just i tried to compile this lib (using MkTypLib) and everything is good:

    Code:
    [
    	uuid(A3A642FE-5E50-40CF-BC40-A649962D2E7D)
    ]
    library IShellFolderViewDual {
    	
    	importlib("stdole2.tlb");
    
    	#define VARIANT_BOOL BOOLEAN
    
    	interface FolderItemVerbs;
    
        [
            uuid(FAC32C80-CBE4-11CE-8350-444553540000), // IID_FolderItem
            helpstring("Definition of interface FolderItem"),
            oleautomation,
            dual
        ]
        interface FolderItem : IDispatch
        {
    
            [propget, helpstring("Get Application object")]
            HRESULT Application ([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get Parent object")]
            HRESULT Parent([out, retval] IDispatch **ppid);
    
            [id(0), propget, helpstring("Get display name for item")]
            HRESULT Name([out, retval] BSTR *pbs);
    
            [id(0), propput, helpstring("Set the name for the item")]
            HRESULT Name([in] BSTR bs);
    
            [propget, helpstring("Get the pathname to the item")]
            HRESULT Path([out, retval]BSTR *pbs);
    
            [propget, helpstring("If item is link return link object")]
            HRESULT GetLink([out, retval] IDispatch **ppid);
    
            [propget, helpstring("If item is a folder return folder object")]
            HRESULT GetFolder([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Is the item a link?")]
            HRESULT IsLink([out, retval] VARIANT_BOOL *pb);
    
            [propget, helpstring("Is the item a Folder?")]
            HRESULT IsFolder([out, retval] VARIANT_BOOL *pb);
    
            [propget, helpstring("Is the item a file system object?")]
            HRESULT IsFileSystem([out, retval] VARIANT_BOOL *pb);
    
            [propget, helpstring("Is the item browsable?")]
            HRESULT IsBrowsable([out, retval] VARIANT_BOOL *pb);
    
            [propget, helpstring("Modification Date?")]
            HRESULT ModifyDate([out, retval] DATE *pdt);
    
            [propput, helpstring("Modification Date?")]
            HRESULT ModifyDate([in] DATE dt);
    
            [propget, helpstring("Size")]
            HRESULT Size([out, retval] LONG *pul);
    
            [propget, helpstring("Type")]
            HRESULT Type([out, retval] BSTR *pbs);
    
            [helpstring("Get the list of verbs for the object")]
            HRESULT Verbs([out, retval] FolderItemVerbs **ppfic);
    
            [helpstring("Execute a command on the item")]
            HRESULT InvokeVerb([in,optional] VARIANT vVerb);
        }
    
        [
            uuid(744129E0-CBE5-11CE-8350-444553540000), // IID_FolderItems
            helpstring("Definition of interface FolderItems"),
            oleautomation,
            dual
        ]
        interface FolderItems : IDispatch
        {
            //Properties
            [propget, helpstring("Get count of items in the folder")]
            HRESULT Count([out, retval] long *plCount);
    
            [propget, helpstring("Get Application object")]
            HRESULT Application ([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get Parent object")]
            HRESULT Parent([out, retval] IDispatch **ppid);
    
            //Methods
            //Standard Methods
            [helpstring("Return the figure for the given index")]
            HRESULT Item([in,optional] VARIANT index, [out, retval]FolderItem **ppid);
    
            [id(-4), helpstring("Enumerates the figures")]
            HRESULT _NewEnum([out, retval] IUnknown **ppunk);
        }
    
        [
            uuid(BBCBDE60-C3FF-11CE-8350-444553540000), // IID_Folder
            helpstring("Definition of interface Folder"),
            oleautomation,
            dual,
        ]
        interface Folder : IDispatch
        {
            //Properties
            [id(0), propget, helpstring("Get the display name for the window")]
            HRESULT Title([out, retval] BSTR *pbs);
    
            [propget, helpstring("Get Application object")]
            HRESULT Application ([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get Parent object")]
            HRESULT Parent([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get Parent object")]
            HRESULT ParentFolder([out, retval] Folder **ppsf);
    
            //Methods
            [helpstring("The collection of Items in folder")]
            HRESULT Items([out, retval] FolderItems **ppid);
    
            [helpstring("Parse the name to get an item.")]
            HRESULT ParseName([in] BSTR bName, [out, retval] FolderItem **ppid);
    
            [helpstring("Create a new sub folder in this folder.")]
            HRESULT NewFolder([in] BSTR bName, [in, optional] VARIANT vOptions);
    
            [helpstring("Move Items to this folder.")]
            HRESULT MoveHere([in] VARIANT vItem, [in, optional] VARIANT vOptions);
    
            [helpstring("Copy Items to this folder.")]
            HRESULT CopyHere([in] VARIANT vItem, [in, optional] VARIANT vOptions);
    
            [helpstring("Get the details about an item.")]
            HRESULT GetDetailsOf([in] VARIANT vItem, [in] int iColumn, [out, retval]BSTR *pbs);
        }
    
        [
            uuid(08EC3E00-50B0-11CF-960C-0080C7F4EE85), // IID_FolderItemVerb
            helpstring("Definition of interface FolderItemVerb"),
            oleautomation,
            dual
        ]
        interface FolderItemVerb : IDispatch
        {
            [propget, helpstring("Get Application object")]
            HRESULT Application ([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get Parent object")]
            HRESULT Parent([out, retval] IDispatch **ppid);
    
            [id(0), propget, helpstring("Get display name for item")]
            HRESULT Name([out, retval] BSTR *pbs);
    
            [helpstring("Execute the verb")]
            HRESULT DoIt();
        }
    
        [
            uuid(1F8352C0-50B0-11CF-960C-0080C7F4EE85), // IID_FolderItemVerbs
            helpstring("Definition of interface FolderItemVerbs"),
            oleautomation,
            dual
        ]
        interface FolderItemVerbs : IDispatch
        {
            //Properties
            [propget, helpstring("Get count of open folder windows")]
            HRESULT Count([out, retval] long *plCount);
    
            [propget, helpstring("Get Application object")]
            HRESULT Application ([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get Parent object")]
            HRESULT Parent([out, retval] IDispatch **ppid);
    
            //Methods
            //Standard Methods
            [helpstring("Return the specified verb")]
            HRESULT Item([in,optional] VARIANT index, [out, retval]FolderItemVerb **ppid);
    
            [id(-4), helpstring("Enumerates the figures")]
            HRESULT _NewEnum([out, retval] IUnknown **ppunk);
        }
    
    	[
            uuid(E7A1AF80-4D96-11CF-960C-0080C7F4EE85), // IID_IShellFolderViewDual
            helpstring("definition of interface IShellFolderViewDual"),
            oleautomation,
            hidden,
            dual
        ]
        interface IShellFolderViewDual : IDispatch
        {
            [propget, helpstring("Get Application object")]
            HRESULT Application([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get Parent object")]
            HRESULT Parent([out, retval] IDispatch **ppid);
    
            [propget, helpstring("Get the folder being viewed")]
            HRESULT Folder([out, retval] Folder **ppid);
    
            [helpstring("The collection of Selected Items in folder")]
            HRESULT SelectedItems([out, retval] FolderItems **ppid);
    
            [propget, helpstring("The currently focused item in the folder")]
            HRESULT FocusedItem([out, retval] FolderItem **ppid);
    
            [helpstring("Select the item")]
            HRESULT SelectItem([in]VARIANT *pvfi, [in] int dwFlags);
    
            [helpstring("Show items menu and return command selected")]
            HRESULT PopupItemMenu([in]FolderItem *pfi, [in, optional]VARIANT vx, [in, optional]VARIANT vy, [out, retval] BSTR *pbs);
    
            [propget, helpstring("Returns the scripting automation model."), helpcontext(0x0000)]
            HRESULT Script([out,retval] IDispatch** ppDisp);
    
            [propget, helpstring("Returns the view options for showing a folder."), helpcontext(0x0000)]
            HRESULT ViewOptions([out,retval] long * plViewOptions);
        }
    
    }
    The problem is seems with your headers.

    This is code in VB:
    Code:
    Implements IShellFolderViewDual.IShellFolderViewDual
    
    Private Property Get IShellFolderViewDual_Application() As Object
    
    End Property
    
    Private Property Get IShellFolderViewDual_FocusedItem() As IShellFolderViewDual.FolderItem
    
    End Property
    
    Private Property Get IShellFolderViewDual_Folder() As IShellFolderViewDual.Folder
    
    End Property
    
    Private Property Get IShellFolderViewDual_Parent() As Object
    
    End Property
    
    Private Function IShellFolderViewDual_PopupItemMenu( _
                     ByVal pfi As IShellFolderViewDual.FolderItem, _
                     Optional ByVal vx As Variant, _
                     Optional ByVal vy As Variant) As String
    
    End Function
    
    Private Property Get IShellFolderViewDual_Script() As Object
    
    End Property
    
    Private Function IShellFolderViewDual_SelectedItems() As IShellFolderViewDual.FolderItems
    
    End Function
    
    Private Sub IShellFolderViewDual_SelectItem( _
                ByRef pvfi As Variant, _
                ByVal dwFlags As Long)
    
    End Sub
    
    Private Property Get IShellFolderViewDual_ViewOptions() As Long
    
    End Property
    Attached Files Attached Files

  13. #13

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

    Re: Implementing interfaces that inherit from IDispatch

    Ah I see the problem; have to use Object instead of IDispatch in VB. Thank you.

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