前几天jhgwqp@csdn留言, 问有没有Demo工程. 做了一个给他.
原来记录这个技术点时, 也想做个Demo留念. 随着时间的推移, 已经忘了这事.
经jhgwqp@csdn提醒, 将这事做了.
工程下载点: srcbk_2015_0722_1819_src-sliding-window-display.rar
编译环境: vs2010 vc++ duilib
效果图:
代码预览:
建立弹出的滑动对话框时, 要以子窗口风格创建, 这样, 主窗口移动时, 我们就不用负责子窗口的位置移动了.
- void CMainDlg::CreateDlgSlidingShow()
- {
- do
- {
- if (NULL != m_pDlgSlidingShow)
- break;
- m_pDlgSlidingShow = new CDlgSlidingShow(
- XML_FILE_NAME_dlgSlidingShow_MainDlg,
- WND_CLASS_NAME_dlgSlidingShow_MainDlg);
- if (NULL == m_pDlgSlidingShow)
- break;
- m_pDlgSlidingShow->SetOwner(this);
- m_pDlgSlidingShow->Create(
- this->GetHWND(),
- WND_DISP_NAME_dlgSlidingShow_MainDlg,
- UI_WNDSTYLE_CHILD,
- WS_EX_WINDOWEDGE);
- /// 先藏起来, 让滑动框自己滑动和显示隐藏, 要不起始位置不对
- /// 所有者没必要之道创建对象的起始条件
- m_pDlgSlidingShow->ShowWindow(false, false);
- } while (0);
- }
- LRESULT CDlgSlidingShow::WndMessageProc_SlidingShow(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- /// 实现一个非模态窗口垂直滑动显示在指定父控件窗口里面
- /// * 从下到上,从最小高度到最大高度
- /// * 然后稳定显示x秒
- /// * 然后从上到下, 从最大高度到最小高度
- /// * 消失
- RECT rtMain; ///< 主窗口size
- RECT rtLayout; ///< 100%显示在父控件下方的大小
- RECT rtLayoutRate; ///< 窗口滑动时, 不通比率下的显示size
- const UINT uDispTimeMax = 1000 * 6; ///< 滑动显示窗稳定显示时间
- /// 垂直显示比率步进值, 控制窗口滑动速度
- /// 这里设定是每10MS, 执行一次 Play()
- const float fDispStep = 0.03f;
- const UINT uMinHeight = 10; ///< 最小窗口高度
- /// 最小高度限制的应对, 开始显示和结束显示的是最小高度
- const float fRateMin = 0.05f; ///< fRateMin 比率对应最小窗口高度
- static UINT uDispTimeTotal = 0; ///< 稳定显示的时间计数
- do
- {
- if (!m_bPlay)
- break;
- if (eDispStatus_inc == m_Status)
- {
- m_fRate += fDispStep;
- if (m_fRate > 1.0f)
- {
- m_fRate = 1.0f;
- uDispTimeTotal = 0;
- m_Status = eDispStatus_disp;
- }
- else if (m_fRate < fRateMin)
- m_fRate = fRateMin;
- }
- else if (eDispStatus_disp == m_Status)
- {
- uDispTimeTotal += TIMER_DELAY_PLAY;
- if (uDispTimeTotal >= uDispTimeMax)
- m_Status = eDispStatus_dec;
- }
- else if (eDispStatus_dec == m_Status)
- {
- m_fRate -= fDispStep;
- if (m_fRate <= fRateMin)
- {
- m_fRate = fRateMin;
- uDispTimeTotal = 0;
- m_Status = eDispStatus_inc;
- m_bPlay = FALSE;
- }
- }
- // ::GetWindowRect(m_pOwner->GetHWND(), &rtMain);
- ::GetClientRect(m_pOwner->GetHWND(), &rtMain);
- rtLayout.right = rtMain.right;
- rtLayout.bottom = rtMain.bottom;
- rtLayout.left = rtLayout.right - (m_rtMeOrg.right - m_rtMeOrg.left);
- rtLayout.top = rtLayout.bottom - (m_rtMeOrg.bottom - m_rtMeOrg.top);
- rtLayoutRate.left = rtLayout.left;
- rtLayoutRate.right = rtLayout.right;
- rtLayoutRate.bottom = rtLayout.bottom;
- rtLayoutRate.top = rtLayout.bottom - 1.0f * (rtLayout.bottom - rtLayout.top) * m_fRate;
- /// 界面库的限制吧 ? 无法设置成很低的高度, 有最小高度限制...
- /// 重载 OnGetMinMaxInfo 也没用
- /// 通过试验, 发现最小高度为10左右
- /// 作为所有者的非子窗口(~UI_WNDSTYLE_CHILD), 用SetWindowPos
- /// 如果是非子窗口, 位置也要重新实验一下, 不能用::GetClientRect.
- /// 要用::GetWindowRect
- // ::SetWindowPos(
- // this->GetHWND(),
- // m_pOwner->GetHWND(),
- // rtLayoutRate.left,
- // rtLayoutRate.top,
- // rtLayoutRate.right - rtLayoutRate.left,
- // rtLayoutRate.bottom - rtLayoutRate.top,
- // SWP_SHOWWINDOW);
- /// 作为所有者的子窗口(UI_WNDSTYLE_CHILD), 用MoveWindow
- ::MoveWindow(
- this->GetHWND(),
- rtLayoutRate.left,
- rtLayoutRate.top,
- rtLayoutRate.right,
- rtLayoutRate.bottom,
- TRUE);
- ::ShowWindow(this->GetHWND(), m_bPlay ? SW_SHOW : SW_HIDE);
- if (!m_bPlay)
- {
- ::PostMessageW(this->GetHWND(), WM_CLOSE, 0, 0);
- }
- } while (0);
- return S_OK;
- }
2014-03-28 03:23 的备份
- void CFloatTextMsgDlg::Play()
- {
- /// 实现一个非模态窗口垂直滑动显示在指定父控件窗口里面
- /// * 从下到上,从最小高度到最大高度
- /// * 然后稳定显示x秒
- /// * 然后从上到下, 从最大高度到最小高度
- /// * 消失
- RECT rtTabView; ///< 要显示的父控件size
- RECT rtMain; ///< 主窗口size
- RECT rtLayout; ///< 100%显示在父控件下方的大小
- RECT rtLayoutRate; ///< 窗口滑动时, 不通比率下的显示size
- const UINT uDispTimeMax = 1000 * 6; ///< 滑动显示窗稳定显示时间
- /// 垂直显示比率步进值, 控制窗口滑动速度
- /// 这里设定是每10MS, 执行一次 Play()
- const float fDispStep = 0.03f;
- const UINT uMinHeight = 10; ///< 最小窗口高度
- /// 最小高度限制的应对, 开始显示和结束显示的是最小高度
- const float fRateMin = 0.05f; ///< fRateMin 比率对应最小窗口高度
- static UINT uDispTimeTotal = 0; ///< 稳定显示的时间计数
- if (!m_bPlay)
- return;
- if (eDispStatus_inc == m_Status)
- {
- m_fRate += fDispStep;
- if (m_fRate > 1.0f)
- {
- m_fRate = 1.0f;
- uDispTimeTotal = 0;
- m_Status = eDispStatus_disp;
- }
- else if (m_fRate < fRateMin)
- m_fRate = fRateMin;
- }
- else if (eDispStatus_disp == m_Status)
- {
- uDispTimeTotal += TIMER_DELAY_PLAY;
- if (uDispTimeTotal >= uDispTimeMax)
- m_Status = eDispStatus_dec;
- }
- else if (eDispStatus_dec == m_Status)
- {
- m_fRate -= fDispStep;
- if (m_fRate <= fRateMin)
- {
- m_fRate = fRateMin;
- uDispTimeTotal = 0;
- m_Status = eDispStatus_inc;
- m_bPlay = FALSE;
- }
- }
- m_pOwner->GetTabViewFramePosition(rtTabView);
- ::GetWindowRect(m_pOwner->GetHWND(), &rtMain);
- rtLayout.left = rtMain.left + rtTabView.left;
- rtLayout.right = rtLayout.left + (m_rtMeOrg.right - m_rtMeOrg.left);
- rtLayout.top = rtMain.top + rtTabView.bottom - (m_rtMeOrg.bottom - m_rtMeOrg.top);
- rtLayout.bottom = rtMain.top + rtTabView.bottom;
- rtLayoutRate.left = rtLayout.left;
- rtLayoutRate.right = rtLayout.right;
- rtLayoutRate.bottom = rtLayout.bottom;
- rtLayoutRate.top = rtLayout.bottom - 1.0f * (rtLayout.bottom - rtLayout.top) * m_fRate;
- /// 界面库的限制吧 ? 无法设置成很低的高度, 有最小高度限制...
- /// 重载 OnGetMinMaxInfo 也没用
- /// 通过试验, 发现最小高度为10左右
- ::SetWindowPos(
- this->GetHWND(),
- m_pOwner->GetHWND(),
- rtLayoutRate.left,
- rtLayoutRate.top,
- rtLayoutRate.right - rtLayoutRate.left,
- rtLayoutRate.bottom - rtLayoutRate.top,
- SWP_SHOWWINDOW);
- ::ShowWindow(this->GetHWND(), m_bPlay ? SW_SHOW : SW_HIDE);
- }