Using MFC vs2010 c++ I'm trying to use the CRichEditCtrl to display an image.
Using the process explained here https://support.microsoft.com/en-us/kb/220844
I'm able to see the "icon" with the name of the image under the icon but I want to see the actual image in the control. If I double click on the icon I then get a pop up app that shows me the original image.
My images will all be JPG. I'm look for something like what the Windows 8.1 WordPad Insert Picture does.
I've read the version that uses an HBITMAP but does that show the actual image or the same icon/name. I was also hoping to keep the jpg format as it is smaller in my cases. So does anyone know if this version shows the image and not the icon?
Am I missing something simple?
答案 0 :(得分:1)
The MSDN example should work with bitmap images. You can use Gdiplus
to open jpeg/png, then get HBITMAP
from Gdiplus handle. Use OleCreateStaticFromData
to insert images in RichEdit control
void InsertBitmap(CRichEditCtrl *edit, HBITMAP hBitmap, int position)
{
STGMEDIUM stgm;
stgm.tymed = TYMED_GDI;
stgm.hBitmap = hBitmap;
stgm.pUnkForRelease = NULL;
FORMATETC fm;
fm.cfFormat = CF_BITMAP;
fm.ptd = NULL;
fm.dwAspect = DVASPECT_CONTENT;
fm.lindex = -1;
fm.tymed = TYMED_GDI;
COleDataSource oleDataSource;
oleDataSource.CacheData(CF_BITMAP, &stgm);
LPDATAOBJECT dataObject = (LPDATAOBJECT)oleDataSource.GetInterface(&IID_IDataObject);
if (OleQueryCreateFromData(dataObject) != OLE_S_STATIC)
return;
LPOLECLIENTSITE oleClientSite;
if (S_OK != edit->GetIRichEditOle()->GetClientSite(&oleClientSite))
return;
//allocate memory
LPLOCKBYTES lockBytes = NULL;
if (S_OK == CreateILockBytesOnHGlobal(NULL, TRUE, &lockBytes) && lockBytes)
{
IStorage *storage = NULL;
if (S_OK == StgCreateDocfileOnILockBytes(lockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &storage) && storage)
{
IOleObject *oleObject = NULL;
if (S_OK == OleCreateStaticFromData(dataObject, IID_IOleObject, OLERENDER_FORMAT, &fm, oleClientSite, storage, (void **)&oleObject) && oleObject)
{
CLSID clsid;
if (S_OK == oleObject->GetUserClassID(&clsid))
{
REOBJECT reobject = { sizeof(REOBJECT) };
reobject.clsid = clsid;
reobject.cp = position;
reobject.dvaspect = DVASPECT_CONTENT;
reobject.poleobj = oleObject;
reobject.polesite = oleClientSite;
reobject.pstg = storage;
edit->GetIRichEditOle()->InsertObject(&reobject);
}
oleObject->Release();
}
storage->Release();
}
lockBytes->Release();
}
oleClientSite->Release();
}
usage:
Gdiplus::Bitmap *gdibmp = Gdiplus::Bitmap::FromFile(filename);
HBITMAP hbitmap = NULL;
gdibmp->GetHBITMAP(0, &hbitmap);
if (hbitmap)
InsertBitmap(&richEdit, hbitmap, 0);
delete gdibmp;
Note, Gdiplus
needs Unicode file name. If your project is ANSI (which it shouldn't be) then use CStringW
to convert filename to Unicode.