More Tab Control fixes

Vitaliy Margolen wine-patch at kievinfo.com
Sun Nov 30 13:54:55 CST 2003


Yet more Tab Control fixes. Now it should look and work much closer to native.

Vitaliy Margolen

changelog:
  - Fix drawing of HotTracked tabs & buttons
  - More tab size fixes in different styles
  - Don't use new padding until style changes
  - Fix left alignment of labels &| icons
  - Don't draw over UpDown control
  - Fully erase tabs when scrolling
  - More tests
-------------- next part --------------
Index: tab.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/tab.c,v
retrieving revision 1.89
diff -u -r1.89 tab.c
--- tab.c	20 Nov 2003 22:04:14 -0000	1.89
+++ tab.c	30 Nov 2003 19:37:47 -0000
@@ -4,6 +4,7 @@
  * Copyright 1998 Anders Carlsson
  * Copyright 1999 Alex Priem <alexp at sci.kun.nl>
  * Copyright 1999 Francis Beaudet
+ * Copyright 2003 Vitaliy Margolen
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -67,6 +68,8 @@
   INT        tabMinWidth;     /* minimum width of items */
   USHORT     uHItemPadding;   /* amount of horizontal padding, in pixels */
   USHORT     uVItemPadding;   /* amount of vertical padding, in pixels */
+  USHORT     uHItemPadding_s; /* Set amount of horizontal padding, in pixels */
+  USHORT     uVItemPadding_s; /* Set amount of vertical padding, in pixels */
   HFONT      hFont;           /* handle to the current font */
   HCURSOR    hcurArrow;       /* handle to the current cursor */
   HIMAGELIST himl;            /* handle to a image list (may be 0) */
@@ -272,8 +275,8 @@
     TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
     
     if (infoPtr == NULL) return 0;
-    infoPtr->uHItemPadding=LOWORD(lParam);
-    infoPtr->uVItemPadding=HIWORD(lParam);
+    infoPtr->uHItemPadding_s=LOWORD(lParam);
+    infoPtr->uVItemPadding_s=HIWORD(lParam);
     return 0;
 }
 
@@ -318,14 +321,13 @@
   if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL))
   {
     itemRect->bottom = clientRect.bottom -
-                   SELECTED_TAB_OFFSET -
                    itemRect->top * (infoPtr->tabHeight - 2) -
-                   ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : 0);
+                   ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
 
     itemRect->top = clientRect.bottom -
                    infoPtr->tabHeight -
                    itemRect->top * (infoPtr->tabHeight - 2) -
-                   ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : 0);
+                   ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
   }
   else if((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
   {
@@ -402,7 +404,6 @@
     /* If it also a bit higher. */
     if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL))
     {
-      selectedRect->top -= 2; /* the border is thicker on the bottom */
       selectedRect->bottom += SELECTED_TAB_OFFSET;
     }
     else if((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
@@ -418,7 +419,7 @@
     else
     {
       selectedRect->top -= SELECTED_TAB_OFFSET;
-      selectedRect->bottom += 1;
+      selectedRect->bottom -= 1;
     }
   }
 
@@ -649,9 +650,12 @@
 TAB_DrawLoneItemInterior(HWND hwnd, TAB_INFO* infoPtr, int iItem)
 {
   HDC hdc = GetDC(hwnd);
-  HFONT hOldFont = SelectObject(hdc, infoPtr->hFont);
+  RECT r, rC;
+
+  GetWindowRect(hwnd, &rC);
+  GetWindowRect(infoPtr->hwndUpDown, &r);
+  ExcludeClipRect(hdc, r.left - rC.left, r.top - rC.top, r.right - rC.left, r.bottom - rC.top);
   TAB_DrawItemInterior(hwnd, hdc, iItem, NULL);
-  SelectObject(hdc, hOldFont);
   ReleaseDC(hwnd, hdc);
 }
 
@@ -1100,6 +1104,10 @@
      clientRect.right = iTemp;
   }
 
+  /* Now use hPadding and vPadding */
+  infoPtr->uHItemPadding = infoPtr->uHItemPadding_s;
+  infoPtr->uVItemPadding = infoPtr->uVItemPadding_s;
+  
   /* The leftmost item will be "0" aligned */
   curItemLeftPos = 0;
   curItemRowCount = infoPtr->uNumItem ? 1 : 0;
@@ -1416,6 +1424,69 @@
   ReleaseDC (hwnd, hdc);
 }
 
+
+static void
+TAB_EraseTabInterior
+    (
+    HWND	hwnd,
+    HDC         hdc,
+    INT         iItem,
+    RECT*       drawRect
+    )
+{
+    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
+    LONG     lStyle  = GetWindowLongA(hwnd, GWL_STYLE);
+    HBRUSH   hbr = CreateSolidBrush (comctl32_color.clrBtnFace);
+    BOOL     deleteBrush = TRUE;
+    RECT     rTemp = *drawRect;
+
+    InflateRect(&rTemp, -2, -2);
+    if (lStyle & TCS_BUTTONS)
+    {
+	if (iItem == infoPtr->iSelected)
+	{
+	    /* Background color */
+	    if (!(lStyle & TCS_OWNERDRAWFIXED))
+	    {
+		DeleteObject(hbr);
+		hbr = GetSysColorBrush(COLOR_SCROLLBAR);
+
+		SetTextColor(hdc, comctl32_color.clr3dFace);
+		SetBkColor(hdc, comctl32_color.clr3dHilight);
+
+		/* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
+		* we better use 0x55aa bitmap brush to make scrollbar's background
+		* look different from the window background.
+		*/
+		if (comctl32_color.clr3dHilight == comctl32_color.clrWindow)
+		    hbr = COMCTL32_hPattern55AABrush;
+
+		deleteBrush = FALSE;
+	    }
+	    FillRect(hdc, &rTemp, hbr);
+	}
+	else  /* ! selected */
+	{
+	    if (lStyle & TCS_FLATBUTTONS)
+	    {
+		FillRect(hdc, drawRect, hbr);
+		if (iItem == infoPtr->iHotTracked)
+		    DrawEdge(hdc, drawRect, EDGE_RAISED, BF_SOFT|BF_RECT);
+	    }
+	    else
+		FillRect(hdc, &rTemp, hbr);
+	}
+
+    }
+    else /* !TCS_BUTTONS */
+    {
+	FillRect(hdc, &rTemp, hbr);
+    }
+
+    /* Cleanup */
+    if (deleteBrush) DeleteObject(hbr);
+}
+
 /******************************************************************************
  * TAB_DrawItemInterior
  *
@@ -1439,7 +1510,8 @@
   HPEN   htextPen;
   HPEN   holdPen;
   INT    oldBkMode;
-
+  HFONT  hOldFont;
+  
   if (drawRect == NULL)
   {
     BOOL isVisible;
@@ -1469,32 +1541,77 @@
       *drawRect = itemRect;
       if (iItem == infoPtr->iSelected)
       {
-        drawRect->right--;
-        drawRect->bottom--;
+	OffsetRect(drawRect, 1, 1);
       }
     }
     else
     {
       if (iItem == infoPtr->iSelected)
+      {
         *drawRect = selectedRect;
+	if (lStyle & TCS_BOTTOM)
+	{
+	  if (lStyle & TCS_VERTICAL)
+	  {
+	    drawRect->left++;
+	  }
+	  else
+	  {
+	    drawRect->top += 3;
+	    drawRect->left += 1;
+	  }
+	}
+      }
       else
         *drawRect = itemRect;
-      drawRect->right--;
-      drawRect->bottom--;
+
+
+      if (lStyle & TCS_BOTTOM && !(lStyle & TCS_VERTICAL))
+      {
+        drawRect->top--;
+        drawRect->bottom--;
+      }
     }
   }
+  TRACE("drawRect=(%ld,%ld)-(%ld,%ld)\n",
+	  drawRect->left, drawRect->top, drawRect->right, drawRect->bottom);
+
+  /* Clear interior */
+  TAB_EraseTabInterior (hwnd, hdc, iItem, drawRect);
+
+  /* Draw the focus rectangle */
+  if (!(lStyle & TCS_FOCUSNEVER) &&
+      (GetFocus() == hwnd) &&
+      (iItem == infoPtr->uFocus) )
+  {
+    RECT rFocus = *drawRect;
+    InflateRect(&rFocus, -3, -3);
+    if (lStyle & TCS_BOTTOM && !(lStyle & TCS_VERTICAL))
+      rFocus.top -= 3;
+    if (lStyle & TCS_BUTTONS)
+    {
+      rFocus.left -= 3;
+      rFocus.top -= 3;
+    }
+
+    DrawFocusRect(hdc, &rFocus);
+  }
 
   /*
    * Text pen
    */
   htextPen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT) );
-  holdPen = SelectObject(hdc, htextPen);
+  holdPen  = SelectObject(hdc, htextPen);
+  hOldFont = SelectObject(hdc, infoPtr->hFont);
 
+  /*
+   * Setup for text output
+  */
   oldBkMode = SetBkMode(hdc, TRANSPARENT);
-  SetTextColor(hdc, ( (iItem == infoPtr->iHotTracked) | (infoPtr->items[iItem].dwState & TCIS_HIGHLIGHTED)) ?
+  SetTextColor(hdc, (((iItem == infoPtr->iHotTracked) && !(lStyle & TCS_FLATBUTTONS)) |
+		     (infoPtr->items[iItem].dwState & TCIS_HIGHLIGHTED)) ?
                      comctl32_color.clrHighlight : comctl32_color.clrBtnText);
 
-
   /*
    * if owner draw, tell the owner to draw
    */
@@ -1523,6 +1640,7 @@
     dis.hwndItem = hwnd;		/* */
     dis.hDC      = hdc;
     CopyRect(&dis.rcItem,drawRect);
+    InflateRect(&dis.rcItem, -2, -2);
     dis.itemData = infoPtr->items[iItem].lParam;
 
     /*
@@ -1532,31 +1650,13 @@
   }
   else
   {
-    INT cx;
-    INT cy;
-    UINT uHorizAlign;
     RECT rcTemp;
     RECT rcImage;
-    LOGFONTA logfont;
-    HFONT hFont = 0;
-    HFONT hOldFont = 0; /* stop uninitialized warning */
-
-    INT nEscapement = 0; /* stop uninitialized warning */
-    INT nOrientation = 0; /* stop uninitialized warning */
-    INT iPointSize;
 
     /* used to center the icon and text in the tab */
     RECT rcText;
     INT center_offset_h, center_offset_v;
 
-    /*
-     * Deflate the rectangle to acount for the padding
-     */
-    if(lStyle & TCS_VERTICAL)
-      InflateRect(drawRect, -infoPtr->uVItemPadding, -infoPtr->uHItemPadding);
-    else
-      InflateRect(drawRect, -infoPtr->uHItemPadding, -infoPtr->uVItemPadding);
-
     /* set rcImage to drawRect, we will use top & left in our ImageList_Draw call */
     rcImage = *drawRect;
 
@@ -1564,17 +1664,9 @@
 
     rcText.left = rcText.top = rcText.right = rcText.bottom = 0;
 
-    /*
-     * Setup for text output
-     */
-    oldBkMode = SetBkMode(hdc, TRANSPARENT);
-    SetTextColor(hdc, ((iItem == infoPtr->iHotTracked) | (infoPtr->items[iItem].dwState & TCIS_HIGHLIGHTED))?
-		 comctl32_color.clrHighlight : comctl32_color.clrBtnText);
-
     /* get the rectangle that the text fits in */
     DrawTextW(hdc, infoPtr->items[iItem].pszText, -1,
               &rcText, DT_CALCRECT);
-    rcText.right += 4;
     /*
      * If not owner draw, then do the drawing ourselves.
      *
@@ -1582,6 +1674,9 @@
      */
     if (infoPtr->himl && (infoPtr->items[iItem].mask & TCIF_IMAGE))
     {
+      INT cx;
+      INT cy;
+      
       ImageList_GetIconSize(infoPtr->himl, &cx, &cy);
 
       if(lStyle & TCS_VERTICAL)
@@ -1595,36 +1690,37 @@
         center_offset_v = ((drawRect->bottom - drawRect->top) - (cy + infoPtr->uVItemPadding)) / 2;
       }
 
-      if ((lStyle & TCS_FIXEDWIDTH &&
-           lStyle & (TCS_FORCELABELLEFT | TCS_FORCEICONLEFT)) ||
-	  (center_offset_h < 0))
-	center_offset_h = 0;
+      if (lStyle & TCS_FIXEDWIDTH && lStyle & (TCS_FORCELABELLEFT | TCS_FORCEICONLEFT))
+	center_offset_h = infoPtr->uHItemPadding;
 
-      TRACE("for <%s>, c_o=%d, draw=(%ld,%ld)-(%ld,%ld), textlen=%ld\n",
-	  debugstr_w(infoPtr->items[iItem].pszText), center_offset_h,
+      if (center_offset_h < 2)
+        center_offset_h = 2;
+	
+      TRACE("for <%s>, c_o_h=%d, c_o_v=%d, draw=(%ld,%ld)-(%ld,%ld), textlen=%ld\n",
+	  debugstr_w(infoPtr->items[iItem].pszText), center_offset_h, center_offset_v,
 	  drawRect->left, drawRect->top, drawRect->right, drawRect->bottom,
 	  (rcText.right-rcText.left));
 
       if((lStyle & TCS_VERTICAL) && (lStyle & TCS_BOTTOM))
       {
-        rcImage.top  = drawRect->top + center_offset_h;
+        rcImage.top = drawRect->top + center_offset_h;
 	/* if tab is TCS_VERTICAL and TCS_BOTTOM, the text is drawn from the */
 	/* right side of the tab, but the image still uses the left as its x position */
 	/* this keeps the image always drawn off of the same side of the tab */
         rcImage.left = drawRect->right - cx - center_offset_v;
-        drawRect->top = rcImage.top + (cx + infoPtr->uHItemPadding);
+        drawRect->top += cy + infoPtr->uHItemPadding;
       }
       else if(lStyle & TCS_VERTICAL)
       {
         rcImage.top  = drawRect->bottom - cy - center_offset_h;
 	rcImage.left = drawRect->left + center_offset_v;
-        drawRect->bottom = rcImage.top - infoPtr->uHItemPadding;
+        drawRect->bottom -= cy + infoPtr->uHItemPadding;
       }
       else /* normal style, whether TCS_BOTTOM or not */
       {
-        rcImage.left = drawRect->left + center_offset_h + 3;
-        drawRect->left = rcImage.left + cx + infoPtr->uHItemPadding;
+        rcImage.left = drawRect->left + center_offset_h;
 	rcImage.top = drawRect->top + center_offset_v;
+        drawRect->left += cx + infoPtr->uHItemPadding;
       }
 
       TRACE("drawing image=%d, left=%ld, top=%ld\n",
@@ -1639,70 +1735,52 @@
         ILD_NORMAL
         );
     }
-    else /* no image, so just shift the drawRect borders around */
-    {
+
+    /* Now position text */
+    if (lStyle & TCS_FIXEDWIDTH && lStyle & TCS_FORCELABELLEFT)
+      center_offset_h = infoPtr->uHItemPadding;
+    else
       if(lStyle & TCS_VERTICAL)
-      {
-        center_offset_h = 0;
-        /*
-        currently the rcText rect is flawed because the rotated font does not
-        often match the horizontal font. So leave this as 0
-        ((drawRect->bottom - drawRect->top) - (rcText.right - rcText.left)) / 2;
-        */
-        if(lStyle & TCS_BOTTOM)
-          drawRect->top+=center_offset_h;
-        else
-          drawRect->bottom-=center_offset_h;
-      }
+        center_offset_h = ((drawRect->bottom - drawRect->top) - (rcText.right - rcText.left)) / 2;
       else
-      {
         center_offset_h = ((drawRect->right - drawRect->left) - (rcText.right - rcText.left)) / 2;
-        drawRect->left+=center_offset_h;
-      }
-    }
 
     if(lStyle & TCS_VERTICAL)
     {
-      center_offset_v = ((drawRect->right - drawRect->left) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2;
-      drawRect->left += center_offset_v;
+      if(lStyle & TCS_BOTTOM)
+        drawRect->top+=center_offset_h;
+      else
+        drawRect->bottom-=center_offset_h;
+
+      drawRect->left += ((drawRect->right - drawRect->left) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2;
     }
     else
     {
-      center_offset_v = ((drawRect->bottom - drawRect->top) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2;
-      drawRect->top += center_offset_v;
+      drawRect->left += center_offset_h;
+      drawRect->top += ((drawRect->bottom - drawRect->top) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2;
     }
 
-
     /* Draw the text */
-    if ((lStyle & TCS_FIXEDWIDTH && lStyle & TCS_FORCELABELLEFT) ||
-	!center_offset_h)
-      uHorizAlign = DT_LEFT;
-    else
-      uHorizAlign = DT_CENTER;
-
     if(lStyle & TCS_VERTICAL) /* if we are vertical rotate the text and each character */
     {
+      LOGFONTA logfont;
+      HFONT hFont = 0;
+      INT nEscapement = 900;
+      INT nOrientation = 900;
+
       if(lStyle & TCS_BOTTOM)
       {
         nEscapement = -900;
         nOrientation = -900;
       }
-      else
-      {
-        nEscapement = 900;
-        nOrientation = 900;
-      }
-    }
 
-    /* to get a font with the escapement and orientation we are looking for, we need to */
-    /* call CreateFontIndirectA, which requires us to set the values of the logfont we pass in */
-    if(lStyle & TCS_VERTICAL)
-    {
+      /* to get a font with the escapement and orientation we are looking for, we need to */
+      /* call CreateFontIndirectA, which requires us to set the values of the logfont we pass in */
       if (!GetObjectA((infoPtr->hFont) ?
                 infoPtr->hFont : GetStockObject(SYSTEM_FONT),
                 sizeof(LOGFONTA),&logfont))
       {
-        iPointSize = 9;
+        INT iPointSize = 9;
 
         lstrcpyA(logfont.lfFaceName, "Arial");
         logfont.lfHeight = -MulDiv(iPointSize, GetDeviceCaps(hdc, LOGPIXELSY),
@@ -1716,11 +1794,8 @@
       logfont.lfEscapement = nEscapement;
       logfont.lfOrientation = nOrientation;
       hFont = CreateFontIndirectA(&logfont);
-      hOldFont = SelectObject(hdc, hFont);
-    }
+      SelectObject(hdc, hFont);
 
-    if (lStyle & TCS_VERTICAL)
-    {
       ExtTextOutW(hdc,
       (lStyle & TCS_BOTTOM) ? drawRect->right : drawRect->left,
       (!(lStyle & TCS_BOTTOM)) ? drawRect->bottom : drawRect->top,
@@ -1729,6 +1804,8 @@
       infoPtr->items[iItem].pszText,
       lstrlenW(infoPtr->items[iItem].pszText),
       0);
+
+      DeleteObject(hFont);
     }
     else
     {
@@ -1738,24 +1815,17 @@
         infoPtr->items[iItem].pszText,
         lstrlenW(infoPtr->items[iItem].pszText),
         drawRect,
-        uHorizAlign | DT_SINGLELINE
+        DT_LEFT | DT_SINGLELINE
         );
     }
 
-    /* clean things up */
     *drawRect = rcTemp; /* restore drawRect */
-
-    if(lStyle & TCS_VERTICAL)
-    {
-      SelectObject(hdc, hOldFont); /* restore the original font */
-      if (hFont)
-        DeleteObject(hFont);
-    }
   }
 
   /*
   * Cleanup
   */
+  SelectObject(hdc, hOldFont);
   SetBkMode(hdc, oldBkMode);
   SelectObject(hdc, holdPen);
   DeleteObject( htextPen );
@@ -1792,6 +1862,13 @@
 
   if (isVisible)
   {
+    RECT rUD, rC;
+
+    /* Clip UpDown control to not draw over it */
+    GetWindowRect(hwnd, &rC);
+    GetWindowRect(infoPtr->hwndUpDown, &rUD);
+    ExcludeClipRect(hdc, rUD.left - rC.left, rUD.top - rC.top, rUD.right - rC.left, rUD.bottom - rC.top);
+
     /* If you need to see what the control is doing,
      * then override these variables. They will change what
      * fill colors are used for filling the tabs, and the
@@ -1802,9 +1879,6 @@
 
     if (lStyle & TCS_BUTTONS)
     {
-      HBRUSH hbr       = CreateSolidBrush (bkgnd);
-      BOOL   deleteBrush = TRUE;
-
       /* Get item rectangle */
       r = itemRect;
 
@@ -1818,43 +1892,15 @@
 
       if (iItem == infoPtr->iSelected)
       {
-        /* Background color */
-        if (!(lStyle & TCS_OWNERDRAWFIXED))
-	{
-              DeleteObject(hbr);
-              hbr = GetSysColorBrush(COLOR_SCROLLBAR);
-
-              SetTextColor(hdc, comctl32_color.clr3dFace);
-              SetBkColor(hdc, comctl32_color.clr3dHilight);
-
-              /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
-               * we better use 0x55aa bitmap brush to make scrollbar's background
-               * look different from the window background.
-               */
-               if (comctl32_color.clr3dHilight == comctl32_color.clrWindow)
-                  hbr = COMCTL32_hPattern55AABrush;
-
-              deleteBrush = FALSE;
-	}
-
-	/* Clear interior */
-        FillRect(hdc, &r, hbr);
-
 	DrawEdge(hdc, &r, EDGE_SUNKEN, BF_SOFT|BF_RECT);
+	
+	OffsetRect(&r, 1, 1);
       }
       else  /* ! selected */
       {
 	if (!(lStyle & TCS_FLATBUTTONS))
-	{
-	  /* Clear interior */
-          FillRect(hdc, &r, hbr);
-
 	  DrawEdge(hdc, &r, EDGE_RAISED, BF_SOFT|BF_RECT);
-	}
       }
-
-      /* Cleanup */
-      if (deleteBrush) DeleteObject(hbr);
     }
     else /* !TCS_BUTTONS */
     {
@@ -2031,11 +2077,17 @@
 	  r1.bottom--;
 	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDTOPLEFT);
 
-	  if ((iItem == infoPtr->iSelected) && (selectedRect.left == 0)) {
+	  if (iItem == infoPtr->iSelected)
+	  {
+	    r.top += 2;
+	    r.left += 1;
+	    if (selectedRect.left == 0)
+	    {
 	      r1 = r;
 	      r1.bottom = r1.top;
 	      r1.top--;
 	      DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_LEFT);
+	    }
 	  }
 
         }
@@ -2083,22 +2135,7 @@
     TAB_DumpItemInternal(infoPtr, iItem);
 
     /* This modifies r to be the text rectangle. */
-    {
-      HFONT hOldFont = SelectObject(hdc, infoPtr->hFont);
-      TAB_DrawItemInterior(hwnd, hdc, iItem, &r);
-      SelectObject(hdc,hOldFont);
-    }
-
-    /* Draw the focus rectangle */
-    if (((lStyle & TCS_FOCUSNEVER) == 0) &&
-	 (GetFocus() == hwnd) &&
-	 (iItem == infoPtr->uFocus) )
-    {
-      r = itemRect;
-      InflateRect(&r, -1, -1);
-
-      DrawFocusRect(hdc, &r);
-    }
+    TAB_DrawItemInterior(hwnd, hdc, iItem, &r);
   }
 }
 
@@ -2357,7 +2394,7 @@
   HWND      hwnd,
   TAB_INFO* infoPtr)
 {
-  RECT clientRect, r;
+  RECT clientRect, rInvalidate;
   DWORD lStyle = GetWindowLongA(hwnd, GWL_STYLE);
   INT lastRow = infoPtr->uNumRows - 1;
   RECT rect;
@@ -2365,49 +2402,54 @@
   if (lastRow < 0) return;
 
   GetClientRect(hwnd, &clientRect);
+  rInvalidate = clientRect;
 
   TAB_InternalGetItemRect(hwnd, infoPtr, infoPtr->uNumItem-1 , &rect, NULL);
   if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL))
   {
-    clientRect.top = clientRect.bottom -
+    rInvalidate.top = clientRect.bottom -
                    infoPtr->tabHeight -
                    lastRow * (infoPtr->tabHeight - 2) -
                    ((lStyle & TCS_BUTTONS) ? lastRow * BUTTON_SPACINGY : 0) - 3;
-    clientRect.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
+    rInvalidate.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
   }
   else if((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
   {
-    clientRect.left = clientRect.right - infoPtr->tabHeight -
+    rInvalidate.left = clientRect.right - infoPtr->tabHeight -
                       lastRow * (infoPtr->tabHeight - 2) -
                       ((lStyle & TCS_BUTTONS) ? lastRow * BUTTON_SPACINGY : 0) - 2;
-    clientRect.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
+    rInvalidate.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
   }
   else if(lStyle & TCS_VERTICAL)
   {
-    clientRect.right = clientRect.left + infoPtr->tabHeight +
+    rInvalidate.right = clientRect.left + infoPtr->tabHeight +
                        lastRow * (infoPtr->tabHeight - 2) -
                       ((lStyle & TCS_BUTTONS) ? lastRow * BUTTON_SPACINGY : 0) + 2;
-    clientRect.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
+    rInvalidate.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
   }
   else
   {
-    clientRect.bottom = clientRect.top + infoPtr->tabHeight +
+    rInvalidate.bottom = clientRect.top + infoPtr->tabHeight +
                       lastRow * (infoPtr->tabHeight - 2) +
                       ((lStyle & TCS_BUTTONS) ? lastRow * BUTTON_SPACINGY : 0) + 2;
-    clientRect.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
+    rInvalidate.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
   }
   
   /* Punch out the updown control */
-  if (infoPtr->needsScrolling && (clientRect.right > 0)) {
+  if (infoPtr->needsScrolling && (rInvalidate.right > 0)) {
+    RECT r;
     GetClientRect(infoPtr->hwndUpDown, &r);
-    clientRect.right = clientRect.right - (r.right - r.left);
+    if (rInvalidate.right > clientRect.right - r.left)
+      rInvalidate.right = rInvalidate.right - (r.right - r.left);
+    else
+      rInvalidate.right = clientRect.right - r.left;
   }
   
   TRACE("invalidate (%ld,%ld)-(%ld,%ld)\n",
 	clientRect.left,clientRect.top,
 	clientRect.right,clientRect.bottom);
  
-  InvalidateRect(hwnd, &clientRect, TRUE);
+  InvalidateRect(hwnd, &rInvalidate, TRUE);
 }
 
 static LRESULT
@@ -3008,6 +3050,8 @@
   infoPtr->uNumRows        = 0;
   infoPtr->uHItemPadding   = 6;
   infoPtr->uVItemPadding   = 3;
+  infoPtr->uHItemPadding_s = 6;
+  infoPtr->uVItemPadding_s = 3;
   infoPtr->hFont           = 0;
   infoPtr->items           = 0;
   infoPtr->hcurArrow       = LoadCursorA (0, (LPSTR)IDC_ARROW);
Index: tests/tab.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/tests/tab.c,v
retrieving revision 1.1
diff -u -r1.1 tab.c
--- tests/tab.c	31 Oct 2003 00:06:42 -0000	1.1
+++ tests/tab.c	30 Nov 2003 19:37:47 -0000
@@ -32,9 +32,11 @@
 #ifdef VISIBLE
 #define WAIT Sleep (1000)
 #define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
+#define trace_tab(str) trace(str)
 #else
 #define WAIT
 #define REDRAW(hwnd)
+#define trace_tab(str)
 #endif
 
 HWND
@@ -47,10 +49,12 @@
 	WC_TABCONTROLA,
 	"TestTab",
 	WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style,
-        0, 0, 300, 100,
+        10, 10, 300, 100,
         NULL, NULL, NULL, 0);
 
     assert (handle);
+    
+    SetWindowLong(handle, GWL_STYLE, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style);
 
     tcNewTab.mask = TCIF_TEXT | TCIF_IMAGE;
     tcNewTab.pszText = "Tab 1";
@@ -74,10 +78,13 @@
 
 void CheckSize(HWND hwnd, INT width, INT height)
 {
-    RECT rTab;
+    RECT rTab, r1;
 
-    SendMessage (hwnd, TCM_GETITEMRECT, 1, (LPARAM) &rTab);
-    /*trace ("Got (%ld,%ld)-(%ld,%ld)\n", rTab.left, rTab.top, rTab.right, rTab.bottom);*/
+    r1.left=r1.top=r1.right=r1.bottom=0;
+    SendMessage (hwnd, TCM_GETITEMRECT, 0, (LPARAM) &rTab);
+    SendMessage (hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM) &r1);
+    /* trace ("Got (%ld,%ld)-(%ld,%ld)", rTab.left, rTab.top, rTab.right, rTab.bottom); */
+    trace (" (%ld,%ld)-(%ld,%ld)\n", r1.left, r1.top, r1.right, r1.bottom);
     if ((width  >= 0) && (height < 0))
 	ok (width  == rTab.right  - rTab.left, "Expected [%d] got [%ld]",  width,  rTab.right  - rTab.left);
     else if ((height >= 0) && (width  < 0))
@@ -107,59 +114,84 @@
 
     hwTab = create_tabcontrol(TCS_FIXEDWIDTH);
 
-    trace ("Testing TCS_FIXEDWIDTH tabs no icon...\n");
-    trace ("  default width...\n");
+    trace_tab ("Testing TCS_FIXEDWIDTH tabs no icon...\n");
+    trace_tab ("  default width...\n");
     CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
-    trace ("  set size...\n");
+    trace_tab ("  set size...\n");
     TabCheckSetSize(hwTab, 50, 20, 50, 20);
     WAIT;
-    trace ("  min size...\n");
+    trace_tab ("  min size...\n");
     TabCheckSetSize(hwTab, 0, 1, 0, 1);
     WAIT;
 
     SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
 
-    trace ("Testing TCS_FIXEDWIDTH tabs with icon...\n");
-    trace ("  set size > icon...\n");
+    trace_tab ("Testing TCS_FIXEDWIDTH tabs with icon...\n");
+    trace_tab ("  set size > icon...\n");
     TabCheckSetSize(hwTab, 50, 30, 50, 30);
-    WAIT;
-    trace ("  set size < icon...\n");
+    trace_tab ("  set size < icon...\n");
     TabCheckSetSize(hwTab, 20, 20, 25, 20);
-    WAIT;
-    trace ("  min size...\n");
+    trace_tab ("  min size...\n");
     TabCheckSetSize(hwTab, 0, 1, 25, 1);
-    WAIT;
 
     DestroyWindow (hwTab);
 
-    trace ("Testing TCS_FIXEDWIDTH buttons no icon...\n");
+    trace_tab ("Testing TCS_FIXEDWIDTH buttons no icon...\n");
     hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BUTTONS);
 
-    trace ("  default width...\n");
+    trace_tab ("  default width...\n");
     CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
-    trace ("  set size 1...\n");
+    trace_tab ("  set size 1...\n");
     TabCheckSetSize(hwTab, 20, 20, 20, 20);
-    trace ("  set size 2...\n");
+    trace_tab ("  set size 2...\n");
     TabCheckSetSize(hwTab, 10, 50, 10, 50);
-    trace ("  min size...\n");
+    trace_tab ("  min size...\n");
     TabCheckSetSize(hwTab, 0, 1, 0, 1);
 
     SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
 
-    trace ("Testing TCS_FIXEDWIDTH buttons with icon...\n");
-    trace ("  set size > icon...\n");
+    trace_tab ("Testing TCS_FIXEDWIDTH buttons with icon...\n");
+    trace_tab ("  set size > icon...\n");
     TabCheckSetSize(hwTab, 50, 30, 50, 30);
-    trace ("  set size < icon...\n");
+    trace_tab ("  set size < icon...\n");
     TabCheckSetSize(hwTab, 20, 20, 25, 20);
-    trace ("  min size...\n");
+    trace_tab ("  min size...\n");
     TabCheckSetSize(hwTab, 0, 1, 25, 1);
-
-    trace (" Add padding...\n");
+    trace_tab (" Add padding...\n");
     SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4));
-    trace ("  min size...\n");
+    trace_tab ("  min size...\n");
     TabCheckSetSize(hwTab, 0, 1, 25, 1);
-    WAIT;
+
+    DestroyWindow (hwTab);
+
+    hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BOTTOM);
+    trace_tab ("Testing TCS_FIXEDWIDTH | TCS_BOTTOM tabs no icon...\n");
+
+    trace_tab ("  default width...\n");
+    CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
+    trace_tab ("  set size 1...\n");
+    TabCheckSetSize(hwTab, 20, 20, 20, 20);
+    trace_tab ("  set size 2...\n");
+    TabCheckSetSize(hwTab, 10, 50, 10, 50);
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 0, 1);
+
+    SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
     
+    trace_tab ("Testing TCS_FIXEDWIDTH | TCS_BOTTOM tabs with icon...\n");
+    trace_tab ("  set size > icon...\n");
+    TabCheckSetSize(hwTab, 50, 30, 50, 30);
+    trace_tab ("  set size < icon...\n");
+    TabCheckSetSize(hwTab, 20, 20, 25, 20);
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 25, 1);
+    trace_tab (" Add padding...\n");
+    SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4));
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 25, 1);
+
     DestroyWindow (hwTab);
+
+
     ImageList_Destroy(himl);
 }


More information about the wine-patches mailing list