Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/listview.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 95d619af75..6b32167dcd 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -1351,11 +1351,14 @@ static inline BOOL iterator_rangesitems(ITERATOR* i, RANGES ranges) static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *frame) { RECT rcItem, rcTemp; - + + TRACE("(frame=%s)\n", wine_dbgstr_rect(frame)); + /* in case we fail, we want to return an empty iterator */ if (!iterator_empty(i)) return FALSE;
- TRACE("(frame=%s)\n", wine_dbgstr_rect(frame)); + if (infoPtr->nItemCount == 0) + return TRUE;
if (infoPtr->uView == LV_VIEW_ICON || infoPtr->uView == LV_VIEW_SMALLICON) {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/listview.c | 2 +- dlls/comctl32/tests/listview.c | 72 ++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 6b32167dcd..7915ece624 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -1808,7 +1808,7 @@ static inline INT LISTVIEW_GetCountPerColumn(const LISTVIEW_INFO *infoPtr) { INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
- return max(nListHeight / infoPtr->nItemHeight, 1); + return infoPtr->nItemHeight ? max(nListHeight / infoPtr->nItemHeight, 1) : 0; }
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 6a7842b495..5c2b3b7a07 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -6398,6 +6398,76 @@ static void test_LVN_ENDLABELEDIT(void) DestroyWindow(hwnd); }
+static LRESULT CALLBACK create_item_height_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_CREATE) + return 0; + + return CallWindowProcA(listviewWndProc, hwnd, msg, wParam, lParam); +} + +static void test_LVM_GETCOUNTPERPAGE(void) +{ + static const DWORD styles[] = { LVS_ICON, LVS_LIST, LVS_REPORT, LVS_SMALLICON }; + unsigned int i, j; + WNDCLASSEXA cls; + ATOM class; + HWND hwnd; + BOOL ret; + + cls.cbSize = sizeof(WNDCLASSEXA); + ret = GetClassInfoExA(GetModuleHandleA(NULL), WC_LISTVIEWA, &cls); + ok(ret, "Failed to get class info.\n"); + listviewWndProc = cls.lpfnWndProc; + cls.lpfnWndProc = create_item_height_wndproc; + cls.lpszClassName = "CountPerPageClass"; + class = RegisterClassExA(&cls); + ok(class, "Failed to register class.\n"); + + for (i = 0; i < ARRAY_SIZE(styles); i++) + { + static char text[] = "item text"; + LVITEMA item = { 0 }; + UINT count, count2; + + hwnd = create_listview_control(styles[i]); + ok(hwnd != NULL, "Failed to create listview window.\n"); + + count = SendMessageA(hwnd, LVM_GETCOUNTPERPAGE, 0, 0); + if (styles[i] == LVS_LIST || styles[i] == LVS_REPORT) + ok(count > 0 || broken(styles[i] == LVS_LIST && count == 0), "%u: unexpected count %u.\n", i, count); + else + ok(count == 0, "%u: unexpected count %u.\n", i, count); + + for (j = 0; j < 10; j++) + { + item.mask = LVIF_TEXT; + item.pszText = text; + SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item); + } + + count2 = SendMessageA(hwnd, LVM_GETCOUNTPERPAGE, 0, 0); + if (styles[i] == LVS_LIST || styles[i] == LVS_REPORT) + ok(count == count2, "%u: unexpected count %u.\n", i, count2); + else + ok(count2 == 10, "%u: unexpected count %u.\n", i, count2); + + DestroyWindow(hwnd); + + hwnd = CreateWindowA("CountPerPageClass", "Test", WS_VISIBLE | styles[i], 0, 0, 100, 100, NULL, NULL, + GetModuleHandleA(NULL), 0); + ok(hwnd != NULL, "Failed to create a window.\n"); + + count = SendMessageA(hwnd, LVM_GETCOUNTPERPAGE, 0, 0); + ok(count == 0, "%u: unexpected count %u.\n", i, count); + + DestroyWindow(hwnd); + } + + ret = UnregisterClassA("CountPerPageClass", NULL); + ok(ret, "Failed to unregister test class.\n"); +} + START_TEST(listview) { ULONG_PTR ctx_cookie; @@ -6460,6 +6530,7 @@ START_TEST(listview) test_state_image(); test_LVSCW_AUTOSIZE(); test_LVN_ENDLABELEDIT(); + test_LVM_GETCOUNTPERPAGE();
if (!load_v6_module(&ctx_cookie, &hCtx)) { @@ -6503,6 +6574,7 @@ START_TEST(listview) test_state_image(); test_LVSCW_AUTOSIZE(); test_LVN_ENDLABELEDIT(); + test_LVM_GETCOUNTPERPAGE();
unload_v6_module(ctx_cookie, hCtx);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/listview.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 7915ece624..c5978b37a5 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -1315,21 +1315,19 @@ static inline void iterator_destroy(const ITERATOR *i) /*** * Create an empty iterator. */ -static inline BOOL iterator_empty(ITERATOR* i) +static inline void iterator_empty(ITERATOR* i) { ZeroMemory(i, sizeof(*i)); i->nItem = i->nSpecial = i->range.lower = i->range.upper = -1; - return TRUE; }
/*** * Create an iterator over a range. */ -static inline BOOL iterator_rangeitems(ITERATOR* i, RANGE range) +static inline void iterator_rangeitems(ITERATOR* i, RANGE range) { iterator_empty(i); i->range = range; - return TRUE; }
/*** @@ -1337,11 +1335,10 @@ static inline BOOL iterator_rangeitems(ITERATOR* i, RANGE range) * Please note that the iterator will take ownership of the ranges, * and will free them upon destruction. */ -static inline BOOL iterator_rangesitems(ITERATOR* i, RANGES ranges) +static inline void iterator_rangesitems(ITERATOR* i, RANGES ranges) { iterator_empty(i); i->ranges = ranges; - return TRUE; }
/*** @@ -1351,11 +1348,12 @@ static inline BOOL iterator_rangesitems(ITERATOR* i, RANGES ranges) static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* infoPtr, const RECT *frame) { RECT rcItem, rcTemp; + RANGES ranges;
TRACE("(frame=%s)\n", wine_dbgstr_rect(frame));
/* in case we fail, we want to return an empty iterator */ - if (!iterator_empty(i)) return FALSE; + iterator_empty(i);
if (infoPtr->nItemCount == 0) return TRUE; @@ -1370,7 +1368,8 @@ static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* info if (IntersectRect(&rcTemp, &rcItem, frame)) i->nSpecial = infoPtr->nFocusedItem; } - if (!(iterator_rangesitems(i, ranges_create(50)))) return FALSE; + if (!(ranges = ranges_create(50))) return FALSE; + iterator_rangesitems(i, ranges); /* to do better here, we need to have PosX, and PosY sorted */ TRACE("building icon ranges:\n"); for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) @@ -1394,7 +1393,7 @@ static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* info range.lower = max(frame->top / infoPtr->nItemHeight, 0); range.upper = min((frame->bottom - 1) / infoPtr->nItemHeight, infoPtr->nItemCount - 1) + 1; if (range.upper <= range.lower) return TRUE; - if (!iterator_rangeitems(i, range)) return FALSE; + iterator_rangeitems(i, range); TRACE(" report=%s\n", debugrange(&i->range)); } else @@ -1426,7 +1425,8 @@ static BOOL iterator_frameditems_absolute(ITERATOR* i, const LISTVIEW_INFO* info if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE;
- if (!(iterator_rangesitems(i, ranges_create(nLastCol - nFirstCol + 1)))) return FALSE; + if (!(ranges = ranges_create(nLastCol - nFirstCol + 1))) return FALSE; + iterator_rangesitems(i, ranges); TRACE("building list ranges:\n"); for (nCol = nFirstCol; nCol <= nLastCol; nCol++) { @@ -1467,7 +1467,11 @@ static BOOL iterator_visibleitems(ITERATOR *i, const LISTVIEW_INFO *infoPtr, HDC INT rgntype;
rgntype = GetClipBox(hdc, &rcClip); - if (rgntype == NULLREGION) return iterator_empty(i); + if (rgntype == NULLREGION) + { + iterator_empty(i); + return TRUE; + } if (!iterator_frameditems(i, infoPtr, &rcClip)) return FALSE; if (rgntype == SIMPLEREGION) return TRUE;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/comctl32/tests/listview.c | 10 ---------- 1 file changed, 10 deletions(-)
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c index 5c2b3b7a07..48612db54f 100644 --- a/dlls/comctl32/tests/listview.c +++ b/dlls/comctl32/tests/listview.c @@ -525,7 +525,6 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP /* always accept new item text */ NMLVDISPINFOA *di = (NMLVDISPINFOA*)lParam; g_editbox_disp_info = *di; - trace("LVN_ENDLABELEDIT: text=%s\n", di->item.pszText ? di->item.pszText : "(null)");
/* edit control still available from this notification */ edit = (HWND)SendMessageA(((NMHDR*)lParam)->hwndFrom, LVM_GETEDITCONTROL, 0, 0); @@ -537,15 +536,6 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP
return TRUE; } - case LVN_BEGINSCROLL: - case LVN_ENDSCROLL: - { - NMLVSCROLL *pScroll = (NMLVSCROLL*)lParam; - - trace("LVN_%sSCROLL: (%d,%d)\n", pScroll->hdr.code == LVN_BEGINSCROLL ? - "BEGIN" : "END", pScroll->dx, pScroll->dy); - } - break; case LVN_ITEMCHANGING: { NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;