Ignore:
Timestamp:
Feb 12, 2000, 7:10:40 PM (26 years ago)
Author:
cbratschi
Message:

next steps

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/comctl32/treeview.c

    r2740 r2769  
    1 /* $Id: treeview.c,v 1.23 2000-02-10 18:51:19 cbratschi Exp $ */
     1/* $Id: treeview.c,v 1.24 2000-02-12 18:10:40 cbratschi Exp $ */
    22/* Treeview control
    33 *
     
    3232 *   WM_HSCROLL is broken.
    3333 *   use separate routine to get item text/image.
    34  *   WM_SETREDRAW isn't handled
    3534 *
    3635 *   Separate drawing/calculation.
     
    4443
    4544/* WINE 991212 level */
     45
     46/* CB: todo
     47
     48 - sub parent lines aren't redrawn in expand handler
     49 - invisible sibling lines aren't drawn in WM_PAINT
     50 - WM_LBUTTONDOWN: bug in highlight code
     51 - WM_SIZE: redraw doesn't work
     52 - hscroll not set
     53
     54*/
    4655
    4756#include <string.h>
     
    7483static void    TREEVIEW_Refresh(HWND hwnd);
    7584static void    TREEVIEW_Draw(HWND hwnd,HDC hdc,RECT *updateRect);
     85static void    TREEVIEW_UnqueueRefresh(HWND hwnd,BOOL calc,BOOL refresh);
     86static void    TREEVIEW_QueueRefresh(HWND hwnd);
    7687
    7788static LRESULT CALLBACK TREEVIEW_Edit_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
     
    488499
    489500  //CB: todo
    490   TREEVIEW_Refresh(hwnd);
     501  if (!(infoPtr->uInternalStatus & TV_NOREDRAW))
     502    TREEVIEW_Refresh(hwnd);
    491503
    492504  return 1;
     
    539551#define TREEVIEW_LEFT_MARGIN 8
    540552
     553//CB: hack for PS_DOT bug in Open32 pen handling
     554
     555BOOL drawPixel;
     556HDC  drawDC;
     557
     558VOID CALLBACK TREEVIEW_DDAProc(int x,int y,LPARAM lpData)
     559{
     560  if (drawPixel) SetPixel(drawDC,x,y,(COLORREF)lpData);
     561  else SetPixel(drawDC,x,y,RGB(255,255,255));
     562  drawPixel = !drawPixel;
     563}
     564
     565static void TREEVIEW_Polyline(HDC hdc,const POINT *lppt,int cPoints,COLORREF color)
     566{
     567  INT x;
     568
     569  drawPixel = TRUE;
     570  drawDC = hdc;
     571  for (x = 0;x < cPoints-1;x++)
     572    LineDDA(lppt[x].x,lppt[x].y,lppt[x+1].x,lppt[x+1].y,TREEVIEW_DDAProc,color);
     573}
    541574
    542575static void
     
    550583  RECT  r;
    551584
    552 
    553585  if (wineItem->state & TVIS_BOLD)
    554         hOldFont = SelectObject (hdc, infoPtr->hBoldFont);
     586    hOldFont = SelectObject (hdc, infoPtr->hBoldFont);
    555587  else
    556         hOldFont = SelectObject (hdc, infoPtr->hFont);
    557 
    558   cditem=0;
    559   //TRACE ("cdmode:%x\n",infoPtr->cdmode);
    560   if (infoPtr->cdmode & CDRF_NOTIFYITEMDRAW) {
    561                 cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc,
    562                              wineItem, CDDS_ITEMPREPAINT);
    563 
    564                 if (cditem & CDRF_SKIPDEFAULT)
    565                         return;
    566         }
     588    hOldFont = SelectObject (hdc, infoPtr->hFont);
     589
     590  cditem = 0;
     591
     592  if (infoPtr->cdmode & CDRF_NOTIFYITEMDRAW)
     593  {
     594    cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, wineItem, CDDS_ITEMPREPAINT);
     595
     596    if (cditem & CDRF_SKIPDEFAULT) return;
     597  }
    567598
    568599  /*
     
    576607   * Display the tree hierarchy
    577608   */
    578   if ( dwStyle & TVS_HASLINES)
     609  if ((dwStyle & TVS_HASLINES) && (wineItem->hItem != infoPtr->TopRootItem))
    579610  {
    580611    /*
     
    586617     * points[2] is attached to the parent or the up sibling
    587618     */
    588     if ( dwStyle & TVS_LINESATROOT)
     619    if (dwStyle & TVS_LINESATROOT)
    589620    {
    590621      TREEVIEW_ITEM *upNode    = NULL;
    591         BOOL  hasParentOrSibling = TRUE;
     622      BOOL  hasParentOrSibling = TRUE;
    592623      RECT  upRect             = {0,0,0,0};
    593624      HPEN  hOldPen, hnewPen;
    594         POINT points[3];
     625      POINT points[3];
    595626      /*
    596627       * determine the target location of the line at root, either be linked
     
    606637      if (upNode)
    607638        upRect = upNode->rect;
    608 
    609       if ( wineItem->iLevel == 0 )
     639//CB: todo: draw full lines to avoid problems with PS_DOT and scrolling
     640      if (wineItem->iLevel == 0)
    610641      {
    611642        points[2].x = points[1].x = upRect.left+8;
     
    613644        points[2].y = upRect.bottom-3;
    614645        points[1].y = points[0].y = center;
    615       }
    616       else
     646      } else
    617647      {
    618648        points[2].x = points[1].x = 8 + (20*wineItem->iLevel);
    619         points[2].y = ( upNode->cChildren == 0) ?
     649        points[2].y = (upNode->cChildren == 0) ?
    620650                        upRect.top :        /* is linked to the "L" above */
    621651                        ( wineItem->upsibling != NULL) ?
     
    629659       * Get a dotted pen
    630660       */
     661#if 0 //CB: workaround for Open32 PS_DOT bug
    631662      hnewPen = CreatePen(PS_DOT, 0, infoPtr->clrLine);
    632663      hOldPen = SelectObject( hdc, hnewPen );
    633664
    634665      if (hasParentOrSibling)
    635         Polyline (hdc,points,3);
     666        Polyline(hdc,points,3);
    636667      else
    637         Polyline (hdc,points,2);
     668        Polyline(hdc,points,2);
    638669
    639670      DeleteObject(hnewPen);
    640671      SelectObject(hdc, hOldPen);
     672#else
     673      if (hasParentOrSibling)
     674        TREEVIEW_Polyline(hdc,points,3,infoPtr->clrLine);
     675      else
     676        TREEVIEW_Polyline(hdc,points,2,infoPtr->clrLine);
     677#endif
    641678    }
    642679  }
     
    650687  if (( dwStyle & TVS_HASBUTTONS) && ( dwStyle & TVS_HASLINES))
    651688  {
    652           if ( (wineItem->cChildren) ||
    653                (wineItem->cChildren == I_CHILDRENCALLBACK))
     689    if ( (wineItem->cChildren) ||
     690         (wineItem->cChildren == I_CHILDRENCALLBACK))
    654691    {
    655692      /* Setup expand box coordinate to facilitate the LMBClick handling */
     
    659696      wineItem->expandBox.bottom = center+5;
    660697
    661                 Rectangle (
    662         hdc,
    663         wineItem->expandBox.left,
    664         wineItem->expandBox.top ,
    665         wineItem->expandBox.right,
    666         wineItem->expandBox.bottom);
    667 
    668                 MoveToEx (hdc, xpos-2, center, NULL);
    669                 LineTo   (hdc, xpos+3, center);
    670 
    671                 if (!(wineItem->state & TVIS_EXPANDED)) {
    672                         MoveToEx (hdc, xpos,   center-2, NULL);
    673                         LineTo   (hdc, xpos,   center+3);
    674           }
     698      Rectangle(hdc,wineItem->expandBox.left,wineItem->expandBox.top,wineItem->expandBox.right,wineItem->expandBox.bottom);
     699
     700      MoveToEx (hdc, xpos-2, center, NULL);
     701      LineTo   (hdc, xpos+3, center);
     702
     703      if (!(wineItem->state & TVIS_EXPANDED))
     704      {
     705        MoveToEx (hdc, xpos,   center-2, NULL);
     706        LineTo   (hdc, xpos,   center+3);
     707      }
    675708    }
    676709  }
     
    680713   */
    681714  xpos += 13; /* update position */
    682   if (wineItem->mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
     715  if (wineItem->mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE))
     716  {
    683717    INT        imageIndex;
    684718    HIMAGELIST *himlp = NULL;
    685719
    686    /* State images are displayed to the left of the Normal image
    687     * image number is in state; zero should be `display no image'.
    688     * FIXME: that last sentence looks like it needs some checking.
    689     */
    690         if (infoPtr->himlState)
    691         himlp=&infoPtr->himlState;
    692         imageIndex=wineItem->state>>12;
    693         imageIndex++;          /* yeah, right */
    694         //TRACE ("imindex:%d\n",imageIndex);
     720    /* State images are displayed to the left of the Normal image
     721     * image number is in state; zero should be `display no image'.
     722     * FIXME: that last sentence looks like it needs some checking.
     723     */
     724    if (infoPtr->himlState)
     725      himlp=&infoPtr->himlState;
     726    imageIndex=wineItem->state>>12;
     727    imageIndex++;          /* yeah, right */
     728
    695729    if ((himlp) && (imageIndex))
    696730    {
    697           imageIndex--;       /* see FIXME */
     731      imageIndex--;       /* see FIXME */
    698732      ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL);
    699           ImageList_GetIconSize (*himlp, &cx, &cy);
    700           wineItem->statebitmap.left=xpos-2;
    701           wineItem->statebitmap.right=xpos-2+cx;
    702           wineItem->statebitmap.top=r.top+1;
    703           wineItem->statebitmap.bottom=r.top+1+cy;
    704           xpos+=cx;
     733      ImageList_GetIconSize (*himlp, &cx, &cy);
     734      wineItem->statebitmap.left=xpos-2;
     735      wineItem->statebitmap.right=xpos-2+cx;
     736      wineItem->statebitmap.top=r.top+1;
     737      wineItem->statebitmap.bottom=r.top+1+cy;
     738      xpos += cx;
    705739    }
    706740
    707                 /* Now, draw the normal image; can be either selected or
    708                  * non-selected image.
    709                  */
    710 
    711         himlp=NULL;
    712         if (infoPtr->himlNormal)
     741    /* Now, draw the normal image; can be either selected or
     742     * non-selected image.
     743     */
     744
     745    himlp=NULL;
     746    if (infoPtr->himlNormal)
    713747      himlp=&infoPtr->himlNormal; /* get the image list */
    714748
    715749    imageIndex = wineItem->iImage;
    716         if ( (wineItem->state & TVIS_SELECTED) &&
    717          (wineItem->iSelectedImage)) {
     750    if ( (wineItem->state & TVIS_SELECTED) &&
     751         (wineItem->iSelectedImage))
     752    {
    718753
    719754      /* The item is curently selected */
    720                   if (wineItem->iSelectedImage == I_IMAGECALLBACK)
    721                         TREEVIEW_SendDispInfoNotify
    722                                         (hwnd, wineItem, TVN_GETDISPINFO, TVIF_SELECTEDIMAGE);
    723 
    724           imageIndex = wineItem->iSelectedImage;
    725           } else {
     755      if (wineItem->iSelectedImage == I_IMAGECALLBACK)
     756        TREEVIEW_SendDispInfoNotify(hwnd, wineItem, TVN_GETDISPINFO, TVIF_SELECTEDIMAGE);
     757
     758      imageIndex = wineItem->iSelectedImage;
     759    } else
     760    {
    726761      /* The item is not selected */
    727                   if (wineItem->iImage == I_IMAGECALLBACK)
    728                           TREEVIEW_SendDispInfoNotify
    729                                         (hwnd, wineItem, TVN_GETDISPINFO, TVIF_IMAGE);
     762      if (wineItem->iImage == I_IMAGECALLBACK)
     763        TREEVIEW_SendDispInfoNotify(hwnd, wineItem, TVN_GETDISPINFO, TVIF_IMAGE);
    730764
    731765      imageIndex = wineItem->iImage;
    732         }
     766    }
    733767
    734768    if (himlp)
    735769    {
    736770      ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL);
    737           ImageList_GetIconSize (*himlp, &cx, &cy);
    738           wineItem->bitmap.left=xpos-2;
    739           wineItem->bitmap.right=xpos-2+cx;
    740           wineItem->bitmap.top=r.top+1;
    741           wineItem->bitmap.bottom=r.top+1+cy;
    742           xpos+=cx;
     771      ImageList_GetIconSize (*himlp, &cx, &cy);
     772      wineItem->bitmap.left=xpos-2;
     773      wineItem->bitmap.right=xpos-2+cx;
     774      wineItem->bitmap.top=r.top+1;
     775      wineItem->bitmap.bottom=r.top+1+cy;
     776      xpos += cx;
    743777    }
    744778  }
     
    763797    wineItem->text.bottom= r.bottom;
    764798
    765     if (wineItem->pszText== LPSTR_TEXTCALLBACKA) {
     799    if (wineItem->pszText== LPSTR_TEXTCALLBACKA)
     800    {
    766801      //TRACE("LPSTR_TEXTCALLBACK\n");
    767802      TREEVIEW_SendDispInfoNotify (hwnd, wineItem, TVN_GETDISPINFO, TVIF_TEXT);
     
    782817
    783818    if (!(cditem & CDRF_NOTIFYPOSTPAINT) &&
    784         (wineItem->state & (TVIS_SELECTED | TVIS_DROPHILITED)) ) {
    785         oldBkMode    = SetBkMode  (hdc, OPAQUE);
    786         oldBkColor   = SetBkColor  (hdc, GetSysColor( COLOR_HIGHLIGHT));
    787         oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT));
    788         } else {
    789         oldBkMode    = SetBkMode  (hdc, TRANSPARENT);
    790                 oldBkColor   = SetBkColor (hdc, infoPtr->clrBk);
     819        (wineItem->state & (TVIS_SELECTED | TVIS_DROPHILITED)) )
     820    {
     821      oldBkMode    = SetBkMode  (hdc, OPAQUE);
     822      oldBkColor   = SetBkColor  (hdc, GetSysColor( COLOR_HIGHLIGHT));
     823      oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT));
     824    } else
     825    {
     826      oldBkMode    = SetBkMode  (hdc, TRANSPARENT);
     827      oldBkColor   = SetBkColor (hdc, infoPtr->clrBk);
    791828 /*         oldTextColor = SetTextColor(hdc, infoPtr->clrText);  */
    792         }
     829    }
    793830
    794831
     
    845882  //              TRACE ("item:%d,mark:%d\n", (int)wineItem->hItem,
    846883  //                             (int) infoPtr->insertMarkItem);
    847   if (wineItem->hItem==infoPtr->insertMarkItem) {
    848                 HPEN hNewPen, hOldPen;
    849                 int offset;
    850 
    851                 hNewPen = CreatePen(PS_SOLID, 2, infoPtr->clrInsertMark);
    852                 hOldPen = SelectObject( hdc, hNewPen );
    853 
    854                 if (infoPtr->insertBeforeorAfter)
    855                         offset=wineItem->text.top+1;
    856                 else
    857                         offset=wineItem->text.bottom-1;
    858 
    859                 MoveToEx (hdc, wineItem->text.left, offset-3, NULL);
    860                 LineTo (hdc, wineItem->text.left, offset+3);
    861 
    862                 MoveToEx (hdc, wineItem->text.left, offset, NULL);
    863                 LineTo (hdc, r.right-2, offset);
    864 
    865                 MoveToEx (hdc, r.right-2, offset+3, NULL);
    866                 LineTo (hdc, r.right-2, offset-3);
    867 
    868         DeleteObject(hNewPen);
    869 
    870         SelectObject(hdc, hOldPen);
    871         }
    872 
    873   if (cditem & CDRF_NOTIFYPOSTPAINT) {
    874                 cditem=TREEVIEW_SendCustomDrawItemNotify
    875                        (hwnd, hdc, wineItem, CDDS_ITEMPOSTPAINT);
    876                 //TRACE("postpaint:cditem-app returns 0x%x\n",cditem);
    877         }
     884  if (wineItem->hItem==infoPtr->insertMarkItem)
     885  {
     886    HPEN hNewPen, hOldPen;
     887    int offset;
     888
     889    hNewPen = CreatePen(PS_SOLID, 2, infoPtr->clrInsertMark);
     890    hOldPen = SelectObject( hdc, hNewPen );
     891
     892    if (infoPtr->insertBeforeorAfter)
     893      offset=wineItem->text.top+1;
     894    else
     895      offset=wineItem->text.bottom-1;
     896
     897    MoveToEx (hdc, wineItem->text.left, offset-3, NULL);
     898    LineTo (hdc, wineItem->text.left, offset+3);
     899
     900    MoveToEx (hdc, wineItem->text.left, offset, NULL);
     901    LineTo (hdc, r.right-2, offset);
     902
     903    MoveToEx (hdc, r.right-2, offset+3, NULL);
     904    LineTo (hdc, r.right-2, offset-3);
     905
     906    DeleteObject(hNewPen);
     907
     908    SelectObject(hdc, hOldPen);
     909  }
     910
     911  if (cditem & CDRF_NOTIFYPOSTPAINT)
     912  {
     913    cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, wineItem, CDDS_ITEMPOSTPAINT);
     914    //TRACE("postpaint:cditem-app returns 0x%x\n",cditem);
     915  }
    878916
    879917  SelectObject (hdc, hOldFont);
     
    894932  if (lpRect == NULL)
    895933    return FALSE;
     934
     935  TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE);
    896936
    897937  /*
     
    10071047{
    10081048    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    1009         TREEVIEW_ITEM *wineItem;
    1010 
    1011         wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)wParam);
    1012         if (!wineItem) return 0;
    1013 
    1014         return (wineItem->state & lParam);
     1049    TREEVIEW_ITEM *wineItem;
     1050
     1051    wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)wParam);
     1052    if (!wineItem) return 0;
     1053
     1054    return (wineItem->state & lParam);
     1055}
     1056
     1057static void TREEVIEW_Refresh(HWND hwnd)
     1058{
     1059  InvalidateRect(hwnd,NULL,TRUE);
    10151060}
    10161061
     
    10191064  if (item && item->visible)
    10201065  {
    1021     //CB: todo: only redraw text and icon
    1022     InvalidateRect(hwnd,&item->rect,TRUE);
    1023   }
    1024 }
    1025 
    1026 static void TREEVIEW_Refresh(HWND hwnd)
    1027 {
    1028   InvalidateRect(hwnd,NULL,TRUE);
    1029 }
    1030 
    1031 static void TREEVIEW_CalcItems(HWND hwnd)
    1032 {
    1033   //CB: todo: TREEVIEW_Draw should only draw, not calculate!
    1034 }
    1035 
    1036 static void TREEVIEW_SetScrollbars(HWND hwnd)
    1037 {
    1038   //CB: todo: dito
    1039 }
    1040 
    1041 static int TREEVIEW_GetFirstVisibleItem(HWND hwnd)
    1042 {
    1043   //CB: todo
    1044 
    1045   return 0;
     1066    RECT rect = item->rect;
     1067
     1068    rect.left += TREEVIEW_LEFT_MARGIN;
     1069    if (item->iLevel != 0) rect.left += (5*item->iLevel);
     1070    rect.left += 15;
     1071    InvalidateRect(hwnd,&rect,TRUE);
     1072  }
     1073}
     1074
     1075//CB: HDC parameter is optional
     1076
     1077static void TREEVIEW_CalcItems(HWND hwnd,HDC hdc,TREEVIEW_INFO *infoPtr)
     1078{
     1079  TREEVIEW_ITEM *item,*prevItem;
     1080  INT iItem, indent, x, y, cx, height, itemHeight;
     1081  TEXTMETRICA tm;
     1082  RECT rect,view;
     1083  BOOL ownDC = FALSE;
     1084
     1085  GetClientRect(hwnd,&rect);
     1086  infoPtr->uVisibleHeight = rect.bottom-rect.top;
     1087  infoPtr->uVisibleWidth = rect.right-rect.left;
     1088  view = rect;
     1089  OffsetRect(&view,infoPtr->cx,infoPtr->cy);
     1090
     1091  iItem = (INT)infoPtr->TopRootItem;
     1092  infoPtr->firstVisible = 0;
     1093  item = NULL;
     1094  indent = 0;
     1095  x = y = 0;
     1096
     1097  while (iItem)
     1098  {
     1099    prevItem = item;
     1100    item = &infoPtr->items[iItem];
     1101    item->iLevel = indent;
     1102
     1103    if ((infoPtr->uInternalStatus & TV_CALCALL) || !item->calculated)
     1104    {
     1105      ImageList_GetIconSize(infoPtr->himlNormal,&cx,&itemHeight);
     1106      if (infoPtr->uItemHeight > itemHeight)
     1107        itemHeight = infoPtr->uItemHeight;
     1108
     1109      if (!hdc)
     1110      {
     1111        ownDC = TRUE;
     1112        hdc = GetDC(hwnd);
     1113      }
     1114
     1115      GetTextMetricsA(hdc,&tm);
     1116      if ((tm.tmHeight + tm.tmExternalLeading) > itemHeight)
     1117        itemHeight = tm.tmHeight + tm.tmExternalLeading;
     1118
     1119      infoPtr->uRealItemHeight = itemHeight;
     1120
     1121      height = itemHeight * item->iIntegral +1;
     1122      item->calculated = TRUE;
     1123    } else height = infoPtr->uRealItemHeight*item->iIntegral+1;
     1124
     1125    item->rect.top    = y - infoPtr->cy + rect.top;
     1126    item->rect.bottom = item->rect.top + height ;
     1127    item->rect.left   = x - infoPtr->cx + rect.left;
     1128    item->rect.right  = rect.right;
     1129
     1130    if ((((y >= view.top) && (y <= view.bottom)) || ((y+height >= view.top) && (y+height <= view.bottom))) &&
     1131        (x >= view.left) && (x <= view.right))
     1132    {
     1133      item->visible     = TRUE;
     1134      if (!infoPtr->firstVisible)
     1135        infoPtr->firstVisible = item->hItem;
     1136    } else item->visible    = FALSE;
     1137
     1138    /* look up next item */
     1139
     1140    if ((item->firstChild) && (item->state & TVIS_EXPANDED))
     1141    {
     1142      iItem = (INT)item->firstChild;
     1143      indent++;
     1144      x += infoPtr->uIndent;
     1145      if (x > infoPtr->uTotalWidth)
     1146        infoPtr->uTotalWidth=x;
     1147    } else
     1148    {
     1149      iItem = (INT)item->sibling;
     1150      while ((!iItem) && (indent > 0))
     1151      {
     1152        indent--;
     1153        x -= infoPtr->uIndent;
     1154        prevItem = item;
     1155        item =& infoPtr->items[(INT)item->parent];
     1156        iItem = (INT)item->sibling;
     1157      }
     1158    }
     1159    y +=height;
     1160  } /* while */
     1161
     1162  if (ownDC) ReleaseDC(hwnd,hdc);
     1163
     1164/* FIXME: infoPtr->uTotalWidth should also take item label into account */
     1165
     1166  infoPtr->uTotalHeight = y;
     1167
     1168  infoPtr->uInternalStatus &= ~TV_CALCALL;
     1169
     1170//CB: todo: use SetScrollInfo, HSCROLL
     1171
     1172  if (infoPtr->uTotalHeight >= infoPtr->uVisibleHeight)
     1173  {
     1174    if (!(infoPtr->uInternalStatus & TV_VSCROLL))
     1175      ShowScrollBar (hwnd, SB_VERT, TRUE);
     1176    infoPtr->uInternalStatus |= TV_VSCROLL;
     1177    SetScrollRange (hwnd, SB_VERT, 0, infoPtr->uTotalHeight - infoPtr->uVisibleHeight, FALSE);
     1178    SetScrollPos (hwnd, SB_VERT, infoPtr->cy, TRUE);
     1179  } else
     1180  {
     1181    if (infoPtr->uInternalStatus & TV_VSCROLL)
     1182      ShowScrollBar (hwnd, SB_VERT, FALSE);
     1183    infoPtr->uInternalStatus &= ~TV_VSCROLL;
     1184  }
    10461185}
    10471186
     
    10501189{
    10511190    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    1052     TEXTMETRICA tm;
    10531191    HBRUSH hbrBk;
    1054     RECT rect,view;
    1055     INT iItem, indent, x, y, cx, height, itemHeight;
    1056     TREEVIEW_ITEM *wineItem, *prevItem;
    1057 
    1058     //TRACE("\n");
     1192    RECT rect;
     1193    TREEVIEW_ITEM *item;
     1194    INT iItem,indent;
     1195    INT visIndent = -1;
     1196
     1197    TREEVIEW_UnqueueRefresh(hwnd,TRUE,FALSE);
    10591198
    10601199    GetClientRect (hwnd, &rect);
    1061     if ((rect.left-rect.right ==0) || (rect.top-rect.bottom==0)) return;
    1062 
    1063     infoPtr->cdmode=TREEVIEW_SendCustomDrawNotify
    1064                                                 (hwnd, CDDS_PREPAINT, hdc, rect);
    1065 
    1066     if (infoPtr->cdmode==CDRF_SKIPDEFAULT) return;
    1067 
    1068     infoPtr->uVisibleHeight= rect.bottom-rect.top;
    1069     infoPtr->uVisibleWidth= rect.right-rect.left;
    1070 
    1071     view = updateRect ? *updateRect:rect;
    1072     view.left = 0;
    1073     view.right = rect.right;
    1074     OffsetRect(&view,infoPtr->cx,infoPtr->cy);
     1200    if ((rect.left == rect.right) || (rect.top == rect.bottom)) return;
     1201
     1202    infoPtr->cdmode = TREEVIEW_SendCustomDrawNotify(hwnd, CDDS_PREPAINT, hdc, rect);
     1203
     1204    if (infoPtr->cdmode == CDRF_SKIPDEFAULT) return;
    10751205
    10761206    /* draw background */
     
    10801210    DeleteObject(hbrBk);
    10811211
    1082     iItem=(INT)infoPtr->TopRootItem;
    1083     infoPtr->firstVisible=0;
    1084     wineItem=NULL;
    1085     indent=0;
    1086     x=y=0;
    1087 
    1088     while (iItem) {
    1089                 prevItem=wineItem;
    1090         wineItem= & infoPtr->items[iItem];
    1091                 wineItem->iLevel=indent;
    1092 
    1093         ImageList_GetIconSize (infoPtr->himlNormal, &cx, &itemHeight);
    1094         if (infoPtr->uItemHeight>itemHeight)
    1095                     itemHeight=infoPtr->uItemHeight;
    1096 
    1097             GetTextMetricsA (hdc, &tm);
    1098             if ((tm.tmHeight + tm.tmExternalLeading) > itemHeight)
    1099                      itemHeight=tm.tmHeight + tm.tmExternalLeading;
    1100 
    1101         infoPtr->uRealItemHeight=itemHeight;
    1102 
    1103                 height=itemHeight * wineItem->iIntegral +1;
    1104                 if ((((y >= view.top) && (y <= view.bottom)) || ((y+height >= view.top) && (y+height <= view.bottom))) &&
    1105                     (x >= view.left) && (x <= view.right))
    1106                 {
    1107                                 wineItem->visible = TRUE;
    1108                         wineItem->rect.top = y - infoPtr->cy + rect.top;
    1109                         wineItem->rect.bottom = wineItem->rect.top + height ;
    1110                         wineItem->rect.left = x - infoPtr->cx + rect.left;
    1111                         wineItem->rect.right = rect.right;
    1112                         if (!infoPtr->firstVisible)
    1113                                 infoPtr->firstVisible=wineItem->hItem;
    1114                 TREEVIEW_DrawItem (hwnd, hdc, wineItem);
    1115                 }
    1116                 else {
    1117                         wineItem->visible   = FALSE;
    1118                         wineItem->rect.left = wineItem->rect.top    = 0;
    1119                         wineItem->rect.right= wineItem->rect.bottom = 0;
    1120                         wineItem->text.left = wineItem->text.top    = 0;
    1121                         wineItem->text.right= wineItem->text.bottom = 0;
    1122                 }
    1123 
    1124                 /* look up next item */
    1125 
    1126                 if ((wineItem->firstChild) && (wineItem->state & TVIS_EXPANDED)) {
    1127                         iItem=(INT)wineItem->firstChild;
    1128                         indent++;
    1129                         x+=infoPtr->uIndent;
    1130                         if (x>infoPtr->uTotalWidth)
    1131                                 infoPtr->uTotalWidth=x;
    1132                 }
    1133                 else {
    1134                         iItem=(INT)wineItem->sibling;
    1135                         while ((!iItem) && (indent>0)) {
    1136                                 indent--;
    1137                                 x-=infoPtr->uIndent;
    1138                                 prevItem=wineItem;
    1139                                 wineItem=&infoPtr->items[(INT)wineItem->parent];
    1140                                 iItem=(INT)wineItem->sibling;
    1141                         }
    1142                 }
    1143         y +=height;
    1144     }                           /* while */
    1145 
    1146 /* FIXME: infoPtr->uTotalWidth should also take item label into account */
    1147 /* FIXME: or should query item sizes (ie check CDRF_NEWFONT) */
    1148 
    1149     infoPtr->uTotalHeight=y;
    1150     if (y >= (view.bottom-view.top)) {
    1151                 if (!(infoPtr->uInternalStatus & TV_VSCROLL))
    1152                         ShowScrollBar (hwnd, SB_VERT, TRUE);
    1153                 infoPtr->uInternalStatus |=TV_VSCROLL;
    1154                 SetScrollRange (hwnd, SB_VERT, 0,
    1155                                         y - infoPtr->uVisibleHeight, FALSE);
    1156                 SetScrollPos (hwnd, SB_VERT, infoPtr->cy, TRUE);
     1212    //draw items
     1213
     1214    iItem = (INT)infoPtr->TopRootItem;
     1215    indent = 0;
     1216
     1217    while (iItem)
     1218    {
     1219      item = &infoPtr->items[iItem];
     1220      /* FIXME: should query item sizes (ie check CDRF_NEWFONT) */
     1221      if (item->visible)
     1222      {
     1223        if (updateRect && IntersectRect(NULL,&item->rect,updateRect)) TREEVIEW_DrawItem(hwnd,hdc,item);
     1224        visIndent = indent;
     1225      } else if (visIndent != -1)
     1226      {
     1227        //draw vertical connections
     1228
     1229        if (visIndent == 0) break;
     1230
     1231        if (indent < visIndent)
     1232        {
     1233//CB: todo
     1234          visIndent = indent;
    11571235        }
    1158     else {
    1159                 if (infoPtr->uInternalStatus & TV_VSCROLL)
    1160                         ShowScrollBar (hwnd, SB_VERT, FALSE);
    1161                 infoPtr->uInternalStatus &= ~TV_VSCROLL;
     1236      }
     1237      if ((item->firstChild) && (item->state & TVIS_EXPANDED))
     1238      {
     1239        iItem = (INT)item->firstChild;
     1240        indent++;
     1241      } else
     1242      {
     1243        iItem = (INT)item->sibling;
     1244        while ((!iItem) && (indent > 0))
     1245        {
     1246          item = &infoPtr->items[(INT)item->parent];
     1247          iItem = (INT)item->sibling;
     1248          indent--;
    11621249        }
    1163 
    1164 
    1165         if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT)
    1166         infoPtr->cdmode=TREEVIEW_SendCustomDrawNotify
    1167                                                                 (hwnd, CDDS_POSTPAINT, hdc, rect);
    1168 
    1169     //TRACE("done\n");
     1250      }
     1251    }
     1252
     1253    if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT)
     1254      infoPtr->cdmode = TREEVIEW_SendCustomDrawNotify(hwnd, CDDS_POSTPAINT, hdc, rect);
     1255}
     1256
     1257static LRESULT TREEVIEW_SetRedraw(HWND hwnd,WPARAM wParam,LPARAM lParam)
     1258{
     1259  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     1260
     1261  if (wParam)
     1262  {
     1263    if (!(infoPtr->uInternalStatus & TV_NOREDRAW)) return 0;
     1264    infoPtr->uInternalStatus &= ~TV_NOREDRAW;
     1265    TREEVIEW_CalcItems(hwnd,0,infoPtr);
     1266    TREEVIEW_Refresh(hwnd);
     1267  } else
     1268  {
     1269    infoPtr->uInternalStatus |= TV_NOREDRAW;
     1270  }
     1271
     1272  return 0;
    11701273}
    11711274
     
    11791282
    11801283  switch (wParam) {
     1284        case TV_REFRESH_TIMER:
     1285                KillTimer (hwnd, TV_REFRESH_TIMER);
     1286                infoPtr->Timer &= ~TV_REFRESH_TIMER_SET;
     1287                TREEVIEW_CalcItems(hwnd,0,infoPtr);
     1288                TREEVIEW_Refresh(hwnd);
     1289                return 0;
     1290
    11811291        case TV_EDIT_TIMER:
    11821292                KillTimer (hwnd, TV_EDIT_TIMER);
     
    11891299
    11901300 return 1;
     1301}
     1302
     1303static void TREEVIEW_QueueRefresh(HWND hwnd)
     1304
     1305{
     1306  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     1307
     1308  if (infoPtr->Timer & TV_REFRESH_TIMER_SET)
     1309    KillTimer (hwnd, TV_REFRESH_TIMER);
     1310
     1311  if (infoPtr->uInternalStatus & TV_NOREDRAW)
     1312  {
     1313    infoPtr->Timer &= ~TV_REFRESH_TIMER_SET;
     1314
     1315    return;
     1316  }
     1317
     1318  SetTimer (hwnd, TV_REFRESH_TIMER, TV_REFRESH_DELAY, 0);
     1319  infoPtr->Timer |= TV_REFRESH_TIMER_SET;
     1320}
     1321
     1322static void TREEVIEW_UnqueueRefresh(HWND hwnd,BOOL calc,BOOL refresh)
     1323{
     1324  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     1325
     1326  if (infoPtr->Timer & TV_REFRESH_TIMER_SET)
     1327  {
     1328    KillTimer (hwnd, TV_REFRESH_TIMER);
     1329    infoPtr->Timer &= ~TV_REFRESH_TIMER_SET;
     1330    if (calc) TREEVIEW_CalcItems(hwnd,0,infoPtr);
     1331    if (refresh) TREEVIEW_Refresh(hwnd);
     1332  }
    11911333}
    11921334
     
    12751417        case TVGN_CARET:retval=(INT)infoPtr->selectedItem;
    12761418                                        break;
    1277         case TVGN_FIRSTVISIBLE: /* FIXME:we should only recalculate, not redraw */
    1278                                         //CB: todo: remove
    1279                                         TREEVIEW_Refresh(hwnd);
    1280                                         retval=(INT)infoPtr->firstVisible;
     1419        case TVGN_FIRSTVISIBLE:
     1420                                        TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE);
     1421                                        retval = (INT)infoPtr->firstVisible;
    12811422                                        break;
    12821423        case TVGN_DROPHILITE:
     
    19142055  wineItem->expandBox.right  = 0;
    19152056  wineItem->expandBox.bottom = 0;
     2057  wineItem->calculated = FALSE;
    19162058
    19172059   if (tvItem->mask & TVIF_IMAGE)
     
    19352077   }
    19362078
    1937    //CB: todo: calc
    1938    TREEVIEW_Refresh(hwnd);
     2079   TREEVIEW_QueueRefresh(hwnd);
    19392080
    19402081   return (LRESULT) iItem;
     
    20122153  }
    20132154
    2014   //CB: todo: calc
    2015   TREEVIEW_Refresh(hwnd);
     2155  TREEVIEW_QueueRefresh(hwnd);
    20162156
    20172157  return TRUE;
     
    21842324  if (wParam == SIZE_RESTORED)
    21852325  {
    2186     infoPtr->uTotalWidth  = LOWORD (lParam);
    2187         infoPtr->uTotalHeight = HIWORD (lParam);
    2188   } else {
    2189 //      FIXME (treeview,"WM_SIZE flag %x %lx not handled\n", wParam, lParam);
    2190   }
    2191 
    2192   //CB: todo: calc
    2193   TREEVIEW_Refresh(hwnd);
     2326    TREEVIEW_UnqueueRefresh(hwnd,FALSE,FALSE);
     2327    TREEVIEW_CalcItems(hwnd,0,infoPtr);
     2328    TREEVIEW_Refresh(hwnd);
     2329  }
     2330
    21942331  return 0;
    21952332}
     
    21992336TREEVIEW_StyleChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
    22002337{
    2201   //TRACE("(%x %lx)\n",wParam,lParam);
    2202   //CB: todo: calc
    2203   TREEVIEW_Refresh (hwnd);
     2338  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     2339
     2340  //CB: todo: check styles
     2341  infoPtr->uInternalStatus |= TV_CALCALL;
     2342  TREEVIEW_QueueRefresh(hwnd);
    22042343
    22052344  return 0;
     
    23402479   TREEVIEW_RemoveTree (hwnd);
    23412480   SetWindowLongA( hwnd, 0, (DWORD)NULL);
    2342 
     2481   if (infoPtr->Timer & TV_REFRESH_TIMER_SET)
     2482     KillTimer (hwnd, TV_REFRESH_TIMER);
    23432483   if (infoPtr->hwndToolTip)
    2344                 DestroyWindow (infoPtr->hwndToolTip);
     2484     DestroyWindow (infoPtr->hwndToolTip);
    23452485
    23462486   COMCTL32_Free (infoPtr);
     
    26782818
    26792819  if (wineItem->cChildren==I_CHILDRENCALLBACK) {
    2680 //    FIXME (treeview,"we don't handle I_CHILDRENCALLBACK yet\n");
     2820    //FIXME (treeview,"we don't handle I_CHILDRENCALLBACK yet\n");
    26812821    return 0;
    26822822  }
     
    26932833  {
    26942834    case TVE_COLLAPSERESET:
    2695 //      TRACE(treeview, "  case TVE_COLLAPSERESET\n");
    26962835      if (!wineItem->state & TVIS_EXPANDED)
    26972836        return 0;
     
    27022841
    27032842    case TVE_COLLAPSE:
    2704 //      TRACE(treeview, "  case TVE_COLLAPSE\n");
    27052843      if (!wineItem->state & TVIS_EXPANDED)
    27062844        return 0;
     
    27102848
    27112849    case TVE_EXPAND:
    2712 //      TRACE(treeview, "  case TVE_EXPAND\n");
    27132850      if (wineItem->state & TVIS_EXPANDED)
    27142851        return 0;
    27152852
    2716 //      TRACE(treeview, "  is not expanded...\n");
    2717 
    27182853      if (!(wineItem->state & TVIS_EXPANDEDONCE))
    27192854      {
    2720 //        TRACE(treeview, "  and has never been expanded...\n");
     2855        //TRACE(treeview, "  and has never been expanded...\n");
    27212856        wineItem->state |= TVIS_EXPANDED;
    27222857
     
    27292864              (HTREEITEM)expand))
    27302865        {
    2731 //          TRACE(treeview, "  TVN_ITEMEXPANDING returned TRUE, exiting...\n");
     2866          //TRACE(treeview, "  TVN_ITEMEXPANDING returned TRUE, exiting...\n");
    27322867          return FALSE;
    27332868        }
     
    27442879        if (! wineItem)
    27452880        {
    2746 //          ERR(treeview,
    2747 //            "Catastropic situation, cannot retreive item #%d\n",
    2748 //            expand);
     2881          //ERR(treeview,
     2882          //  "Catastropic situation, cannot retreive item #%d\n",
     2883          //  expand);
    27492884          return FALSE;
    27502885        }
    27512886
    27522887        wineItem->state |= TVIS_EXPANDEDONCE;
    2753 //        TRACE(treeview, "  TVN_ITEMEXPANDING sent...\n");
     2888        //TRACE(treeview, "  TVN_ITEMEXPANDING sent...\n");
    27542889
    27552890        TREEVIEW_SendTreeviewNotify (
     
    27602895          (HTREEITEM)expand);
    27612896
    2762 //        TRACE(treeview, "  TVN_ITEMEXPANDED sent...\n");
     2897        //TRACE(treeview, "  TVN_ITEMEXPANDED sent...\n");
    27632898
    27642899      }
     
    27712906
    27722907    case TVE_EXPANDPARTIAL:
    2773 //      TRACE(treeview, "  case TVE_EXPANDPARTIAL\n");
    2774 //      FIXME (treeview, "TVE_EXPANDPARTIAL not implemented\n");
     2908      //TRACE(treeview, "  case TVE_EXPANDPARTIAL\n");
     2909      //FIXME (treeview, "TVE_EXPANDPARTIAL not implemented\n");
    27752910      wineItem->state ^=TVIS_EXPANDED;
    27762911      wineItem->state |=TVIS_EXPANDEDONCE;
     
    27782913  }
    27792914
    2780 //  TRACE(treeview, "Exiting, Item %d state is now %d...\n",
    2781 //    expand,
    2782 //    wineItem->state);
    2783 
    2784   //CB: todo: replace
     2915  //TRACE(treeview, "Exiting, Item %d state is now %d...\n",
     2916  //  expand,
     2917  //  wineItem->state);
     2918
     2919  //CB: todo: optimize!
     2920  TREEVIEW_UnqueueRefresh(hwnd,FALSE,FALSE);
     2921  TREEVIEW_CalcItems(hwnd,0,infoPtr);
    27852922  TREEVIEW_Refresh(hwnd);
     2923
    27862924  return TRUE;
    27872925}
     
    32253363     */
    32263364    TREEVIEW_ITEM *parentItem = TREEVIEW_ValidItem (infoPtr, wineItem->parent);
    3227     if ( !(parentItem->state & TVIS_EXPANDED))
     3365
     3366    if (!(parentItem->state & TVIS_EXPANDED))
    32283367      TREEVIEW_Expand (hwnd, TVE_EXPAND, (LPARAM) wineItem->parent);
    32293368  }
     
    32553394      infoPtr->selectedItem=(HTREEITEM)newSelect;
    32563395
     3396      TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE);
    32573397      TREEVIEW_RefreshItem(hwnd,prevItem);
    32583398      TREEVIEW_RefreshItem(hwnd,wineItem);
     
    32783418        wineItem->state |=TVIS_DROPHILITED;
    32793419
     3420      TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE);
    32803421      TREEVIEW_RefreshItem(hwnd,prevItem);
    32813422      TREEVIEW_RefreshItem(hwnd,wineItem);
     
    33173458
    33183459{
    3319  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    3320  TEXTMETRICA tm;
    3321  LOGFONTA logFont;
    3322  HFONT hFont, hOldFont;
    3323  INT height;
    3324  HDC hdc;
    3325 
    3326 // TRACE (treeview,"%x %lx\n",wParam, lParam);
    3327 
    3328  infoPtr->hFont = (HFONT)wParam;
    3329 
    3330  hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
    3331 
    3332  GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
    3333  logFont.lfWeight=FW_BOLD;
    3334  infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
    3335 
    3336  hdc = GetDC (0);
    3337  hOldFont = SelectObject (hdc, hFont);
    3338  GetTextMetricsA (hdc, &tm);
    3339  height= tm.tmHeight + tm.tmExternalLeading;
    3340  if (height>infoPtr->uRealItemHeight)
    3341         infoPtr->uRealItemHeight=height;
    3342  SelectObject (hdc, hOldFont);
    3343  ReleaseDC (0, hdc);
    3344 
    3345  //CB: todo: calc
    3346  if (lParam)
    3347         TREEVIEW_Refresh(hwnd);
    3348 
    3349  return 0;
    3350 }
    3351 
     3460  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     3461  TEXTMETRICA tm;
     3462  LOGFONTA logFont;
     3463  HFONT hFont, hOldFont;
     3464  INT height;
     3465  HDC hdc;
     3466
     3467  infoPtr->hFont = (HFONT)wParam;
     3468
     3469  hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
     3470
     3471  GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
     3472  logFont.lfWeight=FW_BOLD;
     3473  infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
     3474
     3475  hdc = GetDC (0);
     3476  hOldFont = SelectObject (hdc, hFont);
     3477  GetTextMetricsA (hdc, &tm);
     3478  height= tm.tmHeight + tm.tmExternalLeading;
     3479  if (height>infoPtr->uRealItemHeight)
     3480    infoPtr->uRealItemHeight=height;
     3481  SelectObject (hdc, hOldFont);
     3482  ReleaseDC (0, hdc);
     3483
     3484  if (lParam)
     3485  {
     3486    TREEVIEW_UnqueueRefresh(hwnd,FALSE,FALSE);
     3487    infoPtr->uInternalStatus |= TV_CALCALL;
     3488    TREEVIEW_CalcItems(hwnd,0,infoPtr);
     3489    TREEVIEW_Refresh(hwnd);
     3490  }
     3491
     3492  return 0;
     3493}
    33523494
    33533495
     
    33943536  }
    33953537
     3538  TREEVIEW_CalcItems(hwnd,0,infoPtr);
    33963539  ScrollWindowEx(hwnd,0,lastPos-infoPtr->cy,NULL,NULL,0,NULL,SW_INVALIDATE);
    33973540
     
    34043547  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    34053548  int maxWidth;
     3549  int lastPos = infoPtr->cx;
    34063550
    34073551//  TRACE (treeview,"wp %lx, lp %x\n", lParam, wParam);
     
    34403584  }
    34413585
    3442   TREEVIEW_Refresh(hwnd);
    3443 
    3444   //CB: todo: use ScrollWindowEx
     3586  TREEVIEW_CalcItems(hwnd,0,infoPtr);
     3587  ScrollWindowEx(hwnd,lastPos-infoPtr->cx,0,NULL,NULL,0,NULL,SW_INVALIDATE);
    34453588
    34463589  return TRUE;
     
    36423785  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    36433786  UINT uOldScrollTime = infoPtr->uScrollTime;
     3787
    36443788  infoPtr->uScrollTime = min (uScrollTime, 100);
     3789
    36453790  return uOldScrollTime;
    36463791}
     
    38543999
    38554000/*      case WM_SYSCOLORCHANGE: */
    3856 /*      case WM_SETREDRAW: */
     4001
     4002        case WM_SETREDRAW:
     4003                return TREEVIEW_SetRedraw(hwnd,wParam,lParam);
    38574004
    38584005        case WM_TIMER:
     
    38934040
    38944041    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
    3895     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
     4042    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
    38964043    wndClass.lpfnWndProc   = (WNDPROC)TREEVIEW_WindowProc;
    38974044    wndClass.cbClsExtra    = 0;
Note: See TracChangeset for help on using the changeset viewer.