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

VC++
几个数字信号处理算法程序
简易软盘镜像工具的实现及操作系统编写初步
教你使用正则表达式
C++ 扩展和嵌入 Python
拷贝构造和赋值操作符,C#和本机 C++ 代码的互用性
精通VC与Matlab联合编程(六)
精通VC与Matlab联合编程(五)
一个排序用的C++函数模板
浅析VC与MATLAB联合编程
C++编译器如何实现异常处理
文件重定义冲突的分析与解决
一步一步实现MFC扩展DLL中导出类和对话框
C宏:智者的利刃,愚者的恶梦!
引用的作用
《UTF-8与GB2312之间的互换》的改进
程序风格的要素-C++风格指南
VC+6.0实现文本串的自由拆分
怎样给串行化类分配版本号(可配置版本模式)
在常规的编程任务中使用新的 <tuple> 库
使用 typedef 抑制劣质代码

VC++ 中的 类似 MSN 带转义字符的信息发送框的制作(下)


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

类似 MSN 带转义字符的信息发送框的制作(下)


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


下载源代码

一、实现了上回说到的多功能文本框之后,接下去的任务就是做一个表情符号选择器。CIconPicker。

说明:本来是想实现图标选择的,但是后来有需要改成了位图选择器,但是类名没有改过来,还是叫 CIconPicker。附带工程中有图标选择器。

二、图标/位图选择器(以下简称选择器)的实现原理

  当用户按下选择器的时候,应该把所有的图像用一个图片列表显示出来;如果用户选择了其中一个图片,则记录该图片的编号,并把图片列表关闭。如果用户没有选择图片 ,那么直接把图片列表关闭 ( 响应 WM_KILLFOCUS 消息 )。
  首先,从 CButton 派生一个类 CIconPicker 。给它增加一些成员用来实现"选择器"的功能。如下所述:

  • 1、图片列表:CArray 存放所有下拉图片,每个图片都有一个编号,即它在图片数组中的序号
  • 2、GetBitmapAt():顾名思义,按序号获取图片
  • 3、AddBitmap():添加一张图片
  • 4、GetCurrentBitmapIndex():返回选中图片的序号
  • 当 CIconPicker 收到 WM_LBUTTONDOWN 消息时先不忙给父窗体发送 WM_COMMAND消息 ,而是创建一个图片列表CIconContainer(容器),然后在容器上面创建和图片数量一样多的按钮,每个按钮显示一张图片。当然,为了
    实现这个功能还得从CButton再派生一个类CInnerButton用来显示图片,感应鼠标事件。

    三、源代码说明

    1、创建容器

    void CIconPicker::OnLButtonDown(UINT nFlags, CPoint point) {	if(m_bState) return ;	m_bState=TRUE;	this->SetState(TRUE);	RECT rect;	this->GetWindowRect(&rect);	POINT pt;	pt。x=rect。left;pt。y=rect。bottom;	//创建一个图片列表容器	m_pIconContainer=new CIconContainer;	///把图片数组当作参数传过去	if(m_pIconContainer->Create(pt,this,&m_BitmapArray))	{	m_pIconContainer->ShowWindow(SW_SHOW);	m_pIconContainer->UpdateWindow();	m_pIconContainer->SetFocus();	}}
    2、为每一张图片在容器内创建一个按钮CInnerButton。我把这个工作交给容器来完成。重载容器(CIconContainer)的Create()函数,如下:
    BOOL CIconContainer::Create(POINT pt,CButton* pParentButton,CArray *pBitmapArray) {	if(pBitmapArray->GetSize()<=0)return FALSE;	m_pParentButton=pParentButton;	///根据每张图片的大小创建IconContainer	m_nCol=int(sqrt(pBitmapArray->GetSize()))+1; //计算列数	BITMAP bm;	pBitmapArray->GetAt(0)->GetBitmap(&bm); //以图片列表中的第0号图片的大小为	基准	m_nCellWidth=bm。bmWidth+4; //内部单元的宽度	m_nCellHeight=bm。bmHeight+4; //内部单元的高度	CRect rect;	rect。left=pt。x,rect。top=pt。y;	rect。right=pt。x+m_nCellWidth*m_nCol; //容器的宽度	if(pBitmapArray->GetSize()%m_nCol==0) //计算行数	{	m_nRow=pBitmapArray->GetSize()/m_nCol;	}	else	{	m_nRow=pBitmapArray->GetSize()/m_nCol+1;	}	rect。bottom=pt。y+m_nCellHeight*m_nRow+2+46; ///容器的高度=(行数+2)*单元宽度	//pParentButton->GetParent()->ScreenToClient(&rect);	///创建容器	//CWnd::Create(NULL, NULL, WS_VISIBLE | WS_CHILD,	//rect,pParentButton->GetParent(),IDC_ICONCONTAINER, NULL);	CWnd::CreateEx(WS_EX_LEFT,AfxRegisterWndClass(0),NULL,WS_VISIBLE|WS_POPUP,rect,NULL,NULL );	///创建图片张数+2个按钮	for(int i=0;i<m_nRow;i++)	{	for(int j=0;j<m_nCol&& i*m_nCol+j<pBitmapArray->GetSize();j++)	{	///计算按钮的位置	CRect innerrect;	innerrect。left=j*m_nCellWidth;	innerrect。top=i*m_nCellHeight;	innerrect。right=innerrect。left+m_nCellWidth;	innerrect。bottom=innerrect。top+m_nCellHeight;	innerrect。DeflateRect(2,2);	///新建按钮	CInnerButton *pInnerButton;	pInnerButton=new CInnerButton;	pInnerButton->Create(NULL,WS_CHILD |WS_VISIBLE,	innerrect,this,IDC_INNERBUTTON+i*m_nCol+j);	///设置按钮的图标	pInnerButton->SetBitmap(pBitm