MFC 窗口靠邊自動隱藏 功能

整體思路: 捕捉鼠標和窗口的關係 、捕捉窗口的位置。

當窗口位於桌面邊界時,判斷 鼠標和窗口的關係,若鼠標在窗口中,不隱藏,若鼠標不在窗口中,則隱藏

 

 

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,大功告成,將窗體拉動到桌面邊界,自動隱藏之

 


發佈了26 篇原創文章 · 獲贊 20 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章