Index: trunk/src/comctl32/progress.c
===================================================================
--- trunk/src/comctl32/progress.c	(revision 2812)
+++ trunk/src/comctl32/progress.c	(revision 2814)
@@ -1,3 +1,3 @@
-/* $Id: progress.c,v 1.13 2000-02-16 17:22:18 cbratschi Exp $ */
+/* $Id: progress.c,v 1.14 2000-02-17 17:26:50 cbratschi Exp $ */
 /*
  * Progress control
@@ -9,5 +9,5 @@
  *
  * Status: complete
- * Version: 5.00
+ * Version: 5.80
  */
 
Index: trunk/src/comctl32/trackbar.c
===================================================================
--- trunk/src/comctl32/trackbar.c	(revision 2812)
+++ trunk/src/comctl32/trackbar.c	(revision 2814)
@@ -1,3 +1,3 @@
-/* $Id: trackbar.c,v 1.24 1999-12-27 22:54:49 cbratschi Exp $ */
+/* $Id: trackbar.c,v 1.25 2000-02-17 17:26:50 cbratschi Exp $ */
 /*
  * Trackbar control
@@ -10,5 +10,5 @@
  *
  * Status: complete
- * Version: 5.00
+ * Version: 5.80
  *
  * Note: TBM_SETTHUMBLENGTH implemented, COMCTL32 5.00 ignores it
@@ -20,5 +20,4 @@
 #include "trackbar.h"
 #include <stdio.h>
-
 
 #define TRACKBAR_GetInfoPtr(hwnd) ((TRACKBAR_INFO*)GetWindowLongA(hwnd,0))
Index: trunk/src/comctl32/treeview.c
===================================================================
--- trunk/src/comctl32/treeview.c	(revision 2812)
+++ trunk/src/comctl32/treeview.c	(revision 2814)
@@ -1,3 +1,3 @@
-/* $Id: treeview.c,v 1.26 2000-02-16 17:22:19 cbratschi Exp $ */
+/* $Id: treeview.c,v 1.27 2000-02-17 17:26:51 cbratschi Exp $ */
 /* Treeview control
  *
@@ -22,5 +22,5 @@
  *
  * Status: in progress
- * Version: 5.00
+ * Version: 5.80
  */
 
@@ -33,5 +33,11 @@
 /* CB: todo
 
- - bug in SetScrollInfo/ShowScrollBar: WM_SIZE and WM_NCPAINT problems
+ - bug in SetScrollInfo/ShowScrollBar: WM_SIZE and WM_NCPAINT problems (i.e. RegEdit)
+ - WM_HSCROLL: some rects are wrong
+ - TVS_FULLROWSELECT
+ - TVS_SINGLEEXPAND
+ - TVS_TRACKSELECT (called hottrack)
+ - TVS_INFOTIP, TVS_NOTOOLTIPS and tooltip support
+ - WM_ENABLE: draw disabled control
 */
 
@@ -447,19 +453,21 @@
 {
   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
-  INT cx,cy,prevHeight=infoPtr->uItemHeight;
-
-//  TRACE (treeview,"\n");
-  if (wParam==-1) {
-        infoPtr->uItemHeight=-1;
-        return prevHeight;
+  INT cx,cy,prevHeight = infoPtr->uItemHeight;
+
+  if (wParam==-1)
+  {
+    infoPtr->uItemHeight = -1;
+
+    return prevHeight;
   }
 
   ImageList_GetIconSize (infoPtr->himlNormal, &cx, &cy);
 
-  if (wParam>cy) cy=wParam;
-  infoPtr->uItemHeight=cy;
-
-  if (!( GetWindowLongA( hwnd, GWL_STYLE) & TVS_NONEVENHEIGHT))
-        infoPtr->uItemHeight = (INT) wParam & 0xfffffffe;
+  if (wParam > cy) cy = wParam;
+  infoPtr->uItemHeight = cy;
+
+  if (!(GetWindowLongA(hwnd, GWL_STYLE) & TVS_NONEVENHEIGHT))
+    if (infoPtr->uItemHeight & 0x1) infoPtr->uItemHeight += 1;
+
   return prevHeight;
 }
@@ -470,5 +478,4 @@
   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 
-//  TRACE (treeview,"\n");
   return infoPtr->uItemHeight;
 }
@@ -606,14 +613,14 @@
 //pen must be selected!
 
-static void TREEVIEW_DrawVLines(HDC hdc,TREEVIEW_INFO *infoPtr,TREEVIEW_ITEM *wineItem)
+static void TREEVIEW_DrawVLines(HDC hdc,TREEVIEW_INFO *infoPtr,TREEVIEW_ITEM *item)
 {
   POINT points[2];
   INT center;
 
-  center = (wineItem->rect.top+wineItem->rect.bottom)/2;
+  center = (item->rect.top+item->rect.bottom)/2;
 //INT cChildren = TREEVIEW_HasChildren(hwnd,wineItem);
-  if ((wineItem->iLevel == 0) && !wineItem->upsibling && wineItem->sibling)
-  {
-    TREEVIEW_ITEM *lastItem = &infoPtr->items[(INT)wineItem->sibling];
+  if ((item->iLevel == 0) && !item->upsibling && item->sibling)
+  {
+    TREEVIEW_ITEM *lastItem = &infoPtr->items[(INT)item->sibling];
 
     while (lastItem->sibling) lastItem = &infoPtr->items[(INT)lastItem->sibling];
@@ -629,14 +636,14 @@
   }
 
-  if (wineItem->firstChild && (wineItem->state & TVIS_EXPANDED))
-  {
-    TREEVIEW_ITEM *lastItem = &infoPtr->items[(INT)wineItem->firstChild];
+  if (item->firstChild && (item->state & TVIS_EXPANDED))
+  {
+    TREEVIEW_ITEM *lastItem = &infoPtr->items[(INT)item->firstChild];
 
     while (lastItem->sibling) lastItem = &infoPtr->items[(INT)lastItem->sibling];
 
     points[0].y = (lastItem->upsibling != NULL) ?
-                   wineItem->rect.bottom-3:  /* is linked to an icon       */
-                   wineItem->rect.bottom+1;  /* is linked to a +/- box     */
-    points[1].x = points[0].x = 28+20*wineItem->iLevel-infoPtr->cx;
+                   item->rect.bottom-3:  /* is linked to an icon       */
+                   item->rect.bottom+1;  /* is linked to a +/- box     */
+    points[1].x = points[0].x = 28+20*item->iLevel-infoPtr->cx;
     points[1].y = (lastItem->rect.top+lastItem->rect.bottom)/2;  /* is linked to a +/- box     */
 #ifdef OS2LINEHACK
@@ -649,17 +656,15 @@
 
 static void
-TREEVIEW_DrawItem(HWND hwnd,HDC hdc,TREEVIEW_ITEM *wineItem,DWORD dwStyle,TREEVIEW_INFO *infoPtr)
-{
-  INT   center,xpos,cx,cy, cditem;
+TREEVIEW_DrawItem(HWND hwnd,HDC hdc,TREEVIEW_ITEM *item,DWORD dwStyle,TREEVIEW_INFO *infoPtr)
+{
+  INT   center,cditem;
   HFONT hOldFont;
-  UINT  uTextJustify = DT_LEFT;
-  RECT  r;
-
-  if (!wineItem->calculated) TREEVIEW_CalcItem(hwnd,hdc,dwStyle,infoPtr,wineItem);
-
-  if (wineItem->state & TVIS_BOLD)
-    hOldFont = SelectObject (hdc, infoPtr->hBoldFont);
+
+  if (!item->calculated) TREEVIEW_CalcItem(hwnd,hdc,dwStyle,infoPtr,item);
+
+  if (item->state & TVIS_BOLD)
+    hOldFont = SelectObject(hdc,infoPtr->hBoldFont);
   else
-    hOldFont = SelectObject (hdc, infoPtr->hFont);
+    hOldFont = SelectObject(hdc,infoPtr->hFont);
 
   cditem = 0;
@@ -667,5 +672,5 @@
   if (infoPtr->cdmode & CDRF_NOTIFYITEMDRAW)
   {
-    cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, wineItem, CDDS_ITEMPREPAINT);
+    cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, item, CDDS_ITEMPREPAINT);
 
     if (cditem & CDRF_SKIPDEFAULT) return;
@@ -677,7 +682,5 @@
    * Set drawing starting points
    */
-  r      = wineItem->rect;               /* this item rectangle */
-  center = (r.top+r.bottom)/2;           /* this item vertical center */
-  xpos   = r.left + TREEVIEW_LEFT_MARGIN;/* horizontal starting point */
+  center = (item->rect.top+item->rect.bottom)/2; /* this item vertical center */
 
   /*
@@ -704,5 +707,5 @@
       hOldPen = SelectObject(hdc,hnewPen);
 
-      TREEVIEW_DrawVLines(hdc,infoPtr,wineItem);
+      TREEVIEW_DrawVLines(hdc,infoPtr,item);
 
       /*
@@ -710,12 +713,12 @@
        * to the up sibling or to the parent node.
        */
-      if (wineItem->upsibling)
-        upNode  = TREEVIEW_ValidItem (infoPtr, wineItem->upsibling);
-      else if (wineItem->parent)
-        upNode  = TREEVIEW_ValidItem (infoPtr, wineItem->parent);
+      if (item->upsibling)
+        upNode  = TREEVIEW_ValidItem (infoPtr, item->upsibling);
+      else if (item->parent)
+        upNode  = TREEVIEW_ValidItem (infoPtr, item->parent);
 
       if (upNode) upRect = upNode->rect;
 
-      if (wineItem->iLevel == 0)
+      if (item->iLevel == 0)
       {
         points[1].x = upRect.left+8;
@@ -724,5 +727,5 @@
       } else
       {
-        points[1].x = 8+(20*wineItem->iLevel)-infoPtr->cx;
+        points[1].x = 8+(20*item->iLevel)-infoPtr->cx;
         points[1].y = points[0].y = center;
         points[0].x = points[1].x + 10;
@@ -745,20 +748,20 @@
    * Display the (+/-) signs
    */
-  if (wineItem->iLevel != 0)/*  update position only for non root node */
-    xpos += 5*wineItem->iLevel;
-
   if ((dwStyle & TVS_HASBUTTONS) && (dwStyle & TVS_HASLINES))
   {
-    if (TREEVIEW_HasChildren(hwnd, wineItem))
-    {
-      Rectangle(hdc,wineItem->expandBox.left,wineItem->expandBox.top,wineItem->expandBox.right,wineItem->expandBox.bottom);
-
-      MoveToEx (hdc, xpos-2, center, NULL);
-      LineTo   (hdc, xpos+3, center);
-
-      if (!(wineItem->state & TVIS_EXPANDED))
-      {
-        MoveToEx (hdc, xpos,   center-2, NULL);
-        LineTo   (hdc, xpos,   center+3);
+    if (TREEVIEW_HasChildren(hwnd,item))
+    {
+      INT vCenter = (item->expandBox.top+item->expandBox.bottom)/2;
+      INT hCenter = (item->expandBox.right+item->expandBox.left)/2;
+
+      Rectangle(hdc,item->expandBox.left,item->expandBox.top,item->expandBox.right,item->expandBox.bottom);
+
+      MoveToEx(hdc,item->expandBox.left+2,vCenter,NULL);
+      LineTo(hdc,item->expandBox.right-2,vCenter);
+
+      if (!(item->state & TVIS_EXPANDED))
+      {
+        MoveToEx(hdc,hCenter,item->expandBox.top+2,NULL);
+        LineTo(hdc,hCenter,item->expandBox.bottom-2);
       }
     }
@@ -768,6 +771,5 @@
    * Display the image associated with this item
    */
-  xpos += 13; /* update position */
-  if (wineItem->mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE))
+  if ((item->mask & (TVIF_IMAGE | TVIF_SELECTEDIMAGE)) || (dwStyle & TVS_CHECKBOXES))
   {
     INT        imageIndex;
@@ -779,12 +781,11 @@
      */
     if (infoPtr->himlState)
-      himlp=&infoPtr->himlState;
-    imageIndex=wineItem->state >> 12;
-
-    if ((himlp) && (imageIndex))
+      himlp =& infoPtr->himlState;
+    imageIndex = item->state >> 12;
+
+    if (himlp && imageIndex)
     {
       imageIndex--;       /* see FIXME */
-      ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL);
-      xpos += wineItem->statebitmap.right-wineItem->statebitmap.left;
+      ImageList_Draw(*himlp,imageIndex,hdc,item->statebitmap.left,item->statebitmap.top,ILD_NORMAL);
     }
 
@@ -793,25 +794,23 @@
      */
 
-    himlp=NULL;
+    himlp = NULL;
     if (infoPtr->himlNormal)
-      himlp=&infoPtr->himlNormal; /* get the image list */
-
-    imageIndex = wineItem->iImage;
-    if ( (wineItem->state & TVIS_SELECTED) &&
-         (wineItem->iSelectedImage))
-    {
-
+      himlp = &infoPtr->himlNormal; /* get the image list */
+
+    imageIndex = item->iImage;
+    if ((item->state & TVIS_SELECTED) && item->iSelectedImage)
+    {
       /* The item is curently selected */
-      if (wineItem->iSelectedImage == I_IMAGECALLBACK)
-        TREEVIEW_SendDispInfoNotify(hwnd, wineItem, TVN_GETDISPINFO, TVIF_SELECTEDIMAGE);
-
-      imageIndex = wineItem->iSelectedImage;
+      if (item->iSelectedImage == I_IMAGECALLBACK)
+        TREEVIEW_SendDispInfoNotify(hwnd, item, TVN_GETDISPINFO, TVIF_SELECTEDIMAGE);
+
+      imageIndex = item->iSelectedImage;
     } else
     {
       /* The item is not selected */
-      if (wineItem->iImage == I_IMAGECALLBACK)
-        TREEVIEW_SendDispInfoNotify(hwnd, wineItem, TVN_GETDISPINFO, TVIF_IMAGE);
-
-      imageIndex = wineItem->iImage;
+      if (item->iImage == I_IMAGECALLBACK)
+        TREEVIEW_SendDispInfoNotify(hwnd, item, TVN_GETDISPINFO, TVIF_IMAGE);
+
+      imageIndex = item->iImage;
     }
 
@@ -820,9 +819,8 @@
       int ovlIdx = 0;
 
-      if(wineItem->stateMask & TVIS_OVERLAYMASK)
-        ovlIdx = wineItem->state & TVIS_OVERLAYMASK;
-
-      ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL|ovlIdx);
-      xpos += wineItem->bitmap.right-wineItem->bitmap.left;
+      if(item->stateMask & TVIS_OVERLAYMASK)
+        ovlIdx = item->state & TVIS_OVERLAYMASK;
+
+      ImageList_Draw(*himlp,imageIndex,hdc,item->bitmap.left,item->bitmap.top,ILD_NORMAL | ovlIdx);
     }
   }
@@ -832,9 +830,9 @@
    */
   /* Don't paint item's text if it's being edited */
-  if (!infoPtr->hwndEdit || (infoPtr->editItem != wineItem->hItem))
-  {
-    r.left=xpos;
-    if ((wineItem->mask & TVIF_TEXT) && (wineItem->pszText))
-    {
+  if (!infoPtr->hwndEdit || (infoPtr->editItem != item->hItem))
+  {
+    if ((item->mask & TVIF_TEXT) && (item->pszText))
+    {
+      UINT  uTextJustify = DT_LEFT;
       COLORREF oldTextColor = 0;
       INT      oldBkMode;
@@ -842,6 +840,4 @@
       BOOL     inFocus = GetFocus() == hwnd;
 
-      r.left += 3;
-      r.right -= 3;
       oldBkMode = SetBkMode(hdc, TRANSPARENT);
 
@@ -852,50 +848,48 @@
        * - Otherwise - don't fill background
        */
-       if ((wineItem->state & TVIS_DROPHILITED) ||
-           ((wineItem->state & TVIS_SELECTED) &&
-            (inFocus || (GetWindowLongA( hwnd, GWL_STYLE) & TVS_SHOWSELALWAYS))))
-       {
-           if ((wineItem->state & TVIS_DROPHILITED) || inFocus)
-           {
-               hbrBk = CreateSolidBrush(GetSysColor( COLOR_HIGHLIGHT));
-               oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT));
-           }
-           else
-           {
-               hbrBk = CreateSolidBrush(GetSysColor( COLOR_BTNFACE));
-
-               if (infoPtr->clrText == -1)
-                   oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
-               else
-                   oldTextColor = SetTextColor(hdc, infoPtr->clrText);
-           }
+      if ((item->state & TVIS_DROPHILITED) ||
+          ((item->state & TVIS_SELECTED) &&
+          (inFocus || (GetWindowLongA( hwnd, GWL_STYLE) & TVS_SHOWSELALWAYS))))
+      {
+        if ((item->state & TVIS_DROPHILITED) || inFocus)
+        {
+          hbrBk = CreateSolidBrush(GetSysColor( COLOR_HIGHLIGHT));
+          oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT));
+        } else
+        {
+          hbrBk = CreateSolidBrush(GetSysColor( COLOR_BTNFACE));
+
+          if (infoPtr->clrText == -1)
+            oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
+          else
+            oldTextColor = SetTextColor(hdc, infoPtr->clrText);
+        }
+      } else
+      {
+        if (infoPtr->clrText == -1)
+          oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
+        else
+          oldTextColor = SetTextColor(hdc, infoPtr->clrText);
       }
-      else
-      {
-          if (infoPtr->clrText == -1)
-              oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
-          else
-              oldTextColor = SetTextColor(hdc, infoPtr->clrText);
+
+      if (item->pszText == LPSTR_TEXTCALLBACKW)
+        TREEVIEW_SendDispInfoNotify (hwnd, item, TVN_GETDISPINFO, TVIF_TEXT);
+
+      if (hbrBk)
+      {
+        FillRect(hdc, &item->text, hbrBk);
+        DeleteObject(hbrBk);
       }
 
-      if (wineItem->pszText == LPSTR_TEXTCALLBACKW)
-        TREEVIEW_SendDispInfoNotify (hwnd, wineItem, TVN_GETDISPINFO, TVIF_TEXT);
-
-      if (hbrBk)
-      {
-          FillRect(hdc, &wineItem->text, hbrBk);
-          DeleteObject(hbrBk);
-      }
-
-      wineItem->text.left += 2;
+      item->text.left += 2;
 
       /* Draw it */
       DrawTextW ( hdc,
-        wineItem->pszText,
-        lstrlenW(wineItem->pszText),
-        &wineItem->text,
+        item->pszText,
+        lstrlenW(item->pszText),
+        &item->text,
         uTextJustify | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
 
-       wineItem->text.left -= 2;
+      item->text.left -= 2;
 
       /* Restore the hdc state */
@@ -903,5 +897,5 @@
 
       /* Draw the box arround the selected item */
-      if (wineItem->state & TVIS_SELECTED)
+      if (item->state & TVIS_SELECTED)
       {
         HPEN  hNewPen     = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT) );
@@ -910,12 +904,12 @@
         POINT points[5];
 
-        points[4].x = points[0].x = wineItem->text.left;
-        points[4].y = points[0].y = wineItem->text.top;
-        points[1].x = wineItem->text.right-1 ;
-        points[1].y = wineItem->text.top;
-        points[2].x = wineItem->text.right-1;
-        points[2].y = wineItem->text.bottom-1;
-        points[3].x = wineItem->text.left;
-        points[3].y = wineItem->text.bottom-1;
+        points[4].x = points[0].x = item->text.left;
+        points[4].y = points[0].y = item->text.top;
+        points[1].x = item->text.right-1 ;
+        points[1].y = item->text.top;
+        points[2].x = item->text.right-1;
+        points[2].y = item->text.bottom-1;
+        points[3].x = item->text.left;
+        points[3].y = item->text.bottom-1;
 
         Polyline (hdc,points,5);
@@ -927,5 +921,5 @@
 
       if (oldBkMode != TRANSPARENT)
-          SetBkMode(hdc, oldBkMode);
+        SetBkMode(hdc, oldBkMode);
     }
   }
@@ -936,5 +930,5 @@
   //              TRACE ("item:%d,mark:%d\n", (int)wineItem->hItem,
   //                             (int) infoPtr->insertMarkItem);
-  if (wineItem->hItem==infoPtr->insertMarkItem)
+  if (item->hItem == infoPtr->insertMarkItem)
   {
     HPEN hNewPen, hOldPen;
@@ -945,16 +939,16 @@
 
     if (infoPtr->insertBeforeorAfter)
-      offset=wineItem->text.top+1;
+      offset = item->text.top+1;
     else
-      offset=wineItem->text.bottom-1;
-
-    MoveToEx (hdc, wineItem->text.left, offset-3, NULL);
-    LineTo (hdc, wineItem->text.left, offset+3);
-
-    MoveToEx (hdc, wineItem->text.left, offset, NULL);
-    LineTo (hdc, r.right-2, offset);
-
-    MoveToEx (hdc, r.right-2, offset+3, NULL);
-    LineTo (hdc, r.right-2, offset-3);
+      offset = item->text.bottom-1;
+
+    MoveToEx(hdc,item->text.left, offset-3, NULL);
+    LineTo(hdc,item->text.left, offset+3);
+
+    MoveToEx(hdc,item->text.left,offset,NULL);
+    LineTo(hdc,item->text.right-2,offset);
+
+    MoveToEx(hdc,item->text.right-2, offset+3, NULL);
+    LineTo(hdc,item->text.right-2, offset-3);
 
     DeleteObject(hNewPen);
@@ -964,8 +958,5 @@
 
   if (cditem & CDRF_NOTIFYPOSTPAINT)
-  {
-    cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, wineItem, CDDS_ITEMPOSTPAINT);
-    //TRACE("postpaint:cditem-app returns 0x%x\n",cditem);
-  }
+    cditem = TREEVIEW_SendCustomDrawItemNotify(hwnd, hdc, item, CDDS_ITEMPOSTPAINT);
 
   SelectObject (hdc, hOldFont);
@@ -1154,7 +1145,13 @@
     } else
     {
-      rect.left += TREEVIEW_LEFT_MARGIN;
-      if (item->iLevel != 0) rect.left += (5*item->iLevel);
-      rect.left += 15;
+      DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
+
+      //redraw text and image
+      if (((item->mask & (TVIF_IMAGE | TVIF_SELECTEDIMAGE)) || (dwStyle & TVS_CHECKBOXES)) && (item->iSelectedImage != item->iImage))
+      {
+        rect.left += TREEVIEW_LEFT_MARGIN;
+        if (item->iLevel != 0) rect.left += (5*item->iLevel);
+        rect.left += 15;
+      } else rect = item->text;
     }
 
@@ -1194,5 +1191,5 @@
   xpos += 13; /* update position */
 
-  if (item->mask & (TVIF_IMAGE | TVIF_SELECTEDIMAGE))
+  if ((item->mask & (TVIF_IMAGE | TVIF_SELECTEDIMAGE)) || (dwStyle & TVS_CHECKBOXES))
   {
     INT        imageIndex,cx,cy;
@@ -1272,9 +1269,6 @@
     item->text.bottom= r.bottom;
 
-    if (item->pszText== LPSTR_TEXTCALLBACKW)
-    {
-      //TRACE("LPSTR_TEXTCALLBACK\n");
+    if (item->pszText == LPSTR_TEXTCALLBACKW)
       TREEVIEW_SendDispInfoNotify (hwnd, item, TVN_GETDISPINFO, TVIF_TEXT);
-    }
 
     if (!hdc)
@@ -1341,4 +1335,6 @@
   GetTextMetricsA (hdc, &tm);
   itemHeight = MAX(tm.tmHeight+tm.tmExternalLeading,itemHeight);
+  if (!(dwStyle & TVS_NONEVENHEIGHT))
+    if (itemHeight & 0x1) itemHeight += 1; //important for PS_DOT pen!
   infoPtr->uRealItemHeight = itemHeight;
   infoPtr->uTotalWidth = 0;
@@ -1362,5 +1358,5 @@
       item->rect.bottom = item->rect.top+height;
       item->rect.left   = x-infoPtr->cx;
-      item->rect.right  = rect.right;
+      item->rect.right  = rect.right; //dummy
       TREEVIEW_CalcItem(hwnd,hdc,dwStyle,infoPtr,item);
     } else
@@ -1530,10 +1526,4 @@
 
     if (infoPtr->cdmode == CDRF_SKIPDEFAULT) return;
-
-    /* draw background */
-
-    hbrBk = CreateSolidBrush (infoPtr->clrBk);
-    FillRect(hdc, &rect, hbrBk);
-    DeleteObject(hbrBk);
 
     //draw items
@@ -2481,9 +2471,8 @@
 static LRESULT
 TREEVIEW_GetToolTips (HWND hwnd)
-
-{
- TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
-
- return infoPtr->hwndToolTip;
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
+
+  return infoPtr->hwndToolTip;
 }
 
@@ -2491,13 +2480,12 @@
 static LRESULT
 TREEVIEW_SetToolTips (HWND hwnd, WPARAM wParam)
-
-{
- TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
- HWND prevToolTip;
-
- prevToolTip=infoPtr->hwndToolTip;
- infoPtr->hwndToolTip= (HWND) wParam;
-
- return prevToolTip;
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
+  HWND prevToolTip;
+
+  prevToolTip = infoPtr->hwndToolTip;
+  infoPtr->hwndToolTip = (HWND)wParam;
+
+  return prevToolTip;
 }
 
@@ -2647,10 +2635,9 @@
   {
     if (TREEVIEW_CalcItems(hwnd,0,infoPtr))
-      TREEVIEW_Refresh(hwnd);
-  }
-
-  return 0;
-}
-
+      TREEVIEW_Refresh(hwnd); //because size redraw isn't set
+  }
+
+  return TRUE;
+}
 
 static LRESULT
@@ -2658,4 +2645,6 @@
 {
   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
+
+  if (infoPtr->hwndEdit) SetFocus(hwnd);
 
   //CB: todo: check styles
@@ -2666,117 +2655,113 @@
 }
 
+static LRESULT
+TREEVIEW_SysColorChange(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  TREEVIEW_Refresh(hwnd);
+
+  return DefWindowProcA(hwnd,WM_SYSCOLORCHANGE,wParam,lParam);
+}
 
 static LRESULT
 TREEVIEW_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    TREEVIEW_INFO *infoPtr;
-        DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-        LOGFONTA logFont;
-    TEXTMETRICA tm;
-        HDC hdc;
-
-    //TRACE("wnd %x, style %lx\n",hwnd,dwStyle);
-      /* allocate memory for info structure */
-    infoPtr = (TREEVIEW_INFO *) COMCTL32_Alloc (sizeof(TREEVIEW_INFO));
-
-    SetWindowLongA( hwnd, 0, (DWORD)infoPtr);
-
-    if (infoPtr == NULL) {
-                //ERR("could not allocate info memory!\n");
-                return 0;
+  TREEVIEW_INFO *infoPtr;
+  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
+  LOGFONTA logFont;
+  TEXTMETRICA tm;
+  HDC hdc;
+
+  /* allocate memory for info structure */
+  infoPtr = (TREEVIEW_INFO *) COMCTL32_Alloc (sizeof(TREEVIEW_INFO));
+
+  SetWindowLongA( hwnd, 0, (DWORD)infoPtr);
+
+  if (infoPtr == NULL) return 0;
+
+  if ((TREEVIEW_INFO*)GetWindowLongA(hwnd,0) != infoPtr) return 0;
+
+  hdc = GetDC(hwnd);
+
+  /* set default settings */
+  infoPtr->uInternalStatus = 0;
+  if (IsWindowUnicode(hwnd)) infoPtr->uInternalStatus |= TV_UNICODE;
+  infoPtr->uNumItems=0;
+  infoPtr->clrBk   = GetSysColor (COLOR_WINDOW);
+  infoPtr->clrLine = GetSysColor (COLOR_WINDOWTEXT);
+  infoPtr->clrInsertMark = GetSysColor (COLOR_BTNTEXT);
+  infoPtr->cy = 0;
+  infoPtr->cx = 0;
+  infoPtr->uIndent = 15;
+  infoPtr->himlNormal = NULL;
+  infoPtr->himlState = NULL;
+  infoPtr->uItemHeight = -1;
+  GetTextMetricsA (hdc, &tm);
+  infoPtr->hFont = GetStockObject (DEFAULT_GUI_FONT);
+  GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
+  logFont.lfWeight=FW_BOLD;
+  infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
+
+  infoPtr->items = NULL;
+  infoPtr->selectedItem = 0;
+  infoPtr->clrText=-1;        /* use system color */
+  infoPtr->dropItem=0;
+  infoPtr->insertMarkItem=0;
+  infoPtr->insertBeforeorAfter=0;
+  infoPtr->pCallBackSort=NULL;
+  infoPtr->uScrollTime = 300;  /* milliseconds */
+  infoPtr->hwndEdit = 0;
+
+  infoPtr->hwndToolTip=0;
+  if (!(dwStyle & TVS_NOTOOLTIPS))
+  {
+    /* Create tooltip control */
+    TTTOOLINFOA ti;
+
+    infoPtr->hwndToolTip =
+      CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
+                       CW_USEDEFAULT, CW_USEDEFAULT,
+                       CW_USEDEFAULT, CW_USEDEFAULT,
+                       hwnd, 0, 0, 0);
+
+    /* Send NM_TOOLTIPSCREATED notification */
+    if (infoPtr->hwndToolTip)
+    {
+      NMTOOLTIPSCREATED nmttc;
+
+      nmttc.hdr.hwndFrom = hwnd;
+      nmttc.hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
+      nmttc.hdr.code = NM_TOOLTIPSCREATED;
+      nmttc.hwndToolTips = infoPtr->hwndToolTip;
+
+      SendMessageA (GetParent(hwnd),WM_NOTIFY,(WPARAM)GetWindowLongA(hwnd,GWL_ID),(LPARAM)&nmttc);
     }
 
-    if ((TREEVIEW_INFO*) GetWindowLongA( hwnd, 0) != infoPtr) {
-                //ERR("pointer assignment error!\n");
-                return 0;
-    }
-
-        hdc=GetDC (hwnd);
-
-    /* set default settings */
-    infoPtr->uInternalStatus = 0;
-    infoPtr->uNumItems=0;
-    infoPtr->clrBk   = GetSysColor (COLOR_WINDOW);
-    infoPtr->clrLine = GetSysColor (COLOR_WINDOWTEXT);
-    infoPtr->clrInsertMark = GetSysColor (COLOR_BTNTEXT);
-    infoPtr->cy = 0;
-    infoPtr->cx = 0;
-    infoPtr->uIndent = 15;
-    infoPtr->himlNormal = NULL;
-    infoPtr->himlState = NULL;
-    infoPtr->uItemHeight = -1;
-    GetTextMetricsA (hdc, &tm);
-    infoPtr->hFont = GetStockObject (DEFAULT_GUI_FONT);
-    GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
-    logFont.lfWeight=FW_BOLD;
-    infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
-
-    infoPtr->items = NULL;
-    infoPtr->selectedItem = 0;
-    infoPtr->clrText=-1;        /* use system color */
-    infoPtr->dropItem=0;
-    infoPtr->insertMarkItem=0;
-    infoPtr->insertBeforeorAfter=0;
-    infoPtr->pCallBackSort=NULL;
-    infoPtr->uScrollTime = 300;  /* milliseconds */
-    infoPtr->hwndEdit = 0;
-
-/*
-    infoPtr->hwndNotify = GetParent32 (hwnd);
-    infoPtr->bTransparent = ( GetWindowLongA( hwnd, GWL_STYLE) & TBSTYLE_FLAT);
-*/
-
-    infoPtr->hwndToolTip=0;
-    if (!(dwStyle & TVS_NOTOOLTIPS)) {   /* Create tooltip control */
-                TTTOOLINFOA ti;
-
-                infoPtr->hwndToolTip =
-                        CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
-                   CW_USEDEFAULT, CW_USEDEFAULT,
-                   CW_USEDEFAULT, CW_USEDEFAULT,
-                   hwnd, 0, 0, 0);
-
-        /* Send NM_TOOLTIPSCREATED notification */
-        if (infoPtr->hwndToolTip) {
-            NMTOOLTIPSCREATED nmttc;
-
-            nmttc.hdr.hwndFrom = hwnd;
-            nmttc.hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
-            nmttc.hdr.code = NM_TOOLTIPSCREATED;
-            nmttc.hwndToolTips = infoPtr->hwndToolTip;
-
-            SendMessageA (GetParent (hwnd), WM_NOTIFY,
-                (WPARAM) GetWindowLongA( hwnd, GWL_ID), (LPARAM)&nmttc);
-        }
-
-                ZeroMemory (&ti, sizeof(TTTOOLINFOA));
-        ti.cbSize   = sizeof(TTTOOLINFOA);
-        ti.uFlags   = TTF_IDISHWND | TTF_TRACK | TTF_TRANSPARENT ;
-        ti.hwnd     = hwnd;
-        ti.uId      = 0;
-        ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK; */
-        SetRectEmpty (&ti.rect);
-
-        SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
-    }
-
-  if (dwStyle & TVS_CHECKBOXES) {
-                HBITMAP hbmLoad;
-                int nIndex;
-
-                infoPtr->himlState =
-             ImageList_Create (16, 16,ILC_COLOR|ILC_MASK, 15, 1);
-
-                hbmLoad = LoadBitmapA (COMCTL32_hModule, MAKEINTRESOURCEA(IDT_CHECK));
-                //TRACE ("%x\n",hbmLoad);
-        nIndex = ImageList_AddMasked (infoPtr->himlState, hbmLoad, CLR_DEFAULT);
-                //TRACE ("%d\n",nIndex);
-                DeleteObject (hbmLoad);
-        }
+    ZeroMemory (&ti, sizeof(TTTOOLINFOA));
+    ti.cbSize   = sizeof(TTTOOLINFOA);
+    ti.uFlags   = TTF_IDISHWND | TTF_TRACK | TTF_TRANSPARENT;
+    ti.hwnd     = hwnd;
+    ti.uId      = 0;
+    ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK; */
+    SetRectEmpty (&ti.rect);
+
+    SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
+  }
+
+  if (dwStyle & TVS_CHECKBOXES)
+  {
+    HBITMAP hbmLoad;
+    int nIndex;
+
+    infoPtr->himlState = ImageList_Create (16, 16,ILC_COLOR | ILC_MASK, 15, 1);
+
+    //CB: MSDN docu says: uses DrawFrameControl
+    hbmLoad = LoadBitmapA (COMCTL32_hModule, MAKEINTRESOURCEA(IDT_CHECK));
+    nIndex = ImageList_AddMasked (infoPtr->himlState, hbmLoad, CLR_DEFAULT);
+    DeleteObject (hbmLoad);
+  }
   ReleaseDC (hwnd, hdc);
+
   return 0;
 }
-
-
 
 static LRESULT
@@ -2846,4 +2831,11 @@
 }
 
+static LRESULT TREEVIEW_Enable(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  TREEVIEW_Refresh(hwnd);
+
+  return DefWindowProcA(hwnd,WM_ENABLE,wParam,lParam);
+}
+
 static LRESULT
 TREEVIEW_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
@@ -2853,9 +2845,14 @@
     RECT rect;
 
-//    TRACE (treeview,"\n");
     GetClientRect (hwnd, &rect);
     FillRect ((HDC)wParam, &rect, hBrush);
     DeleteObject (hBrush);
+
     return TRUE;
+}
+
+static LRESULT TREEVIEW_GetDlgCode(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  return DLGC_WANTARROWS | DLGC_WANTCHARS;
 }
 
@@ -3175,5 +3172,5 @@
   expand = (INT)lParam;
 
-  wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)expand);
+  wineItem = TREEVIEW_ValidItem (infoPtr,(HTREEITEM)expand);
 
   if (!wineItem)
@@ -3263,4 +3260,5 @@
       }
       break;
+
     default:
       return FALSE;
@@ -3319,5 +3317,5 @@
   }
 
-  lpht->flags=0;
+  lpht->flags = 0;
 
   if (x < wineItem->expandBox.left) {
@@ -3342,10 +3340,8 @@
   }
 
-  lpht->flags|=TVHT_ONITEMRIGHT;
-
+  lpht->flags |= TVHT_ONITEMRIGHT;
 
 done:
   lpht->hItem = wineItem->hItem;
-  //TRACE ("(%ld,%ld):result %x\n",lpht->pt.x,lpht->pt.y,lpht->flags);
 
   return (LRESULT) wineItem->hItem;
@@ -3362,5 +3358,4 @@
   TEXTMETRICA textMetric;
 
-  //TRACE("%d %d\n",(INT)hwnd, (INT)hItem);
   if (!editItem)
     return FALSE;
@@ -3369,13 +3364,13 @@
     return infoPtr->hwndEdit;
 
-        /* Make shure that edit item is selected */
+  /* Make shure that edit item is selected */
 
   TREEVIEW_DoSelectItem ( hwnd, TVGN_CARET, hItem, TVC_UNKNOWN);
 
   if (editItem->pszText == LPSTR_TEXTCALLBACKW)
-                TREEVIEW_SendDispInfoNotify (hwnd, editItem, TVN_GETDISPINFO, TVIF_TEXT);
+    TREEVIEW_SendDispInfoNotify (hwnd, editItem, TVN_GETDISPINFO, TVIF_TEXT);
 
   hdc = GetDC(hwnd);
-    /* Select the font to get appropriate metric dimensions */
+  /* Select the font to get appropriate metric dimensions */
   if(infoPtr->hFont != 0)
   {
@@ -3599,8 +3594,28 @@
   wineItem = &infoPtr->items [(INT)hitinfo.hItem];
 
-  if (TREEVIEW_SendSimpleNotify (hwnd, NM_DBLCLK)!=TRUE) {     /* FIXME!*/
-        TREEVIEW_Expand (hwnd, (WPARAM) TVE_TOGGLE, (LPARAM) wineItem->hItem);
- }
+  //MSDN documentation says: stop on non zero. but this isn't true in this case
+  if (!TREEVIEW_SendSimpleNotify (hwnd, NM_DBLCLK))
+    TREEVIEW_Expand (hwnd, (WPARAM) TVE_TOGGLE, (LPARAM) wineItem->hItem);
+
  return TRUE;
+}
+
+static LRESULT TREEVIEW_MouseMove(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
+  TVHITTESTINFO ht;
+  TREEVIEW_ITEM *item;
+
+  ht.pt.x = (INT)LOWORD(lParam);
+  ht.pt.y = (INT)HIWORD(lParam);
+
+  if (!TREEVIEW_HitTest(hwnd,&ht)) return 0;
+
+  if (ht.hItem)
+  {
+    item = &infoPtr->items[(INT)ht.hItem];
+  }
+
+  return 0;
 }
 
@@ -3612,5 +3627,4 @@
   BOOL bTrack;
   DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-
 
   /* If Edit control is active - kill it and return.
@@ -3629,5 +3643,4 @@
 
   TREEVIEW_HitTest (hwnd,&ht);
-  //TRACE("item %d \n", (INT)ht.hItem);
 
   bTrack = (ht.flags & TVHT_ONITEM) && !(dwStyle & TVS_DISABLEDRAGDROP);
@@ -3655,4 +3668,6 @@
   if(TREEVIEW_SendSimpleNotify (hwnd, NM_CLICK))
      goto setfocus;
+
+//CB: todo: check ht.flags for WM_HSCROLL!
 
   /*
@@ -3679,17 +3694,18 @@
      if (dwStyle & TVS_CHECKBOXES)  /* TVS_CHECKBOXES requires _us_ */
      {                              /* to toggle the current state  */
-        int state;
-        TREEVIEW_ITEM *wineItem;
-
-        wineItem = TREEVIEW_ValidItem(infoPtr, ht.hItem);
-
-                        state=1-(wineItem->state>>12);
-                        //TRACE ("state:%x\n", state);
-                        wineItem->state&= ~TVIS_STATEIMAGEMASK;
-                        wineItem->state|=state<<12;
-                        //TRACE ("state:%x\n", wineItem->state);
-                        //CB: todo: optimize
-                        TREEVIEW_QueueRefresh (hwnd);
-          }
+       int state;
+       TREEVIEW_ITEM *wineItem;
+
+       wineItem = TREEVIEW_ValidItem(infoPtr, ht.hItem);
+
+       state = 1-(wineItem->state>>12);
+       wineItem->state &= ~TVIS_STATEIMAGEMASK;
+       wineItem->state |= state<<12;
+       if (wineItem->visible)
+       {
+         TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE);
+         InvalidateRect(hwnd,&wineItem->statebitmap,TRUE);
+       }
+     }
   }
 
@@ -3732,4 +3748,11 @@
 
         return 0;
+}
+
+static LRESULT TREEVIEW_RButtonDoubleClick(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  TREEVIEW_SendSimpleNotify(hwnd,NM_RDBLCLK);
+
+  return DefWindowProcA(hwnd,WM_RBUTTONDBLCLK,wParam,lParam);
 }
 
@@ -3817,5 +3840,5 @@
     while (parent && !(parent->state & TVIS_EXPANDED))
     {
-      TREEVIEW_Expand(hwnd,TVE_EXPAND,(LPARAM)parent);
+      TREEVIEW_Expand(hwnd,TVE_EXPAND,(LPARAM)parent->hItem);
       parent = TREEVIEW_ValidItem(infoPtr,parent->parent);
     }
@@ -3896,5 +3919,5 @@
           TREEVIEW_CalcItems(hwnd,0,infoPtr);
 
-        ScrollWindowEx(hwnd,0,-scrollY,NULL,NULL,0,NULL,SW_INVALIDATE);
+        ScrollWindowEx(hwnd,0,-scrollY,NULL,NULL,0,NULL,SW_INVALIDATE | SW_SCROLLCHILDREN | (infoPtr->uScrollTime << 16));
       }
 
@@ -3968,38 +3991,48 @@
   int lastPos = infoPtr->cy;
 
-  if (!infoPtr->uInternalStatus & TV_VSCROLL) return FALSE;
-
-  if(infoPtr->hwndEdit)
-    SetFocus(hwnd);
-
-  switch (LOWORD (wParam)) {
-        case SB_LINEUP:
-                        if (!infoPtr->cy) return FALSE;
-                        infoPtr->cy -= infoPtr->uRealItemHeight;
-                        if (infoPtr->cy < 0) infoPtr->cy=0;
-                        break;
-        case SB_LINEDOWN:
-                        maxHeight=infoPtr->uTotalHeight-infoPtr->uVisibleHeight;
-                        if (infoPtr->cy == maxHeight) return FALSE;
-                        infoPtr->cy += infoPtr->uRealItemHeight;
-                        if (infoPtr->cy > maxHeight)
-                          infoPtr->cy = maxHeight;
-                        break;
-        case SB_PAGEUP:
-                        if (!infoPtr->cy) return FALSE;
-                        infoPtr->cy -= infoPtr->uVisibleHeight;
-                        if (infoPtr->cy < 0) infoPtr->cy=0;
-                        break;
-        case SB_PAGEDOWN:
-                        maxHeight=infoPtr->uTotalHeight-infoPtr->uVisibleHeight;
-                        if (infoPtr->cy == maxHeight) return FALSE;
-                        infoPtr->cy += infoPtr->uVisibleHeight;
-                        if (infoPtr->cy > maxHeight)
-                          infoPtr->cy = maxHeight;
-                        break;
-        case SB_THUMBTRACK:
-                        infoPtr->cy = HIWORD (wParam);
-                        break;
-
+  if (!(infoPtr->uInternalStatus & TV_VSCROLL)) return FALSE;
+
+  switch (LOWORD (wParam))
+  {
+    case SB_LINEUP:
+      if (!infoPtr->cy) return FALSE;
+      infoPtr->cy -= infoPtr->uRealItemHeight;
+      if (infoPtr->cy < 0) infoPtr->cy = 0;
+      break;
+
+    case SB_LINEDOWN:
+      maxHeight = infoPtr->uTotalHeight-infoPtr->uVisibleHeight;
+      if (maxHeight <= 0) return FALSE;
+      if (infoPtr->cy == maxHeight) return FALSE;
+      infoPtr->cy += infoPtr->uRealItemHeight;
+      if (infoPtr->cy > maxHeight)
+        infoPtr->cy = maxHeight;
+      break;
+
+    case SB_PAGEUP:
+      if (!infoPtr->cy) return FALSE;
+      infoPtr->cy -= infoPtr->uVisibleHeight;
+      if (infoPtr->cy < 0) infoPtr->cy = 0;
+      break;
+
+    case SB_PAGEDOWN:
+      maxHeight = infoPtr->uTotalHeight-infoPtr->uVisibleHeight;
+      if (maxHeight <= 0) return FALSE;
+      if (infoPtr->cy == maxHeight) return FALSE;
+      infoPtr->cy += infoPtr->uVisibleHeight;
+      if (infoPtr->cy > maxHeight)
+        infoPtr->cy = maxHeight;
+      break;
+
+    case SB_THUMBTRACK:
+      maxHeight = infoPtr->uTotalHeight-infoPtr->uVisibleHeight;
+      if (maxHeight <= 0) return FALSE;
+      infoPtr->cy = HIWORD(wParam);
+      if (infoPtr->cy < 0) infoPtr->cy = 0;
+      if (infoPtr->cy > maxHeight) infoPtr->cy = maxHeight;
+      break;
+
+    default:
+      return FALSE;
   }
 
@@ -4008,8 +4041,10 @@
     if (!TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE))
       TREEVIEW_CalcItems(hwnd,0,infoPtr);
-    ScrollWindowEx(hwnd,0,lastPos-infoPtr->cy,NULL,NULL,0,NULL,SW_INVALIDATE);
-  }
-
-  return TRUE;
+    ScrollWindowEx(hwnd,0,lastPos-infoPtr->cy,NULL,NULL,0,NULL,SW_INVALIDATE | SW_SCROLLCHILDREN | (infoPtr->uScrollTime << 16));
+
+    return TRUE;
+  }
+
+  return FALSE;
 }
 
@@ -4021,40 +4056,48 @@
   int lastPos = infoPtr->cx;
 
-  //TRACE (treeview,"wp %lx, lp %x\n", lParam, wParam);
-
-  if (!infoPtr->uInternalStatus & TV_HSCROLL) return FALSE;
-
-  if(infoPtr->hwndEdit)
-    SetFocus(hwnd);
-
-  switch (LOWORD (wParam)) {
-        case SB_LINEUP:
-                        if (!infoPtr->cx) return FALSE;
-                        infoPtr->cx -= infoPtr->uRealItemHeight;
-                        if (infoPtr->cx < 0) infoPtr->cx=0;
-                        break;
-        case SB_LINEDOWN:
-                        maxWidth=infoPtr->uTotalWidth-infoPtr->uVisibleWidth;
-                        if (infoPtr->cx == maxWidth) return FALSE;
-                        infoPtr->cx += infoPtr->uRealItemHeight; /*FIXME */
-                        if (infoPtr->cx > maxWidth)
-                                infoPtr->cx = maxWidth;
-                        break;
-        case SB_PAGEUP:
-                        if (!infoPtr->cx) return FALSE;
-                        infoPtr->cx -= infoPtr->uVisibleWidth;
-                        if (infoPtr->cx < 0) infoPtr->cx=0;
-                        break;
-        case SB_PAGEDOWN:
-                        maxWidth=infoPtr->uTotalWidth-infoPtr->uVisibleWidth;
-                        if (infoPtr->cx == maxWidth) return FALSE;
-                        infoPtr->cx += infoPtr->uVisibleWidth;
-            if (infoPtr->cx > maxWidth)
-                infoPtr->cx = maxWidth;
-                        break;
-        case SB_THUMBTRACK:
-                        infoPtr->cx = HIWORD (wParam);
-                        break;
-
+  if (!(infoPtr->uInternalStatus & TV_HSCROLL)) return FALSE;
+
+  switch (LOWORD (wParam))
+  {
+    case SB_LINEUP:
+      if (!infoPtr->cx) return FALSE;
+      infoPtr->cx -= infoPtr->uRealItemHeight;
+      if (infoPtr->cx < 0) infoPtr->cx = 0;
+      break;
+
+    case SB_LINEDOWN:
+      maxWidth = infoPtr->uTotalWidth-infoPtr->uVisibleWidth;
+      if (maxWidth <= 0) return FALSE;
+      if (infoPtr->cx == maxWidth) return FALSE;
+      infoPtr->cx += infoPtr->uRealItemHeight; /*FIXME */
+      if (infoPtr->cx > maxWidth)
+        infoPtr->cx = maxWidth;
+      break;
+
+    case SB_PAGEUP:
+      if (!infoPtr->cx) return FALSE;
+      infoPtr->cx -= infoPtr->uVisibleWidth;
+      if (infoPtr->cx < 0) infoPtr->cx = 0;
+      break;
+
+    case SB_PAGEDOWN:
+      maxWidth = infoPtr->uTotalWidth-infoPtr->uVisibleWidth;
+      if (maxWidth <= 0) return FALSE;
+      if (infoPtr->cx == maxWidth) return FALSE;
+      infoPtr->cx += infoPtr->uVisibleWidth;
+      if (infoPtr->cx > maxWidth)
+        infoPtr->cx = maxWidth;
+      break;
+
+    case SB_THUMBTRACK:
+      maxWidth = infoPtr->uTotalWidth-infoPtr->uVisibleWidth;
+      if (maxWidth <= 0) return FALSE;
+      infoPtr->cx = HIWORD(wParam);
+      if (infoPtr->cx < 0) infoPtr->cx = 0;
+      if (infoPtr->cx > maxWidth) infoPtr->cx = maxWidth;
+      break;
+
+    default:
+      return FALSE;
   }
 
@@ -4063,8 +4106,10 @@
     if (!TREEVIEW_UnqueueRefresh(hwnd,TRUE,TRUE))
       TREEVIEW_CalcItems(hwnd,0,infoPtr);
-    ScrollWindowEx(hwnd,lastPos-infoPtr->cx,0,NULL,NULL,0,NULL,SW_INVALIDATE);
-  }
-
-  return TRUE;
+    ScrollWindowEx(hwnd,lastPos-infoPtr->cx,0,NULL,NULL,0,NULL,SW_INVALIDATE | SW_SCROLLCHILDREN | (infoPtr->uScrollTime << 16));
+
+    return TRUE;
+  }
+
+  return FALSE;
 }
 
@@ -4112,6 +4157,50 @@
       NULL;
   TREEVIEW_ITEM *newItem        = NULL;
+  BOOL control;
 
   TREEVIEW_SendKeyDownNotify(hwnd,TVN_KEYDOWN,wParam);
+
+  control = GetKeyState(VK_CONTROL) & 0x8000;
+
+  if (control)
+  {
+    DWORD scrollMsg = 0;
+    BOOL horz = FALSE;
+
+    switch (wParam)
+    {
+      case VK_UP:
+//CB: todo: VK_UP doesn't work
+        scrollMsg = SB_LINELEFT;
+        break;
+
+      case VK_DOWN:
+        scrollMsg = SB_LINERIGHT;
+        break;
+
+      case VK_LEFT:
+        scrollMsg = SB_LINELEFT;
+        horz = TRUE;
+        break;
+
+      case VK_RIGHT:
+        scrollMsg = SB_LINERIGHT;
+        horz = TRUE;
+        break;
+
+      case VK_PRIOR:
+        scrollMsg = SB_PAGELEFT;
+        break;
+
+      case VK_NEXT:
+        scrollMsg = SB_PAGERIGHT;
+        break;
+    }
+    if (scrollMsg)
+    {
+      SendMessageA(hwnd,horz ? WM_HSCROLL:WM_VSCROLL,MAKELONG(scrollMsg,0),0);
+      return TRUE;
+    }
+  }
 
   if (prevSelect == 0)
@@ -4166,4 +4255,5 @@
 
       break;
+
     case VK_RIGHT:
       if (TREEVIEW_HasChildren(hwnd, prevItem))
@@ -4217,6 +4307,9 @@
       break;
 
+    case VK_RETURN:
+      TREEVIEW_SendSimpleNotify(hwnd,NM_RETURN);
+      break;
+
     case VK_BACK:
-    case VK_RETURN:
 
     default:
@@ -4243,4 +4336,5 @@
 {
   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
+
   return infoPtr->uScrollTime;
 }
@@ -4274,5 +4368,5 @@
     while (parent && !(parent->state & TVIS_EXPANDED))
     {
-      TREEVIEW_Expand(hwnd,TVE_EXPAND,(LPARAM)parent);
+      TREEVIEW_Expand(hwnd,TVE_EXPAND,(LPARAM)parent->hItem);
       parent = TREEVIEW_ValidItem(infoPtr,parent->parent);
     }
@@ -4291,5 +4385,5 @@
     infoPtr->cy += scrollY;
     TREEVIEW_CalcItems(hwnd,0,infoPtr);
-    ScrollWindowEx(hwnd,0,-scrollY,NULL,NULL,0,NULL,SW_INVALIDATE);
+    ScrollWindowEx(hwnd,0,-scrollY,NULL,NULL,0,NULL,SW_INVALIDATE | SW_SCROLLCHILDREN | (infoPtr->uScrollTime << 16));
 
     return TRUE;
@@ -4301,7 +4395,34 @@
 static LRESULT TREEVIEW_GetISearchString(HWND hwnd,LPSTR lpsz,BOOL unicode)
 {
-  //CB: todo
+  //CB: todo: MSDN documentation is useless
 
   return 0;
+}
+
+static LRESULT TREEVIEW_SetCursor(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  TREEVIEW_SendSimpleNotify(hwnd,NM_SETCURSOR); //CB: todo: result
+
+  return DefWindowProcA(hwnd,WM_SETCURSOR,wParam,lParam);
+}
+
+static LRESULT TREEVIEW_GetUnicodeFormat(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
+
+  return infoPtr->uInternalStatus & TV_UNICODE;
+}
+
+static LRESULT TREEVIEW_SetUnicodeFormat(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
+  BOOL oldFormat = infoPtr->uInternalStatus & TV_UNICODE;
+
+  if (wParam)
+    infoPtr->uInternalStatus |= TV_UNICODE;
+  else
+    infoPtr->uInternalStatus &= ~TV_UNICODE;
+
+  return oldFormat;
 }
 
@@ -4450,6 +4571,8 @@
 
         case TVM_GETUNICODEFORMAT:
-//                      FIXME (treeview, "Unimplemented msg TVM_GETUNICODEFORMAT\n");
-                return 0;
+                return TREEVIEW_GetUnicodeFormat(hwnd,wParam,lParam);
+
+        case TVM_SETUNICODEFORMAT:
+                return TREEVIEW_SetUnicodeFormat(hwnd,wParam,lParam);
 
         case WM_COMMAND:
@@ -4459,5 +4582,6 @@
                 return TREEVIEW_Destroy (hwnd);
 
-/*      case WM_ENABLE: */
+        case WM_ENABLE:
+                return TREEVIEW_Enable(hwnd,wParam,lParam);
 
         case WM_ERASEBKGND:
@@ -4465,5 +4589,5 @@
 
         case WM_GETDLGCODE:
-                return DLGC_WANTARROWS | DLGC_WANTCHARS;
+                return TREEVIEW_GetDlgCode(hwnd,wParam,lParam);
 
         case WM_PAINT:
@@ -4485,4 +4609,7 @@
                 return TREEVIEW_KillFocus (hwnd, wParam, lParam);
 
+        case WM_MOUSEMOVE:
+                return TREEVIEW_MouseMove(hwnd,wParam,lParam);
+
         case WM_LBUTTONDOWN:
                 return TREEVIEW_LButtonDown (hwnd, wParam, lParam);
@@ -4494,8 +4621,15 @@
                 return TREEVIEW_RButtonDown (hwnd, wParam, lParam);
 
+        case WM_RBUTTONDBLCLK:
+                return TREEVIEW_RButtonDoubleClick(hwnd,wParam,lParam);
+
         case WM_STYLECHANGED:
                 return TREEVIEW_StyleChanged (hwnd, wParam, lParam);
 
-/*      case WM_SYSCOLORCHANGE: */
+        case WM_SYSCOLORCHANGE:
+                return TREEVIEW_SysColorChange(hwnd,wParam,lParam);
+
+        case WM_SETCURSOR:
+                return TREEVIEW_SetCursor(hwnd,wParam,lParam);
 
         case WM_SETREDRAW:
