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)
*
* Notifications:
* LISTVIEW_Notify : most notifications from children (editbox and header)
* LISTVIEW_Notify : most notifications from editbox
*
* Data structure:
* LISTVIEW_SetItemCount : not completed for non OWNERDATA
@ -1059,6 +1059,22 @@ static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
/******** 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 */
#define LISTVIEW_InvalidateRect(infoPtr, rect) while(infoPtr->bRedraw) { \
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)
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);
return (COLUMN_INFO *)DPA_GetPtr(infoPtr->hdpaColumns, nSubItem);
}
RECT rcCol;
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);
LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcCol);
rcCol.top = infoPtr->rcList.top;
rcCol.bottom = infoPtr->rcList.bottom;
LISTVIEW_InvalidateRect(infoPtr, &rcCol);
}
/***
@ -4602,24 +4612,15 @@ static LRESULT LISTVIEW_GetCountPerPage(LISTVIEW_INFO *infoPtr)
* SUCCESS : image list handle
* 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)
{
case LVSIL_NORMAL:
himl = infoPtr->himlNormal;
break;
case LVSIL_SMALL:
himl = infoPtr->himlSmall;
break;
case LVSIL_STATE:
himl = infoPtr->himlState;
break;
case LVSIL_NORMAL: return infoPtr->himlNormal;
case LVSIL_SMALL: return infoPtr->himlSmall;
case LVSIL_STATE: return infoPtr->himlState;
}
return (LRESULT)himl;
return NULL;
}
/* LISTVIEW_GetISearchString */
@ -6041,7 +6042,17 @@ static LRESULT LISTVIEW_SetColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
if (!bResult) return FALSE;
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;
}
@ -7540,7 +7551,7 @@ static LRESULT LISTVIEW_NCDestroy(LISTVIEW_INFO *infoPtr)
/***
* DESCRIPTION:
* Handles notifications from children.
* Handles notifications from header.
*
* PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure
@ -7550,54 +7561,59 @@ static LRESULT LISTVIEW_NCDestroy(LISTVIEW_INFO *infoPtr)
* RETURN:
* 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;
TRACE("(nCtrlId=%d, lpnmh=%p)\n", nCtrlId, lpnmh);
TRACE("(lpnmh=%p)\n", lpnmh);
/* handle notification from header control */
if (lpnmh->hwndFrom == infoPtr->hwndHeader)
if (!lpnmh || lpnmh->iItem < 0 || lpnmh->iItem >= infoPtr->hdpaColumns->nItemCount) return 0;
switch (lpnmh->hdr.code)
{
LPNMHEADERW lphnm = (LPNMHEADERW)lpnmh;
if (lpnmh->code == HDN_TRACKW || lpnmh->code == HDN_TRACKA ||
lpnmh->code == HDN_ITEMCHANGEDW || lpnmh->code == HDN_ITEMCHANGEDA)
case HDN_TRACKW:
case HDN_TRACKA:
case HDN_ITEMCHANGEDW:
case HDN_ITEMCHANGEDA:
{
COLUMN_INFO *lpColumnInfo;
RECT rcCol;
INT dx;
INT dx, cxy;
if (lphnm->iItem < 0 || lphnm->iItem >= infoPtr->hdpaColumns->nItemCount) return 0;
if (!lphnm->pitem || !(lphnm->pitem->mask & HDI_WIDTH)) return 0;
if (!lpnmh->pitem || !(lpnmh->pitem->mask & HDI_WIDTH))
{
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 */
dx = lphnm->pitem->cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left);
/* ajust the column being tracked */
lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, lpnmh->iItem);
dx = cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left);
if (dx != 0)
{
lpColumnInfo->rcHeader.right += dx;
/* compute the rectangle for the tracked column */
rcCol.left = lpColumnInfo->rcHeader.left;
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);
LISTVIEW_ScrollColumns(infoPtr, lpnmh->iItem + 1, dx);
if (uView == LVS_REPORT) LISTVIEW_InvalidateColumn(infoPtr, lpnmh->iItem);
}
else if(lpnmh->code == HDN_ITEMCLICKW || lpnmh->code == HDN_ITEMCLICKA)
}
break;
case HDN_ITEMCLICKW:
case HDN_ITEMCLICKA:
{
/* Handle sorting by Header Column */
NMLISTVIEW nmlv;
ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
nmlv.iItem = -1;
nmlv.iSubItem = lphnm->iItem;
nmlv.iSubItem = lpnmh->iItem;
notify_listview(infoPtr, LVN_COLUMNCLICK, &nmlv);
}
break;
}
return 0;
@ -8195,7 +8211,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return infoPtr->dwHoverTime;
case LVM_GETIMAGELIST:
return LISTVIEW_GetImageList(infoPtr, (INT)wParam);
return (LRESULT)LISTVIEW_GetImageList(infoPtr, (INT)wParam);
/* case LVN_GETINSERTMARK: */
@ -8498,7 +8514,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return LISTVIEW_NCDestroy(infoPtr);
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:
return LISTVIEW_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam);