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); } |
新聞熱點
疑難解答