上一篇讲述了如何在wince上实现自绘按钮,这一篇将继续wince上的自绘控件--列表。效果如下图,主要是依据当时的项目需要进行定制,无法像之前的自绘按钮那样具有通用性,不过如果了解了基本流程,修改起来应该没问题的!
本自绘列表参考了codeproject上的文章"How to skin CListCtrl including scrollbars and column headers"(基于pc的实现)
void CImageListCtrl::PreSubclassWindow() { VERIFY(ModifyStyle(LVS_TYPEMASK | // this styles are removed LVS_SHOWSELALWAYS | LVS_EDITLABELS, LVS_REPORT | // this styles are added LVS_OWNERDRAWFIXED | LVS_NOCOLUMNHEADER | LVS_SINGLESEL, LVS_NOSCROLL)); // Insert at least one column to the list control VERIFY(InsertColumn(0, _T("Column"), LVCFMT_LEFT) == 0); //SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER); CRect clientRect; GetClientRect(&clientRect); SetColumnWidth(0, clientRect.Width()); CListCtrl::PreSubclassWindow(); }由于定制的列表只有一列,所以这当中调用函数 SetColumnWidth 设置列的宽度为客户区的宽度。
void CImageListCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ) { ASSERT(::IsWindow(m_hWnd)); ASSERT(lpDrawItemStruct != 0); CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rcItem(lpDrawItemStruct->rcItem); int nItem = lpDrawItemStruct->itemID; LV_ITEM lvi; lvi.mask = LVIF_STATE; lvi.iItem = nItem; lvi.iSubItem = 0; lvi.stateMask = 0xFFFF; // get all state flags GetItem(&lvi); BOOL isSelected = lvi.state & LVIS_SELECTED; CRect rcBounds; GetItemRect(nItem, rcBounds, LVIR_BOUNDS); CString sLabel = GetItemText(nItem, 0); SetBkColor(RGB(192,192,192)); PaintBk(pDC, rcItem); HBITMAP hbmOldBmp = NULL; CDC bitmapDC; bitmapDC.CreateCompatibleDC(pDC); if (isSelected && m_selImg != NULL) { hbmOldBmp = (HBITMAP)bitmapDC.SelectObject(m_selImg); pDC->BitBlt(rcItem.left, rcItem.top, rcItem.Width(), rcItem.Height(), &bitmapDC,0,0,SRCCOPY); bitmapDC.SelectObject(hbmOldBmp); } else { pDC->FillRect(rcItem,&CBrush(GetBkColor())); } if (m_ItemIcon != NULL) { hbmOldBmp = (HBITMAP)bitmapDC.SelectObject(m_ItemIcon); TransparentImage(pDC->m_hDC,rcItem.left+29, rcItem.top+12, 32, 32, bitmapDC.m_hDC,0, 0, 32, 32,RGB(0,0,0)); bitmapDC.SelectObject(hbmOldBmp); } CFont font; font.CreatePointFont(200, _T("Times New Roman")); pDC->SelectObject(&font); pDC->SetTextColor(m_textColor); pDC->DrawText(sLabel,rcItem, DT_CENTER|DT_VCENTER|DT_SINGLELINE); font.DeleteObject(); HBITMAP hbmNewBmp = NULL; if (isSelected) { if (m_checkedImg != NULL) { hbmNewBmp = m_checkedImg; } } else if(m_uncheckedImg) { hbmNewBmp = m_uncheckedImg; } if (hbmNewBmp != NULL) { hbmOldBmp = (HBITMAP)bitmapDC.SelectObject(hbmNewBmp); TransparentImage(pDC->m_hDC,rcItem.right-50, rcItem.top+12, 32, 32, bitmapDC.m_hDC,0, 0, 32, 32,RGB(0,0,0)); bitmapDC.SelectObject(hbmOldBmp); } }此外,如果想绘制列表子项的边框,需要边界大小,可以通过如下方式得到:
CRect rcBounds; GetItemRect(nItem, rcBounds, LVIR_BOUNDS);
void CImageListCtrl::HideScrollBars() { RECT ierect; int cxvs, cyvs; GetClientRect(&ierect); //Get client width and height cxvs = GetSystemMetrics (SM_CXVSCROLL); //Get the system metrics - VERT cyvs = GetSystemMetrics (SM_CYVSCROLL); //Get the system metrics - HORZ //if(Which==SB_HORZ) cxvs=0; //Set VERT to zero when choosen HORZ //if(Which==SB_VERT) cyvs=0; //Set HORZ to zero when choosen VERT //Here we set the position of the window to the clientrect + the size of the scrollbars SetWindowPos(NULL, ierect.left, ierect.top, ierect.right+cxvs, ierect.bottom+cyvs, SWP_NOMOVE | SWP_NOZORDER); //Her we modify the rect so the right part is subbed from the rect. ierect.bottom -= ierect.top; ierect.right -= ierect.left; //Just to be safe that the left/top corner is 0... ierect.top = 0; ierect.left = 0; HRGN iehrgn = NULL; //This range is created base on which scrollbar that is going to be removed! //The -2 is probably a border of some kind that we also need to remove. I could not find any good //metrics that gave me an 2 as an answer. So insted we makes it static with -2. iehrgn=CreateRectRgn (ierect.left, ierect.top, ierect.right-2, ierect.bottom-2); //After the range has been made we add it... SetWindowRgn (iehrgn, TRUE); }
m_imageListCtrl.LoadVScrollImages(IDB_VERTICLE_SCROLLBAR_BOTTOM,IDB_VERTICLE_SCROLLBAR_DOWNARROW,IDB_VERTICLE_SCROLLBAR_SPAN, IDB_VERTICLE_SCROLLBAR_THUMB,IDB_VERTICLE_SCROLLBAR_TOP,IDB_VERTICLE_SCROLLBAR_UPARROW); m_imageListCtrl.LoadHScrollImages(IDB_HORIZONTAL_SCROLLBAR_LEFTARROW,IDB_HORIZONTAL_SCROLLBAR_RIGHTARROW, IDB_HORIZONTAL_SCROLLBAR_SPAN,IDB_HORIZONTAL_SCROLLBAR_THUMB); m_imageListCtrl.InitCtrl(); //m_imageListCtrl.SetImageList( &m_imageList, LVSIL_SMALL ); m_imageListCtrl.SetItemCheckedImg(IDB_LISTCTRL_CHECKED_BITMAP); m_imageListCtrl.SetItemSelectedImg(IDB_LISTCTRL_ITEM_SEL_BITMAP); m_imageListCtrl.SetItemIcon(IDB_LISTCTRL_ICON_BITMAP); //m_imageListCtrl.SetItemUnCheckedImg(IDB_LISTCTRL_UNCHECK_BITMAP); for (int n = 0; n < 8; n++) { CString str; str.Format(_T("Item %d"), n); m_imageListCtrl.InsertItem(n, str); }