原文地址: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为成员变量