Search code examples
c#comcom-interopole

Problems with native Win32api RichEdit control and its IRichEditOle interface


As part of writing custom command (COM-Visible dll with class that implements Interwoven command interface) for one of Interwoven Worksite dialog boxes, I need to extract information from RichEdit textbox.

The only connection to the existing dialog box is its HWND handle; seemingly trivial task , but I got stuck:

  • Using standard win32 api functions (like GetDlgItemText) returns empty string.

After using Spy++ I noticed that the dialog box gets IRichEditOle interface and seems to encapsulate the string into OLE object.

Here is what I tried to do:

IRichEditOle richEditOleObj = null; 
IntPtr ppv = IntPtr.Zero; 
Guid guid = new Guid("00020D00-0000-0000-c000-000000000046"); 
Marshal.QueryInterface(pRichEdit, ref guid, out ppv); 
richEditOleObj = (IRichEditOle)Marshal.GetTypedObjectForIUnknown(ppv,typeof(IRichEditOle));

Judging by GetObjectCount() method of the interface there is exactly one object in the textbox - most likely the string I need to extract. I used GetObject() method and got IOleObject interface via QueryInterface:

if (richEditOleObj.GetObject(0, reObject, GetObjectOptions.REO_GETOBJ_ALL_INTERFACES) == 0) //S_OK
{ 
    IntPtr oleObjPpv = IntPtr.Zero;
    try
    { 
        IOleObject oleObject = null; 
        Guid objGuid = new Guid("00000112-0000-0000-C000-000000000046"); 
        Marshal.QueryInterface(reObject.poleobj, ref objGuid, out oleObjPpv);
        oleObject = (IOleObject)Marshal.GetTypedObjectForIUnknown(oleObjPpv, typeof(IOleObject)); 

To negate other possibilites I tried to QueryInteface for IRichEditOle to ITextDocument but this also returned empty string.

I tried to send EM_STREAMOUT message and read buffer returned from callback - returned empty buffer.

On this point I got stuck. Googling didn't help much - couldn't find anything that was relevant to my issue - it seems that vast majority of examples on the net about IRichEditOle and RichEdit revolve around inserting bitmap into RichEdit control.

The main problem - I couldn't find a way to extract information I needed from IOleObject interface and didn't find any examples relevant to extracting data from the object.

Now since I know only basic stuff about COM and OLE , I guess I am missing something important here.

I would appreciate any thoughts suggestions or remarks.


Solution

  • I found the missing bit of the puzzle. Perhaps what I did will help others with similar problem.

    After calling IRichEditOle::GetObject I received REOBJECT structure. By using clsid field of the structure I found via registry the dll where needed interface was defined.

    Using explicit cast (This is C#; so it is equivalent to using QueryInterface) from IOleObject to the required interface I achieved what I needed - access to the data stored in that IOleObject.