当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 类似 MSN 信息发送框的制作(上)

VC++
VC++ 的常用编程技巧
VC++编译环境详解
Visual C++制作一个Sniffer实例
vc.net中实现启动画面来个淡入淡出效果
VC++中进程间相互通信的十一种方法
深入了解VC++编译器
VC++删除浮动工具条中“关闭”按钮
VISUAL C++中的OCX控件的使用方法
VC++:用VC++实现上网拨号功能
VC++:基于VC++中ATL创建ActiveX控件的探讨
VC++删除浮动工具条中“关闭”按钮
VC++:VC++中的面向对象和Windows编程
VC++:Vc++中线程的同步
VC++:更新命令用户接口(UI)消息
VC++:CDatabase类的那些事
VC++:小编谈VC++中 CDatabase类的那些事
VC++:小编泛谈MFC的ODBC类
VC++:小编分享线程的创建和终止
在VC资源文件中加入声音资源
C++的static关键字

VC++ 中的 类似 MSN 信息发送框的制作(上)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 41 ::
收藏到网摘: n/a

类似 MSN 信息发送框的制作(上)


作者:北方工业大学 阙荣文 (querw)


下载源代码

一、引言
  用 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 = QUERYI