duilib : 滑动显示的窗口实现

前几天jhgwqp@csdn留言, 问有没有Demo工程. 做了一个给他.
原来记录这个技术点时, 也想做个Demo留念. 随着时间的推移, 已经忘了这事.

经jhgwqp@csdn提醒, 将这事做了.

工程下载点: srcbk_2015_0722_1819_src-sliding-window-display.rar

编译环境: vs2010 vc++ duilib

效果图:


代码预览:

建立弹出的滑动对话框时, 要以子窗口风格创建, 这样, 主窗口移动时, 我们就不用负责子窗口的位置移动了.

[cpp]  view plain copy
  1. void CMainDlg::CreateDlgSlidingShow()  
  2. {  
  3.     do   
  4.     {  
  5.         if (NULL != m_pDlgSlidingShow)  
  6.             break;  
  7.   
  8.         m_pDlgSlidingShow = new CDlgSlidingShow(  
  9.             XML_FILE_NAME_dlgSlidingShow_MainDlg,   
  10.             WND_CLASS_NAME_dlgSlidingShow_MainDlg);  
  11.   
  12.         if (NULL == m_pDlgSlidingShow)  
  13.             break;  
  14.   
  15.         m_pDlgSlidingShow->SetOwner(this);  
  16.         m_pDlgSlidingShow->Create(  
  17.             this->GetHWND(),  
  18.             WND_DISP_NAME_dlgSlidingShow_MainDlg,  
  19.             UI_WNDSTYLE_CHILD,  
  20.             WS_EX_WINDOWEDGE);  
  21.   
  22.         /// 先藏起来, 让滑动框自己滑动和显示隐藏, 要不起始位置不对  
  23.         /// 所有者没必要之道创建对象的起始条件  
  24.         m_pDlgSlidingShow->ShowWindow(falsefalse);  
  25.     } while (0);  
  26. }  
在消息中处理子窗口的滑动显示, 对DuiLib的显示操作, 最好放在消息中处理, 防止崩溃.

[cpp]  view plain copy
  1. LRESULT CDlgSlidingShow::WndMessageProc_SlidingShow(UINT uMsg, WPARAM wParam, LPARAM lParam)  
  2. {  
  3.     /// 实现一个非模态窗口垂直滑动显示在指定父控件窗口里面  
  4.     /// * 从下到上,从最小高度到最大高度  
  5.     /// * 然后稳定显示x秒  
  6.     /// * 然后从上到下, 从最大高度到最小高度  
  7.     /// * 消失  
  8.   
  9.     RECT    rtMain;         ///< 主窗口size  
  10.     RECT    rtLayout;       ///< 100%显示在父控件下方的大小  
  11.     RECT    rtLayoutRate;   ///< 窗口滑动时, 不通比率下的显示size  
  12.     const   UINT uDispTimeMax = 1000 * 6;   ///< 滑动显示窗稳定显示时间  
  13.   
  14.     /// 垂直显示比率步进值, 控制窗口滑动速度  
  15.     /// 这里设定是每10MS, 执行一次 Play()  
  16.     const   float fDispStep = 0.03f;           
  17.     const   UINT uMinHeight = 10;           ///< 最小窗口高度  
  18.   
  19.     /// 最小高度限制的应对, 开始显示和结束显示的是最小高度  
  20.     const   float fRateMin =  0.05f;    ///< fRateMin 比率对应最小窗口高度  
  21.     static  UINT uDispTimeTotal = 0;    ///< 稳定显示的时间计数  
  22.   
  23.     do   
  24.     {  
  25.         if (!m_bPlay)  
  26.             break;  
  27.   
  28.         if (eDispStatus_inc == m_Status)  
  29.         {  
  30.             m_fRate += fDispStep;  
  31.             if (m_fRate > 1.0f)  
  32.             {  
  33.                 m_fRate = 1.0f;  
  34.                 uDispTimeTotal = 0;  
  35.                 m_Status = eDispStatus_disp;  
  36.             }  
  37.             else if (m_fRate < fRateMin)  
  38.                 m_fRate = fRateMin;  
  39.         }  
  40.         else if (eDispStatus_disp == m_Status)  
  41.         {  
  42.             uDispTimeTotal += TIMER_DELAY_PLAY;  
  43.             if (uDispTimeTotal >= uDispTimeMax)  
  44.                 m_Status = eDispStatus_dec;  
  45.         }  
  46.         else if (eDispStatus_dec == m_Status)  
  47.         {  
  48.             m_fRate -= fDispStep;  
  49.             if (m_fRate <= fRateMin)  
  50.             {  
  51.                 m_fRate = fRateMin;  
  52.                 uDispTimeTotal = 0;  
  53.                 m_Status = eDispStatus_inc;  
  54.                 m_bPlay = FALSE;  
  55.             }  
  56.         }  
  57.   
  58.         // ::GetWindowRect(m_pOwner->GetHWND(), &rtMain);  
  59.         ::GetClientRect(m_pOwner->GetHWND(), &rtMain);  
  60.   
  61.         rtLayout.right = rtMain.right;  
  62.         rtLayout.bottom = rtMain.bottom;  
  63.         rtLayout.left = rtLayout.right - (m_rtMeOrg.right - m_rtMeOrg.left);  
  64.         rtLayout.top = rtLayout.bottom - (m_rtMeOrg.bottom - m_rtMeOrg.top);  
  65.   
  66.         rtLayoutRate.left = rtLayout.left;  
  67.         rtLayoutRate.right = rtLayout.right;  
  68.         rtLayoutRate.bottom = rtLayout.bottom;  
  69.         rtLayoutRate.top = rtLayout.bottom - 1.0f * (rtLayout.bottom - rtLayout.top) * m_fRate;  
  70.   
  71.         /// 界面库的限制吧 ? 无法设置成很低的高度, 有最小高度限制...  
  72.         /// 重载 OnGetMinMaxInfo 也没用  
  73.         /// 通过试验, 发现最小高度为10左右  
  74.   
  75.         /// 作为所有者的非子窗口(~UI_WNDSTYLE_CHILD), 用SetWindowPos  
  76.         /// 如果是非子窗口, 位置也要重新实验一下, 不能用::GetClientRect.  
  77.         /// 要用::GetWindowRect  
  78. //         ::SetWindowPos(  
  79. //             this->GetHWND(),   
  80. //             m_pOwner->GetHWND(),   
  81. //             rtLayoutRate.left,   
  82. //             rtLayoutRate.top,   
  83. //             rtLayoutRate.right - rtLayoutRate.left,   
  84. //             rtLayoutRate.bottom - rtLayoutRate.top,   
  85. //             SWP_SHOWWINDOW);  
  86.   
  87.         /// 作为所有者的子窗口(UI_WNDSTYLE_CHILD), 用MoveWindow  
  88.         ::MoveWindow(  
  89.             this->GetHWND(),   
  90.             rtLayoutRate.left,   
  91.             rtLayoutRate.top,   
  92.             rtLayoutRate.right,   
  93.             rtLayoutRate.bottom,   
  94.             TRUE);  
  95.   
  96.         ::ShowWindow(this->GetHWND(), m_bPlay ? SW_SHOW : SW_HIDE);  
  97.         if (!m_bPlay)  
  98.         {  
  99.             ::PostMessageW(this->GetHWND(), WM_CLOSE, 0, 0);  
  100.         }  
  101.     } while (0);  
  102.   
  103.     return S_OK;  
  104. }  




2014-03-28 03:23 的备份

[cpp]  view plain copy
  1. void CFloatTextMsgDlg::Play()  
  2. {  
  3.     /// 实现一个非模态窗口垂直滑动显示在指定父控件窗口里面  
  4.     /// * 从下到上,从最小高度到最大高度  
  5.     /// * 然后稳定显示x秒  
  6.     /// * 然后从上到下, 从最大高度到最小高度  
  7.     /// * 消失  
  8.   
  9.     RECT    rtTabView;      ///< 要显示的父控件size  
  10.     RECT    rtMain;         ///< 主窗口size  
  11.     RECT    rtLayout;       ///< 100%显示在父控件下方的大小  
  12.     RECT    rtLayoutRate;   ///< 窗口滑动时, 不通比率下的显示size  
  13.     const   UINT uDispTimeMax = 1000 * 6;   ///< 滑动显示窗稳定显示时间  
  14.   
  15.     /// 垂直显示比率步进值, 控制窗口滑动速度  
  16.     /// 这里设定是每10MS, 执行一次 Play()  
  17.     const   float fDispStep = 0.03f;           
  18.     const   UINT uMinHeight = 10;           ///< 最小窗口高度  
  19.       
  20.     /// 最小高度限制的应对, 开始显示和结束显示的是最小高度  
  21.     const   float fRateMin =  0.05f;    ///< fRateMin 比率对应最小窗口高度  
  22.     static  UINT uDispTimeTotal = 0;    ///< 稳定显示的时间计数  
  23.       
  24.     if (!m_bPlay)  
  25.         return;  
  26.   
  27.     if (eDispStatus_inc == m_Status)  
  28.     {  
  29.         m_fRate += fDispStep;  
  30.         if (m_fRate > 1.0f)  
  31.         {  
  32.             m_fRate = 1.0f;  
  33.             uDispTimeTotal = 0;  
  34.             m_Status = eDispStatus_disp;  
  35.         }  
  36.         else if (m_fRate < fRateMin)  
  37.             m_fRate = fRateMin;  
  38.     }  
  39.     else if (eDispStatus_disp == m_Status)  
  40.     {  
  41.         uDispTimeTotal += TIMER_DELAY_PLAY;  
  42.         if (uDispTimeTotal >= uDispTimeMax)  
  43.             m_Status = eDispStatus_dec;  
  44.     }  
  45.     else if (eDispStatus_dec == m_Status)  
  46.     {  
  47.         m_fRate -= fDispStep;  
  48.         if (m_fRate <= fRateMin)  
  49.         {  
  50.             m_fRate = fRateMin;  
  51.             uDispTimeTotal = 0;  
  52.             m_Status = eDispStatus_inc;  
  53.             m_bPlay = FALSE;  
  54.         }  
  55.     }  
  56.   
  57.     m_pOwner->GetTabViewFramePosition(rtTabView);  
  58.     ::GetWindowRect(m_pOwner->GetHWND(), &rtMain);  
  59.   
  60.     rtLayout.left = rtMain.left + rtTabView.left;  
  61.     rtLayout.right = rtLayout.left + (m_rtMeOrg.right - m_rtMeOrg.left);  
  62.     rtLayout.top = rtMain.top + rtTabView.bottom - (m_rtMeOrg.bottom - m_rtMeOrg.top);  
  63.     rtLayout.bottom = rtMain.top + rtTabView.bottom;  
  64.   
  65.     rtLayoutRate.left = rtLayout.left;  
  66.     rtLayoutRate.right = rtLayout.right;  
  67.     rtLayoutRate.bottom = rtLayout.bottom;  
  68.     rtLayoutRate.top = rtLayout.bottom - 1.0f * (rtLayout.bottom - rtLayout.top) * m_fRate;  
  69.   
  70.     /// 界面库的限制吧 ? 无法设置成很低的高度, 有最小高度限制...  
  71.     /// 重载 OnGetMinMaxInfo 也没用  
  72.     /// 通过试验, 发现最小高度为10左右  
  73.   
  74.     ::SetWindowPos(  
  75.         this->GetHWND(),   
  76.         m_pOwner->GetHWND(),   
  77.         rtLayoutRate.left,   
  78.         rtLayoutRate.top,   
  79.         rtLayoutRate.right - rtLayoutRate.left,   
  80.         rtLayoutRate.bottom - rtLayoutRate.top,   
  81.         SWP_SHOWWINDOW);  
  82.   
  83.     ::ShowWindow(this->GetHWND(), m_bPlay ? SW_SHOW : SW_HIDE);  
  84. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Selecting the "Horizontal Scroll" and "Verticla Scroll" styles among the properties of your dialog box in the resource editor, you can add scroll bars to the dialog box. Remember also to select the 'resizing' border style. However for adding functionality to the scroll bars, you need to override the WM_VSCROLL and WM_HSCROLL message handlers. Also,override the WM_SIZE handler to set the scroll bar range if the size is reduced than the original. So you get the original size of the dialog in your OninitDialog(). The code would look something like this. Modify to your needs. 1. To OnInitDialog(),add the following line. GetWindowRect(m_rect); m_nScrollPos = 0; to get the original window size. Make m_rect a member variable of your dialog. Add another variable m_nScrollPos and initialize its value to zero. It stores the current vertical scroll position. 2. Here is the WM_SIZE handler for setting the scroll bar range.Set range 0 if size is increased more than original. void CCharlesDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); // TODO: Add your message handler code here m_nCurHeight = cy; int nScrollMax; if (cy < m_rect.Height()) { nScrollMax = m_rect.Height() - cy; } else nScrollMax = 0; SCROLLINFO si; si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_ALL;// SIF_ALL = SIF_PAGE | SIF_RANGE | SIF_POS; si.nMin = 0; si.nMax = nScrollMax; si.nPage = si.nMax/10; si.nPos = 0; SetScrollInfo(SB_VERT, &si, TRUE); } You need m_nCurHeight to store the current height of the dialog and use it to handle the scrolling in OnVScroll. m_ncurHeight is also a member variable of the dialog. 3. Here is the handler for WM_VSCROLL. void CCharlesDlg::OnVScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar) { //TODO:Add your message handler code here and/or call default int nDelta; int nMaxPos = m_rect.Height() - m_nCurHeight; switch(nSBCode) { case SB_LINEDOWN: if (m_nScrollPos >= nMaxPos) return; nDelta = min(nMaxPos/100,nMaxPos-m_nScrollPos); break; case SB_LINEUP: if (m_nScrollPos <= 0) return; nDelta = -min(nMaxPos/100,m_nScrollPos); break; case SB_PAGEDOWN: if (m_nScrollPos >= nMaxPos) return; nDelta = min(nMaxPos/10,nMaxPos-m_nScrollPos); break; case SB_THUMBPOSITION: nDelta = (int)nPos - m_nScrollPos; break; case SB_PAGEUP: if (m_nScrollPos <= 0) return; nDelta = -min(nMaxPos/10,m_nScrollPos); break; default: return; } m_nScrollPos += nDelta; SetScrollPos(SB_VERT,m_nScrollPos,TRUE); ScrollWindow(0,-nDelta); CDialog::OnVScroll(nSBCode, nPos, pScrollBar); } The above code handles the vertical scrolling. For horizontal scrolling add the WM_HSCROLL similarly and add the necessary code to OnSize and OnInitDialog. Information provided in this document and any software that may accompany this document is provided "as is" without warranty of any kind, either expressed or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. The user assumes the entire risk as to the accuracy and the use of this information.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值