VC实现类似QQ自动靠边功能

Home / C++ MrLee 2014-8-6 3045

首先添加3个消息函数,分别是OnMoving、OnMove、OnNcHitTest,其功能分区是移动窗口中、移动完成、鼠标光标进入程序区域。
把代码核心贴出来,变量自己随便创建即可,初始的时候要赋值。 先定义枚举
enum
{
	DOCK_NONE,           //不停靠
	DOCK_TOP,           //停靠上边
	DOCK_LEFT,           //停靠左边
	DOCK_RIGHT           //停靠右边
};
在Dlg初始函数里面初始以下数据
	m_dockMode = DOCK_NONE;
	m_hide = FALSE;
	m_winMove = FALSE;
然后就是OnMoving加入以下代码
void Dlg::OnMoving(UINT fwSide, LPRECT pRect)
{
	CDialogEx::OnMoving(fwSide, pRect);
	// TODO: 在此处添加消息处理程序代码
	m_winMove = TRUE;
	if (pRect->top <= 0) //在上边有效距离内,自动靠拢。
	{
		m_dockMode = DOCK_TOP;
		pRect->bottom -= pRect->top;
		pRect->top = 0;
	}
	else if (pRect->left <= 0) //在左边有效距离内
	{
		m_dockMode = DOCK_LEFT;
		pRect->right -= pRect->left;
		pRect->left = 0;
	}
	else if (pRect->right >= ScreenX) //在右边有效距离内,ScreenX为屏幕宽度,可由GetSystemMetrics(SM_CYSCREEN)得到。
	{
		m_dockMode = DOCK_RIGHT;
		pRect->left += (ScreenX - pRect->right);
		pRect->right = ScreenX;
	}
	else
	{
		m_dockMode = DOCK_NONE;
	}
}
接着是OnMove
void Dlg::OnMove(int x, int y)
{
	CDialogEx::OnMove(x, y);
	// TODO: 在此处添加消息处理程序代码
	if (m_winMove)
	{
		if(m_dockMode != DOCK_NONE)
			SetTimer(TIMER_ANIMATION,ANIMATION_DELAY,NULL);
		else
			KillTimer(TIMER_ANIMATION);
	}
	m_winMove = FALSE;
}
最后OnNcHitTest
LRESULT Dlg::OnNcHitTest(CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//光标进入程序界面区域消息
	if (m_hide)
	{
		AnimateShowHide(FALSE);
		if(m_dockMode != DOCK_NONE)
			SetTimer(TIMER_ANIMATION,ANIMATION_DELAY,NULL);
	}
	return CDialogEx::OnNcHitTest(point);
}
还有一个计算的函数
void Dlg::calcAnimation(void)
{
	if(m_dockMode !=DOCK_NONE)
	{
		CPoint pt;
		CRect rc;
		GetCursorPos(&pt);
		GetWindowRect(&rc);
		if (!PtInRect(&rc, pt))
		{
			AnimateShowHide(TRUE);
			KillTimer(TIMER_ANIMATION);
		}
	}
}
void Dlg::AnimateShowHide(BOOL bHide)
{
	if(m_dockMode == DOCK_NONE)
		return;
	m_hide = bHide;
	const int borderWidth = 3;
	CRect rc;
	GetWindowRect(&rc);
	int width = rc.right - rc.left;
	int height = rc.bottom - rc.top;
	//下边判断窗体该如何移动,由停靠方式决定
	int times = 10; //平移对话框的次数,如果你觉得不够平滑,可以增大该值.
	int xStep, yStep;
	int xEnd, yEnd;
	switch (m_dockMode)
	{
	case DOCK_TOP:
		{
			//向上移藏
			xStep = 0;
			xEnd = rc.left;
			if (bHide)
			{
				yStep = -rc.bottom / times;
				yEnd = -height + borderWidth;
			}
			else
			{
				yStep = -rc.top / times;
				yEnd = 0;
			}
			break;
		}
	case DOCK_LEFT:
		{
			//向左移藏
			yStep = 0;
			yEnd = rc.top;
			if (bHide)
			{
				xStep = -rc.right / times;
				xEnd = -width + borderWidth;
			}
			else
			{
				xStep = -rc.left / times;
				xEnd = 0;
			}
			break;
		}
	case DOCK_RIGHT:
		{
			//向右移藏
			yStep = 0;
			yEnd = rc.top;
			if (bHide)
			{
				xStep = (ScreenX - rc.left) / times;
				xEnd = ScreenX - borderWidth;
			}
			else
			{
				xStep = (ScreenX - rc.right) / times;
				xEnd = ScreenX - width;
			}
			break;
		}
	default:
		_ASSERTE(FALSE);
	}
	//动画滚动窗体.
	for (int i = 0; i < times-1; ++i)
	{
		rc.left += xStep;
		rc.top += yStep;
		SetWindowPos(NULL, rc.left, rc.top, 0, 0,
			SWP_NOSIZE | SWP_NOSENDCHANGING);
		RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
		Sleep(5);
	}
	SetWindowPos(NULL, xEnd, yEnd, 0, 0, SWP_NOSIZE);
}

大功告成!按下F5看看效果吧……

本文链接:https://www.it72.com/62.htm

推荐阅读
最新回复 (0)
返回