WTL分列显示的ListBox

导读:
  在界面数据显示时一般使用ListBox或支持分列显示的ListCtrl,如果同一个界面中有两个以上关联数据表格要显示,那么使用ListBox的好处在任何时候都可以清晰的表明数据行选中/未选中状态,从而表示表格之间的关系,而使用ListCtrl中则状态不明显,比如MFC类向导,其中的数据显示使用ListBox,在多个ListBox窗口中可以同时显示每个窗口的数据选中状态,注意一点,MFC类向导使用的ListBox是分列显示的。那么我们能否也实现一个分列显示的ListBox。在WTL可以轻易实现这一点。代码队在最后:
  如何使用:在WTL使用时,需要注意的是在资源编辑器中将ListBox属性设计为LBS_OWNERDRAWFIXED和LBS_HASSTRINGS,需要在消息宏添加REFLECT_NOTIFICATION()以支持自画消息。
  
  
  BEGIN_MSG_MAP(CMainDlg)
  
  
  ...
  
  
  REFLECT_NOTIFICATION()
  
  
  END_MSG_MAP()
  在添加数据时数据之间使用“;”来进行列之间分开,当然你也可以修改源代码使用其他分隔符或者定义一个变量来指示分隔符,CDevListBoxImpl中的m_nDivider 用来控制列的宽度,如果某一行的列宽超过这个宽度将自动增加宽度来容纳内容,就象MFC的类向导所做的一样,我并没有指定具体一列的宽度,对于我来言,两列足够了。然后需要的话你也可以修改代码使用一个int数组来保存列宽,我相信这对你来言相当容易。
  
  
  CDevListBoxImpl m_list
  
  
  
  
  m_list.SubclassWindow(GetDlgItem(IDC_LISTBOX1);
  
  
  m_list.AddString(_T("Item0;True");
  
  
  m_lsit.AddString(_T("Item1;False");
  
  
  ....
  
  
  CDevListBoxImpl的代码
  
  
  class CDevListBoxImpl : public CWindowImpl , public COwnerDraw
  
  
  
  ...{
  
  public:
  
  
  CDevListBoxImpl()
  
  
  
  
  ...{
  
  
  m_nDivider = 200
  
  
  }
  
  
  
  BEGIN_MSG_MAP(CDevListBoxImpl)
  
  
  MESSAGE_HANDLER(WM_CREATE, OnCreate)
  
  
  CHAIN_MSG_MAP_ALT(COwnerDraw , 1)
  
  
  DEFAULT_REFLECTION_HANDLER()
  
  
  END_MSG_MAP()
  
  
  
  
  // overridden to provide proper initialization
  
  BOOL SubclassWindow(HWND hWnd)
  
  
  
  
  ...{
  
  
  BOOL bRet = CWindowImpl ::SubclassWindow(hWnd);
  
  
  if(bRet)
  
  
  Init();
  
  
  return bRet;
  
  
  }
  
  LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  
  
  
  
  ...{
  
  
  // TODO : Add Code for message handler. Call DefWindowProc if necessary.
  
  Init();
  
  
  bHandled = FALSE;
  
  
  return 1
  
  }
  
  // Implementation
  
  void Init()
  
  
  
  
  ...{
  
  
  // We need this style to prevent Windows from painting the button
  
  ModifyStyle(0, BS_OWNERDRAW | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS );
  
  
  }
  
  
  
  void DrawItem ( LPDRAWITEMSTRUCT lpDIS )
  
  
  
  
  ...{
  
  
  CDCHandle dc = lpDIS->hDC;
  
  
  CRect rect = lpDIS->rcItem;
  
  
  if (m_nDivider==0)
  
  
  m_nDivider = rect.Width() / 2
  
  
  
  
  
  
  if (lpDIS->itemID != (UINT) -1)
  
  
  
  
  ...{
  
  
  
  
  TCHAR sz[128] = ...{0}
  
  CListBox::GetText(lpDIS->itemID,sz);
  
  
  COLORREF oldColor;
  
  
  //draw two rectangles, one for each row column
  
  if (lpDIS->itemState & ODS_SELECTED == ODS_SELECTED )
  
  
  
  
  ...{
  
  
  dc.FillSolidRect(&lpDIS->rcItem,RGB(0,0,128));
  
  
  oldColor = dc.SetTextColor(RGB(255,255,255));
  
  
  }
  
  else
  
  
  
  ...{
  
  
  dc.FillSolidRect(&lpDIS->rcItem,RGB(255,255,255));
  
  
  oldColor = dc.SetTextColor(RGB(0,0,0));
  
  
  }
  
  
  
  dc.SetBkMode(TRANSPARENT);
  
  
  
  
  TCHAR * tok = ::_tcstok(sz,_T(""));
  
  
  while (tok != NULL)
  
  
  
  
  ...{
  
  
  dc.DrawText(tok,lstrlen(tok),rect,DT_LEFT | DT_SINGLELINE);
  
  
  rect.left += m_nDivider;
  
  
  SIZE sz;
  
  
  dc.GetTextExtent(tok,-1,&sz);
  
  
  if (sz.cx >= 2*m_nDivider)
  
  
  
  
  ...{
  
  
  rect.left = rect.left-m_nDivider+sz.cx+20
  
  }
  
  else if (sz.cx >= m_nDivider)
  
  
  
  
  ...{
  
  
  rect.left += m_nDivider;
  
  
  }
  
  tok = ::_tcstok(NULL,_T(""));
  
  
  }
  
  
  
  dc.SetTextColor(oldColor);
  
  
  }
  
  SetMsgHandled(FALSE);
  
  
  }
  
  int m_nDivider;
  
  
  }
  
  
  Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1875614

本文转自
http://blog.csdn.net/visualfc/archive/2007/11/09/1875614.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值