PRotected: //修正移动时窗口的大小 void FixMoving(UINT fwSide, LPRECT pRect); //从收缩状态显示窗口 void DoShow(); //从显示状态收缩窗口 void DoHide(); //重载函数,只是为了方便调用,实际调用CWnd的SetWindowPos(…) BOOL SetWindowPos(const CWnd* pWndInsertAfter,LPCRECT pCRect, UINT nFlags = SWP_SHOWWINDOW); |
private::BOOL m_isSizeChanged;//窗口大小是否改变了 BOOL m_isSetTimer;//是否设置了检测鼠标的Timer INTm_oldWndHeight;//旧的窗口宽度INTm_taskBarHeight;//任务栏高度INTm_edgeHeight;//边缘高度 INTm_edgeWidth;//边缘宽度 INTm_hideMode;//隐藏模式 BOOL m_hsFinished;//隐藏或显示过程是否完成 BOOL m_hiding;//该参数只有在!m_hsFinished才有效 //真:正在隐藏,假:正在显示 |
WM_ NCHITTEST WM_MOVING WM_CREATE WM_TIMER |
//收缩模式#define HM_NONE0//不收缩 #define HM_TOP1//向上收缩 #define HM_BOTTOM2//向下收缩 #define HM_LEFT3//向左收缩 #define HM_RIGHT4//向右收缩 #define CM_ELAPSE200 //检测鼠标是否离开窗口的时间间隔 #define HS_ELAPSE5//伸缩过程每步的时间间隔 #define HS_STEPS10//伸缩过程分成多少步完成 #define INTERVAL20//触发粘附时鼠标与屏幕边界的最小间隔,单位为象素 #define INFALTE10//触发收缩时鼠标与窗口边界的最小间隔,单位为象素 |
m_isSizeChanged = FALSE; m_isSetTimer = FALSE;m_hsFinished = TRUE; m_hiding = FALSE;m_oldWndHeight = MINCY; m_taskBarHeight = 30; m_edgeHeight = 0; m_edgeWidth=0; m_hideMode = HM_NONE; |
int CQQHideWndDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here//获得任务栏高度 CWnd* p; p = this->FindWindow("Shell_TrayWnd",NULL); if(p != NULL) { CRect tRect; p->GetWindowRect(tRect); m_taskBarHeight = tRect.Height(); }//修改风格使得他不在任务栏显示 ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW); //去掉关闭按键(假如想画3个按键的话) //ModifyStyle(WS_SYSMENU,NULL);//获得边缘高度和宽度 m_edgeHeight = GetSystemMetrics(SM_CYEDGE); m_edgeWidth = GetSystemMetrics(SM_CXFRAME);return 0; } |
UINT CQQHideWndDlg::OnNcHitTest(CPoint point) { // TODO: Add your message handler code here and/or call default CString str; str.Format("Mouse (%d,%d)",point.x,point.y); GetDlgItem(IDC_CURSOR)->SetWindowText(str); if(m_hideMode != HM_NONE && !m_isSetTimer && //防止鼠标超出屏幕右边时向右边收缩造成闪烁 point.x < GetSystemMetrics(SM_CXSCREEN) + INFALTE) { //鼠标进入时,假如是从收缩状态到显示状态则开启Timer SetTimer(1,CM_ELAPSE,NULL); m_isSetTimer = TRUE; m_hsFinished = FALSE; m_hiding = FALSE; SetTimer(2,HS_ELAPSE,NULL); //开启显示过程 } return CDialog::OnNcHitTest(point); } |
void CQQHideWndDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(nIDEvent == 1 ) { POINT curPos; GetCursorPos(&curPos); CString str; str.Format("Timer On(%d,%d)",curPos.x,curPos.y); GetDlgItem(IDC_TIMER)->SetWindowText(str);CRect tRect; //获取此时窗口大小 GetWindowRect(tRect); //膨胀tRect,以达到鼠标离开窗口边沿一定距离才触发事件 tRect.InflateRect(INFALTE,INFALTE); if(!tRect.PtInRect(curPos)) //假如鼠标离开了这个区域 { KillTimer(1); //关闭检测鼠标Timer m_isSetTimer = FALSE; GetDlgItem(IDC_TIMER)->SetWindowText("Timer Off");m_hsFinished = FALSE; m_hiding = TRUE; SetTimer(2,HS_ELAPSE,NULL); //开启收缩过程 } }if(nIDEvent == 2) { if(m_hsFinished) //假如收缩或显示过程完毕则关闭Timer KillTimer(2); else m_hiding ? DoHide() : DoShow(); } CDialog::OnTimer(nIDEvent); } |
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"); } } |
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; }SetWindowPos(&wndTopMost,tRect); } |
void CQQHideWndDlg::DoShow() { 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.top += steps; if(tRect.top >= -m_edgeHeight) { //你可以把下面一句替换上面的 ...+=-=steps 达到取消抽屉效果 //更好的办法是添加个BOOL值来控制,其他case同样. tRect.top = -m_edgeHeight; m_hsFinished = TRUE; //完成显示过程 } tRect.bottom = tRect.top + height; break; case HM_BOTTOM: steps = height/HS_STEPS; tRect.top -= steps; if(tRect.top <= (GetSystemMetrics(SM_CYSCREEN) - height)) { tRect.top = GetSystemMetrics(SM_CYSCREEN) - height; m_hsFinished = TRUE; } tRect.bottom = tRect.top + height; break; case HM_LEFT: steps = width/HS_STEPS; tRect.right += steps; if(tRect.right >= width) { tRect.right = width; 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) - width)) { tRect.left = GetSystemMetrics(SM_CXSCREEN) - width; m_hsFinished = TRUE; } tRect.right = tRect.left + width; tRect.top = -m_edgeHeight; tRect.bottom = GetSystemMetrics(SM_CYSCREEN) - m_taskBarHeight; break; default: break; }SetWindowPos(&wndTopMost,tRect); }BOOL CQQHideWndDlg::SetWindowPos(const CWnd* pWndInsertAfter, LPCRECT pCRect, UINT nFlags) { return CDialog::SetWindowPos(pWndInsertAfter,pCRect->left, pCRect->top, pCRect->right - pCRect->left, pCRect->bottom - pCRect->top, nFlags); } |
新闻热点
疑难解答