Fix tab size (3)

Vitaliy Margolen wine-patch at kievinfo.com
Sun Oct 19 18:41:43 CDT 2003


Experimenting with tab control I found this differences between MSDN and actual
implementation:
- TCS_OWNERDRAWFIXED style has nothing to do with fixed with tabs. It should me
  named TCS_OWNERDRAW instead. Unless there is some apps that think otherwise,
  this should work (tested on eMule and test program).

  In other words, this quote from MSDN is not true:
  "Because all tabs in an owner-drawn tab control are the same size..."

- It looks like there is not such thing as not set tab width. According to this:

  "To give all tabs the same width, you can specify the TCS_FIXEDWIDTH
  style. The control sizes all the tabs to fit the widest label, or you can assign
  a specific width and height by using the TCM_SETITEMSIZE message."

  one can assume that if tab width is not explicitly set with TCM_SETITEMSIZE
  message "The control sizes all the tabs to fit the widest label".

  Not true. Native uses default tab size of 96.

- The minimum size of a tab is at least icon width + 3 if icon is present.

- Prior observation that "under Windows, there seems to be a minimum width of 2x
  the height for button style tabs" is not true. At least not in Win98.

Vitaliy Margolen

changelog:
  - Fix tab size for TCS_OWNERDRAWFIXED style
  - Correct size recalculation after setting tab width
  - Fix button sizes to match native.

to-do (I'm working on):
  - Correct text & icon position within each tab/button to match native
  - Fix hot-track
-------------- next part --------------
Index: tab.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/tab.c,v
retrieving revision 1.86
diff -u -r1.86 tab.c
--- tab.c	14 Oct 2003 20:12:05 -0000	1.86
+++ tab.c	19 Oct 2003 23:16:51 -0000
@@ -93,7 +93,7 @@
 #define DISPLAY_AREA_PADDINGY   2
 #define CONTROL_BORDER_SIZEX    2
 #define CONTROL_BORDER_SIZEY    2
-#define BUTTON_SPACINGX         4
+#define BUTTON_SPACINGX         3
 #define BUTTON_SPACINGY         4
 #define FLAT_BTN_SPACINGX       8
 #define DEFAULT_TAB_WIDTH       96
@@ -1072,6 +1072,7 @@
   INT         iTemp;
   RECT*       rcItem;
   INT         iIndex;
+  INT         icon_width = 0;
 
   /*
    * We need to get text information so we need a DC and we need to select
@@ -1134,37 +1135,31 @@
 
   TRACE("client right=%ld\n", clientRect.right);
 
+  /* Get the icon width */
+  if (infoPtr->himl)
+    ImageList_GetIconSize(infoPtr->himl, &icon_width, 0);
+
   for (curItem = 0; curItem < infoPtr->uNumItem; curItem++)
   {
     /* Set the leftmost position of the tab. */
     infoPtr->items[curItem].rect.left = curItemLeftPos;
 
-    if ( lStyle & (TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED) )
+    if (lStyle & TCS_FIXEDWIDTH)
     {
       infoPtr->items[curItem].rect.right = infoPtr->items[curItem].rect.left +
-                                           infoPtr->tabWidth +
-                                           2 * infoPtr->uHItemPadding;
+        max(infoPtr->tabWidth, icon_width + 4);
     }
     else
     {
-      int icon_width  = 0;
       int num = 2;
 
       /* Calculate how wide the tab is depending on the text it contains */
       GetTextExtentPoint32W(hdc, infoPtr->items[curItem].pszText,
                             lstrlenW(infoPtr->items[curItem].pszText), &size);
 
-      /* under Windows, there seems to be a minimum width of 2x the height
-       * for button style tabs */
-      if (lStyle & TCS_BUTTONS)
-	      size.cx = max(size.cx, 2 * (infoPtr->tabHeight - 2));
-
-      /* Add the icon width */
-      if (infoPtr->himl)
-      {
-        ImageList_GetIconSize(infoPtr->himl, &icon_width, 0);
+      /* Add padding if icon is present */
+      if (icon_width)
         num++;
-      }
 
       infoPtr->items[curItem].rect.right = infoPtr->items[curItem].rect.left +
                                            size.cx + icon_width +
@@ -1215,7 +1210,7 @@
      */
     if (lStyle & TCS_BUTTONS)
     {
-      curItemLeftPos = infoPtr->items[curItem].rect.right + 1;
+      curItemLeftPos = infoPtr->items[curItem].rect.right + BUTTON_SPACINGX;
       if (lStyle & TCS_FLATBUTTONS)
         curItemLeftPos += FLAT_BTN_SPACINGX;
     }
@@ -2572,8 +2567,7 @@
   lResult = MAKELONG(infoPtr->tabWidth, infoPtr->tabHeight);
 
   /* UNDOCUMENTED: If requested Width or Height is 0 this means that program wants to use auto size. */
-  if ((lStyle & (TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED)) &&
-      (infoPtr->tabWidth != (INT)LOWORD(lParam)))
+  if (lStyle & TCS_FIXEDWIDTH && (infoPtr->tabWidth != (INT)LOWORD(lParam)))
   {
     infoPtr->tabWidth = max((INT)LOWORD(lParam), infoPtr->tabMinWidth);
     bNeedPaint = TRUE;
@@ -2583,8 +2577,6 @@
   {
     if ((infoPtr->fHeightSet = ((INT)HIWORD(lParam) != 0)))
       infoPtr->tabHeight = (INT)HIWORD(lParam);
-    else
-      TAB_SetItemBounds(hwnd);
 
     bNeedPaint = TRUE;
   }
@@ -2593,7 +2585,10 @@
        infoPtr->tabHeight, infoPtr->tabWidth);
 
   if (bNeedPaint)
+  {
+    TAB_SetItemBounds(hwnd);
     RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
+  }
     
   return lResult;
 }
@@ -2990,7 +2985,7 @@
   infoPtr->needsScrolling  = FALSE;
   infoPtr->hwndUpDown      = 0;
   infoPtr->leftmostVisible = 0;
-  infoPtr->fHeightSet     = FALSE;
+  infoPtr->fHeightSet      = FALSE;
   infoPtr->bUnicode	   = IsWindowUnicode (hwnd);
 
   TRACE("Created tab control, hwnd [%p]\n", hwnd);
@@ -3043,8 +3038,7 @@
 
   /* Initialize the width of a tab. */
   infoPtr->tabWidth = DEFAULT_TAB_WIDTH;
-  /* The minimum width is the default width at creation */
-  infoPtr->tabMinWidth = DEFAULT_TAB_WIDTH;
+  infoPtr->tabMinWidth = 0;
 
   TRACE("tabH=%d, tabW=%d\n", infoPtr->tabHeight, infoPtr->tabWidth);
 


More information about the wine-patches mailing list