文章转自:http://www.gymsaga.com/project/589.html
上一节我们轻松的实现了QQ的登陆界面,这次,我们在实现QQ主面板的设计,先看一下现在的效果图,通过我们之前的控件的重绘,基本上实现这样的一个QQ主面板也不在画下,
说一下完善的内容和本节设计的一些难点
1:QQ登陆,增加了登陆时的效果,如最后一张图示效果,实现的原理很简单,点击登陆,隐藏所有控件,刷新主窗口,同时加载Gif动画条,这里注意一下Gif是怎么绘制的,我在SkinUI中增加了Gif的绘制类,大家可以看一下源码,我这里就不讲解了,然后点击取消按钮,显示所有控件即可
2:QQ主面板,之前我们重绘的对话框功能很简陋,导致一个问题的产生,当对话框上面放上控件的时候,如果我们拉伸窗口的大小,控件因为父窗口的背景被重绘导致控制闪烁,解决办法,将对话框的Clip Children设为true,设置这个属性是剪辑控件的所在的位置使之不在因为父窗口重绘,不过这样一来,我们又发现一件事情,拉伸窗口,控件所在的背景不被刷新,解决办法,1:如果不嫌累的话,可以在主窗口的WM_SIZE消息内,将所有控件全部调用Invalidate函数即可解决问题,2:简易的方法,在CSkinDialog中自动为我们刷新这些控件,响应CSkinDialog的WM_SIZE消息,然后在里面我们枚举窗口上面的所有控件,然后调用Invalidate
void CSkinDialog::OnSize(UINT nType, int cx, int cy)
{
__super::OnSize(nType, cx, cy);
if ( m_bClip )
{
EnumChildWindows(GetSafeHwnd(),EnumChildProc,(LPARAM)(CWnd*)this);
}
}
BOOL CALLBACK CSkinDialog::EnumChildProc( HWND hWndChild, LPARAM lParam )
{
//获取位置
CRect rcWindow;
::GetWindowRect(hWndChild,&rcWindow);
//创建区域
if ((rcWindow.Width()>0)&&(rcWindow.Height()>0))
{
//变量定义
ASSERT(lParam!=0L);
CWnd * pEnumChildInfo=(CWnd *)lParam;
//窗口判断
HWND hWndParent=::GetParent(hWndChild);
if (hWndParent!=pEnumChildInfo->GetSafeHwnd())
{
return TRUE;
}
pEnumChildInfo->Invalidate(FALSE);
}
return TRUE;
}
3:搜索框,原理:在搜索框位置绘制搜索框的图片,然后在主面板添加WM_SETCURSOR消息,我们只需要捕获鼠标位置,在搜索框位置处,我们将鼠标样式更改为工型样式即可,其次,当点击该处,即WM_LBUTTONDOWN,将Edit控件和删除按钮显示出来即可,此时还需要在做另外一件事情,增加Edit的焦点丢失消息,如果焦点丢失,我们隐藏Edit和按钮,刷新复原界面。个性签名原理类似,都是采用偷梁换柱的做法
4:好友列表,之前我们说过用ListBox去模拟,虽然效果可以实现,但是后来发现用ListBox去实现这样的效果还不如自己用窗口去模拟一个,原因有几点:
a)ListBox虽然大体上有个模样,但是如果真的用这个去开发IM系统,用在企业的项目中,会有很多的问题,扩展性很不友好
b)关于ListBox,我们知道他会生成一个滚动条,这个滚动条是很粗的,大约是17px,而QQ的滚动条却只有8px,差距不是一点半点,之前我们实现了一个滚动条的钩子类,但是我们只是在原有 的大小的基础上绘制了皮肤而已,所以采用这个方案我们也要pass
c)如果你感觉这个像TreeCtrl,然后想用TreeCtrl去模拟,那么也会出现一个问题,节点的高度设置,虽然我们可以设置节点的高度,但是节点的高度,据我现在所知道的层面上,只能将节点的 高度规定为根节点的整数倍,如果你想自由设置节点的高度,貌似是不可能。所以单凭这一条就可以pass它了,上面的那一条它也存在这个问题。
所以,基于上面的几个原因,我们采用CWnd,模拟出这么一个Ctree样式,代码花了两天时间,内容比较多,我就不账贴了,大家下载代码,自己观看即可,该控件支持大头像,小头像,正常头像三种样式显示,如上图显示,其次,上面第二条我们也说到了滚动条是一个大问题,因为微软把控件上面的滚动条弄的很诡异,很多细节我们摸不清楚一二三来,为此,我们也需要自己做另外一件事情,模拟滚动条,这里的好友列表和滚动条差不多采用的就是DirectUI设计的思路,只是我们做的很简略,但是思路都是差不多的,又兴趣的朋友可以研究一下DirectUI
如果代码中有什么纰漏或者看不懂的地方欢迎留言
下一节,我们增加QQ主面板的桌面边缘自动隐藏的功能和换肤的功能
代码下载地址:http://pan.baidu.com/s/13RmwY