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

2016-01-29 12:09 6 1 收藏

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

【 tulaoshi.com - C语言心得技巧 】

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

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

下载源代码

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

一、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运行通过。预览图如下:


    预览图

来源:http://www.tulaoshi.com/n/20160129/1484883.html

延伸阅读
前一篇《Visual C#.Net网络程序开发之Socket》中说到:支持Http、Tcp和Udp的类组成了TCP/IP三层模型(请求响应层、应用协议层、传输层)的中间层-应用协议层,该层的类比位于最底层的Socket类提供了更高层次的抽象,它们封装 TCP 和 UDP 套接字的创建,不需要处理连接的细节,这使得我们在编写套接字级别的协议时,可以更多地尝试使用 TCPCli...
Buoy 是一个构建在 Swing 之上的免费用户界面(UI)工具包,它为 UI 开发人员提供了方便性和简单性。在本文中作者用一个简单的 fractal 用户界面程序,介绍了 Buoy 可以做什么、为什么这么做。第一次尝试用 Java 语言构建简单的用户界面时,我对 Swing 接口的复杂性感到有些惊奇。老实说,有点想打退堂鼓。最近,一个朋友向我提到,他使用...
被鱼刺卡住喉咙怎么办? 被鱼刺卡住是常见的事情,在被鱼刺卡住时不要再吃任何的东西。马上用平时喝水的杯子倒半杯的醋喝下去,过几分钟后再往嘴里吃点饭团或者面包之类的食物。鱼刺主要是由钙元素组织而成的,而醋可以喝钙质接触后产生化学反应使鱼刺变软,这时鱼刺就可以咽下。细嚼慢咽的饮食方法对我们的好处颇多,可以保护我们的胃部,...
托盘程序是指这样一类程序:当程序运行后,会在系统的托盘区(也有说是状态区域)创建此程序的图标,使用者可以通过点击图标出现的菜单来控制程序的运行状态。托盘程序有很多优点,如不占屏幕,后台运行,便于控制等。所以现在越来越多的程序都做成了托盘程序。在VB.NET中,编写托盘程序是比较方便和简单的。这是因为VB.NET没有自身类库,...
一、概述 TCP提供的网络通讯接口与用户数据报协议(UDP)截然不同。TCP的特性使网络编程很具魅力,而且它删除了UDP的很多干扰部分(例如数据包的排序和丢失),简化了网络通讯。UDP关心的是数据包的传输,而TCP关注的是建立网络连接,并在网络连接中发送和接收字节流。 数据包可以通过网络用多种方法发送,并且它们到达的时间...