当前位置: 首页 > 图文教程 > 开发语言 > VC++ > QQ2006 界面编程之鸡蛋里挑骨头

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

VC++ 中的 QQ2006 界面编程之鸡蛋里挑骨头


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

QQ2006 界面编程之鸡蛋里挑骨头

作者:韩山师范学院02届 黄锐坤

下载源代码

  2007新的一年即将来临,新版本的QQ估计也要跟我们相见。在此献上本人写于8月份的一个练习程序。主要是希望腾讯做界面的同志能否把创建异形窗体函数 SetWindowRgn 放到合适的位置,别让拖动窗体改变大小时出现用做 MASK 的紫色区域;再者与大家分享不指定窗体风格 WS_THICKFRAME(对于对话框,相当指定其属性 Border 为 Resizing ),用代码实现窗体拖放,任意改变其尺寸。

一、SetWindowRgn的合适位置

1、在void C**Dlg::OnPaint()里调用SetWindowRgn
可以在内存画图完毕准备显示到屏幕前调用,如下:

void C**Dlg::OnPaint(){ if (IsIconic()) { CPaintDC dc(this); ... } else { CPaintDC dc(this); // 用于绘制的设备上下文 CRect rcClient; GetClientRect(&rcClient); //构造内存DC,用于画图 CDC m_MemDC; m_MemDC.CreateCompatibleDC(&dc); CBitmap btScreen; btScreen.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height()); m_MemDC.SelectObject(&btScreen); btScreen.DeleteObject(); //这里画图 ... //创建不规则窗体 ChangeWindowRgn(&m_MemDC);//这里面调用了SetWindowRgn //画到显示器上 dc.BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &m_MemDC, 0, 0, SRCCOPY); m_MemDC.DeleteDC(); }}void C**Dlg::ChangeWindowRgn(CDC *pDC){ COLORREF col = RGB(255,0,255); CRect rcClient; GetClientRect (rcClient); CRgn rgn; rgn.CreateRectRgn (0, 0, rcClient.Width(), rcClient.Height()); ... SetWindowRgn (rgn, TRUE);}
2、在void C**Dlg::OnShowWindow()里调用SetWindowRgn, 如下:
void C**Dlg::OnShowWindow(BOOL bShow, UINT nStatus){ CWnd::OnShowWindow(bShow, nStatus); // TODO: 在此处添加消息处理程序代码 if(bShow) { CRect rc; this->GetClientRect(&rc); CRgn rgnMain; rgnMain.CreateRoundRectRgn(0, 0, rcClient.Width(), rcClient.Height()); ... SetWindowRgn( rgnMain, TRUE ); }}
二、手动做“Resizing对话框”

该思路启发于徐景周的精灵特效窗体。要想点击窗体客户区不放能移动窗体,传统的做法是模拟消息点击标题。

void C**Dlg::OnLButtonDown(UINT nFlags, CPoint point){ // TODO: 在此添加消息处理程序代码 PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,0); CDialog::OnLButtonDown(nFlags, point);}
  这样很方便实现效果。但不足是窗体被移到屏幕上方,大部分在屏幕所能显示以外以后放开鼠标,窗体会自动向下对齐。徐景周的精灵特效窗体用了SetTimer和MoveWindow结合使用,这样窗体想被移到哪里都可以。正因为如此,让我想到拖放窗体的好思路。当然我们完全可以利用窗体风格WS_THICKFRAME,让系统来为我们做事。
  但是如果我们要指定窗体某个部位可以拖放窗体时,像QQ切换主题后,拖放很不方便。可以拖放的区域不是最左,最右,最上,最下,没有别的地方可以点击拖放窗体了。
  如何实现,简单说就是在鼠标按下时判断是否点在规定区域内,是的话启动记时器。然后在记时器里面定时器里面对光标判断当前位置与之前位置,从而调用MoveWindow让窗体朝响应方向拉伸或收缩。代码较琐碎,请见例子。
void C**Dlg::OnLButtonDown(UINT nFlags, CPoint point){ CRect rc(*,*,*,*); if(rc.PtInRect(point)) { SetTimer(1,20,NULL);//启动记时器 return; } CDialog::OnLButtonDown(nFlags, point);}void C**Dlg::OnTimer(UINT_PTR nIDEvent){ // TODO: 在此添加消息处理程序代码和/或调用默认值 switch(nIDEvent) { case(1): { CRect rcW; POINT point; GetWindowRect(rcW);// //实现拖动时窗体跟着右下角拉伸 ::GetCursorPos(&point); //得到“当前位置” if(point.y<rcW.bottom-400) { MoveWindow(m_rcCurRect.left ,point.y-m_ptCurPoint.y, rcW.Width(), m_rcCurRect.bottom-(point.y-m_ptCurPoint.y), true); CRect rc; GetWindowRect(rc); m_rcCurRect = rc;//保存“之前位置” } Invalidate(); } break; ... Default: break; } Dialog::OnTimer(nIDEvent);}
代码在Visual2005下编译,在WindowXP运行通过。预览图如下:


    预览图