void Picker_HandleDrawItem(HWND hWnd, LPDRAWITEMSTRUCT lpDrawItemStruct) { struct PickerInfo *pPickerInfo; HDC hDC = lpDrawItemStruct->hDC; RECT rcItem = lpDrawItemStruct->rcItem; UINT uiFlags = ILD_TRANSPARENT; HIMAGELIST hImageList; int nItem = lpDrawItemStruct->itemID; COLORREF clrTextSave = 0; COLORREF clrBkSave = 0; COLORREF clrImage = GetSysColor(COLOR_WINDOW); static TCHAR szBuff[MAX_PATH]; BOOL bFocus = (GetFocus() == hWnd); LPCTSTR pszText; UINT nStateImageMask = 0; BOOL bSelected = 0; LV_COLUMN lvc; LV_ITEM lvi; RECT rcAllLabels; RECT rcLabel; RECT rcIcon; int offset = 0; SIZE size; int i = 0, j = 0; int nColumn = 0; int nColumnMax = 0; int *order; BOOL bDrawAsChild = 0; int indent_space = 0; BOOL bColorChild = FALSE; BOOL bParentFound = FALSE; int nParent = 0; HBITMAP hBackground = GetBackgroundBitmap(); MYBITMAPINFO *pbmDesc = GetBackgroundInfo(); BOOL res = 0; pPickerInfo = GetPickerInfo(hWnd); order = (int*)malloc(pPickerInfo->nColumnCount * sizeof(*order)); if (!order) return; nColumnMax = Picker_GetNumColumns(hWnd); if (GetUseOldControl()) { pPickerInfo->pCallbacks->pfnGetColumnOrder(order); } else { /* Get the Column Order and save it */ res = ListView_GetColumnOrderArray(hWnd, nColumnMax, order); /* Disallow moving column 0 */ if (order[0] != 0) { for (i = 0; i < nColumnMax; i++) { if (order[i] == 0) { order[i] = order[0]; order[0] = 0; } } res = ListView_SetColumnOrderArray(hWnd, nColumnMax, order); } } /* Labels are offset by a certain amount */ /* This offset is related to the width of a space character */ GetTextExtentPoint32(hDC, TEXT(" "), 1, &size); offset = size.cx; lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM; lvi.iItem = nItem; lvi.iSubItem = order[0]; lvi.pszText = szBuff; lvi.cchTextMax = sizeof(szBuff) / sizeof(szBuff[0]); lvi.stateMask = 0xFFFF; /* get all state flags */ res = ListView_GetItem(hWnd, &lvi); bSelected = ((lvi.state & LVIS_DROPHILITED) || ( (lvi.state & LVIS_SELECTED) && ((bFocus) || (GetWindowLong(hWnd, GWL_STYLE) & LVS_SHOWSELALWAYS)))); /* figure out if we indent and draw grayed */ if (pPickerInfo->pCallbacks->pfnFindItemParent) nParent = pPickerInfo->pCallbacks->pfnFindItemParent(hWnd, lvi.lParam); else nParent = -1; bDrawAsChild = (pPickerInfo->pCallbacks->pfnGetViewMode() == VIEW_GROUPED && (nParent >= 0)); /* only indent if parent is also in this view */ if ((nParent >= 0) && bDrawAsChild) { for (i = 0; i < ListView_GetItemCount(hWnd); i++) { lvi.mask = LVIF_PARAM; lvi.iItem = i; res = ListView_GetItem(hWnd, &lvi); if (lvi.lParam == nParent) { bParentFound = TRUE; break; } } } if (pPickerInfo->pCallbacks->pfnGetOffsetChildren && pPickerInfo->pCallbacks->pfnGetOffsetChildren()) { if (!bParentFound && bDrawAsChild) { /*Reset it, as no Parent is there*/ bDrawAsChild = FALSE; bColorChild = TRUE; } else { nParent = -1; bParentFound = FALSE; } } res = ListView_GetItemRect_Modified(hWnd, nItem, &rcAllLabels, LVIR_BOUNDS); res = ListView_GetItemRect_Modified(hWnd, nItem, &rcLabel, LVIR_LABEL); rcAllLabels.left = rcLabel.left; if (hBackground != NULL) { RECT rcClient; HRGN rgnBitmap; RECT rcTmpBmp = rcItem; RECT rcFirstItem; HPALETTE hPAL; HDC htempDC; HBITMAP oldBitmap; htempDC = CreateCompatibleDC(hDC); oldBitmap = (HBITMAP)SelectObject(htempDC, hBackground); GetClientRect(hWnd, &rcClient); rcTmpBmp.right = rcClient.right; /* We also need to check whether it is the last item The update region has to be extended to the bottom if it is */ if (nItem == ListView_GetItemCount(hWnd) - 1) rcTmpBmp.bottom = rcClient.bottom; rgnBitmap = CreateRectRgnIndirect(&rcTmpBmp); SelectClipRgn(hDC, rgnBitmap); DeleteBitmap(rgnBitmap); hPAL = GetBackgroundPalette(); if (hPAL == NULL) hPAL = CreateHalftonePalette(hDC); if (GetDeviceCaps(htempDC, RASTERCAPS) & RC_PALETTE && hPAL != NULL) { SelectPalette(htempDC, hPAL, FALSE); RealizePalette(htempDC); } res = ListView_GetItemRect_Modified(hWnd, 0, &rcFirstItem, LVIR_BOUNDS); for (i = rcFirstItem.left; i < rcClient.right; i += pbmDesc->bmWidth) for (j = rcFirstItem.top; j < rcClient.bottom; j += pbmDesc->bmHeight) BitBlt(hDC, i, j, pbmDesc->bmWidth, pbmDesc->bmHeight, htempDC, 0, 0, SRCCOPY); SelectObject(htempDC, oldBitmap); DeleteDC(htempDC); if (GetBackgroundPalette() == NULL) { DeletePalette(hPAL); hPAL = NULL; } } indent_space = 0; if (bDrawAsChild) { RECT rect; res = ListView_GetItemRect_Modified(hWnd, nItem, &rect, LVIR_ICON); /* indent width of icon + the space between the icon and text * so left of clone icon starts at text of parent */ indent_space = rect.right - rect.left + offset; } rcAllLabels.left += indent_space; if (bSelected) { HBRUSH hBrush; HBRUSH hOldBrush; if (bFocus) { clrTextSave = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); clrBkSave = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT)); hBrush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); } else { clrTextSave = SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT)); clrBkSave = SetBkColor(hDC, GetSysColor(COLOR_BTNFACE)); hBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); } hOldBrush = (HBRUSH)SelectObject(hDC, hBrush); FillRect(hDC, &rcAllLabels, hBrush); SelectObject(hDC, hOldBrush); DeleteBrush(hBrush); } else { if (hBackground == NULL) { HBRUSH hBrush; hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); FillRect(hDC, &rcAllLabels, hBrush); DeleteBrush(hBrush); } if (pPickerInfo->pCallbacks->pfnGetOffsetChildren && pPickerInfo->pCallbacks->pfnGetOffsetChildren()) { if (bDrawAsChild || bColorChild) clrTextSave = SetTextColor(hDC, GetListCloneColor()); else clrTextSave = SetTextColor(hDC, GetListFontColor()); } else { if (bDrawAsChild) clrTextSave = SetTextColor(hDC, GetListCloneColor()); else clrTextSave = SetTextColor(hDC, GetListFontColor()); } clrBkSave = SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); } if (lvi.state & LVIS_CUT) { clrImage = GetSysColor(COLOR_WINDOW); uiFlags |= ILD_BLEND50; } else if (bSelected) { if (bFocus) clrImage = GetSysColor(COLOR_HIGHLIGHT); else clrImage = GetSysColor(COLOR_BTNFACE); uiFlags |= ILD_BLEND50; } nStateImageMask = lvi.state & LVIS_STATEIMAGEMASK; if (nStateImageMask) { int nImage = (nStateImageMask >> 12) - 1; hImageList = ListView_GetImageList(hWnd, LVSIL_STATE); if (hImageList) ImageList_Draw(hImageList, nImage, hDC, rcItem.left, rcItem.top, ILD_TRANSPARENT); } res = ListView_GetItemRect_Modified(hWnd, nItem, &rcIcon, LVIR_ICON); rcIcon.left += indent_space; res = ListView_GetItemRect_Modified(hWnd, nItem, &rcItem, LVIR_LABEL); hImageList = ListView_GetImageList(hWnd, LVSIL_SMALL); if (hImageList) { UINT nOvlImageMask = lvi.state & LVIS_OVERLAYMASK; if (rcIcon.left + 16 + indent_space < rcItem.right) { ImageList_DrawEx(hImageList, lvi.iImage, hDC, rcIcon.left, rcIcon.top, 16, 16, GetSysColor(COLOR_WINDOW), clrImage, uiFlags | nOvlImageMask); } } res = ListView_GetItemRect_Modified(hWnd, nItem, &rcItem, LVIR_LABEL); pszText = MakeShortString(hDC, szBuff, rcItem.right - rcItem.left, 2*offset + indent_space); rcLabel = rcItem; rcLabel.left += offset + indent_space; rcLabel.right -= offset; DrawText(hDC, pszText, -1, &rcLabel, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER); for (nColumn = 1; nColumn < nColumnMax; nColumn++) { int nRetLen; UINT nJustify; LV_ITEM lvItem; lvc.mask = LVCF_FMT | LVCF_WIDTH; res = ListView_GetColumn(hWnd, order[nColumn], &lvc); lvItem.mask = LVIF_TEXT; lvItem.iItem = nItem; lvItem.iSubItem = order[nColumn]; lvItem.pszText = szBuff; lvItem.cchTextMax = sizeof(szBuff) / sizeof(szBuff[0]); if (ListView_GetItem(hWnd, &lvItem) == FALSE) continue; rcItem.left = rcItem.right; rcItem.right += lvc.cx; nRetLen = _tcslen(szBuff); if (nRetLen == 0) continue; pszText = MakeShortString(hDC, szBuff, rcItem.right - rcItem.left, 2 * offset); nJustify = DT_LEFT; if (pszText == szBuff) { switch (lvc.fmt & LVCFMT_JUSTIFYMASK) { case LVCFMT_RIGHT: nJustify = DT_RIGHT; break; case LVCFMT_CENTER: nJustify = DT_CENTER; break; default: break; } } rcLabel = rcItem; rcLabel.left += offset; rcLabel.right -= offset; DrawText(hDC, pszText, -1, &rcLabel, nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER); } if (lvi.state & LVIS_FOCUSED && bFocus) DrawFocusRect(hDC, &rcAllLabels); SetTextColor(hDC, clrTextSave); SetBkColor(hDC, clrBkSave); free(order); res++; }
void CListCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rcItem(lpDrawItemStruct->rcItem); UINT uiFlags = ILD_TRANSPARENT; CImageList* pImageList; int nItem = lpDrawItemStruct->itemID; BOOL bFocus = (GetFocus() == this); COLORREF clrTextSave, clrBkSave; COLORREF clrImage = m_clrBkgnd; static _TCHAR szBuff[MAX_PATH]; LPCTSTR pszText; // get item data LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; lvi.iItem = nItem; lvi.iSubItem = 0; lvi.pszText = szBuff; lvi.cchTextMax = sizeof(szBuff); lvi.stateMask = 0xFFFF; // get all state flags GetItem(&lvi); BOOL bSelected = (bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED; bSelected = bSelected || (lvi.state & LVIS_DROPHILITED); // set colors if item is selected CRect rcAllLabels; GetItemRect(nItem, rcAllLabels, LVIR_BOUNDS); CRect rcLabel; GetItemRect(nItem, rcLabel, LVIR_LABEL); rcAllLabels.left = rcLabel.left; if (m_bClientWidthSel && rcAllLabels.right<m_cxClient) rcAllLabels.right = m_cxClient; // @@ clrTextSave = pDC->SetTextColor(colTextColor[0]); if (bSelected) { //@@ //clrTextSave = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); clrBkSave = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); pDC->FillRect(rcAllLabels, &CBrush(::GetSysColor(COLOR_HIGHLIGHT))); } else pDC->FillRect(rcAllLabels, &CBrush(m_clrTextBk)); // set color and mask for the icon if (lvi.state & LVIS_CUT) { clrImage = m_clrBkgnd; uiFlags |= ILD_BLEND50; } else if (bSelected) { clrImage = ::GetSysColor(COLOR_HIGHLIGHT); uiFlags |= ILD_BLEND50; } // draw state icon UINT nStateImageMask = lvi.state & LVIS_STATEIMAGEMASK; if (nStateImageMask) { int nImage = (nStateImageMask>>12) - 1; pImageList = GetImageList(LVSIL_STATE); if (pImageList) { pImageList->Draw(pDC, nImage, CPoint(rcItem.left, rcItem.top), ILD_TRANSPARENT); } } // draw normal and overlay icon CRect rcIcon; GetItemRect(nItem, rcIcon, LVIR_ICON); pImageList = GetImageList(LVSIL_SMALL); if (pImageList) { UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK; if (rcItem.left<rcItem.right-1) { ImageList_DrawEx(pImageList->m_hImageList, lvi.iImage, pDC->m_hDC,rcIcon.left,rcIcon.top, 16, 16, m_clrBkgnd, clrImage, uiFlags | nOvlImageMask); } } // draw item label GetItemRect(nItem, rcItem, LVIR_LABEL); rcItem.right -= m_cxStateImageOffset; pszText = MakeShortString(pDC, szBuff, rcItem.right-rcItem.left, 2*OFFSET_FIRST); rcLabel = rcItem; rcLabel.left += OFFSET_FIRST; rcLabel.right -= OFFSET_FIRST; pDC->DrawText(pszText,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER); // draw labels for extra columns LV_COLUMN lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH; for(int nColumn = 1; GetColumn(nColumn, &lvc); nColumn++) { rcItem.left = rcItem.right; rcItem.right += lvc.cx; int nRetLen = GetItemText(nItem, nColumn, szBuff, sizeof(szBuff)); if (nRetLen == 0) continue; pszText = MakeShortString(pDC, szBuff, rcItem.right - rcItem.left, 2*OFFSET_OTHER); UINT nJustify = DT_LEFT; if(pszText == szBuff) { switch(lvc.fmt & LVCFMT_JUSTIFYMASK) { case LVCFMT_RIGHT: nJustify = DT_RIGHT; break; case LVCFMT_CENTER: nJustify = DT_CENTER; break; default: break; } } rcLabel = rcItem; rcLabel.left += OFFSET_OTHER; rcLabel.right -= OFFSET_OTHER; if (nColumn < NR_COL_COLORS) pDC->SetTextColor(colTextColor[nColumn]); pDC->DrawText(pszText, -1, rcLabel, nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER); } // draw focus rectangle if item has focus if (lvi.state & LVIS_FOCUSED && bFocus) pDC->DrawFocusRect(rcAllLabels); // set original colors if item was selected if (bSelected) { pDC->SetTextColor(clrTextSave); pDC->SetBkColor(clrBkSave); } }