標籤:
原文連結:http://blog.csdn.net/tangaowen/article/details/5108980
如何彈出一個視窗氣泡
最近在工作中遇到這樣一個需求,就是需要將一個視窗從右下角工作列下面緩緩的上升到工作列的上面,現在有很多的軟體都有這樣的氣泡,比如:搜狗IME的詞條更新視窗,還比如CSDN的廣告視窗等等。
1.首先 將要彈出的視窗移動到工作列(當前螢幕)以下
2.然後,獲得工作列(本質是個視窗)的高度,這樣就可以知道視窗最終的位置了
3.然後,計算獲得視窗最終停止的位置:計算公式:dwMaxHeight=當前螢幕高度-工作列視窗的頂部高度+/-適度位移值
4.設定一個定時器
5.在定時器中響應視窗,調用MoveWindow或者SetWindowPos等函數來每次固定減少 一個固定的Y座標值dwIncreatmentValue
關於定時器響應的幾種情況:
1.如果上升視窗的top<=dwMaxHeight說明視窗已經浮出到預定的位置了,這個時候
KillTimer
2.如果上升視窗的top>dwMaxHeight,說明還沒有達到預定的位置,這個時候
根據 上升視窗的top+dwIncreatmentValue的值來處理
(1)上升視窗的top+dwIncreatmentValue<=dwMaxHeight,說明這次不要增加
dwIncreatmentValue這麼多值就可以上升到預定位置了,這個時候
讓 上升視窗的top=dwMaxHeight,然後SetWindowPos到預定位置,然後
KillTimer
(2)上升視窗的top+dwIncreatmentValue>dwMaxHeight,說明這一次還不能
上升到預定的位置,所以就直接:上升視窗Rect+dwIncreatmentValue
然後SetWindowPos將視窗向上移動dwIncreatementValue的位置。
下面是相關代碼:
1.在類中聲明兩個成員變數:
[cpp] view plaincopy
- // 視窗浮上來所用的時間間隔
- DWORD m_nUpTimeSpan;
- // 每次上升的高度
- DWORD m_nIncrementHeight;
- // 上升的極限值
- DWORD m_nMinTop;
2. 在類的建構函式中,初始化這些值:
[cpp] view plaincopy
- m_nIncrementHeight=2;
- m_nUpTimeSpan=1*10;
3.將整個升窗的函數寫為StartMove
[cpp] view plaincopy
- // 開始向上移動
- void StartMove(void)
- {
- //獲得當前視窗的地區範圍
- CRect WindowRect;
- ::GetWindowRect(GetSafeHwnd(),&WindowRect);
-
- //獲得螢幕的寬高
- int screenwidth=GetSystemMetrics(SM_CXSCREEN);
- int screenheith=GetSystemMetrics(SM_CYSCREEN);
-
- //將當前視窗移動到螢幕以下的地方
- MoveWindow(screenwidth-WindowRect.Width()-2,screenheith,WindowRect.Width(),WindowRect.Height());
- //測試
- Invalidate(FALSE);
- ShowWindow(SW_SHOWNORMAL);
- //置頂
- ::SetWindowPos(this->GetSafeHwnd(),HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
-
- //獲得 工作列 視窗
- CWnd* cwd = NULL;
- RECT rt;
- HWND hwnd = ::FindWindow(_T("Shell_TrayWnd"), NULL);
- if(hwnd)
- {
- cwd = CWnd::FromHandle(hwnd);
- }
- cwd->GetWindowRect(&rt);
-
- m_nMinTop=rt.top-WindowRect.Height()-2;
-
- //上升定時器的設定
- SetTimer(TM_STARTUP,m_nUpTimeSpan,NULL);
- }
4.OnTimer函數的實現
[cpp] view plaincopy
- void OnTimer(UINT_PTR nIDEvent)
- {
- //如果已經在極限值以上,那麼說明已經完全浮上來了
- CRect WindowRect;
- ::GetWindowRect(GetSafeHwnd(),&WindowRect);
- if (WindowRect.top<=m_nMinTop)
- {
- Invalidate(FALSE);
- ShowWindow(SW_SHOWNORMAL);
- UpdateWindow();
- //置頂
- this->SetForegroundWindow();
- ::SetWindowPos(this->GetSafeHwnd(),HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
- KillTimer(TM_STARTUP);
- }
-
- //否則
- else
- {
- int iHeight=WindowRect.Height();
- WindowRect.top-=m_nIncrementHeight;
-
- if (WindowRect.top<m_nMinTop)
- {
- WindowRect.top=m_nMinTop;
- WindowRect.bottom=WindowRect.top+iHeight;
- MoveWindow(&WindowRect);
- //置頂
- this->SetForegroundWindow();
- ::SetWindowPos(this->GetSafeHwnd(),HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
-
- KillTimer(TM_STARTUP);
- }
- else
- {
- WindowRect.bottom-=m_nIncrementHeight;
- MoveWindow(&WindowRect);
- }
- }
-
- CDialog::OnTimer(nIDEvent);
- }
http://blog.csdn.net/huasonl88/article/details/8705558
如何彈出一個視窗氣泡(使用定時器向上移動)