http://bugs.winehq.org/show_bug.cgi?id=59609 Bug ID: 59609 Summary: comctl32: LVM_GETITEMPOSITION returns client coordinates instead of view coordinates in ICON/SMALLICON views (breaks FastStone Image Viewer) Product: Wine Version: 11.5 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: major Priority: P2 Component: comctl32 Assignee: wine-bugs@list.winehq.org Reporter: lldmakhbfcrmqyluns@nesopf.com Distribution: --- Bug overview: In `dlls/comctl32/listview.c`, the function `LISTVIEW_GetItemPosition` unconditionally adds `Origin.x` and `Origin.y` to the item's coordinates. This converts the coordinates to Client coordinates. However, according to MSDN, for `LV_VIEW_ICON` and `LV_VIEW_SMALLICON` modes, `LVM_GETITEMPOSITION` must return View coordinates (absolute coordinates on the canvas), not Client coordinates. MSDN Documentation reference for LVM_GETITEMPOSITION: "In icon or small icon view, the LVM_GETITEMPOSITION message returns the item's position in view coordinates. To get the client coordinates of an item, subtract the origin from the view coordinates." Symptoms & Application Behavior: This bug breaks the top thumbnail strip in full screen mode of FastStone Image Viewer (FSViewer.exe) when scrolling horizontally. The thumbnail strip is a ListView in Icon mode (height: 150px). When the user scrolls to the right by approximately the width of the screen (e.g., ~1900px on a 1080p monitor), the thumbnails suddenly disappear, leaving blank white spaces and cropped thumbnails. The Mathematical Root Cause: Because Wine incorrectly returns Client coordinates instead of View coordinates, a "double subtraction" occurs in the application's logic: 1. Wine calculates internally: `Returned_X = Absolute_X - ScrollPos` (by adding the negative Origin). 2. FSViewer (following MSDN) attempts to calculate the client position to determine if the item is visible: `App_Client_X = Returned_X - ScrollPos`. 3. The resulting math is: `App_Client_X = Absolute_X - 2 * ScrollPos`. When `ScrollPos` exceeds the width of the window (e.g., scrolling past 1920px), the calculated right edge of the visible items becomes negative. FSViewer incorrectly concludes that all items have moved off-screen to the left. To save resources, FSViewer returns `CDRF_SKIPDEFAULT` (0x4) during the `CDDS_PREPAINT` custom draw notification. Wine respects this flag, skips drawing the items, and `BitBlt` copies a blank/white double-buffer background to the screen. Proposed Fix / Patch: The addition of `Origin` should be restricted to `LV_VIEW_DETAILS` and `LV_VIEW_LIST` views, where Client coordinates are actually expected. In `dlls/comctl32/listview.c`, modify `LISTVIEW_GetItemPosition`: --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -XXXX,X +XXXX,X @@ static BOOL LISTVIEW_GetItemPosition(const LISTVIEW_INFO *infoPtr, INT nItem, LP if (infoPtr->uView == LV_VIEW_ICON) { lpptPosition->x += (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2; lpptPosition->y += ICON_TOP_PADDING; } - lpptPosition->x += Origin.x; - lpptPosition->y += Origin.y; + + /* In Icon/SmallIcon views, position is in view coordinates (absolute). + * In Details/List views, position is in client coordinates. */ + if (infoPtr->uView == LV_VIEW_DETAILS || infoPtr->uView == LV_VIEW_LIST) + { + lpptPosition->x += Origin.x; + lpptPosition->y += Origin.y; + } TRACE (" lpptPosition=%s\n", wine_dbgstr_point(lpptPosition)); return TRUE; Testing: Applying this exact logic fully resolves the white-space rendering bug in FastStone Image Viewer without breaking standard ListView internal mechanics (since Wine internally relies on `LISTVIEW_GetItemOrigin` for drawing, which remains unaffected). -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.