From ce2b1410e217aba08003b117b725d17c8e169199 Mon Sep 17 00:00:00 2001 From: Luc Tourangeau Date: Wed, 17 Feb 1999 12:58:48 +0000 Subject: [PATCH] Preliminary listview control implementation. --- dlls/comctl32/listview.c | 4254 ++++++++++++++++++++++++++++++-------- include/commctrl.h | 28 +- include/listview.h | 12 +- 3 files changed, 3422 insertions(+), 872 deletions(-) diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index 6e2319946be..d10ab566616 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -2,781 +2,2586 @@ * Listview control * * Copyright 1998 Eric Kohl + * Copyright 1999 Luc Tourangeau * * NOTES - * This is just a dummy control. An author is needed! Any volunteers? - * I will only improve this control once in a while. - * Eric + * Listview control implementation. The behavior conforms to version 4.70 + * and earlier of the listview contol. * * TODO: - * - Most messages. - * - Most notifications. + * Most messages and notifications + * Report, small icon and icon display modes */ -#include "windows.h" +#include #include "commctrl.h" #include "listview.h" #include "win.h" #include "debug.h" +#include "winuser.h" + +/* prototypes */ +static INT32 LISTVIEW_GetItemCountPerColumn(HWND32 hwnd); +static INT32 LISTVIEW_GetItemCountPerRow(HWND32 hwnd); +static INT32 LISTVIEW_GetFirstVisibleItem(HWND32 hwnd); +static VOID LISTVIEW_SetVisible(HWND32 hwnd, INT32 nItem); -#define LISTVIEW_GetInfoPtr(wndPtr) ((LISTVIEW_INFO *)wndPtr->wExtra[0]) - - -static VOID -LISTVIEW_Refresh (WND *wndPtr, HDC32 hdc) +/*** + * DESCRIPTION: + * Scrolls the specified item into the visible area. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * + * RETURN: + * None + */ +static VOID LISTVIEW_SetVisible(HWND32 hwnd, INT32 nItem) { -/* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */ + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nItemCountPerRow; + INT32 nItemCountPerColumn; + INT32 nLastItem; + INT32 nFirstItem; + INT32 nHScrollPos; + INT32 nVScrollPos; + /* retrieve the index of the first visible fully item */ + nFirstItem = LISTVIEW_GetFirstVisibleItem(hwnd); + /* nunber of fully visible items per row */ + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + /* nunber of fully visible items per column */ + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + + if ((nItemCountPerRow > 0) && (nItemCountPerColumn > 0)) + { + if (lStyle & LVS_LIST) + { + if (lStyle & WS_HSCROLL) + { + /* last visible item index */ + nLastItem = nItemCountPerColumn * nItemCountPerRow + nFirstItem - 1; + if (nItem > nLastItem) + { + /* calculate new scroll position based on item index */ + if (((nItem - nLastItem) % nItemCountPerColumn) == 0) + nHScrollPos = (nItem - nLastItem) / nItemCountPerColumn; + else + nHScrollPos = (nItem - nLastItem) / nItemCountPerColumn + 1; + SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)nHScrollPos, (LPARAM)0); + } + else if (nItem < nFirstItem) + { + /* calculate new scroll position based on item index */ + if (((nItem - nFirstItem) % nItemCountPerColumn) == 0) + nHScrollPos = (nItem - nFirstItem) / nItemCountPerColumn; + else + nHScrollPos = (nItem - nFirstItem) / nItemCountPerColumn - 1; + SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)nHScrollPos, (LPARAM)0); + } + } + } + else if (lStyle & LVS_REPORT) + { + if (lStyle & WS_VSCROLL) + { + if (nFirstItem > 0) + { + nLastItem = nItemCountPerColumn + nFirstItem; + } + else +{ + nLastItem = nItemCountPerColumn + nFirstItem - 1; + } + + if (nItem > nLastItem) + { + /* calculate new scroll position based on item index */ + nVScrollPos = nItem - nLastItem; + SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)0, (LPARAM)nVScrollPos); + } + else if (nItem < nFirstItem) + { + /* calculate new scroll position based on item index */ + nVScrollPos = nItem - nFirstItem; + SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)0, (LPARAM)nVScrollPos); + } + } + } + else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON)) + { + if (lStyle & WS_VSCROLL) + { + /* last visible item index */ + nLastItem = nItemCountPerColumn * nItemCountPerRow + nFirstItem - 1; + if (nItem > nLastItem) + { + /* calculate new scroll position based on item index */ + nVScrollPos = (nItem - nLastItem) / nItemCountPerRow + 1; + SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)0, (LPARAM)nVScrollPos); + } + else if (nItem < nFirstItem) + { + /* calculate new scroll position based on item index */ + nHScrollPos = (nItem - nFirstItem) / nItemCountPerRow - 1; + SendMessage32A(hwnd, LVM_SCROLL, (WPARAM32)0, (LPARAM)nHScrollPos); + } + } + } + + /* refresh display */ + InvalidateRect32(hwnd, NULL, FALSE); + UpdateWindow32(hwnd); + +} +} + +/*** + * DESCRIPTION: + * Retrieves the index of the item at coordinate (0, 0) of the client area. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * item index + */ +static INT32 LISTVIEW_GetFirstVisibleItem(HWND32 hwnd) +{ + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nItemCountPerRow; + INT32 nItemCountPerColumn; + INT32 nMinRange; + INT32 nMaxRange; + INT32 nHScrollPos; +/* INT32 nVScrollPos; */ + INT32 nItem = 0; + + /* get number of items per column */ + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + + /* get number of fully visble items per row */ + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + + if ((nItemCountPerRow > 0) && (nItemCountPerColumn > 0)) + { + if (lStyle & LVS_LIST) + { + if (lStyle & WS_HSCROLL) + { + GetScrollRange32(hwnd, SB_HORZ, &nMinRange, &nMaxRange); + nHScrollPos = GetScrollPos32(hwnd, SB_HORZ); + if (nMinRange < nHScrollPos) + { + nItem = ((nHScrollPos - nMinRange) * nItemCountPerColumn * + nItemCountPerRow); + } + } + } + else if (lStyle & LVS_REPORT) + { + /* TO DO */ + } + else if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } + } + + return nItem; +} + +/*** + * DESCRIPTION: + * Retrieves the number of items per row. In other words, the number + * visible display columns. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Number of items per row. + */ +static INT32 LISTVIEW_GetItemCountPerRow(HWND32 hwnd) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nItemCountPerRow = 0; + + if (infoPtr->nWidth > 0) + { + if (lStyle & LVS_LIST) + { + if (infoPtr->nColumnWidth > 0) + { + nItemCountPerRow = infoPtr->nWidth / infoPtr->nColumnWidth; + if (nItemCountPerRow == 0) + nItemCountPerRow = 1; + } + } + else if (lStyle & LVS_REPORT) + { + /* TO DO */ + } + else if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } + } + + return nItemCountPerRow; +} + +/*** + * DESCRIPTION: + * Retrieves the number of items that can be displayed vertically in + * the listview. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Number of items per column. + */ +static INT32 LISTVIEW_GetItemCountPerColumn(HWND32 hwnd) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nItemCountPerColumn = 0; + + if (infoPtr->nHeight > 0) + { + if (lStyle & LVS_LIST) + { + if (infoPtr->nItemHeight > 0) + nItemCountPerColumn = infoPtr->nHeight / infoPtr->nItemHeight; + } + else if (lStyle & LVS_REPORT) + { + /* TO DO */ + } + else if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } + } + + return nItemCountPerColumn; +} + +/*** + * DESCRIPTION: + * Retrieves the number of columns needed to display + * all the items in listview. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Number of columns. + */ +static INT32 LISTVIEW_GetColumnCount(HWND32 hwnd) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nColumnCount = 0; + INT32 nItemCountPerColumn; + + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + + if ((infoPtr->nItemCount > 0) && (nItemCountPerColumn > 0)) + { + if (lStyle & LVS_LIST) + { + if ((infoPtr->nItemCount % nItemCountPerColumn) == 0) + { + nColumnCount = infoPtr->nItemCount / nItemCountPerColumn ; + } + else + { + nColumnCount = infoPtr->nItemCount / nItemCountPerColumn + 1; + } + } + else if (lStyle & LVS_REPORT) + { + /* TO DO */ + } + else if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } + } + + return nColumnCount; +} + +/*** + * DESCRIPTION: + * Sets the scrolling parameters. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * None + */ +static VOID LISTVIEW_SetScroll(HWND32 hwnd) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nColumnCount; + INT32 nItemCountPerRow; + INT32 nItemCountPerColumn; + INT32 nMinRange, nMaxRange; + INT32 nHScrollPos; +/* INT32 nVScrollPos; */ + + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + + if ((nItemCountPerColumn > 0) && (nItemCountPerRow > 0)) + { + if (lStyle & LVS_LIST) + { + /* get number of columns needed to display all the listview items */ + nColumnCount = LISTVIEW_GetColumnCount(hwnd); + if (nColumnCount > 0) + { + if (nColumnCount > nItemCountPerRow) + { + /* add scrollbar if not already present */ + if (!(lStyle & WS_HSCROLL)) + { + /* display scrollbar */ + ShowScrollBar32(hwnd, SB_HORZ, TRUE); + + /* set scrollbar range and position */ + nMaxRange = nColumnCount - nItemCountPerRow; + SetScrollRange32(hwnd, SB_HORZ, 0, nMaxRange, FALSE); + SetScrollPos32(hwnd, SB_HORZ, 0, TRUE); + } + else + { + nHScrollPos = GetScrollPos32(hwnd, SB_HORZ); + GetScrollRange32(hwnd, SB_HORZ, &nMinRange, &nMaxRange); + if (nMaxRange != nColumnCount - nItemCountPerRow) + { + nMaxRange = nColumnCount - nItemCountPerRow; + SetScrollRange32(hwnd, SB_HORZ, nMinRange, nMaxRange, FALSE); + + if (nHScrollPos > nMaxRange) + nHScrollPos = nMaxRange; + + SetScrollPos32(hwnd, SB_HORZ, nHScrollPos, TRUE); + } + } + + /* refresh the client area */ + InvalidateRect32(hwnd,NULL, TRUE); + UpdateWindow32(hwnd); + } + else + { + /* remove scrollbar if present */ + if (lStyle & WS_HSCROLL) + { + /* hide scrollbar */ + ShowScrollBar32(hwnd, SB_HORZ, FALSE); + + /* refresh the client area */ + InvalidateRect32(hwnd,NULL, TRUE); + UpdateWindow32(hwnd); + } + } + } + } + else if (lStyle & LVS_REPORT) + { + HDLAYOUT hl; + WINDOWPOS32 wp; + RECT32 rc; + + rc.top = 0; + rc.left = 0; + rc.right = infoPtr->nWidth; + rc.bottom = infoPtr->nHeight; + + hl.prc = &rc; + hl.pwpos = ℘ + SendMessage32A(infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl); + + SetWindowPos32(infoPtr->hwndHeader, hwnd, + wp.x, wp.y, wp.cx, wp.cy, wp.flags); + +/* infoPtr->rcList.top += wp.cy; */ + } + else if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } + } +} + +/*** + * DESCRIPTION: + * Modifies the state (selected and focused) of the listview items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : focused item index + * [I] BOOL32 : flag for determining weither the control keys are used or not + * [I] BOOL32 : flag for determining the input type (mouse or keyboard) + * + * RETURN: + * None + */ +static VOID LISTVIEW_SetItemStates(HWND32 hwnd, INT32 nFocusedItem, + BOOL32 bVirtualKeys, BOOL32 bMouseInput) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + WORD wShift = HIWORD(GetKeyState32(VK_SHIFT)); + WORD wCtrl = HIWORD(GetKeyState32(VK_CONTROL)); + INT32 i; + LVITEM32A lvItem; + + /* initialize memory */ + ZeroMemory(&lvItem, sizeof(LVITEM32A)); + + if (wShift && (bVirtualKeys == TRUE)) + { + /* reset the selected and focused states of all the items */ + lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; + lvItem.state = 0; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem); + + if (infoPtr->nSelectionMark > nFocusedItem) + { + for (i = infoPtr->nSelectionMark; i > nFocusedItem; i--) + { + /* select items */ + lvItem.stateMask = LVIS_SELECTED; + lvItem.state = LVIS_SELECTED; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)i, (LPARAM)&lvItem); + } + } + else + { + for (i = infoPtr->nSelectionMark; i < nFocusedItem; i++) + { + /* select items */ + lvItem.stateMask = LVIS_SELECTED; + lvItem.state = LVIS_SELECTED; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)i, (LPARAM)&lvItem); + } + } + + /* select anf focus item */ + lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; + lvItem.state = LVIS_SELECTED | LVIS_FOCUSED; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)i, (LPARAM)&lvItem); + } + else + { + if (wCtrl && (bVirtualKeys == TRUE)) + { + /* make sure the focus is lost */ + lvItem.stateMask = LVIS_FOCUSED; + lvItem.state = 0; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem); + + if (bMouseInput == TRUE) + { + if (SendMessage32A(hwnd, LVM_GETITEMSTATE, (WPARAM32)nFocusedItem, + (LPARAM)LVIS_SELECTED) & LVIS_SELECTED) + { + /* focus and unselect (toggle selection) */ + lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; + lvItem.state = LVIS_FOCUSED; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)nFocusedItem, + (LPARAM)&lvItem); + } + else + { + /* select and focus */ + lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; + lvItem.state = LVIS_SELECTED | LVIS_FOCUSED; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)nFocusedItem, + (LPARAM)&lvItem); + } + + /* set the group selection start position */ + infoPtr->nSelectionMark = nFocusedItem; + } + else + { + /* focus */ + lvItem.stateMask = LVIS_FOCUSED; + lvItem.state = LVIS_FOCUSED; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)nFocusedItem, + (LPARAM)&lvItem); + } + } + else + { + /* clear selection and focus for all the items */ + lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; + lvItem.state = 0; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem); + + /* set select and focus for this particular item */ + lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED; + lvItem.state = LVIS_FOCUSED | LVIS_SELECTED; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)nFocusedItem, + (LPARAM)&lvItem); + + /* set the new group selection start position */ + infoPtr->nSelectionMark = nFocusedItem; + } + } +} + +/*** + * DESCRIPTION: + * Draws listview items when in list display maode. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] HDC32 : device context handle + * + * RETURN: + * None + */ +static VOID LISTVIEW_RefreshList(HWND32 hwnd, HDC32 hdc) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpItem; + HFONT32 hOldFont; + HPEN32 hPen, hOldPen; + INT32 nItemCountPerColumn; + INT32 nItemCountPerRow; + INT32 nSmallIconWidth; + SIZE32 labelSize; + INT32 nDrawPosX = 0; + INT32 nDrawPosY = 0; + BOOL32 bSelected; + RECT32 rcBoundingBox; + COLORREF clrHighlight; + COLORREF clrHighlightText; + INT32 i; + INT32 nColumn = 0; + INT32 nRow; + INT32 j; + + /* get number of items per column */ + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + + /* get number of items per row */ + nItemCountPerRow = LISTVIEW_GetItemCountPerColumn(hwnd); + + if ((nItemCountPerColumn > 0) && (nItemCountPerRow > 0)) + { + /* select font */ + hOldFont = SelectObject32(hdc, infoPtr->hFont); + + /* inititialize system dependent information */ + clrHighlight = GetSysColor32(COLOR_HIGHLIGHT); + clrHighlightText = GetSysColor32(COLOR_HIGHLIGHTTEXT); + nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON); + + /* select transparent brush (for drawing the focus box) */ + SelectObject32(hdc, GetStockObject32(NULL_BRUSH)); + + /* select the doted pen (for drawing the focus box) */ + hPen = CreatePen32(PS_DOT, 1, 0); + hOldPen = SelectObject32(hdc, hPen); + + /* get starting index */ + i = LISTVIEW_GetFirstVisibleItem(hwnd); + + /* DRAW ITEMS */ + for (j = 0; i < infoPtr->nItemCount; i++, j++) + { + /* set draw position for current item */ + nRow = j % nItemCountPerColumn; + nColumn = j / nItemCountPerColumn; + if (nRow == 0) + nDrawPosY = 0; + else + nDrawPosY += infoPtr->nItemHeight; + + nDrawPosX = nColumn * infoPtr->nColumnWidth; + + /* get item */ + lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, i); + if (lpItem != NULL) + { + if (lpItem->state & LVIS_SELECTED) + { + bSelected = TRUE; + + /* set item colors */ + SetBkColor32(hdc, clrHighlight); + SetTextColor32(hdc, clrHighlightText); + + /* set raster mode */ + SetROP232(hdc, R2_XORPEN); + } + else + { + bSelected = FALSE; + + /* set item colors */ + SetBkColor32(hdc, infoPtr->clrTextBk); + SetTextColor32(hdc, infoPtr->clrText); + + /* set raster mode */ + SetROP232(hdc, R2_COPYPEN); + } + + /* state images */ + if (infoPtr->himlState != NULL) + { + /* right shift 12 bits to obtain index in image list */ + if (bSelected == TRUE) + ImageList_Draw(infoPtr->himlState, lpItem->state >> 12, hdc, + nDrawPosX, nDrawPosY, ILD_SELECTED); + else + ImageList_Draw(infoPtr->himlState, lpItem->state >> 12, hdc, + nDrawPosX, nDrawPosY, ILD_NORMAL); + + nDrawPosX += nSmallIconWidth; + } + + /* small icons */ + if (infoPtr->himlSmall != NULL) + { + if (bSelected == TRUE) + ImageList_Draw(infoPtr->himlSmall, lpItem->iImage, hdc, nDrawPosX, + nDrawPosY, ILD_SELECTED); + else + ImageList_Draw(infoPtr->himlSmall, lpItem->iImage, hdc, nDrawPosX, + nDrawPosY, ILD_NORMAL); + + nDrawPosX += nSmallIconWidth; + } + + /* get string size (in pixels) */ + GetTextExtentPoint32A(hdc, lpItem->pszText, + lstrlen32A(lpItem->pszText), &labelSize); + + /* define a bounding box */ + rcBoundingBox.left = nDrawPosX; + rcBoundingBox.top = nDrawPosY; + + /* 2 pixels for padding purposes */ + rcBoundingBox.right = nDrawPosX + labelSize.cx + 2; + + /* padding already included in infoPtr->nItemHeight */ + rcBoundingBox.bottom = nDrawPosY + infoPtr->nItemHeight; + + /* draw text */ + ExtTextOut32A(hdc, nDrawPosX + 1, nDrawPosY+ 1, + ETO_OPAQUE|ETO_CLIPPED, &rcBoundingBox, + lpItem->pszText, lstrlen32A(lpItem->pszText), NULL); + + if (lpItem->state & LVIS_FOCUSED) + Rectangle32(hdc, rcBoundingBox.left, rcBoundingBox.top, + rcBoundingBox.right, rcBoundingBox.bottom); + } + } + + /* unselect objects */ + SelectObject32(hdc, hOldFont); + SelectObject32(hdc, hOldPen); + + /* delete pen */ + DeleteObject32(hPen); + } +} + +/*** + * DESCRIPTION: + * Draws listview items when in report display mode. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] HDC32 : device context handle + * + * RETURN: + * None + */ +static VOID LISTVIEW_RefreshReport(HWND32 hwnd, HDC32 hdc) +{ + /* TO DO */ +} + +/*** + * DESCRIPTION: + * Draws listview items when in small icon display mode. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] HDC32 : device context handle + * + * RETURN: + * None + */ +static VOID LISTVIEW_RefreshSmallIcon(HWND32 hwnd, HDC32 hdc) +{ + /* TO DO */ +} + +/*** + * DESCRIPTION: + * Draws listview items when in icon display mode. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] HDC32 : device context handle + * + * RETURN: + * None + */ +static VOID LISTVIEW_RefreshIcon(HWND32 hwnd, HDC32 hdc) +{ + /* TO DO */ +} + +/*** + * DESCRIPTION: + * Draws listview items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] HDC32 : device context handle + * + * RETURN: + * None + */ +static VOID LISTVIEW_Refresh(HWND32 hwnd, HDC32 hdc) +{ + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + + if (lStyle & LVS_LIST) + { + LISTVIEW_RefreshList(hwnd, hdc); + } + else if (lStyle & LVS_REPORT) + { + LISTVIEW_RefreshReport(hwnd, hdc); + } + else if (lStyle & LVS_SMALLICON) + { + LISTVIEW_RefreshSmallIcon(hwnd, hdc); + } + else if (lStyle & LVS_ICON) + { + LISTVIEW_RefreshIcon(hwnd, hdc); + } } +/*** + * DESCRIPTION: + * Calculates the approximate width and height of a given number of items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : number of items + * [I] INT32 : width + * [I] INT32 : height + * + * RETURN: + * Returns a DWORD. The width in the low word and the height in high word. + */ +static LRESULT LISTVIEW_ApproximateViewRect(HWND32 hwnd, INT32 nItemCount, + WORD wWidth, WORD wHeight) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nItemCountPerColumn = 1; + INT32 nColumnCount = 0; + DWORD dwViewRect = 0; + + if (nItemCount == -1) + nItemCount = infoPtr->nItemCount; + + if (lStyle & LVS_LIST) + { + if (wHeight == 0xFFFF) + { + /* use current height */ + wHeight = infoPtr->nHeight; + } + + if (wHeight < infoPtr->nItemHeight) + { + wHeight = infoPtr->nItemHeight; + } + + if (nItemCount > 0) + { + if (infoPtr->nItemHeight > 0) + { + nItemCountPerColumn = wHeight / infoPtr->nItemHeight; + if (nItemCountPerColumn == 0) + nItemCountPerColumn = 1; + + if (nItemCount % nItemCountPerColumn != 0) + nColumnCount = nItemCount / nItemCountPerColumn; + else + nColumnCount = nItemCount / nItemCountPerColumn + 1; + } + } + + wHeight = nItemCountPerColumn * infoPtr->nItemHeight + 2; + wWidth = nColumnCount * infoPtr->nColumnWidth + 2; + + dwViewRect = MAKELONG(wWidth, wHeight); + } + else if (lStyle & LVS_REPORT) + { + /* TO DO */ + } + else if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } + + return dwViewRect; +} + +/*** + * DESCRIPTION: + * Arranges listview items in icon display mode. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : alignment code + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_Arrange(HWND32 hwnd, INT32 nAlignCode) +{ + /* LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); */ + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + BOOL32 bResult = FALSE; + + if (lStyle & LVS_ICON) + { + switch (nAlignCode) + { + case LVA_ALIGNLEFT: + /* TO DO */ + break; + case LVA_ALIGNTOP: + /* TO DO */ + break; + case LVA_DEFAULT: + /* TO DO */ + break; + case LVA_SNAPTOGRID: + /* TO DO */ + } + } + + return bResult; +} -/* << LISTVIEW_ApproximateViewRect >> */ -/* << LISTVIEW_Arrange >> */ /* << LISTVIEW_CreateDragImage >> */ - -static LRESULT -LISTVIEW_DeleteAllItems (WND *wndPtr) +/*** + * DESCRIPTION: + * Removes all listview items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_DeleteAllItems(HWND32 hwnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - INT32 nItem; - LISTVIEW_ITEM *lpItem; - NMLISTVIEW nmlv; - BOOL32 bNotify; - - if (infoPtr->nItemCount == 0) - return TRUE; - - TRACE (listview, "\n"); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + LISTVIEW_ITEM *lpItem; + NMLISTVIEW nmlv; + BOOL32 bNotify; + INT32 i; + BOOL32 bResult = TRUE; + if (infoPtr->nItemCount > 0) + { /* send LVN_DELETEALLITEMS notification */ ZeroMemory (&nmlv, sizeof (NMLISTVIEW)); - nmlv.hdr.hwndFrom = wndPtr->hwndSelf; - nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.hwndFrom = hwnd; + nmlv.hdr.idFrom = lCtrlId; nmlv.hdr.code = LVN_DELETEALLITEMS; nmlv.iItem = -1; - bNotify = - !(BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + bNotify = !(BOOL32)SendMessage32A(GetParent32(hwnd), WM_NOTIFY, + (WPARAM32)lCtrlId, (LPARAM)&nmlv); nmlv.hdr.code = LVN_DELETEITEM; - for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) { - /* send notification */ - if (bNotify) { - nmlv.iItem = nItem; - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + for (i = 0; i < infoPtr->nItemCount; i++) + { + if (bNotify == TRUE) + { + /* send LVN_DELETEITEM notification */ + nmlv.iItem = i; + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmlv); } - /* get item pointer */ - lpItem = (LISTVIEW_ITEM*)DPA_GetPtr (infoPtr->hdpaItems, nItem); - if (lpItem) { - /* delete item strings */ - if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A)) + /* get item */ + lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, i); + if (lpItem != NULL) + { + /* free item string */ + if ((lpItem->pszText != NULL) && + (lpItem->pszText != LPSTR_TEXTCALLBACK32A)) COMCTL32_Free (lpItem->pszText); - /* free item data */ + /* free item */ COMCTL32_Free (lpItem); } } + /* ???? needs follow up */ DPA_DeleteAllPtrs (infoPtr->hdpaItems); + + /* reset item counter */ infoPtr->nItemCount = 0; - return TRUE; + /* reset scrollbar */ + LISTVIEW_SetScroll(hwnd); } + return bResult; +} -static LRESULT -LISTVIEW_DeleteColumn (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Removes a column from the listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : column index + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_DeleteColumn(HWND32 hwnd, INT32 nColumn) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - /* INT32 nColumn = (INT32)wParam; */ +/* LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); */ /* FIXME ??? */ - if (infoPtr->nItemCount > 0) - return FALSE; - - if (!SendMessage32A (infoPtr->hwndHeader, HDM_DELETEITEM, wParam, 0)) - return FALSE; - - infoPtr->nColumnCount--; - - FIXME (listview, "semi stub!\n"); +/* if (infoPtr->nItemCount > 0) */ +/* return FALSE; */ +/* if (!SendMessage32A(infoPtr->hwndHeader, HDM_DELETEITEM, wParam, 0)) */ +/* return FALSE; */ +/* infoPtr->nColumnCount--; */ +/* FIXME (listview, "semi stub!\n"); */ return TRUE; } - -static LRESULT -LISTVIEW_DeleteItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Removes an item from the listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_DeleteItem(HWND32 hwnd, INT32 nItem) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - INT32 nItem = (INT32)wParam; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); LISTVIEW_ITEM *lpItem; NMLISTVIEW nmlv; + BOOL32 bResult = FALSE; - if ((nItem < 0) || (nItem >= infoPtr->nItemCount)) - return FALSE; - - TRACE (listview, "(%d)\n", nItem); - - /* send notification */ + if ((nItem >= 0) && (nItem < infoPtr->nItemCount)) + { + /* send LVN_DELETEITEM notification */ ZeroMemory (&nmlv, sizeof (NMLISTVIEW)); - nmlv.hdr.hwndFrom = wndPtr->hwndSelf; - nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.hwndFrom = hwnd; + nmlv.hdr.idFrom = lCtrlId; nmlv.hdr.code = LVN_DELETEITEM; nmlv.iItem = nItem; - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmlv); - /* remove from item array */ + /* remove item */ lpItem = (LISTVIEW_ITEM*)DPA_DeletePtr (infoPtr->hdpaItems, nItem); - - /* delete item strings */ - if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A)) + if (lpItem != NULL) + { + /* free item string */ + if ((lpItem->pszText != NULL) && + (lpItem->pszText != LPSTR_TEXTCALLBACK32A)) COMCTL32_Free (lpItem->pszText); - /* free item data */ + /* free item */ COMCTL32_Free (lpItem); + } + /* decrement item counter */ infoPtr->nItemCount--; - return TRUE; + /* reset some of the draw data */ + LISTVIEW_SetScroll(hwnd); + + bResult = TRUE; } + return bResult; +} /* << LISTVIEW_EditLabel >> */ /* << LISTVIEW_EnsureVisible >> */ -/* << LISTVIEW_FindItem >> */ - -static LRESULT -LISTVIEW_GetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Searches for an item with specific characteristics. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : base item index + * [I] LPLVFINDINFO : item information to look for + * + * RETURN: + * SUCCESS : index of item + * FAILURE : -1 + */ +static LRESULT LISTVIEW_FindItem(HWND32 hwnd, INT32 nStart, + LPLVFINDINFO lpFindInfo) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); +/* LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); */ +/* LISTVIEW_ITEM *lpItem; */ +/* INT32 nItem; */ +/* INT32 nEnd = infoPtr->nItemCount; */ +/* BOOL32 bWrap = FALSE; */ +/* if (nStart == -1) */ +/* nStart = 0; */ +/* else */ +/* nStart++ ; */ +/* if (lpFindInfo->flags & LVFI_PARAM) */ +/* { */ +/* for (nItem = nStart; nItem < nEnd; nItem++) */ +/* { */ + /* get item pointer */ +/* lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); */ +/* if (lpItem != NULL) */ +/* { */ +/* if (lpFindInfo->lParam == lpItem->lParam) */ +/* return nItem; */ +/* } */ +/* } */ +/* } */ +/* else */ +/* { */ +/* if (lpFindInfo->flags & LVFI_PARTIAL) */ +/* { */ +/* for (nItem = nStart; nItem < nEnd; nItem++) */ +/* { */ + /* get item pointer */ +/* lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); */ +/* if (lpItem) */ +/* { */ +/* if (strncmp(lpItem->pszText, lpFindInfo->psz, strlen(lpFindInfo->psz)) */ +/* == 0) */ +/* return nItem; */ +/* } */ +/* } */ +/* } */ + +/* if (lpFindInfo->flags & LVFI_STRING) */ +/* { */ +/* for (nItem = nStart; nItem < nEnd; nItem++) */ +/* { */ + /* get item pointer */ +/* lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); */ +/* if (lpItem != NULL) */ +/* { */ +/* if (strcmp(lpItem->pszText, lpFindInfo->psz) == 0) */ +/* return nItem; */ +/* } */ +/* } */ +/* } */ + +/* if ((lpFindInfo->flags & LVFI_WRAP) && nStart) */ +/* { */ +/* nEnd = nStart; */ +/* nStart = 0; */ +/* bWrap = TRUE; */ +/* } */ +/* else */ +/* bWrap = FALSE; */ + + return -1; +} + +/*** + * DESCRIPTION: + * Retrieves the background color of the listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * COLORREF associated with the background. + */ +static LRESULT LISTVIEW_GetBkColor(HWND32 hwnd) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); return infoPtr->clrBk; } +/*** + * DESCRIPTION: + * Retrieves the background image of the listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [O] LPLVMKBIMAGE : background image information + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +/* static LRESULT LISTVIEW_GetBkImage(HWND32 hwnd, LPLVBKIMAGE lpBkImage) */ +/* { */ +/* return FALSE; */ +/* } */ -/* << LISTVIEW_GetBkImage >> */ /* << LISTVIEW_GetCallbackMask >> */ - -static LRESULT -LISTVIEW_GetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves column attributes. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : column index + * [IO] LPLVCOLUMN32A : column information + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_GetColumn32A(HWND32 hwnd, INT32 nIndex, + LPLVCOLUMN32A lpColumn) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam; - INT32 nIndex = (INT32)wParam; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); HDITEM32A hdi; - if (!lpcol) + if (lpColumn == NULL) return FALSE; - TRACE (listview, "(%d %p)\n", nIndex, lpcol); - ZeroMemory (&hdi, sizeof(HDITEM32A)); - if (lpcol->mask & LVCF_FMT) + if (lpColumn->mask & LVCF_FMT) hdi.mask |= HDI_FORMAT; - if (lpcol->mask & LVCF_WIDTH) + if (lpColumn->mask & LVCF_WIDTH) hdi.mask |= HDI_WIDTH; - if (lpcol->mask & LVCF_TEXT) + if (lpColumn->mask & LVCF_TEXT) hdi.mask |= (HDI_TEXT | HDI_FORMAT); - if (lpcol->mask & LVCF_IMAGE) + if (lpColumn->mask & LVCF_IMAGE) hdi.mask |= HDI_IMAGE; - if (lpcol->mask & LVCF_ORDER) + if (lpColumn->mask & LVCF_ORDER) hdi.mask |= HDI_ORDER; if (!SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A, - wParam, (LPARAM)&hdi)) + (WPARAM32)nIndex, (LPARAM)&hdi)) return FALSE; - if (lpcol->mask & LVCF_FMT) { - lpcol->fmt = 0; + if (lpColumn->mask & LVCF_FMT) + { + lpColumn->fmt = 0; if (hdi.fmt & HDF_LEFT) - lpcol->fmt |= LVCFMT_LEFT; + lpColumn->fmt |= LVCFMT_LEFT; else if (hdi.fmt & HDF_RIGHT) - lpcol->fmt |= LVCFMT_RIGHT; + lpColumn->fmt |= LVCFMT_RIGHT; else if (hdi.fmt & HDF_CENTER) - lpcol->fmt |= LVCFMT_CENTER; + lpColumn->fmt |= LVCFMT_CENTER; if (hdi.fmt & HDF_IMAGE) - lpcol->fmt |= LVCFMT_COL_HAS_IMAGES; + lpColumn->fmt |= LVCFMT_COL_HAS_IMAGES; } - if (lpcol->mask & LVCF_WIDTH) - lpcol->cx = hdi.cxy; + if (lpColumn->mask & LVCF_WIDTH) + lpColumn->cx = hdi.cxy; - if ((lpcol->mask & LVCF_TEXT) && (lpcol->pszText) && (hdi.pszText)) - lstrcpyn32A (lpcol->pszText, hdi.pszText, lpcol->cchTextMax); + if ((lpColumn->mask & LVCF_TEXT) && (lpColumn->pszText) && (hdi.pszText)) + lstrcpyn32A (lpColumn->pszText, hdi.pszText, lpColumn->cchTextMax); - if (lpcol->mask & LVCF_IMAGE) - lpcol->iImage = hdi.iImage; + if (lpColumn->mask & LVCF_IMAGE) + lpColumn->iImage = hdi.iImage; - if (lpcol->mask & LVCF_ORDER) - lpcol->iOrder = hdi.iOrder; + if (lpColumn->mask & LVCF_ORDER) + lpColumn->iOrder = hdi.iOrder; return TRUE; } - /* << LISTVIEW_GetColumn32W >> */ /* << LISTVIEW_GetColumnOrderArray >> */ - -__inline__ static LRESULT -LISTVIEW_GetColumnWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the column width when list or report display mode. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] int32 : column index + * + * RETURN: + * SUCCESS : column width + * FAILURE : zero + */ +static LRESULT LISTVIEW_GetColumnWidth(HWND32 hwnd, INT32 nColumn) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); HDITEM32A hdi; + INT32 nColumnWidth = 0; + if ((lStyle & LVS_LIST) || (lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON)) + { + nColumnWidth = infoPtr->nColumnWidth; + } + else if (lStyle & LVS_REPORT) + { + /* verify validity of index */ + if ((nColumn >= 0) && (nColumn < infoPtr->nColumnCount)) + { + /* get column width from header */ hdi.mask = HDI_WIDTH; if (SendMessage32A (infoPtr->hwndHeader, HDM_GETITEM32A, - wParam, (LPARAM)&hdi)) - return hdi.cxy; + (WPARAM32)nColumn, (LPARAM)&hdi)) + nColumnWidth = hdi.cxy; + } + } - return 0; + return nColumnWidth; } - -/* << LISTVIEW_GetCountPerPage >> */ -/* << LISTVIEW_GetEditControl >> */ -/* << LISTVIEW_GetExtendedListviewStyle >> */ - - -__inline__ static LRESULT -LISTVIEW_GetHeader (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * In list or report display mode, retrieves the number of items that can fit + * vertically in the visible area. In icon or small icon display mode, + * retrieves the total number of visible items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Number of fully visible items. + */ +static LRESULT LISTVIEW_GetCountPerPage(HWND32 hwnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nItemCount = 0; + INT32 nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + INT32 nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + + if (lStyle & LVS_LIST) + { + if ((nItemCountPerRow > 0) && (nItemCountPerColumn > 0)) + { + nItemCount = nItemCountPerRow * nItemCountPerColumn; + } + } + else if (lStyle & LVS_REPORT) + { + nItemCount = nItemCountPerColumn; + } + else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON)) + { + nItemCount = infoPtr->nItemCount; + } + + return nItemCount; +} + +/* << LISTVIEW_GetEditControl >> */ +/* << LISTVIEW_GetExtendedListViewStyle >> */ + +/*** + * DESCRIPTION: + * Retrieves a header handle. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Header handle. + */ +static LRESULT LISTVIEW_GetHeader(HWND32 hwnd) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); return infoPtr->hwndHeader; } - /* << LISTVIEW_GetHotCursor >> */ /* << LISTVIEW_GetHotItem >> */ /* << LISTVIEW_GetHoverTime >> */ - -static LRESULT -LISTVIEW_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves an image list handle. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : image list identifier + * + * RETURN: + * SUCCESS : image list handle + * FAILURE : NULL + */ +static LRESULT LISTVIEW_GetImageList(HWND32 hwnd, INT32 nImageList) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + HIMAGELIST himl = NULL; - TRACE (listview, "(0x%08x)\n", wParam); - - switch (wParam) { + switch (nImageList) + { case LVSIL_NORMAL: - return (LRESULT)infoPtr->himlNormal; - + himl = infoPtr->himlNormal; case LVSIL_SMALL: - return (LRESULT)infoPtr->himlSmall; - + himl = infoPtr->himlSmall; case LVSIL_STATE: - return (LRESULT)infoPtr->himlState; + himl = infoPtr->himlState; } - return (LRESULT)NULL; + return (LRESULT)himl; } /* << LISTVIEW_GetISearchString >> */ - -static LRESULT -LISTVIEW_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves item attributes. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [IO] LPLVITEM32A : item info + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_GetItem32A(HWND32 hwnd, LPLVITEM32A lpItem) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPLVITEM32A lpItem = (LPLVITEM32A)lParam; - LISTVIEW_ITEM *lpRow, *lpSubItem; - - if (!lpItem) - return FALSE; - - if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount)) - return FALSE; - - if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount)) - return FALSE; - - FIXME (listview, "(%d %d %p)\n", - lpItem->iItem, lpItem->iSubItem, lpItem); - - lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem); - if (!lpRow) - return FALSE; - - lpSubItem = &lpRow[lpItem->iSubItem]; - if (!lpSubItem) - return FALSE; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpListItem; + BOOL32 bResult = FALSE; + if (lpItem != NULL) + { + if ((lpItem->iItem >= 0) && (lpItem->iItem < infoPtr->nItemCount)) + { + /* get item */ + lpListItem = DPA_GetPtr(infoPtr->hdpaItems, lpItem->iItem); + if (lpListItem != NULL) + { + /* not tested for subitem > 0 */ + lpListItem += lpItem->iSubItem; + if (lpListItem != NULL) + { + /* retrieve valid data */ if (lpItem->mask & LVIF_STATE) - lpItem->state = lpSubItem->state & lpItem->stateMask; + lpItem->state = lpListItem->state & lpItem->stateMask; - if (lpItem->mask & LVIF_TEXT) { - if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) + if (lpItem->mask & LVIF_TEXT) + { + if (lpListItem->pszText == LPSTR_TEXTCALLBACK32A) lpItem->pszText = LPSTR_TEXTCALLBACK32A; else - Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText, + Str_GetPtr32A(lpListItem->pszText, lpItem->pszText, lpItem->cchTextMax); } if (lpItem->mask & LVIF_IMAGE) - lpItem->iImage = lpSubItem->iImage; + lpItem->iImage = lpListItem->iImage; if (lpItem->mask & LVIF_PARAM) - lpItem->lParam = lpSubItem->lParam; + lpItem->lParam = lpListItem->lParam; if (lpItem->mask & LVIF_INDENT) - lpItem->iIndent = lpSubItem->iIndent; + lpItem->iIndent = lpListItem->iIndent; - return TRUE; + bResult = TRUE; +} + } + } + } + + return bResult; } - /* << LISTVIEW_GetItem32W >> */ +/* << LISTVIEW_GetHotCursor >> */ +/* << LISTVIEW_GetHotItem >> */ +/* << LISTVIEW_GetHoverTime >> */ - -__inline__ static LRESULT -LISTVIEW_GetItemCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the number of items in the listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Number of items. + */ +static LRESULT LISTVIEW_GetItemCount(HWND32 hwnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); + return infoPtr->nItemCount; } - -static LRESULT -LISTVIEW_GetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the position (upper-left) of the listview control item. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * [O] LPPOINT32 : coordinate information + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_GetItemPosition(HWND32 hwnd, INT32 nItem, + LPPOINT32 lpPt) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPPOINT32 lpPt = (LPPOINT32)lParam; - INT32 nIndex = (INT32)wParam; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nColumn; + INT32 nRow; + BOOL32 bResult = FALSE; + INT32 nItemCountPerColumn; + INT32 nItemCountPerRow; + INT32 nFirstItem; + INT32 nLastItem; - if (!lpPt) - return FALSE; - if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount)) - return FALSE; + if ((nItem >= 0) && (nItem < infoPtr->nItemCount) && (lpPt != NULL)) + { + if (lStyle & LVS_LIST) +{ + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); - FIXME (listview, "returning position [0,0]!\n"); - lpPt->x = 0; - lpPt->y = 0; + if ((nItemCountPerColumn > 0) && (nItemCountPerRow > 0)) + { + nFirstItem = LISTVIEW_GetFirstVisibleItem(hwnd); + nLastItem = nFirstItem + nItemCountPerRow * nItemCountPerRow - 1; - return TRUE; + if ((nItem >= nFirstItem) || (nItem <= nLastItem)) + { + nItem -= nFirstItem; + + /* get column */ + nColumn = nItem / nItemCountPerColumn; + + /* get row */ + nRow = nItem % nItemCountPerColumn; + + /* X coordinate of the column */ + lpPt->x = nColumn * infoPtr->nColumnWidth; + + /* Y coordinate of the item */ + lpPt->y = nRow * infoPtr->nItemHeight; + + bResult = TRUE; + } + } + else if (lStyle & LVS_REPORT) + { + /* TO DO */ + } + else if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) +{ + /* TO DO */ + } + } + } + + return bResult; } - -/* << LISTVIEW_GetItemRect >> */ -/* << LISTVIEW_GetItemSpacing >> */ -/* << LISTVIEW_GetItemState >> */ - - -static LRESULT -LISTVIEW_GetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the bounding rectangle for a listview control item. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * [IO] LPRECT32 : bounding rectangle coordinates + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_GetItemRect(HWND32 hwnd, INT32 nItem, LPRECT32 lpRect) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPLVITEM32A lpItem = (LPLVITEM32A)lParam; - INT32 nItem = (INT32)wParam; - LISTVIEW_ITEM *lpRow, *lpSubItem; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpItem; + POINT32 pt; + INT32 nLabelWidth; + BOOL32 bResult = FALSE; + INT32 nSmallIconWidth; - TRACE (listview, "(%d %p)\n", nItem, lpItem); + nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON); - lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem); - if (!lpRow) - return 0; + if ((nItem < 0) || (nItem >= infoPtr->nItemCount) || (lpRect == NULL)) + return FALSE; - lpSubItem = &lpRow[lpItem->iSubItem]; - if (!lpSubItem) - return 0; + /* get item */ + lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); + if (lpItem == NULL) + return FALSE; - if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) { - lpItem->pszText = LPSTR_TEXTCALLBACK32A; - return 0; + if (!SendMessage32A(hwnd, LVM_GETITEMPOSITION, (WPARAM32)nItem, (LPARAM)&pt)) + return FALSE; + + nLabelWidth = SendMessage32A(hwnd, LVM_GETSTRINGWIDTH32A, (WPARAM32)0, + (LPARAM)lpItem->pszText); + switch(lpRect->left) + { + case LVIR_BOUNDS: + lpRect->left = pt.x; + lpRect->top = pt.y; + lpRect->right = lpRect->left + nSmallIconWidth + nLabelWidth; + lpRect->bottom = lpRect->top + infoPtr->nItemHeight; + bResult = TRUE; + break; + case LVIR_ICON: + lpRect->left = pt.x; + lpRect->top = pt.y; + lpRect->right = lpRect->left + nSmallIconWidth; + lpRect->bottom = lpRect->top + infoPtr->nItemHeight; + bResult = TRUE; + break; + case LVIR_LABEL: + lpRect->left = pt.x + nSmallIconWidth; + lpRect->top = pt.y; + lpRect->right = lpRect->left + nLabelWidth; + lpRect->bottom = infoPtr->nItemHeight; + bResult = TRUE; + break; + case LVIR_SELECTBOUNDS: + /* TO DO */ + break; + } + + return bResult; +} + +/*** + * DESCRIPTION: + * Retrieves the spacing between listview control items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] BOOL32 : small icon (TRUE) or large icon (FALSE) + * + * RETURN: + * Horizontal + vertical spacing + */ +static LRESULT LISTVIEW_GetItemSpacing(HWND32 hwnd, BOOL32 bSmall) +{ + INT32 nSmallIconHSpacing; + INT32 nSmallIconVSpacing; + INT32 nIconHSpacing; + INT32 nIconVSpacing; + LONG lResult = 0; + + if (bSmall == TRUE) + { + /* ??? */ + nSmallIconHSpacing = 0; + nSmallIconVSpacing = 0; + lResult = MAKELONG(nSmallIconHSpacing, nSmallIconVSpacing); } else - return Str_GetPtr32A (lpSubItem->pszText, lpItem->pszText, - lpItem->cchTextMax); + { + nIconHSpacing = GetSystemMetrics32(SM_CXICONSPACING); + nIconVSpacing = GetSystemMetrics32(SM_CYICONSPACING); + lResult = MAKELONG(nIconHSpacing, nIconVSpacing); + } + + return lResult; } - -/* << LISTVIEW_GetItemText32A >> */ - - -static LRESULT -LISTVIEW_GetNextItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the state of a listview control item. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * [I] UINT32 : state mask + * + * RETURN: + * State specified by the mask. + */ +static LRESULT LISTVIEW_GetItemState(HWND32 hwnd, INT32 nItem, UINT32 uMask) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - INT32 nStart = (INT32)wParam; - UINT32 uFlags = (UINT32)LOWORD(lParam); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpItem; + INT32 nState = 0; - FIXME (listview, "(%d, 0x%x): semi stub!\n", nStart, uFlags); + if ((nItem >= 0) && (nItem < infoPtr->nItemCount)) + { + lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); + if (lpItem != NULL) + nState = lpItem->state & uMask; + } - if (infoPtr->nItemCount <= 0) - return -1; - - /* just a simple (preliminary) hack */ - if (nStart == -1) - return 0; - else if (nStart < infoPtr->nItemCount - 1) - return nStart + 1; - else - return -1; - - return -1; + return nState; } +/*** + * DESCRIPTION: + * Retrieves the text of a listview control item or subitem. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * [IO] LPLVITEM32A : item information + * + * RETURN: + * None + */ +static VOID LISTVIEW_GetItemText32A(HWND32 hwnd, INT32 nItem, + LPLVITEM32A lpItem) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpListItem; + + if ((nItem < 0) || (nItem >= infoPtr->nItemCount) || (lpItem == NULL)) + return; + + lpListItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); + if (lpListItem == NULL) + return; + + lpListItem += lpItem->iSubItem; + if (lpListItem == NULL) + return; + + if (lpListItem->pszText == LPSTR_TEXTCALLBACK32A) + lpItem->pszText = LPSTR_TEXTCALLBACK32A; + else + Str_GetPtr32A(lpListItem->pszText, lpItem->pszText, lpItem->cchTextMax); +} + +/*** + * DESCRIPTION: + * Searches for an item based on properties + relationships. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * [I] UINT32 : relationship flag + * + * RETURN: + * SUCCESS : item index + * FAILURE : -1 + */ +static LRESULT LISTVIEW_GetNextItem (HWND32 hwnd, INT32 nItem, UINT32 uFlags) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + INT32 nResult = -1; + + /* start at begin */ + if (nItem == -1) + nItem = 0; + + if ((nItem >= 0) && (nItem < infoPtr->nItemCount)) + { + /* TO DO */ +} + + return nResult; +} /* << LISTVIEW_GetNumberOfWorkAreas >> */ -/* << LISTVIEW_GetOrigin >> */ - -static LRESULT -LISTVIEW_GetSelectedCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the current origin when in icon or small icon display mode. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [O] LPPOINT32 : coordinate information + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_GetOrigin(HWND32 hwnd, LPPOINT32 lpOrigin) { - /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */ + LONG lStyle = GetWindowLong32A(hwnd, GWL_ID); + BOOL32 bResult = FALSE; - TRACE (listview, ": empty stub (returns 0)!\n"); + if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } - return 0; + return bResult; } - -/* << LISTVIEW_GetSelectionMark >> */ - - -static LRESULT -LISTVIEW_GetStringWidth32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the number of items that are marked as selected. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Number of items selected. + */ +static LRESULT LISTVIEW_GetSelectedCount(HWND32 hwnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPSTR lpsz = (LPSTR)lParam; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpItem; + INT32 nSelectedCount = 0; + INT32 i; + + for (i = 0; i < infoPtr->nItemCount; i++) + { + lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, i); + if (lpItem != NULL) + { + if (lpItem->state & LVIS_SELECTED) + nSelectedCount++; + } + } + + return nSelectedCount; +} + +/*** + * DESCRIPTION: + * Retrieves item index that marks the start of a multiple selection. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Index number or -1 if there is no selection mark. + */ +static LRESULT LISTVIEW_GetSelectionMark(HWND32 hwnd) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + INT32 nResult = -1; + + if (SendMessage32A(hwnd, LVM_GETSELECTEDCOUNT, (WPARAM32)0, (LPARAM)0) != 0) + nResult = infoPtr->nSelectionMark; + + return nResult; +} + +/*** + * DESCRIPTION: + * Retrieves the width of a string. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * SUCCESS : string width (in pixels) + * FAILURE : zero + */ +static LRESULT LISTVIEW_GetStringWidth32A(HWND32 hwnd, LPCSTR lpsz) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); HFONT32 hFont, hOldFont; HDC32 hdc; - SIZE32 size; - - if (!lpsz) - return 0; - - TRACE (listview, "(%s)\n", lpsz); + SIZE32 textSize; + INT32 nResult = 0; + if (lpsz != NULL) + { hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT); - hdc = GetDC32 (0); + hdc = GetDC32(hwnd); hOldFont = SelectObject32 (hdc, hFont); - GetTextExtentPoint32A (hdc, lpsz, lstrlen32A(lpsz), &size); + GetTextExtentPoint32A(hdc, lpsz, lstrlen32A(lpsz), &textSize); SelectObject32 (hdc, hOldFont); - ReleaseDC32 (0, hdc); + ReleaseDC32(hwnd, hdc); + nResult = textSize.cx; + } - TRACE (listview, "-- ret=%d\n", size.cx); - - return (LRESULT)size.cx; + return nResult; } - - - -__inline__ static LRESULT -LISTVIEW_GetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the text backgound color. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * COLORREF associated with the the background. + */ +static LRESULT LISTVIEW_GetTextBkColor(HWND32 hwnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); - return infoPtr->clrTextBk; + return infoPtr->clrTextBk; } - -__inline__ static LRESULT -LISTVIEW_GetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the text color. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * COLORREF associated with the text. + */ +static LRESULT LISTVIEW_GetTextColor(HWND32 hwnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); - return infoPtr->clrText; + return infoPtr->clrText; } - -static LRESULT -LISTVIEW_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Retrieves the bounding rectangle of all the items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [O] LPRECT32 : bounding rectangle + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_GetViewRect(HWND32 hwnd, LPRECT32 lpBoundingRect) { -/* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */ - LPLVHITTESTINFO lpht = (LPLVHITTESTINFO)lParam; + /* LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); */ + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + BOOL32 bResult = FALSE; - FIXME (listview, "(%p): stub!\n", lpht); + if (lpBoundingRect != NULL) + { + if ((lStyle & LVS_ICON) || (lStyle & LVS_SMALLICON)) + { + /* TO DO */ + } + } - /* FIXME: preliminary */ - lpht->flags = LVHT_NOWHERE; - lpht->iItem = -1; - lpht->iSubItem = 0; + return bResult; +} +/*** + * DESCRIPTION: + * Determines item index when in small icon view. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [IO] LPLVHITTESTINFO : hit test information + * + * RETURN: + * SUCCESS : item index + * FAILURE : -1 + */ +static LRESULT HitTestSmallIconView(HWND32 hwnd, LPLVHITTESTINFO lpHitTestInfo) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpItem; + INT32 nColumn; + INT32 nRow; + INT32 nItem = 0; + INT32 nLabelWidth; + INT32 nOffset; + INT32 nPosX = 0; + INT32 nSmallIconWidth; + INT32 nItemCountPerRow; + + /* get column */ + nColumn = lpHitTestInfo->pt.x / infoPtr->nColumnWidth; + + /* get row */ + nRow = lpHitTestInfo->pt.y / infoPtr->nItemHeight; + + /* calculate offset from start of column (in pixels) */ + nOffset = lpHitTestInfo->pt.x % infoPtr->nColumnWidth; + + /* get recommended width of a small icon */ + nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON); + + /* calculate index */ + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + nItem = nRow * nItemCountPerRow + LISTVIEW_GetFirstVisibleItem(hwnd) + nColumn; + + /* verify existance of item */ + if (nItem < infoPtr->nItemCount) + { + /* get item */ + lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); + if (lpItem != NULL) + { + if (infoPtr->himlState != NULL) + { + nPosX += nSmallIconWidth; + if (nOffset <= nPosX) + { + lpHitTestInfo->flags = LVHT_ONITEMSTATEICON | LVHT_ONITEM; + lpHitTestInfo->iItem = nItem; + lpHitTestInfo->iSubItem = 0; + return nItem; + } + } + + if (infoPtr->himlSmall != NULL) + { + nPosX += nSmallIconWidth; + if (nOffset <= nPosX) + { + lpHitTestInfo->flags = LVHT_ONITEMICON | LVHT_ONITEM; + lpHitTestInfo->iItem = nItem; + lpHitTestInfo->iSubItem = 0; + return nItem; +} + } + + /* get width of label in pixels */ + nLabelWidth = SendMessage32A(hwnd, LVM_GETSTRINGWIDTH32A, (WPARAM32)0, + (LPARAM)lpItem->pszText); + nLabelWidth += nPosX; + + if (nOffset <= nLabelWidth) +{ + lpHitTestInfo->flags = LVHT_ONITEMLABEL | LVHT_ONITEM; + lpHitTestInfo->iItem = nItem; + lpHitTestInfo->iSubItem = 0; + return nItem; + } + } + } + + /* hit is not on an item */ + lpHitTestInfo->flags = LVHT_NOWHERE; + + return -1; +} + +/*** + * DESCRIPTION: + * Determines item index when in list display mode. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [IO] LPLVHITTESTINFO : hit test information + * + * RETURN: + * SUCCESS : item index + * FAILURE : -1 + */ +static LRESULT HitTestListView(HWND32 hwnd, LPLVHITTESTINFO lpHitTestInfo) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpItem; + INT32 nColumn; + INT32 nRow; + INT32 nItem = 0; + INT32 nLabelWidth; + INT32 nOffset; + INT32 nPosX = 0; + INT32 nSmallIconWidth; + INT32 nItemCountPerColumn; + + /* get column */ + nColumn = lpHitTestInfo->pt.x / infoPtr->nColumnWidth; + + /* get row */ + nRow = lpHitTestInfo->pt.y / infoPtr->nItemHeight; + + /* calculate offset from start of column (in pixels) */ + nOffset = lpHitTestInfo->pt.x % infoPtr->nColumnWidth; + + /* get recommended width of a small icon */ + nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON); + + /* calculate index */ + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + nItem = (nColumn * nItemCountPerColumn + LISTVIEW_GetFirstVisibleItem(hwnd) + + nRow); + + /* verify existance of item */ + if (nItem < infoPtr->nItemCount) + { + /* get item */ + lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); + if (lpItem != NULL) + { + if (infoPtr->himlState != NULL) + { + nPosX += nSmallIconWidth; + if (nOffset <= nPosX) + { + lpHitTestInfo->flags = LVHT_ONITEMSTATEICON | LVHT_ONITEM; + lpHitTestInfo->iItem = nItem; + lpHitTestInfo->iSubItem = 0; + return nItem; + } + } + + if (infoPtr->himlSmall != NULL) + { + nPosX += nSmallIconWidth; + if (nOffset <= nPosX) +{ + lpHitTestInfo->flags = LVHT_ONITEMICON | LVHT_ONITEM; + lpHitTestInfo->iItem = nItem; + lpHitTestInfo->iSubItem = 0; + return nItem; + } + } + + /* get width of label in pixels */ + nLabelWidth = SendMessage32A(hwnd, LVM_GETSTRINGWIDTH32A, (WPARAM32)0, + (LPARAM)lpItem->pszText); + nLabelWidth += nPosX; + + if (nOffset <= nLabelWidth) + { + lpHitTestInfo->flags = LVHT_ONITEMLABEL | LVHT_ONITEM; + lpHitTestInfo->iItem = nItem; + lpHitTestInfo->iSubItem = 0; + return nItem; + } + } + } + + /* hit is not on an item */ + lpHitTestInfo->flags = LVHT_NOWHERE; + return -1; } - -static LRESULT -LISTVIEW_InsertColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Determines wich listview item is located at the specified position. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [IO} LPLVHITTESTINFO : hit test information + * + * RETURN: + * SUCCESS : item index + * FAILURE : -1 + */ +static LRESULT LISTVIEW_HitTest(HWND32 hwnd, LPLVHITTESTINFO lpHitTestInfo) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam; - INT32 nIndex = (INT32)wParam; + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + + if (lStyle & LVS_LIST) + return HitTestListView(hwnd, lpHitTestInfo); + else if (lStyle & LVS_REPORT) + { + /* TO DO */ + } + else if (lStyle & LVS_SMALLICON) + { + return HitTestSmallIconView(hwnd, lpHitTestInfo); + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } + + return -1; +} + +/*** + * DESCRIPTION: + * Inserts a new column. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : column index + * [I] LPLVCOLUMN32A : column information + * + * RETURN: + * SUCCESS : new column index + * FAILURE : -1 + */ +static LRESULT LISTVIEW_InsertColumn32A(HWND32 hwnd, INT32 nIndex, + LPLVCOLUMN32A lpColumn) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); HDITEM32A hdi; INT32 nResult; - if ((!lpcol) || (infoPtr->nItemCount > 0)) + if ((lpColumn == NULL) || (infoPtr->nItemCount > 0)) return -1; - FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol); + FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpColumn); + /* initialize memory */ ZeroMemory (&hdi, sizeof(HDITEM32A)); - if (lpcol->mask & LVCF_FMT) { + if (lpColumn->mask & LVCF_FMT) + { if (nIndex == 0) hdi.fmt |= HDF_LEFT; - else if (lpcol->fmt & LVCFMT_LEFT) + else if (lpColumn->fmt & LVCFMT_LEFT) hdi.fmt |= HDF_LEFT; - else if (lpcol->fmt & LVCFMT_RIGHT) + else if (lpColumn->fmt & LVCFMT_RIGHT) hdi.fmt |= HDF_RIGHT; - else if (lpcol->fmt & LVCFMT_CENTER) + else if (lpColumn->fmt & LVCFMT_CENTER) hdi.fmt |= HDF_CENTER; - - if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES) + if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES) hdi.fmt |= HDF_IMAGE; hdi.mask |= HDI_FORMAT; } - if (lpcol->mask & LVCF_WIDTH) { + if (lpColumn->mask & LVCF_WIDTH) + { hdi.mask |= HDI_WIDTH; - hdi.cxy = lpcol->cx; + hdi.cxy = lpColumn->cx; } - if (lpcol->mask & LVCF_TEXT) { + if (lpColumn->mask & LVCF_TEXT) + { hdi.mask |= (HDI_TEXT | HDI_FORMAT); - hdi.pszText = lpcol->pszText; + hdi.pszText = lpColumn->pszText; hdi.fmt |= HDF_STRING; } - if (lpcol->mask & LVCF_IMAGE) { + if (lpColumn->mask & LVCF_IMAGE) + { hdi.mask |= HDI_IMAGE; - hdi.iImage = lpcol->iImage; + hdi.iImage = lpColumn->iImage; } - if (lpcol->mask & LVCF_ORDER) { + if (lpColumn->mask & LVCF_ORDER) + { hdi.mask |= HDI_ORDER; - hdi.iOrder = lpcol->iOrder; + hdi.iOrder = lpColumn->iOrder; } nResult = SendMessage32A (infoPtr->hwndHeader, HDM_INSERTITEM32A, - wParam, (LPARAM)&hdi); + (WPARAM32)nIndex, (LPARAM)&hdi); if (nResult == -1) return -1; + /* increment column counter */ infoPtr->nColumnCount++; return nResult; } - /* << LISTVIEW_InsertColumn32W >> */ - -static LRESULT -LISTVIEW_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Inserts a new item in the listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] LPLVITEM32A : item information + * + * RETURN: + * SUCCESS : new item index + * FAILURE : -1 + */ +static LRESULT LISTVIEW_InsertItem32A(HWND32 hwnd, LPLVITEM32A lpItem) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPLVITEM32A lpItem = (LPLVITEM32A)lParam; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); LISTVIEW_ITEM *lpListItem; - INT32 nIndex; + INT32 nItem; NMLISTVIEW nmlv; + LVITEM32A lvItem; + INT32 nColumnWidth = 0; + INT32 nSmallIconWidth; - if (!lpItem) + if (lpItem == NULL) return -1; - if ((!infoPtr->nColumnCount) || (lpItem->iSubItem)) + if (lpItem->iSubItem != 0) return -1; - FIXME (listview, "(%d %p)\n", lpItem->iItem, lpItem); - FIXME (listview, "(%p %p)\n", infoPtr, infoPtr->hdpaItems); - - lpListItem = (LISTVIEW_ITEM*)COMCTL32_Alloc (infoPtr->nColumnCount * sizeof(LISTVIEW_ITEM)); - nIndex = DPA_InsertPtr (infoPtr->hdpaItems, lpItem->iItem, lpListItem); - if (nIndex == -1) + /* allocate memory */ + lpListItem = (LISTVIEW_ITEM *)COMCTL32_Alloc(sizeof(LISTVIEW_ITEM)); + if (lpListItem == NULL) return -1; - if (lpItem->mask & LVIF_STATE) - lpListItem[0].state = lpItem->state; + nSmallIconWidth = GetSystemMetrics32(SM_CXSMICON); - if (lpItem->mask & LVIF_TEXT) { + /* initialize listview control item */ + ZeroMemory(lpListItem, sizeof(LISTVIEW_ITEM)); + + /* copy only valid data */ + if (lpItem->mask & LVIF_TEXT) + { if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) - lpListItem[0].pszText = LPSTR_TEXTCALLBACK32A; + { + if ((lStyle & LVS_SORTASCENDING) || (lStyle & LVS_SORTDESCENDING)) + return -1; + + lpListItem->pszText = LPSTR_TEXTCALLBACK32A; + } else - Str_SetPtr32A (&lpListItem[0].pszText, lpItem->pszText); + { + nColumnWidth = SendMessage32A(hwnd, LVM_GETSTRINGWIDTH32A, + (WPARAM32)0, (LPARAM)lpItem->pszText); + + /* add padding for separating columns */ + nColumnWidth += 10; + + /* calculate column width; make sure it's at least 96 pixels */ + if (nColumnWidth < 96) + nColumnWidth = 96; + + Str_SetPtr32A(&lpListItem->pszText, lpItem->pszText); + } + } + + if (lpItem->mask & LVIF_STATE) + { + if (lpItem->stateMask & LVIS_FOCUSED) + { + /* clear LVIS_FOCUSED states */ + ZeroMemory(&lvItem, sizeof(LVITEM32A)); + lvItem.stateMask = LVIS_FOCUSED; + lvItem.state = 0; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem); + + /* set focused item index */ + infoPtr->nFocusedItem = lpItem->iItem; } + lpListItem->state = lpItem->state & lpItem->stateMask; + } + if (lpItem->mask & LVIF_IMAGE) - lpListItem[0].iImage = lpItem->iImage; + lpListItem->iImage = lpItem->iImage; if (lpItem->mask & LVIF_PARAM) - lpListItem[0].lParam = lpItem->lParam; + lpListItem->lParam = lpItem->lParam; if (lpItem->mask & LVIF_INDENT) - lpListItem[0].iIndent = lpItem->iIndent; + lpListItem->iIndent = lpItem->iIndent; + /* insert item in listview control data structure */ + nItem = DPA_InsertPtr(infoPtr->hdpaItems, lpItem->iItem, lpListItem); + if (nItem == -1) + return -1; + + /* increment item counter */ infoPtr->nItemCount++; - /* send notification */ + /* calculate column width */ + if (infoPtr->himlSmall != NULL) + nColumnWidth += nSmallIconWidth; + + /* calculate column width */ + if (infoPtr->himlState != NULL) + nColumnWidth += nSmallIconWidth; + + /* set column width */ + if (nColumnWidth > infoPtr->nColumnWidth) + infoPtr->nColumnWidth = nColumnWidth; + + /* set drawing data */ + LISTVIEW_SetScroll(hwnd); + + /* send LVN_INSERTITEM notification */ ZeroMemory (&nmlv, sizeof (NMLISTVIEW)); - nmlv.hdr.hwndFrom = wndPtr->hwndSelf; - nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.hwndFrom = hwnd; + nmlv.hdr.idFrom = lCtrlId; nmlv.hdr.code = LVN_INSERTITEM; - nmlv.iItem = nIndex; - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + nmlv.iItem = nItem; + SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmlv); - return nIndex; + InvalidateRect32(hwnd, NULL, FALSE); + UpdateWindow32(hwnd); + + return nItem; } - /* << LISTVIEW_InsertItem32W >> */ - -static LRESULT -LISTVIEW_RedrawItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Redraws a range of items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : first item + * [I] INT32 : last item + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_RedrawItems(HWND32 hwnd, INT32 nFirst, INT32 nLast) { -/* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); - FIXME (listview, "(%d - %d): empty stub!\n", - (INT32)wParam, (INT32)lParam); + if (nFirst > nLast) + return FALSE; - return TRUE; + if ((nFirst < 0) || (nFirst >= infoPtr->nItemCount)) + return FALSE; + + if ((nLast < 0) || (nLast >= infoPtr->nItemCount)) + return FALSE; + + /* TO DO */ + + return TRUE; } - -/* - << LISTVIEW_Scroll >> -*/ - - -static LRESULT -LISTVIEW_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Scrolls the content of a listview. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : amount of horizontal scrolling + * [I] INT32 : amount of vertical scrolling + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_Scroll(HWND32 hwnd, INT32 nHScroll, INT32 nVScroll) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + BOOL32 bResult = FALSE; + INT32 nHScrollPos; + INT32 nMinRange; + INT32 nMaxRange; - if (!infoPtr) - return FALSE; + if (lStyle & LVS_LIST) + { + nHScrollPos = GetScrollPos32(hwnd, SB_HORZ); + GetScrollRange32(hwnd, SB_HORZ, &nMinRange, &nMaxRange); - /* set background color */ - TRACE (listview, "0x%06lx\n", (COLORREF)lParam); - infoPtr->clrBk = (COLORREF)lParam; + if ((nMinRange <= nHScrollPos + nHScroll) && + (nHScrollPos + nHScroll <= nMaxRange)) + { + bResult = TRUE; + nHScrollPos += nHScroll; + SetScrollPos32(hwnd, SB_HORZ, nHScrollPos, TRUE); - return TRUE; + /* refresh client area */ + InvalidateRect32(hwnd, NULL, TRUE); + UpdateWindow32(hwnd); + } + } + else if (lStyle & LVS_REPORT) + { + /* TO DO */ +} + else if (lStyle & LVS_SMALLICON) + { + /* TO DO */ + } + else if (lStyle & LVS_ICON) + { + /* TO DO */ + } + + return bResult; } - -/* - << LISTVIEW_SetBkImage >> - << LISTVIEW_SetCallbackMask >> +/*** + * DESCRIPTION: + * Sets the background color. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] COLORREF : background color + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE */ - - -static LRESULT -LISTVIEW_SetColumn32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +static LRESULT LISTVIEW_SetBkColor(HWND32 hwnd, COLORREF clrBk) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPLVCOLUMN32A lpcol = (LPLVCOLUMN32A)lParam; - INT32 nIndex = (INT32)wParam; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + + infoPtr->clrBk = clrBk; + InvalidateRect32(hwnd, NULL, TRUE); + + return TRUE; +} + +/*** + * DESCRIPTION: + * Sets column attributes. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : column index + * [I] LPLVCOLUMN32A : column information + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_SetColumn32A(HWND32 hwnd, INT32 nIndex, + LPLVCOLUMN32A lpColumn) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); HDITEM32A hdi; - if (!lpcol) + if (lpColumn == NULL) return -1; - FIXME (listview, "(%d %p): semi stub!\n", nIndex, lpcol); - + /* initialize memory */ ZeroMemory (&hdi, sizeof(HDITEM32A)); - if (lpcol->mask & LVCF_FMT) { + if (lpColumn->mask & LVCF_FMT) + { if (nIndex == 0) hdi.fmt |= HDF_LEFT; - else if (lpcol->fmt & LVCFMT_LEFT) + else if (lpColumn->fmt & LVCFMT_LEFT) hdi.fmt |= HDF_LEFT; - else if (lpcol->fmt & LVCFMT_RIGHT) + else if (lpColumn->fmt & LVCFMT_RIGHT) hdi.fmt |= HDF_RIGHT; - else if (lpcol->fmt & LVCFMT_CENTER) + else if (lpColumn->fmt & LVCFMT_CENTER) hdi.fmt |= HDF_CENTER; - if (lpcol->fmt & LVCFMT_COL_HAS_IMAGES) + if (lpColumn->fmt & LVCFMT_COL_HAS_IMAGES) hdi.fmt |= HDF_IMAGE; hdi.mask |= HDI_FORMAT; } - if (lpcol->mask & LVCF_WIDTH) { + if (lpColumn->mask & LVCF_WIDTH) + { hdi.mask |= HDI_WIDTH; - hdi.cxy = lpcol->cx; + hdi.cxy = lpColumn->cx; } - if (lpcol->mask & LVCF_TEXT) { + if (lpColumn->mask & LVCF_TEXT) + { hdi.mask |= (HDI_TEXT | HDI_FORMAT); - hdi.pszText = lpcol->pszText; + hdi.pszText = lpColumn->pszText; hdi.fmt |= HDF_STRING; } - if (lpcol->mask & LVCF_IMAGE) { + if (lpColumn->mask & LVCF_IMAGE) + { hdi.mask |= HDI_IMAGE; - hdi.iImage = lpcol->iImage; + hdi.iImage = lpColumn->iImage; } - if (lpcol->mask & LVCF_ORDER) { + if (lpColumn->mask & LVCF_ORDER) + { hdi.mask |= HDI_ORDER; - hdi.iOrder = lpcol->iOrder; + hdi.iOrder = lpColumn->iOrder; } return (LRESULT)SendMessage32A (infoPtr->hwndHeader, HDM_SETITEM32A, - wParam, (LPARAM)&hdi); + (WPARAM32)nIndex, (LPARAM)&hdi); } - -/* - << LISTVIEW_SetColumn32W >> - << LISTVIEW_SetColumnOrderArray >> - << LISTVIEW_SetColumnWidth >> - << LISTVIEW_SetExtendedListviewStyle >> - << LISTVIEW_SetHotCursor >> - << LISTVIEW_SetHotItem >> - << LISTVIEW_SetHoverTime >> - << LISTVIEW_SetIconSpacing >> +/*** + * DESCRIPTION: + * Sets image list. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : image list type + * [I] HIMAGELIST : image list handle + * + * RETURN: + * SUCCESS : old image list + * FAILURE : NULL */ - - -static LRESULT -LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +static LRESULT LISTVIEW_SetImageList(HWND32 hwnd, INT32 nType, HIMAGELIST himl) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); HIMAGELIST himlTemp = 0; - TRACE (listview, "(0x%08x 0x%08lx)\n", wParam, lParam); - - switch (wParam) { + switch (nType) + { case LVSIL_NORMAL: himlTemp = infoPtr->himlNormal; - infoPtr->himlNormal = (HIMAGELIST)lParam; + infoPtr->himlNormal = himl; return (LRESULT)himlTemp; - case LVSIL_SMALL: himlTemp = infoPtr->himlSmall; - infoPtr->himlSmall = (HIMAGELIST)lParam; + infoPtr->himlSmall = himl; return (LRESULT)himlTemp; - case LVSIL_STATE: himlTemp = infoPtr->himlState; - infoPtr->himlState = (HIMAGELIST)lParam; + infoPtr->himlState = himl; return (LRESULT)himlTemp; } @@ -784,249 +2589,364 @@ LISTVIEW_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) } -static LRESULT -LISTVIEW_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Sets item attributes. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] LPLVITEM32 : item information + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_SetItem32A(HWND32 hwnd, LPLVITEM32A lpItem) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPLVITEM32A lpItem = (LPLVITEM32A)lParam; - LISTVIEW_ITEM *lpRow, *lpSubItem; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + LISTVIEW_ITEM *lpListItem; NMLISTVIEW nmlv; - if (!lpItem) + if (lpItem == NULL) return FALSE; if ((lpItem->iItem < 0) || (lpItem->iItem >= infoPtr->nItemCount)) return FALSE; - if ((lpItem->iSubItem < 0) || (lpItem->iSubItem >= infoPtr->nColumnCount)) - return FALSE; - /* send LVN_ITEMCHANGING notification */ ZeroMemory (&nmlv, sizeof (NMLISTVIEW)); - nmlv.hdr.hwndFrom = wndPtr->hwndSelf; - nmlv.hdr.idFrom = wndPtr->wIDmenu; + nmlv.hdr.hwndFrom = hwnd; + nmlv.hdr.idFrom = lCtrlId; nmlv.hdr.code = LVN_ITEMCHANGING; nmlv.iItem = lpItem->iItem; nmlv.iSubItem = lpItem->iSubItem; nmlv.uChanged = lpItem->mask; - - if (!SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv)) + if (SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmlv) == FALSE) return FALSE; - TRACE (listview, "(%d %d %p)\n", - lpItem->iItem, lpItem->iSubItem, lpItem); + /* get item */ + lpListItem = DPA_GetPtr(infoPtr->hdpaItems, lpItem->iItem); + if (lpListItem == NULL) + return FALSE; - lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem); - if (!lpRow) + /* copy valid data */ + if (lpItem->iSubItem > 0) + { + /* verify existance of sub-item */ + lpListItem += lpItem->iSubItem; + if (lpListItem == NULL) return FALSE; - lpSubItem = &lpRow[lpItem->iSubItem]; - if (!lpSubItem) + /* exit if indent attribute is valid */ + if (lpItem->mask & LVIF_INDENT) return FALSE; + if (lpItem->mask & LVIF_IMAGE) + { + /* set sub-item attribute */ + } + + } + else + { if (lpItem->mask & LVIF_STATE) - lpSubItem->state = (lpSubItem->state & lpItem->stateMask) | lpItem->state; - - if (lpItem->mask & LVIF_TEXT) { - if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) { - if ((lpSubItem->pszText) && - (lpSubItem->pszText != LPSTR_TEXTCALLBACK32A)) - COMCTL32_Free (lpSubItem->pszText); - lpSubItem->pszText = LPSTR_TEXTCALLBACK32A; - } - else { - if (lpSubItem->pszText == LPSTR_TEXTCALLBACK32A) - lpSubItem->pszText = NULL; - Str_SetPtr32A (&lpSubItem->pszText, lpItem->pszText); - } + { + lpListItem->state &= ~lpItem->stateMask; + lpListItem->state |= (lpItem->state & lpItem->stateMask); } if (lpItem->mask & LVIF_IMAGE) - lpSubItem->iImage = lpItem->iImage; + lpListItem->iImage = lpItem->iImage; if (lpItem->mask & LVIF_PARAM) - lpSubItem->lParam = lpItem->lParam; + lpListItem->lParam = lpItem->lParam; if (lpItem->mask & LVIF_INDENT) - lpSubItem->iIndent = lpItem->iIndent; + lpListItem->iIndent = lpItem->iIndent; + } + + if (lpItem->mask & LVIF_TEXT) + { + if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) + { + if ((lpListItem->pszText != NULL) && + (lpListItem->pszText != LPSTR_TEXTCALLBACK32A)) + COMCTL32_Free (lpListItem->pszText); + + lpListItem->pszText = LPSTR_TEXTCALLBACK32A; + } + else + { + if (lpListItem->pszText == LPSTR_TEXTCALLBACK32A) + lpListItem->pszText = NULL; + + if (Str_SetPtr32A(&lpListItem->pszText, lpItem->pszText) == FALSE) + return FALSE; + } + } /* send LVN_ITEMCHANGED notification */ nmlv.hdr.code = LVN_ITEMCHANGED; - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmlv); return TRUE; } - /* << LISTVIEW_SetItem32W >> */ -/* << LISTVIEW_SetItemCount >> */ +/* LISTVIEW_SetItemCount*/ -static LRESULT -LISTVIEW_SetItemPosition (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Sets item position. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * [I] INT32 : x coordinate + * [I] INT32 : y coordinate + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_SetItemPosition(HWND32 hwnd, INT32 nItem, + INT32 nPosX, INT32 nPosY) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - INT32 nIndex = (INT32)wParam; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); - if ((nIndex < 0) || (nIndex >= infoPtr->nItemCount)) + if ((nItem < 0) || (nItem >= infoPtr->nItemCount)) return FALSE; - FIXME (listview, "setting position [%d, %d]!\n", - (INT32)LOWORD(lParam), (INT32)HIWORD(lParam)); + if ((lStyle & LVS_ICON) && (lStyle & LVS_SMALLICON)) + { + /* get item */ - /* FIXME: set position */ + /* set position of item */ - return TRUE; -} - - -/* - << LISTVIEW_SetItemPosition32 >> - << LISTVIEW_SetItemState >> -*/ - - -static LRESULT -LISTVIEW_SetItemText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) -{ - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPLVITEM32A lpItem = (LPLVITEM32A)lParam; - INT32 nItem = (INT32)wParam; - LISTVIEW_ITEM *lpRow, *lpSubItem; - - TRACE (listview, "(%d %p)\n", nItem, lpItem); - - lpRow = DPA_GetPtr (infoPtr->hdpaItems, lpItem->iItem); - if (!lpRow) - return FALSE; - - lpSubItem = &lpRow[lpItem->iSubItem]; - if (!lpSubItem) - return FALSE; - - if (lpSubItem->pszText) { - if (lpSubItem->pszText != LPSTR_TEXTCALLBACK32A) - COMCTL32_Free (lpSubItem->pszText); - lpSubItem->pszText = NULL; - } - if (lpItem->pszText) { - if (lpItem->pszText == LPSTR_TEXTCALLBACK32A) { - lpItem->pszText = LPSTR_TEXTCALLBACK32A; - } - else { - INT32 len = lstrlen32A (lpItem->pszText); - lpSubItem->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR)); - lstrcpy32A (lpSubItem->pszText, lpItem->pszText); - } + /* refresh */ + if (lStyle & LVS_AUTOARRANGE) + { + InvalidateRect32(hwnd, NULL, FALSE); + UpdateWindow32(hwnd); } return TRUE; } + return FALSE; +} -/* - << LISTVIEW_SetItemText32W >> - << LISTVIEW_SetSelectionMark >> +/*** + * DESCRIPTION: + * Sets the state of one or many items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I]INT32 : item index + * [I] LPLVITEM32 : item information + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE */ - - -static LRESULT -LISTVIEW_SetTextBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +static LRESULT LISTVIEW_SetItemState(HWND32 hwnd, INT32 nItem, + LPLVITEM32A lpItem) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LISTVIEW_ITEM *lpListItem; + INT32 i; - if (!infoPtr) + if (nItem == -1) + { + /* apply to all the items */ + for (i = 0; i< infoPtr->nItemCount; i++) + { + lpListItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, i); + if (lpListItem == NULL) return FALSE; - /* set text background color */ - TRACE (listview, "0x%06lx\n", (COLORREF)lParam); - infoPtr->clrTextBk = (COLORREF)lParam; + lpListItem->state &= ~lpItem->stateMask; + lpListItem->state |= (lpItem->state & lpItem->stateMask); + } + } + else if ((nItem >= 0) && (nItem < infoPtr->nItemCount)) + { + lpListItem = (LISTVIEW_ITEM *)DPA_GetPtr(infoPtr->hdpaItems, nItem); + if (lpListItem == NULL) + return FALSE; + + /* set state */ + lpListItem->state &= ~lpItem->stateMask; + lpListItem->state |= (lpItem->state & lpItem->stateMask); + } + else + return FALSE; return TRUE; } - -static LRESULT -LISTVIEW_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Sets the text background color. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] COLORREF : text background color + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE +*/ +static LRESULT LISTVIEW_SetTextBkColor(HWND32 hwnd, COLORREF clrTextBk) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); - if (!infoPtr) - return FALSE; - - /* set text color */ - TRACE (listview, "0x%06lx\n", (COLORREF)lParam); - infoPtr->clrText = (COLORREF)lParam; + infoPtr->clrTextBk = clrTextBk; return TRUE; } - -/* - << LISTVIEW_SetTooltips >> - << LISTVIEW_SetUnicodeFormat >> - << LISTVIEW_SetWorkAreas >> -*/ - - -static LRESULT -LISTVIEW_SortItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Sets the text background color. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] COLORREF : text color + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_SetTextColor (HWND32 hwnd, COLORREF clrText) { -/* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + + infoPtr->clrText = clrText; + + return TRUE; +} + +/*** + * DESCRIPTION: + * ?? + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE +*/ +static LRESULT LISTVIEW_SortItems(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam) +{ +/* LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); */ FIXME (listview, "empty stub!\n"); - /* fake success */ return TRUE; } - -/* - << LISTVIEW_SubItemHitTest >> - << LISTVIEW_Update >> +/*** + * DESCRIPTION: + * Updates an items. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : item index + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE */ - - - -static LRESULT -LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +static LRESULT LISTVIEW_Update(HWND32 hwnd, INT32 nItem) { - /* info structure is created at NCCreate */ - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LOGFONT32A logFont; - DWORD dwStyle = WS_CHILD | WS_VISIBLE; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + RECT32 rcItemRect; + BOOL32 bResult = FALSE; - TRACE (listview, "styles 0x%08lx 0x%08lx\n", - wndPtr->dwStyle, wndPtr->dwExStyle); + if ((nItem >= 0) || (nItem < infoPtr->nItemCount)) + { + /* get item bounding rectangle */ + rcItemRect.left = LVIR_BOUNDS; + SendMessage32A(hwnd, LVM_GETITEMRECT, (WPARAM32)nItem, + (LPARAM)&rcItemRect); - /* initialize info structure */ - infoPtr->clrBk = CLR_NONE; - infoPtr->clrText = RGB(0, 0, 0); /* preliminary */ - infoPtr->clrTextBk = RGB(255, 255, 255); /* preliminary */ + InvalidateRect32(hwnd, &rcItemRect, FALSE); - if (!(wndPtr->dwStyle & LVS_REPORT) || - (wndPtr->dwStyle & LVS_NOCOLUMNHEADER)) - dwStyle |= HDS_HIDDEN; - if (!(wndPtr->dwStyle & LVS_NOSORTHEADER)) - dwStyle |= HDS_BUTTONS; + /* rearrange with default alignment style */ + if ((lStyle & LVS_AUTOARRANGE) && + ((lStyle & LVS_ICON) || (lStyle & LVS_SMALLICON))) + SendMessage32A(hwnd, LVM_ARRANGE, (WPARAM32)LVA_DEFAULT, (LPARAM)0); + } - /* create header */ - infoPtr->hwndHeader = - CreateWindow32A (WC_HEADER32A, "", dwStyle, - 0, 0, 0, 0, wndPtr->hwndSelf, - (HMENU32)0, wndPtr->hInstance, NULL); + return bResult; +} + +/*** + * DESCRIPTION: + * Creates a listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_Create(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + LOGFONT32A logFont; + HFONT32 hOldFont; + HDC32 hdc; + TEXTMETRIC32A tm; + INT32 nSmallIconHeight; + + /* initialize color information */ + infoPtr->clrBk = GetSysColor32(COLOR_WINDOW); + infoPtr->clrText = GetSysColor32(COLOR_WINDOWTEXT); + infoPtr->clrTextBk = GetSysColor32(COLOR_WINDOW); /* get default font (icon title) */ SystemParametersInfo32A (SPI_GETICONTITLELOGFONT, 0, &logFont, 0); infoPtr->hDefaultFont = CreateFontIndirect32A (&logFont); infoPtr->hFont = infoPtr->hDefaultFont; - /* set header font */ - SendMessage32A (infoPtr->hwndHeader, WM_SETFONT, - (WPARAM32)infoPtr->hFont, (LPARAM)TRUE); + /* initialize column width */ + infoPtr->nColumnWidth = 96; + /* get text height */ + hdc = GetDC32(hwnd); + hOldFont = SelectObject32(hdc, infoPtr->hFont); + GetTextMetrics32A(hdc, &tm); + + /* initialize item height with padding */ + if (!(lStyle & LVS_ICON)) + { + nSmallIconHeight = GetSystemMetrics32(SM_CYSMICON); + infoPtr->nItemHeight = max(tm.tmHeight, nSmallIconHeight) + 2; + } + + SelectObject32(hdc, hOldFont); + ReleaseDC32(hwnd, hdc); + + /* create header */ + infoPtr->hwndHeader = CreateWindow32A(WC_HEADER32A, "", lStyle, 0, 0, 0, 0, + hwnd, (HMENU32)0, + GetWindowLong32A(hwnd, GWL_HINSTANCE), + NULL); + /* set header font */ + SendMessage32A(infoPtr->hwndHeader, WM_SETFONT, (WPARAM32)infoPtr->hFont, + (LPARAM)TRUE); + + /* allocate memory */ infoPtr->hdpaItems = DPA_Create (10); return 0; @@ -1034,12 +2954,12 @@ LISTVIEW_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) static LRESULT -LISTVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +LISTVIEW_Destroy (HWND32 hwnd, WPARAM32 wParam, LPARAM lParam) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); /* delete all items */ - LISTVIEW_DeleteAllItems (wndPtr); + LISTVIEW_DeleteAllItems(hwnd); /* destroy dpa */ DPA_Destroy (infoPtr->hdpaItems); @@ -1053,147 +2973,538 @@ LISTVIEW_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) if (infoPtr->hDefaultFont) DeleteObject32 (infoPtr->hDefaultFont); - + infoPtr->nColumnWidth = 96; return 0; } - -static LRESULT -LISTVIEW_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Erases the background of the listview control + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static LRESULT LISTVIEW_EraseBackground(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + BOOL32 bResult; - if (infoPtr->clrBk == CLR_NONE) { - return SendMessage32A (GetParent32 (wndPtr->hwndSelf), - WM_ERASEBKGND, wParam, lParam); - } - else { - HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk); - FillRect32 ((HDC32)wParam, &infoPtr->rcList, hBrush); - DeleteObject32 (hBrush); - return FALSE; - } + if (infoPtr->clrBk == CLR_NONE) + bResult = SendMessage32A(GetParent32(hwnd), WM_ERASEBKGND, wParam, lParam); + else + { + HBRUSH32 hBrush = CreateSolidBrush32(infoPtr->clrBk); + RECT32 clientRect; - return TRUE; + GetClientRect32(hwnd, &clientRect); + FillRect32((HDC32)wParam, &clientRect, hBrush); + DeleteObject32(hBrush); + bResult = TRUE; + } + + return bResult; } - -__inline__ static LRESULT -LISTVIEW_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Gets the listview control font. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Font handle. + */ +static LRESULT LISTVIEW_GetFont(HWND32 hwnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); - return infoPtr->hFont; + return infoPtr->hFont; } - -/* << LISTVIEW_HScroll >> */ -/* << LISTVIEW_KeyDown >> */ - - -static LRESULT -LISTVIEW_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Performs horizontal scrolling. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : scroll code + * [I] INT32 : scroll position + * [I] HWND32 : scrollbar control window handle + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_HScroll(HWND32 hwnd, INT32 nScrollCode, + INT32 nScrollPos, HWND32 hScrollWnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nHScrollPos; + INT32 nMinRange; + INT32 nMaxRange; + + GetScrollRange32(hwnd, SB_HORZ, &nMinRange, &nMaxRange); + nHScrollPos = GetScrollPos32(hwnd, SB_HORZ); + + if (lStyle & LVS_LIST) + { + switch (nScrollCode) + { + case SB_LINELEFT: + if (nHScrollPos > nMinRange) + nHScrollPos--; + break; + case SB_LINERIGHT: + if (nHScrollPos < nMaxRange) + nHScrollPos++; + break; + case SB_PAGELEFT: + if (nHScrollPos > nMinRange) + nHScrollPos--; + break; + case SB_PAGERIGHT: + if (nHScrollPos < nMaxRange) + nHScrollPos++; + break; + case SB_THUMBPOSITION: + nHScrollPos = nScrollPos; + break; + } + + SetScrollPos32(hwnd, SB_HORZ, nHScrollPos, TRUE); + + /* refresh client area */ + InvalidateRect32(hwnd, NULL, TRUE); + UpdateWindow32(hwnd); + } + + return 0; +} + +/*** + * DESCRIPTION: + * ????? + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : virtual key + * [I] LONG : key data + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_KeyDown(HWND32 hwnd, INT32 nVirtualKey, LONG lKeyData) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + HWND32 hwndParent = GetParent32(hwnd); + INT32 nItemCountPerColumn; + INT32 nItemCountPerRow; + NMHDR nmh; + INT32 nColumn; +/* NMLVKEYDOWN nmKeyDown; */ + + /* send LVN_KEYDOWN notification */ +/* nmh.hwndFrom = hwnd; */ +/* nmh.idFrom = lCtrlId; */ +/* nmh.code = LVN_KEYDOWN; */ +/* nmKeyDown.hdr = nmh; */ +/* nmKeyDown..wVKey = nVirtualKey; */ +/* nmKeyCode.flags = 0; */ +/* SendMessage32A(hwndParent, WM_NOTIFY, (WPARAM32)lCtrlId, (LPARAM)&nmKeyDown); */ + + switch (nVirtualKey) + { + case VK_RETURN: + if ((infoPtr->nItemCount > 0) && (infoPtr->nFocusedItem != -1)) + { + /* send NM_RETURN notification */ + nmh.code = NM_RETURN; + SendMessage32A(hwndParent, WM_NOTIFY, (WPARAM32)lCtrlId, (LPARAM)&nmh); + + /* send LVN_ITEMACTIVATE notification */ + nmh.code = LVN_ITEMACTIVATE; + SendMessage32A(hwndParent, WM_NOTIFY, (WPARAM32)lCtrlId, (LPARAM)&nmh); + } + break; + + case VK_HOME: + if (infoPtr->nItemCount > 0) + { + /* set item state(s) */ + infoPtr->nFocusedItem = 0; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + /* make item visible */ + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); + } + break; + + case VK_END: + if (infoPtr->nItemCount > 0) +{ + /* set item state(s) */ + infoPtr->nFocusedItem = infoPtr->nItemCount - 1; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + /* make item visible */ + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); + } + + break; + + case VK_LEFT: + if (lStyle & LVS_LIST) + { + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + if (infoPtr->nFocusedItem >= nItemCountPerColumn) + { + /* set item state(s) */ + infoPtr->nFocusedItem -= nItemCountPerColumn; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + /* make item visible */ + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); + } + } + else if (lStyle & LVS_REPORT) + { + /* TO DO ; does not affect the focused item, it only scrolls */ + } + else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON)) + { + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + nColumn = infoPtr->nFocusedItem % nItemCountPerRow; + if (nColumn != 0) + { + infoPtr->nFocusedItem -= 1; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + /* refresh display */ + InvalidateRect32(hwnd, NULL, FALSE); + UpdateWindow32(hwnd); + } + } + break; + + case VK_UP: + if ((lStyle & LVS_LIST) || (lStyle & LVS_REPORT)) + { + if (infoPtr->nFocusedItem > 0) + { + infoPtr->nFocusedItem -= 1; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); +} + } + else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON)) + { + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + if (infoPtr->nFocusedItem >= nItemCountPerRow) + { + infoPtr->nFocusedItem -= nItemCountPerRow; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); + } + } + break; + + case VK_RIGHT: + if (lStyle & LVS_LIST) +{ + nItemCountPerColumn = LISTVIEW_GetItemCountPerColumn(hwnd); + if (infoPtr->nFocusedItem < infoPtr->nItemCount - nItemCountPerColumn) + { + infoPtr->nFocusedItem += nItemCountPerColumn; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); + } + } + else if (lStyle & LVS_REPORT) + { + } + else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON)) + { + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + nColumn = infoPtr->nFocusedItem % nItemCountPerRow; + if (nColumn != nItemCountPerRow - 1) + { + infoPtr->nFocusedItem += 1; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + /* refresh display */ + InvalidateRect32(hwnd, NULL, FALSE); + UpdateWindow32(hwnd); +} + + } + break; + + case VK_DOWN: + if ((lStyle & LVS_LIST) || (lStyle & LVS_REPORT)) +{ + if (infoPtr->nFocusedItem < infoPtr->nItemCount - 1) + { + infoPtr->nFocusedItem += 1; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); +} + } + else if ((lStyle & LVS_SMALLICON) || (lStyle & LVS_ICON)) + { + nItemCountPerRow = LISTVIEW_GetItemCountPerRow(hwnd); + if (infoPtr->nFocusedItem < infoPtr->nItemCount - nItemCountPerRow) + { + infoPtr->nFocusedItem += nItemCountPerRow; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, FALSE); + + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); + } + } + break; + + case VK_PRIOR: + break; + + case VK_NEXT: + break; + } + + return 0; +} + +/*** + * DESCRIPTION: + * Kills the focus. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_KillFocus(HWND32 hwnd) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); NMHDR nmh; - FIXME (listview, "semi stub!\n"); - - nmh.hwndFrom = wndPtr->hwndSelf; - nmh.idFrom = wndPtr->wIDmenu; + nmh.hwndFrom = hwnd; + nmh.idFrom = lCtrlId; nmh.code = NM_KILLFOCUS; + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh); - + /* set window focus flag */ infoPtr->bFocus = FALSE; return 0; } - -static LRESULT -LISTVIEW_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Left mouse button double click. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] WORD : key flag + * [I] WORD : x coordinate + * [I] WORD : y coordinate + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_LButtonDblClk(HWND32 hwnd, WORD wKey, WORD wPosX, + WORD wPosY) { - /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */ - NMLISTVIEW nmlv; + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + NMHDR nmh; - FIXME (listview, "semi stub!\n"); + /* send NM_DBLCLK notification */ + nmh.hwndFrom = hwnd; + nmh.idFrom = lCtrlId; + nmh.code = NM_DBLCLK; + SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); - ZeroMemory (&nmlv, sizeof(NMLISTVIEW)); - nmlv.hdr.hwndFrom = wndPtr->hwndSelf; - nmlv.hdr.idFrom = wndPtr->wIDmenu; - nmlv.hdr.code = NM_DBLCLK; - nmlv.iItem = -1; - nmlv.iSubItem = 0; - nmlv.ptAction.x = (INT32)LOWORD(lParam); - nmlv.ptAction.y = (INT32)HIWORD(lParam); + /* send LVN_ITEMACTIVATE notification */ + nmh.code = LVN_ITEMACTIVATE; + SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + return 0; +} + +/*** + * DESCRIPTION: + * Left mouse button down. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] WORD : key flag + * [I] WORD : x coordinate + * [I] WORD : y coordinate + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_LButtonDown(HWND32 hwnd, WORD wKey, WORD wPosX, + WORD wPosY) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + LVHITTESTINFO hitTestInfo; + LVITEM32A lvItem; + NMHDR nmh; + INT32 nItem; + + /* send NM_RELEASEDCAPTURE notification */ + nmh.hwndFrom = hwnd; + nmh.idFrom = lCtrlId; + nmh.code = NM_RELEASEDCAPTURE; + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); + + if (infoPtr->bFocus == FALSE) + SetFocus32(hwnd); + + /* set left button down flag */ + infoPtr->bLButtonDown = TRUE; + + /* set left button hit coordinates */ + hitTestInfo.pt.x = wPosX; + hitTestInfo.pt.y = wPosY; + + /* perform hit test */ + nItem = SendMessage32A(hwnd, LVM_HITTEST, (WPARAM32)0, (LPARAM)&hitTestInfo); + if ((nItem >= 0) && (nItem < infoPtr->nItemCount)) + { + /* perform state changes (selection and focus) */ + infoPtr->nFocusedItem = nItem; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, TRUE, TRUE); + + /* scroll intem into view if doing a multiple selection */ + + if ((wKey & MK_CONTROL) || (wKey & MK_SHIFT)) +{ + LISTVIEW_SetVisible(hwnd, infoPtr->nFocusedItem); + } + else + { + /* refresh display */ + InvalidateRect32(hwnd, NULL, FALSE); + UpdateWindow32(hwnd); + } + } + else + { + /* clear selection(s) */ + ZeroMemory(&lvItem, sizeof(LVITEM32A)); + lvItem.stateMask = LVIS_SELECTED; + lvItem.state = 0; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem); + + /* repaint everything */ + InvalidateRect32(hwnd, NULL, FALSE); + UpdateWindow32(hwnd); + } + + return 0; +} + +/*** + * DESCRIPTION: + * Left mouse button up. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] WORD : key flag + * [I] WORD : x coordinate + * [I] WORD : y coordinate + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_LButtonUp(HWND32 hwnd, WORD wKey, WORD wPosX, + WORD wPosY) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + NMHDR nmh; + + if (infoPtr->bLButtonDown == TRUE) + { + /* send NM_CLICK notification */ + nmh.hwndFrom = hwnd; + nmh.idFrom = lCtrlId; + nmh.code = NM_CLICK; + SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); + } + + /* set left button flag */ + infoPtr->bLButtonDown = FALSE; return 0; } - -static LRESULT -LISTVIEW_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) -{ - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - NMLISTVIEW nmlv; - - FIXME (listview, "semi stub!\n"); - - ZeroMemory (&nmlv, sizeof(NMLISTVIEW)); - nmlv.hdr.hwndFrom = wndPtr->hwndSelf; - nmlv.hdr.idFrom = wndPtr->wIDmenu; - nmlv.hdr.code = NM_CLICK; - nmlv.iItem = -1; - nmlv.iSubItem = 0; - nmlv.ptAction.x = (INT32)LOWORD(lParam); - nmlv.ptAction.y = (INT32)HIWORD(lParam); - - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); - - if (!infoPtr->bFocus) - SetFocus32 (wndPtr->hwndSelf); - - return 0; -} - - -static LRESULT -LISTVIEW_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Creates the listview control (called before WM_CREATE). + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] WPARAM32 : unhandled + * [I] LPARAM : widow creation info + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_NCCreate(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam) { LISTVIEW_INFO *infoPtr; /* allocate memory for info structure */ infoPtr = (LISTVIEW_INFO *)COMCTL32_Alloc (sizeof(LISTVIEW_INFO)); - wndPtr->wExtra[0] = (DWORD)infoPtr; - - if (infoPtr == NULL) { + SetWindowLong32A(hwnd, 0, (LONG)infoPtr); + if (infoPtr == NULL) + { ERR (listview, "could not allocate info memory!\n"); return 0; } - if ((LISTVIEW_INFO*)wndPtr->wExtra[0] != infoPtr) { + if ((LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0) != infoPtr) + { ERR (listview, "pointer assignment error!\n"); return 0; } - return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCREATE, wParam, lParam); + return DefWindowProc32A(hwnd, WM_NCCREATE, wParam, lParam); } - -static LRESULT -LISTVIEW_NCDestroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Destroys the listview control (called after WM_DESTROY). + * + * PARAMETER(S): + * [I] HWND32 : window handle + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_NCDestroy(HWND32 hwnd) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - - - + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); /* free list view info data */ COMCTL32_Free (infoPtr); @@ -1201,297 +3512,477 @@ LISTVIEW_NCDestroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) return 0; } - -static LRESULT -LISTVIEW_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Handles notification from children. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] INT32 : control identifier + * [I] LPNMHDR : notification information + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_Notify(HWND32 hwnd, INT32 nCtrlId, LPNMHDR lpnmh) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - LPNMHDR lpnmh = (LPNMHDR)lParam; - - if (lpnmh->hwndFrom == infoPtr->hwndHeader) { + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + if (lpnmh->hwndFrom == infoPtr->hwndHeader) + { + /* handle notification from header control */ FIXME (listview, "WM_NOTIFY from header!\n"); } - else { - + else + { + /* handle notification from unknown source */ FIXME (listview, "WM_NOTIFY from unknown source!\n"); } return 0; } - -static LRESULT -LISTVIEW_Paint (WND *wndPtr, WPARAM32 wParam) +/*** + * DESCRIPTION: + * Draws the listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] HDC32 : device context handle + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_Paint(HWND32 hwnd, HDC32 hdc) { - HDC32 hdc; PAINTSTRUCT32 ps; - hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam; - LISTVIEW_Refresh (wndPtr, hdc); - if (!wParam) - EndPaint32 (wndPtr->hwndSelf, &ps); - return 0; + if (hdc == 0) + { + hdc = BeginPaint32(hwnd, &ps); + LISTVIEW_Refresh(hwnd, hdc); + EndPaint32(hwnd, &ps); +} + else + LISTVIEW_Refresh(hwnd, hdc); + + return 0; } - -static LRESULT -LISTVIEW_RButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Right mouse button double clisk. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] WORD : key flag + * [I] WORD : x coordinate + * [I] WORD : y coordinate + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_RButtonDblClk(HWND32 hwnd, WORD wKey, WORD wPosX, + WORD wPosY) { - /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */ - NMLISTVIEW nmlv; + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + NMHDR nmh; - FIXME (listview, "semi stub!\n"); + /* send NM_RELEASEDCAPTURE notification */ + nmh.hwndFrom = hwnd; + nmh.idFrom = lCtrlId; + nmh.code = NM_RELEASEDCAPTURE; + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); - ZeroMemory (&nmlv, sizeof(NMLISTVIEW)); - nmlv.hdr.hwndFrom = wndPtr->hwndSelf; - nmlv.hdr.idFrom = wndPtr->wIDmenu; - nmlv.hdr.code = NM_RDBLCLK; - nmlv.iItem = -1; - nmlv.iSubItem = 0; - nmlv.ptAction.x = (INT32)LOWORD(lParam); - nmlv.ptAction.y = (INT32)HIWORD(lParam); - - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + /* send NM_RDBLCLK notification */ + nmh.code = NM_RDBLCLK; + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); return 0; } - -static LRESULT -LISTVIEW_RButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Right mouse button input. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] WORD : key flag + * [I] WORD : x coordinate + * [I] WORD : y coordinate + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_RButtonDown(HWND32 hwnd, WORD wKey, WORD wPosX, + WORD wPosY) { - /* LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); */ - NMLISTVIEW nmlv; + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + LVHITTESTINFO hitTestInfo; + NMHDR nmh; + LVITEM32A lvItem; + INT32 nItem; - FIXME (listview, "semi stub!\n"); + /* The syslistview32 control sends a NM_RELEASEDCAPTURE notification. + I do not know why, but I decided to send it as well for compatibility + purposes. */ + ZeroMemory(&nmh, sizeof(NMHDR)); + nmh.hwndFrom = hwnd; + nmh.idFrom = lCtrlId; + nmh.code = NM_RELEASEDCAPTURE; + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); + + /* make sure listview control has focus */ + if (infoPtr->bFocus == FALSE) + SetFocus32(hwnd); - ZeroMemory (&nmlv, sizeof(NMLISTVIEW)); - nmlv.hdr.hwndFrom = wndPtr->hwndSelf; - nmlv.hdr.idFrom = wndPtr->wIDmenu; - nmlv.hdr.code = NM_RCLICK; - nmlv.iItem = -1; - nmlv.iSubItem = 0; - nmlv.ptAction.x = (INT32)LOWORD(lParam); - nmlv.ptAction.y = (INT32)HIWORD(lParam); + /* set left button down flag */ + infoPtr->bRButtonDown = TRUE; - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmlv); + /* set hit coordinates */ + hitTestInfo.pt.x = wPosX; + hitTestInfo.pt.y = wPosY; + + /* perform hit test */ + nItem = SendMessage32A(hwnd, LVM_HITTEST, (WPARAM32)0, (LPARAM)&hitTestInfo); + if ((nItem >= 0) && (nItem < infoPtr->nItemCount)) + { + /* perform state changes (selection and focus) */ + infoPtr->nFocusedItem = nItem; + LISTVIEW_SetItemStates(hwnd, infoPtr->nFocusedItem, FALSE, TRUE); + } + else + { + /* clear selection(s) */ + ZeroMemory(&lvItem, sizeof(LVITEM32A)); + lvItem.stateMask = LVIS_SELECTED; + lvItem.state = 0; + SendMessage32A(hwnd, LVM_SETITEMSTATE, (WPARAM32)-1, (LPARAM)&lvItem); + } + + /* repaint everything */ + InvalidateRect32(hwnd, NULL, FALSE); + UpdateWindow32(hwnd); return 0; } - -static LRESULT -LISTVIEW_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Right mouse button up. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] WORD : key flag + * [I] WORD : x coordinate + * [I] WORD : y coordinate + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_RButtonUp(HWND32 hwnd, WORD wKey, WORD wPosX, + WORD wPosY) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); NMHDR nmh; - FIXME (listview, "semi stub!\n"); + if (infoPtr->bRButtonDown == TRUE) + { + /* initialize notification information */ + ZeroMemory(&nmh, sizeof(NMHDR)); + nmh.hwndFrom = hwnd; + nmh.idFrom = lCtrlId; + nmh.code = NM_RCLICK; + SendMessage32A(GetParent32 (hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); + } - nmh.hwndFrom = wndPtr->hwndSelf; - nmh.idFrom = wndPtr->wIDmenu; - nmh.code = NM_SETFOCUS; - - SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY, - (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmh); - - infoPtr->bFocus = TRUE; + /* set button flag */ + infoPtr->bRButtonDown = FALSE; return 0; } - -static LRESULT -LISTVIEW_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Sets the focus. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] HWND32 : window handle of previously focused window + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_SetFocus(HWND32 hwnd, HWND32 hwndLoseFocus) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - HFONT32 hFont = (HFONT32)wParam; - - infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont; - - /* set header font */ - SendMessage32A (infoPtr->hwndHeader, WM_SETFONT, wParam, lParam); - - /* reinitialize the listview */ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lCtrlId = GetWindowLong32A(hwnd, GWL_ID); + NMHDR nmh; + /* send NM_SETFOCUS notification */ + nmh.hwndFrom = hwnd; + nmh.idFrom = lCtrlId; + nmh.code = NM_SETFOCUS; + SendMessage32A(GetParent32(hwnd), WM_NOTIFY, (WPARAM32)lCtrlId, + (LPARAM)&nmh); + /* set window focus flag */ + infoPtr->bFocus = TRUE; - if (lParam) { - /* force redraw */ + return 0; +} +/*** + * DESCRIPTION: + * Sets the font. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] HFONT32 : font handle + * [I] WORD : redraw flag + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_SetFont(HWND32 hwnd, HFONT32 hFont, WORD fRedraw) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + if (hFont == 0) + { + infoPtr->hFont = infoPtr->hDefaultFont; + } + else + { + infoPtr->hFont = hFont; } + if (lStyle & LVS_REPORT) + { + /* set font of header */ + SendMessage32A(infoPtr->hwndHeader, WM_SETFONT, (WPARAM32)hFont, + MAKELPARAM(fRedraw, 0)); +} + + /* invalidate listview control client area */ + InvalidateRect32(hwnd, NULL, FALSE); + + if (fRedraw == TRUE) + UpdateWindow32(hwnd); + + return 0; +} + +/*** + * DESCRIPTION: + * Resizes the listview control. + * + * PARAMETER(S): + * [I] HWND32 : window handle + * [I] WORD : new width + * [I] WORD : new height + * + * RETURN: + * Zero + */ +static LRESULT LISTVIEW_Size(HWND32 hwnd, WORD wWidth, WORD wHeight) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLong32A(hwnd, 0); + LONG lStyle = GetWindowLong32A(hwnd, GWL_STYLE); + INT32 nHScrollHeight; + + if (lStyle & LVS_LIST) + { + if (!(lStyle & WS_HSCROLL)) + { + nHScrollHeight = GetSystemMetrics32(SM_CYHSCROLL); + if (wHeight > nHScrollHeight) + wHeight -= nHScrollHeight; + } + + infoPtr->nHeight = (INT32)wHeight; + infoPtr->nWidth = (INT32)wWidth; + } + + /* set scrollbar(s) if needed */ + LISTVIEW_SetScroll(hwnd); + + /* refresh client area */ + InvalidateRect32(hwnd, NULL, TRUE); + UpdateWindow32(hwnd); + return 0; } - - - -static LRESULT -LISTVIEW_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +/*** + * DESCRIPTION: + * Window procedure of the listview control. + * + * PARAMETER(S): + * [I] HWND32 : + * [I] UINT32 : + * [I] WPARAM32 : + * [I] LPARAM : + * + * RETURN: + * + */ +LRESULT WINAPI LISTVIEW_WindowProc(HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, + LPARAM lParam) { - LISTVIEW_INFO *infoPtr = LISTVIEW_GetInfoPtr(wndPtr); - - GetClientRect32 (wndPtr->hwndSelf, &infoPtr->rcList); - - if (wndPtr->dwStyle & LVS_REPORT) { - HDLAYOUT hl; - WINDOWPOS32 wp; - RECT32 rc; - - rc.top = 0; - rc.left = 0; - rc.right = LOWORD(lParam); - rc.bottom = HIWORD(lParam); - - hl.prc = &rc; - hl.pwpos = ℘ - SendMessage32A (infoPtr->hwndHeader, HDM_LAYOUT, 0, (LPARAM)&hl); - - SetWindowPos32 (infoPtr->hwndHeader, wndPtr->hwndSelf, - wp.x, wp.y, wp.cx, wp.cy, wp.flags); - - infoPtr->rcList.top += wp.cy; - } - - return 0; -} - - -LRESULT WINAPI -LISTVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) -{ - WND *wndPtr = WIN_FindWndPtr(hwnd); - switch (uMsg) { -/* case LVM_APPROXIMATEVIEWRECT: */ -/* case LVM_ARRANGE: */ + case LVM_APPROXIMATEVIEWRECT: + return LISTVIEW_ApproximateViewRect(hwnd, (INT32)wParam, + LOWORD(lParam), HIWORD(lParam)); + case LVM_ARRANGE: + return LISTVIEW_Arrange(hwnd, (INT32)wParam); + /* case LVM_CREATEDRAGIMAGE: */ case LVM_DELETEALLITEMS: - return LISTVIEW_DeleteAllItems (wndPtr); + return LISTVIEW_DeleteAllItems(hwnd); case LVM_DELETECOLUMN: - return LISTVIEW_DeleteColumn (wndPtr, wParam, lParam); + return LISTVIEW_DeleteColumn(hwnd, (INT32)wParam); case LVM_DELETEITEM: - return LISTVIEW_DeleteItem (wndPtr, wParam, lParam); + return LISTVIEW_DeleteItem(hwnd, (INT32)wParam); /* case LVM_EDITLABEL: */ /* case LVM_ENSUREVISIBLE: */ -/* case LVM_FINDITEM: */ + + case LVM_FINDITEM32A: + return LISTVIEW_FindItem(hwnd, (INT32)wParam, (LPLVFINDINFO)lParam); case LVM_GETBKCOLOR: - return LISTVIEW_GetBkColor (wndPtr, wParam, lParam); + return LISTVIEW_GetBkColor(hwnd); /* case LVM_GETBKIMAGE: */ /* case LVM_GETCALLBACKMASK: */ case LVM_GETCOLUMN32A: - return LISTVIEW_GetColumn32A (wndPtr, wParam, lParam); + return LISTVIEW_GetColumn32A(hwnd, (INT32)wParam, (LPLVCOLUMN32A)lParam); /* case LVM_GETCOLUMN32W: */ /* case LVM_GETCOLUMNORDERARRAY: */ case LVM_GETCOLUMNWIDTH: - return LISTVIEW_GetColumnWidth (wndPtr, wParam, lParam); + return LISTVIEW_GetColumnWidth(hwnd, (INT32)wParam); + + case LVM_GETCOUNTPERPAGE: + return LISTVIEW_GetCountPerPage(hwnd); -/* case LVM_GETCOUNTPERPAGE: */ /* case LVM_GETEDITCONTROL: */ /* case LVM_GETEXTENDEDLISTVIEWSTYLE: */ case LVM_GETHEADER: - return LISTVIEW_GetHeader (wndPtr, wParam, lParam); + return LISTVIEW_GetHeader(hwnd); /* case LVM_GETHOTCURSOR: */ /* case LVM_GETHOTITEM: */ /* case LVM_GETHOVERTIME: */ case LVM_GETIMAGELIST: - return LISTVIEW_GetImageList (wndPtr, wParam, lParam); + return LISTVIEW_GetImageList(hwnd, (INT32)wParam); /* case LVM_GETISEARCHSTRING: */ case LVM_GETITEM32A: - return LISTVIEW_GetItem32A (wndPtr, wParam, lParam); + return LISTVIEW_GetItem32A(hwnd, (LPLVITEM32A)lParam); /* case LVM_GETITEM32W: */ case LVM_GETITEMCOUNT: - return LISTVIEW_GetItemCount (wndPtr, wParam, lParam); + return LISTVIEW_GetItemCount(hwnd); case LVM_GETITEMPOSITION: - return LISTVIEW_GetItemPosition (wndPtr, wParam, lParam); + return LISTVIEW_GetItemPosition(hwnd, (INT32)wParam, (LPPOINT32)lParam); -/* case LVM_GETITEMRECT: */ -/* case LVM_GETITEMSPACING: */ -/* case LVM_GETITEMSTATE: */ + case LVM_GETITEMRECT: + return LISTVIEW_GetItemRect(hwnd, (INT32)wParam, (LPRECT32)lParam); + case LVM_GETITEMSPACING: + return LISTVIEW_GetItemSpacing(hwnd, (BOOL32)wParam); + + case LVM_GETITEMSTATE: + return LISTVIEW_GetItemState(hwnd, (INT32)wParam, (UINT32)lParam); + case LVM_GETITEMTEXT32A: - return LISTVIEW_GetItemText32A (wndPtr, wParam, lParam); + LISTVIEW_GetItemText32A(hwnd, (INT32)wParam, (LPLVITEM32A)lParam); + break; /* case LVM_GETITEMTEXT32W: */ case LVM_GETNEXTITEM: - return LISTVIEW_GetNextItem (wndPtr, wParam, lParam); + return LISTVIEW_GetNextItem(hwnd, (INT32)wParam, LOWORD(lParam)); /* case LVM_GETNUMBEROFWORKAREAS: */ -/* case LVM_GETORIGIN: */ + case LVM_GETORIGIN: + return LISTVIEW_GetOrigin(hwnd, (LPPOINT32)lParam); case LVM_GETSELECTEDCOUNT: - return LISTVIEW_GetSelectedCount (wndPtr, wParam, lParam); + return LISTVIEW_GetSelectedCount(hwnd); -/* case LVM_GETSELECTIONMARK: */ + case LVM_GETSELECTIONMARK: + return LISTVIEW_GetSelectionMark(hwnd); case LVM_GETSTRINGWIDTH32A: - return LISTVIEW_GetStringWidth32A (wndPtr, wParam, lParam); + return LISTVIEW_GetStringWidth32A (hwnd, (LPCSTR)lParam); /* case LVM_GETSTRINGWIDTH32W: */ /* case LVM_GETSUBITEMRECT: */ case LVM_GETTEXTBKCOLOR: - return LISTVIEW_GetTextBkColor (wndPtr, wParam, lParam); + return LISTVIEW_GetTextBkColor(hwnd); case LVM_GETTEXTCOLOR: - return LISTVIEW_GetTextColor (wndPtr, wParam, lParam); + return LISTVIEW_GetTextColor(hwnd); /* case LVM_GETTOOLTIPS: */ /* case LVM_GETTOPINDEX: */ /* case LVM_GETUNICODEFORMAT: */ -/* case LVM_GETVIEWRECT: */ + + case LVM_GETVIEWRECT: + return LISTVIEW_GetViewRect(hwnd, (LPRECT32)lParam); + /* case LVM_GETWORKAREAS: */ case LVM_HITTEST: - return LISTVIEW_HitTest (wndPtr, wParam, lParam); + return LISTVIEW_HitTest(hwnd, (LPLVHITTESTINFO)lParam); case LVM_INSERTCOLUMN32A: - return LISTVIEW_InsertColumn32A (wndPtr, wParam, lParam); + return LISTVIEW_InsertColumn32A(hwnd, (INT32)wParam, + (LPLVCOLUMN32A)lParam); /* case LVM_INSERTCOLUMN32W: */ case LVM_INSERTITEM32A: - return LISTVIEW_InsertItem32A (wndPtr, wParam, lParam); + return LISTVIEW_InsertItem32A(hwnd, (LPLVITEM32A)lParam); /* case LVM_INSERTITEM32W: */ case LVM_REDRAWITEMS: - return LISTVIEW_RedrawItems (wndPtr, wParam, lParam); + return LISTVIEW_RedrawItems(hwnd, (INT32)wParam, (INT32)lParam); -/* case LVM_SCROLL: */ + case LVM_SCROLL: + return LISTVIEW_Scroll(hwnd, (INT32)wParam, (INT32)lParam); case LVM_SETBKCOLOR: - return LISTVIEW_SetBkColor (wndPtr, wParam, lParam); + return LISTVIEW_SetBkColor(hwnd, (COLORREF)lParam); /* case LVM_SETBKIMAGE: */ /* case LVM_SETCALLBACKMASK: */ case LVM_SETCOLUMN32A: - return LISTVIEW_SetColumn32A (wndPtr, wParam, lParam); + return LISTVIEW_SetColumn32A(hwnd, (INT32)wParam, (LPLVCOLUMN32A)lParam); /* case LVM_SETCOLUMN32W: */ /* case LVM_SETCOLUMNORDERARRAY: */ @@ -1503,105 +3994,121 @@ LISTVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) /* case LVM_SETICONSPACING: */ case LVM_SETIMAGELIST: - return LISTVIEW_SetImageList (wndPtr, wParam, lParam); + return LISTVIEW_SetImageList(hwnd, (INT32)wParam, (HIMAGELIST)lParam); case LVM_SETITEM32A: - return LISTVIEW_SetItem32A (wndPtr, wParam, lParam); + return LISTVIEW_SetItem32A(hwnd, (LPLVITEM32A)lParam); /* case LVM_SETITEM32W: */ /* case LVM_SETITEMCOUNT: */ case LVM_SETITEMPOSITION: - return LISTVIEW_SetItemPosition (wndPtr, wParam, lParam); + return LISTVIEW_SetItemPosition(hwnd, (INT32)wParam, + (INT32)LOWORD(lParam), + (INT32) HIWORD(lParam)); /* case LVM_SETITEMPOSITION32: */ -/* case LVM_SETITEMSTATE: */ - case LVM_SETITEMTEXT32A: - return LISTVIEW_SetItemText32A (wndPtr, wParam, lParam); + case LVM_SETITEMSTATE: + return LISTVIEW_SetItemState(hwnd, (INT32)wParam, (LPLVITEM32A)lParam); -/* case LVM_SETITEMTEXT32W: */ +/* case LVM_SETITEMTEXT: */ /* case LVM_SETSELECTIONMARK: */ case LVM_SETTEXTBKCOLOR: - return LISTVIEW_SetTextBkColor (wndPtr, wParam, lParam); + return LISTVIEW_SetTextBkColor(hwnd, (COLORREF)lParam); case LVM_SETTEXTCOLOR: - return LISTVIEW_SetTextColor (wndPtr, wParam, lParam); + return LISTVIEW_SetTextColor(hwnd, (COLORREF)lParam); /* case LVM_SETTOOLTIPS: */ /* case LVM_SETUNICODEFORMAT: */ /* case LVM_SETWORKAREAS: */ case LVM_SORTITEMS: - return LISTVIEW_SortItems (wndPtr, wParam, lParam); + return LISTVIEW_SortItems(hwnd, wParam, lParam); /* case LVM_SUBITEMHITTEST: */ -/* case LVM_UPDATE: */ - + case LVM_UPDATE: + return LISTVIEW_Update(hwnd, (INT32)wParam); /* case WM_CHAR: */ /* case WM_COMMAND: */ case WM_CREATE: - return LISTVIEW_Create (wndPtr, wParam, lParam); + return LISTVIEW_Create(hwnd, wParam, lParam); case WM_DESTROY: - return LISTVIEW_Destroy (wndPtr, wParam, lParam); + return LISTVIEW_Destroy(hwnd, wParam, lParam); case WM_ERASEBKGND: - return LISTVIEW_EraseBackground (wndPtr, wParam, lParam); + return LISTVIEW_EraseBackground (hwnd, wParam, lParam); case WM_GETDLGCODE: return DLGC_WANTTAB | DLGC_WANTARROWS; case WM_GETFONT: - return LISTVIEW_GetFont (wndPtr, wParam, lParam); + return LISTVIEW_GetFont(hwnd); -/* case WM_HSCROLL: */ -/* case WM_KEYDOWN: */ + case WM_HSCROLL: + return LISTVIEW_HScroll(hwnd, (INT32)LOWORD(wParam), + (INT32)HIWORD(wParam), (HWND32)lParam); + + case WM_KEYDOWN: + return LISTVIEW_KeyDown(hwnd, (INT32)wParam, (LONG)lParam); case WM_KILLFOCUS: - return LISTVIEW_KillFocus (wndPtr, wParam, lParam); + return LISTVIEW_KillFocus(hwnd); case WM_LBUTTONDBLCLK: - return LISTVIEW_LButtonDblClk (wndPtr, wParam, lParam); + return LISTVIEW_LButtonDblClk(hwnd, (WORD)wParam, LOWORD(lParam), + HIWORD(lParam)); case WM_LBUTTONDOWN: - return LISTVIEW_LButtonDown (wndPtr, wParam, lParam); + return LISTVIEW_LButtonDown(hwnd, (WORD)wParam, LOWORD(lParam), + HIWORD(lParam)); + case WM_LBUTTONUP: + return LISTVIEW_LButtonUp(hwnd, (WORD)wParam, LOWORD(lParam), + HIWORD(lParam)); /* case WM_MOUSEMOVE: */ -/* return LISTVIEW_MouseMove (wndPtr, wParam, lParam); */ +/* return LISTVIEW_MouseMove (hwnd, wParam, lParam); */ case WM_NCCREATE: - return LISTVIEW_NCCreate (wndPtr, wParam, lParam); + return LISTVIEW_NCCreate(hwnd, wParam, lParam); case WM_NCDESTROY: - return LISTVIEW_NCDestroy (wndPtr, wParam, lParam); + return LISTVIEW_NCDestroy(hwnd); case WM_NOTIFY: - return LISTVIEW_Notify (wndPtr, wParam, lParam); + return LISTVIEW_Notify(hwnd, (INT32)wParam, (LPNMHDR)lParam); case WM_PAINT: - return LISTVIEW_Paint (wndPtr, wParam); + return LISTVIEW_Paint(hwnd, (HDC32)wParam); case WM_RBUTTONDBLCLK: - return LISTVIEW_RButtonDblClk (wndPtr, wParam, lParam); + return LISTVIEW_RButtonDblClk(hwnd, (WORD)wParam, LOWORD(lParam), + HIWORD(lParam)); case WM_RBUTTONDOWN: - return LISTVIEW_RButtonDown (wndPtr, wParam, lParam); + return LISTVIEW_RButtonDown(hwnd, (WORD)wParam, LOWORD(lParam), + HIWORD(lParam)); + + case WM_RBUTTONUP: + return LISTVIEW_RButtonUp(hwnd, (WORD)wParam, LOWORD(lParam), + HIWORD(lParam)); case WM_SETFOCUS: - return LISTVIEW_SetFocus (wndPtr, wParam, lParam); + return LISTVIEW_SetFocus(hwnd, (HWND32)wParam); case WM_SETFONT: - return LISTVIEW_SetFont (wndPtr, wParam, lParam); + return LISTVIEW_SetFont(hwnd, (HFONT32)wParam, (WORD)lParam); /* case WM_SETREDRAW: */ case WM_SIZE: - return LISTVIEW_Size (wndPtr, wParam, lParam); + return LISTVIEW_Size(hwnd, LOWORD(lParam), HIWORD(lParam)); /* case WM_TIMER: */ /* case WM_VSCROLL: */ @@ -1612,19 +4119,30 @@ LISTVIEW_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) if (uMsg >= WM_USER) ERR (listview, "unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam); + + /* call default window procedure */ return DefWindowProc32A (hwnd, uMsg, wParam, lParam); } + return 0; } - -VOID -LISTVIEW_Register (VOID) +/*** + * DESCRIPTION:` + * Registers the window class. + * + * PARAMETER(S): + * None + * + * RETURN: + * None + */ +VOID LISTVIEW_Register(VOID) { WNDCLASS32A wndClass; - if (GlobalFindAtom32A (WC_LISTVIEW32A)) return; - + if (!GlobalFindAtom32A(WC_LISTVIEW32A)) + { ZeroMemory (&wndClass, sizeof(WNDCLASS32A)); wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS; wndClass.lpfnWndProc = (WNDPROC32)LISTVIEW_WindowProc; @@ -1633,13 +4151,21 @@ LISTVIEW_Register (VOID) wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A); wndClass.hbrBackground = (HBRUSH32)(COLOR_WINDOW + 1); wndClass.lpszClassName = WC_LISTVIEW32A; - RegisterClass32A (&wndClass); } +} - -VOID -LISTVIEW_Unregister (VOID) +/*** + * DESCRIPTION: + * Unregisters the window class. + * + * PARAMETER(S): + * None + * + * RETURN: + * None + */ +VOID LISTVIEW_Unregister(VOID) { if (GlobalFindAtom32A (WC_LISTVIEW32A)) UnregisterClass32A (WC_LISTVIEW32A, (HINSTANCE32)NULL); diff --git a/include/commctrl.h b/include/commctrl.h index 535c5bb0717..990b05ec994 100644 --- a/include/commctrl.h +++ b/include/commctrl.h @@ -5,9 +5,9 @@ #ifndef __WINE_COMMCTRL_H #define __WINE_COMMCTRL_H -#include "windows.h" +#include "wintypes.h" +#include "winuser.h" #include "imagelist.h" -#include "prsht.h" /* c++ likes nameless unions whereas c doesnt */ /* (used in property sheet structures) */ @@ -1798,7 +1798,6 @@ typedef struct { #define TVITEM WINELIB_NAME_AW(TVITEM) #define LPTVITEM WINELIB_NAME_AW(LPTVITEM) - #define TV_ITEM TVITEM typedef struct { @@ -1832,7 +1831,6 @@ typedef struct { #define TVITEMEX WINELIB_NAME_AW(TVITEMEX) #define LPTVITEMEX WINELIB_NAME_AW(LPTVITEMEX) - typedef struct tagTVINSERTSTRUCT32A { HTREEITEM hParent; HTREEITEM hInsertAfter; @@ -1860,7 +1858,6 @@ typedef struct tagTVINSERTSTRUCT32W { - typedef struct tagNMTREEVIEW32A { NMHDR hdr; UINT32 action; @@ -2156,6 +2153,18 @@ typedef struct tagNMTVGETINFOTIP32W #define LVSIL_SMALL 1 #define LVSIL_STATE 2 +#define LVIS_FOCUSED 0x0001 +#define LVIS_SELECTED 0x0002 +#define LVIS_CUT 0x0004 +#define LVIS_DROPHILITED 0x0008 +#define LVIS_ACTIVATING 0x0020 + +#define LVFI_PARAM 0X0001 +#define LVFI_STRING 0X0002 +#define LVFI_PARTIAL 0X0008 +#define LVFI_WRAP 0X0020 +#define LVFI_NEARESTXY 0X0040 + #define LVIF_TEXT 0x0001 #define LVIF_IMAGE 0x0002 #define LVIF_PARAM 0x0004 @@ -2163,6 +2172,11 @@ typedef struct tagNMTVGETINFOTIP32W #define LVIF_INDENT 0x0010 #define LVIF_NORECOMPUTE 0x0800 +#define LVIR_BOUNDS 0x0000 +#define LVIR_LABEL 0x0002 +#define LVIR_ICON 0x0001 +#define LVIR_SELECTBOUNDS 0x0003 + #define LVIS_FOCUSED 0x0001 #define LVIS_SELECTED 0x0002 #define LVIS_CUT 0x0004 @@ -2331,6 +2345,10 @@ typedef struct tagNMTVGETINFOTIP32W #define LVN_SETDISPINFO32W (LVN_FIRST-78) #define LVN_SETDISPINFO WINELIB_NAME_AW(LVN_SETDISPINFO) +#define LVA_ALIGNLEFT 0x0000 +#define LVA_DEFAULT 0x0001 +#define LVA_ALIGNTOP 0x0002 +#define LVA_SNAPTOGRID 0x0005 typedef struct tagLVITEMA { diff --git a/include/listview.h b/include/listview.h index b140b8006a6..f027c96b27c 100644 --- a/include/listview.h +++ b/include/listview.h @@ -27,14 +27,20 @@ typedef struct tagLISTVIEW_INFO HIMAGELIST himlNormal; HIMAGELIST himlSmall; HIMAGELIST himlState; - INT32 nItemCount; + BOOL32 bLButtonDown; + BOOL32 bRButtonDown; INT32 nColumnCount; + INT32 nFocusedItem; + INT32 nItemCount; + INT32 nItemHeight; + INT32 nColumnWidth; + INT32 nSelectionMark; HWND32 hwndHeader; HFONT32 hDefaultFont; HFONT32 hFont; - RECT32 rcList; /* "client" area of the list (without header) */ + INT32 nWidth; + INT32 nHeight; BOOL32 bFocus; - DWORD dwExStyle; /* extended listview style */ HDPA hdpaItems;