MFC 窗口靠边自动隐藏功能

原文地址:http://blog.csdn.net/xian0617/article/details/5960521

整体思路: 捕捉鼠标和窗口的关系 、捕捉窗口的位置。

当窗口位于桌面边界时,判断 鼠标和窗口的关系,若鼠标在窗口中,不隐藏,若鼠标不在窗口中,则隐藏

 

 

1) 标记当前窗口状态

enum HidePosition{
	NO,  //非靠边
	LEFT, //靠左
	RIGHT,//靠右
	TOP	  //靠上
};


 

2)定义一个DWORD m_lastActiveTime; 标记最后active 时间

只需要绑定消息  WM_NCMOUSEMOVE 、WM_MOUSEMOVE 消息,在函数中更新 lastActiveTime = GetTickCount();

void ***::OnMouseMove(UINT nFlags, CPoint point) 
{
	m_lastActiveTime =GetTickCount();
	CDialog::OnMouseMove(nFlags, point);
}

//框架鼠标消息
void ***::OnNcMouseMove(UINT nFlags, CPoint point){
	m_lastActiveTime =GetTickCount();
}


 

3) 定义鼠标是否在窗体内函数

BOOL ***::isMouseInWindow()
{
	CRect rect;
	GetWindowRect(&rect);
	CPoint point;
	GetCursorPos(&point);
	return rect.PtInRect(point);
}


 

4) 初始化关键信息

m_screenX=GetSystemMetrics (SM_CXSCREEN);
m_screenY=GetSystemMetrics (SM_CYSCREEN);
m_lastActiveTime=GetTickCount();
m_hidePosition =HidePosition::NO;
SetTimer(100,100,NULL);//本人喜欢把Timer 的Event 和间隔设置成一个,嘿嘿


 

5) 有了 SetTimer ,当然需要看OnTimer 如何处理了

void DockedDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	switch (nIDEvent)
	{
	case 100: 
		if(GetTickCount()-m_lastActiveTime < 300){//展示
			DockedShow();
		}else{//隐藏
			DockedHidden();
		}
		break;
	}
	CDialog::OnTimer(nIDEvent);
}


 

6) 嘿嘿, 展示和隐藏都很简单的哦,见下面

//停靠隐藏
void ****::DockedHidden()
{
	CRect rect;
	GetWindowRect(&rect);
	if(m_hidePosition ==HidePosition::NO && !isMouseInWindow()){
		m_rect =rect;
		if(m_rect.top <=0 ){//靠顶
			m_hidePosition =HidePosition::TOP;
			ModifyStyle(WS_SYSMENU,NULL);
			this->SetWindowPos(NULL,m_rect.left,0,m_rect.right-m_rect.left,2,SWP_NOCOPYBITS);
			//下移
			//右移动
			m_rect.bottom -=m_rect.top;
			m_rect.top =0;
			
		}else if( m_rect.left <=0 ){ //靠左
			m_hidePosition =HidePosition::LEFT;
			ModifyStyle(WS_SYSMENU,NULL);
			this->SetWindowPos(NULL,0,m_rect.top,2,m_rect.bottom-m_rect.top,SWP_NOCOPYBITS);
			//右移动
			m_rect.right -=m_rect.left;
			m_rect.left =0;
			
		}else if( m_rect.right >= m_screenX){ //靠右
			m_hidePosition =HidePosition::RIGHT;
			ModifyStyle(WS_SYSMENU,NULL);
			this->SetWindowPos(NULL,m_screenX-2,m_rect.top,2,m_rect.bottom-m_rect.top,SWP_NOCOPYBITS);
			//左移动
			m_rect.left = m_screenX-(m_rect.right - m_rect.left);
			m_rect.right =m_screenX;//m_rect.left; //偏移量   m_rect.right - m_screenX
			
		}else{
			m_hidePosition =HidePosition::NO;
		}	
	}
}


//停靠显示
void ****::DockedShow()
{
	if(m_hidePosition !=HidePosition::NO &&isMouseInWindow()){//已隐藏,显示旧值
		//恢复样式
		ModifyStyle(NULL,WS_SYSMENU);
		//还原大小  5下,次处随意写了一下,嘿嘿,按照匀速渐出
		int seq=0;
		switch(m_hidePosition){
		case HidePosition::TOP:
			while (++seq <= 5){
				this->SetWindowPos(NULL,m_rect.left,m_rect.top,m_rect.right-m_rect.left,(m_rect.bottom-m_rect.top)*seq/5,SWP_NOCOPYBITS);
			    Sleep(80);
			}
			break;
		case HidePosition::LEFT:
			while (++seq <= 5){
				this->SetWindowPos(NULL,m_rect.left,m_rect.top,(m_rect.right-m_rect.left)*seq/5,m_rect.bottom-m_rect.top,SWP_NOCOPYBITS);
				Sleep(80);		
			}
			break;
		case HidePosition::RIGHT:
			while (++seq <= 5){
				this->SetWindowPos(NULL,m_rect.left+(m_rect.right-m_rect.left)*(5-seq)/5,m_rect.top,m_rect.right-m_rect.left,m_rect.bottom-m_rect.top,SWP_NOCOPYBITS);
				Sleep(80);		
			}
			break;
		}
		m_hidePosition =HidePosition::NO;
	}
}


 

OK,大功告成,将窗体拉动到桌面边界,自动隐藏之

其中int m_screenX、int m_screenY、HidePosition m_hidePosition、CRect m_rect为成员变量

你可能感兴趣的:(MFC 窗口靠边自动隐藏功能)