MFC中richedit控件插入BMP图片

本文介绍如何使用Visual C++将位图文件插入到RichEdit控件中。通过创建和利用OLE对象,实现位图在文本编辑器中的显示,并提供了一个具体的实现函数。
1在对话框中拉入一个RichEdit控件。为它关联一个控件值

CRichEditCtrl m_rch;

2加入2个头文件

#include <afxole.h>
#include <richole.h>

3在对话框中,添加成员函数

void CRichEditIllustratePngDlg::InsertBitmap( CString pBmpFile )
{
	HBITMAP	hBmp;
	hBmp = (HBITMAP)::LoadImage(NULL, pBmpFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_DEFAULTCOLOR|LR_DEFAULTSIZE);


	STGMEDIUM stgm;
	stgm.tymed			= TYMED_GDI;
	stgm.hBitmap		= hBmp;
	stgm.pUnkForRelease = NULL;


	FORMATETC fm;
	fm.cfFormat = CF_BITMAP;
	fm.ptd		= NULL;
	fm.dwAspect	= DVASPECT_CONTENT;
	fm.lindex	= -1;
	fm.tymed	= TYMED_GDI;


	//创建输入数据源
	IStorage* pStorage;


	//分配内存
	LPLOCKBYTES	lpLockBytes = NULL;
	SCODE sc = CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
	if (sc != S_OK)
	{
		AfxThrowOleException(sc);
	}
	ASSERT(lpLockBytes != NULL);


	sc = StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);
	if (sc != S_OK)
	{
		VERIFY(lpLockBytes->Release() == 0);
		lpLockBytes = NULL;
		AfxThrowOleException(sc);
	}
	ASSERT(pStorage != NULL);


	COleDataSource* pDataSource = new COleDataSource;
	pDataSource->CacheData(CF_BITMAP, &stgm);
	LPDATAOBJECT lpDataObject = (LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);


	//获取RichEdit的OLEClientSite
	LPOLECLIENTSITE lpClientSite;
	m_rch.GetIRichEditOle()->GetClientSite(&lpClientSite);


	//创建OLE对象
	IOleObject* pOleObject;
	sc = OleCreateStaticFromData(lpDataObject, IID_IOleObject, OLERENDER_FORMAT, &fm ,lpClientSite, pStorage, (void**)&pOleObject);
	if (sc != S_OK)
	{
		AfxThrowOleException(sc);
	}


	//插入ole对象
	REOBJECT reObject;
	ZeroMemory(&reObject, sizeof(reObject));
	reObject.cbStruct = sizeof(REOBJECT);


	CLSID clsid;
	sc = pOleObject->GetUserClassID(&clsid);
	if (sc != S_OK)
	{
		AfxThrowOleException(sc);
	}


	reObject.clsid		= clsid;
	reObject.cp			= REO_CP_SELECTION;
	reObject.dvaspect	= DVASPECT_CONTENT;
	reObject.poleobj	= pOleObject;
	reObject.polesite	= lpClientSite;
	reObject.pstg		= pStorage;


	HRESULT hr = m_rch.GetIRichEditOle()->InsertObject(&reObject);


	delete pDataSource;
}
//然后就可以调用这个函数了
void CWhatFuckDlg::OnFasong()   
{  
    // TODO: Add your control notification handler code here  
    InsertBitmap(&CString("d:\\haha.bmp"));  
} 

//值得注意的是,一定要API函数初始化,否则,运行之后是不会弹出窗口的
BOOL CWhatFuckApp::InitInstance()  
{  
    ::AfxInitRichEdit();。。。//要加入这个初始化函数 




不用第三方控件,让richEdit支持图片与表格换行 DELPHI 6 提供的RICHEDIT是1.0,并不支持图片,对复杂表格也会乱成一团,如何在DELPHI原有控件的基础上做少量修改,使之支持显示图片与正确显示表格,其实只需要几行就好了,方法如下: 找到richEdit控件所在单元ComCtrls.pas (在SOURCE\VCL) //第一步 procedure TCustomRichEdit.CreateParams(var Params: TCreateParams); const // RichEditModuleName = 'RICHED32.DLL';//原来语句 // RichEditClassName = 'RICHEDIT'; //原来语句 RichEditModuleName = 'Msftedit.dll'; //改后语句 RichEditClassName = 'RichEdit50W'; //改后语句 //第二步 procedure TCustomRichEdit.CreateWnd; .... //加入一行要放在 CreateWnd 因为此时 HANDLE已建立 Perform(EM_SetOleCallback, 0, Longint(TRichEditOleCallback.Create(TRichEdit(self)) as IRichEditOleCallback)) ; //第三步 procedure TCustomRichEdit.WMRButtonUp(var Message: TWMRButtonUp); begin inherited; // RichEd20 does not pass the WM_RBUTTONUP message to defwndproc, // so we get no WM_CONTEXTMENU message. Simulate message here. // if Win32MajorVersion < 5 then //是原有1.0的要去掉 Perform(WM_CONTEXTMENU, Handle, LParam(PointToSmallPoint( ClientToScreen(SmallPointToPoint(Message.Pos))))); end; //第四步 procedure TRichEditStrings.Insert(Index: Integer; const S: string); .... //要去掉后面两名 // 1.0 uses, 2.0 will error happened 2011 // if RichEdit.SelStart (Selection.cpMax + Length(Str)) then //是原有1.0的要去掉 // raise EOutOfResources.Create(sRichEditInsertError); //是原有1.0的要去掉
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值