(There is no certainty in this response; I'm surprised that no one who knows
more than I do has answered.) I think you need to have that new IStorage
private member in your class so that your code can return a pointer to it --
you can't return a pointer to a local variable that's about to disappear when
your implementation of GetNewStorage returns. The code calling this is going
to be passing (a pointer to) the place it wants the IStorage reference to be
placed, so you don't have to "keep it" for very long.
You should be able to use (almost) the same technique in GetNewStorage that you
used in your Storage function, adding a level of redirection -- declare a local
Object variable; pass a reference to it as the last parameter to CreateStorage;
check the HRESULT returned; convert the object to an IStorage and store it in
the new IStorage private class member:
self.privatestg := CType(localobj, IStorage);
and set the GetNewStorage parameter to (point to) it:
lplpstg := self.privatestg;
If I had to place a bet on whether this will work first time, I would want odds
<g>. But it should get you some more things to try. (I'm surprised that no
one else had a suggestion.)
It would be a good idea to set the privatestg member to NIL at some other
point, else GC will keep that IStorage around for too long.
Good luck.
At 07:32 PM 4/4/2006, John Whattam wrote
>Hello everyone,
>I've been implementing the IRichEditOleCallback interface as a class and
>setting this in my rich edit control's CreateRichEditOleCallback protected
>method. The interface definition I'm using is as follows - only the
>relevant member is listed for brevity:
>
> <ComImport(), CLSCompliant(False), Guid("0000000b-0000-0000-C000-
>000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
> Friend Interface IStorage
> <PreserveSig()> Function CreateStream Etc
> <PreserveSig()> Function OpenStream Etc
> <PreserveSig()> Function CreateStorage(<MarshalAs
>(UnmanagedType.LPWStr)> ByVal pwcsName As String, ByVal grfMode As Stgm,
>ByVal reserved1 As UInteger, ByVal reserved2 As UInteger, <Out(), MarshalAs
>(UnmanagedType.Interface)> ByRef ppStg As IStorage) As Integer
> Etc
> End Interface
>
>In my IRichEditOleCallback callback object I have the following:
>
>Private Declare Auto Function StgCreateStorageEx Lib "ole32.dll"
>(<MarshalAs(UnmanagedType.LPWStr)> ByVal pwcsName As String, ByVal grfMode
>As Stgm, ByVal stgfmt As StgFmt, ByVal grfAttrs As UInt32, ByVal
>pStgOptions As IntPtr, ByVal reserved As IntPtr, <InAttribute()> ByRef
>riid As Guid, ByRef ppObjectOpen As Object) As Integer
>
>This object uses the above to create a file-based storage for use by the
>COM objects within the richtextbox:
>
>''' <summary> Creates a temporary storage file for storing COM objects
>embedded within this control instance. </summary>
> Friend Function Storage() As IStorage
> Dim pResult As Integer = 0
> Dim pStorageObject As Object = Nothing
> Dim pIID_IStorage As Guid = New Guid("0000000b-0000-0000-C000-
>000000000046")
> If mStorage Is Nothing Then
> Try
> ' Create and open a new compound file storage object
>using a temporarily created file.
> pResult = StgCreateStorageEx("C:\TestStorage",
>Stgm.STGM_Create Or Stgm.STGM_ShareExclusive Or Stgm.STGM_ReadWrite,
>StgFmt.STGFMT_Storage, 0, IntPtr.Zero, IntPtr.Zero, pIID_IStorage,
>pStorageObject)
> If (pResult <> S_OK) OrElse (pStorageObject Is
>Nothing) Then
> Throw New Win32Exception("Unable to create
>compound file storage object.")
> Else
> mStorage = CType(pStorageObject, IStorage)
> End If
> Finally
> If pStorageObject IsNot Nothing Then
> Marshal.ReleaseComObject(pStorageObject)
> End If
> End Try
> End If
> Return mStorage
> End Function
>
>Then within the GetNewStorage member of the IRichEditOleCallback interface
>I planned on returning a suitably named sub storage within this storage
>file as follows - here mParent refers to the parent RichTextBox control
>and RichEditOle refers to its IRichEditOle interface which I've
>successfully wrapped:
>Private Function GetNewStorage(ByRef lplpstg As IStorage) As Integer
>Implements IRichEditOleCallback.GetNewStorage
> Trace.WriteLine("GetNewStorage")
> Dim pResult As Integer = Storage.CreateStorage("Object" &
>mParent.RichEditOle.GetObjectCount, Stgm.STGM_Create Or
>Stgm.STGM_ReadWrite Or Stgm.STGM_ShareExclusive, 0, 0, lplpstg)
> Return pResult
> End Function
>
>The call to StgCreateStorageEx works correctly and a storage file is
>created under C:\TestStorage. The problem occurs with how to get the
>interface pointer returned via the ppObjectOpen parameter. According to
>the platform SDK this parameter is defined as:
>
>void** ppObjectOpen
>[out] A pointer to an interface pointer variable that receives a pointer
>for an interface on the new storage object (sounds like an Abbott and
>Costello movie); contains NULL if operation failed.
>
>Because it has two levels of indirection, I defined it as a reference
>object passed by reference.
>
>Note that the remainder of the IRichEditOleCallback class appears to work
>correctly, eg for example I can drag and drop one part of the control's
>contents to another point within the control, also events defined within
>each interface member are raised within the parent richtextbox control
>when they should be. I just cannot get the GetNewStorage member working -
>this is the most critical member of this interface. Without it, when I
>open a file containing say embedded images then the images will not be
>displayed at all.
>
>So my question is - How do I get to the IStorage pointer returned by
>StgCreateStorageEx?
>
>Any help is much appreciated.
J. Merrill / Analytical Software Corp
===================================
This list is hosted by DevelopMentorĀ® http://www.develop.com
View archives and manage your subscription(s) at http://discuss.develop.com