• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 628
  • Last Modified:

For chensu : Rich OLE Interface

chensu :

I read your comment , giving the URL on "how to embedd a bitmap to a RTF document" . I tried to convert the source from MFC to plain API using this function , that is supposed to draw the given bitmap to the current position of the cursor in the richedit "rEdit" : ( I 've not make it doing cleanups , so don't except a delete[] to a new for example )

The problem is , that the OleCreateFromFile always fails , with an error of "file not found" , although the file exists . Can you figure whats wrong with the code ?

int InsertBitmap(HWND rEdit,LPCOLESTR lpszFileName)
   LPRICHEDITOLE      m_pRichEditOle;
   LPOLEOBJECT      m_lpObject;
   LPSTORAGE         m_lpStorage;
   LPOLECLIENTSITE      m_lpClientSite;

   ::SendMessage((HWND)rEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&m_pRichEditOle);
      if (m_pRichEditOle == NULL)
      return false;

   // Create the embedded object

      LPLOCKBYTES lpLockBytes = NULL;
      CLSID clsid = CLSID_NULL;
      CLIPFORMAT cfFormat = 0;
   SCODE sc;

      sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);      if (sc != S_OK)
      if (sc != S_OK)
      return false;

      sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
      if (sc != S_OK)
      return false;

      // fill in FORMATETC struct      FORMATETC formatEtc;      lpFormatEtc = &formatEtc;
      lpFormatEtc->cfFormat = cfFormat;
   lpFormatEtc->ptd = NULL;
   lpFormatEtc->dwAspect = DVASPECT_CONTENT;
   lpFormatEtc->lindex = -1;
      lpFormatEtc->tymed = (DWORD)-1;      // attempt to create the object
      sc = ::OleCreateFromFile(clsid,
            IID_IUnknown, OLERENDER_NONE, lpFormatEtc, m_lpClientSite, m_lpStorage,

   if (sc != S_OK)
            char lpMsgBuf[10000];
            ::FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL,
                                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                                     (LPTSTR) &lpMsgBuf, 10000, NULL );
            MessageBox( 0, lpMsgBuf,"Error", MB_OK );
      return false;

      // m_lpObject is currently an IUnknown, convert to IOleObject
      if (m_lpObject != NULL)      {
               LPUNKNOWN lpUnk = m_lpObject;
            lpUnk->QueryInterface(IID_IOleObject, (void**)&m_lpObject);
            if (m_lpObject == NULL)
         return false;
      // all items are "contained" -- this makes our reference to this object
      //  weak -- which is needed for links to embedding silent update.
      OleSetContainedObject(m_lpObject, TRUE);

   // 3 . Ready !
   REOBJECT reobject;
   ZeroMemory(&reobject, sizeof(REOBJECT));
      reobject.cbStruct = sizeof(REOBJECT);

      sc = m_lpObject->GetUserClassID(&clsid);
   if (sc != S_OK)
            return false;
   reobject.clsid = clsid;
      reobject.cp = REO_CP_SELECTION;
   reobject.dvaspect = DVASPECT_CONTENT;
      reobject.dwFlags = REO_RESIZABLE | REO_BELOWBASELINE;
   reobject.dwUser = 0;
      reobject.poleobj = m_lpObject;
      reobject.polesite = m_lpClientSite;
      reobject.pstg = m_lpStorage;
   SIZEL sizel;
   sizel.cx = sizel.cy = 0;
      reobject.sizel = sizel;

   // 4 . Insert
   return true;
  • 3
  • 3
1 Solution
Just a comment..
Have you initialized your COM libraries..??
OleInitialize (NULL);
WxWAuthor Commented:

1. lpszFileName should be a Unicode string.
2. Make sure m_lpClientSite is valid.
Train for your Pen Testing Engineer Certification

Enroll today in this bundle of courses to gain experience in the logistics of pen testing, Linux fundamentals, vulnerability assessments, detecting live systems, and more! This series, valued at $3,000, is free for Premium members, Team Accounts, and Qualified Experts.

WxWAuthor Commented:
The m_lpClientSite is valid

You mean that passing a standard ASCIIZ string won't work ? How can I convert it ?

for example , convert "c:\\image.bmp\0"
ANSI strings won't work. Pass something like L"c:\\image.bmp".

// To convert an ANSI string lpszA to a Unicode string lpszW

int nLen = ::MultiByteToWideChar(CP_ACP, 0, lpszA, -1, NULL, NULL);

LPWSTR lpszW = new WCHAR[nLen];

::MultiByteToWideChar(CP_ACP, 0, lpszA, -1, lpszW, nLen);

// use lpszW here

delete []lpszW;

WxWAuthor Commented:
Great , that did it . Please answer .
I wonder why it wasn't made to work with ansi strings .
Thank you.

>I wonder why it wasn't made to work with ansi strings.

All the COM/OLE functions use Unicode.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now