32 #define PH_MAX_COMPARE_FUNCTIONS 16
34 typedef struct _PH_EXTLV_CONTEXT
50 ULONG NumberOfFallbackColumns;
72 _In_ LPARAM lParamSort
78 _In_ LPARAM lParamSort
88 _In_ BOOLEAN EnableDefault
98 static PWSTR PhpMakeExtLvContextAtom(
117 oldWndProc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
122 context->Handle = hWnd;
123 context->OldWndProc = oldWndProc;
124 context->Context = NULL;
125 context->TriState =
FALSE;
126 context->SortColumn = 0;
128 context->SortFast =
FALSE;
129 context->TriStateCompareFunction = NULL;
130 memset(context->CompareFunctions, 0,
sizeof(context->CompareFunctions));
131 context->NumberOfFallbackColumns = 0;
133 context->ItemColorFunction = NULL;
134 context->ItemFontFunction = NULL;
136 context->EnableRedraw = 1;
137 context->Cursor = NULL;
139 SetProp(hWnd, PhpMakeExtLvContextAtom(), (HANDLE)context);
155 oldWndProc = context->OldWndProc;
161 SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)oldWndProc);
163 RemoveProp(hwnd, PhpMakeExtLvContextAtom());
168 LPNMHDR header = (LPNMHDR)lParam;
170 switch (header->code)
176 headerHandle = (HWND)CallWindowProc(context->OldWndProc, hwnd, LVM_GETHEADER, 0, 0);
178 if (header->hwndFrom == headerHandle)
180 LPNMHEADER header2 = (LPNMHEADER)header;
182 if (header2->iItem == context->SortColumn)
184 if (context->TriState)
203 context->SortColumn = header2->iItem;
217 LPNMHDR header = (LPNMHDR)lParam;
219 switch (header->code)
223 if (header->hwndFrom == hwnd)
225 LPNMLVCUSTOMDRAW customDraw = (LPNMLVCUSTOMDRAW)header;
227 switch (customDraw->nmcd.dwDrawStage)
230 return CDRF_NOTIFYITEMDRAW;
231 case CDDS_ITEMPREPAINT:
233 BOOLEAN colorChanged =
FALSE;
234 HFONT newFont = NULL;
236 if (context->ItemColorFunction)
238 customDraw->clrTextBk = context->ItemColorFunction(
239 (INT)customDraw->nmcd.dwItemSpec,
240 (PVOID)customDraw->nmcd.lItemlParam,
246 if (context->ItemFontFunction)
248 newFont = context->ItemFontFunction(
249 (INT)customDraw->nmcd.dwItemSpec,
250 (PVOID)customDraw->nmcd.lItemlParam,
256 SelectObject(customDraw->nmcd.hdc, newFont);
261 customDraw->clrText = RGB(0x00, 0x00, 0x00);
263 customDraw->clrText = RGB(0xff, 0xff, 0xff);
267 return CDRF_DODEFAULT;
283 SetCursor(context->Cursor);
288 case WM_UPDATEUISTATE:
291 switch (LOWORD(wParam))
294 wParam |= UISF_HIDEFOCUS << 16;
298 wParam &= ~(UISF_HIDEFOCUS << 16);
306 context->FallbackColumns[context->NumberOfFallbackColumns++] = (ULONG)wParam;
313 ULONG numberOfColumns = (ULONG)wParam;
314 PULONG columns = (PULONG)lParam;
319 &context->FallbackColumns[context->NumberOfFallbackColumns],
321 numberOfColumns *
sizeof(ULONG)
323 context->NumberOfFallbackColumns += numberOfColumns;
336 SetWindowPos(ListView_GetToolTips(hwnd), HWND_TOPMOST, 0, 0, 0, 0,
337 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
340 SendMessage(hwnd, WM_CHANGEUISTATE, MAKELONG(UIS_SET, UISF_HIDEFOCUS), 0);
345 ULONG column = (ULONG)wParam;
355 GetClientRect(hwnd, &clientRect);
356 availableWidth = clientRect.right;
358 lvColumn.mask = LVCF_WIDTH;
364 if (CallWindowProc(oldWndProc, hwnd, LVM_GETCOLUMN, i, (LPARAM)&lvColumn))
366 availableWidth -= lvColumn.cx;
377 if (availableWidth >= 40)
378 return CallWindowProc(oldWndProc, hwnd, LVM_SETCOLUMNWIDTH, column, availableWidth);
381 return CallWindowProc(oldWndProc, hwnd, LVM_SETCOLUMNWIDTH, column, width);
386 ULONG column = (ULONG)wParam;
392 context->CompareFunctions[column] = compareFunction;
397 context->Context = (PVOID)lParam;
402 context->Cursor = (HCURSOR)lParam;
418 context->EnableRedraw++;
420 context->EnableRedraw--;
422 if (context->EnableRedraw == 1)
424 SendMessage(hwnd, WM_SETREDRAW,
TRUE, 0);
425 InvalidateRect(hwnd, NULL,
FALSE);
427 else if (context->EnableRedraw == 0)
429 SendMessage(hwnd, WM_SETREDRAW,
FALSE, 0);
435 context->SortColumn = (ULONG)wParam;
443 context->SortFast = !!wParam;
448 context->TriState = !!wParam;
458 if (context->SortFast)
473 ListView_SortItemsEx(
483 return CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam);
502 count = Header_GetItemCount(hwnd);
507 for (i = 0; i < count; i++)
511 item.mask = HDI_FORMAT;
512 Header_GetItem(hwnd, i, &item);
518 item.fmt &= ~HDF_SORTDOWN;
519 item.fmt |= HDF_SORTUP;
523 item.fmt &= ~HDF_SORTUP;
524 item.fmt |= HDF_SORTDOWN;
529 item.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP);
532 Header_SetItem(hwnd, i, &item);
539 _In_ LPARAM lParamSort
544 INT x = (INT)lParam1;
545 INT y = (INT)lParam2;
547 PULONG fallbackColumns;
553 xItem.mask = LVIF_PARAM | LVIF_STATE;
557 yItem.mask = LVIF_PARAM | LVIF_STATE;
565 if (!CallWindowProc(context->OldWndProc, context->Handle, LVM_GETITEM, 0, (LPARAM)&xItem))
567 if (!CallWindowProc(context->OldWndProc, context->Handle, LVM_GETITEM, 0, (LPARAM)&yItem))
575 context->TriStateCompareFunction
578 result = context->TriStateCompareFunction(
595 fallbackColumns = context->FallbackColumns;
597 for (i = context->NumberOfFallbackColumns; i != 0; i--)
599 ULONG fallbackColumn = *fallbackColumns++;
601 if (fallbackColumn == context->SortColumn)
616 _In_ LPARAM lParamSort
622 PULONG fallbackColumns;
624 if (!lParam1 || !lParam2)
632 context->TriStateCompareFunction
635 result = context->TriStateCompareFunction(
652 fallbackColumns = context->FallbackColumns;
654 for (i = context->NumberOfFallbackColumns; i != 0; i--)
656 ULONG fallbackColumn = *fallbackColumns++;
658 if (fallbackColumn == context->SortColumn)
677 _In_ BOOLEAN EnableDefault
684 Context->CompareFunctions[Column]
688 Context->CompareFunctions[Column](XParam, YParam, Context->Context),
722 item.mask = LVIF_TEXT;
724 item.iSubItem = Column;
725 item.pszText = xText;
726 item.cchTextMax = 260;
729 CallWindowProc(Context->OldWndProc, Context->Handle, LVM_GETITEM, 0, (LPARAM)&item);
734 item.pszText = yText;
735 item.cchTextMax = 260;
738 CallWindowProc(Context->OldWndProc, Context->Handle, LVM_GETITEM, 0, (LPARAM)&item);
745 return wcsicmp(xText, yText);