CListCtrl自动滚动的问题

CListCtrl是MFC中一个基本的控件,使用率很高,有时候根据需要定制也是很正常的。这里要说的问题就是在定制过程中偶遇的。

通过owner draw的方式定制的CListCtrl,同时还替换了默认的滚动条(实现参见http://www.codeproject.com/Articles/4447/How-to-skin-CListCtrl-including-scrollbars-and-col)。一切都很完美,然而问题随之而来。如下图所示(这里借用了别处现成的图片),最底部的“Item 9”部分可见,当用鼠标选中“Item 9”后,CListCtrl会自动向下滚动,使得“Item 9”完全可见。由于使用了自定义的滚动条,没有接收和处理这个消息,所以当CListCtrl滚动的时候,滚动条没有滚动。


那么自然而然想到的解决办法就是捕获相关消息,然后在响应函数里面更新滚动条的位置。

  • 在list control所在的对话框类中添加LVN_ENDSCROLL的消息映射
     ON_NOTIFY( LVN_ENDSCROLL, IDC_LIST1,OnEndScroll)
  • 在list control所在的对话框类中添加LVN_ENDSCROLL的处理函数

void CXXXDlg::OnEndScroll(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVSCROLL pnmLVScroll = (LPNMLVSCROLL) pNMHDR;
m_listCtrl.OnEndScrolling();
*pResult = 0;
}

  • 在派生的ClistCtrl的子类中添加滚动条处理函数

void CXXXListCtrl::OnEndScrolling()
{
//add code to update scroll bar position
}


但是在Wince平台上,上述方法行不通!你可能无法接收到LVN_ENDSCROLL消息(也有可能是我的代码有问题),或者你不想让CListCtrl自动滚动。那怎么办呢?偶然发现了一个方法。
  
  
  
  
  • 派生的ClistCtrl的子类中添加WM_TIMER的消息映射
  ON_WM_TIMER() 

  
  
  
  
  • 在派生的ClistCtrl的子类中添加WM_TIMER的处理函数,函数体为空,或者添加自己的处理代码,但不要调用基类的函数。
void CXXXListCtrl::OnTimer(UINT nIDEvent) { //keep it empty or deal with your timer and don't call base class's OnTimer }
这样就完成了。如果在OnTimer函数体内加断点,会发现即使你没有通过SetTimer启用定时器,OnTimer函数也会被不断调用。所以我猜想,CListCtrl就是通过这种方式来定时检查最底部的行是否完全可见,如果不可见就滚动至完全可见--当然纯属猜想!:)
回头补上一张最终实现的CListCtrl的效果图。

你可能感兴趣的:(CListCtrl自动滚动的问题)