Ignore:
Timestamp:
Mar 22, 2000, 5:56:36 PM (25 years ago)
Author:
cbratschi
Message:

next steps

File:
1 edited

Legend:

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

    r3182 r3194  
    1 /*$Id: listview.cpp,v 1.4 2000-03-21 17:30:42 cbratschi Exp $*/
     1/*$Id: listview.cpp,v 1.5 2000-03-22 16:56:36 cbratschi Exp $*/
    22/*
    33 * Listview control
     
    154154static LRESULT LISTVIEW_SetItemState(HWND hwnd,INT nItem,DWORD data,DWORD mask);
    155155static BOOL    LISTVIEW_SetItemPosition(HWND hwnd, INT nItem, INT nPosX, INT nPosY);
    156 static LRESULT LISTVIEW_GetStringWidth(HWND hwnd,LPWSTR lpszText,BOOL unicode);
     156static LRESULT LISTVIEW_GetStringWidth(HWND hwnd,HDC hdc,LPWSTR lpszText,BOOL unicode);
    157157static BOOL    LISTVIEW_EnsureVisible(HWND hwnd,INT nItem,BOOL bPartial);
     158static VOID    LISTVIEW_UpdateHeaderSize(HWND hwnd, INT nNewScrollPos);
    158159
    159160static VOID LISTVIEW_Refresh(HWND hwnd)
     
    163164  UINT uView;
    164165
    165   if (infoPtr->refreshFlags & RF_REFRESH) return;
     166  if (infoPtr->refreshFlags & (RF_REFRESH | RF_NOREDRAW)) return;
    166167
    167168  dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     
    184185  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    185186
     187  if (infoPtr->refreshFlags & RF_NOREDRAW) return;
     188
    186189  if (infoPtr->refreshFlags & RF_REFRESH)
    187190    KillTimer (hwnd,LV_REFRESH_TIMER);
     
    219222  RECT rect;
    220223
    221   if (infoPtr->refreshFlags & RF_REFRESH) return;
     224  if (infoPtr->refreshFlags & (RF_REFRESH | RF_NOREDRAW)) return;
    222225  LISTVIEW_GetItemRect(hwnd,nItem,&rect,LVIR_SELECTBOUNDS);
    223226  InvalidateRect(hwnd,&rect,TRUE);
     
    227230{
    228231  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    229   RECT rect;
    230 
    231   //CB: todo
    232   if (infoPtr->refreshFlags & RF_REFRESH) return;
     232  RECT rect,header;
     233  INT xOffset = infoPtr->lefttop.x*LISTVIEW_SCROLL_DIV_SIZE;
     234
     235  if (infoPtr->refreshFlags & (RF_REFRESH | RF_NOREDRAW)) return;
    233236  LISTVIEW_GetItemRect(hwnd,nItem,&rect,LVIR_SELECTBOUNDS);
     237
     238  //get header rect
     239  Header_GetItemRect(infoPtr->hwndHeader,nSubItem,&header);
     240  rect.left = header.left+REPORT_MARGINX;
     241  rect.right = max(header.left,header.right-REPORT_MARGINX);
     242
     243  /* Offset the Scroll Bar Pos */
     244  rect.left -= xOffset;
     245  rect.right -= xOffset;
     246
    234247  InvalidateRect(hwnd,&rect,TRUE);
    235248}
     
    239252  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    240253
    241   if (infoPtr->refreshFlags & RF_REFRESH) return;
     254  if (infoPtr->refreshFlags & (RF_REFRESH | RF_NOREDRAW)) return;
    242255
    243256  if (uView == LVS_REPORT)
     
    266279      ScrollWindowEx(hwnd,xScroll,yScroll,&rect,NULL,0,NULL,SW_INVALIDATE);
    267280    }
     281    if (xScroll != 0) LISTVIEW_UpdateHeaderSize(hwnd,infoPtr->lefttop.x);
    268282  } else ScrollWindowEx(hwnd,xScroll,yScroll,NULL,NULL,0,NULL,SW_INVALIDATE);
    269283}
     
    339353    INT nCountPerRow = LISTVIEW_GetCountPerRow(hwnd);
    340354    INT nNumOfItems = GETITEMCOUNT(infoPtr);
    341 
     355//CB: todo: doesn't work!
    342356    infoPtr->maxScroll.x = nNumOfItems / nCountPerColumn+1;
    343357    if ((nNumOfItems % nCountPerColumn) == 0)
     
    10881102{
    10891103  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    1090 
    1091   if (nItem > 0)
    1092   {
    1093     LISTVIEW_RemoveSelections(hwnd, 0, nItem - 1);
    1094   }
    1095 
    1096   if (nItem < GETITEMCOUNT(infoPtr))
    1097   {
    1098     LISTVIEW_RemoveSelections(hwnd, nItem + 1, GETITEMCOUNT(infoPtr));
    1099   }
    1100 
    1101   LISTVIEW_SetItemState(hwnd,infoPtr->nFocusedItem,0,LVIS_FOCUSED);
     1104  DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     1105  DWORD mask = LVIS_FOCUSED;
     1106
     1107  if (!(dwStyle & LVS_SINGLESEL))
     1108  {
     1109    if (nItem > 0)
     1110      LISTVIEW_RemoveSelections(hwnd, 0, nItem - 1);
     1111
     1112    if (nItem < GETITEMCOUNT(infoPtr))
     1113      LISTVIEW_RemoveSelections(hwnd, nItem + 1, GETITEMCOUNT(infoPtr));
     1114  } else mask |= LVIS_SELECTED;
     1115
     1116  LISTVIEW_SetItemState(hwnd,infoPtr->nFocusedItem,0,mask);
    11021117  LISTVIEW_SetItemState(hwnd,nItem,LVIS_SELECTED | LVIS_FOCUSED,LVIS_SELECTED | LVIS_FOCUSED);
    11031118
     
    11651180static LRESULT LISTVIEW_MouseSelection(HWND hwnd, POINT pt)
    11661181{
    1167   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
     1182  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     1183  DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     1184  UINT uView =  dwStyle & LVS_TYPEMASK;
    11681185  RECT rcItem;
    1169   INT i;
    1170 
    1171   for (i = 0; i < GETITEMCOUNT(infoPtr); i++)
     1186  INT i,nFirst = LISTVIEW_GetTopIndex(hwnd),nLast = GETITEMCOUNT(infoPtr);
     1187
     1188  //CB: todo: first calc rect, then compare with item rect
     1189  //    remove loop
     1190
     1191  if (uView == LVS_REPORT)
     1192  {
     1193    nLast = nFirst+LISTVIEW_GetCountPerColumn(hwnd)+2;
     1194    nLast = min(nLast,GETITEMCOUNT(infoPtr));
     1195  }
     1196
     1197  for (i = nFirst;i < nLast;i++)
    11721198  {
    11731199    rcItem.left = LVIR_SELECTBOUNDS;
    1174     if (LISTVIEW_GetItemRect(hwnd, i, &rcItem) == TRUE)
    1175     {
    1176       if (PtInRect(&rcItem, pt) != FALSE)
    1177       {
    1178         return i;
    1179       }
    1180     }
     1200    if (LISTVIEW_GetItemRect(hwnd,i,&rcItem) && PtInRect(&rcItem,pt))
     1201      return i;
    11811202  }
    11821203
     
    11991220{
    12001221  INT i;
     1222
     1223  //CB: really slow!
    12011224
    12021225  for (i = nFirst; i <= nLast; i++)
     
    18581881
    18591882  /* state icons */
    1860   if (infoPtr->himlState != NULL)
     1883  if (infoPtr->himlState)
    18611884  {
    18621885     UINT uStateImage = (lvItem.header.state & LVIS_STATEIMAGEMASK) >> 12;
    1863      if (uStateImage != 0)
    1864      {
    1865        ImageList_Draw(infoPtr->himlState, uStateImage - 1, hdc, rcItem.left,
    1866                       rcItem.top, ILD_NORMAL);
    1867      }
     1886
     1887     if (uStateImage)
     1888       ImageList_Draw(infoPtr->himlState,uStateImage-1,hdc,rcItem.left,rcItem.top,ILD_NORMAL);
    18681889
    18691890     rcItem.left += infoPtr->iconSize.cx;
     
    18711892
    18721893  /* small icons */
    1873   if (infoPtr->himlSmall != NULL)
    1874   {
    1875     if (lvItem.header.state & LVIS_SELECTED)
    1876     {
    1877       ImageList_SetBkColor(infoPtr->himlSmall, CLR_NONE);
    1878       ImageList_Draw(infoPtr->himlSmall, lvItem.header.iImage, hdc, rcItem.left,
    1879                      rcItem.top, ILD_SELECTED);
    1880     }
    1881     else
    1882     {
    1883       ImageList_SetBkColor(infoPtr->himlSmall, CLR_NONE);
    1884       ImageList_Draw(infoPtr->himlSmall, lvItem.header.iImage, hdc, rcItem.left,
    1885                      rcItem.top, ILD_NORMAL);
    1886     }
     1894  if (infoPtr->himlSmall)
     1895  {
     1896    ImageList_SetBkColor(infoPtr->himlSmall, CLR_NONE);
     1897    ImageList_Draw(infoPtr->himlSmall,lvItem.header.iImage,hdc,rcItem.left,rcItem.top,((lvItem.header.state & LVIS_SELECTED) && !infoPtr->bFocus) ? ILD_SELECTED:ILD_NORMAL);
    18871898
    18881899    rcItem.left += infoPtr->iconSize.cx;
     
    19211932  }
    19221933
    1923   nLabelWidth = LISTVIEW_GetStringWidth(hwnd,lvItem.header.pszText,lvItem.unicode);
     1934  nLabelWidth = LISTVIEW_GetStringWidth(hwnd,hdc,lvItem.header.pszText,lvItem.unicode);
    19241935  if (rcItem.left + nLabelWidth < rcItem.right)
    19251936    rcItem.right = rcItem.left + nLabelWidth;
     
    19321943
    19331944  if ((lvItem.header.state & LVIS_FOCUSED) && infoPtr->bFocus)
    1934   {
    19351945    Rectangle(hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);
    1936   }
    1937 
    1938   if (nMixMode != 0)
     1946
     1947  if (nMixMode)
    19391948  {
    19401949    SetROP2(hdc, R2_COPYPEN);
     
    19611970static VOID LISTVIEW_DrawLargeItem(HWND hwnd, HDC hdc, INT nItem, RECT rcItem)
    19621971{
    1963   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    1964   WCHAR szDispText[DISP_TEXT_SIZE];
     1972  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    19651973  INT nDrawPosX = rcItem.left;
    19661974  INT nLabelWidth;
    19671975  TEXTMETRICA tm;
    1968   LVITEMW lvItem;
    1969 
    1970 //  TRACE("(hwnd=%x, hdc=%x, nItem=%d, left=%d, top=%d, right=%d, \
    1971 //bottom=%d)\n", hwnd, hdc, nItem, rcItem.left, rcItem.top, rcItem.right,
    1972 //        rcItem.bottom);
     1976  LVINTERNALITEMW lvItem;
    19731977
    19741978  /* get information needed for drawing the item */
    19751979  ZeroMemory(&lvItem, sizeof(LVITEMW));
    1976   lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
    1977   lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
    1978   lvItem.iItem = nItem;
    1979   lvItem.iSubItem = 0;
    1980   lvItem.cchTextMax = DISP_TEXT_SIZE;
    1981   lvItem.pszText = szDispText;
    1982   LISTVIEW_GetItem(hwnd,&lvItem,TRUE,FALSE);//CB:todo
    1983 
    1984   if (lvItem.state & LVIS_SELECTED)
     1980  lvItem.header.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
     1981  lvItem.header.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
     1982  lvItem.header.iItem = nItem;
     1983  lvItem.header.iSubItem = 0;
     1984  lvItem.header.cchTextMax = DISP_TEXT_SIZE;
     1985  lvItem.header.pszText = NULL;
     1986  lvItem.mustFree = FALSE;
     1987  LISTVIEW_GetItem(hwnd,(LPLVITEMW)&lvItem,TRUE,TRUE);
     1988
     1989  if (lvItem.header.state & LVIS_SELECTED)
    19851990  {
    19861991    /* set item colors */
     
    19891994    /* set raster mode */
    19901995    SetROP2(hdc, R2_XORPEN);
    1991   }
    1992   else
     1996  } else
    19931997  {
    19941998    /* set item colors */
     
    19992003  }
    20002004
    2001   if (infoPtr->himlNormal != NULL)
     2005  if (infoPtr->himlNormal)
    20022006  {
    20032007    rcItem.top += ICON_TOP_PADDING;
    20042008    nDrawPosX += (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
    2005     if (lvItem.state & LVIS_SELECTED)
    2006     {
    2007       ImageList_Draw(infoPtr->himlNormal, lvItem.iImage, hdc, nDrawPosX,
    2008                      rcItem.top, ILD_SELECTED);
    2009     }
    2010     else
    2011     {
    2012       ImageList_Draw(infoPtr->himlNormal, lvItem.iImage, hdc, nDrawPosX,
    2013                      rcItem.top, ILD_NORMAL);
    2014     }
     2009    ImageList_Draw(infoPtr->himlNormal,lvItem.header.iImage,hdc,nDrawPosX,rcItem.top,(lvItem.header.state & LVIS_SELECTED) ? ILD_SELECTED:ILD_NORMAL);
    20152010  }
    20162011
    20172012  /* Don't bother painting item being edited */
    2018   if (infoPtr->hwndEdit && lvItem.state & LVIS_FOCUSED)
    2019       return;
     2013  if (infoPtr->hwndEdit && (lvItem.header.state & LVIS_FOCUSED))
     2014  {
     2015    if (lvItem.mustFree) COMCTL32_Free(lvItem.header.pszText);
     2016    return;
     2017  }
    20202018
    20212019  rcItem.top += infoPtr->iconSize.cy + ICON_BOTTOM_PADDING;
    2022   nLabelWidth = LISTVIEW_GetStringWidth(hwnd,lvItem.pszText,TRUE);
     2020  nLabelWidth = LISTVIEW_GetStringWidth(hwnd,hdc,lvItem.header.pszText,lvItem.unicode);
    20232021  nDrawPosX = infoPtr->iconSpacing.cx - nLabelWidth;
    20242022  if (nDrawPosX > 1)
     
    20262024    rcItem.left += nDrawPosX / 2;
    20272025    rcItem.right = rcItem.left + nLabelWidth;
    2028   }
    2029   else
     2026  } else
    20302027  {
    20312028    rcItem.left += 1;
     
    20342031
    20352032  /* draw label */
    2036   GetTextMetricsA(hdc, &tm);
     2033  GetTextMetricsA(hdc,&tm);
    20372034  rcItem.bottom = rcItem.top + tm.tmHeight + HEIGHT_PADDING;
    2038   ExtTextOutW(hdc, rcItem.left, rcItem.top, ETO_OPAQUE | ETO_CLIPPED,
    2039               &rcItem, lvItem.pszText, lstrlenW(lvItem.pszText), NULL);
    2040 
    2041   if (lvItem.state & LVIS_FOCUSED)
    2042   {
     2035  if (lvItem.unicode)
     2036    ExtTextOutW(hdc,rcItem.left,rcItem.top,ETO_OPAQUE | ETO_CLIPPED,&rcItem,lvItem.header.pszText,lstrlenW(lvItem.header.pszText),NULL);
     2037  else
     2038    ExtTextOutA(hdc,rcItem.left,rcItem.top,ETO_OPAQUE | ETO_CLIPPED,&rcItem,(LPSTR)lvItem.header.pszText,lstrlenA((LPSTR)lvItem.header.pszText),NULL);
     2039
     2040  if (lvItem.header.state & LVIS_FOCUSED)
    20432041    Rectangle(hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);
    2044   }
     2042  if (lvItem.mustFree) COMCTL32_Free(lvItem.header.pszText);
    20452043}
    20462044
     
    20612059  DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
    20622060  INT nDrawPosY = infoPtr->rcList.top;
    2063   INT nColumnCount;
    2064   RECT rcItem,rcClient;
    2065   INT  j;
    2066   INT nItem;
    2067   INT nLast;
     2061  INT nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
     2062  RECT rcItem,rcClient,*rcHeader;
     2063  INT  j,nItem,nLast,xOffset = infoPtr->lefttop.x*LISTVIEW_SCROLL_DIV_SIZE;
    20682064
    20692065  nItem = LISTVIEW_GetTopIndex(hwnd);
     
    20862082  GetClientRect(hwnd,&rcClient);
    20872083
     2084  //get header rects
     2085  rcHeader = (LPRECT)COMCTL32_Alloc(nColumnCount*sizeof(RECT));
     2086  for (j = 0;j < nColumnCount;j++)
     2087  {
     2088    Header_GetItemRect(infoPtr->hwndHeader,j,&rcHeader[j]);
     2089    rcHeader[j].left += REPORT_MARGINX;
     2090    rcHeader[j].right = max(rcHeader[j].left,rcHeader[j].right-REPORT_MARGINX);
     2091
     2092    /* Offset the Scroll Bar Pos */
     2093    if (dwStyle & WS_HSCROLL)
     2094    {
     2095      rcHeader[j].left -= xOffset;
     2096      rcHeader[j].right -= xOffset;
     2097    }
     2098  }
     2099
    20882100  for (; nItem < nLast; nItem++)
    20892101  {
    2090     nColumnCount = Header_GetItemCount(infoPtr->hwndHeader);
    20912102    for (j = 0; j < nColumnCount; j++)
    20922103    {
    2093       Header_GetItemRect(infoPtr->hwndHeader, j, &rcItem);
    2094       rcItem.left += REPORT_MARGINX;
    2095       rcItem.right = max(rcItem.left, rcItem.right - REPORT_MARGINX);
     2104      rcItem = rcHeader[j];
    20962105      rcItem.top = nDrawPosY;
    20972106      rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
    20982107
    2099       if (rcItem.top >= rcClient.bottom) return;
    2100 
    2101       /* Offset the Scroll Bar Pos */
    2102       if (dwStyle & WS_HSCROLL)
    2103       {
    2104         rcItem.left -= (infoPtr->lefttop.x * LISTVIEW_SCROLL_DIV_SIZE);
    2105         rcItem.right -= (infoPtr->lefttop.x * LISTVIEW_SCROLL_DIV_SIZE);
    2106       }
     2108      if (rcItem.top >= (updateRect ? updateRect->bottom:rcClient.bottom)) goto DR_END;
    21072109
    21082110      if (!updateRect || IntersectRect(NULL,&rcItem,updateRect))
     
    21172119    nDrawPosY += infoPtr->nItemHeight;
    21182120  }
     2121DR_END:
     2122  COMCTL32_Free(rcHeader);
    21192123}
    21202124
     
    21762180    nCountPerColumn =  nListHeight / infoPtr->nItemHeight;
    21772181    if (nCountPerColumn == 0)
    2178     {
    21792182      nCountPerColumn = 1;
    2180     }
    21812183  }
    21822184
     
    22382240  INT nItemWidth = infoPtr->nItemWidth;
    22392241  INT nItemHeight = infoPtr->nItemHeight;
     2242  RECT rcClient;
    22402243
    22412244  /* get number of fully visible columns */
     
    22442247  nItem = LISTVIEW_GetTopIndex(hwnd);
    22452248
     2249  GetClientRect(hwnd,&rcClient);
     2250//CB: todo: hscroll!
    22462251  for (i = 0; i < nColumnCount; i++)
    22472252  {
     
    22552260      rcItem.bottom = rcItem.top + nItemHeight;
    22562261      rcItem.right = rcItem.left + nItemWidth;
    2257       LISTVIEW_DrawItem(hwnd, hdc, nItem, rcItem);
     2262
     2263      if (rcItem.left >= (updateRect ? updateRect->right:rcClient.right)) return;
     2264
     2265      if (!updateRect || IntersectRect(NULL,&rcItem,updateRect))
     2266        LISTVIEW_DrawItem(hwnd, hdc, nItem, rcItem);
    22582267    }
    22592268  }
     
    22732282static VOID LISTVIEW_DrawIcon(HWND hwnd,HDC hdc,BOOL bSmall,RECT *updateRect)
    22742283{
    2275   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
     2284  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    22762285  POINT ptPosition;
    22772286  POINT ptOrigin;
     
    22852294    ptPosition.x += ptOrigin.x;
    22862295    ptPosition.y += ptOrigin.y;
    2287 
     2296//CB: wrong nItemWidth/Height!
    22882297    if (ptPosition.y + infoPtr->nItemHeight > infoPtr->rcList.top)
    22892298    {
     
    22982307            rcItem.bottom = rcItem.top + infoPtr->nItemHeight;
    22992308            rcItem.right = rcItem.left + infoPtr->nItemWidth;
    2300             if (bSmall == FALSE)
     2309            if (!updateRect || IntersectRect(NULL,&rcItem,updateRect))
    23012310            {
    2302               LISTVIEW_DrawLargeItem(hwnd, hdc, i, rcItem);
    2303             }
    2304             else
    2305             {
    2306               LISTVIEW_DrawItem(hwnd, hdc, i, rcItem);
    2307             }
     2311              if (!bSmall)
     2312                LISTVIEW_DrawLargeItem(hwnd, hdc, i, rcItem);
     2313              else
     2314                LISTVIEW_DrawItem(hwnd, hdc, i, rcItem);
     2315            } else if (updateRect && (rcItem.top >= updateRect->bottom)) return;
    23082316          }
    2309         }
     2317        } else return;
    23102318      }
    23112319    }
     
    23262334static VOID LISTVIEW_Draw(HWND hwnd,HDC hdc,RECT *updateRect)
    23272335{
    2328   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
     2336  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    23292337  UINT uView = GetWindowLongA(hwnd, GWL_STYLE) & LVS_TYPEMASK;
    23302338  HFONT hOldFont;
     
    23412349  SelectObject(hdc, GetStockObject(NULL_BRUSH));
    23422350
    2343   if (uView == LVS_LIST)
    2344   {
    2345     LISTVIEW_DrawList(hwnd,hdc,updateRect);
    2346   }
    2347   else if (uView == LVS_REPORT)
    2348   {
    2349     LISTVIEW_DrawReport(hwnd,hdc,updateRect);
    2350   }
    2351   else if (uView == LVS_SMALLICON)
    2352   {
    2353     LISTVIEW_DrawIcon(hwnd,hdc,TRUE,updateRect);
    2354   }
    2355   else if (uView == LVS_ICON)
    2356   {
    2357     LISTVIEW_DrawIcon(hwnd,hdc,FALSE,updateRect);
     2351  switch (uView)
     2352  {
     2353    case LVS_LIST:
     2354      LISTVIEW_DrawList(hwnd,hdc,updateRect);
     2355      break;
     2356
     2357    case LVS_REPORT:
     2358      LISTVIEW_DrawReport(hwnd,hdc,updateRect);
     2359      break;
     2360
     2361    case LVS_SMALLICON:
     2362      LISTVIEW_DrawIcon(hwnd,hdc,TRUE,updateRect);
     2363      break;
     2364
     2365    case LVS_ICON:
     2366      LISTVIEW_DrawIcon(hwnd,hdc,FALSE,updateRect);
     2367      break;
    23582368  }
    23592369
     
    41114121  INT nCountPerColumn;
    41124122  INT nRow;
    4113 
    4114 //  TRACE("(hwnd=%x,nItem=%d,lpptPosition=%p)\n", hwnd, nItem,
    4115 //        lpptPosition);
    4116 
     4123//CB: lefttop position not used!!!
    41174124  if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) &&
    41184125      (lpptPosition != NULL))
     
    45254532  lvItem.mustFree = FALSE;
    45264533  if (LISTVIEW_GetItem(hwnd,(LPLVITEMW)&lvItem,TRUE,TRUE))
    4527     nLabelWidth = LISTVIEW_GetStringWidth(hwnd,lvItem.header.pszText,lvItem.unicode);
     4534    nLabelWidth = LISTVIEW_GetStringWidth(hwnd,0,lvItem.header.pszText,lvItem.unicode);
    45284535  if (lvItem.mustFree) COMCTL32_Free(lvItem.header.pszText);
    45294536
     
    47944801  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
    47954802  UINT uView = dwStyle & LVS_TYPEMASK;
    4796   BOOL bResult = FALSE;
    47974803
    47984804  if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
    47994805  {
    4800     ZeroMemory(lpptOrigin, sizeof(POINT));
    4801 
    48024806    if (dwStyle & WS_HSCROLL)
    48034807      lpptOrigin->x = -infoPtr->lefttop.x*LISTVIEW_SCROLL_DIV_SIZE;
     4808    else
     4809      lpptOrigin->x = 0;
    48044810
    48054811    if (dwStyle & WS_VSCROLL)
    48064812      lpptOrigin->y = -infoPtr->lefttop.y*LISTVIEW_SCROLL_DIV_SIZE;
    4807 
    4808     bResult = TRUE;
    4809   }
    4810 
    4811   return bResult;
     4813    else
     4814      lpptOrigin->y = 0;
     4815
     4816    return TRUE;
     4817  }
     4818
     4819  return FALSE;
    48124820}
    48134821
     
    48674875 *   FAILURE : zero
    48684876 */
    4869 static LRESULT LISTVIEW_GetStringWidth(HWND hwnd,LPWSTR lpszText,BOOL unicode)
     4877static LRESULT LISTVIEW_GetStringWidth(HWND hwnd,HDC hdc,LPWSTR lpszText,BOOL unicode)
    48704878{
    48714879  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
    48724880  HFONT hFont, hOldFont;
    48734881  SIZE stringSize;
    4874   HDC hdc;
    4875 
    4876   ZeroMemory(&stringSize, sizeof(SIZE));
    4877   if (lpszText != NULL)
    4878   {
    4879     hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
    4880     hdc = GetDC(hwnd);
    4881     hOldFont = SelectObject(hdc, hFont);
     4882  BOOL ownDC = FALSE;
     4883
     4884  ZeroMemory(&stringSize,sizeof(SIZE));
     4885  if (lpszText)
     4886  {
     4887    if (!hdc)
     4888    {
     4889      hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
     4890      hdc = GetDC(hwnd);
     4891      hOldFont = SelectObject(hdc, hFont);
     4892      ownDC = TRUE;
     4893    }
    48824894    if (unicode)
    48834895      GetTextExtentPointW(hdc,lpszText,lstrlenW(lpszText),&stringSize);
    48844896    else
    48854897      GetTextExtentPointA(hdc,(LPSTR)lpszText,lstrlenA((LPSTR)lpszText),&stringSize);
    4886     SelectObject(hdc, hOldFont);
    4887     ReleaseDC(hwnd, hdc);
     4898    if (ownDC)
     4899    {
     4900      SelectObject(hdc, hOldFont);
     4901      ReleaseDC(hwnd, hdc);
     4902    }
    48884903  }
    48894904
     
    63936408static LRESULT LISTVIEW_HScroll(HWND hwnd,INT nScrollCode,SHORT nCurrentPos,HWND hScrollWnd)
    63946409{
    6395   SCROLLINFO scrollInfo;
    6396 //CB: todo
    6397   ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
    6398   scrollInfo.cbSize = sizeof(SCROLLINFO);
    6399   scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
    6400 
    6401   if (GetScrollInfo(hwnd, SB_HORZ, &scrollInfo) != FALSE)
    6402   {
    6403     INT nOldScrollPos = scrollInfo.nPos;
    6404 
    6405     switch (nScrollCode)
    6406     {
     6410  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
     6411  INT maxX = infoPtr->maxScroll.x-infoPtr->scrollPage.x,oldX = infoPtr->lefttop.x;
     6412
     6413  switch (nScrollCode)
     6414  {
    64076415    case SB_LINELEFT:
    6408       if (scrollInfo.nPos > scrollInfo.nMin)
    6409       {
    6410         scrollInfo.nPos--;
    6411       }
     6416      if (infoPtr->lefttop.x > 0)
     6417        infoPtr->lefttop.x--;
    64126418      break;
    64136419
    64146420    case SB_LINERIGHT:
    6415       if (scrollInfo.nPos < scrollInfo.nMax)
    6416       {
    6417         scrollInfo.nPos++;
    6418       }
     6421      if (infoPtr->lefttop.x < maxX)
     6422        infoPtr->lefttop.x++;
    64196423      break;
    64206424
    64216425    case SB_PAGELEFT:
    6422       if (scrollInfo.nPos > scrollInfo.nMin)
    6423       {
    6424         if (scrollInfo.nPos >= scrollInfo.nPage)
    6425         {
    6426           scrollInfo.nPos -= scrollInfo.nPage;
    6427         }
     6426      if (infoPtr->lefttop.x > 0)
     6427      {
     6428        if (infoPtr->lefttop.x >= infoPtr->scrollPage.x)
     6429          infoPtr->lefttop.x -= infoPtr->scrollPage.x;
    64286430        else
    6429         {
    6430           scrollInfo.nPos = scrollInfo.nMin;
    6431         }
     6431          infoPtr->lefttop.x = 0;
    64326432      }
    64336433      break;
    64346434
    64356435    case SB_PAGERIGHT:
    6436       if (scrollInfo.nPos < scrollInfo.nMax)
    6437       {
    6438         if (scrollInfo.nPos <= scrollInfo.nMax - scrollInfo.nPage)
    6439         {
    6440           scrollInfo.nPos += scrollInfo.nPage;
    6441         }
     6436      if (infoPtr->lefttop.x < maxX)
     6437      {
     6438        if (infoPtr->lefttop.x <= maxX-infoPtr->scrollPage.x)
     6439          infoPtr->lefttop.x += infoPtr->scrollPage.x;
    64426440        else
    6443         {
    6444           scrollInfo.nPos = scrollInfo.nMax;
    6445         }
     6441          infoPtr->lefttop.x = maxX;
    64466442      }
    64476443      break;
    64486444
    64496445    case SB_THUMBTRACK:
    6450         scrollInfo.nPos = nCurrentPos;
    6451 
    6452         if (scrollInfo.nPos > scrollInfo.nMax)
    6453             scrollInfo.nPos=scrollInfo.nMax;
    6454 
    6455         if (scrollInfo.nPos < scrollInfo.nMin)
    6456             scrollInfo.nPos=scrollInfo.nMin;
    6457 
     6446      infoPtr->lefttop.x = nCurrentPos;
     6447
     6448      if (infoPtr->lefttop.x > maxX)
     6449        infoPtr->lefttop.x = maxX;
     6450
     6451      if (infoPtr->lefttop.x < 0)
     6452        infoPtr->lefttop.x = 0;
    64586453      break;
    6459     }
    6460 
    6461     if (nOldScrollPos != scrollInfo.nPos)
    6462     {
    6463       UINT uView = GetWindowLongA(hwnd, GWL_STYLE) & LVS_TYPEMASK;
    6464       scrollInfo.fMask = SIF_POS;
    6465       SetScrollInfo(hwnd, SB_HORZ, &scrollInfo, TRUE);
    6466       if(uView == LVS_REPORT)
    6467       {
    6468           scrollInfo.fMask = SIF_POS;
    6469           GetScrollInfo(hwnd, SB_HORZ, &scrollInfo);
    6470           LISTVIEW_UpdateHeaderSize(hwnd, scrollInfo.nPos);
    6471       }
    6472       LISTVIEW_Refresh(hwnd);
    6473     }
     6454  }
     6455
     6456  if (oldX != infoPtr->lefttop.x)
     6457  {
     6458    SCROLLINFO scrollInfo;
     6459    RECT rect;
     6460    DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
     6461    UINT uView =  dwStyle & LVS_TYPEMASK;
     6462    INT xScroll = (oldX-infoPtr->lefttop.x)* LISTVIEW_SCROLL_DIV_SIZE;//CB:tocheck
     6463
     6464    ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
     6465    scrollInfo.cbSize = sizeof(SCROLLINFO);
     6466    scrollInfo.nPos   = infoPtr->lefttop.x;
     6467    scrollInfo.fMask  = SIF_POS;
     6468    SetScrollInfo(hwnd,SB_HORZ,&scrollInfo,TRUE);
     6469
     6470    LISTVIEW_ScrollWindow(hwnd,xScroll,0,uView);
    64746471  }
    64756472
     
    69126909 * Zero
    69136910 */
    6914 static LRESULT LISTVIEW_LButtonDown(HWND hwnd, WORD wKey, WORD wPosX,
    6915                                     WORD wPosY)
     6911static LRESULT LISTVIEW_LButtonDown(HWND hwnd, WORD wKey, WORD wPosX, WORD wPosY)
    69166912{
    69176913  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
     
    69206916  POINT ptPosition;
    69216917  INT nItem;
    6922 
     6918//CB: selecting last items in a large list -> high cpu usage!
    69236919  /* send NM_RELEASEDCAPTURE notification */
    69246920  sendNotify(hwnd,NM_RELEASEDCAPTURE);
    69256921
    69266922  if (infoPtr->bFocus == FALSE)
    6927   {
    69286923    SetFocus(hwnd);
    6929   }
    69306924
    69316925  /* set left button down flag */
     
    69406934    {
    69416935      if ((LISTVIEW_GetItemState(hwnd, nItem, LVIS_SELECTED) & LVIS_SELECTED) && infoPtr->bDoEditLabel != TRUE)
    6942       {
     6936        infoPtr->bDoEditLabel = TRUE;
     6937      else
     6938        LISTVIEW_SetSelection(hwnd, nItem);
     6939    }
     6940    else
     6941    {
     6942      if ((wKey & MK_CONTROL) && (wKey & MK_SHIFT))
     6943      {
     6944        if (bGroupSelect != FALSE)
     6945        {
     6946          LISTVIEW_AddGroupSelection(hwnd, nItem);
     6947        }
     6948        else
     6949        {
     6950          LISTVIEW_AddSelection(hwnd, nItem);
     6951        }
     6952      }
     6953      else if (wKey & MK_CONTROL)
     6954      {
     6955        bGroupSelect = LISTVIEW_ToggleSelection(hwnd, nItem);
     6956      }
     6957      else  if (wKey & MK_SHIFT)
     6958      {
     6959        LISTVIEW_SetGroupSelection(hwnd, nItem);
     6960      }
     6961      else
     6962      {
     6963        if ((LISTVIEW_GetItemState(hwnd, nItem, LVIS_SELECTED) & LVIS_SELECTED) && (infoPtr->bDoEditLabel != TRUE))
    69436964          infoPtr->bDoEditLabel = TRUE;
    6944       }
    6945       else
    6946       {
    6947         LISTVIEW_SetSelection(hwnd, nItem);
    6948       }
    6949     }
    6950     else
    6951     {
    6952       if ((wKey & MK_CONTROL) && (wKey & MK_SHIFT))
    6953       {
    6954         if (bGroupSelect != FALSE)
    6955         {
    6956           LISTVIEW_AddGroupSelection(hwnd, nItem);
    6957         }
    69586965        else
    6959         {
    6960           LISTVIEW_AddSelection(hwnd, nItem);
    6961         }
    6962       }
    6963       else if (wKey & MK_CONTROL)
    6964       {
    6965         bGroupSelect = LISTVIEW_ToggleSelection(hwnd, nItem);
    6966       }
    6967       else  if (wKey & MK_SHIFT)
    6968       {
    6969         LISTVIEW_SetGroupSelection(hwnd, nItem);
    6970       }
    6971       else
    6972       {
    6973         if ((LISTVIEW_GetItemState(hwnd, nItem, LVIS_SELECTED) & LVIS_SELECTED) && (infoPtr->bDoEditLabel != TRUE))
    6974         {
    6975           infoPtr->bDoEditLabel = TRUE;
    6976         }
    6977         else
    6978         {
    69796966          LISTVIEW_SetSelection(hwnd, nItem);
    6980         }
    69816967      }
    69826968    }
     
    73827368 * DefWinProc return value
    73837369 */
    7384 static LRESULT LISTVIEW_SetRedraw(HWND hwnd, BOOL bRedraw)
    7385 {
     7370static LRESULT LISTVIEW_SetRedraw(HWND hwnd,BOOL bRedraw)
     7371{
     7372  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    73867373  LRESULT lResult;
    7387 //CB:todo
    7388   lResult = DefWindowProcA(hwnd, WM_SETREDRAW, bRedraw, 0);
    7389   //if (bRedraw)
    7390   //  RedrawWindow(hwnd,NULL,0,RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN | RDW_ERASENOW);
     7374
     7375  if (bRedraw)
     7376  {
     7377    infoPtr->refreshFlags &= ~RF_NOREDRAW;
     7378    lResult = DefWindowProcA(hwnd, WM_SETREDRAW, bRedraw, 0);
     7379
     7380    LISTVIEW_UpdateScroll(hwnd);
     7381    //CB: WINE calls RedrawWindow but many (all?) programs invalidate the control themself
     7382    //  RedrawWindow(hwnd,NULL,0,RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN | RDW_ERASENOW);
     7383  } else
     7384  {
     7385    infoPtr->refreshFlags |= RF_NOREDRAW;
     7386    if (infoPtr->refreshFlags & RF_REFRESH)
     7387      KillTimer(hwnd,LV_REFRESH_TIMER);
     7388    infoPtr->refreshFlags &= ~(RF_REFRESH | RF_UPDATESCROLL);
     7389    lResult = DefWindowProcA(hwnd, WM_SETREDRAW, bRedraw, 0);
     7390  }
    73917391
    73927392  return lResult;
     
    74087408static LRESULT LISTVIEW_Size(HWND hwnd, int Width, int Height)
    74097409{
     7410  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    74107411  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
    74117412  UINT uView = lStyle & LVS_TYPEMASK;
    74127413
    7413 //  TRACE("(hwnd=%x, width=%d, height=%d)\n",hwnd, Width, Height);
    7414 
    74157414  LISTVIEW_UpdateSize(hwnd);
    74167415
     
    74277426  }
    74287427
    7429   LISTVIEW_UpdateScroll(hwnd);
    7430 
    74317428  /* invalidate client area + erase background */
    7432   LISTVIEW_Refresh(hwnd);//CB:tocheck
     7429  infoPtr->refreshFlags |= RF_UPDATESCROLL;
     7430  LISTVIEW_QueueRefresh(hwnd);
    74337431
    74347432  return 0;
     
    74477445static VOID LISTVIEW_UpdateSize(HWND hwnd)
    74487446{
    7449   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)LISTVIEW_GetInfoPtr(hwnd);
     7447  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO*)LISTVIEW_GetInfoPtr(hwnd);
    74507448  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
    74517449  UINT uView = lStyle & LVS_TYPEMASK;
     
    79667964
    79677965  case LVM_GETSTRINGWIDTHA:
    7968     return LISTVIEW_GetStringWidth(hwnd,(LPWSTR)lParam,FALSE);
     7966    return LISTVIEW_GetStringWidth(hwnd,0,(LPWSTR)lParam,FALSE);
    79697967
    79707968  case LVM_GETSTRINGWIDTHW:
    7971     return LISTVIEW_GetStringWidth(hwnd,(LPWSTR)lParam,TRUE);
     7969    return LISTVIEW_GetStringWidth(hwnd,0,(LPWSTR)lParam,TRUE);
    79727970
    79737971/*      case LVM_GETSUBITEMRECT: */
Note: See TracChangeset for help on using the changeset viewer.