dedecms织梦内容管理系统    
首页 | java | C/C++ | PHP | 操作系统 | ajax | 脚本编程 | 安全技术 | 本站下载页 | flex | CRM | 专题 | QQ群 | 测试中心 | 会员中心 | 积分规则
  当前位置:主页>C/C++>文章内容
QQ2006 界面编程之鸡蛋里挑骨头
来源: VCKBASE 作者: 黄锐坤 <
  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运行通过。预览图如下:


预览图


· ·



· ·
·
·
·

  查看关于 VC VC++ Visual C++ 的全部文章


上一篇:Visual C++视频教程:第一课 C   下一篇:Visual C++视频教程:第一课 D
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论
  热点文章
·C语言学习
·C语言指针
·C语言数组排序小结
·c语言 最简单的推箱子游戏
·c语言 全国计算机编程大赛复赛试
·c语言 全国计算机编程大赛复赛试
·c++ 数组与指针
·C++中的内存管理(new、delete、
·如何用C语言开发DSP嵌入式系统
·如何用C语言开发DSP嵌入式系统
·Linux下C语言编程
·学习arm的话先看哪本书?
  相关文章
·Visual C++视频教程:第一课 C
·Visual C++视频教程:第一课 D
·Visual C++视频教程:第一课 B
·Visual C++视频教程:第一课 E
·Visual C++视频教程:第一课 A-2
·Visual C++视频教程:第一课 F
·Visual C++视频教程:第一课 A-1
·VC++实现计算机并口的数据采集
·Windows按键突破专家的原理
·用Windows消息循环实现消息延迟
·Windows任务管理器开发原理与实
·VC++与MATLAB混合编程及其应用
  相关信息
copy right @ 百家拳软件项目研究室 2007 辽ICP备07011763