当前位置: 首页 > 图文教程 > 开发语言 > 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   浏览: 72 ::
收藏到网摘: 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