设为首页 加入收藏

TOP

VC超强仿QQ自动伸缩窗口(二)
2013-03-05 14:09:31 来源: 作者: 【 】 浏览:930
Tags:超强 自动 伸缩 窗口

 

  先来看看核心的函数之一的 FixMoving,该函数在OnMoving中被调用,FixMoving通过检测鼠标位置和窗口位置来决定窗口的收缩模式,并修正粘附边界时窗口的位置,从而达到像移动QQ时出现的效果。

  void CQQHideWndDlg::FixMoving(UINT fwSide, LPRECT pRect)

  {

  POINT curPos;

  GetCursorPos(&curPos);

  INT screenHeight = GetSystemMetrics(SM_CYSCREEN);

  INT screenWidth = GetSystemMetrics(SM_CXSCREEN);

  INT height = pRect->bottom - pRect->top;

  INT width = pRect->right - pRect->left;

  if (curPos.y <= INTERVAL)

  { //粘附在上边

  pRect->bottom = height - m_edgeHeight;

  pRect->top = -m_edgeHeight;

  m_hideMode = HM_TOP;

  }

  else if(curPos.y >= (screenHeight - INTERVAL - m_taskBarHeight))

  { //粘附在下边

  pRect->top = screenHeight - m_taskBarHeight - height;

  pRect->bottom = screenHeight - m_taskBarHeight;

  m_hideMode = HM_BOTTOM;

  }

  else if (curPos.x < INTERVAL)

  { //粘附在左边

  if(!m_isSizeChanged)

  {

  CRect tRect;

  GetWindowRect(tRect);

  m_oldWndHeight = tRect.Height();

  }

  pRect->right = width;

  pRect->left = 0;

  pRect->top = -m_edgeHeight;

  pRect->bottom = screenHeight - m_taskBarHeight;

  m_isSizeChanged = TRUE;

  m_hideMode = HM_LEFT;

  }

  else if(curPos.x >= (screenWidth - INTERVAL))

  { //粘附在右边

  if(!m_isSizeChanged)

  {

  CRect tRect;

  GetWindowRect(tRect);

  m_oldWndHeight = tRect.Height();

  }

  pRect->left = screenWidth - width;

  pRect->right = screenWidth;

  pRect->top = -m_edgeHeight;

  pRect->bottom = screenHeight - m_taskBarHeight;

  m_isSizeChanged = TRUE;

  m_hideMode = HM_RIGHT;

  }

  else

  { //不粘附

  if(m_isSizeChanged)

  { //如果收缩到两边,则拖出来后会变回原来大小

  //在"拖动不显示窗口内容下"只有光栅变回原来大小

  pRect->bottom = pRect->top + m_oldWndHeight;

  m_isSizeChanged = FALSE;

  }

  if(m_isSetTimer)

  { //如果Timer开启了,则关闭之

  if(KillTimer(1) == 1)

  m_isSetTimer = FALSE;

  }

  m_hideMode = HM_NONE;

  GetDlgItem(IDC_TIMER)->SetWindowText("Timer off");

  }

  }

  收缩模式和位置决定后,剩下的工作就由最后两个核心函数完成了:实现收缩的DoHide(),实现伸展的DoShow()。在这两个过程中m_hsFinished,m_hiding 这两个变量起到很重要的控制作用。由于伸缩过程没完成时,hsFinished始终为FALSE,所以Timer 2 不会关闭,于是在OnTimer中会重复调用这两个函数之一,在这两个函数体内,窗口位置有规律地递减或递增就可以达到QQ的“抽屉”效果了,有趣的是即使伸缩过程还没完成,你也可以在这个过程中改变m_hiding这个值来决定他是伸还是缩,正如QQ一样。你可以把Timer 2 的事件间隔调大一点,然后在窗口伸缩时,鼠标来回地进出窗口就会很容易看到这样有趣的效果(还没缩进去又被拉了出来,或者还没拉出来又缩进去了)。

  void CQQHideWndDlg::DoHide()

  {

  if(m_hideMode == HM_NONE)

  return;

  CRect tRect;

  GetWindowRect(tRect);

  INT height = tRect.Height();

  INT width = tRect.Width();

  INT steps = 0;

  switch(m_hideMode)

  {

  case HM_TOP:

  steps = height/HS_STEPS;

  tRect.bottom -= steps;

  if(tRect.bottom <= m_edgeWidth)

  { //你可以把下面一句替换上面的 ...+=|-=steps 达到取消抽屉效果

  //更好的办法是添加个BOOL值来控制,其他case同样.

  tRect.bottom = m_edgeWidth;

  m_hsFinished = TRUE; //完成隐藏过程

  }

  tRect.top = tRect.bottom - height;

  break;

  case HM_BOTTOM:

  steps = height/HS_STEPS;

  tRect.top += steps;

  if(tRect.top >= (GetSystemMetrics(SM_CYSCREEN) - m_edgeWidth))

  {

  tRect.top = GetSystemMetrics(SM_CYSCREEN) - m_edgeWidth;

  m_hsFinished = TRUE;

  }

  tRect.bottom = tRect.top + height;

  break;

  case HM_LEFT:

  steps = width/HS_STEPS;

  tRect.right -= steps;

  if(tRect.right <= m_edgeWidth)

  {

  tRect.right = m_edgeWidth;

  m_hsFinished = TRUE;

  }

  tRect.left = tRect.right - width;

  tRect.top = -m_edgeHeight;

  tRect.bottom = GetSystemMetrics(SM_CYSCREEN) - m_taskBarHeight;

  break;

  case HM_RIGHT:

  steps = width/HS_STEPS;

  tRect.left += steps;

  if(tRect.left >= (GetSystemMetrics(SM_CXSCREEN) - m_edgeWidth))

  {

  tRect.left = GetSystemMetrics(SM_CXSCREEN) - m_edgeWidth;

  m_hsFinished = TRUE;

  }

  tRect.right = tRect.left + width;

  tRect.top = -m_edgeHeight;

  tRect.bottom = GetSystemMetrics(SM_CYSCREEN) - m_taskBarHeight;

  break;

  default:

  break;

  }

        

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇让VC窗口轻而易举变漂亮 下一篇用VC纯资源dll解决国际化问题

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: