没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|其它|编辑:郝浩|2006-02-13 11:28:00.000|阅读 1323 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
下载源代码
一、引言
用 MSN 和 QQ 等聊天的时候,当用户输入特定意义的字符串时,系统回自动用一张小图片替代.比如输入" : ) "系统
会用一个小笑脸代替。我要实现的就是这样一个信息输入框 。这个信息输入框由两部分组成:图案选择器和多功能文本框。本篇介绍多功能文本框。
二、原理简介
1、主要功能用CRichEditCtrl实现,像设置字体,设置字体颜色,字号等等CRichEditCtrl都提供了很完善的支持,我就不一一赘述了。
CRichEditCtrl 主要的不足在于以下几个方面:
(1).没有右键菜单
(2).不能插入图片(这是实现转义字符显示的关键)
(3).RTF格式输入输出不够方便(涉及到回调函数的递归调用)
我扩展了CRichEditCtrl类CRichEditCtrlEx实现了上述功能.参考了很多网上的文章,对所有公开源码的开发人员表示崇高的敬意!!
2、实现右键菜单:
///生成右键菜单
void CRichEditCtrlEx::OnRButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message
handler code here and/or call default
//设置为焦点
SetFocus();
//创建一个弹出式菜单
CMenu popmenu;
popmenu.CreatePopupMenu();
//添加菜单项目
popmenu.AppendMenu(0, ID_RICH_UNDO, "&Undo");
popmenu.AppendMenu(0, MF_SEPARATOR);
popmenu.AppendMenu(0, ID_RICH_CUT, "&Cut");
popmenu.AppendMenu(0, ID_RICH_COPY, "C&opy");
popmenu.AppendMenu(0, ID_RICH_PASTE, "&Paste");
popmenu.AppendMenu(0, ID_RICH_CLEAR, "C&lear");
popmenu.AppendMenu(0, MF_SEPARATOR);
popmenu.AppendMenu(0, ID_RICH_SELECTALL, "Select
&All");
popmenu.AppendMenu(0, MF_SEPARATOR);
popmenu.AppendMenu(0, ID_RICH_SETFONT, "Select
&Font");
//初始化菜单项
UINT nUndo=(CanUndo() ? 0 : MF_GRAYED );
popmenu.EnableMenuItem(ID_RICH_UNDO,
MF_BYCOMMAND|nUndo);
UINT nSel=((GetSelectionType()!=SEL_EMPTY) ? 0 :
MF_GRAYED) ;
popmenu.EnableMenuItem(ID_RICH_CUT,
MF_BYCOMMAND|nSel);
popmenu.EnableMenuItem(ID_RICH_COPY,
MF_BYCOMMAND|nSel);
popmenu.EnableMenuItem(ID_RICH_CLEAR,
MF_BYCOMMAND|nSel);
UINT nPaste=(CanPaste() ? 0 : MF_GRAYED) ;
popmenu.EnableMenuItem(ID_RICH_PASTE,
MF_BYCOMMAND|nPaste);
//显示菜单
CPoint pt;
GetCursorPos(&pt);
popmenu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x,
pt.y, this);
popmenu.DestroyMenu();
CRichEditCtrl::OnRButtonDown(nFlags, point);
CRichEditCtrl::OnRButtonUp(nFlags, point);
}
3、关于如何把图片插入到RichEdit中,国外由很多文章介绍,都是(我看到的都是)通过插入OLE对象来实现.主要用两个函数,还涉及到了和多接口的调用。
(1)从文件创建OLE对象OleCreateFromFile();
void CRichEditCtrlEx::InsertBitmap(CString szFileName)
{
USES_CONVERSION;
SCODE sc = ::CreateILockBytesOnHGlobal(NULL,
TRUE, &m_lpLockBytes);
if (sc != S_OK)
AfxThrowOleException(sc);
ASSERT(m_lpLockBytes != NULL);
sc = ::StgCreateDocfileOnILockBytes(m_lpLockBytes,
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_lpStorage);
if (sc != S_OK)
{
VERIFY(m_lpLockBytes->Release() == 0);
m_lpLockBytes =
NULL;
AfxThrowOleException(sc);
}
// attempt to create the
object
sc = ::OleCreateFromFile(CLSID_NULL,
T2COLE(szFileName),
IID_IUnknown,
OLERENDER_DRAW, NULL, NULL,
m_lpStorage, (void
**)&m_lpObject);
if ( sc != S_OK )
{
TCHAR * lpMsgBuf;
::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
::GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
CString msg(
lpMsgBuf );
msg += _T("\n\n\nThe
following file, created in\n"
"Simulation->Plot,
may be missing due\n"
"to not doing a
File->Save Workspace:\n\n" );
msg += szFileName;
AfxMessageBox( msg,
MB_OK );
::LocalFree(
lpMsgBuf );
return;
}
// m_lpObject is currently
an IUnknown, convert to IOleObject
if (m_lpObject != NULL)
{
LPUNKNOWN lpUnk =
m_lpObject;
m_lpObject =
QUERYINTERFACE(lpUnk, IOleObject);
lpUnk->Release();
if (m_lpObject ==
NULL)
AfxThrowOleException(E_OUTOFMEMORY);
}
// cache the IViewObject
interface
m_lpViewObject = QUERYINTERFACE(m_lpObject,
IViewObject2);
if (m_lpViewObject == NULL)
return;
// setup for advises; we
assume that OLE cleans them up properly
LPADVISESINK lpAdviseSink =
(LPADVISESINK)GetInterface(&IID_IAdviseSink);
// set up view advise
VERIFY(m_lpViewObject->SetAdvise(DVASPECT_CONTENT,
0, lpAdviseSink)== S_OK);
// the server shows these in its
user-interface
// (as document title and in File Exit menu)
m_lpObject->SetHostNames(T2COLE(AfxGetAppName()),
T2COLE(_T("Test")));
// 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);
CHARRANGE cr;
this->GetSel( cr );
cr.cpMin = cr.cpMax -1;
this->SetSel( cr );
REOBJECT reo;
memset( &reo, 0, sizeof( reo ) );
reo.cbStruct = sizeof( reo );
CLSID classID;
if ( m_lpObject->GetUserClassID( &classID ) !=
S_OK)
classID = CLSID_NULL;
reo.clsid = classID;
reo.cp = REO_CP_SELECTION;
reo.poleobj = m_lpObject;
reo.pstg = m_lpStorage;
LPOLECLIENTSITE lpClientSite;
this->GetIRichEditOle()->GetClientSite( &lpClientSite
);
reo.polesite = lpClientSite;
SIZEL sizel;
sizel.cx = sizel.cy = 0; //
let richedit determine initial size
reo.sizel = sizel;
reo.dvaspect = DVASPECT_CONTENT;
reo.dwFlags = REO_RESIZABLE;
reo.dwUser = 0;
HRESULT hr = this->GetIRichEditOle()->InsertObject(
&reo );
}
(2)根据位图句柄创建OleCreateStaticFromData();用这个函数可以把资源中的图片插入到文本框中
void CRichEditCtrlEx::InsertBitmap(HBITMAP hBitmap)
{
STGMEDIUM stgm;
stgm.tymed = TYMED_GDI;
// Storage medium = HBITMAP handle
stgm.hBitmap = hBitmap;
stgm.pUnkForRelease = NULL;
// Use ReleaseStgMedium
FORMATETC fm;
fm.cfFormat = CF_BITMAP;
// Clipboard format = CF_BITMAP
fm.ptd = NULL;
// Target Device = Screen
fm.dwAspect = DVASPECT_CONTENT;
// Level of detail = Full content
fm.lindex = -1;
// Index = Not applicaple
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;
this->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 = this->GetIRichEditOle()->InsertObject(
&reobject );
}
4、读取/写入RTF格式字符串
CRichEditCtrl 提供了两个函数StreamIn()和StreamOut()来实现这个功能,输出的内容包含文本信息和字体信息。我把这两个函数重新包装了一下
,用GetRTF()把格式文本返回到一个CString变量中SetRTF(CString )实现逆过程。具体代码参看本文附带的工程文件。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号