Reorganize header notifications.

Support notifications that don't have embedded size info.
Invalidate columns on format change (if needed).
Assorted cleanups.
This commit is contained in:
Dimitrie O. Paun 2002-10-21 19:41:56 +00:00 committed by Alexandre Julliard
parent 713d0a061f
commit 214c721160
1 changed files with 84 additions and 66 deletions

View File

@ -30,7 +30,7 @@
* -- Support CustonDraw options for _WIN32_IE >= 0x560 (see NMLVCUSTOMDRAW docs) * -- Support CustonDraw options for _WIN32_IE >= 0x560 (see NMLVCUSTOMDRAW docs)
* *
* Notifications: * Notifications:
* LISTVIEW_Notify : most notifications from children (editbox and header) * LISTVIEW_Notify : most notifications from editbox
* *
* Data structure: * Data structure:
* LISTVIEW_SetItemCount : not completed for non OWNERDATA * LISTVIEW_SetItemCount : not completed for non OWNERDATA
@ -1059,6 +1059,22 @@ static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
/******** Internal API functions ************************************/ /******** Internal API functions ************************************/
static inline COLUMN_INFO * LISTVIEW_GetColumnInfo(LISTVIEW_INFO *infoPtr, INT nSubItem)
{
assert (nSubItem >= 0 && nSubItem < infoPtr->hdpaColumns->nItemCount);
return (COLUMN_INFO *)DPA_GetPtr(infoPtr->hdpaColumns, nSubItem);
}
static inline void LISTVIEW_GetHeaderRect(LISTVIEW_INFO *infoPtr, INT nSubItem, RECT *lprc)
{
*lprc = LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->rcHeader;
}
static inline BOOL LISTVIEW_GetItemW(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem)
{
return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE);
}
/* The Invalidate* are macros, so we preserve the caller location */ /* The Invalidate* are macros, so we preserve the caller location */
#define LISTVIEW_InvalidateRect(infoPtr, rect) while(infoPtr->bRedraw) { \ #define LISTVIEW_InvalidateRect(infoPtr, rect) while(infoPtr->bRedraw) { \
TRACE(" invalidating rect=%s\n", debugrect(rect)); \ TRACE(" invalidating rect=%s\n", debugrect(rect)); \
@ -1089,20 +1105,14 @@ static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
LISTVIEW_InvalidateRect(infoPtr, NULL) LISTVIEW_InvalidateRect(infoPtr, NULL)
static inline COLUMN_INFO * LISTVIEW_GetColumnInfo(LISTVIEW_INFO *infoPtr, INT nSubItem) static inline void LISTVIEW_InvalidateColumn(LISTVIEW_INFO *infoPtr, INT nColumn)
{ {
assert (nSubItem >= 0 && nSubItem < infoPtr->hdpaColumns->nItemCount); RECT rcCol;
return (COLUMN_INFO *)DPA_GetPtr(infoPtr->hdpaColumns, nSubItem);
}
static inline void LISTVIEW_GetHeaderRect(LISTVIEW_INFO *infoPtr, INT nSubItem, RECT *lprc) LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcCol);
{ rcCol.top = infoPtr->rcList.top;
*lprc = LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->rcHeader; rcCol.bottom = infoPtr->rcList.bottom;
} LISTVIEW_InvalidateRect(infoPtr, &rcCol);
static inline BOOL LISTVIEW_GetItemW(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem)
{
return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE);
} }
/*** /***
@ -4602,24 +4612,15 @@ static LRESULT LISTVIEW_GetCountPerPage(LISTVIEW_INFO *infoPtr)
* SUCCESS : image list handle * SUCCESS : image list handle
* FAILURE : NULL * FAILURE : NULL
*/ */
static LRESULT LISTVIEW_GetImageList(LISTVIEW_INFO *infoPtr, INT nImageList) static HIMAGELIST LISTVIEW_GetImageList(LISTVIEW_INFO *infoPtr, INT nImageList)
{ {
HIMAGELIST himl = NULL; switch (nImageList)
{
switch (nImageList) case LVSIL_NORMAL: return infoPtr->himlNormal;
{ case LVSIL_SMALL: return infoPtr->himlSmall;
case LVSIL_NORMAL: case LVSIL_STATE: return infoPtr->himlState;
himl = infoPtr->himlNormal; }
break; return NULL;
case LVSIL_SMALL:
himl = infoPtr->himlSmall;
break;
case LVSIL_STATE:
himl = infoPtr->himlState;
break;
}
return (LRESULT)himl;
} }
/* LISTVIEW_GetISearchString */ /* LISTVIEW_GetISearchString */
@ -6041,7 +6042,17 @@ static LRESULT LISTVIEW_SetColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
if (!bResult) return FALSE; if (!bResult) return FALSE;
if (lpColumn->mask & LVCF_FMT) if (lpColumn->mask & LVCF_FMT)
LISTVIEW_GetColumnInfo(infoPtr, nColumn)->fmt = lpColumn->fmt; {
COLUMN_INFO *lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, nColumn);
int oldFmt = lpColumnInfo->fmt;
lpColumnInfo->fmt = lpColumn->fmt;
if ((oldFmt ^ lpColumn->fmt) & (LVCFMT_JUSTIFYMASK | LVCFMT_IMAGE))
{
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
if (uView == LVS_REPORT) LISTVIEW_InvalidateColumn(infoPtr, nColumn);
}
}
return TRUE; return TRUE;
} }
@ -7540,7 +7551,7 @@ static LRESULT LISTVIEW_NCDestroy(LISTVIEW_INFO *infoPtr)
/*** /***
* DESCRIPTION: * DESCRIPTION:
* Handles notifications from children. * Handles notifications from header.
* *
* PARAMETER(S): * PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure * [I] infoPtr : valid pointer to the listview structure
@ -7550,54 +7561,59 @@ static LRESULT LISTVIEW_NCDestroy(LISTVIEW_INFO *infoPtr)
* RETURN: * RETURN:
* Zero * Zero
*/ */
static LRESULT LISTVIEW_Notify(LISTVIEW_INFO *infoPtr, INT nCtrlId, LPNMHDR lpnmh) static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, LPNMHEADERW lpnmh)
{ {
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
TRACE("(nCtrlId=%d, lpnmh=%p)\n", nCtrlId, lpnmh); TRACE("(lpnmh=%p)\n", lpnmh);
/* handle notification from header control */ if (!lpnmh || lpnmh->iItem < 0 || lpnmh->iItem >= infoPtr->hdpaColumns->nItemCount) return 0;
if (lpnmh->hwndFrom == infoPtr->hwndHeader)
switch (lpnmh->hdr.code)
{ {
LPNMHEADERW lphnm = (LPNMHEADERW)lpnmh; case HDN_TRACKW:
case HDN_TRACKA:
if (lpnmh->code == HDN_TRACKW || lpnmh->code == HDN_TRACKA || case HDN_ITEMCHANGEDW:
lpnmh->code == HDN_ITEMCHANGEDW || lpnmh->code == HDN_ITEMCHANGEDA) case HDN_ITEMCHANGEDA:
{ {
COLUMN_INFO *lpColumnInfo; COLUMN_INFO *lpColumnInfo;
RECT rcCol; INT dx, cxy;
INT dx;
if (lphnm->iItem < 0 || lphnm->iItem >= infoPtr->hdpaColumns->nItemCount) return 0; if (!lpnmh->pitem || !(lpnmh->pitem->mask & HDI_WIDTH))
if (!lphnm->pitem || !(lphnm->pitem->mask & HDI_WIDTH)) return 0; {
HDITEMW hdi;
lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, lphnm->iItem); hdi.mask = HDI_WIDTH;
if (!Header_GetItemW(infoPtr->hwndHeader, lpnmh->iItem, (LPARAM)&hdi)) return 0;
cxy = hdi.cxy;
}
else
cxy = lpnmh->pitem->cxy;
/* determine how much we change since the last know position */ /* determine how much we change since the last know position */
dx = lphnm->pitem->cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left); lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, lpnmh->iItem);
dx = cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left);
/* ajust the column being tracked */ if (dx != 0)
lpColumnInfo->rcHeader.right += dx; {
lpColumnInfo->rcHeader.right += dx;
/* compute the rectangle for the tracked column */ LISTVIEW_ScrollColumns(infoPtr, lpnmh->iItem + 1, dx);
rcCol.left = lpColumnInfo->rcHeader.left; if (uView == LVS_REPORT) LISTVIEW_InvalidateColumn(infoPtr, lpnmh->iItem);
rcCol.top = infoPtr->rcList.top; }
rcCol.right = lpColumnInfo->rcHeader.right;
rcCol.bottom = infoPtr->rcList.bottom;
LISTVIEW_ScrollColumns(infoPtr, lphnm->iItem + 1, dx);
if (uView == LVS_REPORT) LISTVIEW_InvalidateRect(infoPtr, &rcCol);
} }
else if(lpnmh->code == HDN_ITEMCLICKW || lpnmh->code == HDN_ITEMCLICKA) break;
case HDN_ITEMCLICKW:
case HDN_ITEMCLICKA:
{ {
/* Handle sorting by Header Column */ /* Handle sorting by Header Column */
NMLISTVIEW nmlv; NMLISTVIEW nmlv;
ZeroMemory(&nmlv, sizeof(NMLISTVIEW)); ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
nmlv.iItem = -1; nmlv.iItem = -1;
nmlv.iSubItem = lphnm->iItem; nmlv.iSubItem = lpnmh->iItem;
notify_listview(infoPtr, LVN_COLUMNCLICK, &nmlv); notify_listview(infoPtr, LVN_COLUMNCLICK, &nmlv);
} }
break;
} }
return 0; return 0;
@ -8195,7 +8211,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return infoPtr->dwHoverTime; return infoPtr->dwHoverTime;
case LVM_GETIMAGELIST: case LVM_GETIMAGELIST:
return LISTVIEW_GetImageList(infoPtr, (INT)wParam); return (LRESULT)LISTVIEW_GetImageList(infoPtr, (INT)wParam);
/* case LVN_GETINSERTMARK: */ /* case LVN_GETINSERTMARK: */
@ -8498,7 +8514,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return LISTVIEW_NCDestroy(infoPtr); return LISTVIEW_NCDestroy(infoPtr);
case WM_NOTIFY: case WM_NOTIFY:
return LISTVIEW_Notify(infoPtr, (INT)wParam, (LPNMHDR)lParam); if (lParam && ((LPNMHDR)lParam)->hwndFrom == infoPtr->hwndHeader)
return LISTVIEW_HeaderNotification(infoPtr, (LPNMHEADERW)lParam);
else return 0;
case WM_NOTIFYFORMAT: case WM_NOTIFYFORMAT:
return LISTVIEW_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam); return LISTVIEW_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam);