使用CScrollView作為基類的單文檔視圖(SDI)程式,為什麼拖動捲軸(滑塊)到某一段地區後沒有任何訊息,沒有重繪、Scroll Position 也迴歸到零?

來源:互聯網
上載者:User

作者:khler

E-mail:khler@163.com

日期:2007.05.30

(申明:文章可任意轉載,但必須保證以上資訊完整性)

     最近在做一個SDI程式時,發現Scroll的一個不大不小的問題,當你的 scroll size 過大(一般大於32767)時,一旦拖動滑塊使滑塊的位置超過一定值,那麼滑塊的位置參數就會迴歸為0,即用GetScrollPos()返回的值為0,一旦釋放滑塊,滑塊立即返回到零點位置。
    究其原因,WM_VSCROLL和WM_HSCROLL是使用wParam參數來傳遞滑塊當前位置和滑塊動作flag的,WPARAM 是一個UINT類型的,高位的兩個位元組,即16bit,用來攜帶滑塊位置資訊,低位的16bit用來攜帶flag資訊,這樣,位置資訊的最大值理論上不能超過65535,而實際上,如果高位的第一個bit被置為1,那麼它將被WM_HSCROLL、WM_VSCROLL當作一個負數來處理,所以 scroll size 實際上不能超過 32767,即0x7FFF。
    難道 scroll size 的大小就僅僅局限於32767這樣一個尺寸了嗎?答案當然是否定的,解決辦法是使用GetScrollInfo()函數,配合SCROLLINFO結構體,將SCROLLINFO的fMask欄位設定為SIF_TRACKPOS,我們即可在nTrackPos中獲得正確的int類型的滑塊位置資訊,方法如下:
 重載OnScroll()函數,取得滑塊flag資訊,如果是SB_THUMBTRACK或者SB_THUMBPOSITION,則進行處理。這裡要注意,如果處理對象是水平捲軸,則取nScrollCode的低位元組,如果處理對象是垂直捲軸,則取nScrollCode的第二個位元組:
BOOL CHexViewView::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)
{
 // TODO: Add your specialized code here and/or call the base class
 
 BOOL rtnCod = CScrollView::OnScroll(nScrollCode, nPos, bDoScroll);

 BYTE cod = nScrollCode>>8; // 這裡只處理垂直捲軸的情況
 if( SB_THUMBTRACK == cod || SB_THUMBPOSITION == cod )
 {
  SCROLLINFO si;
  memset( &si, 0, sizeof(si) );
  si.cbSize = sizeof(si);
  si.fMask  = SIF_TRACKPOS;
  if( GetScrollInfo( SB_VERT, &si, SIF_TRACKPOS ) )
  {
   m_nScrollPos = si.nTrackPos;  // 取得正確的滑塊位置
   SetScrollPos( SB_VERT, si.nTrackPos ); // 設定
   RedrawWindow();    // 重繪
  }
 }

 return rtnCod;
}

這裡需要注意五個問題:
1、如果你處理的對象是水平捲軸,則取ScrollCode的低位元組,BYTE cod = nScrollCode&0xFF;
2、一定要在調用基類的OnScroll()之後處理並發送重繪訊息,否則在拖動滑塊、停止拖動但未釋放滑鼠左鍵的瞬間不會顯示任何內容,所以應該先調用基類的BOOL rtnCod = CScrollView::OnScroll(nScrollCode, nPos, bDoScroll);並將傳回值儲存,等處理完成後再返回其傳回值;
3、取得正確的位置資訊後應該使用SetScrollPos()將正確的位置資訊重新設定,否則同樣不能正確設定滑塊位置;
4、必鬚髮送重繪訊息重回視窗;
5、不能在OnVScroll()、OnHScroll()中處理,因為這兩個函數只在滑鼠按鍵按下或者釋放的時候才響應,而OnScroll()響應整個拖動動作。

                                                       khler@163.com

                                                                     2007.5.30

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.