/*
 * Tab control
 *
 * Copyright 1998 Anders Carlsson
 * Copyright 1999 Alex Priem <alexp@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
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * NOTES
 *
 * This code was audited for completeness against the documented features
 * of Comctl32.dll version 6.0 on May. 20, 2005, by James Hawkins.
 *
 * Unless otherwise noted, we believe this code to be complete, as per
 * the specification mentioned above.
 * If you discover missing features, or bugs, please note them below.
 *
 * TODO:
 *
 *  Styles:
 *   TCS_MULTISELECT - implement for VK_SPACE selection
 *   TCS_RIGHT
 *   TCS_RIGHTJUSTIFY
 *   TCS_SCROLLOPPOSITE
 *   TCS_SINGLELINE
 *   TCIF_RTLREADING
 *
 *  Extended Styles:
 *   TCS_EX_REGISTERDROP
 *
 *  Notifications:
 *   NM_RELEASEDCAPTURE
 *   TCN_FOCUSCHANGE
 *   TCN_GETOBJECT
 *
 *  Macros:
 *   TabCtrl_AdjustRect
 *
 */

#include <assert.h>
#include <stdarg.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "uxtheme.h"
#include "vssym32.h"
#include "wine/debug.h"
#include <math.h>

WINE_DEFAULT_DEBUG_CHANNEL(tab);

typedef struct
{
  DWORD  dwState;
  LPWSTR pszText;
  INT    iImage;
  RECT   rect;      /* bounding rectangle of the item relative to the
                     * leftmost item (the leftmost item, 0, would have a
                     * "left" member of 0 in this rectangle)
                     *
                     * additionally the top member holds the row number
                     * and bottom is unused and should be 0 */
  BYTE   extra[1];  /* Space for caller supplied info, variable size */
} TAB_ITEM;

/* The size of a tab item depends on how much extra data is requested.
   TCM_INSERTITEM always stores at least LPARAM sized data. */
#define EXTRA_ITEM_SIZE(infoPtr) (max((infoPtr)->cbInfo, sizeof(LPARAM)))
#define TAB_ITEM_SIZE(infoPtr) FIELD_OFFSET(TAB_ITEM, extra[EXTRA_ITEM_SIZE(infoPtr)])

typedef struct
{
  HWND       hwnd;            /* Tab control window */
  HWND       hwndNotify;      /* notification window (parent) */
  UINT       uNumItem;        /* number of tab items */
  UINT       uNumRows;	      /* number of tab rows */
  INT        tabHeight;       /* height of the tab row */
  INT        tabWidth;        /* width of tabs */
  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 an image list (may be 0) */
  HWND       hwndToolTip;     /* handle to tab's tooltip */
  INT        leftmostVisible; /* Used for scrolling, this member contains
                               * the index of the first visible item */
  INT        iSelected;       /* the currently selected item */
  INT        iHotTracked;     /* the highlighted item under the mouse */
  INT        uFocus;          /* item which has the focus */
  BOOL       DoRedraw;        /* flag for redrawing when tab contents is changed*/
  BOOL       needsScrolling;  /* TRUE if the size of the tabs is greater than
                               * the size of the control */
  BOOL       fHeightSet;      /* was the height of the tabs explicitly set? */
  BOOL       bUnicode;        /* Unicode control? */
  HWND       hwndUpDown;      /* Updown control used for scrolling */
  INT        cbInfo;          /* Number of bytes of caller supplied info per tab */

  DWORD      exStyle;         /* Extended style used, currently:
                                 TCS_EX_FLATSEPARATORS, TCS_EX_REGISTERDROP */
  DWORD      dwStyle;         /* the cached window GWL_STYLE */

  HDPA       items;           /* dynamic array of TAB_ITEM* pointers */
} TAB_INFO;

/******************************************************************************
 * Positioning constants
 */
#define SELECTED_TAB_OFFSET     2
#define ROUND_CORNER_SIZE       2
#define DISPLAY_AREA_PADDINGX   2
#define DISPLAY_AREA_PADDINGY   2
#define CONTROL_BORDER_SIZEX    2
#define CONTROL_BORDER_SIZEY    2
#define BUTTON_SPACINGX         3
#define BUTTON_SPACINGY         3
#define FLAT_BTN_SPACINGX       8
#define DEFAULT_MIN_TAB_WIDTH   54
#define DEFAULT_PADDING_X       6
#define EXTRA_ICON_PADDING      3

#define TAB_GetInfoPtr(hwnd) ((TAB_INFO *)GetWindowLongPtrW(hwnd,0))

#define GET_DEFAULT_MIN_TAB_WIDTH(infoPtr) (DEFAULT_MIN_TAB_WIDTH - (DEFAULT_PADDING_X - (infoPtr)->uHItemPadding) * 2)

/******************************************************************************
 * Hot-tracking timer constants
 */
#define TAB_HOTTRACK_TIMER            1
#define TAB_HOTTRACK_TIMER_INTERVAL   100   /* milliseconds */

static const WCHAR themeClass[] = { 'T','a','b',0 };

static inline TAB_ITEM* TAB_GetItem(const TAB_INFO *infoPtr, INT i)
{
    assert(i >= 0 && i < infoPtr->uNumItem);
    return DPA_GetPtr(infoPtr->items, i);
}

/******************************************************************************
 * Prototypes
 */
static void TAB_InvalidateTabArea(const TAB_INFO *);
static void TAB_EnsureSelectionVisible(TAB_INFO *);
static void TAB_DrawItemInterior(const TAB_INFO *, HDC, INT, RECT*);
static LRESULT TAB_DeselectAll(TAB_INFO *, BOOL);
static BOOL TAB_InternalGetItemRect(const TAB_INFO *, INT, RECT*, RECT*);

static BOOL
TAB_SendSimpleNotify (const TAB_INFO *infoPtr, UINT code)
{
    NMHDR nmhdr;

    nmhdr.hwndFrom = infoPtr->hwnd;
    nmhdr.idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);
    nmhdr.code = code;

    return (BOOL) SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
            nmhdr.idFrom, (LPARAM) &nmhdr);
}

static void
TAB_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
            WPARAM wParam, LPARAM lParam)
{
    MSG msg;

    msg.hwnd = hwndMsg;
    msg.message = uMsg;
    msg.wParam = wParam;
    msg.lParam = lParam;
    msg.time = GetMessageTime ();
    msg.pt.x = (short)LOWORD(GetMessagePos ());
    msg.pt.y = (short)HIWORD(GetMessagePos ());

    SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
}

static void
TAB_DumpItemExternalT(const TCITEMW *pti, UINT iItem, BOOL isW)
{
    if (TRACE_ON(tab)) {
	TRACE("external tab %d, mask=0x%08x, dwState=0x%08x, dwStateMask=0x%08x, cchTextMax=0x%08x\n",
	      iItem, pti->mask, pti->dwState, pti->dwStateMask, pti->cchTextMax);
	TRACE("external tab %d,   iImage=%d, lParam=0x%08lx, pszTextW=%s\n",
	      iItem, pti->iImage, pti->lParam, isW ? debugstr_w(pti->pszText) : debugstr_a((LPSTR)pti->pszText));
    }
}

static void
TAB_DumpItemInternal(const TAB_INFO *infoPtr, UINT iItem)
{
    if (TRACE_ON(tab)) {
	TAB_ITEM *ti = TAB_GetItem(infoPtr, iItem);

	TRACE("tab %d, dwState=0x%08x, pszText=%s, iImage=%d\n",
	      iItem, ti->dwState, debugstr_w(ti->pszText), ti->iImage);
	TRACE("tab %d, rect.left=%d, rect.top(row)=%d\n",
	      iItem, ti->rect.left, ti->rect.top);
    }
}

/* RETURNS
 *   the index of the selected tab, or -1 if no tab is selected. */
static inline LRESULT TAB_GetCurSel (const TAB_INFO *infoPtr)
{
    TRACE("(%p)\n", infoPtr);
    return infoPtr->iSelected;
}

/* RETURNS
 *   the index of the tab item that has the focus. */
static inline LRESULT
TAB_GetCurFocus (const TAB_INFO *infoPtr)
{
    TRACE("(%p)\n", infoPtr);
    return infoPtr->uFocus;
}

static inline LRESULT TAB_GetToolTips (const TAB_INFO *infoPtr)
{
    TRACE("(%p)\n", infoPtr);
    return (LRESULT)infoPtr->hwndToolTip;
}

static inline LRESULT TAB_SetCurSel (TAB_INFO *infoPtr, INT iItem)
{
  INT prevItem = infoPtr->iSelected;

  TRACE("(%p %d)\n", infoPtr, iItem);

  if (iItem >= (INT)infoPtr->uNumItem)
      return -1;

  if (prevItem != iItem) {
      if (prevItem != -1)
          TAB_GetItem(infoPtr, prevItem)->dwState &= ~TCIS_BUTTONPRESSED;

      if (iItem >= 0)
      {
          TAB_GetItem(infoPtr, iItem)->dwState |= TCIS_BUTTONPRESSED;
          infoPtr->iSelected = iItem;
          infoPtr->uFocus = iItem;
      }
      else
      {
          infoPtr->iSelected = -1;
          infoPtr->uFocus = -1;
      }

      TAB_EnsureSelectionVisible(infoPtr);
      TAB_InvalidateTabArea(infoPtr);
  }

  return prevItem;
}

static LRESULT TAB_SetCurFocus (TAB_INFO *infoPtr, INT iItem)
{
  TRACE("(%p %d)\n", infoPtr, iItem);

  if (iItem < 0) {
      infoPtr->uFocus = -1;
      if (infoPtr->iSelected != -1) {
          infoPtr->iSelected = -1;
          TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGE);
          TAB_InvalidateTabArea(infoPtr);
      }
  }
  else if (iItem < infoPtr->uNumItem) {
    if (infoPtr->dwStyle & TCS_BUTTONS) {
      /* set focus to new item, leave selection as is */
      if (infoPtr->uFocus != iItem) {
        INT prev_focus = infoPtr->uFocus;
        RECT r;

        infoPtr->uFocus = iItem;

        if (prev_focus != infoPtr->iSelected) {
          if (TAB_InternalGetItemRect(infoPtr, prev_focus, &r, NULL))
            InvalidateRect(infoPtr->hwnd, &r, FALSE);
        }

        if (TAB_InternalGetItemRect(infoPtr, iItem, &r, NULL))
            InvalidateRect(infoPtr->hwnd, &r, FALSE);

        TAB_SendSimpleNotify(infoPtr, TCN_FOCUSCHANGE);
      }
    } else {
      INT oldFocus = infoPtr->uFocus;
      if (infoPtr->iSelected != iItem || oldFocus == -1 ) {
        infoPtr->uFocus = iItem;
        if (oldFocus != -1) {
          if (!TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGING))  {
            infoPtr->iSelected = iItem;
            TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGE);
          }
          else
            infoPtr->iSelected = iItem;
          TAB_EnsureSelectionVisible(infoPtr);
          TAB_InvalidateTabArea(infoPtr);
        }
      }
    }
  }
  return 0;
}

static inline LRESULT
TAB_SetToolTips (TAB_INFO *infoPtr, HWND hwndToolTip)
{
    TRACE("%p %p\n", infoPtr, hwndToolTip);
    infoPtr->hwndToolTip = hwndToolTip;
    return 0;
}

static inline LRESULT
TAB_SetPadding (TAB_INFO *infoPtr, LPARAM lParam)
{
    TRACE("(%p %d %d)\n", infoPtr, LOWORD(lParam), HIWORD(lParam));
    infoPtr->uHItemPadding_s = LOWORD(lParam);
    infoPtr->uVItemPadding_s = HIWORD(lParam);

    return 0;
}

/******************************************************************************
 * TAB_InternalGetItemRect
 *
 * This method will calculate the rectangle representing a given tab item in
 * client coordinates. This method takes scrolling into account.
 *
 * This method returns TRUE if the item is visible in the window and FALSE
 * if it is completely outside the client area.
 */
static BOOL TAB_InternalGetItemRect(
  const TAB_INFO* infoPtr,
  INT         itemIndex,
  RECT*       itemRect,
  RECT*       selectedRect)
{
  RECT tmpItemRect,clientRect;

  /* Perform a sanity check and a trivial visibility check. */
  if ( (infoPtr->uNumItem <= 0) ||
       (itemIndex >= infoPtr->uNumItem) ||
       (!(((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL))) &&
         (itemIndex < infoPtr->leftmostVisible)))
    {
        TRACE("Not Visible\n");
        /* need to initialize these to empty rects */
        if (itemRect)
        {
            memset(itemRect,0,sizeof(RECT));
            itemRect->bottom = infoPtr->tabHeight;
        }
        if (selectedRect)
            memset(selectedRect,0,sizeof(RECT));
        return FALSE;
    }

  /*
   * Avoid special cases in this procedure by assigning the "out"
   * parameters if the caller didn't supply them
   */
  if (itemRect == NULL)
    itemRect = &tmpItemRect;

  /* Retrieve the unmodified item rect. */
  *itemRect = TAB_GetItem(infoPtr,itemIndex)->rect;

  /* calculate the times bottom and top based on the row */
  GetClientRect(infoPtr->hwnd, &clientRect);

  if ((infoPtr->dwStyle & TCS_BOTTOM) && (infoPtr->dwStyle & TCS_VERTICAL))
  {
    itemRect->right  = clientRect.right - SELECTED_TAB_OFFSET - itemRect->left * infoPtr->tabHeight -
                       ((infoPtr->dwStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGX : 0);
    itemRect->left   = itemRect->right - infoPtr->tabHeight;
  }
  else if (infoPtr->dwStyle & TCS_VERTICAL)
  {
    itemRect->left   = clientRect.left + SELECTED_TAB_OFFSET + itemRect->left * infoPtr->tabHeight +
                       ((infoPtr->dwStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGX : 0);
    itemRect->right  = itemRect->left + infoPtr->tabHeight;
  }
  else if (infoPtr->dwStyle & TCS_BOTTOM)
  {
    itemRect->bottom = clientRect.bottom - itemRect->top * infoPtr->tabHeight -
                       ((infoPtr->dwStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
    itemRect->top    = itemRect->bottom - infoPtr->tabHeight;
  }
  else /* not TCS_BOTTOM and not TCS_VERTICAL */
  {
    itemRect->top    = clientRect.top + itemRect->top * infoPtr->tabHeight +
                       ((infoPtr->dwStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
    itemRect->bottom = itemRect->top + infoPtr->tabHeight;
 }

  /*
   * "scroll" it to make sure the item at the very left of the
   * tab control is the leftmost visible tab.
   */
  if(infoPtr->dwStyle & TCS_VERTICAL)
  {
    OffsetRect(itemRect,
	     0,
	     -TAB_GetItem(infoPtr, infoPtr->leftmostVisible)->rect.top);

    /*
     * Move the rectangle so the first item is slightly offset from
     * the bottom of the tab control.
     */
    OffsetRect(itemRect,
	     0,
	     SELECTED_TAB_OFFSET);

  } else
  {
    OffsetRect(itemRect,
	     -TAB_GetItem(infoPtr, infoPtr->leftmostVisible)->rect.left,
	     0);

    /*
     * Move the rectangle so the first item is slightly offset from
     * the left of the tab control.
     */
    OffsetRect(itemRect,
	     SELECTED_TAB_OFFSET,
	     0);
  }
  TRACE("item %d tab h=%d, rect=(%s)\n",
        itemIndex, infoPtr->tabHeight, wine_dbgstr_rect(itemRect));

  /* Now, calculate the position of the item as if it were selected. */
  if (selectedRect!=NULL)
  {
    CopyRect(selectedRect, itemRect);

    /* The rectangle of a selected item is a bit wider. */
    if(infoPtr->dwStyle & TCS_VERTICAL)
      InflateRect(selectedRect, 0, SELECTED_TAB_OFFSET);
    else
      InflateRect(selectedRect, SELECTED_TAB_OFFSET, 0);

    /* If it also a bit higher. */
    if ((infoPtr->dwStyle & TCS_BOTTOM) && (infoPtr->dwStyle & TCS_VERTICAL))
    {
      selectedRect->left   -= 2; /* the border is thicker on the right */
      selectedRect->right  += SELECTED_TAB_OFFSET;
    }
    else if (infoPtr->dwStyle & TCS_VERTICAL)
    {
      selectedRect->left   -= SELECTED_TAB_OFFSET;
      selectedRect->right  += 1;
    }
    else if (infoPtr->dwStyle & TCS_BOTTOM)
    {
      selectedRect->bottom += SELECTED_TAB_OFFSET;
    }
    else /* not TCS_BOTTOM and not TCS_VERTICAL */
    {
      selectedRect->top    -= SELECTED_TAB_OFFSET;
      selectedRect->bottom -= 1;
    }
  }

  /* Check for visibility */
  if (infoPtr->dwStyle & TCS_VERTICAL)
    return (itemRect->top < clientRect.bottom) && (itemRect->bottom > clientRect.top);
  else
    return (itemRect->left < clientRect.right) && (itemRect->right > clientRect.left);
}

static inline BOOL
TAB_GetItemRect(const TAB_INFO *infoPtr, INT item, RECT *rect)
{
  TRACE("(%p, %d, %p)\n", infoPtr, item, rect);
  return TAB_InternalGetItemRect(infoPtr, item, rect, NULL);
}

/******************************************************************************
 * TAB_KeyDown
 *
 * This method is called to handle keyboard input
 */
static LRESULT TAB_KeyDown(TAB_INFO* infoPtr, WPARAM keyCode, LPARAM lParam)
{
  INT newItem = -1;
  NMTCKEYDOWN nm;

  /* TCN_KEYDOWN notification sent always */
  nm.hdr.hwndFrom = infoPtr->hwnd;
  nm.hdr.idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);
  nm.hdr.code = TCN_KEYDOWN;
  nm.wVKey = keyCode;
  nm.flags = lParam;
  SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nm.hdr.idFrom, (LPARAM)&nm);

  switch (keyCode)
  {
    case VK_LEFT:
      newItem = infoPtr->uFocus - 1;
      break;
    case VK_RIGHT:
      newItem = infoPtr->uFocus + 1;
      break;
  }

  /* If we changed to a valid item, change focused item */
  if (newItem >= 0 && newItem < infoPtr->uNumItem && infoPtr->uFocus != newItem)
      TAB_SetCurFocus(infoPtr, newItem);

  return 0;
}

/*
 * WM_KILLFOCUS handler
 */
static void TAB_KillFocus(TAB_INFO *infoPtr)
{
  /* clear current focused item back to selected for TCS_BUTTONS */
  if ((infoPtr->dwStyle & TCS_BUTTONS) && (infoPtr->uFocus != infoPtr->iSelected))
  {
    RECT r;

    if (TAB_InternalGetItemRect(infoPtr, infoPtr->uFocus, &r, NULL))
      InvalidateRect(infoPtr->hwnd, &r, FALSE);

    infoPtr->uFocus = infoPtr->iSelected;
  }
}

/******************************************************************************
 * TAB_FocusChanging
 *
 * This method is called whenever the focus goes in or out of this control
 * it is used to update the visual state of the control.
 */
static void TAB_FocusChanging(const TAB_INFO *infoPtr)
{
  RECT      selectedRect;
  BOOL      isVisible;

  /*
   * Get the rectangle for the item.
   */
  isVisible = TAB_InternalGetItemRect(infoPtr,
				      infoPtr->uFocus,
				      NULL,
				      &selectedRect);

  /*
   * If the rectangle is not completely invisible, invalidate that
   * portion of the window.
   */
  if (isVisible)
  {
    TRACE("invalidate (%s)\n", wine_dbgstr_rect(&selectedRect));
    InvalidateRect(infoPtr->hwnd, &selectedRect, TRUE);
  }
}

static INT TAB_InternalHitTest (const TAB_INFO *infoPtr, POINT pt, UINT *flags)
{
  RECT rect;
  INT iCount;

  for (iCount = 0; iCount < infoPtr->uNumItem; iCount++)
  {
    TAB_InternalGetItemRect(infoPtr, iCount, &rect, NULL);

    if (PtInRect(&rect, pt))
    {
      *flags = TCHT_ONITEM;
      return iCount;
    }
  }

  *flags = TCHT_NOWHERE;
  return -1;
}

static inline LRESULT
TAB_HitTest (const TAB_INFO *infoPtr, LPTCHITTESTINFO lptest)
{
  TRACE("(%p, %p)\n", infoPtr, lptest);
  return TAB_InternalHitTest (infoPtr, lptest->pt, &lptest->flags);
}

/******************************************************************************
 * TAB_NCHitTest
 *
 * Napster v2b5 has a tab control for its main navigation which has a client
 * area that covers the whole area of the dialog pages.
 * That's why it receives all msgs for that area and the underlying dialog ctrls
 * are dead.
 * So I decided that we should handle WM_NCHITTEST here and return
 * HTTRANSPARENT if we don't hit the tab control buttons.
 * FIXME: WM_NCHITTEST handling correct ? Fix it if you know that Windows
 * doesn't do it that way. Maybe depends on tab control styles ?
 */
static inline LRESULT
TAB_NCHitTest (const TAB_INFO *infoPtr, LPARAM lParam)
{
  POINT pt;
  UINT dummyflag;

  pt.x = (short)LOWORD(lParam);
  pt.y = (short)HIWORD(lParam);
  ScreenToClient(infoPtr->hwnd, &pt);

  if (TAB_InternalHitTest(infoPtr, pt, &dummyflag) == -1)
    return HTTRANSPARENT;
  else
    return HTCLIENT;
}

static LRESULT
TAB_LButtonDown (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
  POINT pt;
  INT newItem;
  UINT dummy;

  if (infoPtr->hwndToolTip)
    TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
		    WM_LBUTTONDOWN, wParam, lParam);

  if (!(infoPtr->dwStyle & TCS_FOCUSNEVER)) {
    SetFocus (infoPtr->hwnd);
  }

  if (infoPtr->hwndToolTip)
    TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
		    WM_LBUTTONDOWN, wParam, lParam);

  pt.x = (short)LOWORD(lParam);
  pt.y = (short)HIWORD(lParam);

  newItem = TAB_InternalHitTest (infoPtr, pt, &dummy);

  TRACE("On Tab, item %d\n", newItem);

  if ((newItem != -1) && (infoPtr->iSelected != newItem))
  {
    if ((infoPtr->dwStyle & TCS_BUTTONS) && (infoPtr->dwStyle & TCS_MULTISELECT) &&
        (wParam & MK_CONTROL))
    {
      RECT r;

      /* toggle multiselection */
      TAB_GetItem(infoPtr, newItem)->dwState ^= TCIS_BUTTONPRESSED;
      if (TAB_InternalGetItemRect (infoPtr, newItem, &r, NULL))
        InvalidateRect (infoPtr->hwnd, &r, TRUE);
    }
    else
    {
      INT i;
      BOOL pressed = FALSE;

      /* any button pressed ? */
      for (i = 0; i < infoPtr->uNumItem; i++)
        if ((TAB_GetItem (infoPtr, i)->dwState & TCIS_BUTTONPRESSED) &&
            (infoPtr->iSelected != i))
        {
          pressed = TRUE;
          break;
        }

      if (TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGING))
        return 0;

      if (pressed)
        TAB_DeselectAll (infoPtr, FALSE);
      else
        TAB_SetCurSel(infoPtr, newItem);

      TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGE);
    }
  }

  return 0;
}

static inline LRESULT
TAB_LButtonUp (const TAB_INFO *infoPtr)
{
  TAB_SendSimpleNotify(infoPtr, NM_CLICK);

  return 0;
}

static inline void
TAB_RButtonUp (const TAB_INFO *infoPtr)
{
  TAB_SendSimpleNotify(infoPtr, NM_RCLICK);
}

/******************************************************************************
 * TAB_DrawLoneItemInterior
 *
 * This calls TAB_DrawItemInterior.  However, TAB_DrawItemInterior is normally
 * called by TAB_DrawItem which is normally called by TAB_Refresh which sets
 * up the device context and font.  This routine does the same setup but
 * only calls TAB_DrawItemInterior for the single specified item.
 */
static void
TAB_DrawLoneItemInterior(const TAB_INFO* infoPtr, int iItem)
{
  HDC hdc = GetDC(infoPtr->hwnd);
  RECT r, rC;

  /* Clip UpDown control to not draw over it */
  if (infoPtr->needsScrolling)
  {
    GetWindowRect(infoPtr->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(infoPtr, hdc, iItem, NULL);
  ReleaseDC(infoPtr->hwnd, hdc);
}

/* update a tab after hottracking - invalidate it or just redraw the interior,
 * based on whether theming is used or not */
static inline void hottrack_refresh(const TAB_INFO *infoPtr, int tabIndex)
{
    if (tabIndex == -1) return;

    if (GetWindowTheme (infoPtr->hwnd))
    {
        RECT rect;
        TAB_InternalGetItemRect(infoPtr, tabIndex, &rect, NULL);
        InvalidateRect (infoPtr->hwnd, &rect, FALSE);
    }
    else
        TAB_DrawLoneItemInterior(infoPtr, tabIndex);
}

/******************************************************************************
 * TAB_HotTrackTimerProc
 *
 * When a mouse-move event causes a tab to be highlighted (hot-tracking), a
 * timer is setup so we can check if the mouse is moved out of our window.
 * (We don't get an event when the mouse leaves, the mouse-move events just
 * stop being delivered to our window and just start being delivered to
 * another window.)  This function is called when the timer triggers so
 * we can check if the mouse has left our window.  If so, we un-highlight
 * the hot-tracked tab.
 */
static void CALLBACK
TAB_HotTrackTimerProc
  (
  HWND hwnd,    /* handle of window for timer messages */
  UINT uMsg,    /* WM_TIMER message */
  UINT_PTR idEvent, /* timer identifier */
  DWORD dwTime  /* current system time */
  )
{
  TAB_INFO* infoPtr = TAB_GetInfoPtr(hwnd);

  if (infoPtr != NULL && infoPtr->iHotTracked >= 0)
  {
    POINT pt;

    /*
    ** If we can't get the cursor position, or if the cursor is outside our
    ** window, we un-highlight the hot-tracked tab.  Note that the cursor is
    ** "outside" even if it is within our bounding rect if another window
    ** overlaps.  Note also that the case where the cursor stayed within our
    ** window but has moved off the hot-tracked tab will be handled by the
    ** WM_MOUSEMOVE event.
    */
    if (!GetCursorPos(&pt) || WindowFromPoint(pt) != hwnd)
    {
      /* Redraw iHotTracked to look normal */
      INT iRedraw = infoPtr->iHotTracked;
      infoPtr->iHotTracked = -1;
      hottrack_refresh (infoPtr, iRedraw);

      /* Kill this timer */
      KillTimer(hwnd, TAB_HOTTRACK_TIMER);
    }
  }
}

/******************************************************************************
 * TAB_RecalcHotTrack
 *
 * If a tab control has the TCS_HOTTRACK style, then the tab under the mouse
 * should be highlighted.  This function determines which tab in a tab control,
 * if any, is under the mouse and records that information.  The caller may
 * supply output parameters to receive the item number of the tab item which
 * was highlighted but isn't any longer and of the tab item which is now
 * highlighted but wasn't previously.  The caller can use this information to
 * selectively redraw those tab items.
 *
 * If the caller has a mouse position, it can supply it through the pos
 * parameter.  For example, TAB_MouseMove does this.  Otherwise, the caller
 * supplies NULL and this function determines the current mouse position
 * itself.
 */
static void
TAB_RecalcHotTrack
  (
  TAB_INFO*       infoPtr,
  const LPARAM*   pos,
  int*            out_redrawLeave,
  int*            out_redrawEnter
  )
{
  int item = -1;


  if (out_redrawLeave != NULL)
    *out_redrawLeave = -1;
  if (out_redrawEnter != NULL)
    *out_redrawEnter = -1;

  if ((infoPtr->dwStyle & TCS_HOTTRACK) || GetWindowTheme(infoPtr->hwnd))
  {
    POINT pt;
    UINT  flags;

    if (pos == NULL)
    {
      GetCursorPos(&pt);
      ScreenToClient(infoPtr->hwnd, &pt);
    }
    else
    {
      pt.x = (short)LOWORD(*pos);
      pt.y = (short)HIWORD(*pos);
    }

    item = TAB_InternalHitTest(infoPtr, pt, &flags);
  }

  if (item != infoPtr->iHotTracked)
  {
    if (infoPtr->iHotTracked >= 0)
    {
      /* Mark currently hot-tracked to be redrawn to look normal */
      if (out_redrawLeave != NULL)
        *out_redrawLeave = infoPtr->iHotTracked;

      if (item < 0)
      {
        /* Kill timer which forces recheck of mouse pos */
        KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);
      }
    }
    else
    {
      /* Start timer so we recheck mouse pos */
      UINT timerID = SetTimer
        (
        infoPtr->hwnd,
        TAB_HOTTRACK_TIMER,
        TAB_HOTTRACK_TIMER_INTERVAL,
        TAB_HotTrackTimerProc
        );

      if (timerID == 0)
        return; /* Hot tracking not available */
    }

    infoPtr->iHotTracked = item;

    if (item >= 0)
    {
	/* Mark new hot-tracked to be redrawn to look highlighted */
      if (out_redrawEnter != NULL)
        *out_redrawEnter = item;
    }
  }
}

/******************************************************************************
 * TAB_MouseMove
 *
 * Handles the mouse-move event.  Updates tooltips.  Updates hot-tracking.
 */
static LRESULT
TAB_MouseMove (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
  int redrawLeave;
  int redrawEnter;

  if (infoPtr->hwndToolTip)
    TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
		    WM_LBUTTONDOWN, wParam, lParam);

  /* Determine which tab to highlight.  Redraw tabs which change highlight
  ** status. */
  TAB_RecalcHotTrack(infoPtr, &lParam, &redrawLeave, &redrawEnter);

  hottrack_refresh (infoPtr, redrawLeave);
  hottrack_refresh (infoPtr, redrawEnter);

  return 0;
}

/******************************************************************************
 * TAB_AdjustRect
 *
 * Calculates the tab control's display area given the window rectangle or
 * the window rectangle given the requested display rectangle.
 */
static LRESULT TAB_AdjustRect(const TAB_INFO *infoPtr, WPARAM fLarger, LPRECT prc)
{
    LONG *iRightBottom, *iLeftTop;

    TRACE ("hwnd=%p fLarger=%ld (%s)\n", infoPtr->hwnd, fLarger,
           wine_dbgstr_rect(prc));

    if (!prc) return -1;

    if(infoPtr->dwStyle & TCS_VERTICAL)
    {
	iRightBottom = &(prc->right);
	iLeftTop     = &(prc->left);
    }
    else
    {
	iRightBottom = &(prc->bottom);
	iLeftTop     = &(prc->top);
    }

    if (fLarger) /* Go from display rectangle */
    {
        /* Add the height of the tabs. */
	if (infoPtr->dwStyle & TCS_BOTTOM)
	    *iRightBottom += infoPtr->tabHeight * infoPtr->uNumRows;
	else
	    *iLeftTop -= infoPtr->tabHeight * infoPtr->uNumRows +
			 ((infoPtr->dwStyle & TCS_BUTTONS)? 3 * (infoPtr->uNumRows - 1) : 0);

	/* Inflate the rectangle for the padding */
	InflateRect(prc, DISPLAY_AREA_PADDINGX, DISPLAY_AREA_PADDINGY); 

	/* Inflate for the border */
	InflateRect(prc, CONTROL_BORDER_SIZEX, CONTROL_BORDER_SIZEY);
    }
    else /* Go from window rectangle. */
    {
	/* Deflate the rectangle for the border */
	InflateRect(prc, -CONTROL_BORDER_SIZEX, -CONTROL_BORDER_SIZEY);

	/* Deflate the rectangle for the padding */
	InflateRect(prc, -DISPLAY_AREA_PADDINGX, -DISPLAY_AREA_PADDINGY);

	/* Remove the height of the tabs. */
	if (infoPtr->dwStyle & TCS_BOTTOM)
	    *iRightBottom -= infoPtr->tabHeight * infoPtr->uNumRows;
	else
	    *iLeftTop += (infoPtr->tabHeight) * infoPtr->uNumRows +
			 ((infoPtr->dwStyle & TCS_BUTTONS)? 3 * (infoPtr->uNumRows - 1) : 0);
    }

  return 0;
}

/******************************************************************************
 * TAB_OnHScroll
 *
 * This method will handle the notification from the scroll control and
 * perform the scrolling operation on the tab control.
 */
static LRESULT TAB_OnHScroll(TAB_INFO *infoPtr, int nScrollCode, int nPos)
{
  if(nScrollCode == SB_THUMBPOSITION && nPos != infoPtr->leftmostVisible)
  {
     if(nPos < infoPtr->leftmostVisible)
        infoPtr->leftmostVisible--;
     else
        infoPtr->leftmostVisible++;

     TAB_RecalcHotTrack(infoPtr, NULL, NULL, NULL);
     TAB_InvalidateTabArea(infoPtr);
     SendMessageW(infoPtr->hwndUpDown, UDM_SETPOS, 0,
                   MAKELONG(infoPtr->leftmostVisible, 0));
   }

   return 0;
}

/******************************************************************************
 * TAB_SetupScrolling
 *
 * This method will check the current scrolling state and make sure the
 * scrolling control is displayed (or not).
 */
static void TAB_SetupScrolling(
  TAB_INFO*   infoPtr,
  const RECT* clientRect)
{
  static const WCHAR emptyW[] = { 0 };
  INT maxRange = 0;

  if (infoPtr->needsScrolling)
  {
    RECT controlPos;
    INT vsize, tabwidth;

    /*
     * Calculate the position of the scroll control.
     */
    controlPos.right = clientRect->right;
    controlPos.left  = controlPos.right - 2 * GetSystemMetrics(SM_CXHSCROLL);

    if (infoPtr->dwStyle & TCS_BOTTOM)
    {
      controlPos.top    = clientRect->bottom - infoPtr->tabHeight;
      controlPos.bottom = controlPos.top + GetSystemMetrics(SM_CYHSCROLL);
    }
    else
    {
      controlPos.bottom = clientRect->top + infoPtr->tabHeight;
      controlPos.top    = controlPos.bottom - GetSystemMetrics(SM_CYHSCROLL);
    }

    /*
     * If we don't have a scroll control yet, we want to create one.
     * If we have one, we want to make sure it's positioned properly.
     */
    if (infoPtr->hwndUpDown==0)
    {
      infoPtr->hwndUpDown = CreateWindowW(UPDOWN_CLASSW, emptyW,
					  WS_VISIBLE | WS_CHILD | UDS_HORZ,
					  controlPos.left, controlPos.top,
					  controlPos.right - controlPos.left,
					  controlPos.bottom - controlPos.top,
					  infoPtr->hwnd, NULL, NULL, NULL);
    }
    else
    {
      SetWindowPos(infoPtr->hwndUpDown,
		   NULL,
		   controlPos.left, controlPos.top,
		   controlPos.right - controlPos.left,
		   controlPos.bottom - controlPos.top,
		   SWP_SHOWWINDOW | SWP_NOZORDER);
    }

    /* Now calculate upper limit of the updown control range.
     * We do this by calculating how many tabs will be offscreen when the
     * last tab is visible.
     */
    if(infoPtr->uNumItem)
    {
       vsize = clientRect->right - (controlPos.right - controlPos.left + 1);
       maxRange = infoPtr->uNumItem;
       tabwidth = TAB_GetItem(infoPtr, infoPtr->uNumItem - 1)->rect.right;

       for(; maxRange > 0; maxRange--)
       {
          if(tabwidth - TAB_GetItem(infoPtr,maxRange - 1)->rect.left > vsize)
             break;
       }

       if(maxRange == infoPtr->uNumItem)
          maxRange--;
    }
  }
  else
  {
    /* If we once had a scroll control... hide it */
    if (infoPtr->hwndUpDown)
      ShowWindow(infoPtr->hwndUpDown, SW_HIDE);
  }
  if (infoPtr->hwndUpDown)
     SendMessageW(infoPtr->hwndUpDown, UDM_SETRANGE32, 0, maxRange);
}

/******************************************************************************
 * TAB_SetItemBounds
 *
 * This method will calculate the position rectangles of all the items in the
 * control. The rectangle calculated starts at 0 for the first item in the
 * list and ignores scrolling and selection.
 * It also uses the current font to determine the height of the tab row and
 * it checks if all the tabs fit in the client area of the window. If they
 * don't, a scrolling control is added.
 */
static void TAB_SetItemBounds (TAB_INFO *infoPtr)
{
  TEXTMETRICW fontMetrics;
  UINT        curItem;
  INT         curItemLeftPos;
  INT         curItemRowCount;
  HFONT       hFont, hOldFont;
  HDC         hdc;
  RECT        clientRect;
  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
   * a font.
   */
  hdc = GetDC(infoPtr->hwnd);

  hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
  hOldFont = SelectObject (hdc, hFont);

  /*
   * We will base the rectangle calculations on the client rectangle
   * of the control.
   */
  GetClientRect(infoPtr->hwnd, &clientRect);

  /* if TCS_VERTICAL then swap the height and width so this code places the
     tabs along the top of the rectangle and we can just rotate them after
     rather than duplicate all of the below code */
  if(infoPtr->dwStyle & TCS_VERTICAL)
  {
     iTemp = clientRect.bottom;
     clientRect.bottom = clientRect.right;
     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;

  if (!(infoPtr->fHeightSet))
  {
    int item_height;
    INT icon_height = 0, cx;

    /* Use the current font to determine the height of a tab. */
    GetTextMetricsW(hdc, &fontMetrics);

    /* Get the icon height */
    if (infoPtr->himl)
      ImageList_GetIconSize(infoPtr->himl, &cx, &icon_height);

    /* Take the highest between font or icon */
    if (fontMetrics.tmHeight > icon_height)
      item_height = fontMetrics.tmHeight + 2;
    else
      item_height = icon_height;

    /*
     * Make sure there is enough space for the letters + icon + growing the
     * selected item + extra space for the selected item.
     */
    infoPtr->tabHeight = item_height + 
	                 ((infoPtr->dwStyle & TCS_BUTTONS) ? 2 : 1) *
                          infoPtr->uVItemPadding;

    TRACE("tabH=%d, tmH=%d, iconh=%d\n",
	  infoPtr->tabHeight, fontMetrics.tmHeight, icon_height);
  }

  TRACE("client right=%d\n", clientRect.right);

  /* Get the icon width */
  if (infoPtr->himl)
  {
    INT cy;

    ImageList_GetIconSize(infoPtr->himl, &icon_width, &cy);

    if (infoPtr->dwStyle & TCS_FIXEDWIDTH)
      icon_width += 4;
    else
      /* Add padding if icon is present */
      icon_width += infoPtr->uHItemPadding;
  }

  for (curItem = 0; curItem < infoPtr->uNumItem; curItem++)
  {
    TAB_ITEM *curr = TAB_GetItem(infoPtr, curItem);
	
    /* Set the leftmost position of the tab. */
    curr->rect.left = curItemLeftPos;

    if (infoPtr->dwStyle & TCS_FIXEDWIDTH)
    {
      curr->rect.right = curr->rect.left +
        max(infoPtr->tabWidth, icon_width);
    }
    else if (!curr->pszText)
    {
      /* If no text use minimum tab width including padding. */
      if (infoPtr->tabMinWidth < 0)
        curr->rect.right = curr->rect.left + GET_DEFAULT_MIN_TAB_WIDTH(infoPtr);
      else
      {
        curr->rect.right = curr->rect.left + infoPtr->tabMinWidth;

        /* Add extra padding if icon is present */
        if (infoPtr->himl && infoPtr->tabMinWidth > 0 && infoPtr->tabMinWidth < DEFAULT_MIN_TAB_WIDTH
            && infoPtr->uHItemPadding > 1)
          curr->rect.right += EXTRA_ICON_PADDING * (infoPtr->uHItemPadding-1);
      }
    }
    else
    {
      int tabwidth;
      SIZE size;
      /* Calculate how wide the tab is depending on the text it contains */
      GetTextExtentPoint32W(hdc, curr->pszText,
                            lstrlenW(curr->pszText), &size);

      tabwidth = size.cx + icon_width + 2 * infoPtr->uHItemPadding;

      if (infoPtr->tabMinWidth < 0)
        tabwidth = max(tabwidth, GET_DEFAULT_MIN_TAB_WIDTH(infoPtr));
      else
        tabwidth = max(tabwidth, infoPtr->tabMinWidth);

      curr->rect.right = curr->rect.left + tabwidth;
      TRACE("for <%s>, l,r=%d,%d\n",
	  debugstr_w(curr->pszText), curr->rect.left, curr->rect.right);
    }

    /*
     * Check if this is a multiline tab control and if so
     * check to see if we should wrap the tabs
     *
     * Wrap all these tabs. We will arrange them evenly later.
     *
     */

    if (((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL)) &&
        (curr->rect.right > 
	(clientRect.right - CONTROL_BORDER_SIZEX - DISPLAY_AREA_PADDINGX)))
    {
        curr->rect.right -= curr->rect.left;

	curr->rect.left = 0;
        curItemRowCount++;
	TRACE("wrapping <%s>, l,r=%d,%d\n", debugstr_w(curr->pszText),
	    curr->rect.left, curr->rect.right);
    }

    curr->rect.bottom = 0;
    curr->rect.top = curItemRowCount - 1;

    TRACE("Rect: %s\n", wine_dbgstr_rect(&curr->rect));

    /*
     * The leftmost position of the next item is the rightmost position
     * of this one.
     */
    if (infoPtr->dwStyle & TCS_BUTTONS)
    {
      curItemLeftPos = curr->rect.right + BUTTON_SPACINGX;
      if (infoPtr->dwStyle & TCS_FLATBUTTONS)
        curItemLeftPos += FLAT_BTN_SPACINGX;
    }
    else
      curItemLeftPos = curr->rect.right;
  }

  if (!((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL)))
  {
    /*
     * Check if we need a scrolling control.
     */
    infoPtr->needsScrolling = (curItemLeftPos + (2 * SELECTED_TAB_OFFSET) >
                               clientRect.right);

    /* Don't need scrolling, then update infoPtr->leftmostVisible */
    if(!infoPtr->needsScrolling)
      infoPtr->leftmostVisible = 0;
  }
  else
  {
    /*
     * No scrolling in Multiline or Vertical styles.
     */
    infoPtr->needsScrolling = FALSE;
    infoPtr->leftmostVisible = 0;
  }
  TAB_SetupScrolling(infoPtr, &clientRect);

  /* Set the number of rows */
  infoPtr->uNumRows = curItemRowCount;

  /* Arrange all tabs evenly if style says so */
   if (!(infoPtr->dwStyle & TCS_RAGGEDRIGHT) &&
       ((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL)) &&
       (infoPtr->uNumItem > 0) &&
       (infoPtr->uNumRows > 1))
   {
      INT tabPerRow,remTab,iRow;
      UINT iItm;
      INT iCount=0;

      /*
       * Ok windows tries to even out the rows. place the same
       * number of tabs in each row. So lets give that a shot
       */

      tabPerRow = infoPtr->uNumItem / (infoPtr->uNumRows);
      remTab = infoPtr->uNumItem % (infoPtr->uNumRows);

      for (iItm=0,iRow=0,iCount=0,curItemLeftPos=0;
           iItm<infoPtr->uNumItem;
           iItm++,iCount++)
      {
          /* normalize the current rect */
          TAB_ITEM *curr = TAB_GetItem(infoPtr, iItm);
 
          /* shift the item to the left side of the clientRect */
          curr->rect.right -= curr->rect.left;
          curr->rect.left = 0;

          TRACE("r=%d, cl=%d, cl.r=%d, iCount=%d, iRow=%d, uNumRows=%d, remTab=%d, tabPerRow=%d\n",
	      curr->rect.right, curItemLeftPos, clientRect.right,
	      iCount, iRow, infoPtr->uNumRows, remTab, tabPerRow);

          /* if we have reached the maximum number of tabs on this row */
          /* move to the next row, reset our current item left position and */
          /* the count of items on this row */

	  if (infoPtr->dwStyle & TCS_VERTICAL) {
	      /* Vert: Add the remaining tabs in the *last* remainder rows */
	      if (iCount >= ((iRow>=(INT)infoPtr->uNumRows - remTab)?tabPerRow + 1:tabPerRow)) {
		  iRow++;
		  curItemLeftPos = 0;
		  iCount = 0;
	      }
	  } else {
	      /* Horz: Add the remaining tabs in the *first* remainder rows */
	      if (iCount >= ((iRow<remTab)?tabPerRow + 1:tabPerRow)) {
		  iRow++;
		  curItemLeftPos = 0;
		  iCount = 0;
	      }
	  }

          /* shift the item to the right to place it as the next item in this row */
          curr->rect.left += curItemLeftPos;
          curr->rect.right += curItemLeftPos;
          curr->rect.top = iRow;
          if (infoPtr->dwStyle & TCS_BUTTONS)
	  {
            curItemLeftPos = curr->rect.right + 1;
            if (infoPtr->dwStyle & TCS_FLATBUTTONS)
	      curItemLeftPos += FLAT_BTN_SPACINGX;
	  }
          else
            curItemLeftPos = curr->rect.right;

          TRACE("arranging <%s>, l,r=%d,%d, row=%d\n",
	      debugstr_w(curr->pszText), curr->rect.left,
	      curr->rect.right, curr->rect.top);
      }

      /*
       * Justify the rows
       */
      {
	INT widthDiff, iIndexStart=0, iIndexEnd=0;
	INT remainder;
	INT iCount=0;

        while(iIndexStart < infoPtr->uNumItem)
        {
          TAB_ITEM *start = TAB_GetItem(infoPtr, iIndexStart);

          /*
           * find the index of the row
           */
          /* find the first item on the next row */
          for (iIndexEnd=iIndexStart;
              (iIndexEnd < infoPtr->uNumItem) &&
 	      (TAB_GetItem(infoPtr, iIndexEnd)->rect.top ==
                start->rect.top) ;
              iIndexEnd++)
          /* intentionally blank */;

          /*
           * we need to justify these tabs so they fill the whole given
           * client area
           *
           */
          /* find the amount of space remaining on this row */
          widthDiff = clientRect.right - (2 * SELECTED_TAB_OFFSET) -
			TAB_GetItem(infoPtr, iIndexEnd - 1)->rect.right;

	  /* iCount is the number of tab items on this row */
	  iCount = iIndexEnd - iIndexStart;

	  if (iCount > 1)
	  {
	    remainder = widthDiff % iCount;
	    widthDiff = widthDiff / iCount;
	    /* add widthDiff/iCount, or extra space/items on row, to each item on this row */
	    for (iIndex=iIndexStart, iCount=0; iIndex < iIndexEnd; iIndex++, iCount++)
	    {
              TAB_ITEM *item = TAB_GetItem(infoPtr, iIndex);

	      item->rect.left += iCount * widthDiff;
	      item->rect.right += (iCount + 1) * widthDiff;

              TRACE("adjusting 1 <%s>, l,r=%d,%d\n",
		  debugstr_w(item->pszText),
		  item->rect.left, item->rect.right);

	    }
	    TAB_GetItem(infoPtr, iIndex - 1)->rect.right += remainder;
	  }
	  else /* we have only one item on this row, make it take up the entire row */
	  {
	    start->rect.left = clientRect.left;
	    start->rect.right = clientRect.right - 4;

            TRACE("adjusting 2 <%s>, l,r=%d,%d\n",
		debugstr_w(start->pszText),
		start->rect.left, start->rect.right);

	  }


	  iIndexStart = iIndexEnd;
	}
      }
  }

  /* if TCS_VERTICAL rotate the tabs so they are along the side of the clientRect */
  if(infoPtr->dwStyle & TCS_VERTICAL)
  {
    RECT rcOriginal;
    for(iIndex = 0; iIndex < infoPtr->uNumItem; iIndex++)
    {
      rcItem = &TAB_GetItem(infoPtr, iIndex)->rect;

      rcOriginal = *rcItem;

      /* this is rotating the items by 90 degrees clockwise around the center of the control */
      rcItem->top = (rcOriginal.left - clientRect.left);
      rcItem->bottom = rcItem->top + (rcOriginal.right - rcOriginal.left);
      rcItem->left = rcOriginal.top;
      rcItem->right = rcOriginal.bottom;
    }
  }

  TAB_EnsureSelectionVisible(infoPtr);
  TAB_RecalcHotTrack(infoPtr, NULL, NULL, NULL);

  /* Cleanup */
  SelectObject (hdc, hOldFont);
  ReleaseDC (infoPtr->hwnd, hdc);
}


static void
TAB_EraseTabInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, const RECT *drawRect)
{
    HBRUSH   hbr = CreateSolidBrush (comctl32_color.clrBtnFace);
    BOOL     deleteBrush = TRUE;
    RECT     rTemp = *drawRect;

    if (infoPtr->dwStyle & TCS_BUTTONS)
    {
	if (iItem == infoPtr->iSelected)
	{
	    /* Background color */
	    if (!(infoPtr->dwStyle & 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 (infoPtr->dwStyle & TCS_FLATBUTTONS)
	    {
		InflateRect(&rTemp, 2, 2);
		FillRect(hdc, &rTemp, hbr);
		if (iItem == infoPtr->iHotTracked ||
                   (iItem != infoPtr->iSelected && iItem == infoPtr->uFocus))
		    DrawEdge(hdc, &rTemp, BDR_RAISEDINNER, BF_RECT);
	    }
	    else
		FillRect(hdc, &rTemp, hbr);
	}

    }
    else /* !TCS_BUTTONS */
    {
        InflateRect(&rTemp, -2, -2);
        if (!GetWindowTheme (infoPtr->hwnd))
	    FillRect(hdc, &rTemp, hbr);
    }

    /* highlighting is drawn on top of previous fills */
    if (TAB_GetItem(infoPtr, iItem)->dwState & TCIS_HIGHLIGHTED)
    {
        if (deleteBrush)
        {
            DeleteObject(hbr);
            deleteBrush = FALSE;
        }
        hbr = GetSysColorBrush(COLOR_HIGHLIGHT);
        FillRect(hdc, &rTemp, hbr);
    }

    /* Cleanup */
    if (deleteBrush) DeleteObject(hbr);
}

/******************************************************************************
 * TAB_DrawItemInterior
 *
 * This method is used to draw the interior (text and icon) of a single tab
 * into the tab control.
 */
static void
TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect)
{
  RECT localRect;

  HPEN   htextPen;
  HPEN   holdPen;
  INT    oldBkMode;
  HFONT  hOldFont;
  
/*  if (drawRect == NULL) */
  {
    BOOL isVisible;
    RECT itemRect;
    RECT selectedRect;

    /*
     * Get the rectangle for the item.
     */
    isVisible = TAB_InternalGetItemRect(infoPtr, iItem, &itemRect, &selectedRect);
    if (!isVisible)
      return;

    /*
     * Make sure drawRect points to something valid; simplifies code.
     */
    drawRect = &localRect;

    /*
     * This logic copied from the part of TAB_DrawItem which draws
     * the tab background.  It's important to keep it in sync.  I
     * would have liked to avoid code duplication, but couldn't figure
     * out how without making spaghetti of TAB_DrawItem.
     */
    if (iItem == infoPtr->iSelected)
      *drawRect = selectedRect;
    else
      *drawRect = itemRect;
        
    if (infoPtr->dwStyle & TCS_BUTTONS)
    {
      if (iItem == infoPtr->iSelected)
      {
	drawRect->left   += 4;
	drawRect->top    += 4;
	drawRect->right  -= 4;

	if (infoPtr->dwStyle & TCS_VERTICAL)
	{
	  if (!(infoPtr->dwStyle & TCS_BOTTOM)) drawRect->right  += 1;
	  drawRect->bottom   -= 4;
	}
	else
	{
	  if (infoPtr->dwStyle & TCS_BOTTOM)
	  {
	    drawRect->top    -= 2;
	    drawRect->bottom -= 4;
	  }
	  else
	    drawRect->bottom -= 1;
	}
      }
      else
      {
	drawRect->left   += 2;
	drawRect->top    += 2;
	drawRect->right  -= 2;
	drawRect->bottom -= 2;
      }
    }
    else
    {
      if ((infoPtr->dwStyle & TCS_VERTICAL) && (infoPtr->dwStyle & TCS_BOTTOM))
      {
        if (iItem != infoPtr->iSelected)
	{
	  drawRect->left   += 2;
	  drawRect->top    += 2;
	  drawRect->bottom -= 2;
	}
      }
      else if (infoPtr->dwStyle & TCS_VERTICAL)
      {
        if (iItem == infoPtr->iSelected)
	{
	  drawRect->right  += 1;
	}
	else
	{
	  drawRect->top    += 2;
	  drawRect->right  -= 2;
	  drawRect->bottom -= 2;
	}
      }
      else if (infoPtr->dwStyle & TCS_BOTTOM)
      {
        if (iItem == infoPtr->iSelected)
	{
	  drawRect->top    -= 2;
	}
	else
	{
	  InflateRect(drawRect, -2, -2);
          drawRect->bottom += 2;
	}
      }
      else
      {
        if (iItem == infoPtr->iSelected)
	{
	  drawRect->bottom += 3;
	}
	else
	{
	  drawRect->bottom -= 2;
	  InflateRect(drawRect, -2, 0);
	}
      }
    }
  }
  TRACE("drawRect=(%s)\n", wine_dbgstr_rect(drawRect));

  /* Clear interior */
  TAB_EraseTabInterior (infoPtr, hdc, iItem, drawRect);

  /* Draw the focus rectangle */
  if (!(infoPtr->dwStyle & TCS_FOCUSNEVER) &&
      (GetFocus() == infoPtr->hwnd) &&
      (iItem == infoPtr->uFocus) )
  {
    RECT rFocus = *drawRect;

    if (!(infoPtr->dwStyle & TCS_BUTTONS)) InflateRect(&rFocus, -3, -3);
    if (infoPtr->dwStyle & TCS_BOTTOM && !(infoPtr->dwStyle & TCS_VERTICAL))
      rFocus.top -= 3;

    /* focus should stay on selected item for TCS_BUTTONS style */
    if (!((infoPtr->dwStyle & TCS_BUTTONS) && (infoPtr->iSelected != iItem)))
      DrawFocusRect(hdc, &rFocus);
  }

  /*
   * Text pen
   */
  htextPen = CreatePen( PS_SOLID, 1, comctl32_color.clrBtnText );
  holdPen  = SelectObject(hdc, htextPen);
  hOldFont = SelectObject(hdc, infoPtr->hFont);

  /*
   * Setup for text output
  */
  oldBkMode = SetBkMode(hdc, TRANSPARENT);
  if (!GetWindowTheme (infoPtr->hwnd) || (infoPtr->dwStyle & TCS_BUTTONS))
  {
    if ((infoPtr->dwStyle & TCS_HOTTRACK) && (iItem == infoPtr->iHotTracked) &&
        !(infoPtr->dwStyle & TCS_FLATBUTTONS))
      SetTextColor(hdc, comctl32_color.clrHighlight);
    else if (TAB_GetItem(infoPtr, iItem)->dwState & TCIS_HIGHLIGHTED)
      SetTextColor(hdc, comctl32_color.clrHighlightText);
    else
      SetTextColor(hdc, comctl32_color.clrBtnText);
  }

  /*
   * if owner draw, tell the owner to draw
   */
  if ((infoPtr->dwStyle & TCS_OWNERDRAWFIXED) && IsWindow(infoPtr->hwndNotify))
  {
    DRAWITEMSTRUCT dis;
    UINT id;

    drawRect->top += 2;
    drawRect->right -= 1;
    if ( iItem == infoPtr->iSelected )
    {
        drawRect->right -= 1;
        drawRect->left += 1;
    }

    id = (UINT)GetWindowLongPtrW( infoPtr->hwnd, GWLP_ID );

    /* fill DRAWITEMSTRUCT */
    dis.CtlType    = ODT_TAB;
    dis.CtlID      = id;
    dis.itemID     = iItem;
    dis.itemAction = ODA_DRAWENTIRE;
    dis.itemState = 0;
    if ( iItem == infoPtr->iSelected )
      dis.itemState |= ODS_SELECTED;
    if (infoPtr->uFocus == iItem) 
      dis.itemState |= ODS_FOCUS;
    dis.hwndItem = infoPtr->hwnd;
    dis.hDC      = hdc;
    CopyRect(&dis.rcItem,drawRect);

    /* when extra data fits ULONG_PTR, store it directly */
    if (infoPtr->cbInfo > sizeof(LPARAM))
        dis.itemData =  (ULONG_PTR) TAB_GetItem(infoPtr, iItem)->extra;
    else
    {
        /* this could be considered broken on 64 bit, but that's how it works -
           only first 4 bytes are copied */
        dis.itemData = 0;
        memcpy(&dis.itemData, (ULONG_PTR*)TAB_GetItem(infoPtr, iItem)->extra, 4);
    }

    /* draw notification */
    SendMessageW( infoPtr->hwndNotify, WM_DRAWITEM, id, (LPARAM)&dis );
  }
  else
  {
    TAB_ITEM *item = TAB_GetItem(infoPtr, iItem);
    RECT rcTemp;
    RECT rcImage;

    /* used to center the icon and text in the tab */
    RECT rcText;
    INT center_offset_h, center_offset_v;

    /* set rcImage to drawRect, we will use top & left in our ImageList_Draw call */
    rcImage = *drawRect;

    rcTemp = *drawRect;

    rcText.left = rcText.top = rcText.right = rcText.bottom = 0;

    /* get the rectangle that the text fits in */
    if (item->pszText)
    {
      DrawTextW(hdc, item->pszText, -1, &rcText, DT_CALCRECT);
    }
    /*
     * If not owner draw, then do the drawing ourselves.
     *
     * Draw the icon.
     */
    if (infoPtr->himl && item->iImage != -1)
    {
      INT cx;
      INT cy;
      
      ImageList_GetIconSize(infoPtr->himl, &cx, &cy);

      if(infoPtr->dwStyle & TCS_VERTICAL)
      {
        center_offset_h = ((drawRect->bottom - drawRect->top) - (cy + infoPtr->uHItemPadding + (rcText.right  - rcText.left))) / 2;
        center_offset_v = ((drawRect->right - drawRect->left) - cx) / 2;
      }
      else
      {
        center_offset_h = ((drawRect->right - drawRect->left) - (cx + infoPtr->uHItemPadding + (rcText.right  - rcText.left))) / 2;
        center_offset_v = ((drawRect->bottom - drawRect->top) - cy) / 2;
      }

      /* if an item is selected, the icon is shifted up instead of down */
      if (iItem == infoPtr->iSelected)
        center_offset_v -= infoPtr->uVItemPadding / 2;
      else
        center_offset_v += infoPtr->uVItemPadding / 2;

      if (infoPtr->dwStyle & TCS_FIXEDWIDTH && infoPtr->dwStyle & (TCS_FORCELABELLEFT | TCS_FORCEICONLEFT))
	center_offset_h = infoPtr->uHItemPadding;

      if (center_offset_h < 2)
        center_offset_h = 2;
	
      if (center_offset_v < 0)
        center_offset_v = 0;
	
      TRACE("for <%s>, c_o_h=%d, c_o_v=%d, draw=(%s), textlen=%d\n",
	  debugstr_w(item->pszText), center_offset_h, center_offset_v,
          wine_dbgstr_rect(drawRect), (rcText.right-rcText.left));

      if((infoPtr->dwStyle & TCS_VERTICAL) && (infoPtr->dwStyle & TCS_BOTTOM))
      {
        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 += cy + infoPtr->uHItemPadding;
      }
      else if(infoPtr->dwStyle & TCS_VERTICAL)
      {
        rcImage.top  = drawRect->bottom - cy - center_offset_h;
	rcImage.left = drawRect->left + center_offset_v;
        drawRect->bottom -= cy + infoPtr->uHItemPadding;
      }
      else /* normal style, whether TCS_BOTTOM or not */
      {
        rcImage.left = drawRect->left + center_offset_h;
	rcImage.top = drawRect->top + center_offset_v;
        drawRect->left += cx + infoPtr->uHItemPadding;
      }

      TRACE("drawing image=%d, left=%d, top=%d\n",
	    item->iImage, rcImage.left, rcImage.top-1);
      ImageList_Draw
        (
        infoPtr->himl,
        item->iImage,
        hdc,
        rcImage.left,
        rcImage.top,
        ILD_NORMAL
        );
    }

    /* Now position text */
    if (infoPtr->dwStyle & TCS_FIXEDWIDTH && infoPtr->dwStyle & TCS_FORCELABELLEFT)
      center_offset_h = infoPtr->uHItemPadding;
    else
      if(infoPtr->dwStyle & TCS_VERTICAL)
        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;

    if(infoPtr->dwStyle & TCS_VERTICAL)
    {
      if(infoPtr->dwStyle & TCS_BOTTOM)
        drawRect->top+=center_offset_h;
      else
        drawRect->bottom-=center_offset_h;

      center_offset_v = ((drawRect->right - drawRect->left) - (rcText.bottom - rcText.top)) / 2;
    }
    else
    {
      drawRect->left += center_offset_h;
      center_offset_v = ((drawRect->bottom - drawRect->top) - (rcText.bottom - rcText.top)) / 2;
    }

    /* if an item is selected, the text is shifted up instead of down */
    if (iItem == infoPtr->iSelected)
        center_offset_v -= infoPtr->uVItemPadding / 2;
    else
        center_offset_v += infoPtr->uVItemPadding / 2;

    if (center_offset_v < 0)
      center_offset_v = 0;

    if(infoPtr->dwStyle & TCS_VERTICAL)
      drawRect->left += center_offset_v;
    else
      drawRect->top += center_offset_v;

    /* Draw the text */
    if(infoPtr->dwStyle & TCS_VERTICAL) /* if we are vertical rotate the text and each character */
    {
      LOGFONTW logfont;
      HFONT hFont;
      INT nEscapement = 900;
      INT nOrientation = 900;

      if(infoPtr->dwStyle & TCS_BOTTOM)
      {
        nEscapement = -900;
        nOrientation = -900;
      }

      /* to get a font with the escapement and orientation we are looking for, we need to */
      /* call CreateFontIndirect, which requires us to set the values of the logfont we pass in */
      if (!GetObjectW(infoPtr->hFont, sizeof(logfont), &logfont))
        GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(logfont), &logfont);

      logfont.lfEscapement = nEscapement;
      logfont.lfOrientation = nOrientation;
      hFont = CreateFontIndirectW(&logfont);
      SelectObject(hdc, hFont);

      if (item->pszText)
      {
        ExtTextOutW(hdc,
        (infoPtr->dwStyle & TCS_BOTTOM) ? drawRect->right : drawRect->left,
        (!(infoPtr->dwStyle & TCS_BOTTOM)) ? drawRect->bottom : drawRect->top,
        ETO_CLIPPED,
        drawRect,
        item->pszText,
        lstrlenW(item->pszText),
        0);
      }

      DeleteObject(hFont);
    }
    else
    {
      TRACE("for <%s>, c_o_h=%d, c_o_v=%d, draw=(%s), textlen=%d\n",
	  debugstr_w(item->pszText), center_offset_h, center_offset_v,
          wine_dbgstr_rect(drawRect), (rcText.right-rcText.left));
      if (item->pszText)
      {
        DrawTextW
        (
          hdc,
          item->pszText,
          lstrlenW(item->pszText),
          drawRect,
          DT_LEFT | DT_SINGLELINE
        );
      }
    }

    *drawRect = rcTemp; /* restore drawRect */
  }

  /*
  * Cleanup
  */
  SelectObject(hdc, hOldFont);
  SetBkMode(hdc, oldBkMode);
  SelectObject(hdc, holdPen);
  DeleteObject( htextPen );
}

/******************************************************************************
 * TAB_DrawItem
 *
 * This method is used to draw a single tab into the tab control.
 */
static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
{
  RECT      itemRect;
  RECT      selectedRect;
  BOOL      isVisible;
  RECT      r, fillRect, r1;
  INT       clRight = 0;
  INT       clBottom = 0;
  COLORREF  bkgnd, corner;
  HTHEME    theme;

  /*
   * Get the rectangle for the item.
   */
  isVisible = TAB_InternalGetItemRect(infoPtr,
				      iItem,
				      &itemRect,
				      &selectedRect);

  if (isVisible)
  {
    RECT rUD, rC;

    /* Clip UpDown control to not draw over it */
    if (infoPtr->needsScrolling)
    {
      GetWindowRect(infoPtr->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
     * corners when drawing the edge.
     */
    bkgnd = comctl32_color.clrBtnFace;
    corner = comctl32_color.clrBtnFace;

    if (infoPtr->dwStyle & TCS_BUTTONS)
    {
      /* Get item rectangle */
      r = itemRect;

      /* Separators between flat buttons */
      if ((infoPtr->dwStyle & TCS_FLATBUTTONS) && (infoPtr->exStyle & TCS_EX_FLATSEPARATORS))
      {
	r1 = r;
	r1.right += (FLAT_BTN_SPACINGX -2);
	DrawEdge(hdc, &r1, EDGE_ETCHED, BF_RIGHT);
      }

      if (iItem == infoPtr->iSelected)
      {
	DrawEdge(hdc, &r, EDGE_SUNKEN, BF_SOFT|BF_RECT);
	
	OffsetRect(&r, 1, 1);
      }
      else  /* ! selected */
      {
        DWORD state = TAB_GetItem(infoPtr, iItem)->dwState;

        if ((state & TCIS_BUTTONPRESSED) || (iItem == infoPtr->uFocus))
          DrawEdge(hdc, &r, EDGE_SUNKEN, BF_SOFT|BF_RECT);
        else
          if (!(infoPtr->dwStyle & TCS_FLATBUTTONS))
            DrawEdge(hdc, &r, EDGE_RAISED, BF_SOFT|BF_RECT);
      }
    }
    else /* !TCS_BUTTONS */
    {
      /* We draw a rectangle of different sizes depending on the selection
       * state. */
      if (iItem == infoPtr->iSelected) {
	RECT rect;
	GetClientRect (infoPtr->hwnd, &rect);
	clRight = rect.right;
	clBottom = rect.bottom;
        r = selectedRect;
      }
      else
        r = itemRect;

      /*
       * Erase the background. (Delay it but setup rectangle.)
       * This is necessary when drawing the selected item since it is larger
       * than the others, it might overlap with stuff already drawn by the
       * other tabs
       */
      fillRect = r;

      /* Draw themed tabs - but only if they are at the top.
       * Windows draws even side or bottom tabs themed, with wacky results.
       * However, since in Wine apps may get themed that did not opt in via
       * a manifest avoid theming when we know the result will be wrong */
      if ((theme = GetWindowTheme (infoPtr->hwnd)) 
          && ((infoPtr->dwStyle & (TCS_VERTICAL | TCS_BOTTOM)) == 0))
      {
          static const int partIds[8] = {
              /* Normal item */
              TABP_TABITEM,
              TABP_TABITEMLEFTEDGE,
              TABP_TABITEMRIGHTEDGE,
              TABP_TABITEMBOTHEDGE,
              /* Selected tab */
              TABP_TOPTABITEM,
              TABP_TOPTABITEMLEFTEDGE,
              TABP_TOPTABITEMRIGHTEDGE,
              TABP_TOPTABITEMBOTHEDGE,
          };
          int partIndex = 0;
          int stateId = TIS_NORMAL;

          /* selected and unselected tabs have different parts */
          if (iItem == infoPtr->iSelected)
              partIndex += 4;
          /* The part also differs on the position of a tab on a line.
           * "Visually" determining the position works well enough. */
          GetClientRect(infoPtr->hwnd, &r1);
          if(selectedRect.left == 0)
              partIndex += 1;
          if(selectedRect.right == r1.right)
              partIndex += 2;

          if (iItem == infoPtr->iSelected)
              stateId = TIS_SELECTED;
          else if (iItem == infoPtr->iHotTracked)
              stateId = TIS_HOT;
          else if (iItem == infoPtr->uFocus)
              stateId = TIS_FOCUSED;

          /* Adjust rectangle for bottommost row */
          if (TAB_GetItem(infoPtr, iItem)->rect.top == infoPtr->uNumRows-1)
            r.bottom += 3;

          DrawThemeBackground (theme, hdc, partIds[partIndex], stateId, &r, NULL);
          GetThemeBackgroundContentRect (theme, hdc, partIds[partIndex], stateId, &r, &r);
      }
      else if(infoPtr->dwStyle & TCS_VERTICAL)
      {
	/* These are for adjusting the drawing of a Selected tab      */
	/* The initial values are for the normal case of non-Selected */
	int ZZ = 1;   /* Do not stretch if selected */
	if (iItem == infoPtr->iSelected) {
	    ZZ = 0;

	    /* if leftmost draw the line longer */
	    if(selectedRect.top == 0)
		fillRect.top += CONTROL_BORDER_SIZEY;
	    /* if rightmost draw the line longer */
	    if(selectedRect.bottom == clBottom)
		fillRect.bottom -= CONTROL_BORDER_SIZEY;
	}

        if (infoPtr->dwStyle & TCS_BOTTOM)
        {
	  /* Adjust both rectangles to match native */
	  r.left += (1-ZZ);

          TRACE("<right> item=%d, fill=(%s), edge=(%s)\n",
                iItem, wine_dbgstr_rect(&fillRect), wine_dbgstr_rect(&r));

	  /* Clear interior */
	  SetBkColor(hdc, bkgnd);
	  ExtTextOutW(hdc, 0, 0, 2, &fillRect, NULL, 0, 0);

	  /* Draw rectangular edge around tab */
	  DrawEdge(hdc, &r, EDGE_RAISED, BF_SOFT|BF_RIGHT|BF_TOP|BF_BOTTOM);

	  /* Now erase the top corner and draw diagonal edge */
	  SetBkColor(hdc, corner);
	  r1.left = r.right - ROUND_CORNER_SIZE - 1;
	  r1.top = r.top;
	  r1.right = r.right;
	  r1.bottom = r1.top + ROUND_CORNER_SIZE;
	  ExtTextOutW(hdc, 0, 0, 2, &r1, NULL, 0, 0);
	  r1.right--;
	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDTOPLEFT);

	  /* Now erase the bottom corner and draw diagonal edge */
	  r1.left = r.right - ROUND_CORNER_SIZE - 1;
	  r1.bottom = r.bottom;
	  r1.right = r.right;
	  r1.top = r1.bottom - ROUND_CORNER_SIZE;
	  ExtTextOutW(hdc, 0, 0, 2, &r1, NULL, 0, 0);
	  r1.right--;
	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDBOTTOMLEFT);

	  if ((iItem == infoPtr->iSelected) && (selectedRect.top == 0)) {
	      r1 = r;
	      r1.right = r1.left;
	      r1.left--;
	      DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_TOP);
	  }

        }
        else
        {
          TRACE("<left> item=%d, fill=(%s), edge=(%s)\n",
                iItem, wine_dbgstr_rect(&fillRect), wine_dbgstr_rect(&r));

	  /* Clear interior */
	  SetBkColor(hdc, bkgnd);
	  ExtTextOutW(hdc, 0, 0, 2, &fillRect, NULL, 0, 0);

	  /* Draw rectangular edge around tab */
	  DrawEdge(hdc, &r, EDGE_RAISED, BF_SOFT|BF_LEFT|BF_TOP|BF_BOTTOM);

	  /* Now erase the top corner and draw diagonal edge */
	  SetBkColor(hdc, corner);
	  r1.left = r.left;
	  r1.top = r.top;
	  r1.right = r1.left + ROUND_CORNER_SIZE + 1;
	  r1.bottom = r1.top + ROUND_CORNER_SIZE;
	  ExtTextOutW(hdc, 0, 0, 2, &r1, NULL, 0, 0);
	  r1.left++;
	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDTOPRIGHT);

	  /* Now erase the bottom corner and draw diagonal edge */
	  r1.left = r.left;
	  r1.bottom = r.bottom;
	  r1.right = r1.left + ROUND_CORNER_SIZE + 1;
	  r1.top = r1.bottom - ROUND_CORNER_SIZE;
	  ExtTextOutW(hdc, 0, 0, 2, &r1, NULL, 0, 0);
	  r1.left++;
	  DrawEdge(hdc, &r1, EDGE_SUNKEN, BF_DIAGONAL_ENDTOPLEFT);
        }
      }
      else  /* ! TCS_VERTICAL */
      {
	/* These are for adjusting the drawing of a Selected tab      */
	/* The initial values are for the normal case of non-Selected */
	if (iItem == infoPtr->iSelected) {
	    /* if leftmost draw the line longer */
	    if(selectedRect.left == 0)
		fillRect.left += CONTROL_BORDER_SIZEX;
	    /* if rightmost draw the line longer */
	    if(selectedRect.right == clRight)
		fillRect.right -= CONTROL_BORDER_SIZEX;
	}

        if (infoPtr->dwStyle & TCS_BOTTOM)
        {
	  /* Adjust both rectangles for topmost row */
	  if (TAB_GetItem(infoPtr, iItem)->rect.top == infoPtr->uNumRows-1)
	  {
	    fillRect.top -= 2;
	    r.top -= 1;
	  }

          TRACE("<bottom> item=%d, fill=(%s), edge=(%s)\n",
                iItem, wine_dbgstr_rect(&fillRect), wine_dbgstr_rect(&r));

	  /* Clear interior */
	  SetBkColor(hdc, bkgnd);
	  ExtTextOutW(hdc, 0, 0, 2, &fillRect, NULL, 0, 0);

	  /* Draw rectangular edge around tab */
	  DrawEdge(hdc, &r, EDGE_RAISED, BF_SOFT|BF_LEFT|BF_BOTTOM|BF_RIGHT);

	  /* Now erase the righthand corner and draw diagonal edge */
	  SetBkColor(hdc, corner);
	  r1.left = r.right - ROUND_CORNER_SIZE;
	  r1.bottom = r.bottom;
	  r1.right = r.right;
	  r1.top = r1.bottom - ROUND_CORNER_SIZE - 1;
	  ExtTextOutW(hdc, 0, 0, 2, &r1, NULL, 0, 0);
	  r1.bottom--;
	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDBOTTOMLEFT);

	  /* Now erase the lefthand corner and draw diagonal edge */
	  r1.left = r.left;
	  r1.bottom = r.bottom;
	  r1.right = r1.left + ROUND_CORNER_SIZE;
	  r1.top = r1.bottom - ROUND_CORNER_SIZE - 1;
	  ExtTextOutW(hdc, 0, 0, 2, &r1, NULL, 0, 0);
	  r1.bottom--;
	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDTOPLEFT);

	  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);
	    }
	  }

        }
        else
        {
	  /* Adjust both rectangles for bottommost row */
	  if (TAB_GetItem(infoPtr, iItem)->rect.top == infoPtr->uNumRows-1)
	  {
	    fillRect.bottom += 3;
	    r.bottom += 2;
	  }

          TRACE("<top> item=%d, fill=(%s), edge=(%s)\n",
                iItem, wine_dbgstr_rect(&fillRect), wine_dbgstr_rect(&r));

	  /* Clear interior */
	  SetBkColor(hdc, bkgnd);
	  ExtTextOutW(hdc, 0, 0, 2, &fillRect, NULL, 0, 0);

	  /* Draw rectangular edge around tab */
	  DrawEdge(hdc, &r, EDGE_RAISED, BF_SOFT|BF_LEFT|BF_TOP|BF_RIGHT);

	  /* Now erase the righthand corner and draw diagonal edge */
	  SetBkColor(hdc, corner);
	  r1.left = r.right - ROUND_CORNER_SIZE;
	  r1.top = r.top;
	  r1.right = r.right;
	  r1.bottom = r1.top + ROUND_CORNER_SIZE + 1;
	  ExtTextOutW(hdc, 0, 0, 2, &r1, NULL, 0, 0);
	  r1.top++;
	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDBOTTOMRIGHT);

	  /* Now erase the lefthand corner and draw diagonal edge */
	  r1.left = r.left;
	  r1.top = r.top;
	  r1.right = r1.left + ROUND_CORNER_SIZE;
	  r1.bottom = r1.top + ROUND_CORNER_SIZE + 1;
	  ExtTextOutW(hdc, 0, 0, 2, &r1, NULL, 0, 0);
	  r1.top++;
	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDTOPRIGHT);
        }
      }
    }

    TAB_DumpItemInternal(infoPtr, iItem);

    /* This modifies r to be the text rectangle. */
    TAB_DrawItemInterior(infoPtr, hdc, iItem, &r);
  }
}

/******************************************************************************
 * TAB_DrawBorder
 *
 * This method is used to draw the raised border around the tab control
 * "content" area.
 */
static void TAB_DrawBorder(const TAB_INFO *infoPtr, HDC hdc)
{
  RECT rect;
  HTHEME theme = GetWindowTheme (infoPtr->hwnd);

  GetClientRect (infoPtr->hwnd, &rect);

  /*
   * Adjust for the style
   */

  if (infoPtr->uNumItem)
  {
    if ((infoPtr->dwStyle & TCS_BOTTOM) && !(infoPtr->dwStyle & TCS_VERTICAL))
      rect.bottom -= infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
    else if((infoPtr->dwStyle & TCS_BOTTOM) && (infoPtr->dwStyle & TCS_VERTICAL))
      rect.right  -= infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
    else if(infoPtr->dwStyle & TCS_VERTICAL)
      rect.left   += infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
    else /* not TCS_VERTICAL and not TCS_BOTTOM */
      rect.top    += infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
  }

  TRACE("border=(%s)\n", wine_dbgstr_rect(&rect));

  if (theme)
      DrawThemeBackground (theme, hdc, TABP_PANE, 0, &rect, NULL);
  else
      DrawEdge(hdc, &rect, EDGE_RAISED, BF_SOFT|BF_RECT);
}

/******************************************************************************
 * TAB_Refresh
 *
 * This method repaints the tab control..
 */
static void TAB_Refresh (const TAB_INFO *infoPtr, HDC hdc)
{
  HFONT hOldFont;
  INT i;

  if (!infoPtr->DoRedraw)
    return;

  hOldFont = SelectObject (hdc, infoPtr->hFont);

  if (infoPtr->dwStyle & TCS_BUTTONS)
  {
    for (i = 0; i < infoPtr->uNumItem; i++)
      TAB_DrawItem (infoPtr, hdc, i);
  }
  else
  {
    /* Draw all the non selected item first */
    for (i = 0; i < infoPtr->uNumItem; i++)
    {
      if (i != infoPtr->iSelected)
	TAB_DrawItem (infoPtr, hdc, i);
    }

    /* Now, draw the border, draw it before the selected item
     * since the selected item overwrites part of the border. */
    TAB_DrawBorder (infoPtr, hdc);

    /* Then, draw the selected item */
    TAB_DrawItem (infoPtr, hdc, infoPtr->iSelected);
  }

  SelectObject (hdc, hOldFont);
}

static inline DWORD TAB_GetRowCount (const TAB_INFO *infoPtr)
{
  TRACE("(%p)\n", infoPtr);
  return infoPtr->uNumRows;
}

static inline LRESULT TAB_SetRedraw (TAB_INFO *infoPtr, BOOL doRedraw)
{
  infoPtr->DoRedraw = doRedraw;
  return 0;
}

/******************************************************************************
 * TAB_EnsureSelectionVisible
 *
 * This method will make sure that the current selection is completely
 * visible by scrolling until it is.
 */
static void TAB_EnsureSelectionVisible(
  TAB_INFO* infoPtr)
{
  INT iSelected = infoPtr->iSelected;
  INT iOrigLeftmostVisible = infoPtr->leftmostVisible;

  if (iSelected < 0)
    return;

  /* set the items row to the bottommost row or topmost row depending on
   * style */
  if ((infoPtr->uNumRows > 1) && !(infoPtr->dwStyle & TCS_BUTTONS))
  {
      TAB_ITEM *selected = TAB_GetItem(infoPtr, iSelected);
      INT newselected;
      INT iTargetRow;

      if(infoPtr->dwStyle & TCS_VERTICAL)
        newselected = selected->rect.left;
      else
        newselected = selected->rect.top;

      /* the target row is always (number of rows - 1)
         as row 0 is furthest from the clientRect */
      iTargetRow = infoPtr->uNumRows - 1;

      if (newselected != iTargetRow)
      {
         UINT i;
         if(infoPtr->dwStyle & TCS_VERTICAL)
         {
           for (i=0; i < infoPtr->uNumItem; i++)
           {
             /* move everything in the row of the selected item to the iTargetRow */
             TAB_ITEM *item = TAB_GetItem(infoPtr, i);

             if (item->rect.left == newselected )
                 item->rect.left = iTargetRow;
             else
             {
               if (item->rect.left > newselected)
                 item->rect.left-=1;
             }
           }
         }
         else
         {
           for (i=0; i < infoPtr->uNumItem; i++)
           {
             TAB_ITEM *item = TAB_GetItem(infoPtr, i);

             if (item->rect.top == newselected )
                 item->rect.top = iTargetRow;
             else
             {
               if (item->rect.top > newselected)
                 item->rect.top-=1;
             }
          }
        }
        TAB_RecalcHotTrack(infoPtr, NULL, NULL, NULL);
      }
  }

  /*
   * Do the trivial cases first.
   */
  if ( (!infoPtr->needsScrolling) ||
       (infoPtr->hwndUpDown==0) || (infoPtr->dwStyle & TCS_VERTICAL))
    return;

  if (infoPtr->leftmostVisible >= iSelected)
  {
    infoPtr->leftmostVisible = iSelected;
  }
  else
  {
     TAB_ITEM *selected = TAB_GetItem(infoPtr, iSelected);
     RECT r;
     INT width;
     UINT i;

     /* Calculate the part of the client area that is visible */
     GetClientRect(infoPtr->hwnd, &r);
     width = r.right;

     GetClientRect(infoPtr->hwndUpDown, &r);
     width -= r.right;

     if ((selected->rect.right -
          selected->rect.left) >= width )
     {
        /* Special case: width of selected item is greater than visible
         * part of control.
         */
        infoPtr->leftmostVisible = iSelected;
     }
     else
     {
        for (i = infoPtr->leftmostVisible; i < infoPtr->uNumItem; i++)
        {
           if ((selected->rect.right - TAB_GetItem(infoPtr, i)->rect.left) < width)
              break;
        }
        infoPtr->leftmostVisible = i;
     }
  }

  if (infoPtr->leftmostVisible != iOrigLeftmostVisible)
    TAB_RecalcHotTrack(infoPtr, NULL, NULL, NULL);

  SendMessageW(infoPtr->hwndUpDown, UDM_SETPOS, 0,
               MAKELONG(infoPtr->leftmostVisible, 0));
}

/******************************************************************************
 * TAB_InvalidateTabArea
 *
 * This method will invalidate the portion of the control that contains the
 * tabs. It is called when the state of the control changes and needs
 * to be redisplayed
 */
static void TAB_InvalidateTabArea(const TAB_INFO *infoPtr)
{
  RECT clientRect, rInvalidate, rAdjClient;
  INT lastRow = infoPtr->uNumRows - 1;
  RECT rect;

  if (lastRow < 0) return;

  GetClientRect(infoPtr->hwnd, &clientRect);
  rInvalidate = clientRect;
  rAdjClient = clientRect;

  TAB_AdjustRect(infoPtr, 0, &rAdjClient);

  TAB_InternalGetItemRect(infoPtr, infoPtr->uNumItem-1 , &rect, NULL);
  if ((infoPtr->dwStyle & TCS_BOTTOM) && (infoPtr->dwStyle & TCS_VERTICAL))
  {
    rInvalidate.left = rAdjClient.right;
    if (infoPtr->uNumRows == 1)
      rInvalidate.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
  }
  else if(infoPtr->dwStyle & TCS_VERTICAL)
  {
    rInvalidate.right = rAdjClient.left;
    if (infoPtr->uNumRows == 1)
      rInvalidate.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
  }
  else if (infoPtr->dwStyle & TCS_BOTTOM)
  {
    rInvalidate.top = rAdjClient.bottom;
    if (infoPtr->uNumRows == 1)
      rInvalidate.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
  }
  else 
  {
    rInvalidate.bottom = rAdjClient.top;
    if (infoPtr->uNumRows == 1)
      rInvalidate.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
  }
  
  /* Punch out the updown control */
  if (infoPtr->needsScrolling && (rInvalidate.right > 0)) {
    RECT r;
    GetClientRect(infoPtr->hwndUpDown, &r);
    if (rInvalidate.right > clientRect.right - r.left)
      rInvalidate.right = rInvalidate.right - (r.right - r.left);
    else
      rInvalidate.right = clientRect.right - r.left;
  }

  TRACE("invalidate (%s)\n", wine_dbgstr_rect(&rInvalidate));

  InvalidateRect(infoPtr->hwnd, &rInvalidate, TRUE);
}

static inline LRESULT TAB_Paint (TAB_INFO *infoPtr, HDC hdcPaint)
{
  HDC hdc;
  PAINTSTRUCT ps;

  if (hdcPaint)
    hdc = hdcPaint;
  else
  {
    hdc = BeginPaint (infoPtr->hwnd, &ps);
    TRACE("erase %d, rect=(%s)\n", ps.fErase, wine_dbgstr_rect(&ps.rcPaint));
  }

  TAB_Refresh (infoPtr, hdc);

  if (!hdcPaint)
    EndPaint (infoPtr->hwnd, &ps);

  return 0;
}

static LRESULT
TAB_InsertItemT (TAB_INFO *infoPtr, INT iItem, const TCITEMW *pti, BOOL bUnicode)
{
  TAB_ITEM *item;
  RECT rect;

  GetClientRect (infoPtr->hwnd, &rect);
  TRACE("Rect: %p %s\n", infoPtr->hwnd, wine_dbgstr_rect(&rect));

  if (iItem < 0) return -1;
  if (iItem > infoPtr->uNumItem)
    iItem = infoPtr->uNumItem;

  TAB_DumpItemExternalT(pti, iItem, bUnicode);

  if (!(item = Alloc(TAB_ITEM_SIZE(infoPtr)))) return FALSE;
  if (DPA_InsertPtr(infoPtr->items, iItem, item) == -1)
  {
      Free(item);
      return FALSE;
  }

  if (infoPtr->uNumItem == 0)
      infoPtr->iSelected = 0;
  else if (iItem <= infoPtr->iSelected)
      infoPtr->iSelected++;

  infoPtr->uNumItem++;

  item->pszText = NULL;
  if (pti->mask & TCIF_TEXT)
  {
    if (bUnicode)
      Str_SetPtrW (&item->pszText, pti->pszText);
    else
      Str_SetPtrAtoW (&item->pszText, (LPSTR)pti->pszText);
  }

  if (pti->mask & TCIF_IMAGE)
    item->iImage = pti->iImage;
  else
    item->iImage = -1;

  if (pti->mask & TCIF_PARAM)
    memcpy(item->extra, &pti->lParam, EXTRA_ITEM_SIZE(infoPtr));
  else
    memset(item->extra, 0, EXTRA_ITEM_SIZE(infoPtr));

  TAB_SetItemBounds(infoPtr);
  if (infoPtr->uNumItem > 1)
    TAB_InvalidateTabArea(infoPtr);
  else
    InvalidateRect(infoPtr->hwnd, NULL, TRUE);

  TRACE("[%p]: added item %d %s\n",
        infoPtr->hwnd, iItem, debugstr_w(item->pszText));

  /* If we haven't set the current focus yet, set it now. */
  if (infoPtr->uFocus == -1)
    TAB_SetCurFocus(infoPtr, iItem);

  return iItem;
}

static LRESULT
TAB_SetItemSize (TAB_INFO *infoPtr, INT cx, INT cy)
{
  LONG lResult = 0;
  BOOL bNeedPaint = FALSE;

  lResult = MAKELONG(infoPtr->tabWidth, infoPtr->tabHeight);

  /* UNDOCUMENTED: If requested Width or Height is 0 this means that program wants to use auto size. */
  if (infoPtr->dwStyle & TCS_FIXEDWIDTH && (infoPtr->tabWidth != cx))
  {
    infoPtr->tabWidth = cx;
    bNeedPaint = TRUE;
  }

  if (infoPtr->tabHeight != cy)
  {
    if ((infoPtr->fHeightSet = (cy != 0)))
      infoPtr->tabHeight = cy;

    bNeedPaint = TRUE;
  }
  TRACE("was h=%d,w=%d, now h=%d,w=%d\n",
       HIWORD(lResult), LOWORD(lResult),
       infoPtr->tabHeight, infoPtr->tabWidth);

  if (bNeedPaint)
  {
    TAB_SetItemBounds(infoPtr);
    RedrawWindow(infoPtr->hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
  }

  return lResult;
}

static inline LRESULT TAB_SetMinTabWidth (TAB_INFO *infoPtr, INT cx)
{
  INT oldcx = 0;

  TRACE("(%p,%d)\n", infoPtr, cx);

  if (infoPtr->tabMinWidth < 0)
    oldcx = DEFAULT_MIN_TAB_WIDTH;
  else
    oldcx = infoPtr->tabMinWidth;
  infoPtr->tabMinWidth = cx;
  TAB_SetItemBounds(infoPtr);
  return oldcx;
}

static inline LRESULT 
TAB_HighlightItem (TAB_INFO *infoPtr, INT iItem, BOOL fHighlight)
{
  LPDWORD lpState;
  DWORD oldState;
  RECT r;

  TRACE("(%p,%d,%s)\n", infoPtr, iItem, fHighlight ? "true" : "false");

  if (iItem < 0 || iItem >= infoPtr->uNumItem)
    return FALSE;

  lpState = &TAB_GetItem(infoPtr, iItem)->dwState;
  oldState = *lpState;

  if (fHighlight)
    *lpState |= TCIS_HIGHLIGHTED;
  else
    *lpState &= ~TCIS_HIGHLIGHTED;

  if ((oldState != *lpState) && TAB_InternalGetItemRect (infoPtr, iItem, &r, NULL))
    InvalidateRect (infoPtr->hwnd, &r, TRUE);

  return TRUE;
}

static LRESULT
TAB_SetItemT (TAB_INFO *infoPtr, INT iItem, LPTCITEMW tabItem, BOOL bUnicode)
{
  TAB_ITEM *wineItem;

  TRACE("(%p,%d,%p,%s)\n", infoPtr, iItem, tabItem, bUnicode ? "true" : "false");

  if (iItem < 0 || iItem >= infoPtr->uNumItem)
    return FALSE;

  TAB_DumpItemExternalT(tabItem, iItem, bUnicode);

  wineItem = TAB_GetItem(infoPtr, iItem);

  if (tabItem->mask & TCIF_IMAGE)
    wineItem->iImage = tabItem->iImage;

  if (tabItem->mask & TCIF_PARAM)
    memcpy(wineItem->extra, &tabItem->lParam, infoPtr->cbInfo);

  if (tabItem->mask & TCIF_RTLREADING)
    FIXME("TCIF_RTLREADING\n");

  if (tabItem->mask & TCIF_STATE)
    wineItem->dwState = (wineItem->dwState & ~tabItem->dwStateMask) |
                        ( tabItem->dwState &  tabItem->dwStateMask);

  if (tabItem->mask & TCIF_TEXT)
  {
    Free(wineItem->pszText);
    wineItem->pszText = NULL;
    if (bUnicode)
      Str_SetPtrW(&wineItem->pszText, tabItem->pszText);
    else
      Str_SetPtrAtoW(&wineItem->pszText, (LPSTR)tabItem->pszText);
  }

  /* Update and repaint tabs */
  TAB_SetItemBounds(infoPtr);
  TAB_InvalidateTabArea(infoPtr);

  return TRUE;
}

static inline LRESULT TAB_GetItemCount (const TAB_INFO *infoPtr)
{
  TRACE("\n");
  return infoPtr->uNumItem;
}


static LRESULT
TAB_GetItemT (TAB_INFO *infoPtr, INT iItem, LPTCITEMW tabItem, BOOL bUnicode)
{
  TAB_ITEM *wineItem;

  TRACE("(%p,%d,%p,%s)\n", infoPtr, iItem, tabItem, bUnicode ? "true" : "false");

  if (!tabItem) return FALSE;

  if (iItem < 0 || iItem >= infoPtr->uNumItem)
  {
    /* init requested fields */
    if (tabItem->mask & TCIF_IMAGE) tabItem->iImage  = 0;
    if (tabItem->mask & TCIF_PARAM) tabItem->lParam  = 0;
    if (tabItem->mask & TCIF_STATE) tabItem->dwState = 0;
    return FALSE;
  }

  wineItem = TAB_GetItem(infoPtr, iItem);

  if (tabItem->mask & TCIF_IMAGE)
    tabItem->iImage = wineItem->iImage;

  if (tabItem->mask & TCIF_PARAM)
    memcpy(&tabItem->lParam, wineItem->extra, infoPtr->cbInfo);

  if (tabItem->mask & TCIF_RTLREADING)
    FIXME("TCIF_RTLREADING\n");

  if (tabItem->mask & TCIF_STATE)
    tabItem->dwState = wineItem->dwState & tabItem->dwStateMask;

  if (tabItem->mask & TCIF_TEXT)
  {
    if (bUnicode)
      Str_GetPtrW (wineItem->pszText, tabItem->pszText, tabItem->cchTextMax);
    else
      Str_GetPtrWtoA (wineItem->pszText, (LPSTR)tabItem->pszText, tabItem->cchTextMax);
  }

  TAB_DumpItemExternalT(tabItem, iItem, bUnicode);

  return TRUE;
}


static LRESULT TAB_DeleteItem (TAB_INFO *infoPtr, INT iItem)
{
    TAB_ITEM *item;

    TRACE("(%p, %d)\n", infoPtr, iItem);

    if (iItem < 0 || iItem >= infoPtr->uNumItem) return FALSE;

    TAB_InvalidateTabArea(infoPtr);
    item = TAB_GetItem(infoPtr, iItem);
    Free(item->pszText);
    Free(item);
    infoPtr->uNumItem--;
    DPA_DeletePtr(infoPtr->items, iItem);

    if (infoPtr->uNumItem == 0)
    {
        if (infoPtr->iHotTracked >= 0)
        {
            KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);
            infoPtr->iHotTracked = -1;
        }

        infoPtr->iSelected = -1;
    }
    else
    {
        if (iItem <= infoPtr->iHotTracked)
        {
            /* When tabs move left/up, the hot track item may change */
            FIXME("Recalc hot track\n");
        }
    }

    /* adjust the selected index */
    if (iItem == infoPtr->iSelected)
        infoPtr->iSelected = -1;
    else if (iItem < infoPtr->iSelected)
        infoPtr->iSelected--;

    /* reposition and repaint tabs */
    TAB_SetItemBounds(infoPtr);

    return TRUE;
}

static inline LRESULT TAB_DeleteAllItems (TAB_INFO *infoPtr)
{
    TRACE("(%p)\n", infoPtr);
    while (infoPtr->uNumItem)
      TAB_DeleteItem (infoPtr, 0);
    return TRUE;
}


static inline LRESULT TAB_GetFont (const TAB_INFO *infoPtr)
{
  TRACE("(%p) returning %p\n", infoPtr, infoPtr->hFont);
  return (LRESULT)infoPtr->hFont;
}

static inline LRESULT TAB_SetFont (TAB_INFO *infoPtr, HFONT hNewFont)
{
  TRACE("(%p,%p)\n", infoPtr, hNewFont);

  infoPtr->hFont = hNewFont;

  TAB_SetItemBounds(infoPtr);

  TAB_InvalidateTabArea(infoPtr);

  return 0;
}


static inline LRESULT TAB_GetImageList (const TAB_INFO *infoPtr)
{
  TRACE("\n");
  return (LRESULT)infoPtr->himl;
}

static inline LRESULT TAB_SetImageList (TAB_INFO *infoPtr, HIMAGELIST himlNew)
{
    HIMAGELIST himlPrev = infoPtr->himl;
    TRACE("himl=%p\n", himlNew);
    infoPtr->himl = himlNew;
    TAB_SetItemBounds(infoPtr);
    InvalidateRect(infoPtr->hwnd, NULL, TRUE);
    return (LRESULT)himlPrev;
}

static inline LRESULT TAB_GetUnicodeFormat (const TAB_INFO *infoPtr)
{
    TRACE("(%p)\n", infoPtr);
    return infoPtr->bUnicode;
}

static inline LRESULT TAB_SetUnicodeFormat (TAB_INFO *infoPtr, BOOL bUnicode)
{
    BOOL bTemp = infoPtr->bUnicode;

    TRACE("(%p %d)\n", infoPtr, bUnicode);
    infoPtr->bUnicode = bUnicode;

    return bTemp;
}

static inline LRESULT TAB_Size (TAB_INFO *infoPtr)
{
/* I'm not really sure what the following code was meant to do.
   This is what it is doing:
   When WM_SIZE is sent with SIZE_RESTORED, the control
   gets positioned in the top left corner.

  RECT parent_rect;
  HWND parent;
  UINT uPosFlags,cx,cy;

  uPosFlags=0;
  if (!wParam) {
    parent = GetParent (hwnd);
    GetClientRect(parent, &parent_rect);
    cx=LOWORD (lParam);
    cy=HIWORD (lParam);
    if (GetWindowLongW(hwnd, GWL_STYLE) & CCS_NORESIZE)
        uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);

    SetWindowPos (hwnd, 0, parent_rect.left, parent_rect.top,
            cx, cy, uPosFlags | SWP_NOZORDER);
  } else {
    FIXME("WM_SIZE flag %x %lx not handled\n", wParam, lParam);
  } */

  /* Recompute the size/position of the tabs. */
  TAB_SetItemBounds (infoPtr);

  /* Force a repaint of the control. */
  InvalidateRect(infoPtr->hwnd, NULL, TRUE);

  return 0;
}


static LRESULT TAB_Create (HWND hwnd, LPARAM lParam)
{
  TAB_INFO *infoPtr;
  TEXTMETRICW fontMetrics;
  HDC hdc;
  HFONT hOldFont;
  DWORD style;

  infoPtr = Alloc (sizeof(TAB_INFO));

  SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);

  infoPtr->hwnd            = hwnd;
  infoPtr->hwndNotify      = ((LPCREATESTRUCTW)lParam)->hwndParent;
  infoPtr->uNumItem        = 0;
  infoPtr->uNumRows        = 0;
  infoPtr->uHItemPadding   = 6;
  infoPtr->uVItemPadding   = 3;
  infoPtr->uHItemPadding_s = 6;
  infoPtr->uVItemPadding_s = 3;
  infoPtr->hFont           = 0;
  infoPtr->items           = DPA_Create(8);
  infoPtr->hcurArrow       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
  infoPtr->iSelected       = -1;
  infoPtr->iHotTracked     = -1;
  infoPtr->uFocus          = -1;
  infoPtr->hwndToolTip     = 0;
  infoPtr->DoRedraw        = TRUE;
  infoPtr->needsScrolling  = FALSE;
  infoPtr->hwndUpDown      = 0;
  infoPtr->leftmostVisible = 0;
  infoPtr->fHeightSet      = FALSE;
  infoPtr->bUnicode        = IsWindowUnicode (hwnd);
  infoPtr->cbInfo          = sizeof(LPARAM);

  TRACE("Created tab control, hwnd [%p]\n", hwnd);

  /* The tab control always has the WS_CLIPSIBLINGS style. Even
     if you don't specify it in CreateWindow. This is necessary in
     order for paint to work correctly. This follows windows behaviour. */
  style = GetWindowLongW(hwnd, GWL_STYLE);
  if (style & TCS_VERTICAL) style |= TCS_MULTILINE;
  style |= WS_CLIPSIBLINGS;
  SetWindowLongW(hwnd, GWL_STYLE, style);

  infoPtr->dwStyle = style;
  infoPtr->exStyle = (style & TCS_FLATBUTTONS) ? TCS_EX_FLATSEPARATORS : 0;

  if (infoPtr->dwStyle & TCS_TOOLTIPS) {
    /* Create tooltip control */
    infoPtr->hwndToolTip =
      CreateWindowExW (0, TOOLTIPS_CLASSW, NULL, WS_POPUP,
		       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 = GetWindowLongPtrW(hwnd, GWLP_ID);
      nmttc.hdr.code = NM_TOOLTIPSCREATED;
      nmttc.hwndToolTips = infoPtr->hwndToolTip;

      SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
                    GetWindowLongPtrW(hwnd, GWLP_ID), (LPARAM)&nmttc);
    }
  }

  OpenThemeData (infoPtr->hwnd, themeClass);
  
  /*
   * We need to get text information so we need a DC and we need to select
   * a font.
   */
  hdc = GetDC(hwnd);
  hOldFont = SelectObject (hdc, GetStockObject (SYSTEM_FONT));

  /* Use the system font to determine the initial height of a tab. */
  GetTextMetricsW(hdc, &fontMetrics);

  /*
   * Make sure there is enough space for the letters + growing the
   * selected item + extra space for the selected item.
   */
  infoPtr->tabHeight = fontMetrics.tmHeight + SELECTED_TAB_OFFSET +
	               ((infoPtr->dwStyle & TCS_BUTTONS) ? 2 : 1) *
                        infoPtr->uVItemPadding;

  /* Initialize the width of a tab. */
  if (infoPtr->dwStyle & TCS_FIXEDWIDTH)
    infoPtr->tabWidth = GetDeviceCaps(hdc, LOGPIXELSX);

  infoPtr->tabMinWidth = -1;

  TRACE("tabH=%d, tabW=%d\n", infoPtr->tabHeight, infoPtr->tabWidth);

  SelectObject (hdc, hOldFont);
  ReleaseDC(hwnd, hdc);

  return 0;
}

static LRESULT
TAB_Destroy (TAB_INFO *infoPtr)
{
  INT iItem;

  SetWindowLongPtrW(infoPtr->hwnd, 0, 0);

  for (iItem = infoPtr->uNumItem - 1; iItem >= 0; iItem--)
  {
      TAB_ITEM *tab = TAB_GetItem(infoPtr, iItem);

      DPA_DeletePtr(infoPtr->items, iItem);
      infoPtr->uNumItem--;

      Free(tab->pszText);
      Free(tab);
  }
  DPA_Destroy(infoPtr->items);
  infoPtr->items = NULL;

  if (infoPtr->hwndToolTip)
    DestroyWindow (infoPtr->hwndToolTip);

  if (infoPtr->hwndUpDown)
    DestroyWindow(infoPtr->hwndUpDown);

  if (infoPtr->iHotTracked >= 0)
    KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);

  CloseThemeData (GetWindowTheme (infoPtr->hwnd));

  Free (infoPtr);
  return 0;
}

/* update theme after a WM_THEMECHANGED message */
static LRESULT theme_changed(const TAB_INFO *infoPtr)
{
    HTHEME theme = GetWindowTheme (infoPtr->hwnd);
    CloseThemeData (theme);
    OpenThemeData (infoPtr->hwnd, themeClass);
    return 0;
}

static LRESULT TAB_NCCalcSize(WPARAM wParam)
{
  if (!wParam)
    return 0;
  return WVR_ALIGNTOP;
}

static inline LRESULT
TAB_SetItemExtra (TAB_INFO *infoPtr, INT cbInfo)
{
  TRACE("(%p %d)\n", infoPtr, cbInfo);

  if (cbInfo < 0 || infoPtr->uNumItem) return FALSE;

  infoPtr->cbInfo = cbInfo;
  return TRUE;
}

static LRESULT TAB_RemoveImage (TAB_INFO *infoPtr, INT image)
{
  TRACE("%p %d\n", infoPtr, image);

  if (ImageList_Remove (infoPtr->himl, image))
  {
    INT i, *idx;
    RECT r;

    /* shift indices, repaint items if needed */
    for (i = 0; i < infoPtr->uNumItem; i++)
    {
      idx = &TAB_GetItem(infoPtr, i)->iImage;
      if (*idx >= image)
      {
        if (*idx == image)
          *idx = -1;
        else
          (*idx)--;

        /* repaint item */
        if (TAB_InternalGetItemRect (infoPtr, i, &r, NULL))
          InvalidateRect (infoPtr->hwnd, &r, TRUE);
      }
    }
  }

  return 0;
}

static LRESULT
TAB_SetExtendedStyle (TAB_INFO *infoPtr, DWORD exMask, DWORD exStyle)
{
  DWORD prevstyle = infoPtr->exStyle;

  /* zero mask means all styles */
  if (exMask == 0) exMask = ~0;

  if (exMask & TCS_EX_REGISTERDROP)
  {
    FIXME("TCS_EX_REGISTERDROP style unimplemented\n");
    exMask  &= ~TCS_EX_REGISTERDROP;
    exStyle &= ~TCS_EX_REGISTERDROP;
  }

  if (exMask & TCS_EX_FLATSEPARATORS)
  {
    if ((prevstyle ^ exStyle) & TCS_EX_FLATSEPARATORS)
    {
        infoPtr->exStyle ^= TCS_EX_FLATSEPARATORS;
        TAB_InvalidateTabArea(infoPtr);
    }
  }

  return prevstyle;
}

static inline LRESULT
TAB_GetExtendedStyle (const TAB_INFO *infoPtr)
{
  return infoPtr->exStyle;
}

static LRESULT
TAB_DeselectAll (TAB_INFO *infoPtr, BOOL excludesel)
{
  BOOL paint = FALSE;
  INT i, selected = infoPtr->iSelected;

  TRACE("(%p, %d)\n", infoPtr, excludesel);

  if (!(infoPtr->dwStyle & TCS_BUTTONS))
    return 0;

  for (i = 0; i < infoPtr->uNumItem; i++)
  {
    if ((TAB_GetItem(infoPtr, i)->dwState & TCIS_BUTTONPRESSED) &&
        (selected != i))
    {
      TAB_GetItem(infoPtr, i)->dwState &= ~TCIS_BUTTONPRESSED;
      paint = TRUE;
    }
  }

  if (!excludesel && (selected != -1))
  {
    TAB_GetItem(infoPtr, selected)->dwState &= ~TCIS_BUTTONPRESSED;
    infoPtr->iSelected = -1;
    paint = TRUE;
  }

  if (paint)
    TAB_InvalidateTabArea (infoPtr);

  return 0;
}

/***
 * DESCRIPTION:
 * Processes WM_STYLECHANGED messages.
 *
 * PARAMETER(S):
 * [I] infoPtr : valid pointer to the tab data structure
 * [I] wStyleType : window style type (normal or extended)
 * [I] lpss : window style information
 *
 * RETURN:
 * Zero
 */
static INT TAB_StyleChanged(TAB_INFO *infoPtr, WPARAM wStyleType,
                            const STYLESTRUCT *lpss)
{
    TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
          wStyleType, lpss->styleOld, lpss->styleNew);

    if (wStyleType != GWL_STYLE) return 0;

    infoPtr->dwStyle = lpss->styleNew;

    TAB_SetItemBounds (infoPtr);
    InvalidateRect(infoPtr->hwnd, NULL, TRUE);

    return 0;
}

static LRESULT WINAPI
TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);

    TRACE("hwnd=%p msg=%x wParam=%lx lParam=%lx\n", hwnd, uMsg, wParam, lParam);
    if (!infoPtr && (uMsg != WM_CREATE))
      return DefWindowProcW (hwnd, uMsg, wParam, lParam);

    switch (uMsg)
    {
    case TCM_GETIMAGELIST:
      return TAB_GetImageList (infoPtr);

    case TCM_SETIMAGELIST:
      return TAB_SetImageList (infoPtr, (HIMAGELIST)lParam);

    case TCM_GETITEMCOUNT:
      return TAB_GetItemCount (infoPtr);

    case TCM_GETITEMA:
    case TCM_GETITEMW:
      return TAB_GetItemT (infoPtr, (INT)wParam, (LPTCITEMW)lParam, uMsg == TCM_GETITEMW);

    case TCM_SETITEMA:
    case TCM_SETITEMW:
      return TAB_SetItemT (infoPtr, (INT)wParam, (LPTCITEMW)lParam, uMsg == TCM_SETITEMW);

    case TCM_DELETEITEM:
      return TAB_DeleteItem (infoPtr, (INT)wParam);

    case TCM_DELETEALLITEMS:
     return TAB_DeleteAllItems (infoPtr);

    case TCM_GETITEMRECT:
     return TAB_GetItemRect (infoPtr, (INT)wParam, (LPRECT)lParam);

    case TCM_GETCURSEL:
      return TAB_GetCurSel (infoPtr);

    case TCM_HITTEST:
      return TAB_HitTest (infoPtr, (LPTCHITTESTINFO)lParam);

    case TCM_SETCURSEL:
      return TAB_SetCurSel (infoPtr, (INT)wParam);

    case TCM_INSERTITEMA:
    case TCM_INSERTITEMW:
      return TAB_InsertItemT (infoPtr, (INT)wParam, (TCITEMW*)lParam, uMsg == TCM_INSERTITEMW);

    case TCM_SETITEMEXTRA:
      return TAB_SetItemExtra (infoPtr, (INT)wParam);

    case TCM_ADJUSTRECT:
      return TAB_AdjustRect (infoPtr, (BOOL)wParam, (LPRECT)lParam);

    case TCM_SETITEMSIZE:
      return TAB_SetItemSize (infoPtr, (INT)LOWORD(lParam), (INT)HIWORD(lParam));

    case TCM_REMOVEIMAGE:
      return TAB_RemoveImage (infoPtr, (INT)wParam);

    case TCM_SETPADDING:
      return TAB_SetPadding (infoPtr, lParam);

    case TCM_GETROWCOUNT:
      return TAB_GetRowCount(infoPtr);

    case TCM_GETUNICODEFORMAT:
      return TAB_GetUnicodeFormat (infoPtr);

    case TCM_SETUNICODEFORMAT:
      return TAB_SetUnicodeFormat (infoPtr, (BOOL)wParam);

    case TCM_HIGHLIGHTITEM:
      return TAB_HighlightItem (infoPtr, (INT)wParam, (BOOL)LOWORD(lParam));

    case TCM_GETTOOLTIPS:
      return TAB_GetToolTips (infoPtr);

    case TCM_SETTOOLTIPS:
      return TAB_SetToolTips (infoPtr, (HWND)wParam);

    case TCM_GETCURFOCUS:
      return TAB_GetCurFocus (infoPtr);

    case TCM_SETCURFOCUS:
      return TAB_SetCurFocus (infoPtr, (INT)wParam);

    case TCM_SETMINTABWIDTH:
      return TAB_SetMinTabWidth(infoPtr, (INT)lParam);

    case TCM_DESELECTALL:
      return TAB_DeselectAll (infoPtr, (BOOL)wParam);

    case TCM_GETEXTENDEDSTYLE:
      return TAB_GetExtendedStyle (infoPtr);

    case TCM_SETEXTENDEDSTYLE:
      return TAB_SetExtendedStyle (infoPtr, wParam, lParam);

    case WM_GETFONT:
      return TAB_GetFont (infoPtr);

    case WM_SETFONT:
      return TAB_SetFont (infoPtr, (HFONT)wParam);

    case WM_CREATE:
      return TAB_Create (hwnd, lParam);

    case WM_NCDESTROY:
      return TAB_Destroy (infoPtr);

    case WM_GETDLGCODE:
      return DLGC_WANTARROWS | DLGC_WANTCHARS;

    case WM_LBUTTONDOWN:
      return TAB_LButtonDown (infoPtr, wParam, lParam);

    case WM_LBUTTONUP:
      return TAB_LButtonUp (infoPtr);

    case WM_NOTIFY:
      return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);

    case WM_RBUTTONUP:
      TAB_RButtonUp (infoPtr);
      return DefWindowProcW (hwnd, uMsg, wParam, lParam);

    case WM_MOUSEMOVE:
      return TAB_MouseMove (infoPtr, wParam, lParam);

    case WM_PRINTCLIENT:
    case WM_PAINT:
      return TAB_Paint (infoPtr, (HDC)wParam);

    case WM_SIZE:
      return TAB_Size (infoPtr);

    case WM_SETREDRAW:
      return TAB_SetRedraw (infoPtr, (BOOL)wParam);

    case WM_HSCROLL:
      return TAB_OnHScroll(infoPtr, (int)LOWORD(wParam), (int)HIWORD(wParam));

    case WM_STYLECHANGED:
      return TAB_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);

    case WM_SYSCOLORCHANGE:
      COMCTL32_RefreshSysColors();
      return 0;

    case WM_THEMECHANGED:
      return theme_changed (infoPtr);

    case WM_KILLFOCUS:
      TAB_KillFocus(infoPtr);
    case WM_SETFOCUS:
      TAB_FocusChanging(infoPtr);
      break;   /* Don't disturb normal focus behavior */

    case WM_KEYDOWN:
      return TAB_KeyDown(infoPtr, wParam, lParam);

    case WM_NCHITTEST:
      return TAB_NCHitTest(infoPtr, lParam);

    case WM_NCCALCSIZE:
      return TAB_NCCalcSize(wParam);

    default:
      if (uMsg >= WM_USER && uMsg < WM_APP && !COMCTL32_IsReflectedMessage(uMsg))
	WARN("unknown msg %04x wp=%08lx lp=%08lx\n",
	     uMsg, wParam, lParam);
      break;
    }
    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}


void
TAB_Register (void)
{
  WNDCLASSW wndClass;

  ZeroMemory (&wndClass, sizeof(WNDCLASSW));
  wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
  wndClass.lpfnWndProc   = TAB_WindowProc;
  wndClass.cbClsExtra    = 0;
  wndClass.cbWndExtra    = sizeof(TAB_INFO *);
  wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
  wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
  wndClass.lpszClassName = WC_TABCONTROLW;

  RegisterClassW (&wndClass);
}


void
TAB_Unregister (void)
{
    UnregisterClassW (WC_TABCONTROLW, NULL);
}
