新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → 如何实现图像平滑滚动效果? 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 3698 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 如何实现图像平滑滚动效果? 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     葛靖青001 美女呀,离线,快来找我吧!水瓶座1984-2-14
      
      
      等级:大三(研究MFC有点眉目了!)
      文章:168
      积分:595
      门派:XML.ORG.CN
      注册:2010/11/2

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给葛靖青001发送一个短消息 把葛靖青001加入好友 查看葛靖青001的个人资料 搜索葛靖青001在『 C/C++编程思想 』的所有贴子 点击这里发送电邮给葛靖青001 引用回复这个贴子 回复这个贴子 查看葛靖青001的博客楼主
    发贴心情 如何实现图像平滑滚动效果?

    【转自互联网】

    前言:

      在图像的编程中,经常会遇到这样一种情况,在有限的区域中显示了一幅大图,这时要浏览图像的各个部分,这就需要用到图像的滚动。关于它的实现,许多书都有提及,但其中的关键点和难点,即拖动中的刷新和闪烁问题,却讲述的不多,这也是我写本文的目的所在,下面我将详细分析实现方法。

      实现效果及实现方法:

      在图像区域中按下鼠标左键,可拖动图像在某一有限区域中任意滚动。

      方法为 :拖动时计算上次与本次的偏移,然后将图像显示的起始点进行变化并刷新图像区域。

      实现部分:

      第一步:响应WM_LBUTTONDOWN 消息,记录按下开始拖动的起始位置。

      void CWingImgDlg::OnLButtonDown(UINT nFlags, CPoint point)

      {

      // TODO: Add your message handler code here and/or call default

      m_lPicOldLeft = point.x;

      m_lPicOldTop = point.y;

      CDialog::OnLButtonDown(nFlags, point);

      }

      第二步:响应WM_MOUSEMOVE 消息,实现滚动。

      void CWingImgDlg::OnMouseMove(UINT nFlags, CPoint point)

      {

      // TODO: Add your message handler code here and/or call default

      file://如果鼠标按下

      if( (nFlags & MK_LBUTTON) == MK_LBUTTON )

      {

      m_lPicNewLeft = point.x;

      m_lPicNewTop = point.y;

      DWORD dwLRShift = m_lPicNewLeft - m_lPicOldLeft;

      DWORD dwTBShift = m_lPicNewTop - m_lPicOldTop;

      file://改变图像显示的起始点

      m_lPicLeft = m_lPicLeft - dwLRShift;

      m_lPicTop = m_lPicTop - dwTBShift;

      file://判断边界的语句,省去。

      m_lPicOldLeft = m_lPicNewLeft;

      m_lPicOldTop = m_lPicNewTop;

      file://进行刷新的语句,见第四步。
    }

      CDialog::OnMouseMove(nFlags, point);

      }

      第三步:在OnPaint中显示,显示的其他部分,如图像的得来等,省去。

      void CWingImgDlg::OnPaint()

      {

      CPaintDC dc(this); // device context for painting

      file://其他的显示内容,省去。

      if(m_pImgInfo != NULL)

      dc.BitBlt(m_wShowAdjLeft,m_wShowAdjTop,m_lWidth,m_lHeight,&m_AdjDC,

      m_lPicLeft,m_lPicTop,SRCCOPY);

      CDialog::OnPaint();

      }

      第四步:刷新处理。

      最常想到的方法,当然是使用Invalidate(TRUE);//刷新整个无效区

      UpdateWindow();

      这时,会刷新整个程序区域的无效区,闪烁非常严重,改正如下:

      InvalidateRect(&m_rtPic,TRUE); file://仅刷新图像显示区域

      UpdateWindow();

      此时,仅会刷新图像所在区域,闪烁有所缓解,再进一步,可使用

      InvalidateRect(&m_rtPic,TRUE); file://使用快速重画

      ReDrawWindow(&m_rtPic,NULL,RDW_INTERNALPAINT| RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);

      进行处理,此时闪烁更进一步减小,考虑到,其他部分可能影响刷新区域,干脆将OnPaint()直接使用在此处,即变为:

      OnPaint();

      但如果在OnPaint()中有大量的绘图语句,这种方法仍旧不可行,考虑到不能激发OnPaint()这一因素及控制刷新范围,我采用了如下非标准的方法解决,代码如下:

      CDC *pDC;

      pDC = GetDC();

      if(m_pImgInfo != NULL)

      pDC->BitBlt(m_wShowLeft,m_wShowTop,m_lWidth,m_lHeight,&m_AdjDC,m_lPicLeft,m_lPicTop,SRCCOPY);

      ReleaseDC(pDC);

      这种方法很好地解决了刷新闪烁的问题,图像拖动时很平稳且无闪烁。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    ---人之所以能,是相信能!!

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2010/11/24 15:08:00
     
     GoogleAdSense水瓶座1984-2-14
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 点击这里发送电邮给Google AdSense 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/12/22 1:18:05

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms