影像平滑滾動效果的VC實現 (轉)

worldblog發表於2007-12-06
影像平滑滾動效果的VC實現 (轉)[@more@]

  影像平滑滾動效果的VC實現
  鄭力群

前言:

  在影像的中,經常會遇到這樣一種情況,在有限的區域中顯示了一幅大圖,

這時要瀏覽影像的各個部分,這就需要用到影像的滾動。關於它的實現,許多書都有

提及,但其中的關鍵點和難點,即拖動中的重新整理和閃爍問題,卻講述的不多,這也是

我寫本文的目的所在,下面我將詳細分析實現方法。

  實現效果及實現方法:

  在影像區域中按下滑鼠左鍵,可拖動影像在某一有限區域中任意滾動。

  方法為 :拖動時計算上次與本次的偏移,然後將影像顯示的起始點進行變化並刷

新影像區域。

  實現部分:

  第一步:響應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

  如果滑鼠按下

   if( (nFlags & MK_LBUTTON) == MK_LBUTTON )

   {

    m_lPicNewLeft = point.x;

    m_lPicNewTop = point.y;

    D dwLRShift = m_lPicNewLeft - m_lPicOldLeft;

    DWORD dwTBShift = m_lPicNewTop - m_lPicOldTop;

  改變影像顯示的起始點

    m_lPicLeft = m_lPicLeft - dwLRShift;

    m_lPicTop = m_lPicTop - dwTBShift;

  判斷邊界的語句,省去。

    m_lPicOldLeft = m_lPicNewLeft;

    m_lPicOldTop = m_lPicNewTop;

    進行重新整理的語句,見第四步。

   }

   CDialog::OnMouseMove(nFlags, point);

  }

  第三步:在OnPaint中顯示,顯示的其他部分,如影像的得來等,省去。

  void CWingImgDlg::OnPaint()

   {

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

    其他的顯示內容,省去。

    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);僅重新整理影像顯示區域

    UpdateWindow();

   此時,僅會重新整理影像所在區域,閃爍有所緩解,再進一步,可使用

    InvalidateRect(&m_rtPic,TRUE);使用重畫

    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);

  這種方法很好地解決了重新整理閃爍的問題,影像拖動時很平穩且無閃爍。

  這是我在實踐中遇到的一個問題,寫出來,與大家共享。如果有問題,或者有更

好的建議和做法,歡迎和我聯絡探討,如需要整個程式的源,請聯絡(

)。

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989098/,如需轉載,請註明出處,否則將追究法律責任。

相關文章