Changeset 3385 for trunk/src


Ignore:
Timestamp:
Apr 15, 2000, 4:22:31 PM (25 years ago)
Author:
cbratschi
Message:

new listview item handling, new messages

Location:
trunk/src/comctl32
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/comctl32/comctl32undoc.cpp

    r3154 r3385  
    1 /* $Id: comctl32undoc.cpp,v 1.2 2000-03-18 16:17:22 cbratschi Exp $ */
     1/* $Id: comctl32undoc.cpp,v 1.3 2000-04-15 14:22:11 cbratschi Exp $ */
    22/*
    33 * Undocumented functions from COMCTL32.DLL
     
    10461046    HDPA hdpa;
    10471047
    1048     dprintf(("COMCTL32: DPA_Create"));
     1048    dprintf2(("COMCTL32: DPA_Create"));
    10491049
    10501050    hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
     
    10771077DPA_Destroy (const HDPA hdpa)
    10781078{
    1079     dprintf(("COMCTL32: DPA_Destroy"));
     1079    dprintf2(("COMCTL32: DPA_Destroy"));
    10801080
    10811081    if (!hdpa)
     
    11061106DPA_Grow (const HDPA hdpa, INT nGrow)
    11071107{
    1108     dprintf(("COMCTL32: DPA_Grow"));
     1108    dprintf2(("COMCTL32: DPA_Grow"));
    11091109
    11101110    if (!hdpa)
     
    11431143    HDPA hdpaTemp;
    11441144
    1145     dprintf(("COMCTL32: DPA_Clone"));
     1145    dprintf2(("COMCTL32: DPA_Clone"));
    11461146
    11471147    if (!hdpa)
     
    14481448DPA_DeleteAllPtrs (const HDPA hdpa)
    14491449{
    1450     dprintf(("COMCTL32: DPA_DeleteAllPtrs"));
     1450    dprintf2(("COMCTL32: DPA_DeleteAllPtrs"));
    14511451
    14521452    if (!hdpa)
     
    15111511}
    15121512
     1513//internal API
     1514INT DPA_InsertPtrSorted(const HDPA hdpa,LPVOID p,PFNDPACOMPARE pfnCompare,LPARAM lParam)
     1515{
     1516  INT pos,minPos,maxPos,res;
     1517
     1518  if (!hdpa || !pfnCompare) return -1;
     1519
     1520  if (hdpa->nItemCount == 0)
     1521    return DPA_InsertPtr(hdpa,0,p);
     1522
     1523  //check last
     1524  if ((pfnCompare)(p,hdpa->ptrs[hdpa->nItemCount-1],lParam) >= 0)
     1525  {
     1526    return DPA_InsertPtr(hdpa,hdpa->nItemCount,p);
     1527  }
     1528  //check first
     1529  if ((pfnCompare)(p,hdpa->ptrs[0],lParam) < 0)
     1530  {
     1531    return DPA_InsertPtr(hdpa,0,p);
     1532  }
     1533
     1534  minPos = 1;
     1535  maxPos = hdpa->nItemCount-1;
     1536
     1537  while (minPos != maxPos)
     1538  {
     1539    pos = (minPos+maxPos)/2;
     1540    res = (pfnCompare)(p,hdpa->ptrs[pos],lParam);
     1541    if (res < 0)
     1542      maxPos = pos;
     1543    else
     1544      minPos = pos+1;
     1545  }
     1546
     1547  return DPA_InsertPtr(hdpa,minPos,p);
     1548}
    15131549
    15141550/**************************************************************************
     
    15301566DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
    15311567{
    1532     dprintf(("COMCTL32: DPA_Sort"));
     1568    dprintf2(("COMCTL32: DPA_Sort"));
    15331569
    15341570    if (!hdpa || !pfnCompare)
     
    15701606            PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
    15711607{
    1572     dprintf(("COMCTL32: DPA_Search"));
     1608    dprintf2(("COMCTL32: DPA_Search"));
    15731609
    15741610    if (!hdpa || !pfnCompare || !pFind)
     
    16491685    HDPA hdpa;
    16501686
    1651     dprintf(("COMCTL32: DPA_CreateEx"));
     1687    dprintf2(("COMCTL32: DPA_CreateEx"));
    16521688
    16531689    if (hHeap)
  • trunk/src/comctl32/header.cpp

    r3351 r3385  
    1 /* $Id: header.cpp,v 1.5 2000-04-08 18:32:53 cbratschi Exp $ */
     1/* $Id: header.cpp,v 1.6 2000-04-15 14:22:15 cbratschi Exp $ */
    22/*
    33 *  Header control
     
    11091109LRESULT HEADER_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
    11101110{
    1111     HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
     1111    HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd);
    11121112    INT iItem = (INT)wParam;
    11131113    LPRECT lpRect = (LPRECT)lParam;
     
    12541254  for (x = 0;x < infoPtr->uNumItem;x++)
    12551255    for (y = 0;y < infoPtr->uNumItem;y++)
    1256       if (infoPtr->items[x].iOrder == lpiArray[x]) memcpy(&newItems[x],&infoPtr->items[y],sizeof(HEADER_ITEM));
     1256      if (infoPtr->items[y].iOrder == lpiArray[x]) memcpy(&newItems[x],&infoPtr->items[y],sizeof(HEADER_ITEM));
    12571257  COMCTL32_Free(infoPtr->items);
    12581258  infoPtr->items = newItems;
  • trunk/src/comctl32/listview.cpp

    r3369 r3385  
    1 /*$Id: listview.cpp,v 1.12 2000-04-12 16:38:58 cbratschi Exp $*/
     1/*$Id: listview.cpp,v 1.13 2000-04-15 14:22:19 cbratschi Exp $*/
    22/*
    33 * Listview control
     
    1313 * TODO:
    1414 *   - Hot item handling.
    15  *   - subitems not sort save! (sortitem.exe)
    1615 *   - rcView and origin (need testcase!!!)
    1716 *   - rcView not updated in LVM_SETITEMPOSITION and other messages
     17 *   - LISTVIEW_SetBkImage
     18 *   - LISTVIEW_GetBkImage
     19 *   - LVS_NOLABELWRAP
     20 *   - LVS_OWNERDATA
     21 *   - LVS_OWNERDRAWFIXED
     22 *   - LVS_EX_*
    1823 *   - many things untested!
    19  *
    20  * Notifications:
    21  *   LISTVIEW_Notify : most notifications from children (editbox and header)
    2224 *
    2325 * Data structure:
     
    2628 * Advanced functionality:
    2729 *   LISTVIEW_GetNumberOfWorkAreas : not implemented
    28  *   LISTVIEW_GetHotCursor : not implemented
    2930 *   LISTVIEW_GetHoverTime : not implemented
    3031 *   LISTVIEW_GetISearchString : not implemented
    31  *   LISTVIEW_GetBkImage : not implemented
    32  *   LISTVIEW_GetColumnOrderArray : simple hack only
    33  *   LISTVIEW_SetColumnOrderArray : simple hack only
    34  *   LISTVIEW_ApproximateViewRect : incomplete
    3532 *
    3633 */
     
    8582 * macros
    8683 */
    87 #define GETITEMCOUNT(infoPtr) ((infoPtr)->hdpaItems->nItemCount)
     84
    8885/* retrieve the number of items in the listview */
    8986#define GETITEMCOUNT(infoPtr) ((infoPtr)->hdpaItems->nItemCount)
     
    112109static VOID    LISTVIEW_AddGroupSelection(HWND, INT);
    113110static VOID    LISTVIEW_AddSelection(HWND, INT);
    114 static BOOL    LISTVIEW_AddSubItem(HWND, LPLVITEMW,BOOL);
     111static LISTVIEW_ITEMDATA* LISTVIEW_GetItemData(HDPA hdpaSubItems,INT nSubItem);
    115112static INT     LISTVIEW_FindInsertPosition(HDPA, INT);
    116113static INT     LISTVIEW_GetItemHeight(HWND);
     
    121118static LRESULT LISTVIEW_GetOrigin(HWND, LPPOINT);
    122119static INT     LISTVIEW_CalculateWidth(HWND hwnd, INT nItem);
    123 static LISTVIEW_SUBITEM* LISTVIEW_GetSubItem(HDPA, INT);
    124120static LRESULT LISTVIEW_GetViewRect(HWND, LPRECT);
    125121static BOOL    LISTVIEW_InitItem(HWND, LISTVIEW_ITEM *, LPLVITEMW,BOOL);
    126 static BOOL    LISTVIEW_InitSubItem(HWND,LISTVIEW_SUBITEM*,LPLVITEMW,BOOL);
    127122static LRESULT LISTVIEW_MouseSelection(HWND, POINT);
    128123static BOOL    LISTVIEW_RemoveColumn(HDPA, INT);
    129124static VOID    LISTVIEW_RemoveSelections(HWND, INT, INT);
    130 static BOOL    LISTVIEW_RemoveSubItem(HDPA, INT);
     125static BOOL    LISTVIEW_RemoveItemData(HDPA,INT);
    131126static VOID    LISTVIEW_SetGroupSelection(HWND, INT);
    132127static LRESULT LISTVIEW_SetItem(HWND, LPLVITEMW,BOOL);
     
    139134static LRESULT LISTVIEW_SetViewRect(HWND, LPRECT);
    140135static BOOL    LISTVIEW_ToggleSelection(HWND, INT);
    141 static VOID    LISTVIEW_UnsupportedStyles(LONG lStyle);
    142136static HWND    LISTVIEW_EditLabel(HWND hwnd,INT nItem,BOOL unicode);
    143137static BOOL    LISTVIEW_EndEditLabel(HWND hwnd,LPSTR pszText,DWORD nItem,BOOL cancel);
     
    506500/***
    507501 * DESCRIPTION:
    508  * Prints a message for unsupported window styles.
    509  * A kind of TODO list for window styles.
    510  *
    511  * PARAMETER(S):
    512  * [I] LONG : window style
    513  *
    514  * RETURN:
    515  * None
    516  */
    517 static VOID LISTVIEW_UnsupportedStyles(LONG lStyle)
    518 {
    519   if ((LVS_TYPEMASK & lStyle) == LVS_NOLABELWRAP)
    520   {
    521     //FIXME("  LVS_NOLABELWRAP\n");
    522   }
    523 
    524   if ((LVS_TYPEMASK & lStyle) == LVS_OWNERDRAWFIXED)
    525   {
    526     //FIXME("  LVS_OWNERDRAWFIXED\n");
    527   }
    528 
    529   if ((LVS_TYPEMASK & lStyle) == LVS_SHAREIMAGELISTS)
    530   {
    531     //FIXME("  LVS_SHAREIMAGELISTS\n");
    532   }
    533 
    534   if ((LVS_TYPEMASK & lStyle) == LVS_SORTASCENDING)
    535   {
    536     //FIXME("  LVS_SORTASCENDING\n");
    537   }
    538 
    539   if ((LVS_TYPEMASK & lStyle) == LVS_SORTDESCENDING)
    540   {
    541     //FIXME("  LVS_SORTDESCENDING\n");
    542   }
    543 }
    544 
    545 /***
    546  * DESCRIPTION:
    547502 * Aligns the items with the top edge of the window.
    548503 *
     
    718673
    719674  return bResult;
    720 }
    721 
    722 /***
    723  * DESCRIPTION:
    724  * Retrieves the subitem pointer associated with the subitem index.
    725  *
    726  * PARAMETER(S):
    727  * [I] HDPA : DPA handle for a specific item
    728  * [I] INT : index of subitem
    729  *
    730  * RETURN:
    731  *   SUCCESS : subitem pointer
    732  *   FAILURE : NULL
    733  */
    734 static LISTVIEW_SUBITEM* LISTVIEW_GetSubItemPtr(HDPA hdpaSubItems,
    735                                                 INT nSubItem)
    736 {
    737   LISTVIEW_SUBITEM *lpSubItem;
    738   INT i;
    739 
    740   for (i = 1; i < hdpaSubItems->nItemCount; i++)
    741   {
    742     lpSubItem = (LISTVIEW_SUBITEM *) DPA_GetPtr(hdpaSubItems, i);
    743     if (lpSubItem)
    744     {
    745       if (lpSubItem->iSubItem == nSubItem)
    746       {
    747         return lpSubItem;
    748       }
    749     }
    750   }
    751 
    752   return NULL;
    753675}
    754676
     
    13001222{
    13011223  BOOL bResult = TRUE;
    1302   HDPA hdpaSubItems;
     1224  LISTVIEW_ITEM *lpItem;
    13031225  INT i;
    13041226
    13051227  for (i = 0; i < hdpaItems->nItemCount; i++)
    13061228  {
    1307     hdpaSubItems = (HDPA)DPA_GetPtr(hdpaItems, i);
    1308     if (hdpaSubItems)
    1309     {
    1310       if (LISTVIEW_RemoveSubItem(hdpaSubItems, nSubItem) == FALSE)
     1229    lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(hdpaItems,i);
     1230    if (lpItem)
     1231    {
     1232      if (LISTVIEW_RemoveItemData(lpItem->hdpaSubItems,nSubItem) == FALSE)
    13111233      {
    13121234        bResult = FALSE;
     
    13301252 *   FAILURE : FALSE
    13311253 */
    1332 static BOOL LISTVIEW_RemoveSubItem(HDPA hdpaSubItems, INT nSubItem)
    1333 {
    1334   LISTVIEW_SUBITEM *lpSubItem;
     1254static BOOL LISTVIEW_RemoveItemData(HDPA hdpaSubItems,INT nSubItem)
     1255{
     1256  LISTVIEW_ITEMDATA *lpItemData = LISTVIEW_GetItemData(hdpaSubItems,nSubItem);
    13351257  INT i;
    13361258
    1337   for (i = 1; i < hdpaSubItems->nItemCount; i++)
    1338   {
    1339     lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
    1340     if (lpSubItem != NULL)
    1341     {
    1342       if (lpSubItem->iSubItem == nSubItem)
    1343       {
    1344         /* free string */
    1345         if ((lpSubItem->pszText != NULL) &&
    1346             (lpSubItem->pszText != LPSTR_TEXTCALLBACKW))
    1347         {
    1348           COMCTL32_Free(lpSubItem->pszText);
    1349         }
    1350 
    1351         /* free item */
    1352         COMCTL32_Free(lpSubItem);
    1353 
    1354         /* free dpa memory */
    1355         if (DPA_DeletePtr(hdpaSubItems, i) == NULL)
    1356         {
    1357           return FALSE;
    1358         }
    1359       }
    1360       else if (lpSubItem->iSubItem > nSubItem)
    1361       {
    1362         return TRUE;
    1363       }
     1259  if (lpItemData)
     1260  {
     1261    /* free string */
     1262    if (lpItemData->pszText && (lpItemData->pszText != LPSTR_TEXTCALLBACKW))
     1263    {
     1264      COMCTL32_Free(lpItemData->pszText);
     1265    }
     1266
     1267    /* free item */
     1268    COMCTL32_Free(lpItemData);
     1269
     1270    /* free dpa memory */
     1271    if (DPA_DeletePtr(hdpaSubItems,i) == NULL)
     1272    {
     1273      return FALSE;
    13641274    }
    13651275  }
     
    13791289 *   LVIF_* flags
    13801290 */
    1381 static UINT LISTVIEW_GetItemChanges(LISTVIEW_ITEM *lpItem,LPLVITEMW lpLVItem,BOOL unicode)
     1291static UINT LISTVIEW_GetItemChanges(LISTVIEW_ITEM *lpItem,LISTVIEW_ITEMDATA *lpItemData,LPLVITEMW lpLVItem,BOOL unicode)
    13821292{
    13831293  UINT uChanged = 0;
    13841294
    1385   if ((lpItem != NULL) && (lpLVItem != NULL))
     1295  if (lpItem && lpItemData && lpLVItem)
    13861296  {
    13871297    if (lpLVItem->mask & LVIF_STATE)
     
    13961306    if (lpLVItem->mask & LVIF_IMAGE)
    13971307    {
    1398       if (lpItem->iImage != lpLVItem->iImage)
     1308      if (lpItemData->iImage != lpLVItem->iImage)
    13991309      {
    14001310        uChanged |= LVIF_IMAGE;
     
    14241334        if (lpLVItem->pszText == LPSTR_TEXTCALLBACKW)
    14251335        {
    1426           if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
     1336          if (lpItemData->pszText != LPSTR_TEXTCALLBACKW)
    14271337          {
    14281338            uChanged |= LVIF_TEXT;
     
    14321342        else
    14331343        {
    1434           if (lpItem->pszText == LPSTR_TEXTCALLBACKW)
     1344          if (lpItemData->pszText == LPSTR_TEXTCALLBACKW)
    14351345          {
    14361346            uChanged |= LVIF_TEXT;
     
    14401350            if (lpLVItem->pszText)
    14411351            {
    1442               if (lpItem->pszText)
     1352              if (lpItemData->pszText)
    14431353              {
    1444                 if (lstrcmpW(lpLVItem->pszText, lpItem->pszText) != 0)
     1354                if (lstrcmpW(lpLVItem->pszText,lpItemData->pszText) != 0)
    14451355                {
    14461356                  uChanged |= LVIF_TEXT;
     
    14541364            else
    14551365            {
    1456               if (lpItem->pszText)
     1366              if (lpItemData->pszText)
    14571367              {
    14581368                uChanged |= LVIF_TEXT;
     
    14651375        if ((LPSTR)lpLVItem->pszText == LPSTR_TEXTCALLBACKA)
    14661376        {
    1467           if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
     1377          if (lpItemData->pszText != LPSTR_TEXTCALLBACKW)
    14681378          {
    14691379            uChanged |= LVIF_TEXT;
     
    14731383        else
    14741384        {
    1475           if (lpItem->pszText == LPSTR_TEXTCALLBACKW)
     1385          if (lpItemData->pszText == LPSTR_TEXTCALLBACKW)
    14761386          {
    14771387            uChanged |= LVIF_TEXT;
     
    14811391            if (lpLVItem->pszText)
    14821392            {
    1483               if (lpItem->pszText)
     1393              if (lpItemData->pszText)
    14841394              {
    1485                 if (lstrcmpAtoW((LPSTR)lpLVItem->pszText,lpItem->pszText) != 0)
     1395                if (lstrcmpAtoW((LPSTR)lpLVItem->pszText,lpItemData->pszText) != 0)
    14861396                {
    14871397                  uChanged |= LVIF_TEXT;
     
    14951405            else
    14961406            {
    1497               if (lpItem->pszText)
     1407              if (lpItemData->pszText)
    14981408              {
    14991409                uChanged |= LVIF_TEXT;
     
    15371447    }
    15381448
     1449    if (lpLVItem->mask & LVIF_PARAM)
     1450    {
     1451      lpItem->lParam = lpLVItem->lParam;
     1452    }
     1453
     1454    if (lpLVItem->mask & LVIF_INDENT)
     1455    {
     1456      lpItem->iIndent = lpLVItem->iIndent;
     1457    }
     1458  }
     1459
     1460  return bResult;
     1461}
     1462
     1463static BOOL LISTVIEW_InitItemData(HWND hwnd,LISTVIEW_ITEMDATA *lpItemData,LPLVITEMW lpLVItem,BOOL unicode)
     1464{
     1465  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     1466  BOOL bResult = FALSE;
     1467
     1468  if (lpItemData && lpLVItem)
     1469  {
     1470    bResult = TRUE;
     1471
     1472    lpItemData->iSubItem = lpLVItem->iSubItem;
     1473
    15391474    if (lpLVItem->mask & LVIF_IMAGE)
    15401475    {
    1541       lpItem->iImage = lpLVItem->iImage;
    1542     }
    1543 
    1544     if (lpLVItem->mask & LVIF_PARAM)
    1545     {
    1546       lpItem->lParam = lpLVItem->lParam;
    1547     }
    1548 
    1549     if (lpLVItem->mask & LVIF_INDENT)
    1550     {
    1551       lpItem->iIndent = lpLVItem->iIndent;
     1476      lpItemData->iImage = lpLVItem->iImage;
    15521477    }
    15531478
     
    15581483        if (lpLVItem->pszText == LPSTR_TEXTCALLBACKW)
    15591484        {
    1560           if ((infoPtr->dwStyle & LVS_SORTASCENDING) || (infoPtr->dwStyle & LVS_SORTDESCENDING))
     1485          if (!lpItemData->iSubItem && ((infoPtr->dwStyle & LVS_SORTASCENDING) || (infoPtr->dwStyle & LVS_SORTDESCENDING)))
    15611486          {
    15621487            return FALSE;
    15631488          }
    15641489
    1565           if (lpItem->pszText && (lpItem->pszText != LPSTR_TEXTCALLBACKW))
     1490          if (lpItemData->pszText && (lpItemData->pszText != LPSTR_TEXTCALLBACKW))
    15661491          {
    1567             COMCTL32_Free(lpItem->pszText);
     1492            COMCTL32_Free(lpItemData->pszText);
    15681493          }
    15691494
    1570           lpItem->pszText = LPSTR_TEXTCALLBACKW;
    1571         }
    1572         else
     1495          lpItemData->pszText = LPSTR_TEXTCALLBACKW;
     1496        } else
    15731497        {
    1574           if (lpItem->pszText == LPSTR_TEXTCALLBACKW)
     1498          if (lpItemData->pszText == LPSTR_TEXTCALLBACKW)
    15751499          {
    1576             lpItem->pszText = NULL;
     1500            lpItemData->pszText = NULL;
    15771501          }
    15781502
    1579           bResult = Str_SetPtrW(&lpItem->pszText, lpLVItem->pszText);
     1503          bResult = Str_SetPtrW(&lpItemData->pszText,lpLVItem->pszText);
    15801504        }
    15811505      } else //!unicode
     
    15831507        if ((LPSTR)lpLVItem->pszText == LPSTR_TEXTCALLBACKA)
    15841508        {
    1585           if ((infoPtr->dwStyle & LVS_SORTASCENDING) || (infoPtr->dwStyle & LVS_SORTDESCENDING))
     1509          if (!lpItemData->iSubItem && ((infoPtr->dwStyle & LVS_SORTASCENDING) || (infoPtr->dwStyle & LVS_SORTDESCENDING)))
    15861510          {
    15871511            return FALSE;
    15881512          }
    15891513
    1590           if ((lpItem->pszText != NULL) &&
    1591               (lpItem->pszText != LPSTR_TEXTCALLBACKW))
     1514          if (lpItemData->pszText && (lpItemData->pszText != LPSTR_TEXTCALLBACKW))
    15921515          {
    1593             COMCTL32_Free(lpItem->pszText);
     1516            COMCTL32_Free(lpItemData->pszText);
    15941517          }
    15951518
    1596           lpItem->pszText = LPSTR_TEXTCALLBACKW;
    1597         }
    1598         else
     1519          lpItemData->pszText = LPSTR_TEXTCALLBACKW;
     1520        } else
    15991521        {
    16001522          INT len;
    16011523
    1602           if (lpItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(lpItem->pszText);
    1603           len = (lpLVItem->pszText != NULL) ? lstrlenA((LPSTR)lpLVItem->pszText):0;
     1524          if (lpItemData->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(lpItemData->pszText);
     1525          len = lpLVItem->pszText ? lstrlenA((LPSTR)lpLVItem->pszText):0;
    16041526
    16051527          if (len > 0)
    16061528          {
    16071529            len++;
    1608             lpItem->pszText = (LPWSTR)COMCTL32_Alloc(len*sizeof(WCHAR));
    1609             lstrcpyAtoW(lpItem->pszText,(LPSTR)lpLVItem->pszText);
    1610           } else lpItem->pszText = NULL;
     1530            lpItemData->pszText = (LPWSTR)COMCTL32_Alloc(len*sizeof(WCHAR));
     1531            lstrcpyAtoW(lpItemData->pszText,(LPSTR)lpLVItem->pszText);
     1532          } else lpItemData->pszText = NULL;
    16111533
    16121534          bResult = TRUE;
     
    16211543/***
    16221544 * DESCRIPTION:
    1623  * Initializes subitem attributes.
    1624  *
    1625  * NOTE: The documentation specifies that the operation fails if the user
    1626  * tries to set the indent of a subitem.
    1627  *
    1628  * PARAMETER(S):
    1629  * [I] HWND : window handle
    1630  * [O] LISTVIEW_SUBITEM *: destination subitem
    1631  * [I] LPLVITEM : source subitem
    1632  *
    1633  * RETURN:
    1634  *   SUCCCESS : TRUE
    1635  *   FAILURE : FALSE
    1636  */
    1637 static BOOL LISTVIEW_InitSubItem(HWND hwnd,LISTVIEW_SUBITEM *lpSubItem,LPLVITEMW lpLVItem,BOOL unicode)
    1638 {
    1639   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    1640   BOOL bResult = FALSE;
    1641 
    1642   if ((lpSubItem != NULL) && (lpLVItem != NULL))
    1643   {
    1644     if (!(lpLVItem->mask & LVIF_INDENT))
    1645     {
    1646       bResult = TRUE;
    1647       ZeroMemory(lpSubItem,sizeof(LISTVIEW_SUBITEM));
    1648 
    1649       lpSubItem->iSubItem = lpLVItem->iSubItem;
    1650 
    1651       if (lpLVItem->mask & LVIF_IMAGE)
    1652         lpSubItem->iImage = lpLVItem->iImage;
    1653 
    1654       if (lpLVItem->mask & LVIF_TEXT)
    1655       {
    1656         if (unicode)
    1657         {
    1658           if (lpLVItem->pszText == LPSTR_TEXTCALLBACKW)
    1659           {
    1660             if ((infoPtr->dwStyle & LVS_SORTASCENDING) || (infoPtr->dwStyle & LVS_SORTDESCENDING))
    1661               return FALSE;
    1662 
    1663             if ((lpSubItem->pszText != NULL) && (lpSubItem->pszText != LPSTR_TEXTCALLBACKW))
    1664               COMCTL32_Free(lpSubItem->pszText);
    1665 
    1666             lpSubItem->pszText = LPSTR_TEXTCALLBACKW;
    1667           } else
    1668           {
    1669             if (lpSubItem->pszText == LPSTR_TEXTCALLBACKW)
    1670               lpSubItem->pszText = NULL;
    1671 
    1672             bResult = Str_SetPtrW(&lpSubItem->pszText,lpLVItem->pszText);
    1673           }
    1674         } else //!unicode
    1675         {
    1676           if ((LPSTR)lpLVItem->pszText == LPSTR_TEXTCALLBACKA)
    1677           {
    1678             if ((infoPtr->dwStyle & LVS_SORTASCENDING) || (infoPtr->dwStyle & LVS_SORTDESCENDING))
    1679               return FALSE;
    1680 
    1681             if ((lpSubItem->pszText != NULL) && (lpSubItem->pszText != LPSTR_TEXTCALLBACKW))
    1682               COMCTL32_Free(lpSubItem->pszText);
    1683 
    1684             lpSubItem->pszText = LPSTR_TEXTCALLBACKW;
    1685           } else
    1686           {
    1687             INT len;
    1688 
    1689             if (lpSubItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(lpSubItem->pszText);
    1690             len = lpLVItem->pszText ? lstrlenA((LPSTR)lpLVItem->pszText):0;
    1691 
    1692             if (len > 0)
    1693             {
    1694               len++;
    1695               lpSubItem->pszText = (LPWSTR)COMCTL32_Alloc(len*sizeof(WCHAR));
    1696               lstrcpyAtoW(lpSubItem->pszText,(LPSTR)lpLVItem->pszText);
    1697             } else lpSubItem->pszText = NULL;
    1698 
    1699             bResult = TRUE;
    1700           }
    1701         }
    1702       }
    1703     }
    1704   }
    1705 
    1706   return bResult;
    1707 }
    1708 
    1709 /***
    1710  * DESCRIPTION:
    1711  * Adds a subitem at a given position (column index).
    1712  *
    1713  * PARAMETER(S):
    1714  * [I] HWND : window handle
    1715  * [I] LPLVITEM : new subitem atttributes
     1545 * Finds the dpa insert position (array index).
     1546 *
     1547 * PARAMETER(S):
     1548 * [I] HWND : window handle
     1549 * [I] INT : subitem index
    17161550 *
    17171551 * RETURN:
     
    17191553 *   FAILURE : FALSE
    17201554 */
    1721 static BOOL LISTVIEW_AddSubItem(HWND hwnd, LPLVITEMW lpLVItem,BOOL unicode)
    1722 {
    1723   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    1724   LISTVIEW_SUBITEM *lpSubItem = NULL;
    1725   BOOL bResult = FALSE;
    1726   HDPA hdpaSubItems;
    1727   INT nPosition, nItem;
    1728 
    1729   if (lpLVItem != NULL)
    1730   {
    1731     hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
    1732     if (hdpaSubItems != NULL)
    1733     {
    1734       lpSubItem = (LISTVIEW_SUBITEM *)COMCTL32_Alloc(sizeof(LISTVIEW_SUBITEM));
    1735       if (lpSubItem != NULL)
    1736       {
    1737         if (LISTVIEW_InitSubItem(hwnd, lpSubItem, lpLVItem,unicode) != FALSE)
    1738         {
    1739           nPosition = LISTVIEW_FindInsertPosition(hdpaSubItems,
    1740                                                   lpSubItem->iSubItem);
    1741           nItem = DPA_InsertPtr(hdpaSubItems, nPosition, lpSubItem);
    1742           if (nItem != -1)
    1743           {
    1744             bResult = TRUE;
    1745           }
    1746         }
    1747       }
    1748     }
    1749   }
    1750 
    1751   /* cleanup if unsuccessful */
    1752   if ((bResult == FALSE) && (lpSubItem != NULL))
    1753   {
    1754     COMCTL32_Free(lpSubItem);
    1755   }
    1756 
    1757   return bResult;
    1758 }
    1759 
    1760 /***
    1761  * DESCRIPTION:
    1762  * Finds the dpa insert position (array index).
     1555static INT LISTVIEW_FindInsertPosition(HDPA hdpaSubItems,INT nSubItem)
     1556{
     1557  LISTVIEW_ITEMDATA *lpItemData;
     1558  INT i;
     1559
     1560  for (i = 1; i < hdpaSubItems->nItemCount; i++)
     1561  {
     1562    lpItemData = (LISTVIEW_ITEMDATA*)DPA_GetPtr(hdpaSubItems,i);
     1563    if (lpItemData)
     1564    {
     1565      if (lpItemData->iSubItem > nSubItem)
     1566      {
     1567        return i;
     1568      }
     1569    }
     1570  }
     1571
     1572  return hdpaSubItems->nItemCount;
     1573}
     1574
     1575/***
     1576 * DESCRIPTION:
     1577 * Retrieves a listview subitem at a given position (column index).
    17631578 *
    17641579 * PARAMETER(S):
     
    17701585 *   FAILURE : FALSE
    17711586 */
    1772 static INT LISTVIEW_FindInsertPosition(HDPA hdpaSubItems, INT nSubItem)
    1773 {
    1774   LISTVIEW_SUBITEM *lpSubItem;
     1587static LISTVIEW_ITEMDATA* LISTVIEW_GetItemData(HDPA hdpaSubItems,INT nSubItem)
     1588{
     1589  LISTVIEW_ITEMDATA *lpItemData;
    17751590  INT i;
    17761591
    1777   for (i = 1; i < hdpaSubItems->nItemCount; i++)
    1778   {
    1779     lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
    1780     if (lpSubItem != NULL)
    1781     {
    1782       if (lpSubItem->iSubItem > nSubItem)
    1783       {
    1784         return i;
    1785       }
    1786     }
    1787   }
    1788 
    1789   return hdpaSubItems->nItemCount;
    1790 }
    1791 
    1792 /***
    1793  * DESCRIPTION:
    1794  * Retrieves a listview subitem at a given position (column index).
    1795  *
    1796  * PARAMETER(S):
    1797  * [I] HWND : window handle
    1798  * [I] INT : subitem index
    1799  *
    1800  * RETURN:
    1801  *   SUCCESS : TRUE
    1802  *   FAILURE : FALSE
    1803  */
    1804 static LISTVIEW_SUBITEM* LISTVIEW_GetSubItem(HDPA hdpaSubItems, INT nSubItem)
    1805 {
    1806   LISTVIEW_SUBITEM *lpSubItem;
    1807   INT i;
    1808 
    1809   for (i = 1; i < hdpaSubItems->nItemCount; i++)
    1810   {
    1811     lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
    1812     if (lpSubItem != NULL)
    1813     {
    1814       if (lpSubItem->iSubItem == nSubItem)
    1815       {
    1816         return lpSubItem;
    1817       }
    1818       else if (lpSubItem->iSubItem > nSubItem)
     1592  for (i = 0;i < hdpaSubItems->nItemCount;i++)
     1593  {
     1594    lpItemData = (LISTVIEW_ITEMDATA*)DPA_GetPtr(hdpaSubItems,i);
     1595    if (lpItemData)
     1596    {
     1597      if (lpItemData->iSubItem == nSubItem)
     1598      {
     1599        return lpItemData;
     1600      } else if (lpItemData->iSubItem > nSubItem)
    18191601      {
    18201602        return NULL;
     
    18951677}
    18961678
     1679static VOID LISTVIEW_DrawHottrackLine(HDC hdc,RECT *rect)
     1680{
     1681  HPEN hPen,hOldPen;
     1682  INT rop;
     1683
     1684  rop = SetROP2(hdc,R2_XORPEN);
     1685  hPen = CreatePen(PS_SOLID,2,RGB(0,0,0));
     1686  hOldPen = SelectObject(hdc,hPen);
     1687
     1688  MoveToEx(hdc,rect->left,rect->bottom-1,NULL);
     1689  LineTo(hdc,rect->right,rect->bottom-1);
     1690
     1691  DeleteObject(hPen);
     1692  SelectObject(hdc,hOldPen);
     1693  SetROP2(hdc,rop);
     1694}
    18971695
    18981696/***
     
    20001798    SetTextColor(hdc, infoPtr->clrText);
    20011799  }
     1800  if (nItem == infoPtr->nHotItem)
     1801    LISTVIEW_DrawHottrackLine(hdc,&rcItem);
     1802
    20021803  if (lvItem.mustFree) COMCTL32_Free(lvItem.header.pszText);
    20031804}
     
    21571958      {
    21581959        if (j == 0)
    2159           LISTVIEW_DrawItem(hwnd, hdc, nItem, rcItem);
     1960          LISTVIEW_DrawItem(hwnd,hdc,nItem,rcItem);
    21601961        else
    2161           LISTVIEW_DrawSubItem(hwnd, hdc, nItem, j, rcItem);
     1962          LISTVIEW_DrawSubItem(hwnd,hdc,nItem,j,rcItem);
    21621963      }
    21631964    }
     
    24302231 * Returns a DWORD. The width in the low word and the height in high word.
    24312232 */
    2432 static LRESULT LISTVIEW_ApproximateViewRect(HWND hwnd, INT nItemCount,
    2433                                             WORD wWidth, WORD wHeight)
     2233static LRESULT LISTVIEW_ApproximateViewRect(HWND hwnd,INT nItemCount,WORD wWidth,WORD wHeight)
    24342234{
    24352235  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     
    24822282
    24832283    dwViewRect = MAKELONG(wWidth, wHeight);
    2484   }
    2485   else if (infoPtr->uView == LVS_REPORT)
    2486   {
    2487     /* TO DO */
    2488   }
    2489   else if (infoPtr->uView == LVS_SMALLICON)
    2490   {
    2491     /* TO DO */
    2492   }
    2493   else if (infoPtr->uView == LVS_ICON)
    2494   {
    2495     /* TO DO */
     2284  } else if (infoPtr->uView == LVS_REPORT)
     2285  {
     2286    wHeight = infoPtr->nItemHeight;
     2287    wWidth = max(infoPtr->nItemWidth,100);
     2288
     2289    dwViewRect = MAKELONG(wWidth,infoPtr->rcList.top+nItemCount*wHeight);
     2290  } else if ((infoPtr->uView == LVS_SMALLICON) || (infoPtr->uView == LVS_ICON))
     2291  {
     2292    INT lines,itemW,itemH;
     2293
     2294    if (wWidth == 0xFFFF)
     2295      wWidth = infoPtr->rcList.right-infoPtr->rcList.left;
     2296
     2297    itemH = infoPtr->nItemHeight;
     2298    itemW = max(infoPtr->nItemWidth,32);
     2299
     2300    nColumnCount = wWidth/itemW;
     2301    lines =  nItemCount/nColumnCount;
     2302    if (nItemCount%nColumnCount) lines++;
     2303
     2304    dwViewRect = MAKELONG(nColumnCount*itemW,lines*itemH);
    24962305  }
    24972306
     
    25912400{
    25922401  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    2593   LISTVIEW_ITEM *lpItem;
    2594   LISTVIEW_SUBITEM *lpSubItem;
    25952402  NMLISTVIEW nmlv;
    25962403  BOOL bSuppress;
     
    25982405  INT i;
    25992406  INT j;
    2600   HDPA hdpaSubItems;
    26012407
    26022408  if (GETITEMCOUNT(infoPtr) > 0)
     
    26142420    for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
    26152421    {
    2616       hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, i);
    2617       if (hdpaSubItems != NULL)
    2618       {
    2619         for (j = 1; j < hdpaSubItems->nItemCount; j++)
     2422      LISTVIEW_ITEM *lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(infoPtr->hdpaItems,i);
     2423
     2424      if (lpItem)
     2425      {
     2426        for (j = 0;j < lpItem->hdpaSubItems->nItemCount;j++)
    26202427        {
    2621           lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, j);
    2622           if (lpSubItem != NULL)
     2428          LISTVIEW_ITEMDATA *lpItemData = (LISTVIEW_ITEMDATA*)DPA_GetPtr(lpItem->hdpaSubItems,j);
     2429          if (lpItemData)
    26232430          {
    2624             /* free subitem string */
    2625             if ((lpSubItem->pszText != NULL) &&
    2626                 (lpSubItem->pszText != LPSTR_TEXTCALLBACKW))
     2431            /* free item string */
     2432            if (lpItemData->pszText && (lpItemData->pszText != LPSTR_TEXTCALLBACKW))
    26272433            {
    2628               COMCTL32_Free(lpSubItem->pszText);
     2434              COMCTL32_Free(lpItemData->pszText);
    26292435            }
    26302436
    26312437            /* free subitem */
    2632             COMCTL32_Free(lpSubItem);
     2438            COMCTL32_Free(lpItemData);
    26332439          }
    26342440        }
    26352441
    2636         lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
    2637         if (lpItem != NULL)
     2442        if (bSuppress == FALSE)
    26382443        {
    2639           if (bSuppress == FALSE)
    2640           {
    2641             /* send LVN_DELETEITEM notification */
    2642             nmlv.iItem = i;
    2643             nmlv.lParam = lpItem->lParam;
    2644             sendNotify(hwnd,LVN_DELETEITEM,&nmlv.hdr);
    2645           }
    2646 
    2647           /* free item string */
    2648           if ((lpItem->pszText != NULL) &&
    2649               (lpItem->pszText != LPSTR_TEXTCALLBACKW))
    2650           {
    2651             COMCTL32_Free(lpItem->pszText);
    2652           }
    2653 
    2654           /* free item */
    2655           COMCTL32_Free(lpItem);
     2444          /* send LVN_DELETEITEM notification */
     2445          nmlv.iItem = i;
     2446          nmlv.lParam = lpItem->lParam;
     2447          sendNotify(hwnd,LVN_DELETEITEM,&nmlv.hdr);
    26562448        }
    26572449
    2658         DPA_Destroy(hdpaSubItems);
     2450        /* free item */
     2451        DPA_Destroy(lpItem->hdpaSubItems);
     2452        COMCTL32_Free(lpItem);
    26592453      }
    26602454    }
     
    27412535  NMLISTVIEW nmlv;
    27422536  BOOL bResult = FALSE;
    2743   HDPA hdpaSubItems;
    27442537  LISTVIEW_ITEM *lpItem;
    2745   LISTVIEW_SUBITEM *lpSubItem;
    27462538  INT i;
    27472539
     
    27512543    ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
    27522544
    2753     hdpaSubItems = (HDPA)DPA_DeletePtr(infoPtr->hdpaItems, nItem);
    2754     if (hdpaSubItems)
    2755     {
    2756       for (i = 1; i < hdpaSubItems->nItemCount; i++)
    2757       {
    2758         lpSubItem = (LISTVIEW_SUBITEM *)DPA_GetPtr(hdpaSubItems, i);
    2759         if (lpSubItem != NULL)
     2545    lpItem = (LISTVIEW_ITEM*)DPA_DeletePtr(infoPtr->hdpaItems,nItem);
     2546    if (lpItem)
     2547    {
     2548      for (i = 0;i < lpItem->hdpaSubItems->nItemCount;i++)
     2549      {
     2550        LISTVIEW_ITEMDATA *lpItemData = (LISTVIEW_ITEMDATA*)DPA_GetPtr(lpItem->hdpaSubItems,i);
     2551
     2552        if (lpItemData)
    27602553        {
    27612554          /* free item string */
    2762           if ((lpSubItem->pszText != NULL) &&
    2763               (lpSubItem->pszText != LPSTR_TEXTCALLBACKW))
     2555          if (lpItemData->pszText && (lpItemData->pszText != LPSTR_TEXTCALLBACKW))
    27642556          {
    2765             COMCTL32_Free(lpSubItem->pszText);
     2557            COMCTL32_Free(lpItemData->pszText);
    27662558          }
    27672559
    27682560          /* free item */
    2769           COMCTL32_Free(lpSubItem);
     2561          COMCTL32_Free(lpItemData);
    27702562        }
    27712563      }
    27722564
    2773       lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
    2774       if (lpItem)
    2775       {
    2776         //remove from selection list
    2777         DPA_DeletePtr(infoPtr->hdpaSelItems,DPA_GetPtrIndex(infoPtr->hdpaSelItems,lpItem));
    2778 
    2779         /* send LVN_DELETEITEM notification */
    2780         nmlv.iItem = nItem;
    2781         nmlv.lParam = lpItem->lParam;
    2782         sendNotify(hwnd,LVN_DELETEITEM,&nmlv.hdr);
    2783 
    2784         /* free item string */
    2785         if ((lpItem->pszText != NULL) &&
    2786             (lpItem->pszText != LPSTR_TEXTCALLBACKW))
    2787         {
    2788           COMCTL32_Free(lpItem->pszText);
    2789         }
    2790 
    2791         /* free item */
    2792         COMCTL32_Free(lpItem);
    2793       }
    2794 
    2795       bResult = DPA_Destroy(hdpaSubItems);
     2565      //remove from selection list
     2566      DPA_DeletePtr(infoPtr->hdpaSelItems,DPA_GetPtrIndex(infoPtr->hdpaSelItems,lpItem));
     2567
     2568      /* send LVN_DELETEITEM notification */
     2569      nmlv.iItem = nItem;
     2570      nmlv.lParam = lpItem->lParam;
     2571      sendNotify(hwnd,LVN_DELETEITEM,&nmlv.hdr);
     2572
     2573      /* free item */
     2574      bResult = DPA_Destroy(lpItem->hdpaSubItems);
     2575      COMCTL32_Free(lpItem);
    27962576    }
    27972577
     
    28642644  NMLVDISPINFOW dispInfo;
    28652645  LISTVIEW_ITEM *lpItem;
     2646  LISTVIEW_ITEMDATA *lpItemData;
    28662647  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    2867   HDPA hdpaSubItems;
    28682648  BOOL bUpdateItemText;
    28692649  WCHAR* textW = NULL;
     
    28712651  ZeroMemory(&dispInfo, sizeof(NMLVDISPINFOW));
    28722652
    2873   if (!(hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem)))
     2653  if (!(lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(infoPtr->hdpaItems,nItem)))
    28742654    return FALSE;
    28752655
    2876   if (!(lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0)))
     2656  if (!(lpItemData = LISTVIEW_GetItemData(lpItem->hdpaSubItems,0)))
    28772657    return FALSE;
    28782658
     
    28992679    }
    29002680  }
    2901   dispInfo.item.iImage = lpItem->iImage;
     2681  dispInfo.item.iImage = lpItemData->iImage;
    29022682  dispInfo.item.lParam = lpItem->lParam;
    29032683  infoPtr->hwndEdit = 0;
     
    29232703    if ((lvItem.unicode && (lstrcmpAtoW(pszText,lvItem.header.pszText) != 0)) || (!lvItem.unicode && (lstrcmpA((LPSTR)lvItem.header.pszText,pszText) != 0)))
    29242704    {
    2925       if (lpItem->pszText != LPSTR_TEXTCALLBACKW)
     2705      if (lpItemData->pszText != LPSTR_TEXTCALLBACKW)
    29262706      {
    29272707        if (isUnicodeNotify(&infoPtr->header))
    2928           Str_SetPtrW(&lpItem->pszText,textW);
     2708          Str_SetPtrW(&lpItemData->pszText,textW);
    29292709        else
    29302710        {
    2931           COMCTL32_Free(lpItem->pszText);
    2932           lpItem->pszText = HEAP_strdupAtoW(GetProcessHeap(),0,pszText);
     2711          COMCTL32_Free(lpItemData->pszText);
     2712          lpItemData->pszText = HEAP_strdupAtoW(GetProcessHeap(),0,pszText);
    29332713        }
    29342714      } else
     
    29792759  RECT rect;
    29802760  LISTVIEW_ITEM *lpItem;
     2761  LISTVIEW_ITEMDATA *lpItemData;
    29812762  HWND hedit;
    29822763  HINSTANCE hinst = GetWindowLongA(hwnd, GWL_HINSTANCE);
    2983   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    2984   HDPA hdpaSubItems;
     2764  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    29852765  LVITEMW lvItem;
    29862766  CHAR* textA = NULL;
     
    29982778
    29992779  ZeroMemory(&dispInfo, sizeof(NMLVDISPINFOA));
    3000   if (NULL == (hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem)))
     2780  if (!(lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(infoPtr->hdpaItems,nItem)))
    30012781    return 0;
    30022782
    3003   if (NULL == (lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0)))
     2783  if (!(lpItemData = LISTVIEW_GetItemData(lpItem->hdpaSubItems,0)))
    30042784    return 0;
    30052785
     
    30292809  dispInfo.item.stateMask = 0;
    30302810  dispInfo.item.pszText = lvItem.pszText;
    3031   dispInfo.item.iImage = lpItem->iImage;
     2811  dispInfo.item.iImage = lpItemData->iImage;
    30322812  dispInfo.item.lParam = lpItem->lParam;
    30332813
     
    34523232 *   FAILURE : FALSE`
    34533233 */
    3454 /* static LRESULT LISTVIEW_GetBkImage(HWND hwnd, LPLVBKIMAGE lpBkImage)   */
    3455 /* {   */
    3456 /*   FIXME (listview, "empty stub!\n"); */
    3457 /*   return FALSE;   */
    3458 /* }   */
     3234static LRESULT LISTVIEW_GetBkImage(HWND hwnd,WPARAM wParam,LPARAM lParam,BOOL unicode)
     3235{
     3236  LPLVBKIMAGEW plvbki = (LPLVBKIMAGEW)lParam;
     3237
     3238  if (!plvbki) return FALSE;
     3239
     3240  //todo: use COM OLE interface
     3241
     3242  return FALSE;
     3243}
    34593244
    34603245/***
     
    35773362static LRESULT LISTVIEW_GetColumnOrderArray(HWND hwnd, INT iCount, LPINT lpiArray)
    35783363{
    3579 /*  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd); */
    3580     INT i;
    3581 
    3582     if (!lpiArray)
    3583         return FALSE;
    3584 
    3585     /* little hack */
    3586     for (i = 0; i < iCount; i++)
    3587         lpiArray[i] = i;
    3588 
    3589     return TRUE;
     3364  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
     3365
     3366  return Header_GetOrderArray(infoPtr->hwndHeader,iCount,lpiArray);
    35903367}
    35913368
     
    36773454static LRESULT LISTVIEW_GetExtendedListViewStyle(HWND hwnd)
    36783455{
    3679     LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    3680 
    3681     /* make sure we can get the listview info */
    3682     if (!infoPtr)
    3683       return (0);
    3684     return (infoPtr->dwExStyle);
     3456  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     3457
     3458  return (infoPtr->dwExStyle);
    36853459}
    36863460
     
    37023476}
    37033477
    3704 /* LISTVIEW_GetHotCursor */
    3705 /* LISTVIEW_GetHotItem */
     3478static LRESULT LISTVIEW_GetHotCursor(HWND hwnd,WPARAM wParam,LPARAM lParam)
     3479{
     3480  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     3481
     3482  return (LRESULT)infoPtr->hHotCursor;
     3483}
     3484
    37063485/* LISTVIEW_GetHoverTime */
    37073486
     
    37613540  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    37623541  BOOL bResult = FALSE;
    3763   NMLVDISPINFOW dispInfo;
    37643542
    37653543  if (lpLVItem)
     
    37673545    if ((lpLVItem->iItem >= 0) && (lpLVItem->iItem < GETITEMCOUNT(infoPtr)))
    37683546    {
    3769       HDPA hdpaSubItems;
    3770 
    3771       ZeroMemory(&dispInfo,sizeof(NMLVDISPINFOW));
    3772       hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems,lpLVItem->iItem);
    3773       if (hdpaSubItems)
    3774       {
    3775         LISTVIEW_ITEM *lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(hdpaSubItems,0);
    3776 
    3777         if (lpItem)
     3547      LISTVIEW_ITEM *lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(infoPtr->hdpaItems,lpLVItem->iItem);
     3548
     3549      if (lpItem)
     3550      {
     3551        LISTVIEW_ITEMDATA *lpItemData = LISTVIEW_GetItemData(lpItem->hdpaSubItems,lpLVItem->iSubItem);
     3552
     3553        if (lpItemData)
    37783554        {
     3555          NMLVDISPINFOW dispInfo;
     3556          LPSTR textA = NULL;
     3557          LPWSTR textW = NULL;
     3558
     3559          ZeroMemory(&dispInfo,sizeof(NMLVDISPINFOW));
    37793560          bResult = TRUE;
    3780           if (lpLVItem->iSubItem == 0)
     3561
     3562          if ((lpItemData->iImage == I_IMAGECALLBACK) && (lpLVItem->mask & LVIF_IMAGE))
     3563            dispInfo.item.mask |= LVIF_IMAGE;
     3564
     3565          if ((lpItemData->pszText == LPSTR_TEXTCALLBACKW) && (lpLVItem->mask & LVIF_TEXT))
    37813566          {
    3782             LPSTR textA = NULL;
    3783             LPWSTR textW = NULL;
    3784 
    3785             if ((lpItem->iImage == I_IMAGECALLBACK) && (lpLVItem->mask & LVIF_IMAGE))
    3786               dispInfo.item.mask |= LVIF_IMAGE;
    3787 
    3788             if ((lpItem->pszText == LPSTR_TEXTCALLBACKW) && (lpLVItem->mask & LVIF_TEXT))
     3567            dispInfo.item.mask |= LVIF_TEXT;
     3568            dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
     3569            if (isUnicodeNotify(&infoPtr->header))
    37893570            {
    3790               dispInfo.item.mask |= LVIF_TEXT;
    3791               dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
     3571              textW = (WCHAR*)COMCTL32_Alloc(dispInfo.item.cchTextMax*sizeof(WCHAR));
     3572              if (textW) textW[0] = 0;
     3573              dispInfo.item.pszText = textW;
     3574            } else
     3575            {
     3576              textA = (CHAR*)COMCTL32_Alloc(dispInfo.item.cchTextMax*sizeof(CHAR));
     3577              if (textA) textA[0] = 0;
     3578              dispInfo.item.pszText = (LPWSTR)textA;
     3579            }
     3580          }
     3581
     3582          if ((infoPtr->uCallbackMask != 0) && (lpLVItem->mask & LVIF_STATE))
     3583          {
     3584            dispInfo.item.mask |= LVIF_STATE;
     3585            dispInfo.item.stateMask = infoPtr->uCallbackMask;
     3586          }
     3587
     3588          if (dispInfo.item.mask != 0)
     3589          {
     3590            dispInfo.item.iItem = lpLVItem->iItem;
     3591            dispInfo.item.iSubItem = lpLVItem->iSubItem;
     3592            dispInfo.item.lParam = lpItem->lParam;
     3593            sendNotify(hwnd,isUnicodeNotify(&infoPtr->header) ? LVN_GETDISPINFOW:LVN_GETDISPINFOA,&dispInfo.hdr);
     3594          }
     3595
     3596          if (dispInfo.item.mask & LVIF_IMAGE)
     3597          {
     3598            lpLVItem->iImage = dispInfo.item.iImage;
     3599            if (dispInfo.item.mask & LVIF_DI_SETITEM)
     3600              lpItemData->iImage = dispInfo.item.iImage;
     3601          } else if (lpLVItem->mask & LVIF_IMAGE)
     3602              lpLVItem->iImage = lpItemData->iImage;
     3603
     3604          if (dispInfo.item.mask & LVIF_TEXT)
     3605          {
     3606            if (dispInfo.item.mask & LVIF_DI_SETITEM)
     3607            {
    37923608              if (isUnicodeNotify(&infoPtr->header))
    37933609              {
    3794                 textW = (WCHAR*)COMCTL32_Alloc(dispInfo.item.cchTextMax*sizeof(WCHAR));
    3795                 if (textW) textW[0] = 0;
    3796                 dispInfo.item.pszText = textW;
     3610                Str_SetPtrW(&lpItemData->pszText,dispInfo.item.pszText);
    37973611              } else
    37983612              {
    3799                 textA = (CHAR*)COMCTL32_Alloc(dispInfo.item.cchTextMax*sizeof(CHAR));
    3800                 if (textA) textA[0] = 0;
    3801                 dispInfo.item.pszText = (LPWSTR)textA;
     3613                INT len = dispInfo.item.pszText ? lstrlenA((LPSTR)dispInfo.item.pszText):0;
     3614
     3615                if (lpItemData->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(lpItemData->pszText);
     3616                if (len > 0)
     3617                {
     3618                  len++;
     3619                  lpItemData->pszText = (WCHAR*)COMCTL32_Alloc(len*sizeof(WCHAR));
     3620                  lstrcpyAtoW(lpItemData->pszText,(LPSTR)dispInfo.item.pszText);
     3621                } else lpItemData->pszText = NULL;
    38023622              }
    38033623            }
    3804 
    3805             if ((infoPtr->uCallbackMask != 0) && (lpLVItem->mask & LVIF_STATE))
     3624            /* Make sure the source string is valid */
     3625            if (!dispInfo.item.pszText)
    38063626            {
    3807               dispInfo.item.mask |= LVIF_STATE;
    3808               dispInfo.item.stateMask = infoPtr->uCallbackMask;
    3809             }
    3810 
    3811             if (dispInfo.item.mask != 0)
     3627              if (!internal)
     3628              {
     3629                if (unicode)
     3630                  lpLVItem->pszText[0] = L'\0';
     3631                else
     3632                  ((LPSTR)lpLVItem->pszText)[0] = '\0';
     3633              } else
     3634              {
     3635                lpLVItem->pszText = NULL;
     3636                ((LPLVINTERNALITEMW)lpLVItem)->unicode = unicode;
     3637              }
     3638            } else
    38123639            {
    3813               dispInfo.item.iItem = lpLVItem->iItem;
    3814               dispInfo.item.iSubItem = 0;
    3815               dispInfo.item.lParam = lpItem->lParam;
    3816               sendNotify(hwnd,isUnicodeNotify(&infoPtr->header) ? LVN_GETDISPINFOW:LVN_GETDISPINFOA,&dispInfo.hdr);
    3817             }
    3818 
    3819             if (dispInfo.item.mask & LVIF_IMAGE)
    3820             {
    3821               lpLVItem->iImage = dispInfo.item.iImage;
    3822               if (dispInfo.item.mask & LVIF_DI_SETITEM)
    3823                 lpItem->iImage = dispInfo.item.iImage;
    3824             } else if (lpLVItem->mask & LVIF_IMAGE)
    3825                 lpLVItem->iImage = lpItem->iImage;
    3826 
    3827             if (dispInfo.item.mask & LVIF_TEXT)
    3828             {
    3829               if (dispInfo.item.mask & LVIF_DI_SETITEM)
     3640              if (internal)
    38303641              {
     3642                lpLVItem->pszText = dispInfo.item.pszText;
    38313643                if (isUnicodeNotify(&infoPtr->header))
    38323644                {
    3833                   Str_SetPtrW(&lpItem->pszText,dispInfo.item.pszText);
     3645                  ((LPLVINTERNALITEMW)lpLVItem)->unicode = TRUE;
     3646                  if (textW == dispInfo.item.pszText)
     3647                  {
     3648                    ((LPLVINTERNALITEMW)lpLVItem)->mustFree = TRUE;
     3649                    textW = NULL;
     3650                  } else ((LPLVINTERNALITEMW)lpLVItem)->mustFree = FALSE;
    38343651                } else
    38353652                {
    3836                   INT len = dispInfo.item.pszText ? lstrlenA((LPSTR)dispInfo.item.pszText):0;
    3837 
    3838                   if (lpItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(lpItem->pszText);
    3839                   if (len > 0)
     3653                  ((LPLVINTERNALITEMW)lpLVItem)->unicode = FALSE;
     3654                  if (textA == (LPSTR)dispInfo.item.pszText)
    38403655                  {
    3841                     len++;
    3842                     lpItem->pszText = (WCHAR*)COMCTL32_Alloc(len*sizeof(WCHAR));
    3843                     lstrcpyAtoW(lpItem->pszText,(LPSTR)dispInfo.item.pszText);
    3844                   } else lpItem->pszText = NULL;
    3845                 }
    3846               }
    3847               /* Make sure the source string is valid */
    3848               if (dispInfo.item.pszText == NULL)
    3849               {
    3850                 if (!internal)
    3851                 {
    3852                   if (unicode)
    3853                     lpLVItem->pszText[0] = L'\0';
    3854                   else
    3855                     ((LPSTR)lpLVItem->pszText)[0] = '\0';
    3856                 } else
    3857                 {
    3858                   lpLVItem->pszText = NULL;
    3859                   ((LPLVINTERNALITEMW)lpLVItem)->unicode = unicode;
     3656                    ((LPLVINTERNALITEMW)lpLVItem)->mustFree = TRUE;
     3657                    textA = NULL;
     3658                  } else ((LPLVINTERNALITEMW)lpLVItem)->mustFree = FALSE;
    38603659                }
    38613660              } else
    38623661              {
    3863                 if (internal)
     3662                if (unicode)
    38643663                {
    3865                   lpLVItem->pszText = dispInfo.item.pszText;
    38663664                  if (isUnicodeNotify(&infoPtr->header))
    3867                   {
    3868                     ((LPLVINTERNALITEMW)lpLVItem)->unicode = TRUE;
    3869                     if (textW == dispInfo.item.pszText)
    3870                     {
    3871                       ((LPLVINTERNALITEMW)lpLVItem)->mustFree = TRUE;
    3872                       textW = NULL;
    3873                     } else ((LPLVINTERNALITEMW)lpLVItem)->mustFree = FALSE;
    3874                   } else
    3875                   {
    3876                     ((LPLVINTERNALITEMW)lpLVItem)->unicode = FALSE;
    3877                     if (textA == (LPSTR)dispInfo.item.pszText)
    3878                     {
    3879                       ((LPLVINTERNALITEMW)lpLVItem)->mustFree = TRUE;
    3880                       textA = NULL;
    3881                     } else ((LPLVINTERNALITEMW)lpLVItem)->mustFree = FALSE;
    3882                   }
     3665                    lstrcpynW(lpLVItem->pszText,dispInfo.item.pszText,lpLVItem->cchTextMax);
     3666                  else
     3667                    lstrcpynAtoW(lpLVItem->pszText,(LPSTR)dispInfo.item.pszText,lpLVItem->cchTextMax);
     3668                  lpLVItem->pszText[lpLVItem->cchTextMax-1] = L'\0';
    38833669                } else
    38843670                {
    3885                   if (unicode)
    3886                   {
    3887                     if (isUnicodeNotify(&infoPtr->header))
    3888                       lstrcpynW(lpLVItem->pszText,dispInfo.item.pszText,lpLVItem->cchTextMax);
    3889                     else
    3890                       lstrcpynAtoW(lpLVItem->pszText,(LPSTR)dispInfo.item.pszText,lpLVItem->cchTextMax);
    3891                     lpLVItem->pszText[lpLVItem->cchTextMax-1] = L'\0';
    3892                   } else
    3893                   {
    3894                     if (isUnicodeNotify(&infoPtr->header))
    3895                       lstrcpynWtoA((LPSTR)lpLVItem->pszText,dispInfo.item.pszText,lpLVItem->cchTextMax);
    3896                     else
    3897                       lstrcpynA((LPSTR)lpLVItem->pszText,(LPSTR)dispInfo.item.pszText,lpLVItem->cchTextMax);
    3898                     ((LPSTR)lpLVItem->pszText)[lpLVItem->cchTextMax-1] = '\0';
    3899                   }
    3900                 }
    3901               }
    3902             } else if (lpLVItem->mask & LVIF_TEXT)
    3903             {
    3904               if (lpItem->pszText != NULL)
    3905               {
    3906                 if (internal)
    3907                 {
    3908                   lpLVItem->pszText = lpItem->pszText;
    3909                   ((LPLVINTERNALITEMW)lpLVItem)->unicode = TRUE;
    3910                 } else
    3911                 {
    3912                   if (unicode)
    3913                   {
    3914                     lstrcpynW(lpLVItem->pszText,lpItem->pszText,lpLVItem->cchTextMax);
    3915                     lpLVItem->pszText[lpLVItem->cchTextMax-1] = L'\0';
    3916                   } else
    3917                   {
    3918                     lstrcpynWtoA((LPSTR)lpLVItem->pszText,lpItem->pszText,lpLVItem->cchTextMax);
    3919                     ((LPSTR)lpLVItem->pszText)[lpLVItem->cchTextMax-1] = '\0';
    3920                   }
    3921                 }
    3922               } else
    3923               {
    3924                 if (internal)
    3925                 {
    3926                   lpLVItem->pszText = NULL;
    3927                   ((LPLVINTERNALITEMW)lpLVItem)->unicode = unicode;
    3928                 } else
    3929                 {
    3930                   if (unicode)
    3931                     lpLVItem->pszText[0] = 0;
     3671                  if (isUnicodeNotify(&infoPtr->header))
     3672                    lstrcpynWtoA((LPSTR)lpLVItem->pszText,dispInfo.item.pszText,lpLVItem->cchTextMax);
    39323673                  else
    3933                     ((CHAR*)lpLVItem->pszText)[0] = 0;
     3674                    lstrcpynA((LPSTR)lpLVItem->pszText,(LPSTR)dispInfo.item.pszText,lpLVItem->cchTextMax);
     3675                  ((LPSTR)lpLVItem->pszText)[lpLVItem->cchTextMax-1] = '\0';
    39343676                }
    39353677              }
    39363678            }
    3937 
    3938             if (dispInfo.item.mask & LVIF_STATE)
     3679          } else if (lpLVItem->mask & LVIF_TEXT)
     3680          {
     3681            if (lpItemData->pszText)
    39393682            {
    3940               lpLVItem->state = lpItem->state;
    3941               lpLVItem->state &= ~dispInfo.item.stateMask;
    3942               lpLVItem->state |= (dispInfo.item.state &
    3943                                   dispInfo.item.stateMask);
    3944             } else if (lpLVItem->mask & LVIF_STATE)
    3945                 lpLVItem->state = lpItem->state & lpLVItem->stateMask;
    3946 
    3947             if (lpLVItem->mask & LVIF_PARAM)
    3948               lpLVItem->lParam = lpItem->lParam;
    3949 
    3950             if (lpLVItem->mask & LVIF_INDENT)
    3951               lpLVItem->iIndent = lpItem->iIndent;
    3952 
    3953             if (textA) COMCTL32_Free(textA);
    3954             if (textW) COMCTL32_Free(textW);
    3955           } else //SubItem
    3956           {
    3957             CHAR* textA = NULL;
    3958             WCHAR* textW = NULL;
    3959             LISTVIEW_SUBITEM *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems,lpLVItem->iSubItem);
    3960 
    3961             if (lpSubItem)
    3962             {
    3963               if ((lpSubItem->iImage == I_IMAGECALLBACK) && (lpLVItem->mask & LVIF_IMAGE))
    3964                 dispInfo.item.mask |= LVIF_IMAGE;
    3965 
    3966               if ((lpSubItem->pszText == LPSTR_TEXTCALLBACKW) && (lpLVItem->mask & LVIF_TEXT))
     3683              if (internal)
    39673684              {
    3968                 dispInfo.item.mask |= LVIF_TEXT;
    3969                 dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
    3970                 if (isUnicodeNotify(&infoPtr->header))
     3685                lpLVItem->pszText = lpItemData->pszText;
     3686                ((LPLVINTERNALITEMW)lpLVItem)->unicode = TRUE;
     3687              } else
     3688              {
     3689                if (unicode)
    39713690                {
    3972                   textW = (WCHAR*)COMCTL32_Alloc(dispInfo.item.cchTextMax*sizeof(WCHAR));
    3973                   if (textW) textW[0] = 0;
    3974                   dispInfo.item.pszText = textW;
     3691                  lstrcpynW(lpLVItem->pszText,lpItemData->pszText,lpLVItem->cchTextMax);
     3692                  lpLVItem->pszText[lpLVItem->cchTextMax-1] = L'\0';
    39753693                } else
    39763694                {
    3977                   textA = (CHAR*)COMCTL32_Alloc(dispInfo.item.cchTextMax*sizeof(CHAR));
    3978                   if (textA) textA[0] = 0;
    3979                   dispInfo.item.pszText = (LPWSTR)textA;
     3695                  lstrcpynWtoA((LPSTR)lpLVItem->pszText,lpItemData->pszText,lpLVItem->cchTextMax);
     3696                  ((LPSTR)lpLVItem->pszText)[lpLVItem->cchTextMax-1] = '\0';
    39803697                }
    39813698              }
    3982             } else //lpSubItem == NULL
     3699            } else
    39833700            {
    3984               if (lpLVItem->mask & LVIF_IMAGE)
    3985                 dispInfo.item.mask |= LVIF_IMAGE;
    3986 
    3987               if (lpLVItem->mask & LVIF_TEXT)
     3701              if (internal)
    39883702              {
    3989                 dispInfo.item.mask |= LVIF_TEXT;
    3990                 dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
    3991                 if (isUnicodeNotify(&infoPtr->header))
    3992                 {
    3993                   textW = (WCHAR*)COMCTL32_Alloc(dispInfo.item.cchTextMax*sizeof(WCHAR));
    3994                   if (textW) textW[0] = 0;
    3995                   dispInfo.item.pszText = textW;
    3996                 } else
    3997                 {
    3998                   textA = (CHAR*)COMCTL32_Alloc(dispInfo.item.cchTextMax*sizeof(CHAR));
    3999                   if (textA) textA[0] = 0;
    4000                   dispInfo.item.pszText = (LPWSTR)textA;
    4001                 }
     3703                lpLVItem->pszText = NULL;
     3704                ((LPLVINTERNALITEMW)lpLVItem)->unicode = unicode;
     3705              } else
     3706              {
     3707                if (unicode)
     3708                  lpLVItem->pszText[0] = 0;
     3709                else
     3710                  ((CHAR*)lpLVItem->pszText)[0] = 0;
    40023711              }
    40033712            }
    4004 
    4005             if (dispInfo.item.mask != 0)
    4006             {
    4007               dispInfo.item.iItem = lpLVItem->iItem;
    4008               dispInfo.item.iSubItem = lpLVItem->iSubItem;
    4009               dispInfo.item.lParam = lpItem->lParam;
    4010               sendNotify(hwnd,isUnicodeNotify(&infoPtr->header) ? LVN_GETDISPINFOW:LVN_GETDISPINFOA,&dispInfo.hdr);
    4011             }
    4012 
    4013             if (dispInfo.item.mask & LVIF_IMAGE)
    4014             {
    4015               lpLVItem->iImage = dispInfo.item.iImage;
    4016               if (dispInfo.item.mask & LVIF_DI_SETITEM)
    4017                 lpSubItem->iImage = dispInfo.item.iImage;
    4018             } else if (lpLVItem->mask & LVIF_IMAGE)
    4019                 lpLVItem->iImage = lpSubItem->iImage;
    4020 
    4021             if (dispInfo.item.mask & LVIF_PARAM)
    4022               lpLVItem->lParam = dispInfo.item.lParam;
    4023             else if (lpLVItem->mask & LVIF_PARAM)
    4024               lpLVItem->lParam = lpItem->lParam;
    4025 
    4026             if (dispInfo.item.mask & LVIF_TEXT)
    4027             {
    4028               if ((dispInfo.item.mask & LVIF_DI_SETITEM) && lpSubItem)
    4029               {
    4030                 if (isUnicodeNotify(&infoPtr->header))
    4031                 {
    4032                   Str_SetPtrW(&lpSubItem->pszText,dispInfo.item.pszText);
    4033                 } else
    4034                 {
    4035                   INT len = dispInfo.item.pszText ? lstrlenA((LPSTR)dispInfo.item.pszText):0;
    4036 
    4037                   if (lpSubItem->pszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(lpSubItem->pszText);
    4038                   if (len > 0)
    4039                   {
    4040                     len++;
    4041                     lpSubItem->pszText = (WCHAR*)COMCTL32_Alloc(len*sizeof(WCHAR));
    4042                     lstrcpyAtoW(lpSubItem->pszText,(LPSTR)dispInfo.item.pszText);
    4043                   } else lpSubItem->pszText = NULL;
    4044                 }
    4045               }
    4046               /* Make sure the source string is valid */
    4047               if (dispInfo.item.pszText == NULL)
    4048               {
    4049                 if (internal)
    4050                 {
    4051                   lpLVItem->pszText = NULL;
    4052                   ((LPLVINTERNALITEMW)lpLVItem)->unicode = unicode;
    4053                 } else
    4054                 {
    4055                   if (unicode)
    4056                     lpLVItem->pszText[0] = L'\0';
    4057                   else
    4058                     ((LPSTR)lpLVItem->pszText)[0] = '\0';
    4059                 }
    4060               } else
    4061               {
    4062                 if (internal)
    4063                 {
    4064                   lpLVItem->pszText = dispInfo.item.pszText;
    4065                   if (isUnicodeNotify(&infoPtr->header))
    4066                   {
    4067                     ((LPLVINTERNALITEMW)lpLVItem)->unicode = TRUE;
    4068                     if (textW == dispInfo.item.pszText)
    4069                     {
    4070                       ((LPLVINTERNALITEMW)lpLVItem)->mustFree = TRUE;
    4071                       textW = NULL;
    4072                     } else ((LPLVINTERNALITEMW)lpLVItem)->mustFree = FALSE;
    4073                   } else
    4074                   {
    4075                     ((LPLVINTERNALITEMW)lpLVItem)->unicode = FALSE;
    4076                     if (textA == (LPSTR)dispInfo.item.pszText)
    4077                     {
    4078                       ((LPLVINTERNALITEMW)lpLVItem)->mustFree = TRUE;
    4079                       textA = NULL;
    4080                     } else ((LPLVINTERNALITEMW)lpLVItem)->mustFree = FALSE;
    4081                   }
    4082                 } else
    4083                 {
    4084                   if (unicode)
    4085                   {
    4086                     if (isUnicodeNotify(&infoPtr->header))
    4087                       lstrcpynW(lpLVItem->pszText,dispInfo.item.pszText,lpLVItem->cchTextMax);
    4088                     else
    4089                       lstrcpynAtoW(lpLVItem->pszText,(LPSTR)dispInfo.item.pszText,lpLVItem->cchTextMax);
    4090                     lpLVItem->pszText[lpLVItem->cchTextMax-1] = L'\0';
    4091                   } else
    4092                   {
    4093                     if (isUnicodeNotify(&infoPtr->header))
    4094                       lstrcpynWtoA((LPSTR)lpLVItem->pszText,dispInfo.item.pszText,lpLVItem->cchTextMax);
    4095                     else
    4096                       lstrcpynA((LPSTR)lpLVItem->pszText,(LPSTR)dispInfo.item.pszText,lpLVItem->cchTextMax);
    4097                     ((LPSTR)lpLVItem->pszText)[lpLVItem->cchTextMax-1] = '\0';
    4098                   }
    4099                 }
    4100               }
    4101             } else if (lpLVItem->mask & LVIF_TEXT)
    4102             {
    4103               if (lpSubItem->pszText)
    4104               {
    4105                 if (internal)
    4106                 {
    4107                   lpLVItem->pszText = lpSubItem->pszText;
    4108                   ((LPLVINTERNALITEMW)lpLVItem)->unicode = TRUE;
    4109                 } else
    4110                 {
    4111                   if (unicode)
    4112                   {
    4113                     lstrcpynW(lpLVItem->pszText,lpSubItem->pszText,lpLVItem->cchTextMax);
    4114                     lpLVItem->pszText[lpLVItem->cchTextMax-1] = L'\0';
    4115                   } else
    4116                   {
    4117                     lstrcpynWtoA((LPSTR)lpLVItem->pszText,lpSubItem->pszText,lpLVItem->cchTextMax);
    4118                     ((LPSTR)lpLVItem->pszText)[lpLVItem->cchTextMax-1] = '\0';
    4119                   }
    4120                 }
    4121               } else
    4122               {
    4123                 if (internal)
    4124                 {
    4125                   lpLVItem->pszText = NULL;
    4126                   ((LPLVINTERNALITEMW)lpLVItem)->unicode = unicode;
    4127                 } else
    4128                 {
    4129                   if (unicode)
    4130                     lpLVItem->pszText[0] = 0;
    4131                   else
    4132                     ((CHAR*)lpLVItem->pszText)[0] = 0;
    4133                 }
    4134               }
    4135             }
    4136             if (textA) COMCTL32_Free(textA);
    4137             if (textW) COMCTL32_Free(textW);
    41383713          }
     3714
     3715          if (dispInfo.item.mask & LVIF_STATE)
     3716          {
     3717            lpLVItem->state = lpItem->state;
     3718            lpLVItem->state &= ~dispInfo.item.stateMask;
     3719            lpLVItem->state |= (dispInfo.item.state & dispInfo.item.stateMask);
     3720          } else if (lpLVItem->mask & LVIF_STATE)
     3721              lpLVItem->state = lpItem->state & lpLVItem->stateMask;
     3722
     3723          if (lpLVItem->mask & LVIF_PARAM)
     3724            lpLVItem->lParam = lpItem->lParam;
     3725
     3726          if (lpLVItem->mask & LVIF_INDENT)
     3727            lpLVItem->iIndent = lpItem->iIndent;
     3728
     3729          if (textA) COMCTL32_Free(textA);
     3730          if (textW) COMCTL32_Free(textW);
    41393731        }
    41403732      }
     
    41443736  return bResult;
    41453737}
    4146 
    4147 /* LISTVIEW_GetHotCursor */
    41483738
    41493739/***
     
    41603750static LRESULT LISTVIEW_GetHotItem(HWND hwnd)
    41613751{
    4162     LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    4163 
    4164     /* make sure we can get the listview info */
    4165     if (!infoPtr)
    4166       return (-1);
    4167     return (infoPtr->nHotItem);
     3752  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     3753
     3754  return (infoPtr->nHotItem);
    41683755}
    41693756
     
    42043791  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    42053792  BOOL bResult = FALSE;
    4206   HDPA hdpaSubItems;
    4207   LISTVIEW_ITEM *lpItem;
    42083793  INT nCountPerColumn;
    42093794  INT nRow;
     
    42353820        lpptPosition->y = nItem % nCountPerColumn * infoPtr->nItemHeight;
    42363821      }
    4237     }
    4238     else if (infoPtr->uView == LVS_REPORT)
     3822    } else if (infoPtr->uView == LVS_REPORT)
    42393823    {
    42403824      bResult = TRUE;
     
    42423826      lpptPosition->y = ((nItem - LISTVIEW_GetTopIndex(hwnd)) *
    42433827                         infoPtr->nItemHeight) + infoPtr->rcList.top;
    4244     }
    4245     else
    4246     {
    4247       hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
    4248       if (hdpaSubItems != NULL)
    4249       {
    4250         lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
    4251         if (lpItem != NULL)
    4252         {
    4253           bResult = TRUE;
    4254           lpptPosition->x = lpItem->ptPosition.x;
    4255           lpptPosition->y = lpItem->ptPosition.y;
    4256         }
     3828    } else
     3829    {
     3830      LISTVIEW_ITEM *lpItem;
     3831
     3832      lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(infoPtr->hdpaItems,nItem);
     3833      if (lpItem)
     3834      {
     3835        bResult = TRUE;
     3836        lpptPosition->x = lpItem->ptPosition.x;
     3837        lpptPosition->y = lpItem->ptPosition.y;
    42573838      }
    42583839    }
     
    52674848    are sorted based on item text..."
    52684849*/
    5269 static INT WINAPI LISTVIEW_InsertCompare(  LPVOID first, LPVOID second,  LPARAM lParam)
    5270 {
    5271   HDPA  hdpa_first = (HDPA) first;
    5272   HDPA  hdpa_second = (HDPA) second;
    5273   LISTVIEW_ITEM* lv_first = (LISTVIEW_ITEM*) DPA_GetPtr( hdpa_first, 0 );
    5274   LISTVIEW_ITEM* lv_second = (LISTVIEW_ITEM*) DPA_GetPtr( hdpa_second, 0 );
    5275   LONG dwStyle = GetWindowLongA((HWND) lParam, GWL_STYLE);
    5276   INT  cmpv = lstrcmpW( lv_first->pszText, lv_second->pszText );
     4850static INT WINAPI LISTVIEW_InsertCompare(LPVOID first,LPVOID second,LPARAM lParam)
     4851{
     4852  LISTVIEW_ITEM* lv_first = (LISTVIEW_ITEM*)first;
     4853  LISTVIEW_ITEM* lv_second = (LISTVIEW_ITEM*)second;
     4854  LISTVIEW_ITEMDATA* lv_firstData = (LISTVIEW_ITEMDATA*)DPA_GetPtr(lv_first->hdpaSubItems,0);
     4855  LISTVIEW_ITEMDATA* lv_secondData = (LISTVIEW_ITEMDATA*)DPA_GetPtr(lv_second->hdpaSubItems,0);
     4856  LONG dwStyle = GetWindowLongA((HWND)lParam,GWL_STYLE);
     4857  INT  cmpv = lstrcmpiW(lv_firstData->pszText,lv_secondData->pszText);
     4858
    52774859  /* if we're sorting descending, negate the return value */
    52784860  return (dwStyle & LVS_SORTDESCENDING) ? -cmpv : cmpv;
     
    52964878  NMLISTVIEW nmlv;
    52974879  INT nItem = -1;
    5298   HDPA hdpaSubItems;
    52994880  INT nItemWidth = 0;
    53004881  LISTVIEW_ITEM *lpItem = NULL;
     4882  LISTVIEW_ITEMDATA *lpItemData = NULL;
    53014883
    53024884  if (lpLVItem)
     
    53054887    if (lpLVItem->iSubItem == 0)
    53064888    {
    5307       lpItem = (LISTVIEW_ITEM *)COMCTL32_Alloc(sizeof(LISTVIEW_ITEM));
    5308       if (lpItem)
    5309       {
    5310         ZeroMemory(lpItem, sizeof(LISTVIEW_ITEM));
    5311         if (LISTVIEW_InitItem(hwnd, lpItem, lpLVItem,unicode))
     4889      lpItem = (LISTVIEW_ITEM*)COMCTL32_Alloc(sizeof(LISTVIEW_ITEM));
     4890      lpItemData = (LISTVIEW_ITEMDATA*)COMCTL32_Alloc(sizeof(LISTVIEW_ITEMDATA));
     4891      if (lpItem && lpItemData)
     4892      {
     4893        ZeroMemory(lpItem,sizeof(LISTVIEW_ITEM));
     4894        ZeroMemory(lpItemData,sizeof(LISTVIEW_ITEMDATA));
     4895        if (LISTVIEW_InitItem(hwnd,lpItem,lpLVItem,unicode) && LISTVIEW_InitItemData(hwnd,lpItemData,lpLVItem,unicode))
    53124896        {
    53134897          /* insert item in listview control data structure */
    5314           hdpaSubItems = DPA_Create(8);
    5315           if (hdpaSubItems)
     4898          lpItem->hdpaSubItems = DPA_Create(8);
     4899          if (lpItem->hdpaSubItems)
    53164900          {
    5317             nItem = DPA_InsertPtr(hdpaSubItems, 0, lpItem);
     4901            nItem = DPA_InsertPtr(lpItem->hdpaSubItems,0,lpItemData);
    53184902            if (nItem != -1)
    53194903            {
     
    53244908                /* Insert the item in the proper sort order based on the pszText
    53254909                  member. See comments for LISTVIEW_InsertCompare() for greater detail */
    5326                   nItem = DPA_InsertPtr( infoPtr->hdpaItems,
    5327                           GETITEMCOUNT( infoPtr ) + 1, hdpaSubItems );
    5328                   DPA_Sort( infoPtr->hdpaItems, LISTVIEW_InsertCompare, hwnd );
    5329                   nItem = DPA_GetPtrIndex( infoPtr->hdpaItems, hdpaSubItems );
    5330               }
    5331               else
     4910                nItem = DPA_InsertPtrSorted(infoPtr->hdpaItems,lpItem,LISTVIEW_InsertCompare,hwnd);
     4911              } else
    53324912              {
    5333                 nItem = DPA_InsertPtr(infoPtr->hdpaItems, lpLVItem->iItem,
    5334                                     hdpaSubItems);
     4913                nItem = DPA_InsertPtr(infoPtr->hdpaItems,lpLVItem->iItem,lpItem);
    53354914              }
    53364915
     
    53914970
    53924971  /* free memory if unsuccessful */
    5393   if ((nItem == -1) && (lpItem != NULL))
    5394     COMCTL32_Free(lpItem);
     4972  if (nItem == -1)
     4973  {
     4974    if (lpItem) COMCTL32_Free(lpItem);
     4975    if (lpItemData) COMCTL32_Free(lpItemData);
     4976  }
    53954977
    53964978  return nItem;
     
    55375119}
    55385120
    5539 /* LISTVIEW_SetBkImage */
     5121static LRESULT LISTVIEW_SetBkImage(HWND hwnd,WPARAM wParam,LPARAM lParam,BOOL unicode)
     5122{
     5123  LPLVBKIMAGEW plvbki = (LPLVBKIMAGEW)lParam;
     5124
     5125  if (!plvbki) return FALSE;
     5126
     5127  //todo: use OLE COM interface
     5128
     5129  return TRUE;
     5130}
    55405131
    55415132/***
     
    56845275 *   FAILURE : FALSE
    56855276 */
    5686 static LRESULT LISTVIEW_SetColumnOrderArray(HWND hwnd, INT iCount, LPINT lpiArray)
    5687 {
    5688 /*  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd); */
    5689 
    5690 //    FIXME("iCount %d lpiArray %p\n", iCount, lpiArray);
    5691 
    5692     if (!lpiArray)
    5693         return FALSE;
    5694 
    5695     return TRUE;
     5277static LRESULT LISTVIEW_SetColumnOrderArray(HWND hwnd,INT iCount,LPINT lpiArray)
     5278{
     5279  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     5280  LPINT oldArray,diffList;
     5281  INT nHeaderItemCount;
     5282  BOOL rc,changed = FALSE;
     5283
     5284  nHeaderItemCount = Header_GetItemCount(infoPtr->hwndHeader);
     5285  if (iCount != nHeaderItemCount) return FALSE;
     5286
     5287  oldArray = (LPINT)COMCTL32_Alloc(nHeaderItemCount*sizeof(INT));
     5288  Header_GetOrderArray(infoPtr->hwndHeader,nHeaderItemCount,oldArray);
     5289  rc = Header_SetOrderArray(infoPtr->hwndHeader,iCount,lpiArray);
     5290  if (rc)
     5291  {
     5292    INT x,y;
     5293
     5294    //build offset list
     5295    diffList = (LPINT)COMCTL32_Alloc(nHeaderItemCount*sizeof(INT));
     5296    for (x = 0;x < nHeaderItemCount;x++)
     5297      for (y = 0;y < nHeaderItemCount;y++)
     5298      {
     5299        if (lpiArray[x] == oldArray[y])
     5300        {
     5301          diffList[x] = y;
     5302          if (x != y) changed = TRUE;
     5303          break;
     5304        }
     5305      }
     5306
     5307    if (changed)
     5308    {
     5309      //change order
     5310      for (x = 0;x < GETITEMCOUNT(infoPtr);x++)
     5311      {
     5312        LISTVIEW_ITEM *lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(infoPtr->hdpaItems,x);
     5313        HDPA newDPA;
     5314
     5315        if (!lpItem) continue;
     5316        newDPA = DPA_Create(8);
     5317        for (y = 0;y < nHeaderItemCount;y++)
     5318        {
     5319          LISTVIEW_ITEMDATA *lpItemData;
     5320
     5321          lpItemData = LISTVIEW_GetItemData(lpItem->hdpaSubItems,diffList[y]);
     5322          if (!lpItemData) continue;
     5323          DPA_InsertPtr(newDPA,newDPA->nItemCount,lpItemData);
     5324        }
     5325        DPA_Destroy(lpItem->hdpaSubItems);
     5326        lpItem->hdpaSubItems = newDPA;
     5327      }
     5328      if (diffList) COMCTL32_Free(diffList);
     5329
     5330      LISTVIEW_Refresh(hwnd);
     5331    }
     5332  }
     5333  if (oldArray) COMCTL32_Free(oldArray);
     5334
     5335  return rc;
    56965336}
    56975337
     
    57735413static LRESULT LISTVIEW_SetExtendedListViewStyle(HWND hwnd, DWORD dwMask, DWORD dwStyle)
    57745414{
    5775     LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    5776     DWORD dwOldStyle;
    5777 
    5778     /* make sure we can get the listview info */
    5779     if (!infoPtr)
    5780       return (0);
    5781     /* store previous style */
    5782     dwOldStyle = infoPtr->dwExStyle;
    5783     /* set new style */
    5784     infoPtr->dwExStyle = (dwOldStyle & ~dwMask) | (dwStyle & dwMask);
    5785     return (dwOldStyle);
    5786 }
    5787 
    5788 /* LISTVIEW_SetHotCursor */
     5415  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     5416  DWORD dwOldStyle;
     5417
     5418  /* store previous style */
     5419  dwOldStyle = infoPtr->dwExStyle;
     5420  /* set new style */
     5421  infoPtr->dwExStyle = (dwOldStyle & ~dwMask) | (dwStyle & dwMask);
     5422  return (dwOldStyle);
     5423}
     5424
     5425static LRESULT LISTVIEW_SetHotCursor(HWND hwnd,WPARAM wParam,LPARAM lParam)
     5426{
     5427  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     5428  HCURSOR hOldCursor = infoPtr->hHotCursor;
     5429
     5430  infoPtr->hHotCursor = (HCURSOR)lParam;
     5431
     5432  return hOldCursor;
     5433}
    57895434
    57905435/***
     
    58025447static LRESULT LISTVIEW_SetHotItem(HWND hwnd, INT iIndex)
    58035448{
    5804     LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    5805     INT iOldIndex;
    5806 
    5807     /* make sure we can get the listview info */
    5808     if (!infoPtr)
    5809         return (-1);
    5810     /* store previous index */
    5811     iOldIndex = infoPtr->nHotItem;
     5449  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     5450  INT iOldIndex;
     5451
     5452  /* store previous index */
     5453  iOldIndex = infoPtr->nHotItem;
     5454  if (iOldIndex != infoPtr->nHotItem)
     5455  {
     5456    HDC hdc = 0;
     5457
    58125458    /* set new style */
    58135459    infoPtr->nHotItem = iIndex;
    5814     return (iOldIndex);
     5460
     5461    if (iOldIndex != -1)
     5462    {
     5463      RECT rect;
     5464
     5465      if (!hdc) hdc = GetDC(hwnd);
     5466      LISTVIEW_GetItemRect(hwnd,iOldIndex,&rect,LVIR_LABEL);
     5467      LISTVIEW_DrawHottrackLine(hdc,&rect);
     5468    }
     5469    if (iIndex != -1)
     5470    {
     5471      RECT rect;
     5472
     5473      if (!hdc) hdc = GetDC(hwnd);
     5474      LISTVIEW_GetItemRect(hwnd,iIndex,&rect,LVIR_LABEL);
     5475      LISTVIEW_DrawHottrackLine(hdc,&rect);
     5476    }
     5477    if (hdc) ReleaseDC(hwnd,hdc);
     5478  }
     5479
     5480  return (iOldIndex);
    58155481}
    58165482
     
    58375503  switch (nType)
    58385504  {
    5839   case LVSIL_NORMAL:
    5840     himlTemp = infoPtr->himlNormal;
    5841     infoPtr->himlNormal = himl;
    5842     return (LRESULT)himlTemp;
    5843 
    5844   case LVSIL_SMALL:
    5845     himlTemp = infoPtr->himlSmall;
    5846     infoPtr->himlSmall = himl;
    5847     return (LRESULT)himlTemp;
    5848 
    5849   case LVSIL_STATE:
    5850     himlTemp = infoPtr->himlState;
    5851     infoPtr->himlState = himl;
    5852     ImageList_SetBkColor(infoPtr->himlState, CLR_NONE);
    5853     return (LRESULT)himlTemp;
     5505    case LVSIL_NORMAL:
     5506      himlTemp = infoPtr->himlNormal;
     5507      infoPtr->himlNormal = himl;
     5508      return (LRESULT)himlTemp;
     5509
     5510    case LVSIL_SMALL:
     5511      himlTemp = infoPtr->himlSmall;
     5512      infoPtr->himlSmall = himl;
     5513      return (LRESULT)himlTemp;
     5514
     5515    case LVSIL_STATE:
     5516      himlTemp = infoPtr->himlState;
     5517      infoPtr->himlState = himl;
     5518      ImageList_SetBkColor(infoPtr->himlState, CLR_NONE);
     5519      return (LRESULT)himlTemp;
    58545520  }
    58555521
     
    58735539  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    58745540  BOOL bResult = FALSE;
    5875   HDPA hdpaSubItems;
    58765541  NMLISTVIEW nmlv;
    58775542
     
    58805545    if ((lpLVItem->iItem >= 0) && (lpLVItem->iItem < GETITEMCOUNT(infoPtr)))
    58815546    {
    5882       if (lpLVItem->iSubItem == 0)
    5883       {
    5884         hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
    5885         if (hdpaSubItems)
     5547      LISTVIEW_ITEM *lpItem;
     5548
     5549      lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(infoPtr->hdpaItems,lpLVItem->iItem);
     5550      if (lpItem)
     5551      {
     5552        LISTVIEW_ITEMDATA *lpItemData;
     5553
     5554        lpItemData = LISTVIEW_GetItemData(lpItem->hdpaSubItems,lpLVItem->iSubItem);
     5555
     5556        if (lpItemData)
    58865557        {
    5887           LISTVIEW_ITEM *lpItem;
    5888 
    5889           lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, lpLVItem->iSubItem);
    5890           if (lpItem)
     5558          UINT uChanged;
     5559
     5560          ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
     5561          nmlv.lParam = lpItem->lParam;
     5562          uChanged = LISTVIEW_GetItemChanges(lpItem,lpItemData,lpLVItem,unicode);
     5563          if (uChanged != 0)
    58915564          {
    5892             UINT uChanged;
    5893 
    5894             ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
     5565            if (uChanged & LVIF_STATE)
     5566            {
     5567              nmlv.uNewState = lpLVItem->state & lpLVItem->stateMask;
     5568              nmlv.uOldState = lpItem->state & lpLVItem->stateMask;
     5569            }
     5570
     5571            nmlv.uChanged = uChanged;
     5572            nmlv.iItem = lpLVItem->iItem;
    58955573            nmlv.lParam = lpItem->lParam;
    5896             uChanged = LISTVIEW_GetItemChanges(lpItem,lpLVItem,unicode);
    5897             if (uChanged != 0)
     5574            /* send LVN_ITEMCHANGING notification */
     5575            sendNotify(hwnd,LVN_ITEMCHANGING,&nmlv.hdr);
     5576
     5577            /* copy information */
     5578            if (uChanged & LVIF_STATE)
    58985579            {
    5899               if (uChanged & LVIF_STATE)
     5580              if ((nmlv.uNewState & LVIS_SELECTED) != (nmlv.uOldState & LVIS_SELECTED))
    59005581              {
    5901                 nmlv.uNewState = lpLVItem->state & lpLVItem->stateMask;
    5902                 nmlv.uOldState = lpItem->state & lpLVItem->stateMask;
     5582                if (nmlv.uOldState & LVIS_SELECTED)
     5583                  DPA_DeletePtr(infoPtr->hdpaSelItems,DPA_GetPtrIndex(infoPtr->hdpaSelItems,lpItem));
     5584                else
     5585                  DPA_InsertPtr(infoPtr->hdpaSelItems,0,lpItem);
    59035586              }
    5904 
    5905               nmlv.uChanged = uChanged;
    5906               nmlv.iItem = lpLVItem->iItem;
    5907               nmlv.lParam = lpItem->lParam;
    5908               /* send LVN_ITEMCHANGING notification */
    5909               sendNotify(hwnd,LVN_ITEMCHANGING,&nmlv.hdr);
    5910 
    5911               /* copy information */
    5912               if (uChanged & LVIF_STATE)
     5587            }
     5588            bResult = LISTVIEW_InitItem(hwnd,lpItem,lpLVItem,unicode) && LISTVIEW_InitItemData(hwnd,lpItemData,lpLVItem,unicode);
     5589
     5590            /* send LVN_ITEMCHANGED notification */
     5591            sendNotify(hwnd,LVN_ITEMCHANGED,&nmlv.hdr);
     5592
     5593            if ((uChanged & LVIF_TEXT) && ((infoPtr->uView == LVS_SMALLICON) || (infoPtr->uView == LVS_LIST)))
     5594            {
     5595              INT nItemWidth = LISTVIEW_CalculateWidth(hwnd,lpLVItem->iItem);
     5596
     5597              if (nItemWidth > infoPtr->nItemWidth)
    59135598              {
    5914                 if ((nmlv.uNewState & LVIS_SELECTED) != (nmlv.uOldState & LVIS_SELECTED))
    5915                 {
    5916                   if (nmlv.uOldState & LVIS_SELECTED)
    5917                     DPA_DeletePtr(infoPtr->hdpaSelItems,DPA_GetPtrIndex(infoPtr->hdpaSelItems,lpItem));
    5918                   else
    5919                     DPA_InsertPtr(infoPtr->hdpaSelItems,0,lpItem);
    5920                 }
     5599                infoPtr->nItemWidth = nItemWidth;
     5600                LISTVIEW_Refresh(hwnd);
     5601
     5602                return bResult;
    59215603              }
    5922               bResult = LISTVIEW_InitItem(hwnd, lpItem, lpLVItem,unicode);
    5923 
    5924               /* send LVN_ITEMCHANGED notification */
    5925               sendNotify(hwnd,LVN_ITEMCHANGED,&nmlv.hdr);
    5926 
    5927               if ((uChanged & LVIF_TEXT) && ((infoPtr->uView == LVS_SMALLICON) || (infoPtr->uView == LVS_LIST)))
    5928               {
    5929                 INT nItemWidth = LISTVIEW_CalculateWidth(hwnd,lpLVItem->iItem);
    5930 
    5931                 if (nItemWidth > infoPtr->nItemWidth)
    5932                 {
    5933                   infoPtr->nItemWidth = nItemWidth;
    5934                   LISTVIEW_Refresh(hwnd);
    5935 
    5936                   return bResult;
    5937                 }
    5938               }
    5939 
     5604            }
     5605
     5606            if (!lpLVItem->iSubItem)
    59405607              LISTVIEW_RefreshItem(hwnd,lpLVItem->iItem,TRUE);
    5941             } else
    5942                 bResult = TRUE;
    5943           }
    5944         }
    5945       } else //sub-item
    5946       {
    5947         hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems,lpLVItem->iItem);
    5948         if (hdpaSubItems)
     5608            else
     5609              LISTVIEW_RefreshSubItem(hwnd,lpLVItem->iItem,lpLVItem->iSubItem);
     5610          } else
     5611              bResult = TRUE;
     5612        } else
    59495613        {
    59505614          /* set subitem only if column is present */
    59515615          if (Header_GetItemCount(infoPtr->hwndHeader) > lpLVItem->iSubItem)
    59525616          {
    5953             LISTVIEW_SUBITEM *lpSubItem;
    5954 
    5955             lpSubItem = LISTVIEW_GetSubItem(hdpaSubItems,lpLVItem->iSubItem);
    5956             if (lpSubItem)
    5957               bResult = LISTVIEW_InitSubItem(hwnd,lpSubItem,lpLVItem,unicode);
    5958             else
    5959               bResult = LISTVIEW_AddSubItem(hwnd,lpLVItem,unicode);
    5960 
    5961             LISTVIEW_RefreshSubItem(hwnd,lpLVItem->iItem,lpLVItem->iSubItem);
     5617            lpItemData = (LISTVIEW_ITEMDATA*)COMCTL32_Alloc(sizeof(LISTVIEW_ITEMDATA));
     5618            if (lpItemData)
     5619            {
     5620              ZeroMemory(lpItemData,sizeof(LISTVIEW_ITEMDATA));
     5621              if (LISTVIEW_InitItem(hwnd,lpItem,lpLVItem,unicode) && LISTVIEW_InitItemData(hwnd,lpItemData,lpLVItem,unicode))
     5622              {
     5623                INT nPosition = LISTVIEW_FindInsertPosition(lpItem->hdpaSubItems,lpItemData->iSubItem);
     5624                INT nItem = DPA_InsertPtr(lpItem->hdpaSubItems,nPosition,lpItemData);
     5625
     5626                if (nItem != -1)
     5627                {
     5628                  bResult = TRUE;
     5629                  LISTVIEW_RefreshSubItem(hwnd,lpLVItem->iItem,lpLVItem->iSubItem);
     5630                }
     5631              }
     5632            }
     5633            if (!bResult)
     5634            {
     5635              if (lpItemData) COMCTL32_Free(lpItemData);
     5636            }
    59625637          }
    59635638        }
     
    60285703{
    60295704  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    6030   LISTVIEW_ITEM *lpItem;
    6031   HDPA hdpaSubItems;
    60325705  BOOL bResult = FALSE;
    60335706
     
    60365709    if ((infoPtr->uView == LVS_ICON) || (infoPtr->uView == LVS_SMALLICON))
    60375710    {
    6038       hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
    6039       if (hdpaSubItems)
    6040       {
    6041         lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
    6042         if (lpItem)
     5711      LISTVIEW_ITEM *lpItem;
     5712
     5713      lpItem = (LISTVIEW_ITEM*)DPA_GetPtr(infoPtr->hdpaItems,nItem);
     5714      if (lpItem)
     5715      {
     5716        bResult = TRUE;
     5717
     5718        if ((lpItem->ptPosition.x == nPosX) && (lpItem->ptPosition.y == nPosY))
     5719          return bResult;
     5720
     5721        if (infoPtr->dwStyle & LVS_AUTOARRANGE)
    60435722        {
    6044           bResult = TRUE;
    6045 
    6046           if ((lpItem->ptPosition.x == nPosX) && (lpItem->ptPosition.y == nPosY))
    6047             return bResult;
    6048 
    6049           if (infoPtr->dwStyle & LVS_AUTOARRANGE)
    6050           {
    6051             lpItem->ptPosition.x = nPosX;
    6052             lpItem->ptPosition.y = nPosY;
    6053 
    6054             if (!ignoreAutoArrange) LISTVIEW_Arrange(hwnd,LVA_DEFAULT);
    6055           } else
    6056           {
    6057             POINT point;
    6058             RECT rect1,rect2;
    6059 
    6060             LISTVIEW_GetItemRect(hwnd,nItem,&rect1,LVIR_BOUNDS);
    6061             lpItem->ptPosition.x = nPosX;
    6062             lpItem->ptPosition.y = nPosY;
    6063             LISTVIEW_GetItemRect(hwnd,nItem,&rect2,LVIR_BOUNDS);
    6064             InvalidateRect(hwnd,&rect1,TRUE);
    6065             InvalidateRect(hwnd,&rect2,TRUE);
    6066           }
     5723          lpItem->ptPosition.x = nPosX;
     5724          lpItem->ptPosition.y = nPosY;
     5725
     5726          if (!ignoreAutoArrange) LISTVIEW_Arrange(hwnd,LVA_DEFAULT);
     5727        } else
     5728        {
     5729          POINT point;
     5730          RECT rect1,rect2;
     5731
     5732          LISTVIEW_GetItemRect(hwnd,nItem,&rect1,LVIR_BOUNDS);
     5733          lpItem->ptPosition.x = nPosX;
     5734          lpItem->ptPosition.y = nPosY;
     5735          LISTVIEW_GetItemRect(hwnd,nItem,&rect2,LVIR_BOUNDS);
     5736          InvalidateRect(hwnd,&rect1,TRUE);
     5737          InvalidateRect(hwnd,&rect2,TRUE);
    60675738        }
    60685739      }
     
    63125983{
    63135984    LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    6314     HDPA hdpaSubItems;
    63155985    LISTVIEW_ITEM *lpItem;
    63165986    int nCount, i;
    6317     HDPA sortList;
    63185987
    63195988    if (!infoPtr || !infoPtr->hdpaItems)
     
    63245993    if (nCount > 1)
    63255994    {
    6326         sortList = DPA_Create(nCount);
    6327 
    6328         infoPtr->pfnCompare = (PFNLVCOMPARE)lParam;
    6329         infoPtr->lParamSort = (LPARAM)wParam;
    6330 
    6331         // append pointers one by one to sortList
    6332         for (i = 0; i < nCount; i++)
    6333         {
    6334             hdpaSubItems = (HDPA) DPA_GetPtr(infoPtr->hdpaItems, i);
    6335             if (hdpaSubItems)
    6336             {
    6337               lpItem = (LISTVIEW_ITEM *) DPA_GetPtr(hdpaSubItems, 0);
    6338               if (lpItem)
    6339                 DPA_InsertPtr(sortList, nCount + 1, lpItem);
    6340             }
    6341         }
    6342 
    6343         // sort the sortList
    6344         DPA_Sort(sortList, LISTVIEW_CallBackCompare, hwnd);
    6345 
    6346         // copy the pointers back
    6347         for (i = 0; i < nCount; i++)
    6348         {
    6349             hdpaSubItems = (HDPA) DPA_GetPtr(infoPtr->hdpaItems, i);
    6350             if (hdpaSubItems)
    6351             {
    6352               lpItem = (LISTVIEW_ITEM *) DPA_GetPtr(sortList, i);
    6353               if (lpItem)
    6354                 DPA_SetPtr(hdpaSubItems, 0, lpItem);
    6355             }
    6356         }
    6357 
    6358         DPA_Destroy(sortList);
    6359         LISTVIEW_Refresh(hwnd);
     5995      infoPtr->pfnCompare = (PFNLVCOMPARE)lParam;
     5996      infoPtr->lParamSort = (LPARAM)wParam;
     5997
     5998      // sort the sortList
     5999      DPA_Sort(infoPtr->hdpaItems,LISTVIEW_CallBackCompare,hwnd);
     6000
     6001      LISTVIEW_Refresh(hwnd);
    63606002    }
    63616003
     
    64276069  infoPtr->clrText = GetSysColor(COLOR_WINDOWTEXT);
    64286070  infoPtr->clrTextBk = GetSysColor(COLOR_WINDOW);
     6071
     6072  infoPtr->hHotCursor = LoadCursorA(0,IDC_ARROWA);
    64296073
    64306074  /* set default values */
     
    72936937static LRESULT LISTVIEW_NCDestroy(HWND hwnd)
    72946938{
    7295   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
     6939  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    72966940
    72976941  /* delete all items */
     
    73076951  {
    73086952    DeleteObject(infoPtr->hDefaultFont);
     6953  }
     6954
     6955  //destroy image lists
     6956  if (!(infoPtr->dwStyle & LVS_SHAREIMAGELISTS))
     6957  {
     6958    if (infoPtr->himlNormal) ImageList_Destroy(infoPtr->himlNormal);
     6959    if (infoPtr->himlSmall) ImageList_Destroy(infoPtr->himlSmall);
     6960    if (infoPtr->himlState) ImageList_Destroy(infoPtr->himlState);
    73096961  }
    73106962
     
    77997451    /* invalidate client area + erase background */
    78007452    LISTVIEW_Refresh(hwnd);
    7801 
    7802     /* print the list of unsupported window styles */
    7803     LISTVIEW_UnsupportedStyles(lpss->styleNew);
    78047453  }
    78057454
     
    79887637    HDC hOldFont=0;
    79897638    TEXTMETRICA textMetric;
    7990     LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(parent);
     7639    LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(parent);
    79917640
    79927641    if (NULL == (infoPtr->pedititem = (EDITLABEL_ITEM*)COMCTL32_Alloc(sizeof(EDITLABEL_ITEM))))
     
    80347683static LRESULT LISTVIEW_CreateDragImage(HWND hwnd,WPARAM wParam,LPARAM lParam)
    80357684{
    8036   //CB: todo
    8037 
    8038   return 0;
     7685  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     7686  INT iItem = (INT)wParam;
     7687  LPPOINT lpptUpLeft = (LPPOINT)lParam;
     7688  HWND hwtop;
     7689  HDC htopdc,hdc;
     7690  HFONT hOldFont;
     7691  RECT rect;
     7692  HBITMAP hbmp,hOldbmp;
     7693  HIMAGELIST dragImage = NULL;
     7694
     7695  LISTVIEW_GetOrigin(hwnd,lpptUpLeft);
     7696
     7697  if ((iItem < 0) || (iItem > infoPtr->hdpaItems->nItemCount)) return 0;
     7698
     7699  //get size
     7700  LISTVIEW_GetItemRect(hwnd,iItem,&rect,LVIR_BOUNDS);
     7701  rect.right -= rect.left;
     7702  rect.bottom -= rect.top;
     7703  rect.left = 0;
     7704  rect.top = 0;
     7705
     7706  hwtop = GetDesktopWindow();
     7707  htopdc = GetDC(hwtop);
     7708  hdc = CreateCompatibleDC(htopdc);
     7709
     7710  hOldFont = SelectObject(hdc,infoPtr->hFont);
     7711  hbmp = CreateCompatibleBitmap(htopdc,rect.right,rect.bottom);
     7712  hOldbmp = SelectObject(hdc,hbmp);
     7713
     7714  if (infoPtr->uView == LVS_ICON)
     7715  {
     7716    LISTVIEW_DrawLargeItem(hwnd,hdc,iItem,rect);
     7717  } else
     7718  {
     7719    LISTVIEW_DrawItem(hwnd,hdc,iItem,rect);
     7720  }
     7721
     7722  SelectObject(hdc,hOldFont);
     7723  SelectObject(hdc,hOldbmp);
     7724
     7725  dragImage = ImageList_Create(rect.right,rect.bottom,ILC_COLOR,10,10);
     7726  ImageList_Add(dragImage,hbmp,0);
     7727
     7728  DeleteDC(hdc);
     7729  DeleteObject(hbmp);
     7730  ReleaseDC(hwtop,htopdc);
     7731
     7732  return (LRESULT)dragImage;
    80397733}
    80407734
     
    80937787      return LISTVIEW_GetBkColor(hwnd);
    80947788
    8095 /*      case LVM_GETBKIMAGE: */
     7789    case LVM_GETBKIMAGEA:
     7790      return LISTVIEW_GetBkImage(hwnd,wParam,lParam,FALSE);
     7791
     7792    case LVM_GETBKIMAGEW:
     7793      return LISTVIEW_GetBkImage(hwnd,wParam,lParam,TRUE);
    80967794
    80977795    case LVM_GETCALLBACKMASK:
     
    81227820      return LISTVIEW_GetHeader(hwnd);
    81237821
    8124 /*      case LVM_GETHOTCURSOR: */
     7822    case LVM_GETHOTCURSOR:
     7823      return LISTVIEW_GetHotCursor(hwnd,wParam,lParam);
    81257824
    81267825    case LVM_GETHOTITEM:
     
    82277926      return LISTVIEW_SetBkColor(hwnd, (COLORREF)lParam);
    82287927
    8229 /*      case LVM_SETBKIMAGE: */
     7928    case LVM_SETBKIMAGEA:
     7929      return LISTVIEW_SetBkImage(hwnd,wParam,lParam,FALSE);
     7930
     7931    case LVM_SETBKIMAGEW:
     7932      return LISTVIEW_SetBkImage(hwnd,wParam,lParam,TRUE);
    82307933
    82317934    case LVM_SETCALLBACKMASK:
     
    82477950      return LISTVIEW_SetExtendedListViewStyle(hwnd, (DWORD)wParam, (DWORD)lParam);
    82487951
    8249 /*      case LVM_SETHOTCURSOR: */
     7952    case LVM_SETHOTCURSOR:
     7953      return LISTVIEW_SetHotCursor(hwnd,wParam,lParam);
    82507954
    82517955    case LVM_SETHOTITEM:
  • trunk/src/comctl32/treeview.cpp

    r3369 r3385  
    1 /* $Id: treeview.cpp,v 1.8 2000-04-12 16:39:00 cbratschi Exp $ */
     1/* $Id: treeview.cpp,v 1.9 2000-04-15 14:22:31 cbratschi Exp $ */
    22/* Treeview control
    33 *
     
    41204120}
    41214121
    4122 static LRESULT
    4123 TREEVIEW_CreateDragImage (HWND hwnd, WPARAM wParam, LPARAM lParam)
     4122static LRESULT TREEVIEW_CreateDragImage (HWND hwnd, WPARAM wParam, LPARAM lParam)
    41244123{
    41254124  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     
    41354134  BOOL mustFree = FALSE;
    41364135
    4137   if (!(infoPtr->himlNormal))  return 0;
     4136  if (!(infoPtr->himlNormal)) return 0;
    41384137  dragItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM) lParam);
    41394138
Note: See TracChangeset for help on using the changeset viewer.