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

VC++
用VC++创建自定义向导程序
自定义 CRichEditCtrl 控件
Office 2000 风格的停泊、智能型菜单
黑客攻击手段之偷梁换柱
完善 CPopupText 类
让工具条显示256色图像
定制编辑框的上下文菜单
列表控件排序功能的实现
一个优秀的网格控件CGridCtrl
如何用代码动态添加控件
如何在编辑框中使用IAutoComplete接口
应用程序中添加“Coolbars”的简单方法
介绍一个有Toolbar功能的可重用类 CPopupText
在工具栏按钮上添加文本标签
类似Dreamweaver的颜色选择器
如何设置ListView控件的完全行(Full Row)选项
如何enable/disable菜单项
关于CEdit控件的透明 --作者:monsoon
动态菜单项、状态条提示、工具条提示问题
CAnimateCtrl::Open的使用问题

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


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