Listview M4
Dimitrie O. Paun
dpaun at rogers.com
Tue Oct 8 09:13:10 CDT 2002
Heh, the last patch (M3) was nick named 'For the love of cool cars' :)
ChangeLog
Factor out owner draw code, so that it works for all modes
Documentation updates.
--- dlls/comctl32/listview.c.M3 Tue Oct 8 09:35:19 2002
+++ dlls/comctl32/listview.c Tue Oct 8 10:09:59 2002
@@ -3249,11 +3249,89 @@
/***
* DESCRIPTION:
+ * Draws listview items when in owner draw mode.
+ *
+ * PARAMETER(S):
+ * [I] infoPtr : valid pointer to the listview structure
+ * [I] hdc : device context handle
+ *
+ * RETURN:
+ * None
+ */
+static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, HDC hdc)
+{
+ INT nTop, nItem, nLast, nUpdateHeight, nUpdateWidth, rgntype;
+ UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
+ HWND hwndParent = GetParent(infoPtr->hwndSelf);
+ POINT Origin, Position;
+ DRAWITEMSTRUCT dis;
+ LVITEMW item;
+ RECT rcClip;
+
+ TRACE("()\n");
+
+ /* figure out what to draw */
+ /* FIXME: this works for REPORT only */
+ rgntype = GetClipBox(hdc, &rcClip);
+ if (rgntype == NULLREGION) return;
+ nUpdateHeight = rcClip.bottom - rcClip.top + 1;
+ nUpdateWidth = rcClip.right - rcClip.left;
+ nTop = LISTVIEW_GetTopIndex(infoPtr);
+ nItem = nTop + (rcClip.top - infoPtr->rcList.top) / infoPtr->nItemHeight;
+ if (nItem < nTop)
+ nItem = nTop;
+ nLast = nItem + nUpdateHeight / infoPtr->nItemHeight;
+ if (nUpdateHeight % infoPtr->nItemHeight) nLast++;
+ if (nLast > infoPtr->nItemCount)
+ nLast = infoPtr->nItemCount;
+ ZeroMemory(&dis, sizeof(dis));
+
+ /* Get scroll info once before loop */
+ if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return;
+
+
+ /* send cache hint notification */
+ if (infoPtr->dwStyle & LVS_OWNERDATA)
+ notify_odcachehint(infoPtr, nItem, nLast);
+
+ /* iterate through the invalidated rows */
+ for (; nItem < nLast; nItem++)
+ {
+ item.iItem = nItem;
+ item.iSubItem = 0;
+ item.mask = LVIF_PARAM | LVIF_STATE;
+ item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
+ if (!LISTVIEW_GetItemW(infoPtr, &item)) continue;
+
+ dis.CtlType = ODT_LISTVIEW;
+ dis.CtlID = uID;
+ dis.itemID = nItem;
+ dis.itemAction = ODA_DRAWENTIRE;
+ dis.itemState = 0;
+ if (item.state & LVIS_SELECTED) dis.itemState |= ODS_SELECTED;
+ if (infoPtr->bFocus && (item.state & LVIS_FOCUSED)) dis.itemState |= ODS_FOCUS;
+ dis.hwndItem = infoPtr->hwndSelf;
+ dis.hDC = hdc;
+ if (!LISTVIEW_GetItemListOrigin(infoPtr, nItem, &Position)) continue;
+ dis.rcItem.left = Position.x + Origin.x;
+ dis.rcItem.right = dis.rcItem.left + infoPtr->nItemWidth;
+ dis.rcItem.top = Position.y + Origin.y;
+ dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight;
+ 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);
+ }
+}
+
+/***
+ * DESCRIPTION:
* Draws listview items when in report display mode.
*
* PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure
- * [I] HDC : device context handle
+ * [I] hdc : device context handle
+ * [I] cdmode : custom draw mode
*
* RETURN:
* None
@@ -3266,8 +3344,6 @@
RECT rcItem, rcClip, rcFullSelect;
BOOL bFullSelected, isFocused;
DWORD cditemmode = CDRF_DODEFAULT;
- LONG lStyle = infoPtr->dwStyle;
- UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
TEXTATTR tmpTa, oldTa;
COLUMNCACHE *lpCols;
LVCOLUMNW lvColumn;
@@ -3291,7 +3367,7 @@
nLast = infoPtr->nItemCount;
/* send cache hint notification */
- if (lStyle & LVS_OWNERDATA)
+ if (infoPtr->dwStyle & LVS_OWNERDATA)
notify_odcachehint(infoPtr, nItem, nLast);
/* cache column info */
@@ -3341,45 +3417,6 @@
/* iterate through the invalidated rows */
for (; nItem < nLast; nItem++, nDrawPosY += infoPtr->nItemHeight)
{
- /* if owner wants to take a first stab at it, have it his way... */
- if (lStyle & LVS_OWNERDRAWFIXED)
- {
- DRAWITEMSTRUCT dis;
-
- TRACE("Owner Drawn\n");
-
- item.iItem = nItem;
- item.iSubItem = 0;
- item.mask = LVIF_PARAM | LVIF_STATE;
- item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
- if (!LISTVIEW_GetItemW(infoPtr, &item)) continue;
-
- ZeroMemory(&dis, sizeof(dis));
- dis.CtlType = ODT_LISTVIEW;
- dis.CtlID = uID;
- dis.itemID = nItem;
- dis.itemAction = ODA_DRAWENTIRE;
- if (item.state & LVIS_SELECTED) dis.itemState |= ODS_SELECTED;
- if (infoPtr->bFocus && (item.state & LVIS_FOCUSED)) dis.itemState |= ODS_FOCUS;
- dis.hwndItem = infoPtr->hwndSelf;
- dis.hDC = hdc;
- dis.rcItem.left = lpCols[0].rc.left;
- dis.rcItem.right = lpCols[nColumnCount - 1].rc.right;
- dis.rcItem.top = nDrawPosY;
- dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight;
- OffsetRect(&dis.rcItem, ptOrig.x, 0);
- dis.itemData = item.lParam;
-
- TRACE("item=%s, rcItem=%s\n", debuglvitem_t(&item, TRUE), debugrect(&dis.rcItem));
- SendMessageW(GetParent(infoPtr->hwndSelf), WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
- /* In theory we should do the default drawing if WM_DRAWITEM
- * returns FALSE but, in the words of Larry McVoy, in practice
- * theory is different than practice, and hence there are
- * important apps out there that depend on no default drawing
- * in LVS_OWNERDRAWFIXED. So we always skip to the next item. */
- continue;
- }
-
/* compute the full select rectangle, if needed */
if (bFullSelected)
{
@@ -3444,7 +3481,8 @@
*
* PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure
- * [I] HDC : device context handle
+ * [I] hdc : device context handle
+ * [I] cdmode : custom draw mode
*
* RETURN:
* None
@@ -3501,7 +3539,8 @@
*
* PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure
- * [I] HDC : device context handle
+ * [I] hdc : device context handle
+ * [I] cdmode : custom draw mode
*
* RETURN:
* None
@@ -3637,7 +3676,9 @@
/* select font */
hOldFont = SelectObject(hdc, infoPtr->hFont);
- if (uView == LVS_LIST)
+ if (infoPtr->dwStyle & LVS_OWNERDRAWFIXED)
+ LISTVIEW_RefreshOwnerDraw(infoPtr, hdc);
+ else if (uView == LVS_LIST)
LISTVIEW_RefreshList(infoPtr, hdc, cdmode);
else if (uView == LVS_REPORT)
LISTVIEW_RefreshReport(infoPtr, hdc, cdmode);
More information about the wine-patches
mailing list