Listview: custom draw for owner draw
Dimitrie O. Paun
dpaun at rogers.com
Sun Apr 27 23:31:14 CDT 2003
Strangly, some programs (e.g. emule) depend on having
custom draw messages for owner draw listviews. Odd.
ChangeLog
Generate custom draw notifications for ownerdraw listviews.
(Based on a patch by Maxime Bellenge)
Reorganize the custom draw code for better reuse.
Index: dlls/comctl32/listview.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/listview.c,v
retrieving revision 1.346
diff -u -r1.346 listview.c
--- dlls/comctl32/listview.c 24 Mar 2003 19:28:50 -0000 1.346
+++ dlls/comctl32/listview.c 27 Apr 2003 15:57:13 -0000
@@ -849,21 +849,73 @@
return bResult;
}
-static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc, const RECT *rcBounds)
+static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc,
+ const RECT *rcBounds, const LVITEMW *lplvItem)
{
ZeroMemory(lpnmlvcd, sizeof(NMLVCUSTOMDRAW));
lpnmlvcd->nmcd.hdc = hdc;
lpnmlvcd->nmcd.rc = *rcBounds;
lpnmlvcd->clrTextBk = infoPtr->clrTextBk;
lpnmlvcd->clrText = infoPtr->clrText;
+ if (!lplvItem) return;
+ lpnmlvcd->nmcd.dwItemSpec = lplvItem->iItem;
+ lpnmlvcd->iSubItem = lplvItem->iSubItem;
+ if (lplvItem->state & LVIS_SELECTED) lpnmlvcd->nmcd.uItemState |= CDIS_SELECTED;
+ if (lplvItem->state & LVIS_FOCUSED) lpnmlvcd->nmcd.uItemState |= CDIS_FOCUS;
+ if (lplvItem->iItem == infoPtr->nHotItem) lpnmlvcd->nmcd.uItemState |= CDIS_HOT;
+ lpnmlvcd->nmcd.lItemlParam = lplvItem->lParam;
}
static inline DWORD notify_customdraw (LISTVIEW_INFO *infoPtr, DWORD dwDrawStage, NMLVCUSTOMDRAW *lpnmlvcd)
{
lpnmlvcd->nmcd.dwDrawStage = dwDrawStage;
+ if (lpnmlvcd->nmcd.dwItemSpec) lpnmlvcd->nmcd.dwDrawStage |= CDDS_ITEM;
return notify_hdr(infoPtr, NM_CUSTOMDRAW, &lpnmlvcd->nmcd.hdr);
}
+static DWORD notify_prepaint (LISTVIEW_INFO *infoPtr, HDC hdc, NMLVCUSTOMDRAW *lpnmlvcd)
+{
+ BOOL isSelected = lpnmlvcd->nmcd.uItemState & CDIS_SELECTED;
+ DWORD cditemmode = notify_customdraw(infoPtr, CDDS_PREPAINT, lpnmlvcd);
+
+ if (cditemmode & CDRF_SKIPDEFAULT) return cditemmode;
+
+ /* apprently, for selected items, we have to override the returned values */
+ if (isSelected)
+ {
+ if (infoPtr->bFocus)
+ {
+ lpnmlvcd->clrTextBk = comctl32_color.clrHighlight;
+ lpnmlvcd->clrText = comctl32_color.clrHighlightText;
+ }
+ else if (infoPtr->dwStyle & LVS_SHOWSELALWAYS)
+ {
+ lpnmlvcd->clrTextBk = comctl32_color.clr3dFace;
+ lpnmlvcd->clrText = comctl32_color.clrBtnText;
+ }
+ }
+
+ /* Set the text attributes */
+ if (lpnmlvcd->clrTextBk != CLR_NONE)
+ {
+ SetBkMode(hdc, OPAQUE);
+ if (lpnmlvcd->clrTextBk == CLR_DEFAULT)
+ SetBkColor(hdc, infoPtr->clrTextBkDefault);
+ else
+ SetBkColor(hdc,lpnmlvcd->clrTextBk);
+ }
+ else
+ SetBkMode(hdc, TRANSPARENT);
+ SetTextColor(hdc, lpnmlvcd->clrText);
+
+ return cditemmode;
+}
+
+static inline DWORD notify_postpaint (LISTVIEW_INFO *infoPtr, NMLVCUSTOMDRAW *lpnmlvcd)
+{
+ return notify_customdraw(infoPtr, CDDS_POSTPAINT, lpnmlvcd);
+}
+
/******** Item iterator functions **********************************/
static RANGES ranges_create(int count);
@@ -3504,33 +3556,12 @@
debugrect(&rcBox), debugrect(&rcState), debugrect(&rcIcon), debugrect(&rcLabel));
/* fill in the custom draw structure */
- customdraw_fill(&nmlvcd, infoPtr, hdc, &rcBox);
- nmlvcd.nmcd.dwItemSpec = lvItem.iItem;
- nmlvcd.iSubItem = lvItem.iSubItem;
- if (lvItem.state & LVIS_SELECTED) nmlvcd.nmcd.uItemState |= CDIS_SELECTED;
- if (lvItem.state & LVIS_FOCUSED) nmlvcd.nmcd.uItemState |= CDIS_FOCUS;
- if (lvItem.iItem == infoPtr->nHotItem) nmlvcd.nmcd.uItemState |= CDIS_HOT;
- nmlvcd.nmcd.lItemlParam = lvItem.lParam;
+ customdraw_fill(&nmlvcd, infoPtr, hdc, &rcBox, &lvItem);
if (cdmode & CDRF_NOTIFYITEMDRAW)
- cditemmode = notify_customdraw (infoPtr, CDDS_ITEMPREPAINT, &nmlvcd);
+ cditemmode = notify_prepaint (infoPtr, hdc, &nmlvcd);
if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint;
- /* apprently, for selected items, we have to override the returned values */
- if (lvItem.state & LVIS_SELECTED)
- {
- if (infoPtr->bFocus)
- {
- nmlvcd.clrTextBk = comctl32_color.clrHighlight;
- nmlvcd.clrText = comctl32_color.clrHighlightText;
- }
- else if (infoPtr->dwStyle & LVS_SHOWSELALWAYS)
- {
- nmlvcd.clrTextBk = comctl32_color.clr3dFace;
- nmlvcd.clrText = comctl32_color.clrBtnText;
- }
- }
-
/* in full row select, subitems, will just use main item's colors */
if (nSubItem && uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
nmlvcd.clrTextBk = CLR_NONE;
@@ -3558,16 +3589,6 @@
/* Don't bother painting item being edited */
if (infoPtr->hwndEdit && nItem == infoPtr->nEditLabelItem && nSubItem == 0) goto postpaint;
- /* Set the text attributes */
- if (nmlvcd.clrTextBk != CLR_NONE)
- {
- SetBkMode(hdc, OPAQUE);
- SetBkColor(hdc, nmlvcd.clrTextBk == CLR_DEFAULT ? infoPtr->clrTextBkDefault : nmlvcd.clrTextBk);
- }
- else
- SetBkMode(hdc, TRANSPARENT);
- SetTextColor(hdc, nmlvcd.clrText);
-
/* draw the selection background, if we're drawing the main item */
if (nSubItem == 0)
{
@@ -3603,7 +3624,7 @@
postpaint:
if (cditemmode & CDRF_NOTIFYPOSTPAINT)
- notify_customdraw(infoPtr, CDDS_ITEMPOSTPAINT, &nmlvcd);
+ notify_postpaint(infoPtr, &nmlvcd);
return TRUE;
}
@@ -3618,10 +3639,12 @@
* RETURN:
* None
*/
-static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc)
+static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc, DWORD cdmode)
{
UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
HWND hwndParent = GetParent(infoPtr->hwndSelf);
+ DWORD cditemmode = CDRF_DODEFAULT;
+ NMLVCUSTOMDRAW nmlvcd;
POINT Origin, Position;
DRAWITEMSTRUCT dis;
LVITEMW item;
@@ -3659,7 +3682,18 @@
dis.itemData = item.lParam;
TRACE("item=%s, rcItem=%s\n", debuglvitem_t(&item, TRUE), debugrect(&dis.rcItem));
- SendMessageW(hwndParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
+
+ if (cdmode & CDRF_NOTIFYITEMDRAW)
+ {
+ customdraw_fill(&nmlvcd, infoPtr, hdc, &dis.rcItem, &item);
+ cditemmode = notify_prepaint (infoPtr, hdc, &nmlvcd);
+ }
+
+ if (!(cditemmode & CDRF_SKIPDEFAULT))
+ SendMessageW(hwndParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
+
+ if (cditemmode & CDRF_NOTIFYPOSTPAINT)
+ notify_postpaint(infoPtr, &nmlvcd);
}
}
@@ -3800,8 +3834,8 @@
oldClrText = infoPtr->clrText;
GetClientRect(infoPtr->hwndSelf, &rcClient);
- customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient);
- cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd);
+ customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient, 0);
+ cdmode = notify_prepaint(infoPtr, hdc, &nmlvcd);
if (cdmode & CDRF_SKIPDEFAULT) goto enddraw;
/* Use these colors to draw the items */
@@ -3827,7 +3861,7 @@
}
if ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && (uView == LVS_REPORT))
- LISTVIEW_RefreshOwnerDraw(infoPtr, &i, hdc);
+ LISTVIEW_RefreshOwnerDraw(infoPtr, &i, hdc, cdmode);
else
{
if (uView == LVS_REPORT)
@@ -3843,7 +3877,7 @@
enddraw:
if (cdmode & CDRF_NOTIFYPOSTPAINT)
- notify_customdraw(infoPtr, CDDS_POSTPAINT, &nmlvcd);
+ notify_postpaint(infoPtr, &nmlvcd);
infoPtr->clrTextBk = oldClrTextBk;
infoPtr->clrText = oldClrText;
--
Dimi.
More information about the wine-patches
mailing list