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

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 59 ::
收藏到网摘: 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