原文链接:http://blog.csdn.net/tangaowen/article/details/5108980
如何弹出一个窗口气泡
最近在工作中遇到这样一个需求,就是需要将一个窗口从右下角任务栏下面缓缓的上升到任务栏的上面,现在有很多的软件都有这样的气泡,比如:搜狗输入法的词条更新窗口,还比如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.在类中声明两个成员变量:
- // 窗口浮上来所用的时间间隔
- DWORD m_nUpTimeSpan;
- // 每次上升的高度
- DWORD m_nIncrementHeight;
- // 上升的极限值
- DWORD m_nMinTop;
2. 在类的构造函数中,初始化这些值:
- m_nIncrementHeight=2;
- m_nUpTimeSpan=1*10;
3.将整个升窗的函数写为StartMove
- // 开始向上移动
- 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函数的实现
- 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