hagejid
副版主
帖子
408
精华
0
无忧币 2144
积分 494
阅读权限 140
|
发表于:2008-1-23 13:02
该回复被 bone3360 奖励 20 点无忧币
此回复于2008-02-05 17:43被 ribut9225 评为最佳答案
LPUNKNOWN AFXAPI _AfxQueryInterface(LPUNKNOWN lpUnknown, REFIID iid)
{
ASSERT(lpUnknown != NULL);
LPUNKNOWN lpW = NULL;
if (lpUnknown->QueryInterface(iid, (LPLP)&lpW) != S_OK)
return NULL;
return lpW;
}
void CSimulationReportView::InsertPlotBitmap()
{
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);
}
CWorkSpace * pWorkSpace = GetDocument()->GetWorkSpace();
if ( !pWorkSpace )
return;
CString plotName;
plotName.LoadString( IDS_PLOT_FILENAME );
CString szFileName( pWorkSpace->GetWkspTempDirectory() +
_T("\\") + plotName );
// 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(GetDocument()->GetTitle()));
// 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;
m_reportCtrl.GetSel( cr );
cr.cpMin = cr.cpMax -1;
m_reportCtrl.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;
m_reportCtrl.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 = m_reportCtrl.GetIRichEditOle()->InsertObject(&reo);
}
附件(查看下载说明):
[别人的代码,只是做BMP的,改改应该可以显示其他的.]
rtfbitmap.zip (2008-1-23 13:02,大小:37.45 K)
该附件被下载 5 次
您下载该主题帖内所有附件同时将被扣掉2点无忧币
查看分数政策说明
|
 C到底该不该学,看看这个就明白 |
|
hagejid
副版主
帖子
408
精华
0
无忧币 2144
积分 494
阅读权限 140
|
发表于:2008-1-23 21:14
先尝试编译一下吧,我看了一下,里边
BOOL CRTFBitmapDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
RECT rect;
GetClientRect( &rect );
m_reportCtrl.Create( WS_VISIBLE | WS_CHILD | ES_MULTILINE |
ES_WANTRETURN | WS_HSCROLL | WS_VSCROLL |
ES_AUTOHSCROLL | ES_AUTOVSCROLL,
rect, this, RTF_CTRL_ID );
m_reportCtrl.ReplaceSel( _T("Here is a line of text.\n\n\n") );
InsertPlotBitmap();
m_reportCtrl.ReplaceSel( _T("\n\nHere is another line of text.") );
return TRUE; // return TRUE unless you set the focus to a control
}
最后三个函数调用就是插入文字和图片的,你可以试一下用什么方法来修改成自己的.
还有一个就是在RICHEDIT里边使用OLE
以上信息都是用百度搜到的
像我这种三脚猫程序员,搜索和盗用别人的代码是很重要的工作,呵呵
下面再给你一些资料,就是QQ,MSN等显示表情图片有关的
压缩文件里的AxImageDemoBin.RAR只有 ImageOle.dll 有用
配合里边的英文的网页,应该就可以做出显示表情图片
附件(查看下载说明):
ole显示图片.rar (2008-1-23 21:14,大小:709.71 K)
该附件被下载 4 次
您下载该主题帖内所有附件同时将被扣掉2点无忧币
查看分数政策说明
|
 C到底该不该学,看看这个就明白 |
|
ribut9225
主版主
帖子
3113
精华
1
无忧币 5989
积分 4101
阅读权限 150
来自 (保密)
|
发表于:2008-2-2 09:58
转自:http://www.vckbase.com/document/viewdoc/?id=1290
一个在RichEdit中添加表情图象的类
作者:中原工学院 刘翔
下载源代码
说明
本文根据VC知识库《在线杂志》的第30期的一篇文章:《类似 MSN 信息发送框的制作》,介绍了一个可以在RichEdit中添加表情图象的类CFaceEdit。 以下是使用这个类的程序截图:
一个在RichEdit中添加表情图象的类
作者:中原工学院 刘翔
下载源代码
说明
本文根据VC知识库《在线杂志》的第30期的一篇文章:《类似 MSN 信息发送框的制作》,介绍了一个可以在RichEdit中添加表情图象的类CFaceEdit。 以下是使用这个类的程序截图:
图一 CFaceEdit类的使用
使用方法
我们可以先看一下它的使用方法:
//将对话框类成员变量由CRichEditCtrl改为CFaceEdit
CFaceEdit m_FaceEdit;
//自定义一组表情
CString pSymbol[] = {" ", " ", ";)", ":0", ";-)"};
//表情对应的图象ID
UINT nIDBmp[] = { IDB_BITMAP1, IDB_BITMAP2, IDB_BITMAP3, IDB_BITMAP4, IDB_BITMAP5};
m_FaceEdit.Init(5, pSymbol, nIDBmp);
......
m_FaceEdit.SetText("Visual Studio 包括许多示例 ,用以说明开发人员为.NET 平台;)创建的应用程序:-) 。");
也可以以位图文件的形式导入位图:CString sBmpFile[] = {"res\\kid.bmp", "res\\sad.bmp", "res\\showoff.bmp", "res\\quip.bmp", "res\\maze.bmp"};
m_FaceEdit.Init(5, pSymbol, sBmpFile);
...
m_FaceEdit.SetText("Visual Studio 包括许多示例 ,用以说明开发人员为.NET 平台;)创建的应用程序:-) 。");
插入图象的主要原理,是由《类似 MSN 信息发送框的制作》一文中提供的InsertBitmap()函数实现的。该函数可以通过指定图象的ID插入图象,或通过图象文件的路径来插入图象。
那么如何将文本中的字符表情,如::)、;-) 等翻译成图象呢?例如,对于字符串:
"Visual Studio 包括许多示例:),用以说明开发人员为.NET 平台;)创建的应用程序:-)。"
翻译之后,变成:
"Visual Studio 包括许多示例,用以说明开发人员为.NET 平台创建的应用程序。"
如何实现呢?
在使用InsertBitmap()函数插入图象时,我发现只要先将RichEdit中的某一段文本内容选中,然后再调用InsertBitmap()函数,便可实现将选定内容替换成图象。如:
"Visual Studio 包括许多示例:),用以说明开发人员为.NET 平台;)创建的应用程序:-)。"
再调用InsertBitmap()函数:
"Visual Studio 包括许多示例,用以说明开发人员为.NET 平台;)创建的应用程序:-)。"
后面的符号只要使用相同的方法处理即可。明白了这一点,想要实现转换图象的功能也就不难了。我们可以使用CRichEditCtrl::SetSel()来实现,不过在此之前,要对各表情字符的一些信息,如位置、表情类型、长度等进行保存,以下是翻译文本的函数的代码: /*-----------------------------------------------------------------------------
* 函数名 :SetTextWithFace
*
* 功能 :实现插入图象的算法函数。
* 实现原理:
假设:CString pSymbol[] = {":)", " ", "#", "AK47", ":-)"};
先将包括表情符号的文本( 如:"haha:)" )直接显示到CRichEditCtrl中,
然后选定其中的表情符号( 如:":)" ),再调用InsertBitmap函数
实现插入,详见注释
-----------------------------------------------------------------------------*/
void CFaceEdit::SetTextWithFace(CString str)
{
CString *pstr = new CString[m_nfaceCount];
for(int n = 0; n<m_nfaceCount; n++)
{
pstr[n] = m_pSymbol[n];
}
SetWindowText(str);
int nFaceCount = 0; //str中共有多少个表情。
stFace faceNode; //faceNode中存储的是在哪个位置插入,插入哪一个表情。
vector <stFace> vecFace; //vecFace[0]表示第一个表情的位置和型号、vecFace[1]表示第二的位置和型号…
/* ************************************************************************
* 第一步:
* 在str中查找表情字符(pstr)。
*
* 如str = "我们的:-)明天更美好AK47,一定:-)非常美好#。"。那么以下操作将生成四个
* stFace(定义见FaceEdit.h)结点,它们的值分别为{3, 3, 3}, {15, 3, 4}, {10, 1, 3}, {21, 0, 1}。
* 使用vector数组vecFace进行存储。
*
* *************************************************************************/
for(int i=0, m = -1; i<m_nfaceCount; i++)
{
//关键的一步:查找宽字符,汉字算一个字符。放在循环中,就可以查找重复的字符。
while(1)
{
m = (int)str.Find(pstr, m + 1); //循环搜索
if(m != -1)
{
faceNode.nPos = m;
faceNode.nFaceIndex = i;
faceNode.nLength = (int)pstr.GetLength();
vecFace.push_back(faceNode);
nFaceCount++;
}
else
{
break;
}
}
} //查找完毕
if(nFaceCount==0) //在str中没找到一个表情,下面就无需插入表情了。
return;
delete []pstr;
/* ************************************************************************
* 第二步:
* 使用泛型算法sort进行排序。
*
* 上面的四个结点:A:{3, 3, 3}, B:{15, 3, 4}, C:{10, 1, 3}, D:{21, 0, 1},显然这不是按照
* 顺序排的,这里应该按表情在文本中出现的次序依次替换,否则替换算法将会非常麻烦。
*
* *************************************************************************/
bool less_than(stFace &face1, stFace &face2); //声明排序的"条件"函数
//详见我的ObjectSort工程中的说明。可参见《Essential C++》P84
sort(vecFace.begin(), vecFace.end(), less_than);
/* ***********************************************************************
* 第三步:
* 调整各表情字符位置(nPos)。
*
* 排序之后各结点:A:{3, 3, 3}, C:{10, 1, 3}, B:{15, 3, 4}, D:{21, 0, 1}。
* 经过摸索,发现这样一个规律:
* 本结点应该向前挪的值(prev) = 上一个表情的长度(prevLength) - 1 + 上一个结点应该向前挪的值(prev)
*
* 如:
CString pSymbol[] = {":)", " ", "#", "AK47", ":-)"};
序号:? 0 1? 2? ?3? ?4
"我们的:-)明天更美好AK47,一定:-)非常美好#。"
位置: 3 11 18 25
"#"(25, 2, 1) "AK47"(11, 3, 4) ":-)"(3, 4, 3) ":-)"(18, 4, 3)
~~ ~~ ~~ ~~
排序后:
":-)"(3, 4, 3) "AK47"(11,3, 4) ":-)"(18, 4, 3) "#"(25, 2, 1)
~~ ~~ ~~ ~~
处理后:
":-)"(3, 4, 3) "AK47"(9, 3, 4) ":-)"(13, 4, 3) "#"(18, 2, 1)
~~ ~~ ~~ ~~
少了0 少了2 少了5 少了7
3-1+0 4-1+2 3-1+5
*
*
* *********************************************************************/
for(int t = 0, prevLength = 0, prev = 0; t<nFaceCount; t++)
{
vecFace[t].nPos -= prev;
prevLength = vecFace[t].nLength;
prev = prevLength - 1 + prev;
}
/* ********************************************************************
* 第四步:
* 下面插入表情。
*
* 调用InsertBitmap插入各处理完成的各结点A:{3, 3], C:{9, 1}, B:{13, 3}, D:{18, 0}。
*
* *********************************************************************/
try
{
for(int j=0; j<nFaceCount; j++)
{
stFace faceNode = vecFace[j];
InsertBitmap(faceNode);
}
}
catch(char *sError)
{
MessageBox(sError, "HBITMAP", MB_OK | MB_ICONERROR);
}
}
注意事项
本类有两个版本,一个是针对RichEdit 1.0的,另一个是针对RichEdit 2.0的。它们的区别是,前者把一个汉字作为两个字节处理,而后者把一个汉字作为一个字节处理。请读者区分使用。
|
 用户必读,51CTO积分系统调整通知 |
|