Sync uo to HEAD (r47720). backups/header-work@57446
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 9 Jun 2010 18:58:14 +0000 (18:58 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 9 Jun 2010 18:58:14 +0000 (18:58 +0000)
svn path=/branches/header-work/; revision=47721

26 files changed:
Makefile
dll/win32/comctl32/pager.c
dll/win32/comctl32/propsheet.c
dll/win32/comctl32/rebar.c
dll/win32/comctl32/status.c
dll/win32/comctl32/string.c
dll/win32/comctl32/syslink.c
dll/win32/comctl32/tab.c
dll/win32/comctl32/theme_combo.c
dll/win32/comctl32/toolbar.c
dll/win32/comctl32/tooltips.c
dll/win32/comctl32/trackbar.c
dll/win32/comctl32/treeview.c
dll/win32/comctl32/updown.c
drivers/ksfilter/ks/api.c
drivers/ksfilter/ks/connectivity.c
drivers/ksfilter/ks/event.c
drivers/ksfilter/ks/image.c
drivers/ksfilter/ks/irp.c
drivers/ksfilter/ks/misc.c
drivers/ksfilter/ks/pin.c
drivers/ksfilter/ks/topology.c
drivers/wdm/audio/backpln/portcls/irp.cpp
lib/drivers/ip/transport/tcp/tcp.c
lib/drivers/sound/mmixer/controls.c
lib/drivers/sound/mmixer/mixer.c

index 07148d0..cf320c4 100644 (file)
--- a/Makefile
+++ b/Makefile
 #        This is faster than the depends target which does a complete dependency
 #        check of the ReactOS codebase.
 #
+#    bootcdregtest
+#        This target builds an ISO (ReactOS-RegTest.ISO) which is used for unattended
+#        regression testing.
+#
 #
 # Accepted environment variables:
 #
index fdf470c..f3461fd 100644 (file)
@@ -841,7 +841,6 @@ static LRESULT
 PAGER_NCCalcSize(PAGER_INFO* infoPtr, WPARAM wParam, LPRECT lpRect)
 {
     RECT rcChild, rcWindow;
-    INT scrollRange;
 
     /*
      * lpRect points to a RECT struct.  On entry, the struct
@@ -863,8 +862,6 @@ PAGER_NCCalcSize(PAGER_INFO* infoPtr, WPARAM wParam, LPRECT lpRect)
        infoPtr->nWidth = lpRect->right - lpRect->left;
        PAGER_CalcSize (infoPtr, &infoPtr->nWidth, TRUE);
 
-       scrollRange = infoPtr->nWidth - (rcWindow.right - rcWindow.left);
-
        if (infoPtr->TLbtnState && (lpRect->left + infoPtr->nButtonSize < lpRect->right))
            lpRect->left += infoPtr->nButtonSize;
        if (infoPtr->BRbtnState && (lpRect->right - infoPtr->nButtonSize > lpRect->left))
@@ -875,8 +872,6 @@ PAGER_NCCalcSize(PAGER_INFO* infoPtr, WPARAM wParam, LPRECT lpRect)
        infoPtr->nHeight = lpRect->bottom - lpRect->top;
        PAGER_CalcSize (infoPtr, &infoPtr->nHeight, FALSE);
 
-       scrollRange = infoPtr->nHeight - (rcWindow.bottom - rcWindow.top);
-
        if (infoPtr->TLbtnState && (lpRect->top + infoPtr->nButtonSize < lpRect->bottom))
            lpRect->top += infoPtr->nButtonSize;
        if (infoPtr->BRbtnState && (lpRect->bottom - infoPtr->nButtonSize > lpRect->top))
index 6264923..25a9218 100644 (file)
@@ -330,7 +330,7 @@ static void PROPSHEET_CollectSheetInfoA(LPCPROPSHEETHEADERA lppsh,
      psInfo->ppshheader.pszCaption = NULL;
   else
   {
-     if (HIWORD(lppsh->pszCaption))
+     if (!IS_INTRESOURCE(lppsh->pszCaption))
      {
         int len = MultiByteToWideChar(CP_ACP, 0, lppsh->pszCaption, -1, NULL, 0);
         WCHAR *caption = Alloc( len*sizeof (WCHAR) );
@@ -373,7 +373,7 @@ static void PROPSHEET_CollectSheetInfoW(LPCPROPSHEETHEADERW lppsh,
      psInfo->ppshheader.pszCaption = NULL;
   else
   {
-     if (HIWORD(lppsh->pszCaption))
+     if (!IS_INTRESOURCE(lppsh->pszCaption))
      {
         int len = strlenW(lppsh->pszCaption);
         WCHAR *caption = Alloc( (len+1)*sizeof(WCHAR) );
@@ -553,7 +553,7 @@ static BOOL PROPSHEET_CollectPageInfo(LPCPROPSHEETPAGEW lppsp,
     WCHAR *text;
     int len;
 
-    if ( !HIWORD( lppsp->pszTitle ) )
+    if (IS_INTRESOURCE( lppsp->pszTitle ))
     {
       if (!LoadStringW( lppsp->hInstance, (DWORD_PTR)lppsp->pszTitle,szTitle,sizeof(szTitle)/sizeof(szTitle[0]) ))
       {
@@ -1197,7 +1197,7 @@ static BOOL PROPSHEET_CreateTabControl(HWND hwndParent,
     }
 
     item.pszText = (LPWSTR) psInfo->proppage[i].pszText;
-    SendMessageW(hwndTabCtrl, TCM_INSERTITEMW, (WPARAM)i, (LPARAM)&item);
+    SendMessageW(hwndTabCtrl, TCM_INSERTITEMW, i, (LPARAM)&item);
   }
   SendMessageW(GetDlgItem(hwndTabCtrl, IDC_TABCONTROL), WM_SETREDRAW, 1, 0);
 
@@ -1370,10 +1370,10 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent,
                                 const PropSheetInfo * psInfo,
                                 LPCPROPSHEETPAGEW ppshpage)
 {
-  DLGTEMPLATE* pTemplate;
+  const DLGTEMPLATE* pTemplate;
   HWND hwndPage;
   DWORD resSize;
-  LPVOID temp = NULL;
+  DLGTEMPLATE* pTemplateCopy = NULL;
 
   TRACE("index %d\n", index);
 
@@ -1384,7 +1384,7 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent,
 
   if (ppshpage->dwFlags & PSP_DLGINDIRECT)
     {
-      pTemplate = (DLGTEMPLATE*)ppshpage->u.pResource;
+      pTemplate = ppshpage->u.pResource;
       resSize = GetTemplateSize(pTemplate);
     }
   else if(ppshpage->dwFlags & PSP_INTERNAL_UNICODE)
@@ -1431,39 +1431,38 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent,
      * Make a copy of the dialog template to make it writable
      */
   }
-  temp = Alloc(resSize);
-  if (!temp)
+  pTemplateCopy = Alloc(resSize);
+  if (!pTemplateCopy)
     return FALSE;
   
-  TRACE("copying pTemplate %p into temp %p (%d)\n", pTemplate, temp, resSize);
-  memcpy(temp, pTemplate, resSize);
-  pTemplate = temp;
+  TRACE("copying pTemplate %p into pTemplateCopy %p (%d)\n", pTemplate, pTemplateCopy, resSize);
+  memcpy(pTemplateCopy, pTemplate, resSize);
 
-  if (((MyDLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF)
+  if (((MyDLGTEMPLATEEX*)pTemplateCopy)->signature == 0xFFFF)
   {
-    ((MyDLGTEMPLATEEX*)pTemplate)->style |= WS_CHILD | WS_TABSTOP | DS_CONTROL;
-    ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~DS_MODALFRAME;
-    ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_CAPTION;
-    ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_SYSMENU;
-    ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_POPUP;
-    ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_DISABLED;
-    ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_VISIBLE;
-    ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_THICKFRAME;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->style |= WS_CHILD | WS_TABSTOP | DS_CONTROL;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->style &= ~DS_MODALFRAME;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->style &= ~WS_CAPTION;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->style &= ~WS_SYSMENU;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->style &= ~WS_POPUP;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->style &= ~WS_DISABLED;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->style &= ~WS_VISIBLE;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->style &= ~WS_THICKFRAME;
 
-    ((MyDLGTEMPLATEEX*)pTemplate)->exStyle |= WS_EX_CONTROLPARENT;
+    ((MyDLGTEMPLATEEX*)pTemplateCopy)->exStyle |= WS_EX_CONTROLPARENT;
   }
   else
   {
-    pTemplate->style |= WS_CHILD | WS_TABSTOP | DS_CONTROL;
-    pTemplate->style &= ~DS_MODALFRAME;
-    pTemplate->style &= ~WS_CAPTION;
-    pTemplate->style &= ~WS_SYSMENU;
-    pTemplate->style &= ~WS_POPUP;
-    pTemplate->style &= ~WS_DISABLED;
-    pTemplate->style &= ~WS_VISIBLE;
-    pTemplate->style &= ~WS_THICKFRAME;
+    pTemplateCopy->style |= WS_CHILD | WS_TABSTOP | DS_CONTROL;
+    pTemplateCopy->style &= ~DS_MODALFRAME;
+    pTemplateCopy->style &= ~WS_CAPTION;
+    pTemplateCopy->style &= ~WS_SYSMENU;
+    pTemplateCopy->style &= ~WS_POPUP;
+    pTemplateCopy->style &= ~WS_DISABLED;
+    pTemplateCopy->style &= ~WS_VISIBLE;
+    pTemplateCopy->style &= ~WS_THICKFRAME;
 
-    pTemplate->dwExtendedStyle |= WS_EX_CONTROLPARENT;
+    pTemplateCopy->dwExtendedStyle |= WS_EX_CONTROLPARENT;
   }
 
   if (psInfo->proppage[index].useCallback)
@@ -1472,18 +1471,18 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent,
 
   if(ppshpage->dwFlags & PSP_INTERNAL_UNICODE)
      hwndPage = CreateDialogIndirectParamW(ppshpage->hInstance,
-                                       pTemplate,
+                                       pTemplateCopy,
                                        hwndParent,
                                        ppshpage->pfnDlgProc,
                                        (LPARAM)ppshpage);
   else
      hwndPage = CreateDialogIndirectParamA(ppshpage->hInstance,
-                                       pTemplate,
+                                       pTemplateCopy,
                                        hwndParent,
                                        ppshpage->pfnDlgProc,
                                        (LPARAM)ppshpage);
   /* Free a no more needed copy */
-  Free(temp);
+  Free(pTemplateCopy);
 
   psInfo->proppage[index].hwndPage = hwndPage;
 
@@ -2131,7 +2130,7 @@ static void PROPSHEET_SetCurSelId(HWND hwndDlg, int id)
  */
 static void PROPSHEET_SetTitleA(HWND hwndDlg, DWORD dwStyle, LPCSTR lpszText)
 {
-  if(HIWORD(lpszText))
+  if(!IS_INTRESOURCE(lpszText))
   {
      WCHAR szTitle[256];
      MultiByteToWideChar(CP_ACP, 0, lpszText, -1,
@@ -2153,7 +2152,7 @@ static void PROPSHEET_SetTitleW(HWND hwndDlg, DWORD dwStyle, LPCWSTR lpszText)
   WCHAR szTitle[256];
 
   TRACE("%s (style %08x)\n", debugstr_w(lpszText), dwStyle);
-  if (HIWORD(lpszText) == 0) {
+  if (IS_INTRESOURCE(lpszText)) {
     if (!LoadStringW(psInfo->ppshheader.hInstance,
                      LOWORD(lpszText), szTitle, sizeof(szTitle)/sizeof(szTitle[0])))
       return;
@@ -2422,28 +2421,6 @@ static BOOL PROPSHEET_RemovePage(HWND hwndDlg,
   return FALSE;
 }
 
-BOOL CALLBACK
-EnumChildProc(HWND hwnd, LPARAM lParam)
-{
-    WCHAR szType[20];
-    RealGetWindowClassW(hwnd, szType, 20);
-
-    if (strcmpW(szType, WC_EDITW) == 0)
-    {
-        if (IsWindowEnabled(hwnd) && IsWindowVisible(hwnd))
-        {
-            SetFocus(hwnd);
-            return FALSE;
-        }
-    } 
-    else
-    {
-        EnumChildWindows(hwnd, EnumChildProc, 0);
-    }
-
-    return TRUE;
-}
-
 /******************************************************************************
  *            PROPSHEET_SetWizButtons
  *
@@ -2465,6 +2442,17 @@ static void PROPSHEET_SetWizButtons(HWND hwndDlg, DWORD dwFlags)
   EnableWindow(hwndNext, FALSE);
   EnableWindow(hwndFinish, FALSE);
 
+  /* set the default pushbutton to an enabled button */
+  if (((dwFlags & PSWIZB_FINISH) || psInfo->hasFinish) && !(dwFlags & PSWIZB_DISABLEDFINISH))
+    SendMessageW(hwndDlg, DM_SETDEFID, IDC_FINISH_BUTTON, 0);
+  else if (dwFlags & PSWIZB_NEXT)
+    SendMessageW(hwndDlg, DM_SETDEFID, IDC_NEXT_BUTTON, 0);
+  else if (dwFlags & PSWIZB_BACK)
+    SendMessageW(hwndDlg, DM_SETDEFID, IDC_BACK_BUTTON, 0);
+  else
+    SendMessageW(hwndDlg, DM_SETDEFID, IDCANCEL, 0);
+
+
   if (dwFlags & PSWIZB_BACK)
     EnableWindow(hwndBack, TRUE);
 
@@ -2494,31 +2482,6 @@ static void PROPSHEET_SetWizButtons(HWND hwndDlg, DWORD dwFlags)
   }
   else if (!(dwFlags & PSWIZB_DISABLEDFINISH))
     EnableWindow(hwndFinish, TRUE);
-
-  /* set the default pushbutton to an enabled button and give it focus */
-  if (((dwFlags & PSWIZB_FINISH) || psInfo->hasFinish) && !(dwFlags & PSWIZB_DISABLEDFINISH))
-  {
-    SendMessageW(hwndDlg, DM_SETDEFID, IDC_FINISH_BUTTON, 0);
-    SetFocus(hwndFinish);
-  }
-  else if (dwFlags & PSWIZB_NEXT)
-  {
-    SendMessageW(hwndDlg, DM_SETDEFID, IDC_NEXT_BUTTON, 0);
-    SetFocus(hwndNext);
-  }
-  else if (dwFlags & PSWIZB_BACK)
-  {
-    SendMessageW(hwndDlg, DM_SETDEFID, IDC_BACK_BUTTON, 0);
-    SetFocus(hwndBack);
-  }
-  else
-  {
-    SendMessageW(hwndDlg, DM_SETDEFID, IDCANCEL, 0);
-    SetFocus(GetDlgItem(hwndDlg, IDCANCEL));
-  }
-
-  /* Now try to find an edit control that deserves focus */
-  EnumChildWindows(PropSheet_GetCurrentPageHwnd(hwndDlg), EnumChildProc, 0);
 }
 
 /******************************************************************************
@@ -2526,7 +2489,7 @@ static void PROPSHEET_SetWizButtons(HWND hwndDlg, DWORD dwFlags)
  */
 static BOOL PROPSHEET_InsertPage(HWND hwndDlg, HPROPSHEETPAGE hpageInsertAfter, HPROPSHEETPAGE hpage)
 {
-    if (!HIWORD(hpageInsertAfter))
+    if (IS_INTRESOURCE(hpageInsertAfter))
         FIXME("(%p, %d, %p): stub\n", hwndDlg, LOWORD(hpageInsertAfter), hpage);
     else
         FIXME("(%p, %p, %p): stub\n", hwndDlg, hpageInsertAfter, hpage);
@@ -2589,6 +2552,8 @@ static LRESULT PROPSHEET_IndexToHwnd(HWND hwndDlg, int iPageIndex)
 {
     PropSheetInfo * psInfo = GetPropW(hwndDlg, PropSheetInfoStr);
     TRACE("(%p, %d)\n", hwndDlg, iPageIndex);
+    if (!psInfo)
+        return 0;
     if (iPageIndex<0 || iPageIndex>=psInfo->nPages) {
         WARN("%d out of range.\n", iPageIndex);
        return 0;
@@ -2658,7 +2623,7 @@ static LRESULT PROPSHEET_IndexToId(HWND hwndDlg, int iPageIndex)
        return 0;
     }
     psp = (LPCPROPSHEETPAGEW)psInfo->proppage[iPageIndex].hpage;
-    if (psp->dwFlags & PSP_DLGINDIRECT || HIWORD(psp->u.pszTemplate)) {
+    if (psp->dwFlags & PSP_DLGINDIRECT || !IS_INTRESOURCE(psp->u.pszTemplate)) {
         return 0;
     }
     return (LRESULT)psp->u.pszTemplate;
@@ -2718,7 +2683,7 @@ static void PROPSHEET_CleanUp(HWND hwndDlg)
 
   TRACE("\n");
   if (!psInfo) return;
-  if (HIWORD(psInfo->ppshheader.pszCaption))
+  if (!IS_INTRESOURCE(psInfo->ppshheader.pszCaption))
       Free ((LPVOID)psInfo->ppshheader.pszCaption);
 
   for (i = 0; i < psInfo->nPages; i++)
@@ -2974,7 +2939,7 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageA(
 
     if ( !(ppsp->dwFlags & PSP_DLGINDIRECT) )
     {
-        if (HIWORD( ppsp->u.pszTemplate ))
+        if (!IS_INTRESOURCE( ppsp->u.pszTemplate ))
         {
             int len = strlen(lpPropSheetPage->u.pszTemplate) + 1;
             char *template = Alloc( len );
@@ -2985,13 +2950,13 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageA(
 
     if (ppsp->dwFlags & PSP_USEICONID)
     {
-        if (HIWORD( ppsp->u2.pszIcon ))
+        if (!IS_INTRESOURCE( ppsp->u2.pszIcon ))
             PROPSHEET_AtoW(&ppsp->u2.pszIcon, lpPropSheetPage->u2.pszIcon);
     }
 
     if (ppsp->dwFlags & PSP_USETITLE)
     {
-        if (HIWORD( ppsp->pszTitle ))
+        if (!IS_INTRESOURCE( ppsp->pszTitle ))
             PROPSHEET_AtoW( &ppsp->pszTitle, lpPropSheetPage->pszTitle );
         else
             ppsp->pszTitle = load_string( ppsp->hInstance, ppsp->pszTitle );
@@ -3004,7 +2969,7 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageA(
 
     if (ppsp->dwFlags & PSP_USEHEADERTITLE)
     {
-        if (HIWORD( ppsp->pszHeaderTitle ))
+        if (!IS_INTRESOURCE( ppsp->pszHeaderTitle ))
             PROPSHEET_AtoW(&ppsp->pszHeaderTitle, lpPropSheetPage->pszHeaderTitle);
         else
             ppsp->pszHeaderTitle = load_string( ppsp->hInstance, ppsp->pszHeaderTitle );
@@ -3014,7 +2979,7 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageA(
 
     if (ppsp->dwFlags & PSP_USEHEADERSUBTITLE)
     {
-        if (HIWORD( ppsp->pszHeaderSubTitle ))
+        if (!IS_INTRESOURCE( ppsp->pszHeaderSubTitle ))
             PROPSHEET_AtoW(&ppsp->pszHeaderSubTitle, lpPropSheetPage->pszHeaderSubTitle);
         else
             ppsp->pszHeaderSubTitle = load_string( ppsp->hInstance, ppsp->pszHeaderSubTitle );
@@ -3040,7 +3005,7 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage
 
     if ( !(ppsp->dwFlags & PSP_DLGINDIRECT) )
     {
-        if (HIWORD( ppsp->u.pszTemplate ))
+        if (!IS_INTRESOURCE( ppsp->u.pszTemplate ))
         {
             int len = strlenW(lpPropSheetPage->u.pszTemplate) + 1;
             WCHAR *template = Alloc( len * sizeof (WCHAR) );
@@ -3051,7 +3016,7 @@ HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage
 
     if ( ppsp->dwFlags & PSP_USEICONID )
     {
-        if (HIWORD( ppsp->u2.pszIcon ))
+        if (!IS_INTRESOURCE( ppsp->u2.pszIcon ))
         {
             int len = strlenW(lpPropSheetPage->u2.pszIcon) + 1;
             WCHAR *icon = Alloc( len * sizeof (WCHAR) );
@@ -3099,13 +3064,13 @@ BOOL WINAPI DestroyPropertySheetPage(HPROPSHEETPAGE hPropPage)
   if (!psp)
      return FALSE;
 
-  if ( !(psp->dwFlags & PSP_DLGINDIRECT) && HIWORD( psp->u.pszTemplate ) )
+  if (!(psp->dwFlags & PSP_DLGINDIRECT) && !IS_INTRESOURCE( psp->u.pszTemplate ))
      Free ((LPVOID)psp->u.pszTemplate);
 
-  if ( (psp->dwFlags & PSP_USEICONID) && HIWORD( psp->u2.pszIcon ) )
+  if ((psp->dwFlags & PSP_USEICONID) && !IS_INTRESOURCE( psp->u2.pszIcon ))
      Free ((LPVOID)psp->u2.pszIcon);
 
-  if ((psp->dwFlags & PSP_USETITLE) && HIWORD( psp->pszTitle ))
+  if ((psp->dwFlags & PSP_USETITLE) && !IS_INTRESOURCE( psp->pszTitle ))
      Free ((LPVOID)psp->pszTitle);
 
   Free(hPropPage);
@@ -3326,7 +3291,7 @@ static LRESULT PROPSHEET_Paint(HWND hwnd, HDC hdcParam)
 
        if (ppshpage->dwFlags & PSP_USEHEADERTITLE) {
            SetRect(&r, 20, 10, 0, 0);
-           if (HIWORD(ppshpage->pszHeaderTitle))
+            if (!IS_INTRESOURCE(ppshpage->pszHeaderTitle))
                 DrawTextW(hdc, ppshpage->pszHeaderTitle, -1, &r, DT_LEFT | DT_SINGLELINE | DT_NOCLIP);
            else
            {
@@ -3342,7 +3307,7 @@ static LRESULT PROPSHEET_Paint(HWND hwnd, HDC hdcParam)
        if (ppshpage->dwFlags & PSP_USEHEADERSUBTITLE) {
            SelectObject(hdc, psInfo->hFont);
            SetRect(&r, 40, 25, rzone.right - 69, rzone.bottom);
-           if (HIWORD(ppshpage->pszHeaderTitle))
+            if (!IS_INTRESOURCE(ppshpage->pszHeaderTitle))
                 DrawTextW(hdc, ppshpage->pszHeaderSubTitle, -1, &r, DT_LEFT | DT_WORDBREAK);
            else
            {
@@ -3504,7 +3469,7 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
         }
       }
 
-      if (!HIWORD(psInfo->ppshheader.pszCaption) &&
+      if (IS_INTRESOURCE(psInfo->ppshheader.pszCaption) &&
               psInfo->ppshheader.hInstance)
       {
          WCHAR szText[256];
index e11d974..cd3abad 100644 (file)
@@ -78,6 +78,7 @@
  *    at least RB_INSERTBAND
  */
 
+#include <assert.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
@@ -183,7 +184,7 @@ typedef struct
     INT      ichevronhotBand; /* last band that had a hot chevron */
     INT      iGrabbedBand;/* band number of band whose gripper was grabbed */
 
-    REBAR_BAND *bands;      /* pointer to the array of rebar bands */
+    HDPA     bands;       /* pointer to the array of rebar bands */
 } REBAR_INFO;
 
 /* fStatus flags */
@@ -256,6 +257,13 @@ typedef struct
 static LRESULT REBAR_NotifyFormat(REBAR_INFO *infoPtr, LPARAM lParam);
 static void REBAR_AutoSize(REBAR_INFO *infoPtr, BOOL needsLayout);
 
+/* no index check here */
+static inline REBAR_BAND* REBAR_GetBand(const REBAR_INFO *infoPtr, INT i)
+{
+    assert(i >= 0 && i < infoPtr->uNumBands);
+    return DPA_GetPtr(infoPtr->bands, i);
+}
+
 /* "constant values" retrieved when DLL was initialized    */
 /* FIXME we do this when the classes are registered.       */
 static UINT mindragx = 0;
@@ -379,7 +387,7 @@ REBAR_DumpBand (const REBAR_INFO *iP)
           iP->hwndSelf, iP->dwStyle, (iP->bUnicode)?"TRUE":"FALSE",
           (iP->DoRedraw)?"TRUE":"FALSE");
     for (i = 0; i < iP->uNumBands; i++) {
-       pB = &iP->bands[i];
+       pB = REBAR_GetBand(iP, i);
        TRACE("band # %u:", i);
        if (pB->fMask & RBBIM_ID)
            TRACE(" ID=%u", pB->wID);
@@ -523,11 +531,11 @@ static INT
 REBAR_Notify_NMREBAR (const REBAR_INFO *infoPtr, UINT uBand, UINT code)
 {
     NMREBAR notify_rebar;
-    REBAR_BAND *lpBand;
 
     notify_rebar.dwMask = 0;
-    if (uBand!=-1) {
-       lpBand = &infoPtr->bands[uBand];
+    if (uBand != -1) {
+       REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, uBand);
+
        if (lpBand->fMask & RBBIM_ID) {
            notify_rebar.dwMask |= RBNM_ID;
            notify_rebar.wID = lpBand->wID;
@@ -680,7 +688,7 @@ REBAR_Refresh (const REBAR_INFO *infoPtr, HDC hdc)
     if (!infoPtr->DoRedraw) return;
 
     for (i = 0; i < infoPtr->uNumBands; i++) {
-       lpBand = &infoPtr->bands[i];
+       lpBand = REBAR_GetBand(infoPtr, i);
 
        if (HIDDENBAND(lpBand)) continue;
 
@@ -688,7 +696,6 @@ REBAR_Refresh (const REBAR_INFO *infoPtr, HDC hdc)
        TRACE("[%p] drawing band %i, flags=%08x\n",
              infoPtr->hwndSelf, i, lpBand->fDraw);
        REBAR_DrawBand (hdc, infoPtr, lpBand);
-
     }
 }
 
@@ -700,11 +707,11 @@ REBAR_CalcHorzBand (const REBAR_INFO *infoPtr, UINT rstart, UINT rend)
      /* *** Supports only Horizontal bars. ***                   */
 {
     REBAR_BAND *lpBand;
-    UINT i, xoff, yoff;
+    UINT i, xoff;
     RECT work;
 
     for(i=rstart; i<rend; i++){
-      lpBand = &infoPtr->bands[i];
+      lpBand = REBAR_GetBand(infoPtr, i);
       if (HIDDENBAND(lpBand)) {
           SetRect (&lpBand->rcChild,
                   lpBand->rcBand.right, lpBand->rcBand.top,
@@ -763,12 +770,24 @@ REBAR_CalcHorzBand (const REBAR_INFO *infoPtr, UINT rstart, UINT rend)
       }
 
       /* set initial child window rectangle if there is a child */
-      if (lpBand->hwndChild != NULL) {
-          int cyBand = lpBand->rcBand.bottom - lpBand->rcBand.top;
-          yoff = (cyBand - lpBand->cyChild) / 2;
-         SetRect (&lpBand->rcChild,
-                   lpBand->rcBand.left + lpBand->cxHeader, lpBand->rcBand.top + yoff,
-                   lpBand->rcBand.right - REBAR_POST_CHILD, lpBand->rcBand.top + yoff + lpBand->cyChild);
+      if (lpBand->hwndChild) {
+
+          lpBand->rcChild.left  = lpBand->rcBand.left + lpBand->cxHeader;
+          lpBand->rcChild.right = lpBand->rcBand.right - REBAR_POST_CHILD;
+
+          if (lpBand->cyChild > 0) {
+
+              UINT yoff = (lpBand->rcBand.bottom - lpBand->rcBand.top - lpBand->cyChild) / 2;
+
+              /* center child if height is known */
+              lpBand->rcChild.top = lpBand->rcBand.top + yoff;
+              lpBand->rcChild.bottom = lpBand->rcBand.top + yoff + lpBand->cyChild;
+          }
+          else {
+              lpBand->rcChild.top = lpBand->rcBand.top;
+              lpBand->rcChild.bottom = lpBand->rcBand.bottom;
+          }
+
          if ((lpBand->fStyle & RBBS_USECHEVRON) && (lpBand->rcChild.right - lpBand->rcChild.left < lpBand->cxIdeal))
          {
              lpBand->rcChild.right -= CHEVRON_WIDTH;
@@ -795,7 +814,7 @@ REBAR_CalcHorzBand (const REBAR_INFO *infoPtr, UINT rstart, UINT rend)
          work.right += SEP_WIDTH;
          work.bottom += SEP_WIDTH;
          InvalidateRect(infoPtr->hwndSelf, &work, TRUE);
-         InvalidateRect(lpBand->hwndChild, NULL, TRUE);
+         if (lpBand->hwndChild) InvalidateRect(lpBand->hwndChild, NULL, TRUE);
       }
 
     }
@@ -815,7 +834,7 @@ REBAR_CalcVertBand (const REBAR_INFO *infoPtr, UINT rstart, UINT rend)
 
     for(i=rstart; i<rend; i++){
         RECT rcBand;
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
        if (HIDDENBAND(lpBand)) continue;
 
         translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
@@ -892,7 +911,7 @@ REBAR_CalcVertBand (const REBAR_INFO *infoPtr, UINT rstart, UINT rend)
        }
 
        /* set initial child window rectangle if there is a child */
-       if (lpBand->hwndChild != NULL) {
+       if (lpBand->hwndChild) {
             int cxBand = rcBand.right - rcBand.left;
             xoff = (cxBand - lpBand->cyChild) / 2;
            SetRect (&lpBand->rcChild,
@@ -916,7 +935,7 @@ REBAR_CalcVertBand (const REBAR_INFO *infoPtr, UINT rstart, UINT rend)
            work.bottom += SEP_WIDTH;
            work.right += SEP_WIDTH;
            InvalidateRect(infoPtr->hwndSelf, &work, TRUE);
-           InvalidateRect(lpBand->hwndChild, NULL, TRUE);
+           if (lpBand->hwndChild) InvalidateRect(lpBand->hwndChild, NULL, TRUE);
        }
 
     }
@@ -1006,7 +1025,7 @@ REBAR_MoveChildWindows (const REBAR_INFO *infoPtr, UINT start, UINT endplus)
         ERR("BeginDeferWindowPos returned NULL\n");
 
     for (i = start; i < endplus; i++) {
-       lpBand = &infoPtr->bands[i];
+       lpBand = REBAR_GetBand(infoPtr, i);
 
        if (HIDDENBAND(lpBand)) continue;
        if (lpBand->hwndChild) {
@@ -1107,7 +1126,7 @@ static int next_visible(const REBAR_INFO *infoPtr, int i)
 {
     int n;
     for (n = i + 1; n < infoPtr->uNumBands; n++)
-        if (!HIDDENBAND(&infoPtr->bands[n]))
+        if (!HIDDENBAND(REBAR_GetBand(infoPtr, n)))
             break;
     return n;
 }
@@ -1118,7 +1137,7 @@ static int prev_visible(const REBAR_INFO *infoPtr, int i)
 {
     int n;
     for (n = i - 1; n >= 0; n--)
-        if (!HIDDENBAND(&infoPtr->bands[n]))
+        if (!HIDDENBAND(REBAR_GetBand(infoPtr, n)))
             break;
     return n;
 }
@@ -1133,9 +1152,9 @@ static int first_visible(const REBAR_INFO *infoPtr)
 static int get_row_begin_for_band(const REBAR_INFO *infoPtr, INT iBand)
 {
     int iLastBand = iBand;
-    int iRow = infoPtr->bands[iBand].iRow;
+    int iRow = REBAR_GetBand(infoPtr, iBand)->iRow;
     while ((iBand = prev_visible(infoPtr, iBand)) >= 0) {
-        if (infoPtr->bands[iBand].iRow != iRow)
+        if (REBAR_GetBand(infoPtr, iBand)->iRow != iRow)
             break;
         else
             iLastBand = iBand;
@@ -1146,9 +1165,9 @@ static int get_row_begin_for_band(const REBAR_INFO *infoPtr, INT iBand)
 /* Returns the first visible band for the next row (or infoPtr->uNumBands if none) */
 static int get_row_end_for_band(const REBAR_INFO *infoPtr, INT iBand)
 {
-    int iRow = infoPtr->bands[iBand].iRow;
+    int iRow = REBAR_GetBand(infoPtr, iBand)->iRow;
     while ((iBand = next_visible(infoPtr, iBand)) < infoPtr->uNumBands)
-        if (infoPtr->bands[iBand].iRow != iRow)
+        if (REBAR_GetBand(infoPtr, iBand)->iRow != iRow)
             break;
     return iBand;
 }
@@ -1160,9 +1179,9 @@ static void REBAR_SetRowRectsX(const REBAR_INFO *infoPtr, INT iBeginBand, INT iE
     int xPos = 0, i;
     for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
     {
-        REBAR_BAND *lpBand = &infoPtr->bands[i];
+        REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, i);
 
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
         if (lpBand->rcBand.left != xPos || lpBand->rcBand.right != xPos + lpBand->cxEffective) {
             lpBand->fDraw |= NTF_INVALIDATE;
             TRACE("Setting rect %d to %d,%d\n", i, xPos, xPos + lpBand->cxEffective);
@@ -1183,19 +1202,20 @@ static REBAR_BAND *REBAR_FindBandToGrow(const REBAR_INFO *infoPtr, INT iBeginBan
 {
     INT cxMinFirstBand = 0, i;
 
-    cxMinFirstBand = infoPtr->bands[iBeginBand].cxMinBand;
+    cxMinFirstBand = REBAR_GetBand(infoPtr, iBeginBand)->cxMinBand;
 
     for (i = prev_visible(infoPtr, iEndBand); i >= iBeginBand; i = prev_visible(infoPtr, i))
-        if (infoPtr->bands[i].cxEffective > cxMinFirstBand && !(infoPtr->bands[i].fStyle&RBBS_FIXEDSIZE))
+        if (REBAR_GetBand(infoPtr, i)->cxEffective > cxMinFirstBand &&
+          !(REBAR_GetBand(infoPtr, i)->fStyle & RBBS_FIXEDSIZE))
             break;
 
     if (i < iBeginBand)
         for (i = prev_visible(infoPtr, iEndBand); i >= iBeginBand; i = prev_visible(infoPtr, i))
-            if (infoPtr->bands[i].cxMinBand == cxMinFirstBand)
+            if (REBAR_GetBand(infoPtr, i)->cxMinBand == cxMinFirstBand)
                 break;
 
     TRACE("Extra space for row [%d..%d) should be added to band %d\n", iBeginBand, iEndBand, i);
-    return &infoPtr->bands[i];
+    return REBAR_GetBand(infoPtr, i);
 }
 
 /* Try to shrink the visible bands in [iBeginBand; iEndBand) by cxShrink, starting from the right */
@@ -1207,7 +1227,7 @@ static int REBAR_ShrinkBandsRTL(const REBAR_INFO *infoPtr, INT iBeginBand, INT i
     TRACE("Shrinking bands [%d..%d) by %d, right-to-left\n", iBeginBand, iEndBand, cxShrink);
     for (i = prev_visible(infoPtr, iEndBand); i >= iBeginBand; i = prev_visible(infoPtr, i))
     {
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
 
         width = max(lpBand->cxEffective - cxShrink, (int)lpBand->cxMinBand);
         cxShrink -= lpBand->cxEffective - width;
@@ -1231,7 +1251,7 @@ static int REBAR_ShrinkBandsLTR(const REBAR_INFO *infoPtr, INT iBeginBand, INT i
     TRACE("Shrinking bands [%d..%d) by %d, left-to-right\n", iBeginBand, iEndBand, cxShrink);
     for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
     {
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
 
         width = max(lpBand->cxEffective - cxShrink, (int)lpBand->cxMinBand);
         cxShrink -= lpBand->cxEffective - width;
@@ -1250,11 +1270,11 @@ static int REBAR_SetBandsHeight(const REBAR_INFO *infoPtr, INT iBeginBand, INT i
     REBAR_BAND *lpBand;
     int yMaxHeight = 0;
     int yPos = yStart;
-    int row = infoPtr->bands[iBeginBand].iRow;
+    int row = REBAR_GetBand(infoPtr, iBeginBand)->iRow;
     int i;
     for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
     {
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
         lpBand->cyRowSoFar = yMaxHeight;
         yMaxHeight = max(yMaxHeight, lpBand->cyMinBand);
     }
@@ -1262,7 +1282,7 @@ static int REBAR_SetBandsHeight(const REBAR_INFO *infoPtr, INT iBeginBand, INT i
 
     for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
     {
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
         /* we may be called for multiple rows if RBS_VARHEIGHT not set */
         if (lpBand->iRow != row) {
             yPos += yMaxHeight + SEP_WIDTH;
@@ -1288,12 +1308,12 @@ static void REBAR_LayoutRow(const REBAR_INFO *infoPtr, int iBeginBand, int iEndB
 
     TRACE("Adjusting row [%d;%d). Width: %d\n", iBeginBand, iEndBand, cx);
     for (i = iBeginBand; i < iEndBand; i++)
-        infoPtr->bands[i].iRow = *piRow;
+        REBAR_GetBand(infoPtr, i)->iRow = *piRow;
 
     /* compute the extra space */
     for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
     {
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
         if (i > iBeginBand)
             width += SEP_WIDTH;
         lpBand->cxEffective = max(lpBand->cxMinBand, lpBand->cx);
@@ -1356,7 +1376,7 @@ REBAR_Layout(REBAR_INFO *infoPtr)
     /* divide rows */
     for (i = rowstart; i < infoPtr->uNumBands; i = next_visible(infoPtr, i))
     {
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
 
         if (i > rowstart && (lpBand->fStyle & RBBS_BREAK || xMin + lpBand->cxMinBand > adjcx)) {
             TRACE("%s break on band %d\n", (lpBand->fStyle & RBBS_BREAK ? "Hard" : "Soft"), i - 1);
@@ -1369,7 +1389,8 @@ REBAR_Layout(REBAR_INFO *infoPtr)
 
         xMin += lpBand->cxMinBand;
     }
-    REBAR_LayoutRow(infoPtr, rowstart, infoPtr->uNumBands, adjcx, &row, &yPos);
+    if (rowstart < infoPtr->uNumBands)
+        REBAR_LayoutRow(infoPtr, rowstart, infoPtr->uNumBands, adjcx, &row, &yPos);
 
     if (!(infoPtr->dwStyle & RBS_VARHEIGHT))
         yPos = REBAR_SetBandsHeight(infoPtr, first_visible(infoPtr), infoPtr->uNumBands, 0);
@@ -1413,10 +1434,11 @@ REBAR_SizeChildrenToHeight(const REBAR_INFO *infoPtr, int iBeginBand, int iEndBa
 
     TRACE("[%d;%d) by %d\n", iBeginBand, iEndBand, extra);
 
-    cyBandsOld = infoPtr->bands[iBeginBand].rcBand.bottom - infoPtr->bands[iBeginBand].rcBand.top;
+    cyBandsOld = REBAR_GetBand(infoPtr, iBeginBand)->rcBand.bottom -
+                 REBAR_GetBand(infoPtr, iBeginBand)->rcBand.top;
     for (i = iBeginBand; i < iEndBand; i = next_visible(infoPtr, i))
     {
-        REBAR_BAND *lpBand = &infoPtr->bands[i];
+        REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, i);
         int cyMaxChild = cyBandsOld - REBARSPACE(lpBand) + extra;
         int cyChild = round_child_height(lpBand, cyMaxChild);
 
@@ -1452,7 +1474,7 @@ REBAR_SizeToHeight(REBAR_INFO *infoPtr, int height)
     {
         for (i = prev_visible(infoPtr, infoPtr->uNumBands); i > 0; i = prev_visible(infoPtr, i))
         {
-            REBAR_BAND *lpBand = &infoPtr->bands[i];
+            REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, i);
             int height = lpBand->rcBand.bottom - lpBand->rcBand.top;
             int cyBreakExtra;  /* additional cy for the rebar after a RBBS_BREAK on this band */
 
@@ -1488,13 +1510,14 @@ REBAR_SizeToHeight(REBAR_INFO *infoPtr, int height)
         int iRow = 0;
         while (i < infoPtr->uNumBands)
         {
-            REBAR_BAND *lpBand = &infoPtr->bands[i];
+            REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, i);
             int extraForRow = extra / (int)(uNumRows - iRow);
             int rowEnd;
 
             /* we can't use get_row_end_for_band as we might have added RBBS_BREAK in the first phase */
             for (rowEnd = next_visible(infoPtr, i); rowEnd < infoPtr->uNumBands; rowEnd = next_visible(infoPtr, rowEnd))
-                if (infoPtr->bands[rowEnd].iRow != lpBand->iRow || (infoPtr->bands[rowEnd].fStyle & RBBS_BREAK))
+                if (REBAR_GetBand(infoPtr, rowEnd)->iRow != lpBand->iRow ||
+                    REBAR_GetBand(infoPtr, rowEnd)->fStyle & RBBS_BREAK)
                     break;
 
             extra -= REBAR_SizeChildrenToHeight(infoPtr, i, rowEnd, extraForRow, &fChanged);
@@ -1572,7 +1595,7 @@ REBAR_ValidateBand (const REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
     /* count number of non-FIXEDSIZE and non-Hidden bands */
     nonfixed = 0;
     for (i=0; i<infoPtr->uNumBands; i++){
-       tBand = &infoPtr->bands[i];
+       tBand = REBAR_GetBand(infoPtr, i);
        if (!HIDDENBAND(tBand) && !(tBand->fStyle & RBBS_FIXEDSIZE))
            nonfixed++;
     }
@@ -1775,7 +1798,7 @@ REBAR_CommonSetupBand(HWND hwnd, const REBARBANDINFOW *lprbbi, REBAR_BAND *lpBan
 }
 
 static LRESULT
-REBAR_InternalEraseBkGnd (const REBAR_INFO *infoPtr, WPARAM wParam, const RECT *clip)
+REBAR_InternalEraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc, const RECT *clip)
      /* Function:  This erases the background rectangle by drawing  */
      /*  each band with its background color (or the default) and   */
      /*  draws each bands right separator if necessary. The row     */
@@ -1784,7 +1807,6 @@ REBAR_InternalEraseBkGnd (const REBAR_INFO *infoPtr, WPARAM wParam, const RECT *
     REBAR_BAND *lpBand;
     UINT i;
     INT oldrow;
-    HDC hdc = (HDC)wParam;
     RECT cr;
     COLORREF old = CLR_NONE, new;
     HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
@@ -1794,7 +1816,7 @@ REBAR_InternalEraseBkGnd (const REBAR_INFO *infoPtr, WPARAM wParam, const RECT *
     oldrow = -1;
     for(i=0; i<infoPtr->uNumBands; i++) {
         RECT rcBand;
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
        if (HIDDENBAND(lpBand)) continue;
         translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
 
@@ -1918,7 +1940,7 @@ REBAR_InternalHitTest (const REBAR_INFO *infoPtr, const POINT *lpPt, UINT *pFlag
            /* somewhere inside */
            for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
                 RECT rcBand;
-               lpBand = &infoPtr->bands[iCount];
+               lpBand = REBAR_GetBand(infoPtr, iCount);
                 translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
                 if (HIDDENBAND(lpBand)) continue;
                if (PtInRect (&rcBand, *lpPt)) {
@@ -2004,21 +2026,25 @@ REBAR_HandleLRDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
     iHitBand = infoPtr->iGrabbedBand;
     iRowBegin = get_row_begin_for_band(infoPtr, iHitBand);
     iRowEnd = get_row_end_for_band(infoPtr, iHitBand);
-    hitBand = &infoPtr->bands[iHitBand];
+    hitBand = REBAR_GetBand(infoPtr, iHitBand);
 
     xBand = hitBand->rcBand.left;
     movement = (infoPtr->dwStyle&CCS_VERT ? ptsmove->y : ptsmove->x)
                     - (xBand + REBAR_PRE_GRIPPER - infoPtr->ihitoffset);
 
     if (movement < 0) {
-        int cxLeft = REBAR_ShrinkBandsRTL(infoPtr, iRowBegin, iHitBand, -movement, TRUE);
+        INT cxLeft = REBAR_ShrinkBandsRTL(infoPtr, iRowBegin, iHitBand, -movement, TRUE);
         hitBand->cxEffective += -movement - cxLeft;
         hitBand->cx = hitBand->cxEffective;
     } else if (movement > 0) {
-        int cxLeft = REBAR_ShrinkBandsLTR(infoPtr, iHitBand, iRowEnd, movement, TRUE);
-        REBAR_BAND *lpPrev = &infoPtr->bands[prev_visible(infoPtr, iHitBand)];
-        lpPrev->cxEffective += movement - cxLeft;
-        lpPrev->cx = lpPrev->cxEffective;
+        INT prev;
+
+        if ((prev = prev_visible(infoPtr, iHitBand)) >= 0) {
+            INT cxLeft = REBAR_ShrinkBandsLTR(infoPtr, iHitBand, iRowEnd, movement, TRUE);
+            REBAR_BAND *lpPrev = REBAR_GetBand(infoPtr, prev_visible(infoPtr, iHitBand));
+            lpPrev->cxEffective += movement - cxLeft;
+            lpPrev->cx = lpPrev->cxEffective;
+        }
     }
 
     REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
@@ -2044,24 +2070,23 @@ REBAR_DeleteBand (REBAR_INFO *infoPtr, WPARAM wParam)
        return FALSE;
 
     TRACE("deleting band %u!\n", uBand);
-    lpBand = &infoPtr->bands[uBand];
+    lpBand = REBAR_GetBand(infoPtr, uBand);
     REBAR_Notify_NMREBAR (infoPtr, uBand, RBN_DELETINGBAND);
     /* TODO: a return of 1 should probably cancel the deletion */
 
     if (lpBand->hwndChild)
         ShowWindow(lpBand->hwndChild, SW_HIDE);
     Free(lpBand->lpText);
+    Free(lpBand);
 
     infoPtr->uNumBands--;
-    memmove(&infoPtr->bands[uBand], &infoPtr->bands[uBand+1],
-        (infoPtr->uNumBands - uBand) * sizeof(REBAR_BAND));
-    infoPtr->bands = ReAlloc(infoPtr->bands, infoPtr->uNumBands * sizeof(REBAR_BAND));
+    DPA_DeletePtr(infoPtr->bands, uBand);
 
     REBAR_Notify_NMREBAR (infoPtr, -1, RBN_DELETEDBAND);
 
     /* if only 1 band left the re-validate to possible eliminate gripper */
     if (infoPtr->uNumBands == 1)
-      REBAR_ValidateBand (infoPtr, &infoPtr->bands[0]);
+      REBAR_ValidateBand (infoPtr, REBAR_GetBand(infoPtr, 0));
 
     REBAR_Layout(infoPtr);
 
@@ -2074,17 +2099,16 @@ REBAR_DeleteBand (REBAR_INFO *infoPtr, WPARAM wParam)
 
 
 static LRESULT
-REBAR_GetBandBorders (const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+REBAR_GetBandBorders (const REBAR_INFO *infoPtr, UINT uBand, RECT *lpRect)
 {
-    LPRECT lpRect = (LPRECT)lParam;
     REBAR_BAND *lpBand;
 
-    if (!lParam)
+    if (!lpRect)
        return 0;
-    if ((UINT)wParam >= infoPtr->uNumBands)
+    if (uBand >= infoPtr->uNumBands)
        return 0;
 
-    lpBand = &infoPtr->bands[(UINT)wParam];
+    lpBand = REBAR_GetBand(infoPtr, uBand);
 
     /* FIXME - the following values were determined by experimentation */
     /* with the REBAR Control Spy. I have guesses as to what the 4 and */
@@ -2122,22 +2146,20 @@ REBAR_GetBandCount (const REBAR_INFO *infoPtr)
 
 
 static LRESULT
-REBAR_GetBandInfoT(const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
+REBAR_GetBandInfoT(const REBAR_INFO *infoPtr, UINT uIndex, LPREBARBANDINFOW lprbbi, BOOL bUnicode)
 {
-    LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
     REBAR_BAND *lpBand;
 
-    if (lprbbi == NULL)
-       return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
+    if (!lprbbi || lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
        return FALSE;
-    if ((UINT)wParam >= infoPtr->uNumBands)
+
+    if (uIndex >= infoPtr->uNumBands)
        return FALSE;
 
-    TRACE("index %u (bUnicode=%d)\n", (UINT)wParam, bUnicode);
+    TRACE("index %u (bUnicode=%d)\n", uIndex, bUnicode);
 
     /* copy band information */
-    lpBand = &infoPtr->bands[(UINT)wParam];
+    lpBand = REBAR_GetBand(infoPtr, uIndex);
 
     if (lprbbi->fMask & RBBIM_STYLE)
        lprbbi->fStyle = lpBand->fStyle;
@@ -2215,14 +2237,9 @@ REBAR_GetBarHeight (const REBAR_INFO *infoPtr)
 
 
 static LRESULT
-REBAR_GetBarInfo (const REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_GetBarInfo (const REBAR_INFO *infoPtr, LPREBARINFO lpInfo)
 {
-    LPREBARINFO lpInfo = (LPREBARINFO)lParam;
-
-    if (lpInfo == NULL)
-       return FALSE;
-
-    if (lpInfo->cbSize < sizeof (REBARINFO))
+    if (!lpInfo || lpInfo->cbSize < sizeof (REBARINFO))
        return FALSE;
 
     TRACE("getting bar info!\n");
@@ -2255,7 +2272,7 @@ REBAR_GetBkColor (const REBAR_INFO *infoPtr)
 
 
 static LRESULT
-REBAR_GetPalette (const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+REBAR_GetPalette (const REBAR_INFO *infoPtr)
 {
     FIXME("empty stub!\n");
 
@@ -2264,18 +2281,16 @@ REBAR_GetPalette (const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 
 
 static LRESULT
-REBAR_GetRect (const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+REBAR_GetRect (const REBAR_INFO *infoPtr, INT iBand, RECT *lprc)
 {
-    INT iBand = (INT)wParam;
-    LPRECT lprc = (LPRECT)lParam;
     REBAR_BAND *lpBand;
 
-    if ((iBand < 0) || ((UINT)iBand >= infoPtr->uNumBands))
+    if (iBand < 0 || iBand >= infoPtr->uNumBands)
        return FALSE;
     if (!lprc)
        return FALSE;
 
-    lpBand = &infoPtr->bands[iBand];
+    lpBand = REBAR_GetBand(infoPtr, iBand);
     /* For CCS_VERT the coordinates will be swapped - like on Windows */
     CopyRect (lprc, &lpBand->rcBand);
 
@@ -2295,15 +2310,14 @@ REBAR_GetRowCount (const REBAR_INFO *infoPtr)
 
 
 static LRESULT
-REBAR_GetRowHeight (const REBAR_INFO *infoPtr, WPARAM wParam)
+REBAR_GetRowHeight (const REBAR_INFO *infoPtr, INT iRow)
 {
-    INT iRow = (INT)wParam;
     int j = 0, ret = 0;
     UINT i;
     REBAR_BAND *lpBand;
 
     for (i=0; i<infoPtr->uNumBands; i++) {
-       lpBand = &infoPtr->bands[i];
+       lpBand = REBAR_GetBand(infoPtr, i);
        if (HIDDENBAND(lpBand)) continue;
        if (lpBand->iRow != iRow) continue;
         j = lpBand->rcBand.bottom - lpBand->rcBand.top;
@@ -2351,10 +2365,8 @@ REBAR_GetVersion (const REBAR_INFO *infoPtr)
 
 
 static LRESULT
-REBAR_HitTest (const REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_HitTest (const REBAR_INFO *infoPtr, LPRBHITTESTINFO lprbht)
 {
-    LPRBHITTESTINFO lprbht = (LPRBHITTESTINFO)lParam;
-
     if (!lprbht)
        return -1;
 
@@ -2365,60 +2377,55 @@ REBAR_HitTest (const REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static LRESULT
-REBAR_IdToIndex (const REBAR_INFO *infoPtr, WPARAM wParam)
+REBAR_IdToIndex (const REBAR_INFO *infoPtr, UINT uId)
 {
     UINT i;
 
-    if (infoPtr == NULL)
-       return -1;
-
     if (infoPtr->uNumBands < 1)
        return -1;
 
     for (i = 0; i < infoPtr->uNumBands; i++) {
-       if (infoPtr->bands[i].wID == (UINT)wParam) {
-           TRACE("id %u is band %u found!\n", (UINT)wParam, i);
+       if (REBAR_GetBand(infoPtr, i)->wID == uId) {
+           TRACE("id %u is band %u found!\n", uId, i);
            return i;
        }
     }
 
-    TRACE("id %u is not found\n", (UINT)wParam);
+    TRACE("id %u is not found\n", uId);
     return -1;
 }
 
 
 static LRESULT
-REBAR_InsertBandT(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
+REBAR_InsertBandT(REBAR_INFO *infoPtr, INT iIndex, LPREBARBANDINFOW lprbbi, BOOL bUnicode)
 {
-    LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
-    UINT uIndex = (UINT)wParam;
     REBAR_BAND *lpBand;
 
-    if (infoPtr == NULL)
-       return FALSE;
-    if (lprbbi == NULL)
-       return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
+    if (!lprbbi || lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
        return FALSE;
 
     /* trace the index as signed to see the -1 */
-    TRACE("insert band at %d (bUnicode=%d)!\n", (INT)uIndex, bUnicode);
+    TRACE("insert band at %d (bUnicode=%d)!\n", iIndex, bUnicode);
     REBAR_DumpBandInfo(lprbbi);
 
-    infoPtr->bands = ReAlloc(infoPtr->bands, (infoPtr->uNumBands+1) * sizeof(REBAR_BAND));
-    if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
-        uIndex = infoPtr->uNumBands;
-    memmove(&infoPtr->bands[uIndex+1], &infoPtr->bands[uIndex],
-        sizeof(REBAR_BAND) * (infoPtr->uNumBands - uIndex));
+    if (!(lpBand = Alloc(sizeof(REBAR_BAND)))) return FALSE;
+    if ((iIndex == -1) || (iIndex > infoPtr->uNumBands))
+        iIndex = infoPtr->uNumBands;
+    if (DPA_InsertPtr(infoPtr->bands, iIndex, lpBand) == -1)
+    {
+        Free(lpBand);
+        return FALSE;
+    }
     infoPtr->uNumBands++;
 
-    TRACE("index %u!\n", uIndex);
+    TRACE("index %d!\n", iIndex);
 
-    /* initialize band (infoPtr->bands[uIndex])*/
-    lpBand = &infoPtr->bands[uIndex];
-    ZeroMemory(lpBand, sizeof(*lpBand));
-    lpBand->clrFore = infoPtr->clrText;
-    lpBand->clrBack = infoPtr->clrBk;
+    /* initialize band */
+    memset(lpBand, 0, sizeof(*lpBand));
+    lpBand->clrFore = infoPtr->clrText == CLR_NONE ? infoPtr->clrBtnText :
+                                                     infoPtr->clrText;
+    lpBand->clrBack = infoPtr->clrBk == CLR_NONE ? infoPtr->clrBtnFace :
+                                                   infoPtr->clrBk;
     lpBand->iImage = -1;
 
     REBAR_CommonSetupBand(infoPtr->hwndSelf, lprbbi, lpBand);
@@ -2440,7 +2447,7 @@ REBAR_InsertBandT(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnico
     REBAR_ValidateBand (infoPtr, lpBand);
     /* On insert of second band, revalidate band 1 to possible add gripper */
     if (infoPtr->uNumBands == 2)
-       REBAR_ValidateBand (infoPtr, &infoPtr->bands[0]);
+       REBAR_ValidateBand (infoPtr, REBAR_GetBand(infoPtr, 0));
 
     REBAR_DumpBand (infoPtr);
 
@@ -2452,29 +2459,27 @@ REBAR_InsertBandT(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnico
 
 
 static LRESULT
-REBAR_MaximizeBand (const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+REBAR_MaximizeBand (const REBAR_INFO *infoPtr, INT iBand, LPARAM lParam)
 {
     REBAR_BAND *lpBand;
-    UINT uBand = (UINT) wParam;
     int iRowBegin, iRowEnd;
     int cxDesired, extra, extraOrig;
     int cxIdealBand;
 
     /* Validate */
-    if ((infoPtr->uNumBands == 0) ||
-       ((INT)uBand < 0) || (uBand >= infoPtr->uNumBands)) {
+    if (infoPtr->uNumBands == 0 || iBand < 0 || iBand >= infoPtr->uNumBands) {
        /* error !!! */
        ERR("Illegal MaximizeBand, requested=%d, current band count=%d\n",
-             (INT)uBand, infoPtr->uNumBands);
+             iBand, infoPtr->uNumBands);
        return FALSE;
     }
 
-    lpBand = &infoPtr->bands[uBand];
+    lpBand = REBAR_GetBand(infoPtr, iBand);
 
     if (lpBand->fStyle & RBBS_HIDDEN)
     {
         /* Windows is buggy and creates a hole */
-        WARN("Ignoring maximize request on a hidden band (%d)\n", uBand);
+        WARN("Ignoring maximize request on a hidden band (%d)\n", iBand);
         return FALSE;
     }
 
@@ -2484,16 +2489,16 @@ REBAR_MaximizeBand (const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
     else
         cxDesired = infoPtr->calcSize.cx;
 
-    iRowBegin = get_row_begin_for_band(infoPtr, uBand);
-    iRowEnd   = get_row_end_for_band(infoPtr, uBand);
+    iRowBegin = get_row_begin_for_band(infoPtr, iBand);
+    iRowEnd   = get_row_end_for_band(infoPtr, iBand);
     extraOrig = extra = cxDesired - lpBand->cxEffective;
     if (extra > 0)
-        extra = REBAR_ShrinkBandsRTL(infoPtr, iRowBegin, uBand, extra, TRUE);
+        extra = REBAR_ShrinkBandsRTL(infoPtr, iRowBegin, iBand, extra, TRUE);
     if (extra > 0)
-        extra = REBAR_ShrinkBandsLTR(infoPtr, next_visible(infoPtr, uBand), iRowEnd, extra, TRUE);
+        extra = REBAR_ShrinkBandsLTR(infoPtr, next_visible(infoPtr, iBand), iRowEnd, extra, TRUE);
     lpBand->cxEffective += extraOrig - extra;
     lpBand->cx = lpBand->cxEffective;
-    TRACE("(%ld, %ld): Wanted size %d, obtained %d (shrink %d, %d)\n", wParam, lParam, cxDesired, lpBand->cx, extraOrig, extra);
+    TRACE("(%d, %ld): Wanted size %d, obtained %d (shrink %d, %d)\n", iBand, lParam, cxDesired, lpBand->cx, extraOrig, extra);
     REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
 
     if (infoPtr->dwStyle & CCS_VERT)
@@ -2507,10 +2512,9 @@ REBAR_MaximizeBand (const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 
 
 static LRESULT
-REBAR_MinimizeBand (const REBAR_INFO *infoPtr, WPARAM wParam)
+REBAR_MinimizeBand (const REBAR_INFO *infoPtr, INT iBand)
 {
     REBAR_BAND *lpBand;
-    UINT uBand = (UINT) wParam;
     int iPrev, iRowBegin, iRowEnd;
 
     /* A "minimize" band is equivalent to "dragging" the gripper
@@ -2519,43 +2523,42 @@ REBAR_MinimizeBand (const REBAR_INFO *infoPtr, WPARAM wParam)
      */
 
     /* Validate */
-    if ((infoPtr->uNumBands == 0) ||
-       ((INT)uBand < 0) || (uBand >= infoPtr->uNumBands)) {
+    if (infoPtr->uNumBands == 0 || iBand < 0 || iBand >= infoPtr->uNumBands) {
        /* error !!! */
        ERR("Illegal MinimizeBand, requested=%d, current band count=%d\n",
-             (INT)uBand, infoPtr->uNumBands);
+             iBand, infoPtr->uNumBands);
        return FALSE;
     }
 
     /* compute amount of movement and validate */
-    lpBand = &infoPtr->bands[uBand];
+    lpBand = REBAR_GetBand(infoPtr, iBand);
 
     if (lpBand->fStyle & RBBS_HIDDEN)
     {
         /* Windows is buggy and creates a hole/overlap */
-        WARN("Ignoring minimize request on a hidden band (%d)\n", uBand);
+        WARN("Ignoring minimize request on a hidden band (%d)\n", iBand);
         return FALSE;
     }
 
-    iPrev = prev_visible(infoPtr, uBand);
+    iPrev = prev_visible(infoPtr, iBand);
     /* if first band in row */
-    if (iPrev < 0 || infoPtr->bands[iPrev].iRow != lpBand->iRow) {
-        int iNext = next_visible(infoPtr, uBand);
-        if (iNext < infoPtr->uNumBands && infoPtr->bands[iNext].iRow == lpBand->iRow) {
-            TRACE("(%ld): Minimizing the first band in row is by maximizing the second\n", wParam);
+    if (iPrev < 0 || REBAR_GetBand(infoPtr, iPrev)->iRow != lpBand->iRow) {
+        int iNext = next_visible(infoPtr, iBand);
+        if (iNext < infoPtr->uNumBands && REBAR_GetBand(infoPtr, iNext)->iRow == lpBand->iRow) {
+            TRACE("(%d): Minimizing the first band in row is by maximizing the second\n", iBand);
             REBAR_MaximizeBand(infoPtr, iNext, FALSE);
         }
         else
-            TRACE("(%ld): Only one band in row - nothing to do\n", wParam);
+            TRACE("(%d): Only one band in row - nothing to do\n", iBand);
         return TRUE;
     }
 
-    infoPtr->bands[iPrev].cxEffective += lpBand->cxEffective - lpBand->cxMinBand;
-    infoPtr->bands[iPrev].cx = infoPtr->bands[iPrev].cxEffective;
+    REBAR_GetBand(infoPtr, iPrev)->cxEffective += lpBand->cxEffective - lpBand->cxMinBand;
+    REBAR_GetBand(infoPtr, iPrev)->cx = REBAR_GetBand(infoPtr, iPrev)->cxEffective;
     lpBand->cx = lpBand->cxEffective = lpBand->cxMinBand;
 
-    iRowBegin = get_row_begin_for_band(infoPtr, uBand);
-    iRowEnd = get_row_end_for_band(infoPtr, uBand);
+    iRowBegin = get_row_begin_for_band(infoPtr, iBand);
+    iRowEnd = get_row_end_for_band(infoPtr, iBand);
     REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
 
     if (infoPtr->dwStyle & CCS_VERT)
@@ -2568,53 +2571,25 @@ REBAR_MinimizeBand (const REBAR_INFO *infoPtr, WPARAM wParam)
 
 
 static LRESULT
-REBAR_MoveBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+REBAR_MoveBand (REBAR_INFO *infoPtr, INT iFrom, INT iTo)
 {
-    REBAR_BAND *oldBands = infoPtr->bands;
-    REBAR_BAND holder;
-    UINT uFrom = (UINT)wParam;
-    UINT uTo = (UINT)lParam;
+    REBAR_BAND *lpBand;
 
     /* Validate */
     if ((infoPtr->uNumBands == 0) ||
-       ((INT)uFrom < 0) || (uFrom >= infoPtr->uNumBands) ||
-       ((INT)uTo < 0)   || (uTo >= infoPtr->uNumBands)) {
+       (iFrom < 0) || iFrom >= infoPtr->uNumBands ||
+       (iTo < 0)   || iTo >= infoPtr->uNumBands) {
        /* error !!! */
        ERR("Illegal MoveBand, from=%d, to=%d, current band count=%d\n",
-             (INT)uFrom, (INT)uTo, infoPtr->uNumBands);
+             iFrom, iTo, infoPtr->uNumBands);
        return FALSE;
     }
 
-    /* save one to be moved */
-    holder = oldBands[uFrom];
-
-    /* close up rest of bands (pseudo delete) */
-    if (uFrom < infoPtr->uNumBands - 1) {
-       memcpy (&oldBands[uFrom], &oldBands[uFrom+1],
-               (infoPtr->uNumBands - uFrom - 1) * sizeof(REBAR_BAND));
-    }
-
-    /* allocate new space and copy rest of bands into it */
-    infoPtr->bands = Alloc ((infoPtr->uNumBands)*sizeof(REBAR_BAND));
-
-    /* pre insert copy */
-    if (uTo > 0) {
-       memcpy (&infoPtr->bands[0], &oldBands[0],
-               uTo * sizeof(REBAR_BAND));
-    }
-
-    /* set moved band */
-    infoPtr->bands[uTo] = holder;
+    lpBand = REBAR_GetBand(infoPtr, iFrom);
+    DPA_DeletePtr(infoPtr->bands, iFrom);
+    DPA_InsertPtr(infoPtr->bands, iTo, lpBand);
 
-    /* post copy */
-    if (uTo < infoPtr->uNumBands - 1) {
-       memcpy (&infoPtr->bands[uTo+1], &oldBands[uTo],
-               (infoPtr->uNumBands - uTo - 1) * sizeof(REBAR_BAND));
-    }
-
-    Free (oldBands);
-
-    TRACE("moved band %d to index %d\n", uFrom, uTo);
+    TRACE("moved band %d to index %d\n", iFrom, iTo);
     REBAR_DumpBand (infoPtr);
 
     /* **************************************************** */
@@ -2638,24 +2613,22 @@ REBAR_strdifW( LPCWSTR a, LPCWSTR b )
 }
 
 static LRESULT
-REBAR_SetBandInfoT(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
+REBAR_SetBandInfoT(REBAR_INFO *infoPtr, INT iBand, LPREBARBANDINFOW lprbbi, BOOL bUnicode)
 {
-    LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
     REBAR_BAND *lpBand;
     UINT uChanged;
 
-    if (lprbbi == NULL)
-       return FALSE;
-    if (lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
+    if (!lprbbi || lprbbi->cbSize < REBARBANDINFOA_V3_SIZE)
        return FALSE;
-    if ((UINT)wParam >= infoPtr->uNumBands)
+
+    if (iBand >= infoPtr->uNumBands)
        return FALSE;
 
-    TRACE("index %u\n", (UINT)wParam);
+    TRACE("index %d\n", iBand);
     REBAR_DumpBandInfo (lprbbi);
 
     /* set band information */
-    lpBand = &infoPtr->bands[(UINT)wParam];
+    lpBand = REBAR_GetBand(infoPtr, iBand);
 
     uChanged = REBAR_CommonSetupBand (infoPtr->hwndSelf, lprbbi, lpBand);
     if (lprbbi->fMask & RBBIM_TEXT) {
@@ -2688,16 +2661,12 @@ REBAR_SetBandInfoT(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnic
 
 
 static LRESULT
-REBAR_SetBarInfo (REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_SetBarInfo (REBAR_INFO *infoPtr, LPREBARINFO lpInfo)
 {
-    LPREBARINFO lpInfo = (LPREBARINFO)lParam;
     REBAR_BAND *lpBand;
     UINT i;
 
-    if (lpInfo == NULL)
-       return FALSE;
-
-    if (lpInfo->cbSize < sizeof (REBARINFO))
+    if (!lpInfo || lpInfo->cbSize < sizeof (REBARINFO))
        return FALSE;
 
     TRACE("setting bar info!\n");
@@ -2720,7 +2689,7 @@ REBAR_SetBarInfo (REBAR_INFO *infoPtr, LPARAM lParam)
 
     /* revalidate all bands to reset flags for images in headers of bands */
     for (i=0; i<infoPtr->uNumBands; i++) {
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
        REBAR_ValidateBand (infoPtr, lpBand);
     }
 
@@ -2729,12 +2698,12 @@ REBAR_SetBarInfo (REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static LRESULT
-REBAR_SetBkColor (REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_SetBkColor (REBAR_INFO *infoPtr, COLORREF clr)
 {
     COLORREF clrTemp;
 
     clrTemp = infoPtr->clrBk;
-    infoPtr->clrBk = (COLORREF)lParam;
+    infoPtr->clrBk = clr;
 
     TRACE("background color 0x%06x!\n", infoPtr->clrBk);
 
@@ -2747,23 +2716,23 @@ REBAR_SetBkColor (REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static LRESULT
-REBAR_SetParent (REBAR_INFO *infoPtr, WPARAM wParam)
+REBAR_SetParent (REBAR_INFO *infoPtr, HWND parent)
 {
     HWND hwndTemp = infoPtr->hwndNotify;
 
-    infoPtr->hwndNotify = (HWND)wParam;
+    infoPtr->hwndNotify = parent;
 
     return (LRESULT)hwndTemp;
 }
 
 
 static LRESULT
-REBAR_SetTextColor (REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_SetTextColor (REBAR_INFO *infoPtr, COLORREF clr)
 {
     COLORREF clrTemp;
 
     clrTemp = infoPtr->clrText;
-    infoPtr->clrText = (COLORREF)lParam;
+    infoPtr->clrText = clr;
 
     TRACE("text color 0x%06x!\n", infoPtr->clrText);
 
@@ -2775,15 +2744,15 @@ REBAR_SetTextColor (REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static inline LRESULT
-REBAR_SetUnicodeFormat (REBAR_INFO *infoPtr, WPARAM wParam)
+REBAR_SetUnicodeFormat (REBAR_INFO *infoPtr, BOOL unicode)
 {
     BOOL bTemp = infoPtr->bUnicode;
 
     TRACE("to %s hwnd=%p, was %s\n",
-         ((BOOL)wParam) ? "TRUE" : "FALSE", infoPtr->hwndSelf,
+          unicode ? "TRUE" : "FALSE", infoPtr->hwndSelf,
          (bTemp) ? "TRUE" : "FALSE");
 
-    infoPtr->bUnicode = (BOOL)wParam;
+    infoPtr->bUnicode = unicode;
 
    return bTemp;
 }
@@ -2806,23 +2775,23 @@ REBAR_SetVersion (REBAR_INFO *infoPtr, INT iVersion)
 
 
 static LRESULT
-REBAR_ShowBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+REBAR_ShowBand (REBAR_INFO *infoPtr, INT iBand, BOOL show)
 {
     REBAR_BAND *lpBand;
 
-    if (((INT)wParam < 0) || ((INT)wParam > infoPtr->uNumBands))
+    if (iBand < 0 || iBand > infoPtr->uNumBands)
        return FALSE;
 
-    lpBand = &infoPtr->bands[(INT)wParam];
+    lpBand = REBAR_GetBand(infoPtr, iBand);
 
-    if ((BOOL)lParam) {
-       TRACE("show band %d\n", (INT)wParam);
+    if (show) {
+       TRACE("show band %d\n", iBand);
        lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN;
        if (IsWindow (lpBand->hwndChild))
            ShowWindow (lpBand->hwndChild, SW_SHOW);
     }
     else {
-       TRACE("hide band %d\n", (INT)wParam);
+       TRACE("hide band %d\n", iBand);
        lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN;
        if (IsWindow (lpBand->hwndChild))
            ShowWindow (lpBand->hwndChild, SW_HIDE);
@@ -2836,12 +2805,9 @@ REBAR_ShowBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 
 
 static LRESULT
-REBAR_SizeToRect (REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_SizeToRect (REBAR_INFO *infoPtr, const RECT *lpRect)
 {
-    LPRECT lpRect = (LPRECT)lParam;
-
-    if (lpRect == NULL)
-       return FALSE;
+    if (!lpRect) return FALSE;
 
     TRACE("[%s]\n", wine_dbgstr_rect(lpRect));
     REBAR_SizeToHeight(infoPtr, get_rect_cy(infoPtr, lpRect));
@@ -2851,9 +2817,8 @@ REBAR_SizeToRect (REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static LRESULT
-REBAR_Create (REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_Create (REBAR_INFO *infoPtr, LPCREATESTRUCTW cs)
 {
-    LPCREATESTRUCTW cs = (LPCREATESTRUCTW) lParam;
     RECT wnrc1, clrc1;
 
     if (TRACE_ON(rebar)) {
@@ -2871,7 +2836,7 @@ REBAR_Create (REBAR_INFO *infoPtr, LPARAM lParam)
         /* native seems to clear WS_BORDER when themed */
         infoPtr->dwStyle &= ~WS_BORDER;
     }
-    
+
     return 0;
 }
 
@@ -2882,30 +2847,27 @@ REBAR_Destroy (REBAR_INFO *infoPtr)
     REBAR_BAND *lpBand;
     UINT i;
 
+    /* clean up each band */
+    for (i = 0; i < infoPtr->uNumBands; i++) {
+       lpBand = REBAR_GetBand(infoPtr, i);
 
-    /* free rebar bands */
-    if ((infoPtr->uNumBands > 0) && infoPtr->bands) {
-       /* clean up each band */
-       for (i = 0; i < infoPtr->uNumBands; i++) {
-           lpBand = &infoPtr->bands[i];
-
-           /* delete text strings */
-            Free (lpBand->lpText);
-            lpBand->lpText = NULL;
-           /* destroy child window */
-           DestroyWindow (lpBand->hwndChild);
-       }
-
-       /* free band array */
-       Free (infoPtr->bands);
-       infoPtr->bands = NULL;
+       /* delete text strings */
+        Free (lpBand->lpText);
+       lpBand->lpText = NULL;
+       /* destroy child window */
+       DestroyWindow (lpBand->hwndChild);
+       Free (lpBand);
     }
 
+    /* free band array */
+    DPA_Destroy (infoPtr->bands);
+    infoPtr->bands = NULL;
+
     DestroyCursor (infoPtr->hcurArrow);
     DestroyCursor (infoPtr->hcurHorz);
     DestroyCursor (infoPtr->hcurVert);
     DestroyCursor (infoPtr->hcurDrag);
-    if(infoPtr->hDefaultFont) DeleteObject (infoPtr->hDefaultFont);
+    if (infoPtr->hDefaultFont) DeleteObject (infoPtr->hDefaultFont);
     SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0);
     
     CloseThemeData (GetWindowTheme (infoPtr->hwndSelf));
@@ -2918,12 +2880,12 @@ REBAR_Destroy (REBAR_INFO *infoPtr)
 
 
 static LRESULT
-REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, WPARAM wParam)
+REBAR_EraseBkGnd (const REBAR_INFO *infoPtr, HDC hdc)
 {
     RECT cliprect;
 
-    if (GetClipBox ( (HDC)wParam, &cliprect))
-        return REBAR_InternalEraseBkGnd (infoPtr, wParam, &cliprect);
+    if (GetClipBox ( hdc, &cliprect))
+        return REBAR_InternalEraseBkGnd (infoPtr, hdc, &cliprect);
     return 0;
 }
 
@@ -2935,14 +2897,14 @@ REBAR_GetFont (const REBAR_INFO *infoPtr)
 }
 
 static LRESULT
-REBAR_PushChevron(const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+REBAR_PushChevron(const REBAR_INFO *infoPtr, UINT uBand, LPARAM lParam)
 {
-    if ((UINT)wParam < infoPtr->uNumBands)
+    if (uBand < infoPtr->uNumBands)
     {
         NMREBARCHEVRON nmrbc;
-        REBAR_BAND *lpBand = &infoPtr->bands[wParam];
+        REBAR_BAND *lpBand = REBAR_GetBand(infoPtr, uBand);
 
-        TRACE("Pressed chevron on band %ld\n", wParam);
+        TRACE("Pressed chevron on band %u\n", uBand);
 
         /* redraw chevron in pushed state */
         lpBand->fDraw |= DRAW_CHEVRONPUSHED;
@@ -2950,7 +2912,7 @@ REBAR_PushChevron(const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
           RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
 
         /* notify app so it can display a popup menu or whatever */
-        nmrbc.uBand = wParam;
+        nmrbc.uBand = uBand;
         nmrbc.wID = lpBand->wID;
         nmrbc.lParam = lpBand->lParam;
         nmrbc.rc = lpBand->rcChevron;
@@ -2969,7 +2931,6 @@ REBAR_PushChevron(const REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 static LRESULT
 REBAR_LButtonDown (REBAR_INFO *infoPtr, LPARAM lParam)
 {
-    REBAR_BAND *lpBand;
     UINT htFlags;
     INT iHitBand;
     POINT ptMouseDown;
@@ -2977,7 +2938,6 @@ REBAR_LButtonDown (REBAR_INFO *infoPtr, LPARAM lParam)
     ptMouseDown.y = (short)HIWORD(lParam);
 
     REBAR_InternalHitTest(infoPtr, &ptMouseDown, &htFlags, &iHitBand);
-    lpBand = &infoPtr->bands[iHitBand];
 
     if (htFlags == RBHT_CHEVRON)
     {
@@ -2985,8 +2945,12 @@ REBAR_LButtonDown (REBAR_INFO *infoPtr, LPARAM lParam)
     }
     else if (htFlags == RBHT_GRABBER || htFlags == RBHT_CAPTION)
     {
+        REBAR_BAND *lpBand;
+
         TRACE("Starting drag\n");
 
+        lpBand = REBAR_GetBand(infoPtr, iHitBand);
+
         SetCapture (infoPtr->hwndSelf);
         infoPtr->iGrabbedBand = iHitBand;
 
@@ -3036,7 +3000,7 @@ REBAR_MouseLeave (REBAR_INFO *infoPtr)
 {
     if (infoPtr->ichevronhotBand >= 0)
     {
-        REBAR_BAND *lpChevronBand = &infoPtr->bands[infoPtr->ichevronhotBand];
+        REBAR_BAND *lpChevronBand = REBAR_GetBand(infoPtr, infoPtr->ichevronhotBand);
         if (lpChevronBand->fDraw & DRAW_CHEVRONHOT)
         {
             lpChevronBand->fDraw &= ~DRAW_CHEVRONHOT;
@@ -3061,14 +3025,15 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, LPARAM lParam)
     /* if we are currently dragging a band */
     if (infoPtr->iGrabbedBand >= 0)
     {
-        REBAR_BAND *band1, *band2;
+        REBAR_BAND *band1 = NULL, *band2;
         int yPtMove = (infoPtr->dwStyle & CCS_VERT ? ptMove.x : ptMove.y);
 
         if (GetCapture() != infoPtr->hwndSelf)
             ERR("We are dragging but haven't got capture?!?\n");
 
-        band1 = &infoPtr->bands[infoPtr->iGrabbedBand-1];
-        band2 = &infoPtr->bands[infoPtr->iGrabbedBand];
+        if (infoPtr->iGrabbedBand > 0)
+            band1 = REBAR_GetBand(infoPtr, infoPtr->iGrabbedBand - 1);
+        band2 = REBAR_GetBand(infoPtr, infoPtr->iGrabbedBand);
 
         /* if mouse did not move much, exit */
         if ((abs(ptMove.x - infoPtr->dragNow.x) <= mindragx) &&
@@ -3094,7 +3059,7 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, LPARAM lParam)
 
         if (infoPtr->iOldBand >= 0 && infoPtr->iOldBand == infoPtr->ichevronhotBand)
         {
-            lpChevronBand = &infoPtr->bands[infoPtr->ichevronhotBand];
+            lpChevronBand = REBAR_GetBand(infoPtr, infoPtr->ichevronhotBand);
             if (lpChevronBand->fDraw & DRAW_CHEVRONHOT)
             {
                 lpChevronBand->fDraw &= ~DRAW_CHEVRONHOT;
@@ -3124,7 +3089,7 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, LPARAM lParam)
                 _TrackMouseEvent(&trackinfo);
             }
 
-            lpChevronBand = &infoPtr->bands[iHitBand];
+            lpChevronBand = REBAR_GetBand(infoPtr, iHitBand);
             if (!(lpChevronBand->fDraw & DRAW_CHEVRONHOT))
             {
                 lpChevronBand->fDraw |= DRAW_CHEVRONHOT;
@@ -3140,10 +3105,9 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static inline LRESULT
-REBAR_NCCalcSize (const REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_NCCalcSize (const REBAR_INFO *infoPtr, RECT *rect)
 {
     HTHEME theme;
-    RECT *rect = (RECT *)lParam;
 
     if (infoPtr->dwStyle & WS_BORDER) {
         rect->left   = min(rect->left + GetSystemMetrics(SM_CXEDGE), rect->right);
@@ -3162,15 +3126,14 @@ REBAR_NCCalcSize (const REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static LRESULT
-REBAR_NCCreate (HWND hwnd, LPARAM lParam)
+REBAR_NCCreate (HWND hwnd, LPCREATESTRUCTW cs)
 {
-    LPCREATESTRUCTW cs = (LPCREATESTRUCTW) lParam;
     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
     RECT wnrc1, clrc1;
     NONCLIENTMETRICSW ncm;
     HFONT tfont;
 
-    if (infoPtr != NULL) {
+    if (infoPtr) {
        ERR("Strange info structure pointer *not* NULL\n");
        return FALSE;
     }
@@ -3203,6 +3166,7 @@ REBAR_NCCreate (HWND hwnd, LPARAM lParam)
     infoPtr->hcurDrag  = LoadCursorW (0, (LPWSTR)IDC_SIZE);
     infoPtr->fStatus = 0;
     infoPtr->hFont = GetStockObject (SYSTEM_FONT);
+    infoPtr->bands = DPA_Create(8);
 
     /* issue WM_NOTIFYFORMAT to get unicode status of parent */
     REBAR_NotifyFormat(infoPtr, NF_REQUERY);
@@ -3327,11 +3291,11 @@ REBAR_NCPaint (const REBAR_INFO *infoPtr)
 
 
 static LRESULT
-REBAR_NotifyFormat (REBAR_INFO *infoPtr, LPARAM lParam)
+REBAR_NotifyFormat (REBAR_INFO *infoPtr, LPARAM cmd)
 {
     INT i;
 
-    if (lParam == NF_REQUERY) {
+    if (cmd == NF_REQUERY) {
        i = SendMessageW(REBAR_GetNotifyParent (infoPtr),
                         WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY);
         if ((i != NFR_ANSI) && (i != NFR_UNICODE)) {
@@ -3346,10 +3310,8 @@ REBAR_NotifyFormat (REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static LRESULT
-REBAR_Paint (const REBAR_INFO *infoPtr, WPARAM wParam)
+REBAR_Paint (const REBAR_INFO *infoPtr, HDC hdc)
 {
-    HDC hdc = (HDC)wParam;
-
     if (hdc) {
         TRACE("painting\n");
         REBAR_Refresh (infoPtr, hdc);
@@ -3359,7 +3321,7 @@ REBAR_Paint (const REBAR_INFO *infoPtr, WPARAM wParam)
         TRACE("painting (%s)\n", wine_dbgstr_rect(&ps.rcPaint));
         if (ps.fErase) {
             /* Erase area of paint if requested */
-            REBAR_InternalEraseBkGnd (infoPtr, wParam, &ps.rcPaint);
+            REBAR_InternalEraseBkGnd (infoPtr, hdc, &ps.rcPaint);
         }
         REBAR_Refresh (infoPtr, hdc);
        EndPaint (infoPtr->hwndSelf, &ps);
@@ -3397,16 +3359,16 @@ REBAR_SetCursor (const REBAR_INFO *infoPtr, LPARAM lParam)
 
 
 static LRESULT
-REBAR_SetFont (REBAR_INFO *infoPtr, WPARAM wParam)
+REBAR_SetFont (REBAR_INFO *infoPtr, HFONT font)
 {
     REBAR_BAND *lpBand;
     UINT i;
 
-    infoPtr->hFont = (HFONT)wParam;
+    infoPtr->hFont = font;
 
     /* revalidate all bands to change sizes of text in headers of bands */
     for (i=0; i<infoPtr->uNumBands; i++) {
-        lpBand = &infoPtr->bands[i];
+        lpBand = REBAR_GetBand(infoPtr, i);
        REBAR_ValidateBand (infoPtr, lpBand);
     }
 
@@ -3415,26 +3377,25 @@ REBAR_SetFont (REBAR_INFO *infoPtr, WPARAM wParam)
 }
 
 
+/*****************************************************
+ *
+ *  Handles the WM_SETREDRAW message.
+ *
+ * Documentation:
+ *  According to testing V4.71 of COMCTL32 returns the
+ *  *previous* status of the redraw flag (either 0 or -1)
+ *  instead of the MSDN documented value of 0 if handled
+ *
+ *****************************************************/
 static inline LRESULT
-REBAR_SetRedraw (REBAR_INFO *infoPtr, WPARAM wParam)
-     /*****************************************************
-      *
-      * Function;
-      *  Handles the WM_SETREDRAW message.
-      *
-      * Documentation:
-      *  According to testing V4.71 of COMCTL32 returns the
-      *  *previous* status of the redraw flag (either 0 or -1)
-      *  instead of the MSDN documented value of 0 if handled
-      *
-      *****************************************************/
+REBAR_SetRedraw (REBAR_INFO *infoPtr, BOOL redraw)
 {
     BOOL oldredraw = infoPtr->DoRedraw;
 
     TRACE("set to %s, fStatus=%08x\n",
-         (wParam) ? "TRUE" : "FALSE", infoPtr->fStatus);
-    infoPtr->DoRedraw = (BOOL) wParam;
-    if (wParam) {
+         (redraw) ? "TRUE" : "FALSE", infoPtr->fStatus);
+    infoPtr->DoRedraw = redraw;
+    if (redraw) {
        if (infoPtr->fStatus & BAND_NEEDS_REDRAW) {
            REBAR_MoveChildWindows (infoPtr, 0, infoPtr->uNumBands);
            REBAR_ForceResize (infoPtr);
@@ -3532,23 +3493,21 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 /*     case RB_ENDDRAG: */
 
        case RB_GETBANDBORDERS:
-           return REBAR_GetBandBorders (infoPtr, wParam, lParam);
+           return REBAR_GetBandBorders (infoPtr, wParam, (LPRECT)lParam);
 
        case RB_GETBANDCOUNT:
            return REBAR_GetBandCount (infoPtr);
 
        case RB_GETBANDINFO_OLD:
        case RB_GETBANDINFOA:
-           return REBAR_GetBandInfoT(infoPtr, wParam, lParam, FALSE);
-
        case RB_GETBANDINFOW:
-           return REBAR_GetBandInfoT(infoPtr, wParam, lParam, TRUE);
-
+           return REBAR_GetBandInfoT(infoPtr, wParam, (LPREBARBANDINFOW)lParam,
+                                                       uMsg == RB_GETBANDINFOW);
        case RB_GETBARHEIGHT:
            return REBAR_GetBarHeight (infoPtr);
 
        case RB_GETBARINFO:
-           return REBAR_GetBarInfo (infoPtr, lParam);
+           return REBAR_GetBarInfo (infoPtr, (LPREBARINFO)lParam);
 
        case RB_GETBKCOLOR:
            return REBAR_GetBkColor (infoPtr);
@@ -3557,10 +3516,10 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 /*     case RB_GETDROPTARGET: */
 
        case RB_GETPALETTE:
-           return REBAR_GetPalette (infoPtr, wParam, lParam);
+           return REBAR_GetPalette (infoPtr);
 
        case RB_GETRECT:
-           return REBAR_GetRect (infoPtr, wParam, lParam);
+           return REBAR_GetRect (infoPtr, wParam, (LPRECT)lParam);
 
        case RB_GETROWCOUNT:
            return REBAR_GetRowCount (infoPtr);
@@ -3581,17 +3540,15 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return REBAR_GetVersion (infoPtr);
 
        case RB_HITTEST:
-           return REBAR_HitTest (infoPtr, lParam);
+           return REBAR_HitTest (infoPtr, (LPRBHITTESTINFO)lParam);
 
        case RB_IDTOINDEX:
            return REBAR_IdToIndex (infoPtr, wParam);
 
        case RB_INSERTBANDA:
-           return REBAR_InsertBandT(infoPtr, wParam, lParam, FALSE);
-
        case RB_INSERTBANDW:
-           return REBAR_InsertBandT(infoPtr, wParam, lParam, TRUE);
-
+           return REBAR_InsertBandT(infoPtr, wParam, (LPREBARBANDINFOW)lParam,
+                                                      uMsg == RB_INSERTBANDW);
        case RB_MAXIMIZEBAND:
            return REBAR_MaximizeBand (infoPtr, wParam, lParam);
 
@@ -3605,23 +3562,20 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return REBAR_PushChevron (infoPtr, wParam, lParam);
 
        case RB_SETBANDINFOA:
-           return REBAR_SetBandInfoT(infoPtr, wParam, lParam, FALSE);
-
        case RB_SETBANDINFOW:
-           return REBAR_SetBandInfoT(infoPtr, wParam, lParam, TRUE);
-
+           return REBAR_SetBandInfoT(infoPtr, wParam, (LPREBARBANDINFOW)lParam,
+                                                       uMsg == RB_SETBANDINFOW);
        case RB_SETBARINFO:
-           return REBAR_SetBarInfo (infoPtr, lParam);
+           return REBAR_SetBarInfo (infoPtr, (LPREBARINFO)lParam);
 
        case RB_SETBKCOLOR:
            return REBAR_SetBkColor (infoPtr, lParam);
 
 /*     case RB_SETCOLORSCHEME: */
 /*     case RB_SETPALETTE: */
-/*         return REBAR_GetPalette (infoPtr, wParam, lParam); */
 
        case RB_SETPARENT:
-           return REBAR_SetParent (infoPtr, wParam);
+           return REBAR_SetParent (infoPtr, (HWND)wParam);
 
        case RB_SETTEXTCOLOR:
            return REBAR_SetTextColor (infoPtr, lParam);
@@ -3638,7 +3592,7 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return REBAR_ShowBand (infoPtr, wParam, lParam);
 
        case RB_SIZETORECT:
-           return REBAR_SizeToRect (infoPtr, lParam);
+           return REBAR_SizeToRect (infoPtr, (LPCRECT)lParam);
 
 
 /*    Messages passed to parent */
@@ -3651,13 +3605,13 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 /*      case WM_CHARTOITEM:     supported according to ControlSpy */
 
        case WM_CREATE:
-           return REBAR_Create (infoPtr, lParam);
+           return REBAR_Create (infoPtr, (LPCREATESTRUCTW)lParam);
 
        case WM_DESTROY:
            return REBAR_Destroy (infoPtr);
 
         case WM_ERASEBKGND:
-           return REBAR_EraseBkGnd (infoPtr, wParam);
+           return REBAR_EraseBkGnd (infoPtr, (HDC)wParam);
 
        case WM_GETFONT:
            return REBAR_GetFont (infoPtr);
@@ -3679,10 +3633,10 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return REBAR_MouseLeave (infoPtr);
 
        case WM_NCCALCSIZE:
-           return REBAR_NCCalcSize (infoPtr, lParam);
+           return REBAR_NCCalcSize (infoPtr, (RECT*)lParam);
 
         case WM_NCCREATE:
-           return REBAR_NCCreate (hwnd, lParam);
+           return REBAR_NCCreate (hwnd, (LPCREATESTRUCTW)lParam);
 
         case WM_NCHITTEST:
            return REBAR_NCHitTest (infoPtr, lParam);
@@ -3695,7 +3649,7 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
        case WM_PRINTCLIENT:
        case WM_PAINT:
-           return REBAR_Paint (infoPtr, wParam);
+           return REBAR_Paint (infoPtr, (HDC)wParam);
 
 /*      case WM_PALETTECHANGED: supported according to ControlSpy */
 /*      case WM_QUERYNEWPALETTE:supported according to ControlSpy */
@@ -3706,7 +3660,7 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return REBAR_SetCursor (infoPtr, lParam);
 
        case WM_SETFONT:
-           return REBAR_SetFont (infoPtr, wParam);
+           return REBAR_SetFont (infoPtr, (HFONT)wParam);
 
         case WM_SETREDRAW:
            return REBAR_SetRedraw (infoPtr, wParam);
index d6b627a..1b69ef2 100644 (file)
@@ -233,7 +233,7 @@ STATUSBAR_DrawPart (const STATUS_INFO *infoPtr, HDC hdc, const STATUSWINDOWPART
        dis.hDC = hdc;
        dis.rcItem = r;
        dis.itemData = (ULONG_PTR)part->text;
-       SendMessageW (infoPtr->Notify, WM_DRAWITEM, (WPARAM)dis.CtlID, (LPARAM)&dis);
+       SendMessageW (infoPtr->Notify, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
     } else {
        if (part->hIcon) {
           INT cy = r.bottom - r.top;
@@ -728,7 +728,7 @@ STATUSBAR_SetParts (STATUS_INFO *infoPtr, INT count, LPINT parts)
 
 static BOOL
 STATUSBAR_SetTextT (STATUS_INFO *infoPtr, INT nPart, WORD style,
-                   LPCWSTR text, BOOL isW)
+                   LPWSTR text, BOOL isW)
 {
     STATUSWINDOWPART *part=NULL;
     BOOL changed = FALSE;
@@ -759,7 +759,7 @@ STATUSBAR_SetTextT (STATUS_INFO *infoPtr, INT nPart, WORD style,
     if (style & SBT_OWNERDRAW) {
         if (!(oldStyle & SBT_OWNERDRAW))
             Free (part->text);
-        part->text = (LPWSTR)text;
+        part->text = text;
     } else {
        LPWSTR ntext;
        WCHAR  *idx;
@@ -1162,7 +1162,7 @@ STATUSBAR_NotifyFormat (STATUS_INFO *infoPtr, HWND from, INT cmd)
 
 
 static LRESULT
-STATUSBAR_SendMouseNotify(const STATUS_INFO *infoPtr, UINT code, LPARAM lParam)
+STATUSBAR_SendMouseNotify(const STATUS_INFO *infoPtr, UINT code, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     NMMOUSE  nm;
 
@@ -1175,7 +1175,12 @@ STATUSBAR_SendMouseNotify(const STATUS_INFO *infoPtr, UINT code, LPARAM lParam)
     nm.dwItemSpec = STATUSBAR_InternalHitTest(infoPtr, &nm.pt);
     nm.dwItemData = 0;
     nm.dwHitInfo = 0x30000;     /* seems constant */
-    SendMessageW(infoPtr->Notify, WM_NOTIFY, 0, (LPARAM)&nm);
+
+    /* Do default processing if WM_NOTIFY returns zero */
+    if(!SendMessageW(infoPtr->Notify, WM_NOTIFY, nm.hdr.idFrom, (LPARAM)&nm))
+    {
+      return DefWindowProcW(infoPtr->Self, msg, wParam, lParam);
+    }
     return 0;
 }
 
@@ -1243,10 +1248,10 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
            return STATUSBAR_SetParts (infoPtr, (INT)wParam, (LPINT)lParam);
 
        case SB_SETTEXTA:
-           return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPCWSTR)lParam, FALSE);
+           return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPWSTR)lParam, FALSE);
 
        case SB_SETTEXTW:
-           return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPCWSTR)lParam, TRUE);
+           return STATUSBAR_SetTextT (infoPtr, nPart, wParam & 0xff00, (LPWSTR)lParam, TRUE);
 
        case SB_SETTIPTEXTA:
            return STATUSBAR_SetTipTextA (infoPtr, (INT)wParam, (LPSTR)lParam);
@@ -1276,10 +1281,10 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
            return STATUSBAR_GetTextLength (infoPtr, 0);
 
        case WM_LBUTTONDBLCLK:
-            return STATUSBAR_SendMouseNotify(infoPtr, NM_DBLCLK, lParam);
+            return STATUSBAR_SendMouseNotify(infoPtr, NM_DBLCLK, msg, wParam, lParam);
 
        case WM_LBUTTONUP:
-           return STATUSBAR_SendMouseNotify(infoPtr, NM_CLICK, lParam);
+           return STATUSBAR_SendMouseNotify(infoPtr, NM_CLICK, msg, wParam, lParam);
 
        case WM_MOUSEMOVE:
            return STATUSBAR_Relay2Tip (infoPtr, msg, wParam, lParam);
@@ -1303,10 +1308,10 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
            return STATUSBAR_WMPaint (infoPtr, (HDC)wParam);
 
        case WM_RBUTTONDBLCLK:
-           return STATUSBAR_SendMouseNotify(infoPtr, NM_RDBLCLK, lParam);
+           return STATUSBAR_SendMouseNotify(infoPtr, NM_RDBLCLK, msg, wParam, lParam);
 
        case WM_RBUTTONUP:
-           return STATUSBAR_SendMouseNotify(infoPtr, NM_RCLICK, lParam);
+           return STATUSBAR_SendMouseNotify(infoPtr, NM_RCLICK, msg, wParam, lParam);
 
        case WM_SETFONT:
            return STATUSBAR_WMSetFont (infoPtr, (HFONT)wParam, LOWORD(lParam));
index f6dbd8c..7fead7c 100644 (file)
@@ -235,7 +235,7 @@ INT WINAPI Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
  */
 BOOL WINAPI Str_SetPtrW (LPWSTR *lppDest, LPCWSTR lpSrc)
 {
-    TRACE("(%p %p)\n", lppDest, lpSrc);
+    TRACE("(%p %s)\n", lppDest, debugstr_w(lpSrc));
 
     if (lpSrc) {
         INT len = strlenW (lpSrc) + 1;
index f361779..9340fc6 100644 (file)
@@ -39,7 +39,7 @@
 #include "wine/unicode.h"
 #include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(progress);
+WINE_DEFAULT_DEBUG_CHANNEL(syslink);
 
 INT WINAPI StrCmpNIW(LPCWSTR,LPCWSTR,INT);
 
@@ -94,7 +94,9 @@ typedef struct
     COLORREF  TextColor;    /* Color of the text */
     COLORREF  LinkColor;    /* Color of links */
     COLORREF  VisitedColor; /* Color of visited links */
+    COLORREF  BackColor;    /* Background color, set on creation */
     WCHAR     BreakChar;    /* Break Character for the current font */
+    BOOL      IgnoreReturn; /* (infoPtr->Style & LWS_IGNORERETURN) on creation */
 } SYSLINK_INFO;
 
 static const WCHAR SL_LINKOPEN[] =  { '<','a', 0 };
@@ -196,6 +198,8 @@ static UINT SYSLINK_ParseText (SYSLINK_INFO *infoPtr, LPCWSTR Text)
     LPCWSTR lpID, lpUrl;
     UINT lenId, lenUrl;
 
+    TRACE("(%p %s)\n", infoPtr, debugstr_w(Text));
+
     for(current = Text; *current != 0;)
     {
         if(*current == '<')
@@ -831,7 +835,7 @@ static LRESULT SYSLINK_Draw (const SYSLINK_INFO *infoPtr, HDC hdc)
 
     hOldFont = SelectObject(hdc, infoPtr->Font);
     OldTextColor = SetTextColor(hdc, infoPtr->TextColor);
-    OldBkColor = SetBkColor(hdc, comctl32_color.clrBtnFace);
+    OldBkColor = SetBkColor(hdc, infoPtr->BackColor);
     
     GetClientRect(infoPtr->Self, &rc);
     rc.right -= SL_RIGHTMARGIN + SL_LEFTMARGIN;
@@ -906,6 +910,22 @@ static LRESULT SYSLINK_Paint (const SYSLINK_INFO *infoPtr, HDC hdcParam)
     return 0;
 }
 
+/***********************************************************************
+ * SYSLINK_EraseBkgnd
+ * Handles the WM_ERASEBKGND message.
+ */
+static LRESULT SYSLINK_EraseBkgnd (const SYSLINK_INFO *infoPtr, HDC hdc)
+{
+   HBRUSH hbr;
+   RECT r;
+
+   GetClientRect(infoPtr->Self, &r);
+   hbr = CreateSolidBrush(infoPtr->BackColor);
+   FillRect(hdc, &r, hbr);
+   DeleteObject(hbr);
+
+   return 1;
+}
 
 /***********************************************************************
  *           SYSLINK_SetFont
@@ -1434,13 +1454,13 @@ static LRESULT SYSLINK_LButtonUp (SYSLINK_INFO *infoPtr, const POINT *pt)
  */
 static BOOL SYSLINK_OnEnter (const SYSLINK_INFO *infoPtr)
 {
-    if(infoPtr->HasFocus)
+    if(infoPtr->HasFocus && !infoPtr->IgnoreReturn)
     {
         PDOC_ITEM Focus;
         int id;
         
         Focus = SYSLINK_GetFocusLink(infoPtr, &id);
-        if(Focus != NULL)
+        if(Focus)
         {
             SYSLINK_SendParentNotify(infoPtr, NM_RETURN, Focus, id);
             return TRUE;
@@ -1551,6 +1571,9 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
     case WM_PAINT:
         return SYSLINK_Paint (infoPtr, (HDC)wParam);
 
+    case WM_ERASEBKGND:
+        return SYSLINK_EraseBkgnd(infoPtr, (HDC)wParam);
+
     case WM_SETCURSOR:
     {
         LHITTESTINFO ht;
@@ -1730,7 +1753,10 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
         infoPtr->TextColor = comctl32_color.clrWindowText;
         infoPtr->LinkColor = comctl32_color.clrHighlight;
         infoPtr->VisitedColor = comctl32_color.clrHighlight;
+        infoPtr->BackColor = infoPtr->Style & LWS_TRANSPARENT ?
+                             comctl32_color.clrWindow : comctl32_color.clrBtnFace;
         infoPtr->BreakChar = ' ';
+        infoPtr->IgnoreReturn = infoPtr->Style & LWS_IGNORERETURN;
         TRACE("SysLink Ctrl creation, hwnd=%p\n", hwnd);
         SYSLINK_SetText(infoPtr, ((LPCREATESTRUCTW)lParam)->lpszName);
         return 0;
@@ -1746,6 +1772,8 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
 
     case WM_SYSCOLORCHANGE:
         COMCTL32_RefreshSysColors();
+        if (infoPtr->Style & LWS_TRANSPARENT)
+            infoPtr->BackColor = comctl32_color.clrWindow;
         return 0;
 
     default:
index 94da29e..c99153e 100644 (file)
@@ -46,7 +46,6 @@
  *   NM_RELEASEDCAPTURE
  *   TCN_FOCUSCHANGE
  *   TCN_GETOBJECT
- *   TCN_KEYDOWN
  *
  *  Macros:
  *   TabCtrl_AdjustRect
@@ -120,6 +119,7 @@ typedef struct
 
   DWORD      exStyle;         /* Extended style used, currently:
                                  TCS_EX_FLATSEPARATORS, TCS_EX_REGISTERDROP */
+  DWORD      dwStyle;         /* the cached window GWL_STYLE */
 } TAB_INFO;
 
 /******************************************************************************
@@ -160,6 +160,7 @@ 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)
@@ -220,6 +221,7 @@ TAB_DumpItemInternal(const TAB_INFO *infoPtr, UINT iItem)
  *   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;
 }
 
@@ -228,12 +230,13 @@ static inline LRESULT TAB_GetCurSel (const TAB_INFO *infoPtr)
 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)
 {
-    if (infoPtr == NULL) return 0;
+    TRACE("(%p)\n", infoPtr);
     return (LRESULT)infoPtr->hwndToolTip;
 }
 
@@ -241,17 +244,20 @@ static inline LRESULT TAB_SetCurSel (TAB_INFO *infoPtr, INT iItem)
 {
   INT prevItem = infoPtr->iSelected;
 
+  TRACE("(%p %d)\n", infoPtr, iItem);
+
   if (iItem < 0)
-      infoPtr->iSelected=-1;
+      infoPtr->iSelected = -1;
   else if (iItem >= infoPtr->uNumItem)
       return -1;
   else {
-      if (infoPtr->iSelected != iItem) {
-          TAB_GetItem(infoPtr, prevItem)->dwState &= ~TCIS_BUTTONPRESSED;
+      if (prevItem != iItem) {
+          if (prevItem != -1)
+              TAB_GetItem(infoPtr, prevItem)->dwState &= ~TCIS_BUTTONPRESSED;
           TAB_GetItem(infoPtr, iItem)->dwState |= TCIS_BUTTONPRESSED;
 
-          infoPtr->iSelected=iItem;
-          infoPtr->uFocus=iItem;
+          infoPtr->iSelected = iItem;
+          infoPtr->uFocus = iItem;
           TAB_EnsureSelectionVisible(infoPtr);
           TAB_InvalidateTabArea(infoPtr);
       }
@@ -261,13 +267,37 @@ static inline LRESULT TAB_SetCurSel (TAB_INFO *infoPtr, INT iItem)
 
 static LRESULT TAB_SetCurFocus (TAB_INFO *infoPtr, INT iItem)
 {
-  if (iItem < 0)
+  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 (GetWindowLongW(infoPtr->hwnd, GWL_STYLE) & TCS_BUTTONS) {
-      FIXME("Should set input focus\n");
+    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;
+      INT oldFocus = infoPtr->uFocus;
       if (infoPtr->iSelected != iItem || oldFocus == -1 ) {
         infoPtr->uFocus = iItem;
         if (oldFocus != -1) {
@@ -289,19 +319,18 @@ static LRESULT TAB_SetCurFocus (TAB_INFO *infoPtr, INT iItem)
 static inline LRESULT
 TAB_SetToolTips (TAB_INFO *infoPtr, HWND hwndToolTip)
 {
-    if (infoPtr)
-        infoPtr->hwndToolTip = hwndToolTip;
+    TRACE("%p %p\n", infoPtr, hwndToolTip);
+    infoPtr->hwndToolTip = hwndToolTip;
     return 0;
 }
 
 static inline LRESULT
 TAB_SetPadding (TAB_INFO *infoPtr, LPARAM lParam)
 {
-    if (infoPtr)
-    {
-        infoPtr->uHItemPadding_s=LOWORD(lParam);
-        infoPtr->uVItemPadding_s=HIWORD(lParam);
-    }
+    TRACE("(%p %d %d)\n", infoPtr, LOWORD(lParam), HIWORD(lParam));
+    infoPtr->uHItemPadding_s = LOWORD(lParam);
+    infoPtr->uVItemPadding_s = HIWORD(lParam);
+
     return 0;
 }
 
@@ -321,12 +350,12 @@ static BOOL TAB_InternalGetItemRect(
   RECT*       selectedRect)
 {
   RECT tmpItemRect,clientRect;
-  LONG lStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
 
   /* Perform a sanity check and a trivial visibility check. */
   if ( (infoPtr->uNumItem <= 0) ||
        (itemIndex >= infoPtr->uNumItem) ||
-       (!((lStyle & TCS_MULTILINE) || (lStyle & TCS_VERTICAL)) && (itemIndex < infoPtr->leftmostVisible)) )
+       (!(((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL))) &&
+         (itemIndex < infoPtr->leftmostVisible)))
     {
         TRACE("Not Visible\n");
         /* need to initialize these to empty rects */
@@ -353,28 +382,28 @@ static BOOL TAB_InternalGetItemRect(
   /* calculate the times bottom and top based on the row */
   GetClientRect(infoPtr->hwnd, &clientRect);
 
-  if ((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
+  if ((infoPtr->dwStyle & TCS_BOTTOM) && (infoPtr->dwStyle & TCS_VERTICAL))
   {
     itemRect->right  = clientRect.right - SELECTED_TAB_OFFSET - itemRect->left * infoPtr->tabHeight -
-                       ((lStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGX : 0);
+                       ((infoPtr->dwStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGX : 0);
     itemRect->left   = itemRect->right - infoPtr->tabHeight;
   }
-  else if (lStyle & TCS_VERTICAL)
+  else if (infoPtr->dwStyle & TCS_VERTICAL)
   {
     itemRect->left   = clientRect.left + SELECTED_TAB_OFFSET + itemRect->left * infoPtr->tabHeight +
-                       ((lStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGX : 0);
+                       ((infoPtr->dwStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGX : 0);
     itemRect->right  = itemRect->left + infoPtr->tabHeight;
   }
-  else if (lStyle & TCS_BOTTOM)
+  else if (infoPtr->dwStyle & TCS_BOTTOM)
   {
     itemRect->bottom = clientRect.bottom - itemRect->top * infoPtr->tabHeight -
-                       ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
+                       ((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 +
-                       ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
+                       ((infoPtr->dwStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
     itemRect->bottom = itemRect->top + infoPtr->tabHeight;
  }
 
@@ -382,7 +411,7 @@ static BOOL TAB_InternalGetItemRect(
    * "scroll" it to make sure the item at the very left of the
    * tab control is the leftmost visible tab.
    */
-  if(lStyle & TCS_VERTICAL)
+  if(infoPtr->dwStyle & TCS_VERTICAL)
   {
     OffsetRect(itemRect,
             0,
@@ -419,23 +448,23 @@ static BOOL TAB_InternalGetItemRect(
     CopyRect(selectedRect, itemRect);
 
     /* The rectangle of a selected item is a bit wider. */
-    if(lStyle & TCS_VERTICAL)
+    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 ((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
+    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 (lStyle & TCS_VERTICAL)
+    else if (infoPtr->dwStyle & TCS_VERTICAL)
     {
       selectedRect->left   -= SELECTED_TAB_OFFSET;
       selectedRect->right  += 1;
     }
-    else if (lStyle & TCS_BOTTOM)
+    else if (infoPtr->dwStyle & TCS_BOTTOM)
     {
       selectedRect->bottom += SELECTED_TAB_OFFSET;
     }
@@ -447,26 +476,36 @@ static BOOL TAB_InternalGetItemRect(
   }
 
   /* Check for visibility */
-  if (lStyle & TCS_VERTICAL)
+  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, WPARAM wParam, LPARAM lParam)
+TAB_GetItemRect(const TAB_INFO *infoPtr, INT item, RECT *rect)
 {
-  return TAB_InternalGetItemRect(infoPtr, wParam, (LPRECT)lParam, NULL);
+  TRACE("(%p, %d, %p)\n", infoPtr, item, rect);
+  return TAB_InternalGetItemRect(infoPtr, item, rect, NULL);
 }
 
 /******************************************************************************
- * TAB_KeyUp
+ * TAB_KeyDown
  *
  * This method is called to handle keyboard input
  */
-static LRESULT TAB_KeyUp(TAB_INFO* infoPtr, WPARAM keyCode)
+static LRESULT TAB_KeyDown(TAB_INFO* infoPtr, WPARAM keyCode, LPARAM lParam)
 {
-  int       newItem = -1;
+  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)
   {
@@ -478,23 +517,30 @@ static LRESULT TAB_KeyUp(TAB_INFO* infoPtr, WPARAM keyCode)
       break;
   }
 
-  /*
-   * If we changed to a valid item, change the selection
-   */
-  if (newItem >= 0 &&
-      newItem < infoPtr->uNumItem &&
-      infoPtr->uFocus != newItem)
-  {
-    if (!TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGING))
-    {
-      TAB_SetCurSel(infoPtr, newItem);
-      TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGE);
-    }
-  }
+  /* 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
  *
@@ -548,6 +594,7 @@ static INT TAB_InternalHitTest (const TAB_INFO *infoPtr, POINT pt, UINT *flags)
 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);
 }
 
@@ -585,13 +632,12 @@ TAB_LButtonDown (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
   POINT pt;
   INT newItem;
   UINT dummy;
-  LONG lStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
 
   if (infoPtr->hwndToolTip)
     TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
                    WM_LBUTTONDOWN, wParam, lParam);
 
-  if (GetWindowLongW(infoPtr->hwnd, GWL_STYLE) & TCS_FOCUSONBUTTONDOWN ) {
+  if (!(infoPtr->dwStyle & TCS_FOCUSNEVER)) {
     SetFocus (infoPtr->hwnd);
   }
 
@@ -608,7 +654,7 @@ TAB_LButtonDown (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 
   if ((newItem != -1) && (infoPtr->iSelected != newItem))
   {
-    if ((lStyle & TCS_BUTTONS) && (lStyle & TCS_MULTISELECT) &&
+    if ((infoPtr->dwStyle & TCS_BUTTONS) && (infoPtr->dwStyle & TCS_MULTISELECT) &&
         (wParam & MK_CONTROL))
     {
       RECT r;
@@ -782,8 +828,7 @@ TAB_RecalcHotTrack
   if (out_redrawEnter != NULL)
     *out_redrawEnter = -1;
 
-  if ((GetWindowLongW(infoPtr->hwnd, GWL_STYLE) & TCS_HOTTRACK)
-      || GetWindowTheme (infoPtr->hwnd))
+  if ((infoPtr->dwStyle & TCS_HOTTRACK) || GetWindowTheme(infoPtr->hwnd))
   {
     POINT pt;
     UINT  flags;
@@ -875,7 +920,6 @@ TAB_MouseMove (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
  */
 static LRESULT TAB_AdjustRect(const TAB_INFO *infoPtr, WPARAM fLarger, LPRECT prc)
 {
-    DWORD lStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
     LONG *iRightBottom, *iLeftTop;
 
     TRACE ("hwnd=%p fLarger=%ld (%s)\n", infoPtr->hwnd, fLarger,
@@ -883,7 +927,7 @@ static LRESULT TAB_AdjustRect(const TAB_INFO *infoPtr, WPARAM fLarger, LPRECT pr
 
     if (!prc) return -1;
 
-    if(lStyle & TCS_VERTICAL)
+    if(infoPtr->dwStyle & TCS_VERTICAL)
     {
        iRightBottom = &(prc->right);
        iLeftTop     = &(prc->left);
@@ -897,11 +941,11 @@ static LRESULT TAB_AdjustRect(const TAB_INFO *infoPtr, WPARAM fLarger, LPRECT pr
     if (fLarger) /* Go from display rectangle */
     {
         /* Add the height of the tabs. */
-       if (lStyle & TCS_BOTTOM)
+       if (infoPtr->dwStyle & TCS_BOTTOM)
            *iRightBottom += infoPtr->tabHeight * infoPtr->uNumRows;
        else
            *iLeftTop -= infoPtr->tabHeight * infoPtr->uNumRows +
-                        ((lStyle & TCS_BUTTONS)? 3 * (infoPtr->uNumRows - 1) : 0);
+                        ((infoPtr->dwStyle & TCS_BUTTONS)? 3 * (infoPtr->uNumRows - 1) : 0);
 
        /* Inflate the rectangle for the padding */
        InflateRect(prc, DISPLAY_AREA_PADDINGX, DISPLAY_AREA_PADDINGY); 
@@ -918,11 +962,11 @@ static LRESULT TAB_AdjustRect(const TAB_INFO *infoPtr, WPARAM fLarger, LPRECT pr
        InflateRect(prc, -DISPLAY_AREA_PADDINGX, -DISPLAY_AREA_PADDINGY);
 
        /* Remove the height of the tabs. */
-       if (lStyle & TCS_BOTTOM)
+       if (infoPtr->dwStyle & TCS_BOTTOM)
            *iRightBottom -= infoPtr->tabHeight * infoPtr->uNumRows;
        else
            *iLeftTop += (infoPtr->tabHeight) * infoPtr->uNumRows +
-                        ((lStyle & TCS_BUTTONS)? 3 * (infoPtr->uNumRows - 1) : 0);
+                        ((infoPtr->dwStyle & TCS_BUTTONS)? 3 * (infoPtr->uNumRows - 1) : 0);
     }
 
   return 0;
@@ -959,14 +1003,11 @@ static LRESULT TAB_OnHScroll(TAB_INFO *infoPtr, int nScrollCode, int nPos)
  * scrolling control is displayed (or not).
  */
 static void TAB_SetupScrolling(
-  HWND        hwnd,
   TAB_INFO*   infoPtr,
   const RECT* clientRect)
 {
-  static const WCHAR msctls_updown32W[] = { 'm','s','c','t','l','s','_','u','p','d','o','w','n','3','2',0 };
   static const WCHAR emptyW[] = { 0 };
   INT maxRange = 0;
-  DWORD lStyle = GetWindowLongW(hwnd, GWL_STYLE);
 
   if (infoPtr->needsScrolling)
   {
@@ -976,12 +1017,12 @@ static void TAB_SetupScrolling(
     /*
      * Calculate the position of the scroll control.
      */
-    if(lStyle & TCS_VERTICAL)
+    if(infoPtr->dwStyle & TCS_VERTICAL)
     {
       controlPos.right = clientRect->right;
       controlPos.left  = controlPos.right - 2 * GetSystemMetrics(SM_CXHSCROLL);
 
-      if (lStyle & TCS_BOTTOM)
+      if (infoPtr->dwStyle & TCS_BOTTOM)
       {
         controlPos.top    = clientRect->bottom - infoPtr->tabHeight;
         controlPos.bottom = controlPos.top + GetSystemMetrics(SM_CYHSCROLL);
@@ -997,7 +1038,7 @@ static void TAB_SetupScrolling(
       controlPos.right = clientRect->right;
       controlPos.left  = controlPos.right - 2 * GetSystemMetrics(SM_CXHSCROLL);
 
-      if (lStyle & TCS_BOTTOM)
+      if (infoPtr->dwStyle & TCS_BOTTOM)
       {
         controlPos.top    = clientRect->bottom - infoPtr->tabHeight;
         controlPos.bottom = controlPos.top + GetSystemMetrics(SM_CYHSCROLL);
@@ -1015,12 +1056,12 @@ static void TAB_SetupScrolling(
      */
     if (infoPtr->hwndUpDown==0)
     {
-      infoPtr->hwndUpDown = CreateWindowW(msctls_updown32W, emptyW,
+      infoPtr->hwndUpDown = CreateWindowW(UPDOWN_CLASSW, emptyW,
                                          WS_VISIBLE | WS_CHILD | UDS_HORZ,
                                          controlPos.left, controlPos.top,
                                          controlPos.right - controlPos.left,
                                          controlPos.bottom - controlPos.top,
-                                         hwnd, NULL, NULL, NULL);
+                                         infoPtr->hwnd, NULL, NULL, NULL);
     }
     else
     {
@@ -1055,7 +1096,7 @@ static void TAB_SetupScrolling(
   else
   {
     /* If we once had a scroll control... hide it */
-    if (infoPtr->hwndUpDown!=0)
+    if (infoPtr->hwndUpDown)
       ShowWindow(infoPtr->hwndUpDown, SW_HIDE);
   }
   if (infoPtr->hwndUpDown)
@@ -1074,7 +1115,6 @@ static void TAB_SetupScrolling(
  */
 static void TAB_SetItemBounds (TAB_INFO *infoPtr)
 {
-  LONG        lStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
   TEXTMETRICW fontMetrics;
   UINT        curItem;
   INT         curItemLeftPos;
@@ -1105,7 +1145,7 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
   /* 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(lStyle & TCS_VERTICAL)
+  if(infoPtr->dwStyle & TCS_VERTICAL)
   {
      iTemp = clientRect.bottom;
      clientRect.bottom = clientRect.right;
@@ -1143,7 +1183,7 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
      * selected item + extra space for the selected item.
      */
     infoPtr->tabHeight = item_height + 
-                        ((lStyle & TCS_BUTTONS) ? 2 : 1) *
+                        ((infoPtr->dwStyle & TCS_BUTTONS) ? 2 : 1) *
                           infoPtr->uVItemPadding;
 
     TRACE("tabH=%d, tmH=%d, iconh=%d\n",
@@ -1157,7 +1197,7 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
   {
     ImageList_GetIconSize(infoPtr->himl, &icon_width, 0);
 
-    if (lStyle & TCS_FIXEDWIDTH)
+    if (infoPtr->dwStyle & TCS_FIXEDWIDTH)
       icon_width += 4;
     else
       /* Add padding if icon is present */
@@ -1171,7 +1211,7 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
     /* Set the leftmost position of the tab. */
     curr->rect.left = curItemLeftPos;
 
-    if (lStyle & TCS_FIXEDWIDTH)
+    if (infoPtr->dwStyle & TCS_FIXEDWIDTH)
     {
       curr->rect.right = curr->rect.left +
         max(infoPtr->tabWidth, icon_width);
@@ -1219,7 +1259,7 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
      *
      */
 
-    if (((lStyle & TCS_MULTILINE) || (lStyle & TCS_VERTICAL)) &&
+    if (((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL)) &&
         (curr->rect.right > 
        (clientRect.right - CONTROL_BORDER_SIZEX - DISPLAY_AREA_PADDINGX)))
     {
@@ -1240,17 +1280,17 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
      * The leftmost position of the next item is the rightmost position
      * of this one.
      */
-    if (lStyle & TCS_BUTTONS)
+    if (infoPtr->dwStyle & TCS_BUTTONS)
     {
       curItemLeftPos = curr->rect.right + BUTTON_SPACINGX;
-      if (lStyle & TCS_FLATBUTTONS)
+      if (infoPtr->dwStyle & TCS_FLATBUTTONS)
         curItemLeftPos += FLAT_BTN_SPACINGX;
     }
     else
       curItemLeftPos = curr->rect.right;
   }
 
-  if (!((lStyle & TCS_MULTILINE) || (lStyle & TCS_VERTICAL)))
+  if (!((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL)))
   {
     /*
      * Check if we need a scrolling control.
@@ -1270,14 +1310,14 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
     infoPtr->needsScrolling = FALSE;
     infoPtr->leftmostVisible = 0;
   }
-  TAB_SetupScrolling(infoPtr->hwnd, infoPtr, &clientRect);
+  TAB_SetupScrolling(infoPtr, &clientRect);
 
   /* Set the number of rows */
   infoPtr->uNumRows = curItemRowCount;
 
   /* Arrange all tabs evenly if style says so */
-   if (!(lStyle & TCS_RAGGEDRIGHT) &&
-       ((lStyle & TCS_MULTILINE) || (lStyle & TCS_VERTICAL)) &&
+   if (!(infoPtr->dwStyle & TCS_RAGGEDRIGHT) &&
+       ((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL)) &&
        (infoPtr->uNumItem > 0) &&
        (infoPtr->uNumRows > 1))
    {
@@ -1312,7 +1352,7 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
           /* move to the next row, reset our current item left position and */
           /* the count of items on this row */
 
-         if (lStyle & TCS_VERTICAL) {
+         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++;
@@ -1332,10 +1372,10 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
           curr->rect.left += curItemLeftPos;
           curr->rect.right += curItemLeftPos;
           curr->rect.top = iRow;
-          if (lStyle & TCS_BUTTONS)
+          if (infoPtr->dwStyle & TCS_BUTTONS)
          {
             curItemLeftPos = curr->rect.right + 1;
-            if (lStyle & TCS_FLATBUTTONS)
+            if (infoPtr->dwStyle & TCS_FLATBUTTONS)
              curItemLeftPos += FLAT_BTN_SPACINGX;
          }
           else
@@ -1418,7 +1458,7 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
   }
 
   /* if TCS_VERTICAL rotate the tabs so they are along the side of the clientRect */
-  if(lStyle & TCS_VERTICAL)
+  if(infoPtr->dwStyle & TCS_VERTICAL)
   {
     RECT rcOriginal;
     for(iIndex = 0; iIndex < infoPtr->uNumItem; iIndex++)
@@ -1447,17 +1487,16 @@ static void TAB_SetItemBounds (TAB_INFO *infoPtr)
 static void
 TAB_EraseTabInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, const RECT *drawRect)
 {
-    LONG     lStyle  = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
     HBRUSH   hbr = CreateSolidBrush (comctl32_color.clrBtnFace);
     BOOL     deleteBrush = TRUE;
     RECT     rTemp = *drawRect;
 
-    if (lStyle & TCS_BUTTONS)
+    if (infoPtr->dwStyle & TCS_BUTTONS)
     {
        if (iItem == infoPtr->iSelected)
        {
            /* Background color */
-           if (!(lStyle & TCS_OWNERDRAWFIXED))
+           if (!(infoPtr->dwStyle & TCS_OWNERDRAWFIXED))
            {
                DeleteObject(hbr);
                hbr = GetSysColorBrush(COLOR_SCROLLBAR);
@@ -1478,11 +1517,12 @@ TAB_EraseTabInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, const RECT *dr
        }
        else  /* ! selected */
        {
-           if (lStyle & TCS_FLATBUTTONS)
+           if (infoPtr->dwStyle & TCS_FLATBUTTONS)
            {
                InflateRect(&rTemp, 2, 2);
                FillRect(hdc, &rTemp, hbr);
-               if (iItem == infoPtr->iHotTracked)
+               if (iItem == infoPtr->iHotTracked ||
+                   (iItem != infoPtr->iSelected && iItem == infoPtr->uFocus))
                    DrawEdge(hdc, &rTemp, BDR_RAISEDINNER, BF_RECT);
            }
            else
@@ -1522,8 +1562,6 @@ TAB_EraseTabInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, const RECT *dr
 static void
 TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect)
 {
-  LONG      lStyle  = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
-
   RECT localRect;
 
   HPEN   htextPen;
@@ -1560,7 +1598,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
     else
       *drawRect = itemRect;
         
-    if (lStyle & TCS_BUTTONS)
+    if (infoPtr->dwStyle & TCS_BUTTONS)
     {
       if (iItem == infoPtr->iSelected)
       {
@@ -1568,14 +1606,14 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
        drawRect->top    += 4;
        drawRect->right  -= 4;
 
-       if (lStyle & TCS_VERTICAL)
+       if (infoPtr->dwStyle & TCS_VERTICAL)
        {
-         if (!(lStyle & TCS_BOTTOM)) drawRect->right  += 1;
+         if (!(infoPtr->dwStyle & TCS_BOTTOM)) drawRect->right  += 1;
          drawRect->bottom   -= 4;
        }
        else
        {
-         if (lStyle & TCS_BOTTOM)
+         if (infoPtr->dwStyle & TCS_BOTTOM)
          {
            drawRect->top    -= 2;
            drawRect->bottom -= 4;
@@ -1594,7 +1632,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
     }
     else
     {
-      if ((lStyle & TCS_VERTICAL) && (lStyle & TCS_BOTTOM))
+      if ((infoPtr->dwStyle & TCS_VERTICAL) && (infoPtr->dwStyle & TCS_BOTTOM))
       {
         if (iItem != infoPtr->iSelected)
        {
@@ -1603,7 +1641,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
          drawRect->bottom -= 2;
        }
       }
-      else if (lStyle & TCS_VERTICAL)
+      else if (infoPtr->dwStyle & TCS_VERTICAL)
       {
         if (iItem == infoPtr->iSelected)
        {
@@ -1616,7 +1654,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
          drawRect->bottom -= 2;
        }
       }
-      else if (lStyle & TCS_BOTTOM)
+      else if (infoPtr->dwStyle & TCS_BOTTOM)
       {
         if (iItem == infoPtr->iSelected)
        {
@@ -1648,21 +1686,19 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
   TAB_EraseTabInterior (infoPtr, hdc, iItem, drawRect);
 
   /* Draw the focus rectangle */
-  if (!(lStyle & TCS_FOCUSNEVER) &&
+  if (!(infoPtr->dwStyle & TCS_FOCUSNEVER) &&
       (GetFocus() == infoPtr->hwnd) &&
       (iItem == infoPtr->uFocus) )
   {
     RECT rFocus = *drawRect;
-    InflateRect(&rFocus, -3, -3);
-    if (lStyle & TCS_BOTTOM && !(lStyle & TCS_VERTICAL))
-      rFocus.top -= 3;
-    if (lStyle & TCS_BUTTONS)
-    {
-      rFocus.left -= 3;
+
+    if (!(infoPtr->dwStyle & TCS_BUTTONS)) InflateRect(&rFocus, -3, -3);
+    if (infoPtr->dwStyle & TCS_BOTTOM && !(infoPtr->dwStyle & TCS_VERTICAL))
       rFocus.top -= 3;
-    }
 
-    DrawFocusRect(hdc, &rFocus);
+    /* focus should stay on selected item for TCS_BUTTONS style */
+    if (!((infoPtr->dwStyle & TCS_BUTTONS) && (infoPtr->iSelected != iItem)))
+      DrawFocusRect(hdc, &rFocus);
   }
 
   /*
@@ -1676,10 +1712,10 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
    * Setup for text output
   */
   oldBkMode = SetBkMode(hdc, TRANSPARENT);
-  if (!GetWindowTheme (infoPtr->hwnd) || (lStyle & TCS_BUTTONS))
+  if (!GetWindowTheme (infoPtr->hwnd) || (infoPtr->dwStyle & TCS_BUTTONS))
   {
-    if ((lStyle & TCS_HOTTRACK) && (iItem == infoPtr->iHotTracked) &&
-        !(lStyle & TCS_FLATBUTTONS))
+    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);
@@ -1690,7 +1726,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
   /*
    * if owner draw, tell the owner to draw
    */
-  if ((lStyle & TCS_OWNERDRAWFIXED) && GetParent(infoPtr->hwnd))
+  if ((infoPtr->dwStyle & TCS_OWNERDRAWFIXED) && GetParent(infoPtr->hwnd))
   {
     DRAWITEMSTRUCT dis;
     UINT id;
@@ -1728,7 +1764,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
     /*
      * send the draw message
      */
-    SendMessageW( infoPtr->hwndNotify, WM_DRAWITEM, (WPARAM)id, (LPARAM)&dis );
+    SendMessageW( infoPtr->hwndNotify, WM_DRAWITEM, id, (LPARAM)&dis );
   }
   else
   {
@@ -1764,7 +1800,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
       
       ImageList_GetIconSize(infoPtr->himl, &cx, &cy);
 
-      if(lStyle & TCS_VERTICAL)
+      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;
@@ -1781,7 +1817,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
       else
         center_offset_v += infoPtr->uVItemPadding / 2;
 
-      if (lStyle & TCS_FIXEDWIDTH && lStyle & (TCS_FORCELABELLEFT | TCS_FORCEICONLEFT))
+      if (infoPtr->dwStyle & TCS_FIXEDWIDTH && infoPtr->dwStyle & (TCS_FORCELABELLEFT | TCS_FORCEICONLEFT))
        center_offset_h = infoPtr->uHItemPadding;
 
       if (center_offset_h < 2)
@@ -1794,7 +1830,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
          debugstr_w(item->pszText), center_offset_h, center_offset_v,
           wine_dbgstr_rect(drawRect), (rcText.right-rcText.left));
 
-      if((lStyle & TCS_VERTICAL) && (lStyle & TCS_BOTTOM))
+      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 */
@@ -1803,7 +1839,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
         rcImage.left = drawRect->right - cx - center_offset_v;
         drawRect->top += cy + infoPtr->uHItemPadding;
       }
-      else if(lStyle & TCS_VERTICAL)
+      else if(infoPtr->dwStyle & TCS_VERTICAL)
       {
         rcImage.top  = drawRect->bottom - cy - center_offset_h;
        rcImage.left = drawRect->left + center_offset_v;
@@ -1830,17 +1866,17 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
     }
 
     /* Now position text */
-    if (lStyle & TCS_FIXEDWIDTH && lStyle & TCS_FORCELABELLEFT)
+    if (infoPtr->dwStyle & TCS_FIXEDWIDTH && infoPtr->dwStyle & TCS_FORCELABELLEFT)
       center_offset_h = infoPtr->uHItemPadding;
     else
-      if(lStyle & TCS_VERTICAL)
+      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(lStyle & TCS_VERTICAL)
+    if(infoPtr->dwStyle & TCS_VERTICAL)
     {
-      if(lStyle & TCS_BOTTOM)
+      if(infoPtr->dwStyle & TCS_BOTTOM)
         drawRect->top+=center_offset_h;
       else
         drawRect->bottom-=center_offset_h;
@@ -1862,13 +1898,13 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
     if (center_offset_v < 0)
       center_offset_v = 0;
 
-    if(lStyle & TCS_VERTICAL)
+    if(infoPtr->dwStyle & TCS_VERTICAL)
       drawRect->left += center_offset_v;
     else
       drawRect->top += center_offset_v;
 
     /* Draw the text */
-    if(lStyle & TCS_VERTICAL) /* if we are vertical rotate the text and each character */
+    if(infoPtr->dwStyle & TCS_VERTICAL) /* if we are vertical rotate the text and each character */
     {
       static const WCHAR ArialW[] = { 'A','r','i','a','l',0 };
       LOGFONTW logfont;
@@ -1876,7 +1912,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
       INT nEscapement = 900;
       INT nOrientation = 900;
 
-      if(lStyle & TCS_BOTTOM)
+      if(infoPtr->dwStyle & TCS_BOTTOM)
       {
         nEscapement = -900;
         nOrientation = -900;
@@ -1907,8 +1943,8 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
       if (item->pszText)
       {
         ExtTextOutW(hdc,
-        (lStyle & TCS_BOTTOM) ? drawRect->right : drawRect->left,
-        (!(lStyle & TCS_BOTTOM)) ? drawRect->bottom : drawRect->top,
+        (infoPtr->dwStyle & TCS_BOTTOM) ? drawRect->right : drawRect->left,
+        (!(infoPtr->dwStyle & TCS_BOTTOM)) ? drawRect->bottom : drawRect->top,
         ETO_CLIPPED,
         drawRect,
         item->pszText,
@@ -1955,7 +1991,6 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
  */
 static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
 {
-  LONG      lStyle  = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
   RECT      itemRect;
   RECT      selectedRect;
   BOOL      isVisible;
@@ -1993,13 +2028,13 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
     bkgnd = comctl32_color.clrBtnFace;
     corner = comctl32_color.clrBtnFace;
 
-    if (lStyle & TCS_BUTTONS)
+    if (infoPtr->dwStyle & TCS_BUTTONS)
     {
       /* Get item rectangle */
       r = itemRect;
 
       /* Separators between flat buttons */
-      if ((lStyle & TCS_FLATBUTTONS) && (infoPtr->exStyle & TCS_EX_FLATSEPARATORS))
+      if ((infoPtr->dwStyle & TCS_FLATBUTTONS) && (infoPtr->exStyle & TCS_EX_FLATSEPARATORS))
       {
        r1 = r;
        r1.right += (FLAT_BTN_SPACINGX -2);
@@ -2016,10 +2051,10 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
       {
         DWORD state = TAB_GetItem(infoPtr, iItem)->dwState;
 
-        if (state & TCIS_BUTTONPRESSED)
+        if ((state & TCIS_BUTTONPRESSED) || (iItem == infoPtr->uFocus))
           DrawEdge(hdc, &r, EDGE_SUNKEN, BF_SOFT|BF_RECT);
         else
-          if (!(lStyle & TCS_FLATBUTTONS))
+          if (!(infoPtr->dwStyle & TCS_FLATBUTTONS))
             DrawEdge(hdc, &r, EDGE_RAISED, BF_SOFT|BF_RECT);
       }
     }
@@ -2050,7 +2085,7 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
        * 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)) 
-          && ((lStyle & (TCS_VERTICAL | TCS_BOTTOM)) == 0))
+          && ((infoPtr->dwStyle & (TCS_VERTICAL | TCS_BOTTOM)) == 0))
       {
           static const int partIds[8] = {
               /* Normal item */
@@ -2091,7 +2126,7 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
           DrawThemeBackground (theme, hdc, partIds[partIndex], stateId, &r, NULL);
           GetThemeBackgroundContentRect (theme, hdc, partIds[partIndex], stateId, &r, &r);
       }
-      else if(lStyle & TCS_VERTICAL)
+      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 */
@@ -2107,7 +2142,7 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
                fillRect.bottom -= CONTROL_BORDER_SIZEY;
        }
 
-        if (lStyle & TCS_BOTTOM)
+        if (infoPtr->dwStyle & TCS_BOTTOM)
         {
          /* Adjust both rectangles to match native */
          r.left += (1-ZZ);
@@ -2194,7 +2229,7 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
                fillRect.right -= CONTROL_BORDER_SIZEX;
        }
 
-        if (lStyle & TCS_BOTTOM)
+        if (infoPtr->dwStyle & TCS_BOTTOM)
         {
          /* Adjust both rectangles for topmost row */
          if (TAB_GetItem(infoPtr, iItem)->rect.top == infoPtr->uNumRows-1)
@@ -2303,7 +2338,6 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC  hdc, INT  iItem)
 static void TAB_DrawBorder(const TAB_INFO *infoPtr, HDC hdc)
 {
   RECT rect;
-  DWORD lStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
   HTHEME theme = GetWindowTheme (infoPtr->hwnd);
 
   GetClientRect (infoPtr->hwnd, &rect);
@@ -2314,11 +2348,11 @@ static void TAB_DrawBorder(const TAB_INFO *infoPtr, HDC hdc)
 
   if (infoPtr->uNumItem)
   {
-    if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL))
+    if ((infoPtr->dwStyle & TCS_BOTTOM) && !(infoPtr->dwStyle & TCS_VERTICAL))
       rect.bottom -= infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
-    else if((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
+    else if((infoPtr->dwStyle & TCS_BOTTOM) && (infoPtr->dwStyle & TCS_VERTICAL))
       rect.right  -= infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
-    else if(lStyle & TCS_VERTICAL)
+    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;
@@ -2337,7 +2371,7 @@ static void TAB_DrawBorder(const TAB_INFO *infoPtr, HDC hdc)
  *
  * This method repaints the tab control..
  */
-static void TAB_Refresh (TAB_INFO *infoPtr, HDC hdc)
+static void TAB_Refresh (const TAB_INFO *infoPtr, HDC hdc)
 {
   HFONT hOldFont;
   INT i;
@@ -2347,7 +2381,7 @@ static void TAB_Refresh (TAB_INFO *infoPtr, HDC hdc)
 
   hOldFont = SelectObject (hdc, infoPtr->hFont);
 
-  if (GetWindowLongW(infoPtr->hwnd, GWL_STYLE) & TCS_BUTTONS)
+  if (infoPtr->dwStyle & TCS_BUTTONS)
   {
     for (i = 0; i < infoPtr->uNumItem; i++)
       TAB_DrawItem (infoPtr, hdc, i);
@@ -2374,6 +2408,7 @@ static void TAB_Refresh (TAB_INFO *infoPtr, HDC hdc)
 
 static inline DWORD TAB_GetRowCount (const TAB_INFO *infoPtr)
 {
+  TRACE("(%p)\n", infoPtr);
   return infoPtr->uNumRows;
 }
 
@@ -2393,18 +2428,17 @@ static void TAB_EnsureSelectionVisible(
   TAB_INFO* infoPtr)
 {
   INT iSelected = infoPtr->iSelected;
-  LONG lStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
   INT iOrigLeftmostVisible = infoPtr->leftmostVisible;
 
   /* set the items row to the bottommost row or topmost row depending on
    * style */
-  if ((infoPtr->uNumRows > 1) && !(lStyle & TCS_BUTTONS))
+  if ((infoPtr->uNumRows > 1) && !(infoPtr->dwStyle & TCS_BUTTONS))
   {
       TAB_ITEM *selected = TAB_GetItem(infoPtr, iSelected);
       INT newselected;
       INT iTargetRow;
 
-      if(lStyle & TCS_VERTICAL)
+      if(infoPtr->dwStyle & TCS_VERTICAL)
         newselected = selected->rect.left;
       else
         newselected = selected->rect.top;
@@ -2416,7 +2450,7 @@ static void TAB_EnsureSelectionVisible(
       if (newselected != iTargetRow)
       {
          UINT i;
-         if(lStyle & TCS_VERTICAL)
+         if(infoPtr->dwStyle & TCS_VERTICAL)
          {
            for (i=0; i < infoPtr->uNumItem; i++)
            {
@@ -2455,7 +2489,7 @@ static void TAB_EnsureSelectionVisible(
    * Do the trivial cases first.
    */
   if ( (!infoPtr->needsScrolling) ||
-       (infoPtr->hwndUpDown==0) || (lStyle & TCS_VERTICAL))
+       (infoPtr->hwndUpDown==0) || (infoPtr->dwStyle & TCS_VERTICAL))
     return;
 
   if (infoPtr->leftmostVisible >= iSelected)
@@ -2512,7 +2546,6 @@ static void TAB_EnsureSelectionVisible(
 static void TAB_InvalidateTabArea(const TAB_INFO *infoPtr)
 {
   RECT clientRect, rInvalidate, rAdjClient;
-  DWORD lStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
   INT lastRow = infoPtr->uNumRows - 1;
   RECT rect;
 
@@ -2525,19 +2558,19 @@ static void TAB_InvalidateTabArea(const TAB_INFO *infoPtr)
   TAB_AdjustRect(infoPtr, 0, &rAdjClient);
 
   TAB_InternalGetItemRect(infoPtr, infoPtr->uNumItem-1 , &rect, NULL);
-  if ((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
+  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(lStyle & TCS_VERTICAL)
+  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 (lStyle & TCS_BOTTOM)
+  else if (infoPtr->dwStyle & TCS_BOTTOM)
   {
     rInvalidate.top = rAdjClient.bottom;
     if (infoPtr->uNumRows == 1)
@@ -2587,19 +2620,14 @@ static inline LRESULT TAB_Paint (TAB_INFO *infoPtr, HDC hdcPaint)
 }
 
 static LRESULT
-TAB_InsertItemT (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
+TAB_InsertItemT (TAB_INFO *infoPtr, INT iItem, TCITEMW *pti, BOOL bUnicode)
 {
   TAB_ITEM *item;
-  TCITEMW *pti;
-  INT iItem;
   RECT rect;
 
   GetClientRect (infoPtr->hwnd, &rect);
   TRACE("Rect: %p %s\n", infoPtr->hwnd, wine_dbgstr_rect(&rect));
 
-  pti = (TCITEMW *)lParam;
-  iItem = (INT)wParam;
-
   if (iItem < 0) return -1;
   if (iItem > infoPtr->uNumItem)
     iItem = infoPtr->uNumItem;
@@ -2677,25 +2705,24 @@ TAB_InsertItemT (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
 }
 
 static LRESULT
-TAB_SetItemSize (TAB_INFO *infoPtr, LPARAM lParam)
+TAB_SetItemSize (TAB_INFO *infoPtr, INT cx, INT cy)
 {
-  LONG lStyle = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
   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 (lStyle & TCS_FIXEDWIDTH && (infoPtr->tabWidth != (INT)LOWORD(lParam)))
+  if (infoPtr->dwStyle & TCS_FIXEDWIDTH && (infoPtr->tabWidth != cx))
   {
-    infoPtr->tabWidth = (INT)LOWORD(lParam);
+    infoPtr->tabWidth = cx;
     bNeedPaint = TRUE;
   }
 
-  if (infoPtr->tabHeight != (INT)HIWORD(lParam))
+  if (infoPtr->tabHeight != cy)
   {
-    if ((infoPtr->fHeightSet = ((INT)HIWORD(lParam) != 0)))
-      infoPtr->tabHeight = (INT)HIWORD(lParam);
+    if ((infoPtr->fHeightSet = (cy != 0)))
+      infoPtr->tabHeight = cy;
 
     bNeedPaint = TRUE;
   }
@@ -2736,9 +2763,9 @@ TAB_HighlightItem (TAB_INFO *infoPtr, INT iItem, BOOL fHighlight)
 
   TRACE("(%p,%d,%s)\n", infoPtr, iItem, fHighlight ? "true" : "false");
 
-  if (!infoPtr || iItem < 0 || iItem >= infoPtr->uNumItem)
+  if (iItem < 0 || iItem >= infoPtr->uNumItem)
     return FALSE;
-  
+
   lpState = &TAB_GetItem(infoPtr, iItem)->dwState;
   oldState = *lpState;
 
@@ -2799,7 +2826,8 @@ TAB_SetItemT (TAB_INFO *infoPtr, INT iItem, LPTCITEMW tabItem, BOOL bUnicode)
 
 static inline LRESULT TAB_GetItemCount (const TAB_INFO *infoPtr)
 {
-   return infoPtr->uNumItem;
+  TRACE("\n");
+  return infoPtr->uNumItem;
 }
 
 
@@ -2894,10 +2922,9 @@ static LRESULT TAB_DeleteItem (TAB_INFO *infoPtr, INT iItem)
        Free(oldItems);
 
        /* Readjust the selected index */
-       if ((iItem == infoPtr->iSelected) && (iItem > 0))
-           infoPtr->iSelected--;
-
-       if (iItem < infoPtr->iSelected)
+       if (iItem == infoPtr->iSelected)
+           infoPtr->iSelected = -1;
+       else if (iItem < infoPtr->iSelected)
            infoPtr->iSelected--;
 
        if (infoPtr->uNumItem == 0)
@@ -2950,7 +2977,7 @@ static inline LRESULT TAB_GetImageList (const TAB_INFO *infoPtr)
 static inline LRESULT TAB_SetImageList (TAB_INFO *infoPtr, HIMAGELIST himlNew)
 {
     HIMAGELIST himlPrev = infoPtr->himl;
-    TRACE("\n");
+    TRACE("himl=%p\n", himlNew);
     infoPtr->himl = himlNew;
     TAB_SetItemBounds(infoPtr);
     InvalidateRect(infoPtr->hwnd, NULL, TRUE);
@@ -2959,6 +2986,7 @@ static inline LRESULT TAB_SetImageList (TAB_INFO *infoPtr, HIMAGELIST himlNew)
 
 static inline LRESULT TAB_GetUnicodeFormat (const TAB_INFO *infoPtr)
 {
+    TRACE("(%p)\n", infoPtr);
     return infoPtr->bUnicode;
 }
 
@@ -2966,6 +2994,7 @@ 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;
@@ -3050,9 +3079,10 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam)
   dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
   SetWindowLongW(hwnd, GWL_STYLE, dwStyle|WS_CLIPSIBLINGS);
 
+  infoPtr->dwStyle = dwStyle | WS_CLIPSIBLINGS;
   infoPtr->exStyle = (dwStyle & TCS_FLATBUTTONS) ? TCS_EX_FLATSEPARATORS : 0;
 
-  if (dwStyle & TCS_TOOLTIPS) {
+  if (infoPtr->dwStyle & TCS_TOOLTIPS) {
     /* Create tooltip control */
     infoPtr->hwndToolTip =
       CreateWindowExW (0, TOOLTIPS_CLASSW, NULL, WS_POPUP,
@@ -3070,7 +3100,7 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam)
       nmttc.hwndToolTips = infoPtr->hwndToolTip;
 
       SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
-                   (WPARAM)GetWindowLongPtrW(hwnd, GWLP_ID), (LPARAM)&nmttc);
+                    GetWindowLongPtrW(hwnd, GWLP_ID), (LPARAM)&nmttc);
     }
   }
 
@@ -3091,11 +3121,11 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam)
    * selected item + extra space for the selected item.
    */
   infoPtr->tabHeight = fontMetrics.tmHeight + SELECTED_TAB_OFFSET +
-                      ((dwStyle & TCS_BUTTONS) ? 2 : 1) *
+                      ((infoPtr->dwStyle & TCS_BUTTONS) ? 2 : 1) *
                         infoPtr->uVItemPadding;
 
   /* Initialize the width of a tab. */
-  if (dwStyle & TCS_FIXEDWIDTH)
+  if (infoPtr->dwStyle & TCS_FIXEDWIDTH)
     infoPtr->tabWidth = GetDeviceCaps(hdc, LOGPIXELSX);
 
   infoPtr->tabMinWidth = -1;
@@ -3113,9 +3143,6 @@ TAB_Destroy (TAB_INFO *infoPtr)
 {
   UINT iItem;
 
-  if (!infoPtr)
-      return 0;
-
   SetWindowLongPtrW(infoPtr->hwnd, 0, 0);
 
   if (infoPtr->items) {
@@ -3135,7 +3162,7 @@ TAB_Destroy (TAB_INFO *infoPtr)
     KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);
 
   CloseThemeData (GetWindowTheme (infoPtr->hwnd));
-  
+
   Free (infoPtr);
   return 0;
 }
@@ -3159,7 +3186,9 @@ static LRESULT TAB_NCCalcSize(WPARAM wParam)
 static inline LRESULT
 TAB_SetItemExtra (TAB_INFO *infoPtr, INT cbInfo)
 {
-  if (!infoPtr || cbInfo <= 0)
+  TRACE("(%p %d)\n", infoPtr, cbInfo);
+
+  if (cbInfo <= 0)
     return FALSE;
 
   if (infoPtr->uNumItem)
@@ -3174,8 +3203,7 @@ TAB_SetItemExtra (TAB_INFO *infoPtr, INT cbInfo)
 
 static LRESULT TAB_RemoveImage (TAB_INFO *infoPtr, INT image)
 {
-  if (!infoPtr)
-    return 0;
+  TRACE("%p %d\n", infoPtr, image);
 
   if (ImageList_Remove (infoPtr->himl, image))
   {
@@ -3239,11 +3267,12 @@ TAB_GetExtendedStyle (const TAB_INFO *infoPtr)
 static LRESULT
 TAB_DeselectAll (TAB_INFO *infoPtr, BOOL excludesel)
 {
-  LONG style = GetWindowLongW(infoPtr->hwnd, GWL_STYLE);
   BOOL paint = FALSE;
   INT i, selected = infoPtr->iSelected;
 
-  if (!(style & TCS_BUTTONS))
+  TRACE("(%p, %d)\n", infoPtr, excludesel);
+
+  if (!(infoPtr->dwStyle & TCS_BUTTONS))
     return 0;
 
   for (i = 0; i < infoPtr->uNumItem; i++)
@@ -3269,6 +3298,34 @@ TAB_DeselectAll (TAB_INFO *infoPtr, BOOL excludesel)
   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)
 {
@@ -3304,7 +3361,7 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
      return TAB_DeleteAllItems (infoPtr);
 
     case TCM_GETITEMRECT:
-     return TAB_GetItemRect (infoPtr, wParam, lParam);
+     return TAB_GetItemRect (infoPtr, (INT)wParam, (LPRECT)lParam);
 
     case TCM_GETCURSEL:
       return TAB_GetCurSel (infoPtr);
@@ -3317,19 +3374,19 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
     case TCM_INSERTITEMA:
     case TCM_INSERTITEMW:
-      return TAB_InsertItemT (infoPtr, wParam, lParam, uMsg == TCM_INSERTITEMW);
+      return TAB_InsertItemT (infoPtr, (INT)wParam, (TCITEMW*)lParam, uMsg == TCM_INSERTITEMW);
 
     case TCM_SETITEMEXTRA:
-      return TAB_SetItemExtra (infoPtr, (int)wParam);
+      return TAB_SetItemExtra (infoPtr, (INT)wParam);
 
     case TCM_ADJUSTRECT:
       return TAB_AdjustRect (infoPtr, (BOOL)wParam, (LPRECT)lParam);
 
     case TCM_SETITEMSIZE:
-      return TAB_SetItemSize (infoPtr, lParam);
+      return TAB_SetItemSize (infoPtr, (INT)LOWORD(lParam), (INT)HIWORD(lParam));
 
     case TCM_REMOVEIMAGE:
-      return TAB_RemoveImage (infoPtr, wParam);
+      return TAB_RemoveImage (infoPtr, (INT)wParam);
 
     case TCM_SETPADDING:
       return TAB_SetPadding (infoPtr, lParam);
@@ -3414,9 +3471,7 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
       return TAB_OnHScroll(infoPtr, (int)LOWORD(wParam), (int)HIWORD(wParam));
 
     case WM_STYLECHANGED:
-      TAB_SetItemBounds (infoPtr);
-      InvalidateRect(hwnd, NULL, TRUE);
-      return 0;
+      return TAB_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);
 
     case WM_SYSCOLORCHANGE:
       COMCTL32_RefreshSysColors();
@@ -3426,12 +3481,14 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
       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_KEYUP:
-      return TAB_KeyUp(infoPtr, wParam);
+    case WM_KEYDOWN:
+      return TAB_KeyDown(infoPtr, wParam, lParam);
+
     case WM_NCHITTEST:
       return TAB_NCHitTest(infoPtr, lParam);
 
index 477138e..a6c6f87 100644 (file)
@@ -69,7 +69,7 @@ static void paint_text (HWND hwnd, HDC hdc, DWORD dwStyle, const COMBOBOXINFO *c
         if( (pText = HeapAlloc( GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR))) )
         {
             /* size from LB_GETTEXTLEN may be too large, from LB_GETTEXT is accurate */
-            size=SendMessageW (cbi->hwndList, LB_GETTEXT, (WPARAM)id, (LPARAM)pText);
+            size = SendMessageW (cbi->hwndList, LB_GETTEXT, id, (LPARAM)pText);
             pText[size] = '\0'; /* just in case */
         } else return;
     }
@@ -116,8 +116,7 @@ static void paint_text (HWND hwnd, HDC hdc, DWORD dwStyle, const COMBOBOXINFO *c
        dis.itemState    = itemState;
        dis.hDC          = hdc;
        dis.rcItem       = rectEdit;
-       dis.itemData     = SendMessageW(cbi->hwndList, LB_GETITEMDATA,
-                                        (WPARAM)id, 0 );
+       dis.itemData     = SendMessageW(cbi->hwndList, LB_GETITEMDATA, id, 0);
 
        /*
         * Clip the DC and have the parent draw the item.
index d95dc7d..d24b3dc 100644 (file)
@@ -264,7 +264,7 @@ TOOLBAR_GetText(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr)
     LPWSTR lpText = NULL;
 
     /* NOTE: iString == -1 is undocumented */
-    if ((HIWORD(btnPtr->iString) != 0) && (btnPtr->iString != -1))
+    if (!IS_INTRESOURCE(btnPtr->iString) && (btnPtr->iString != -1))
         lpText = (LPWSTR)btnPtr->iString;
     else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
         lpText = infoPtr->strings[btnPtr->iString];
@@ -315,6 +315,11 @@ TOOLBAR_DumpToolbar(const TOOLBAR_INFO *iP, INT line)
     }
 }
 
+static inline BOOL
+TOOLBAR_ButtonHasString(const TBUTTON_INFO *btnPtr)
+{
+    return HIWORD(btnPtr->iString) && btnPtr->iString != -1;
+}
 
 /***********************************************************************
 *              TOOLBAR_CheckStyle
@@ -1832,7 +1837,7 @@ TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButto
         btnPtr->dwData    = lpTbb[iButton].dwData;
         if (btnPtr->fsStyle & BTNS_SEP)
             btnPtr->iString = -1;
-        else if(HIWORD(lpTbb[iButton].iString) && lpTbb[iButton].iString != -1)
+        else if(!IS_INTRESOURCE(lpTbb[iButton].iString) && lpTbb[iButton].iString != -1)
         {
             if (fUnicode)
                 Str_SetPtrW((LPWSTR*)&btnPtr->iString, (LPWSTR)lpTbb[iButton].iString );
@@ -2601,7 +2606,7 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                COLORREF oldBk = 0;
 
                /* get item data */
-               btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, wParam, LB_GETITEMDATA, (WPARAM)lpdis->itemID, 0);
+               btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, wParam, LB_GETITEMDATA, lpdis->itemID, 0);
                if (btnInfo == NULL)
                {
                    FIXME("btnInfo invalid!\n");
@@ -2892,7 +2897,7 @@ TOOLBAR_AddStringW (TOOLBAR_INFO *infoPtr, HINSTANCE hInstance, LPARAM lParam)
     BOOL fFirstString = (infoPtr->nNumStrings == 0);
     INT nIndex = infoPtr->nNumStrings;
 
-    if (hInstance && (HIWORD(lParam) == 0)) {
+    if (hInstance && IS_INTRESOURCE(lParam)) {
        WCHAR szString[MAX_RESOURCE_STRING_LENGTH];
        WCHAR delimiter;
        WCHAR *next_delim;
@@ -2960,7 +2965,7 @@ TOOLBAR_AddStringA (TOOLBAR_INFO *infoPtr, HINSTANCE hInstance, LPARAM lParam)
     INT nIndex;
     INT len;
 
-    if (hInstance && (HIWORD(lParam) == 0))  /* load from resources */
+    if (hInstance && IS_INTRESOURCE(lParam))  /* load from resources */
         return TOOLBAR_AddStringW(infoPtr, hInstance, lParam);
 
     p = (LPSTR)lParam;
@@ -3151,8 +3156,6 @@ TOOLBAR_Customize (TOOLBAR_INFO *infoPtr)
 {
     CUSTDLG_INFO custInfo;
     LRESULT ret;
-    LPCVOID template;
-    HRSRC hRes;
     NMHDR nmhdr;
 
     custInfo.tbInfo = infoPtr;
@@ -3161,17 +3164,8 @@ TOOLBAR_Customize (TOOLBAR_INFO *infoPtr)
     /* send TBN_BEGINADJUST notification */
     TOOLBAR_SendNotify (&nmhdr, infoPtr, TBN_BEGINADJUST);
 
-    if (!(hRes = FindResourceW (COMCTL32_hModule,
-                                MAKEINTRESOURCEW(IDD_TBCUSTOMIZE),
-                                (LPWSTR)RT_DIALOG)))
-       return FALSE;
-
-    if(!(template = LoadResource (COMCTL32_hModule, hRes)))
-       return FALSE;
-
-    ret = DialogBoxIndirectParamW ((HINSTANCE)GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_HINSTANCE),
-                                   template, infoPtr->hwndSelf, TOOLBAR_CustomizeDialogProc,
-                                   (LPARAM)&custInfo);
+    ret = DialogBoxParamW (COMCTL32_hModule, MAKEINTRESOURCEW(IDD_TBCUSTOMIZE),
+                           infoPtr->hwndSelf, TOOLBAR_CustomizeDialogProc, (LPARAM)&custInfo);
 
     /* send TBN_ENDADJUST notification */
     TOOLBAR_SendNotify (&nmhdr, infoPtr, TBN_ENDADJUST);
@@ -3203,6 +3197,8 @@ TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex)
 
     if (infoPtr->nNumButtons == 1) {
        TRACE(" simple delete!\n");
+       if (TOOLBAR_ButtonHasString(infoPtr->buttons))
+           Free((LPWSTR)infoPtr->buttons[0].iString);
        Free (infoPtr->buttons);
        infoPtr->buttons = NULL;
        infoPtr->nNumButtons = 0;
@@ -3223,6 +3219,8 @@ TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex)
                     (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
         }
 
+        if (TOOLBAR_ButtonHasString(&oldButtons[nIndex]))
+            Free((LPWSTR)oldButtons[nIndex].iString);
        Free (oldButtons);
     }
 
@@ -3364,7 +3362,7 @@ TOOLBAR_GetButtonInfoT(const TOOLBAR_INFO *infoPtr, INT Id, LPTBBUTTONINFOW lpTb
     if (lpTbInfo->dwMask & TBIF_TEXT) {
         /* TB_GETBUTTONINFO doesn't retrieve text from the string list, so we
            can't use TOOLBAR_GetText here */
-        if (HIWORD(btnPtr->iString) && (btnPtr->iString != -1)) {
+        if (!IS_INTRESOURCE(btnPtr->iString) && (btnPtr->iString != -1)) {
             LPWSTR lpText = (LPWSTR)btnPtr->iString;
             if (bUnicode)
                 Str_GetPtrW(lpText, lpTbInfo->pszText, lpTbInfo->cchText);
@@ -3386,24 +3384,7 @@ TOOLBAR_GetButtonSize (const TOOLBAR_INFO *infoPtr)
 
 
 static LRESULT
-TOOLBAR_GetButtonTextA (const TOOLBAR_INFO *infoPtr, INT Id, LPSTR lpText)
-{
-    INT nIndex;
-    LPWSTR lpTextW;
-
-    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, FALSE);
-    if (nIndex == -1)
-       return -1;
-
-    lpTextW = TOOLBAR_GetText(infoPtr,&infoPtr->buttons[nIndex]);
-
-    return WideCharToMultiByte( CP_ACP, 0, lpTextW, -1,
-                                lpText, lpText ? 0x7fffffff : 0, NULL, NULL ) - 1;
-}
-
-
-static LRESULT
-TOOLBAR_GetButtonTextW (const TOOLBAR_INFO *infoPtr, INT Id, LPWSTR lpStr)
+TOOLBAR_GetButtonText (const TOOLBAR_INFO *infoPtr, INT Id, LPWSTR lpStr, BOOL isW)
 {
     INT nIndex;
     LPWSTR lpText;
@@ -3415,14 +3396,17 @@ TOOLBAR_GetButtonTextW (const TOOLBAR_INFO *infoPtr, INT Id, LPWSTR lpStr)
 
     lpText = TOOLBAR_GetText(infoPtr,&infoPtr->buttons[nIndex]);
 
-    if (lpText)
+    if (isW)
     {
-        ret = strlenW (lpText);
-
-        if (lpStr)
-            strcpyW (lpStr, lpText);
+        if (lpText)
+        {
+            ret = strlenW (lpText);
+            if (lpStr) strcpyW (lpStr, lpText);
+        }
     }
-
+    else
+        ret = WideCharToMultiByte( CP_ACP, 0, lpText, -1,
+                                  (LPSTR)lpStr, lpStr ? 0x7fffffff : 0, NULL, NULL ) - 1;
     return ret;
 }
 
@@ -3996,7 +3980,7 @@ TOOLBAR_ReplaceBitmap (TOOLBAR_INFO *infoPtr, const TBREPLACEBITMAP *lpReplace)
         FIXME("changing standard bitmaps not implemented\n");
         return FALSE;
     }
-    else if (lpReplace->hInstOld != 0)
+    else if (lpReplace->hInstOld != 0 && lpReplace->hInstOld != lpReplace->hInstNew)
         FIXME("resources not in the current module not implemented\n");
 
     TRACE("To be replaced hInstOld %p nIDOld %lx\n", lpReplace->hInstOld, lpReplace->nIDOld);
@@ -4158,7 +4142,7 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
 
                 /* can't contain real string as we don't know whether
                  * the client put an ANSI or Unicode string in there */
-                if (HIWORD(nmtbr.tbButton.iString))
+                if (!IS_INTRESOURCE(nmtbr.tbButton.iString))
                     nmtbr.tbButton.iString = 0;
 
                 TOOLBAR_InsertButtonT(infoPtr, -1, &nmtbr.tbButton, TRUE);
@@ -4301,58 +4285,8 @@ TOOLBAR_SetBitmapSize (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 
 
 static LRESULT
-TOOLBAR_SetButtonInfoA (TOOLBAR_INFO *infoPtr, INT Id, const TBBUTTONINFOA *lptbbi)
-{
-    TBUTTON_INFO *btnPtr;
-    INT nIndex;
-    RECT oldBtnRect;
-
-    if (lptbbi == NULL)
-       return FALSE;
-    if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
-       return FALSE;
-
-    nIndex = TOOLBAR_GetButtonIndex (infoPtr, Id, lptbbi->dwMask & TBIF_BYINDEX);
-    if (nIndex == -1)
-       return FALSE;
-
-    btnPtr = &infoPtr->buttons[nIndex];
-    if (lptbbi->dwMask & TBIF_COMMAND)
-       btnPtr->idCommand = lptbbi->idCommand;
-    if (lptbbi->dwMask & TBIF_IMAGE)
-       btnPtr->iBitmap = lptbbi->iImage;
-    if (lptbbi->dwMask & TBIF_LPARAM)
-       btnPtr->dwData = lptbbi->lParam;
-    if (lptbbi->dwMask & TBIF_SIZE)
-       btnPtr->cx = lptbbi->cx;
-    if (lptbbi->dwMask & TBIF_STATE)
-       btnPtr->fsState = lptbbi->fsState;
-    if (lptbbi->dwMask & TBIF_STYLE)
-       btnPtr->fsStyle = lptbbi->fsStyle;
-
-    if ((lptbbi->dwMask & TBIF_TEXT) && ((INT_PTR)lptbbi->pszText != -1)) {
-        if ((HIWORD(btnPtr->iString) == 0) || (btnPtr->iString == -1))
-           /* iString is index, zero it to make Str_SetPtr succeed */
-           btnPtr->iString=0;
-
-         Str_SetPtrAtoW ((LPWSTR *)&btnPtr->iString, lptbbi->pszText);
-    }
-
-    /* save the button rect to see if we need to redraw the whole toolbar */
-    oldBtnRect = btnPtr->rect;
-    TOOLBAR_LayoutToolbar(infoPtr);
-
-    if (!EqualRect(&oldBtnRect, &btnPtr->rect))
-        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
-    else
-        InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE);
-
-    return TRUE;
-}
-
-
-static LRESULT
-TOOLBAR_SetButtonInfoW (TOOLBAR_INFO *infoPtr, INT Id, const TBBUTTONINFOW *lptbbi)
+TOOLBAR_SetButtonInfo (TOOLBAR_INFO *infoPtr, INT Id,
+                       const TBBUTTONINFOW *lptbbi, BOOL isW)
 {
     TBUTTON_INFO *btnPtr;
     INT nIndex;
@@ -4382,10 +4316,13 @@ TOOLBAR_SetButtonInfoW (TOOLBAR_INFO *infoPtr, INT Id, const TBBUTTONINFOW *lptb
        btnPtr->fsStyle = lptbbi->fsStyle;
 
     if ((lptbbi->dwMask & TBIF_TEXT) && ((INT_PTR)lptbbi->pszText != -1)) {
-        if ((HIWORD(btnPtr->iString) == 0) || (btnPtr->iString == -1))
-           /* iString is index, zero it to make Str_SetPtr succeed */
-           btnPtr->iString=0;
-        Str_SetPtrW ((LPWSTR *)&btnPtr->iString, lptbbi->pszText);
+        /* iString is index, zero it to make Str_SetPtr succeed */
+        if (!TOOLBAR_ButtonHasString(btnPtr)) btnPtr->iString = 0;
+
+        if (isW)
+            Str_SetPtrW ((LPWSTR *)&btnPtr->iString, lptbbi->pszText);
+        else
+            Str_SetPtrAtoW ((LPWSTR *)&btnPtr->iString, (LPSTR)lptbbi->pszText);
     }
 
     /* save the button rect to see if we need to redraw the whole toolbar */
@@ -5205,7 +5142,7 @@ TOOLBAR_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
     infoPtr->dwStyle = dwStyle;
     GetClientRect(hwnd, &infoPtr->client_rect);
     infoPtr->bUnicode = infoPtr->hwndNotify && 
-        (NFR_UNICODE == SendMessageW(hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, (LPARAM)NF_REQUERY));
+        (NFR_UNICODE == SendMessageW(hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_REQUERY));
     infoPtr->hwndToolTip = NULL; /* if needed the tooltip control will be created after a WM_MOUSEMOVE */
 
     SystemParametersInfoW (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
@@ -5222,6 +5159,8 @@ TOOLBAR_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
 static LRESULT
 TOOLBAR_Destroy (TOOLBAR_INFO *infoPtr)
 {
+    INT i;
+
     /* delete tooltip control */
     if (infoPtr->hwndToolTip)
        DestroyWindow (infoPtr->hwndToolTip);
@@ -5231,11 +5170,13 @@ TOOLBAR_Destroy (TOOLBAR_INFO *infoPtr)
     Free (infoPtr->bitmaps);            /* bitmaps list */
 
     /* delete button data */
+    for (i = 0; i < infoPtr->nNumButtons; i++)
+        if (TOOLBAR_ButtonHasString(&infoPtr->buttons[i]))
+            Free ((LPWSTR)infoPtr->buttons[i].iString);
     Free (infoPtr->buttons);
 
     /* delete strings */
     if (infoPtr->strings) {
-       INT i;
        for (i = 0; i < infoPtr->nNumStrings; i++)
            Free (infoPtr->strings[i]);
 
@@ -5648,7 +5589,7 @@ TOOLBAR_LButtonUp (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
         else
         {
             TRACE("button %d dragged out of toolbar\n", infoPtr->nButtonDrag);
-            TOOLBAR_DeleteButton(infoPtr, (WPARAM)infoPtr->nButtonDrag);
+            TOOLBAR_DeleteButton(infoPtr, infoPtr->nButtonDrag);
         }
 
         /* button under cursor changed so need to re-set hot item */
@@ -6156,7 +6097,7 @@ static LRESULT TOOLBAR_TTGetDispInfo (TOOLBAR_INFO *infoPtr, NMTTDISPINFOW *lpnm
                 return 0;
             }
         }
-        else if (tbgit.pszText[0])
+        else if (tbgit.pszText && tbgit.pszText[0])
         {
             MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1,
                                 lpnmtdi->lpszText, sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0]));
@@ -6434,7 +6375,7 @@ TOOLBAR_StyleChanged (TOOLBAR_INFO *infoPtr, INT nType, const STYLESTRUCT *lpSty
 
 
 static LRESULT
-TOOLBAR_SysColorChange ()
+TOOLBAR_SysColorChange (void)
 {
     COMCTL32_RefreshSysColors();
 
@@ -6469,11 +6410,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLBAR_AddBitmap (infoPtr, (INT)wParam, (TBADDBITMAP*)lParam);
 
        case TB_ADDBUTTONSA:
-           return TOOLBAR_AddButtonsT(infoPtr, wParam, (LPTBBUTTON)lParam, FALSE);
-
        case TB_ADDBUTTONSW:
-           return TOOLBAR_AddButtonsT(infoPtr, wParam, (LPTBBUTTON)lParam, TRUE);
-
+           return TOOLBAR_AddButtonsT (infoPtr, wParam, (LPTBBUTTON)lParam,
+                                       uMsg == TB_ADDBUTTONSW);
        case TB_ADDSTRINGA:
            return TOOLBAR_AddStringA (infoPtr, (HINSTANCE)wParam, lParam);
 
@@ -6520,19 +6459,16 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLBAR_GetButton (infoPtr, wParam, (TBBUTTON*)lParam);
 
        case TB_GETBUTTONINFOA:
-           return TOOLBAR_GetButtonInfoT(infoPtr, wParam, (LPTBBUTTONINFOW)lParam, FALSE);
-
        case TB_GETBUTTONINFOW:
-           return TOOLBAR_GetButtonInfoT(infoPtr, wParam, (LPTBBUTTONINFOW)lParam, TRUE);
-
+           return TOOLBAR_GetButtonInfoT (infoPtr, wParam, (LPTBBUTTONINFOW)lParam,
+                                          uMsg == TB_GETBUTTONINFOW);
        case TB_GETBUTTONSIZE:
            return TOOLBAR_GetButtonSize (infoPtr);
 
        case TB_GETBUTTONTEXTA:
-           return TOOLBAR_GetButtonTextA (infoPtr, wParam, (LPSTR)lParam);
-
        case TB_GETBUTTONTEXTW:
-           return TOOLBAR_GetButtonTextW (infoPtr, wParam, (LPWSTR)lParam);
+           return TOOLBAR_GetButtonText (infoPtr, wParam, (LPWSTR)lParam,
+                                         uMsg == TB_GETBUTTONTEXTW);
 
        case TB_GETDISABLEDIMAGELIST:
            return TOOLBAR_GetDisabledImageList (infoPtr, wParam);
@@ -6603,10 +6539,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLBAR_Indeterminate (infoPtr, wParam, LOWORD(lParam));
 
        case TB_INSERTBUTTONA:
-           return TOOLBAR_InsertButtonT(infoPtr, wParam, (TBBUTTON*)lParam, FALSE);
-
        case TB_INSERTBUTTONW:
-           return TOOLBAR_InsertButtonT(infoPtr, wParam, (TBBUTTON*)lParam, TRUE);
+           return TOOLBAR_InsertButtonT(infoPtr, wParam, (TBBUTTON*)lParam,
+                                        uMsg == TB_INSERTBUTTONW);
 
 /*     case TB_INSERTMARKHITTEST:              */ /* 4.71 */
 
@@ -6660,11 +6595,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLBAR_SetBitmapSize (infoPtr, wParam, lParam);
 
        case TB_SETBUTTONINFOA:
-           return TOOLBAR_SetButtonInfoA (infoPtr, wParam, (LPTBBUTTONINFOA)lParam);
-
        case TB_SETBUTTONINFOW:
-           return TOOLBAR_SetButtonInfoW (infoPtr, wParam, (LPTBBUTTONINFOW)lParam);
-
+           return TOOLBAR_SetButtonInfo (infoPtr, wParam, (LPTBBUTTONINFOW)lParam,
+                                          uMsg == TB_SETBUTTONINFOW);
        case TB_SETBUTTONSIZE:
            return TOOLBAR_SetButtonSize (infoPtr, lParam);
 
index d19d0bc..688d3b5 100644 (file)
@@ -175,6 +175,14 @@ static LRESULT CALLBACK
 TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uId, DWORD_PTR dwRef);
 
 
+static inline BOOL TOOLTIPS_IsCallbackString(LPCWSTR str, BOOL isW)
+{
+    if (isW)
+      return str == LPSTR_TEXTCALLBACKW;
+    else
+      return (LPCSTR)str == LPSTR_TEXTCALLBACKA;
+}
+
 static inline UINT_PTR
 TOOLTIPS_GetTitleIconIndex(HICON hIcon)
 {
@@ -205,15 +213,12 @@ TOOLTIPS_InitSystemSettings (TOOLTIPS_INFO *infoPtr)
 
 /* Custom draw routines */
 static void
-TOOLTIPS_customdraw_fill(NMTTCUSTOMDRAW *lpnmttcd,
-                         const HWND hwnd,
+TOOLTIPS_customdraw_fill(const TOOLTIPS_INFO *infoPtr, NMTTCUSTOMDRAW *lpnmttcd,
                          HDC hdc, const RECT *rcBounds, UINT uFlags)
 {
-    TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
-
     ZeroMemory(lpnmttcd, sizeof(NMTTCUSTOMDRAW));
     lpnmttcd->uDrawFlags = uFlags;
-    lpnmttcd->nmcd.hdr.hwndFrom = hwnd;
+    lpnmttcd->nmcd.hdr.hwndFrom = infoPtr->hwndSelf;
     lpnmttcd->nmcd.hdr.code     = NM_CUSTOMDRAW;
     if (infoPtr->nCurrentTool != -1) {
         TTTOOL_INFO *toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
@@ -268,7 +273,7 @@ TOOLTIPS_Refresh (const TOOLTIPS_INFO *infoPtr, HDC hdc)
 
     /* Custom draw - Call PrePaint once initial properties set up     */
     /* Note: Contrary to MSDN, CDRF_SKIPDEFAULT still draws a tooltip */
-    TOOLTIPS_customdraw_fill(&nmttcd, infoPtr->hwndSelf, hdc, &rc, uFlags);
+    TOOLTIPS_customdraw_fill(infoPtr, &nmttcd, hdc, &rc, uFlags);
     cdmode = TOOLTIPS_notify_customdraw(CDDS_PREPAINT, &nmttcd);
     uFlags = nmttcd.uDrawFlags;
 
@@ -878,36 +883,10 @@ TOOLTIPS_TrackHide (const TOOLTIPS_INFO *infoPtr)
                    SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
 }
 
-
+/* Structure layout is the same for TTTOOLINFOW and TTTOOLINFOA,
+   this helper is used in both cases. */
 static INT
-TOOLTIPS_GetToolFromInfoA (const TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpToolInfo)
-{
-    TTTOOL_INFO *toolPtr;
-    UINT nTool;
-
-    for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
-       toolPtr = &infoPtr->tools[nTool];
-
-       if (!(toolPtr->uFlags & TTF_IDISHWND) &&
-           (lpToolInfo->hwnd == toolPtr->hwnd) &&
-           (lpToolInfo->uId == toolPtr->uId))
-           return nTool;
-    }
-
-    for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
-       toolPtr = &infoPtr->tools[nTool];
-
-       if ((toolPtr->uFlags & TTF_IDISHWND) &&
-           (lpToolInfo->uId == toolPtr->uId))
-           return nTool;
-    }
-
-    return -1;
-}
-
-
-static INT
-TOOLTIPS_GetToolFromInfoW (const TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
+TOOLTIPS_GetToolFromInfoT (const TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
 {
     TTTOOL_INFO *toolPtr;
     UINT nTool;
@@ -1020,19 +999,16 @@ TOOLTIPS_Activate (TOOLTIPS_INFO *infoPtr, BOOL activate)
 
 
 static LRESULT
-TOOLTIPS_AddToolA (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpToolInfo)
+TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
 {
     TTTOOL_INFO *toolPtr;
     INT nResult;
 
-    if (lpToolInfo == NULL)
-       return FALSE;
-    if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
-       return FALSE;
+    if (!ti) return FALSE;
 
     TRACE("add tool (%p) %p %ld%s!\n",
-          infoPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
-          (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
+          infoPtr->hwndSelf, ti->hwnd, ti->uId,
+          (ti->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
 
     if (infoPtr->uNumTools == 0) {
        infoPtr->tools = Alloc (sizeof(TTTOOL_INFO));
@@ -1051,39 +1027,43 @@ TOOLTIPS_AddToolA (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpToolInfo)
     infoPtr->uNumTools++;
 
     /* copy tool data */
-    toolPtr->uFlags = lpToolInfo->uFlags;
-    toolPtr->hwnd   = lpToolInfo->hwnd;
-    toolPtr->uId    = lpToolInfo->uId;
-    toolPtr->rect   = lpToolInfo->rect;
-    toolPtr->hinst  = lpToolInfo->hinst;
-
-    if (IS_INTRESOURCE(lpToolInfo->lpszText)) {
-       TRACE("add string id %x!\n", LOWORD(lpToolInfo->lpszText));
-       toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
-    }
-    else if (lpToolInfo->lpszText) {
-       if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA) {
+    toolPtr->uFlags = ti->uFlags;
+    toolPtr->hwnd   = ti->hwnd;
+    toolPtr->uId    = ti->uId;
+    toolPtr->rect   = ti->rect;
+    toolPtr->hinst  = ti->hinst;
+
+    if (IS_INTRESOURCE(ti->lpszText)) {
+       TRACE("add string id %x\n", LOWORD(ti->lpszText));
+       toolPtr->lpszText = ti->lpszText;
+    }
+    else if (ti->lpszText) {
+       if (TOOLTIPS_IsCallbackString(ti->lpszText, isW)) {
            TRACE("add CALLBACK!\n");
            toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
        }
+       else if (isW) {
+           INT len = lstrlenW (ti->lpszText);
+           TRACE("add text %s!\n", debugstr_w(ti->lpszText));
+           toolPtr->lpszText = Alloc ((len + 1)*sizeof(WCHAR));
+           strcpyW (toolPtr->lpszText, ti->lpszText);
+       }
        else {
-           INT len = MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
-                                         NULL, 0);
-           TRACE("add text \"%s\"!\n", lpToolInfo->lpszText);
+           INT len = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText, -1, NULL, 0);
+           TRACE("add text \"%s\"!\n", (LPSTR)ti->lpszText);
            toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
-           MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
-                               toolPtr->lpszText, len);
+           MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText, -1, toolPtr->lpszText, len);
        }
     }
 
-    if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
-       toolPtr->lParam = lpToolInfo->lParam;
+    if (ti->cbSize >= TTTOOLINFOW_V2_SIZE)
+       toolPtr->lParam = ti->lParam;
 
     /* install subclassing hook */
     if (toolPtr->uFlags & TTF_SUBCLASS) {
        if (toolPtr->uFlags & TTF_IDISHWND) {
            SetWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1,
-                              (DWORD_PTR)infoPtr->hwndSelf);
+                             (DWORD_PTR)infoPtr->hwndSelf);
        }
        else {
            SetWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1,
@@ -1092,8 +1072,8 @@ TOOLTIPS_AddToolA (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpToolInfo)
        TRACE("subclassing installed!\n");
     }
 
-    nResult = (INT) SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
-                                 (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);
+    nResult = SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
+                            (WPARAM)infoPtr->hwndSelf, NF_QUERY);
     if (nResult == NFR_ANSI) {
         toolPtr->bNotifyUnicode = FALSE;
        TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
@@ -1109,102 +1089,24 @@ TOOLTIPS_AddToolA (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpToolInfo)
 
 
 static LRESULT
-TOOLTIPS_AddToolW (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
+TOOLTIPS_DelToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
 {
     TTTOOL_INFO *toolPtr;
-    INT nResult;
-
-    if (lpToolInfo == NULL)
-       return FALSE;
-    if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
-       return FALSE;
-
-    TRACE("add tool (%p) %p %ld%s!\n",
-          infoPtr->hwndSelf, lpToolInfo->hwnd, lpToolInfo->uId,
-          (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
-
-    if (infoPtr->uNumTools == 0) {
-       infoPtr->tools = Alloc (sizeof(TTTOOL_INFO));
-       toolPtr = infoPtr->tools;
-    }
-    else {
-       TTTOOL_INFO *oldTools = infoPtr->tools;
-       infoPtr->tools =
-           Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
-       memcpy (infoPtr->tools, oldTools,
-               infoPtr->uNumTools * sizeof(TTTOOL_INFO));
-       Free (oldTools);
-       toolPtr = &infoPtr->tools[infoPtr->uNumTools];
-    }
-
-    infoPtr->uNumTools++;
-
-    /* copy tool data */
-    toolPtr->uFlags = lpToolInfo->uFlags;
-    toolPtr->hwnd   = lpToolInfo->hwnd;
-    toolPtr->uId    = lpToolInfo->uId;
-    toolPtr->rect   = lpToolInfo->rect;
-    toolPtr->hinst  = lpToolInfo->hinst;
-
-    if (IS_INTRESOURCE(lpToolInfo->lpszText)) {
-       TRACE("add string id %x\n", LOWORD(lpToolInfo->lpszText));
-       toolPtr->lpszText = lpToolInfo->lpszText;
-    }
-    else if (lpToolInfo->lpszText) {
-       if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW) {
-           TRACE("add CALLBACK!\n");
-           toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
-       }
-       else {
-           INT len = lstrlenW (lpToolInfo->lpszText);
-           TRACE("add text %s!\n",
-                  debugstr_w(lpToolInfo->lpszText));
-           toolPtr->lpszText = Alloc ((len + 1)*sizeof(WCHAR));
-           strcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
-       }
-    }
-
-    if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
-       toolPtr->lParam = lpToolInfo->lParam;
-
-    /* install subclassing hook */
-    if (toolPtr->uFlags & TTF_SUBCLASS) {
-       if (toolPtr->uFlags & TTF_IDISHWND) {
-           SetWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1,
-                             (DWORD_PTR)infoPtr->hwndSelf);
-       }
-       else {
-           SetWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1,
-                             (DWORD_PTR)infoPtr->hwndSelf);
-       }
-       TRACE("subclassing installed!\n");
-    }
-
-    nResult = (INT) SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
-                                 (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);
-    if (nResult == NFR_ANSI) {
-        toolPtr->bNotifyUnicode = FALSE;
-       TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
-    } else if (nResult == NFR_UNICODE) {
-        toolPtr->bNotifyUnicode = TRUE;
-       TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
-    } else {
-        TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
-    }
-
-    return TRUE;
-}
+    INT nTool;
 
+    if (!ti) return 0;
+    if (isW && ti->cbSize > TTTOOLINFOW_V2_SIZE &&
+               ti->cbSize != TTTOOLINFOW_V3_SIZE)
+       return 0;
+    if (infoPtr->uNumTools == 0)
+       return 0;
 
-static void
-TOOLTIPS_DelToolCommon (TOOLTIPS_INFO *infoPtr, INT nTool)
-{
-    TTTOOL_INFO *toolPtr;
+    nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
 
     TRACE("tool %d\n", nTool);
 
     if (nTool == -1)
-        return;
+        return 0;
 
     /* make sure the tooltip has disappeared before deleting it */
     TOOLTIPS_Hide(infoPtr);
@@ -1270,88 +1172,18 @@ TOOLTIPS_DelToolCommon (TOOLTIPS_INFO *infoPtr, INT nTool)
         infoPtr->nCurrentTool--;
 
     infoPtr->uNumTools--;
-}
-
-static LRESULT
-TOOLTIPS_DelToolA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo)
-{
-    INT nTool;
-
-    if (lpToolInfo == NULL)
-       return 0;
-    if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
-       return 0;
-    if (infoPtr->uNumTools == 0)
-       return 0;
-
-    nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
-
-    TOOLTIPS_DelToolCommon (infoPtr, nTool);
 
     return 0;
 }
 
-
-static LRESULT
-TOOLTIPS_DelToolW (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOW lpToolInfo)
-{
-    INT nTool;
-
-    if (lpToolInfo == NULL)
-       return 0;
-    if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
-       return 0;
-    if (infoPtr->uNumTools == 0)
-       return 0;
-
-    nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
-
-    TOOLTIPS_DelToolCommon (infoPtr, nTool);
-
-    return 0;
-}
-
-
-static LRESULT
-TOOLTIPS_EnumToolsA (const TOOLTIPS_INFO *infoPtr, UINT uIndex, LPTTTOOLINFOA lpToolInfo)
-{
-    TTTOOL_INFO *toolPtr;
-
-    if (lpToolInfo == NULL)
-       return FALSE;
-    if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
-       return FALSE;
-    if (uIndex >= infoPtr->uNumTools)
-       return FALSE;
-
-    TRACE("index=%u\n", uIndex);
-
-    toolPtr = &infoPtr->tools[uIndex];
-
-    /* copy tool data */
-    lpToolInfo->uFlags   = toolPtr->uFlags;
-    lpToolInfo->hwnd     = toolPtr->hwnd;
-    lpToolInfo->uId      = toolPtr->uId;
-    lpToolInfo->rect     = toolPtr->rect;
-    lpToolInfo->hinst    = toolPtr->hinst;
-/*    lpToolInfo->lpszText = toolPtr->lpszText; */
-    lpToolInfo->lpszText = NULL;  /* FIXME */
-
-    if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
-       lpToolInfo->lParam = toolPtr->lParam;
-
-    return TRUE;
-}
-
-
 static LRESULT
-TOOLTIPS_EnumToolsW (const TOOLTIPS_INFO *infoPtr, UINT uIndex, LPTTTOOLINFOW lpToolInfo)
+TOOLTIPS_EnumToolsT (const TOOLTIPS_INFO *infoPtr, UINT uIndex, TTTOOLINFOW *ti,
+                     BOOL isW)
 {
     TTTOOL_INFO *toolPtr;
 
-    if (lpToolInfo == NULL)
-       return FALSE;
-    if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
+    if (!ti) return FALSE;
+    if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
        return FALSE;
     if (uIndex >= infoPtr->uNumTools)
        return FALSE;
@@ -1361,16 +1193,16 @@ TOOLTIPS_EnumToolsW (const TOOLTIPS_INFO *infoPtr, UINT uIndex, LPTTTOOLINFOW lp
     toolPtr = &infoPtr->tools[uIndex];
 
     /* copy tool data */
-    lpToolInfo->uFlags   = toolPtr->uFlags;
-    lpToolInfo->hwnd     = toolPtr->hwnd;
-    lpToolInfo->uId      = toolPtr->uId;
-    lpToolInfo->rect     = toolPtr->rect;
-    lpToolInfo->hinst    = toolPtr->hinst;
-/*    lpToolInfo->lpszText = toolPtr->lpszText; */
-    lpToolInfo->lpszText = NULL;  /* FIXME */
+    ti->uFlags   = toolPtr->uFlags;
+    ti->hwnd     = toolPtr->hwnd;
+    ti->uId      = toolPtr->uId;
+    ti->rect     = toolPtr->rect;
+    ti->hinst    = toolPtr->hinst;
+/*    ti->lpszText = toolPtr->lpszText; */
+    ti->lpszText = NULL;  /* FIXME */
 
-    if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
-       lpToolInfo->lParam = toolPtr->lParam;
+    if (ti->cbSize >= TTTOOLINFOA_V2_SIZE)
+       ti->lParam = toolPtr->lParam;
 
     return TRUE;
 }
@@ -1386,7 +1218,7 @@ TOOLTIPS_GetBubbleSize (const TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolI
     if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
        return FALSE;
 
-    nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
+    nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, lpToolInfo);
     if (nTool == -1) return 0;
 
     TRACE("tool %d\n", nTool);
@@ -1398,58 +1230,26 @@ TOOLTIPS_GetBubbleSize (const TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolI
 }
 
 static LRESULT
-TOOLTIPS_GetCurrentToolA (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo)
-{
-    TTTOOL_INFO *toolPtr;
-
-    if (lpToolInfo) {
-        if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
-            return FALSE;
-
-       if (infoPtr->nCurrentTool > -1) {
-           toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
-
-           /* copy tool data */
-           lpToolInfo->uFlags   = toolPtr->uFlags;
-           lpToolInfo->rect     = toolPtr->rect;
-           lpToolInfo->hinst    = toolPtr->hinst;
-/*         lpToolInfo->lpszText = toolPtr->lpszText; */
-           lpToolInfo->lpszText = NULL;  /* FIXME */
-
-           if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
-               lpToolInfo->lParam = toolPtr->lParam;
-
-           return TRUE;
-       }
-       else
-           return FALSE;
-    }
-    else
-       return (infoPtr->nCurrentTool != -1);
-}
-
-
-static LRESULT
-TOOLTIPS_GetCurrentToolW (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOW lpToolInfo)
+TOOLTIPS_GetCurrentToolT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL isW)
 {
     TTTOOL_INFO *toolPtr;
 
-    if (lpToolInfo) {
-        if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
+    if (ti) {
+        if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
             return FALSE;
 
        if (infoPtr->nCurrentTool > -1) {
            toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
 
            /* copy tool data */
-           lpToolInfo->uFlags   = toolPtr->uFlags;
-           lpToolInfo->rect     = toolPtr->rect;
-           lpToolInfo->hinst    = toolPtr->hinst;
-/*         lpToolInfo->lpszText = toolPtr->lpszText; */
-           lpToolInfo->lpszText = NULL;  /* FIXME */
+           ti->uFlags   = toolPtr->uFlags;
+           ti->rect     = toolPtr->rect;
+           ti->hinst    = toolPtr->hinst;
+/*         ti->lpszText = toolPtr->lpszText; */
+           ti->lpszText = NULL;  /* FIXME */
 
-           if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
-               lpToolInfo->lParam = toolPtr->lParam;
+           if (ti->cbSize >= TTTOOLINFOW_V2_SIZE)
+               ti->lParam = toolPtr->lParam;
 
            return TRUE;
        }
@@ -1504,50 +1304,36 @@ TOOLTIPS_GetMaxTipWidth (const TOOLTIPS_INFO *infoPtr)
 
 
 static LRESULT
-TOOLTIPS_GetTextA (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo)
+TOOLTIPS_GetTextT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL isW)
 {
-    WCHAR buffer[INFOTIPSIZE];
     INT nTool;
 
-    if (lpToolInfo == NULL)
-       return 0;
-    if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
+    if (!ti) return 0;
+    if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
        return 0;
 
-    nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
+    nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
     if (nTool == -1) return 0;
 
-    /* NB this API is broken, there is no way for the app to determine
-       what size buffer it requires nor a way to specify how long the
-       one it supplies is.  We'll assume it's up to INFOTIPSIZE */
-
-    buffer[0] = '\0';
-    TOOLTIPS_GetTipText(infoPtr, nTool, buffer);
-    WideCharToMultiByte(CP_ACP, 0, buffer, -1, lpToolInfo->lpszText,
-                                               INFOTIPSIZE, NULL, NULL);
-
-    return 0;
-}
-
-
-static LRESULT
-TOOLTIPS_GetTextW (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOW lpToolInfo)
-{
-    INT nTool;
-
-    if (lpToolInfo == NULL)
-       return 0;
-    if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
+    if (infoPtr->tools[nTool].lpszText == NULL)
        return 0;
 
-    nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
-    if (nTool == -1) return 0;
+    if (isW) {
+        ti->lpszText[0] = '\0';
+        TOOLTIPS_GetTipText(infoPtr, nTool, ti->lpszText);
+    }
+    else {
+        WCHAR buffer[INFOTIPSIZE];
 
-    if (infoPtr->tools[nTool].lpszText == NULL)
-       return 0;
+        /* NB this API is broken, there is no way for the app to determine
+           what size buffer it requires nor a way to specify how long the
+           one it supplies is.  We'll assume it's up to INFOTIPSIZE */
 
-    lpToolInfo->lpszText[0] = '\0';
-    TOOLTIPS_GetTipText(infoPtr, nTool, lpToolInfo->lpszText);
+        buffer[0] = '\0';
+        TOOLTIPS_GetTipText(infoPtr, nTool, buffer);
+        WideCharToMultiByte(CP_ACP, 0, buffer, -1, (LPSTR)ti->lpszText,
+                                                   INFOTIPSIZE, NULL, NULL);
+    }
 
     return 0;
 }
@@ -1575,19 +1361,18 @@ TOOLTIPS_GetToolCount (const TOOLTIPS_INFO *infoPtr)
 
 
 static LRESULT
-TOOLTIPS_GetToolInfoA (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo)
+TOOLTIPS_GetToolInfoT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL isW)
 {
     TTTOOL_INFO *toolPtr;
     INT nTool;
 
-    if (lpToolInfo == NULL)
-       return FALSE;
-    if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
+    if (!ti) return FALSE;
+    if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
        return FALSE;
     if (infoPtr->uNumTools == 0)
        return FALSE;
 
-    nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
+    nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
     if (nTool == -1)
        return FALSE;
 
@@ -1596,89 +1381,22 @@ TOOLTIPS_GetToolInfoA (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo)
     toolPtr = &infoPtr->tools[nTool];
 
     /* copy tool data */
-    lpToolInfo->uFlags   = toolPtr->uFlags;
-    lpToolInfo->rect     = toolPtr->rect;
-    lpToolInfo->hinst    = toolPtr->hinst;
+    ti->uFlags   = toolPtr->uFlags;
+    ti->rect     = toolPtr->rect;
+    ti->hinst    = toolPtr->hinst;
 /*    lpToolInfo->lpszText = toolPtr->lpszText; */
-    lpToolInfo->lpszText = NULL;  /* FIXME */
+    ti->lpszText = NULL;  /* FIXME */
 
-    if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
-       lpToolInfo->lParam = toolPtr->lParam;
+    if (ti->cbSize >= TTTOOLINFOW_V2_SIZE)
+       ti->lParam = toolPtr->lParam;
 
     return TRUE;
 }
 
 
 static LRESULT
-TOOLTIPS_GetToolInfoW (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOW lpToolInfo)
-{
-    TTTOOL_INFO *toolPtr;
-    INT nTool;
-
-    if (lpToolInfo == NULL)
-       return FALSE;
-    if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
-       return FALSE;
-    if (infoPtr->uNumTools == 0)
-       return FALSE;
-
-    nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
-    if (nTool == -1)
-       return FALSE;
-
-    TRACE("tool %d\n", nTool);
-
-    toolPtr = &infoPtr->tools[nTool];
-
-    /* copy tool data */
-    lpToolInfo->uFlags   = toolPtr->uFlags;
-    lpToolInfo->rect     = toolPtr->rect;
-    lpToolInfo->hinst    = toolPtr->hinst;
-/*    lpToolInfo->lpszText = toolPtr->lpszText; */
-    lpToolInfo->lpszText = NULL;  /* FIXME */
-
-    if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
-       lpToolInfo->lParam = toolPtr->lParam;
-
-    return TRUE;
-}
-
-
-static LRESULT
-TOOLTIPS_HitTestA (const TOOLTIPS_INFO *infoPtr, LPTTHITTESTINFOA lptthit)
-{
-    TTTOOL_INFO *toolPtr;
-    INT nTool;
-
-    if (lptthit == 0)
-       return FALSE;
-
-    nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
-    if (nTool == -1)
-       return FALSE;
-
-    TRACE("tool %d!\n", nTool);
-
-    /* copy tool data */
-    if (lptthit->ti.cbSize >= sizeof(TTTOOLINFOA)) {
-       toolPtr = &infoPtr->tools[nTool];
-
-       lptthit->ti.uFlags   = toolPtr->uFlags;
-       lptthit->ti.hwnd     = toolPtr->hwnd;
-       lptthit->ti.uId      = toolPtr->uId;
-       lptthit->ti.rect     = toolPtr->rect;
-       lptthit->ti.hinst    = toolPtr->hinst;
-/*     lptthit->ti.lpszText = toolPtr->lpszText; */
-       lptthit->ti.lpszText = NULL;  /* FIXME */
-       lptthit->ti.lParam   = toolPtr->lParam;
-    }
-
-    return TRUE;
-}
-
-
-static LRESULT
-TOOLTIPS_HitTestW (const TOOLTIPS_INFO *infoPtr, LPTTHITTESTINFOW lptthit)
+TOOLTIPS_HitTestT (const TOOLTIPS_INFO *infoPtr, LPTTHITTESTINFOW lptthit,
+                   BOOL isW)
 {
     TTTOOL_INFO *toolPtr;
     INT nTool;
@@ -1693,7 +1411,7 @@ TOOLTIPS_HitTestW (const TOOLTIPS_INFO *infoPtr, LPTTHITTESTINFOW lptthit)
     TRACE("tool %d!\n", nTool);
 
     /* copy tool data */
-    if (lptthit->ti.cbSize >= sizeof(TTTOOLINFOW)) {
+    if (lptthit->ti.cbSize >= TTTOOLINFOW_V1_SIZE) {
        toolPtr = &infoPtr->tools[nTool];
 
        lptthit->ti.uFlags   = toolPtr->uFlags;
@@ -1703,7 +1421,8 @@ TOOLTIPS_HitTestW (const TOOLTIPS_INFO *infoPtr, LPTTHITTESTINFOW lptthit)
        lptthit->ti.hinst    = toolPtr->hinst;
 /*     lptthit->ti.lpszText = toolPtr->lpszText; */
        lptthit->ti.lpszText = NULL;  /* FIXME */
-       lptthit->ti.lParam   = toolPtr->lParam;
+       if (lptthit->ti.cbSize >= TTTOOLINFOW_V2_SIZE)
+           lptthit->ti.lParam   = toolPtr->lParam;
     }
 
     return TRUE;
@@ -1711,44 +1430,21 @@ TOOLTIPS_HitTestW (const TOOLTIPS_INFO *infoPtr, LPTTHITTESTINFOW lptthit)
 
 
 static LRESULT
-TOOLTIPS_NewToolRectA (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpti)
+TOOLTIPS_NewToolRectT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
 {
     INT nTool;
 
-    if (lpti == NULL)
-       return 0;
-    if (lpti->cbSize < TTTOOLINFOA_V1_SIZE)
+    if (!ti) return 0;
+    if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
        return FALSE;
 
-    nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
+    nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
 
-    TRACE("nTool = %d, rect = %s\n", nTool, wine_dbgstr_rect(&lpti->rect));
+    TRACE("nTool = %d, rect = %s\n", nTool, wine_dbgstr_rect(&ti->rect));
 
     if (nTool == -1) return 0;
 
-    infoPtr->tools[nTool].rect = lpti->rect;
-
-    return 0;
-}
-
-
-static LRESULT
-TOOLTIPS_NewToolRectW (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpti)
-{
-    INT nTool;
-
-    if (lpti == NULL)
-       return 0;
-    if (lpti->cbSize < TTTOOLINFOW_V1_SIZE)
-       return FALSE;
-
-    nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpti);
-
-    TRACE("nTool = %d, rect = %s\n", nTool, wine_dbgstr_rect(&lpti->rect));
-
-    if (nTool == -1) return 0;
-
-    infoPtr->tools[nTool].rect = lpti->rect;
+    infoPtr->tools[nTool].rect = ti->rect;
 
     return 0;
 }
@@ -1908,37 +1604,8 @@ TOOLTIPS_SetTipTextColor (TOOLTIPS_INFO *infoPtr, COLORREF clrText)
 
 
 static LRESULT
-TOOLTIPS_SetTitleA (TOOLTIPS_INFO *infoPtr, UINT_PTR uTitleIcon, LPCSTR pszTitle)
-{
-    UINT size;
-
-    TRACE("hwnd = %p, title = %s, icon = %p\n", infoPtr->hwndSelf, debugstr_a(pszTitle),
-        (void*)uTitleIcon);
-
-    Free(infoPtr->pszTitle);
-
-    if (pszTitle)
-    {
-        size = sizeof(WCHAR)*MultiByteToWideChar(CP_ACP, 0, pszTitle, -1, NULL, 0);
-        infoPtr->pszTitle = Alloc(size);
-        if (!infoPtr->pszTitle)
-            return FALSE;
-        MultiByteToWideChar(CP_ACP, 0, pszTitle, -1, infoPtr->pszTitle, size/sizeof(WCHAR));
-    }
-    else
-        infoPtr->pszTitle = NULL;
-
-    if (uTitleIcon <= TTI_ERROR)
-        infoPtr->hTitleIcon = hTooltipIcons[uTitleIcon];
-    else
-        infoPtr->hTitleIcon = CopyIcon((HICON)uTitleIcon);
-
-    return TRUE;
-}
-
-
-static LRESULT
-TOOLTIPS_SetTitleW (TOOLTIPS_INFO *infoPtr, UINT_PTR uTitleIcon, LPCWSTR pszTitle)
+TOOLTIPS_SetTitleT (TOOLTIPS_INFO *infoPtr, UINT_PTR uTitleIcon, LPCWSTR pszTitle,
+                    BOOL isW)
 {
     UINT size;
 
@@ -1949,11 +1616,22 @@ TOOLTIPS_SetTitleW (TOOLTIPS_INFO *infoPtr, UINT_PTR uTitleIcon, LPCWSTR pszTitl
 
     if (pszTitle)
     {
-        size = (strlenW(pszTitle)+1)*sizeof(WCHAR);
-        infoPtr->pszTitle = Alloc(size);
-        if (!infoPtr->pszTitle)
-            return FALSE;
-        memcpy(infoPtr->pszTitle, pszTitle, size);
+        if (isW)
+        {
+            size = (strlenW(pszTitle)+1)*sizeof(WCHAR);
+            infoPtr->pszTitle = Alloc(size);
+            if (!infoPtr->pszTitle)
+                return FALSE;
+            memcpy(infoPtr->pszTitle, pszTitle, size);
+        }
+        else
+        {
+            size = sizeof(WCHAR)*MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszTitle, -1, NULL, 0);
+            infoPtr->pszTitle = Alloc(size);
+            if (!infoPtr->pszTitle)
+                return FALSE;
+            MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszTitle, -1, infoPtr->pszTitle, size/sizeof(WCHAR));
+        }
     }
     else
         infoPtr->pszTitle = NULL;
@@ -1970,17 +1648,16 @@ TOOLTIPS_SetTitleW (TOOLTIPS_INFO *infoPtr, UINT_PTR uTitleIcon, LPCWSTR pszTitl
 
 
 static LRESULT
-TOOLTIPS_SetToolInfoA (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpToolInfo)
+TOOLTIPS_SetToolInfoT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
 {
     TTTOOL_INFO *toolPtr;
     INT nTool;
 
-    if (lpToolInfo == NULL)
-       return 0;
-    if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
+    if (!ti) return 0;
+    if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
        return 0;
 
-    nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
+    nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
     if (nTool == -1) return 0;
 
     TRACE("tool %d\n", nTool);
@@ -1988,74 +1665,18 @@ TOOLTIPS_SetToolInfoA (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpToolInfo)
     toolPtr = &infoPtr->tools[nTool];
 
     /* copy tool data */
-    toolPtr->uFlags = lpToolInfo->uFlags;
-    toolPtr->hwnd   = lpToolInfo->hwnd;
-    toolPtr->uId    = lpToolInfo->uId;
-    toolPtr->rect   = lpToolInfo->rect;
-    toolPtr->hinst  = lpToolInfo->hinst;
-
-    if (IS_INTRESOURCE(lpToolInfo->lpszText)) {
-       TRACE("set string id %x\n", LOWORD(lpToolInfo->lpszText));
-       toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
-    }
-    else if (lpToolInfo->lpszText) {
-       if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
-           toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
-       else {
-           if ( (toolPtr->lpszText) &&
-                !IS_INTRESOURCE(toolPtr->lpszText) ) {
-               if( toolPtr->lpszText != LPSTR_TEXTCALLBACKW)
-                    Free (toolPtr->lpszText);
-               toolPtr->lpszText = NULL;
-           }
-           if (lpToolInfo->lpszText) {
-               INT len = MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText,
-                                             -1, NULL, 0);
-               toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
-               MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
-                                   toolPtr->lpszText, len);
-           }
-       }
-    }
+    toolPtr->uFlags = ti->uFlags;
+    toolPtr->hwnd   = ti->hwnd;
+    toolPtr->uId    = ti->uId;
+    toolPtr->rect   = ti->rect;
+    toolPtr->hinst  = ti->hinst;
 
-    if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
-       toolPtr->lParam = lpToolInfo->lParam;
-
-    return 0;
-}
-
-
-static LRESULT
-TOOLTIPS_SetToolInfoW (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
-{
-    TTTOOL_INFO *toolPtr;
-    INT nTool;
-
-    if (lpToolInfo == NULL)
-       return 0;
-    if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
-       return 0;
-
-    nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
-    if (nTool == -1) return 0;
-
-    TRACE("tool %d\n", nTool);
-
-    toolPtr = &infoPtr->tools[nTool];
-
-    /* copy tool data */
-    toolPtr->uFlags = lpToolInfo->uFlags;
-    toolPtr->hwnd   = lpToolInfo->hwnd;
-    toolPtr->uId    = lpToolInfo->uId;
-    toolPtr->rect   = lpToolInfo->rect;
-    toolPtr->hinst  = lpToolInfo->hinst;
-
-    if (IS_INTRESOURCE(lpToolInfo->lpszText)) {
-       TRACE("set string id %x!\n", LOWORD(lpToolInfo->lpszText));
-       toolPtr->lpszText = lpToolInfo->lpszText;
+    if (IS_INTRESOURCE(ti->lpszText)) {
+       TRACE("set string id %x!\n", LOWORD(ti->lpszText));
+       toolPtr->lpszText = ti->lpszText;
     }
     else {
-       if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW)
+       if (TOOLTIPS_IsCallbackString(ti->lpszText, isW))
            toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
        else {
            if ( (toolPtr->lpszText) &&
@@ -2064,16 +1685,25 @@ TOOLTIPS_SetToolInfoW (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
                     Free (toolPtr->lpszText);
                toolPtr->lpszText = NULL;
            }
-           if (lpToolInfo->lpszText) {
-               INT len = lstrlenW (lpToolInfo->lpszText);
-               toolPtr->lpszText = Alloc ((len+1)*sizeof(WCHAR));
-               strcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
+           if (ti->lpszText) {
+               if (isW) {
+                   INT len = lstrlenW (ti->lpszText);
+                   toolPtr->lpszText = Alloc ((len+1)*sizeof(WCHAR));
+                   strcpyW (toolPtr->lpszText, ti->lpszText);
+               }
+               else {
+                   INT len = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText,
+                                             -1, NULL, 0);
+                   toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
+                   MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText, -1,
+                                       toolPtr->lpszText, len);
+               }
            }
        }
     }
 
-    if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
-       toolPtr->lParam = lpToolInfo->lParam;
+    if (ti->cbSize >= TTTOOLINFOW_V2_SIZE)
+       toolPtr->lParam = ti->lParam;
 
     if (infoPtr->nCurrentTool == nTool)
     {
@@ -2090,17 +1720,16 @@ TOOLTIPS_SetToolInfoW (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
 
 
 static LRESULT
-TOOLTIPS_TrackActivate (TOOLTIPS_INFO *infoPtr, BOOL track_activate, const TTTOOLINFOA *lpToolInfo)
+TOOLTIPS_TrackActivate (TOOLTIPS_INFO *infoPtr, BOOL track_activate, const TTTOOLINFOA *ti)
 {
     if (track_activate) {
 
-       if (lpToolInfo == NULL)
-           return 0;
-       if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
+       if (!ti) return 0;
+       if (ti->cbSize < TTTOOLINFOA_V1_SIZE)
            return FALSE;
 
        /* activate */
-       infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
+       infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoT (infoPtr, (const TTTOOLINFOW*)ti);
        if (infoPtr->nTrackTool != -1) {
            TRACE("activated!\n");
            infoPtr->bTrackActive = TRUE;
@@ -2149,72 +1778,16 @@ TOOLTIPS_Update (TOOLTIPS_INFO *infoPtr)
 
 
 static LRESULT
-TOOLTIPS_UpdateTipTextA (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOA *lpToolInfo)
+TOOLTIPS_UpdateTipTextT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
 {
     TTTOOL_INFO *toolPtr;
     INT nTool;
 
-    if (lpToolInfo == NULL)
-       return 0;
-    if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
+    if (!ti) return 0;
+    if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
        return FALSE;
 
-    nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
-    if (nTool == -1) return 0;
-
-    TRACE("tool %d\n", nTool);
-
-    toolPtr = &infoPtr->tools[nTool];
-
-    /* copy tool text */
-    toolPtr->hinst  = lpToolInfo->hinst;
-
-    if (IS_INTRESOURCE(lpToolInfo->lpszText)){
-       toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
-    }
-    else if (lpToolInfo->lpszText) {
-       if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
-           toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
-       else {
-           if ( (toolPtr->lpszText) &&
-                !IS_INTRESOURCE(toolPtr->lpszText) ) {
-               if( toolPtr->lpszText != LPSTR_TEXTCALLBACKW)
-                    Free (toolPtr->lpszText);
-               toolPtr->lpszText = NULL;
-           }
-           if (lpToolInfo->lpszText) {
-               INT len = MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText,
-                                             -1, NULL, 0);
-               toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
-               MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
-                                   toolPtr->lpszText, len);
-           }
-       }
-    }
-
-    if(infoPtr->nCurrentTool == -1) return 0;
-    /* force repaint */
-    if (infoPtr->bActive)
-       TOOLTIPS_Show (infoPtr, FALSE);
-    else if (infoPtr->bTrackActive)
-       TOOLTIPS_TrackShow (infoPtr);
-
-    return 0;
-}
-
-
-static LRESULT
-TOOLTIPS_UpdateTipTextW (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
-{
-    TTTOOL_INFO *toolPtr;
-    INT nTool;
-
-    if (lpToolInfo == NULL)
-       return 0;
-    if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
-       return FALSE;
-
-    nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
+    nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
     if (nTool == -1)
        return 0;
 
@@ -2223,13 +1796,13 @@ TOOLTIPS_UpdateTipTextW (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
     toolPtr = &infoPtr->tools[nTool];
 
     /* copy tool text */
-    toolPtr->hinst  = lpToolInfo->hinst;
+    toolPtr->hinst  = ti->hinst;
 
-    if (IS_INTRESOURCE(lpToolInfo->lpszText)){
-       toolPtr->lpszText = lpToolInfo->lpszText;
+    if (IS_INTRESOURCE(ti->lpszText)){
+       toolPtr->lpszText = ti->lpszText;
     }
-    else if (lpToolInfo->lpszText) {
-       if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW)
+    else if (ti->lpszText) {
+       if (TOOLTIPS_IsCallbackString(ti->lpszText, isW))
            toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
        else {
            if ( (toolPtr->lpszText)  &&
@@ -2238,10 +1811,19 @@ TOOLTIPS_UpdateTipTextW (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
                     Free (toolPtr->lpszText);
                toolPtr->lpszText = NULL;
            }
-           if (lpToolInfo->lpszText) {
-               INT len = lstrlenW (lpToolInfo->lpszText);
-               toolPtr->lpszText = Alloc ((len+1)*sizeof(WCHAR));
-               strcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
+           if (ti->lpszText) {
+               if (isW) {
+                   INT len = lstrlenW (ti->lpszText);
+                   toolPtr->lpszText = Alloc ((len+1)*sizeof(WCHAR));
+                   strcpyW (toolPtr->lpszText, ti->lpszText);
+               }
+               else {
+                   INT len = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText,
+                                               -1, NULL, 0);
+                   toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
+                   MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText, -1,
+                                       toolPtr->lpszText, len);
+               }
            }
        }
     }
@@ -2404,32 +1986,8 @@ TOOLTIPS_NCHitTest (const TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 static LRESULT
 TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
-    TTTOOL_INFO *toolPtr = infoPtr->tools;
-    INT nResult;
-
-    TRACE("hwnd=%p wParam=%lx lParam=%lx\n", infoPtr->hwndSelf, wParam, lParam);
+    FIXME ("hwnd=%p wParam=%lx lParam=%lx\n", infoPtr->hwndSelf, wParam, lParam);
 
-    if (lParam == NF_QUERY) {
-        if (toolPtr->bNotifyUnicode) {
-            return NFR_UNICODE;
-        } else {
-            return NFR_ANSI;
-        }
-    }
-    else if (lParam == NF_REQUERY) {
-        nResult = (INT) SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
-                    (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);
-        if (nResult == NFR_ANSI) {
-            toolPtr->bNotifyUnicode = FALSE;
-            TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
-        } else if (nResult == NFR_UNICODE) {
-            toolPtr->bNotifyUnicode = TRUE;
-            TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
-        } else {
-            TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
-        }
-        return nResult;
-    }
     return 0;
 }
 
@@ -2609,31 +2167,24 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLTIPS_Activate (infoPtr, (BOOL)wParam);
 
        case TTM_ADDTOOLA:
-           return TOOLTIPS_AddToolA (infoPtr, (LPTTTOOLINFOA)lParam);
-
        case TTM_ADDTOOLW:
-           return TOOLTIPS_AddToolW (infoPtr, (LPTTTOOLINFOW)lParam);
+           return TOOLTIPS_AddToolT (infoPtr, (LPTTTOOLINFOW)lParam, uMsg == TTM_ADDTOOLW);
 
        case TTM_DELTOOLA:
-           return TOOLTIPS_DelToolA (infoPtr, (LPTOOLINFOA)lParam);
-
        case TTM_DELTOOLW:
-           return TOOLTIPS_DelToolW (infoPtr, (LPTOOLINFOW)lParam);
-
+           return TOOLTIPS_DelToolT (infoPtr, (LPTOOLINFOW)lParam,
+                                      uMsg == TTM_DELTOOLW);
        case TTM_ENUMTOOLSA:
-           return TOOLTIPS_EnumToolsA (infoPtr, (UINT)wParam, (LPTTTOOLINFOA)lParam);
-
        case TTM_ENUMTOOLSW:
-           return TOOLTIPS_EnumToolsW (infoPtr, (UINT)wParam, (LPTTTOOLINFOW)lParam);
-
+           return TOOLTIPS_EnumToolsT (infoPtr, (UINT)wParam, (LPTTTOOLINFOW)lParam,
+                                        uMsg == TTM_ENUMTOOLSW);
        case TTM_GETBUBBLESIZE:
            return TOOLTIPS_GetBubbleSize (infoPtr, (LPTTTOOLINFOW)lParam);
 
        case TTM_GETCURRENTTOOLA:
-           return TOOLTIPS_GetCurrentToolA (infoPtr, (LPTTTOOLINFOA)lParam);
-
        case TTM_GETCURRENTTOOLW:
-           return TOOLTIPS_GetCurrentToolW (infoPtr, (LPTTTOOLINFOW)lParam);
+           return TOOLTIPS_GetCurrentToolT (infoPtr, (LPTTTOOLINFOW)lParam,
+                                             uMsg == TTM_GETCURRENTTOOLW);
 
        case TTM_GETDELAYTIME:
            return TOOLTIPS_GetDelayTime (infoPtr, (DWORD)wParam);
@@ -2645,10 +2196,9 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLTIPS_GetMaxTipWidth (infoPtr);
 
        case TTM_GETTEXTA:
-           return TOOLTIPS_GetTextA (infoPtr, (LPTTTOOLINFOA)lParam);
-
        case TTM_GETTEXTW:
-           return TOOLTIPS_GetTextW (infoPtr, (LPTTTOOLINFOW)lParam);
+           return TOOLTIPS_GetTextT (infoPtr, (LPTTTOOLINFOW)lParam,
+                                      uMsg == TTM_GETTEXTW);
 
        case TTM_GETTIPBKCOLOR:
            return TOOLTIPS_GetTipBkColor (infoPtr);
@@ -2660,23 +2210,18 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLTIPS_GetToolCount (infoPtr);
 
        case TTM_GETTOOLINFOA:
-           return TOOLTIPS_GetToolInfoA (infoPtr, (LPTTTOOLINFOA)lParam);
-
        case TTM_GETTOOLINFOW:
-           return TOOLTIPS_GetToolInfoW (infoPtr, (LPTTTOOLINFOW)lParam);
+           return TOOLTIPS_GetToolInfoT (infoPtr, (LPTTTOOLINFOW)lParam,
+                                          uMsg == TTM_GETTOOLINFOW);
 
        case TTM_HITTESTA:
-           return TOOLTIPS_HitTestA (infoPtr, (LPTTHITTESTINFOA)lParam);
-
        case TTM_HITTESTW:
-           return TOOLTIPS_HitTestW (infoPtr, (LPTTHITTESTINFOW)lParam);
-
+           return TOOLTIPS_HitTestT (infoPtr, (LPTTHITTESTINFOW)lParam,
+                                      uMsg == TTM_HITTESTW);
        case TTM_NEWTOOLRECTA:
-           return TOOLTIPS_NewToolRectA (infoPtr, (LPTTTOOLINFOA)lParam);
-
        case TTM_NEWTOOLRECTW:
-           return TOOLTIPS_NewToolRectW (infoPtr, (LPTTTOOLINFOW)lParam);
-
+           return TOOLTIPS_NewToolRectT (infoPtr, (LPTTTOOLINFOW)lParam,
+                                          uMsg == TTM_NEWTOOLRECTW);
        case TTM_POP:
            return TOOLTIPS_Pop (infoPtr);
 
@@ -2699,16 +2244,14 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLTIPS_SetTipTextColor (infoPtr, (COLORREF)wParam);
 
        case TTM_SETTITLEA:
-           return TOOLTIPS_SetTitleA (infoPtr, (UINT_PTR)wParam, (LPCSTR)lParam);
-
        case TTM_SETTITLEW:
-           return TOOLTIPS_SetTitleW (infoPtr, (UINT_PTR)wParam, (LPCWSTR)lParam);
+           return TOOLTIPS_SetTitleT (infoPtr, (UINT_PTR)wParam, (LPCWSTR)lParam,
+                                       uMsg == TTM_SETTITLEW);
 
        case TTM_SETTOOLINFOA:
-           return TOOLTIPS_SetToolInfoA (infoPtr, (LPTTTOOLINFOA)lParam);
-
        case TTM_SETTOOLINFOW:
-           return TOOLTIPS_SetToolInfoW (infoPtr, (LPTTTOOLINFOW)lParam);
+           return TOOLTIPS_SetToolInfoT (infoPtr, (LPTTTOOLINFOW)lParam,
+                                          uMsg == TTM_SETTOOLINFOW);
 
        case TTM_TRACKACTIVATE:
            return TOOLTIPS_TrackActivate (infoPtr, (BOOL)wParam, (LPTTTOOLINFOA)lParam);
@@ -2720,10 +2263,9 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLTIPS_Update (infoPtr);
 
        case TTM_UPDATETIPTEXTA:
-           return TOOLTIPS_UpdateTipTextA (infoPtr, (LPTTTOOLINFOA)lParam);
-
        case TTM_UPDATETIPTEXTW:
-           return TOOLTIPS_UpdateTipTextW (infoPtr, (LPTTTOOLINFOW)lParam);
+           return TOOLTIPS_UpdateTipTextT (infoPtr, (LPTTTOOLINFOW)lParam,
+                                            uMsg == TTM_UPDATETIPTEXTW);
 
        case TTM_WINDOWFROMPOINT:
            return TOOLTIPS_WindowFromPoint (hwnd, wParam, lParam);
index 5abc77f..c924b53 100644 (file)
@@ -135,18 +135,15 @@ static inline int notify (const TRACKBAR_INFO *infoPtr, INT code)
     return notify_hdr(infoPtr, code, &nmh);
 }
 
-static BOOL
-notify_with_scroll (const TRACKBAR_INFO *infoPtr, UINT code)
+static void notify_with_scroll (const TRACKBAR_INFO *infoPtr, UINT code)
 {
-    BOOL bVert = infoPtr->dwStyle & TBS_VERT;
+    UINT scroll = infoPtr->dwStyle & TBS_VERT ? WM_VSCROLL : WM_HSCROLL;
 
     TRACE("%x\n", code);
 
-    return (BOOL) SendMessageW (infoPtr->hwndNotify,
-                                bVert ? WM_VSCROLL : WM_HSCROLL,
-                               (WPARAM)code, (LPARAM)infoPtr->hwndSelf);
+    SendMessageW (infoPtr->hwndNotify, scroll, code, (LPARAM)infoPtr->hwndSelf);
 }
-    
+
 static void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
 {
     int tic;
index f7b1afa..8d2a6f3 100644 (file)
@@ -28,7 +28,7 @@
  *      We use callbackMask to keep track of fields to be updated.
  *
  * TODO:
- *   missing notifications: NM_SETCURSOR, TVN_GETINFOTIP, TVN_KEYDOWN,
+ *   missing notifications: TVN_GETINFOTIP, TVN_KEYDOWN,
  *      TVN_SETDISPINFO, TVN_SINGLEEXPAND
  *
  *   missing styles: TVS_FULLROWSELECT, TVS_INFOTIP, TVS_RTLREADING,
@@ -63,6 +63,8 @@
 #include "wine/unicode.h"
 #include "wine/debug.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(treeview);
+
 /* internal structures */
 
 typedef struct _TREEITEM    /* HTREEITEM is a _TREEINFO *. */
@@ -153,10 +155,10 @@ typedef struct tagTREEVIEW_INFO
   int           stateImageWidth;
   HDPA          items;
 
-  DWORD lastKeyPressTimestamp; /* Added */
-  WPARAM charCode; /* Added */
-  INT nSearchParamLength; /* Added */
-  WCHAR szSearchParam[ MAX_PATH ]; /* Added */
+  DWORD lastKeyPressTimestamp;
+  WPARAM charCode;
+  INT nSearchParamLength;
+  WCHAR szSearchParam[ MAX_PATH ];
 } TREEVIEW_INFO;
 
 
@@ -177,14 +179,6 @@ typedef struct tagTREEVIEW_INFO
 #define TV_EDIT_TIMER    2
 #define TV_EDIT_TIMER_SET 2
 
-
-VOID TREEVIEW_Register (VOID);
-VOID TREEVIEW_Unregister (VOID);
-
-
-WINE_DEFAULT_DEBUG_CHANNEL(treeview);
-
-
 #define TEXT_CALLBACK_SIZE 260
 
 #define TREEVIEW_LEFT_MARGIN 8
@@ -197,6 +191,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(treeview);
 #define OVERLAYIMAGEINDEX(x) (((x) >> 8) & 0x0f)
 #define ISVISIBLE(x)         ((x)->visibleOrder >= 0)
 
+#define GETLINECOLOR(x) ((x) == CLR_DEFAULT ? comctl32_color.clrGrayText   : (x))
+#define GETBKCOLOR(x)   ((x) == CLR_NONE    ? comctl32_color.clrWindow     : (x))
+#define GETTXTCOLOR(x)  ((x) == CLR_NONE    ? comctl32_color.clrWindowText : (x))
+#define GETINSCOLOR(x)  ((x) == CLR_DEFAULT ? comctl32_color.clrBtnText    : (x))
 
 static const WCHAR themeClass[] = { 'T','r','e','e','v','i','e','w',0 };
 
@@ -213,8 +211,6 @@ static LRESULT TREEVIEW_RButtonUp(const TREEVIEW_INFO *, const POINT *);
 static LRESULT TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel);
 static VOID TREEVIEW_UpdateScrollBars(TREEVIEW_INFO *infoPtr);
 static LRESULT TREEVIEW_HScroll(TREEVIEW_INFO *, WPARAM);
-static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND wParam, UINT lParam);
-
 
 /* Random Utilities *****************************************************/
 
@@ -842,6 +838,23 @@ TREEVIEW_HasChildren(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem)
     return wineItem->cChildren > 0;
 }
 
+static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand)
+{
+    INT format;
+
+    TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand);
+
+    if (nCommand != NF_REQUERY) return 0;
+
+    format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY);
+    TRACE("format=%d\n", format);
+
+    if (format != NFR_ANSI && format != NFR_UNICODE) return 0;
+
+    infoPtr->bNtfUnicode = (format == NFR_UNICODE);
+
+    return format;
+}
 
 /* Item Position ********************************************************/
 
@@ -1685,10 +1698,10 @@ TREEVIEW_GetImageList(const TREEVIEW_INFO *infoPtr, WPARAM wParam)
 
     switch (wParam)
     {
-    case (WPARAM)TVSIL_NORMAL:
+    case TVSIL_NORMAL:
        return (LRESULT)infoPtr->himlNormal;
 
-    case (WPARAM)TVSIL_STATE:
+    case TVSIL_STATE:
        return (LRESULT)infoPtr->himlState;
 
     default:
@@ -1742,7 +1755,7 @@ TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
 
     switch (wParam)
     {
-    case (WPARAM)TVSIL_NORMAL:
+    case TVSIL_NORMAL:
        himlOld = infoPtr->himlNormal;
        infoPtr->himlNormal = himlNew;
 
@@ -1757,7 +1770,7 @@ TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
 
        break;
 
-    case (WPARAM)TVSIL_STATE:
+    case TVSIL_STATE:
        himlOld = infoPtr->himlState;
        infoPtr->himlState = himlNew;
 
@@ -1871,6 +1884,7 @@ TREEVIEW_SetFont(TREEVIEW_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
     infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont;
 
     DeleteObject(infoPtr->hBoldFont);
+    DeleteObject(infoPtr->hUnderlineFont);
     infoPtr->hBoldFont = TREEVIEW_CreateBoldFont(infoPtr->hFont);
     infoPtr->hUnderlineFont = TREEVIEW_CreateUnderlineFont(infoPtr->hFont);
 
@@ -2313,15 +2327,14 @@ TREEVIEW_DrawItemLines(const TREEVIEW_INFO *infoPtr, HDC hdc, const TREEVIEW_ITE
                 & (TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS))
                > TVS_LINESATROOT);
     HBRUSH hbr, hbrOld;
-    COLORREF clrBk = infoPtr->clrBk == -1 ? comctl32_color.clrWindow:
-                                            infoPtr->clrBk;
+    COLORREF clrBk = GETBKCOLOR(infoPtr->clrBk);
 
     if (!lar && item->iLevel == 0)
        return;
 
     hbr    = CreateSolidBrush(clrBk);
     hbrOld = SelectObject(hdc, hbr);
-    
+
     centerx = (item->linesOffset + item->stateOffset) / 2;
     centery = (item->rect.top + item->rect.bottom) / 2;
 
@@ -2333,7 +2346,7 @@ TREEVIEW_DrawItemLines(const TREEVIEW_INFO *infoPtr, HDC hdc, const TREEVIEW_ITE
 
        /* Get a dotted grey pen */
         lb.lbStyle = BS_SOLID;
-        lb.lbColor = infoPtr->clrLine;
+        lb.lbColor = GETLINECOLOR(infoPtr->clrLine);
         hNewPen = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, NULL);
        hOldPen = SelectObject(hdc, hNewPen);
 
@@ -2402,16 +2415,20 @@ TREEVIEW_DrawItemLines(const TREEVIEW_INFO *infoPtr, HDC hdc, const TREEVIEW_ITE
                 LONG rectsize = min(height, width) / 4;
                 /* plussize = ceil(rectsize * 3/4) */
                 LONG plussize = (rectsize + 1) * 3 / 4;
-    
-                HPEN hNewPen  = CreatePen(PS_SOLID, 0, infoPtr->clrLine);
-                HPEN hOldPen  = SelectObject(hdc, hNewPen);
-    
+
+                HPEN new_pen  = CreatePen(PS_SOLID, 0, GETLINECOLOR(infoPtr->clrLine));
+                HPEN old_pen  = SelectObject(hdc, new_pen);
+
                 Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1,
                           centerx + rectsize + 2, centery + rectsize + 2);
-    
-                SelectObject(hdc, hOldPen);
-                DeleteObject(hNewPen);
-    
+
+                SelectObject(hdc, old_pen);
+                DeleteObject(new_pen);
+
+                /* draw +/- signs with current text color */
+                new_pen = CreatePen(PS_SOLID, 0, GETTXTCOLOR(infoPtr->clrText));
+                old_pen = SelectObject(hdc, new_pen);
+
                 if (height < 18 || width < 18)
                 {
                     MoveToEx(hdc, centerx - plussize + 1, centery, NULL);
@@ -2436,6 +2453,9 @@ TREEVIEW_DrawItemLines(const TREEVIEW_INFO *infoPtr, HDC hdc, const TREEVIEW_ITE
                         SetPixel(hdc, centerx + 1, centery, clrBk);
                     }
                 }
+
+                SelectObject(hdc, old_pen);
+                DeleteObject(new_pen);
             }
        }
     }
@@ -2473,22 +2493,16 @@ TREEVIEW_DrawItem(const TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem
        else
        {
            nmcdhdr.clrTextBk = comctl32_color.clrBtnFace;
-           if (infoPtr->clrText == -1)
-               nmcdhdr.clrText = comctl32_color.clrWindowText;
-           else
-               nmcdhdr.clrText = infoPtr->clrText;
+           nmcdhdr.clrText   = GETTXTCOLOR(infoPtr->clrText);
        }
     }
     else
     {
-       nmcdhdr.clrTextBk = infoPtr->clrBk == -1 ? comctl32_color.clrWindow:
-                                                   infoPtr->clrBk;
+       nmcdhdr.clrTextBk = GETBKCOLOR(infoPtr->clrBk);
        if ((infoPtr->dwStyle & TVS_TRACKSELECT) && (wineItem == infoPtr->hotItem))
            nmcdhdr.clrText = comctl32_color.clrHighlight;
-       else if (infoPtr->clrText == -1)
-           nmcdhdr.clrText = comctl32_color.clrWindowText;
        else
-           nmcdhdr.clrText = infoPtr->clrText;
+           nmcdhdr.clrText = GETTXTCOLOR(infoPtr->clrText);
     }
 
     hOldFont = SelectObject(hdc, TREEVIEW_FontForItem(infoPtr, wineItem));
@@ -2620,7 +2634,7 @@ TREEVIEW_DrawItem(const TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem
        int offset;
        int left, right;
 
-       hNewPen = CreatePen(PS_SOLID, 2, infoPtr->clrInsertMark);
+       hNewPen = CreatePen(PS_SOLID, 2, GETINSCOLOR(infoPtr->clrInsertMark));
        hOldPen = SelectObject(hdc, hNewPen);
 
        if (infoPtr->insertBeforeorAfter)
@@ -2788,19 +2802,27 @@ TREEVIEW_UpdateScrollBars(TREEVIEW_INFO *infoPtr)
        infoPtr->uInternalStatus &= ~TV_HSCROLL;
 }
 
+static void
+TREEVIEW_FillBkgnd(const TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
+{
+    HBRUSH hBrush;
+    COLORREF clrBk = GETBKCOLOR(infoPtr->clrBk);
+
+    hBrush =  CreateSolidBrush(clrBk);
+    FillRect(hdc, rc, hBrush);
+    DeleteObject(hBrush);
+}
+
 /* CtrlSpy doesn't mention this, but CorelDRAW's object manager needs it. */
 static LRESULT
-TREEVIEW_EraseBackground(const TREEVIEW_INFO *infoPtr, HDC hDC)
+TREEVIEW_EraseBackground(const TREEVIEW_INFO *infoPtr, HDC hdc)
 {
-    HBRUSH hBrush;
-    COLORREF clrBk = infoPtr->clrBk == -1 ? comctl32_color.clrWindow:
-                                            infoPtr->clrBk;
     RECT rect;
 
-    hBrush =  CreateSolidBrush(clrBk);
+    TRACE("%p\n", infoPtr);
+
     GetClientRect(infoPtr->hwnd, &rect);
-    FillRect(hDC, &rect, hBrush);
-    DeleteObject(hBrush);
+    TREEVIEW_FillBkgnd(infoPtr, hdc, &rect);
 
     return 1;
 }
@@ -2855,17 +2877,23 @@ TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
            TREEVIEW_SendCustomDrawNotify(infoPtr, CDDS_POSTPAINT, hdc, rect);
 }
 
+static inline void
+TREEVIEW_InvalidateItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
+{
+    if (item) InvalidateRect(infoPtr->hwnd, &item->rect, TRUE);
+}
+
 static void
 TREEVIEW_Invalidate(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
 {
-    if (item != NULL)
+    if (item)
        InvalidateRect(infoPtr->hwnd, &item->rect, TRUE);
     else
         InvalidateRect(infoPtr->hwnd, NULL, TRUE);
 }
 
 static LRESULT
-TREEVIEW_Paint(TREEVIEW_INFO *infoPtr, WPARAM wParam)
+TREEVIEW_Paint(TREEVIEW_INFO *infoPtr, HDC hdc_ref)
 {
     HDC hdc;
     PAINTSTRUCT ps;
@@ -2873,27 +2901,48 @@ TREEVIEW_Paint(TREEVIEW_INFO *infoPtr, WPARAM wParam)
 
     TRACE("\n");
 
-    if (wParam)
+    if (hdc_ref)
     {
-        hdc = (HDC)wParam;
-        GetClientRect(infoPtr->hwnd, &rc);        
-        TREEVIEW_EraseBackground(infoPtr, hdc);
+        hdc = hdc_ref;
+        GetClientRect(infoPtr->hwnd, &rc);
     }
     else
     {
         hdc = BeginPaint(infoPtr->hwnd, &ps);
-        rc = ps.rcPaint;
+        rc  = ps.rcPaint;
+        if(ps.fErase)
+            TREEVIEW_FillBkgnd(infoPtr, hdc, &rc);
     }
 
     if(infoPtr->bRedraw) /* WM_SETREDRAW sets bRedraw */
         TREEVIEW_Refresh(infoPtr, hdc, &rc);
 
-    if (!wParam)
+    if (!hdc_ref)
        EndPaint(infoPtr->hwnd, &ps);
 
     return 0;
 }
 
+static LRESULT
+TREEVIEW_PrintClient(TREEVIEW_INFO *infoPtr, HDC hdc, DWORD options)
+{
+    FIXME("Partial Stub: (hdc=%p options=0x%08x)\n", hdc, options);
+
+    if ((options & PRF_CHECKVISIBLE) && !IsWindowVisible(infoPtr->hwnd))
+        return 0;
+
+    if (options & PRF_ERASEBKGND)
+        TREEVIEW_EraseBackground(infoPtr, hdc);
+
+    if (options & PRF_CLIENT)
+    {
+        RECT rc;
+        GetClientRect(infoPtr->hwnd, &rc);
+        TREEVIEW_Refresh(infoPtr, hdc, &rc);
+    }
+
+    return 0;
+}
 
 /* Sorting **************************************************************/
 
@@ -3564,12 +3613,12 @@ TREEVIEW_Edit_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return DLGC_WANTARROWS | DLGC_WANTALLKEYS;
 
     case WM_KEYDOWN:
-       if (wParam == (WPARAM)VK_ESCAPE)
+       if (wParam == VK_ESCAPE)
        {
            bCancel = TRUE;
            break;
        }
-       else if (wParam == (WPARAM)VK_RETURN)
+       else if (wParam == VK_RETURN)
        {
            break;
        }
@@ -3679,7 +3728,6 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     HDC hdc;
     HFONT hOldFont=0;
     TEXTMETRICW textMetric;
-    static const WCHAR EditW[] = {'E','d','i','t',0};
 
     TRACE("%p %p\n", hwnd, hItem);
     if (!TREEVIEW_ValidItem(infoPtr, hItem))
@@ -3726,7 +3774,7 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     infoPtr->editItem = hItem;
 
     hwndEdit = CreateWindowExW(WS_EX_LEFT,
-                              EditW,
+                              WC_EDITW,
                               0,
                               WS_CHILD | WS_BORDER | ES_AUTOHSCROLL |
                               WS_CLIPSIBLINGS | ES_WANTRETURN |
@@ -4003,7 +4051,6 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
     HWND hwnd = infoPtr->hwnd;
     TVHITTESTINFO ht;
     BOOL bTrack, bDoLabelEdit;
-    HTREEITEM tempItem;
 
     /* If Edit control is active - kill it and return.
      * The best way to do it is to set focus to itself.
@@ -4026,10 +4073,8 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
     if(ht.hItem && (ht.flags & TVHT_ONITEM))
     {
         infoPtr->focusedItem = ht.hItem;
-        InvalidateRect(hwnd, &ht.hItem->rect, TRUE);
-
-        if(infoPtr->selectedItem)
-            InvalidateRect(hwnd, &(infoPtr->selectedItem->rect), TRUE);
+        TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
+        TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem);
     }
 
     bTrack = (ht.flags & TVHT_ONITEM)
@@ -4063,12 +4108,11 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
             if(infoPtr->focusedItem)
             {
                 /* refresh the item that was focused */
-                tempItem = infoPtr->focusedItem;
-                infoPtr->focusedItem = 0;
-                InvalidateRect(infoPtr->hwnd, &tempItem->rect, TRUE);
+                TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
+                infoPtr->focusedItem = NULL;
 
                 /* refresh the selected item to return the filled background */
-                InvalidateRect(infoPtr->hwnd, &(infoPtr->selectedItem->rect), TRUE);
+                TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem);
             }
 
            return 0;
@@ -4288,7 +4332,6 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect,
                      INT cause)
 {
     TREEVIEW_ITEM *prevSelect;
-    RECT rcFocused;
 
     assert(newSelect == NULL || TREEVIEW_ValidItem(infoPtr, newSelect));
 
@@ -4298,12 +4341,8 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect,
 
     /* reset and redraw focusedItem if focusedItem was set so we don't */
     /* have to worry about the previously focused item when we set a new one */
-    if(infoPtr->focusedItem)
-    {
-        rcFocused = (infoPtr->focusedItem)->rect;
-        infoPtr->focusedItem = 0;
-        InvalidateRect(infoPtr->hwnd, &rcFocused, TRUE);
-    }
+    TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
+    infoPtr->focusedItem = NULL;
 
     switch (action)
     {
@@ -4332,10 +4371,8 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect,
 
        TREEVIEW_EnsureVisible(infoPtr, infoPtr->selectedItem, FALSE);
 
-       if (prevSelect)
-           TREEVIEW_Invalidate(infoPtr, prevSelect);
-       if (newSelect)
-           TREEVIEW_Invalidate(infoPtr, newSelect);
+        TREEVIEW_InvalidateItem(infoPtr, prevSelect);
+        TREEVIEW_InvalidateItem(infoPtr, newSelect);
 
        TREEVIEW_SendTreeviewNotify(infoPtr,
                                    TVN_SELCHANGEDW,
@@ -4428,13 +4465,8 @@ TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item)
  *
  *  TREEVIEW_ProcessLetterKeys
  */
-static INT TREEVIEW_ProcessLetterKeys(
-    HWND hwnd, /* handle to the window */
-    WPARAM charCode, /* the character code, the actual character */
-    LPARAM keyData /* key data */
-    )
+static INT TREEVIEW_ProcessLetterKeys(TREEVIEW_INFO *infoPtr, WPARAM charCode, LPARAM keyData)
 {
-    TREEVIEW_INFO *infoPtr;
     HTREEITEM nItem;
     HTREEITEM endidx,idx;
     TVITEMEXW item;
@@ -4442,12 +4474,7 @@ static INT TREEVIEW_ProcessLetterKeys(
     DWORD timestamp,elapsed;
 
     /* simple parameter checking */
-    if (!hwnd || !charCode || !keyData)
-        return 0;
-
-    infoPtr=(TREEVIEW_INFO*)GetWindowLongPtrW(hwnd, 0);
-    if (!infoPtr)
-        return 0;
+    if (!charCode || !keyData) return 0;
 
     /* only allow the valid WM_CHARs through */
     if (!isalnum(charCode) &&
@@ -4856,11 +4883,14 @@ scroll:
 }
 
 static LRESULT
-TREEVIEW_MouseWheel(TREEVIEW_INFO *infoPtr, WPARAM wParam)
+TREEVIEW_MouseWheel(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
     short gcWheelDelta;
     UINT pulScrollLines = 3;
 
+    if (wParam & (MK_SHIFT | MK_CONTROL))
+        return DefWindowProcW(infoPtr->hwnd, WM_MOUSEWHEEL, wParam, lParam);
+
     if (infoPtr->firstVisible == NULL)
        return TRUE;
 
@@ -4978,10 +5008,10 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
 
     infoPtr->scrollX = 0;
 
-    infoPtr->clrBk   = -1; /* use system color */
-    infoPtr->clrText = -1;     /* use system color */
-    infoPtr->clrLine = RGB(128, 128, 128);
-    infoPtr->clrInsertMark = comctl32_color.clrBtnText;
+    infoPtr->clrBk   = CLR_NONE; /* use system color */
+    infoPtr->clrText = CLR_NONE; /* use system color */
+    infoPtr->clrLine = CLR_DEFAULT;
+    infoPtr->clrInsertMark = CLR_DEFAULT;
 
     /* hwndToolTip */
 
@@ -5048,7 +5078,11 @@ TREEVIEW_Destroy(TREEVIEW_INFO *infoPtr)
 {
     TRACE("\n");
 
+    /* free item data */
     TREEVIEW_RemoveTree(infoPtr);
+    /* root isn't freed with other items */
+    TREEVIEW_FreeItem(infoPtr, infoPtr->root);
+    DPA_Destroy(infoPtr->items);
 
     /* tool tip is automatically destroyed: we are its owner */
 
@@ -5236,12 +5270,10 @@ TREEVIEW_KeyDown(TREEVIEW_INFO *infoPtr, WPARAM wParam)
 static LRESULT
 TREEVIEW_MouseLeave (TREEVIEW_INFO * infoPtr)
 {
-    if (infoPtr->hotItem)
-    {
-        /* remove hot effect from item */
-        InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
-        infoPtr->hotItem = NULL;
-    }
+    /* remove hot effect from item */
+    TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
+    infoPtr->hotItem = NULL;
+
     return 0;
 }
 
@@ -5252,11 +5284,12 @@ TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, LPARAM lParam)
     TRACKMOUSEEVENT trackinfo;
     TREEVIEW_ITEM * item;
 
+    if (!(infoPtr->dwStyle & TVS_TRACKSELECT)) return 0;
+
     /* fill in the TRACKMOUSEEVENT struct */
     trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
     trackinfo.dwFlags = TME_QUERY;
     trackinfo.hwndTrack = infoPtr->hwnd;
-    trackinfo.dwHoverTime = HOVER_DEFAULT;
 
     /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
     _TrackMouseEvent(&trackinfo);
@@ -5265,6 +5298,9 @@ TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, LPARAM lParam)
     if(!(trackinfo.dwFlags & TME_LEAVE))
     {
         trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
+        trackinfo.hwndTrack = infoPtr->hwnd;
+        /* do it as fast as possible, minimal systimer latency will be used */
+        trackinfo.dwHoverTime = 1;
 
         /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
         /* and can properly deactivate the hot item */
@@ -5279,19 +5315,17 @@ TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, LPARAM lParam)
     if (item != infoPtr->hotItem)
     {
         /* redraw old hot item */
-        if (infoPtr->hotItem)
-            InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
+        TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
         infoPtr->hotItem = item;
         /* redraw new hot item */
-        if (infoPtr->hotItem)
-            InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
+        TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
     }
 
     return 0;
 }
 
 /* Draw themed border */
-static BOOL nc_paint (const TREEVIEW_INFO *infoPtr, HRGN region)
+static BOOL TREEVIEW_NCPaint (const TREEVIEW_INFO *infoPtr, HRGN region, LPARAM lParam)
 {
     HTHEME theme = GetWindowTheme (infoPtr->hwnd);
     HDC dc;
@@ -5300,7 +5334,8 @@ static BOOL nc_paint (const TREEVIEW_INFO *infoPtr, HRGN region)
     int cxEdge = GetSystemMetrics (SM_CXEDGE),
         cyEdge = GetSystemMetrics (SM_CYEDGE);
 
-    if (!theme) return FALSE;
+    if (!theme)
+        return DefWindowProcW (infoPtr->hwnd, WM_NCPAINT, (WPARAM)region, lParam);
 
     GetWindowRect(infoPtr->hwnd, &r);
 
@@ -5347,24 +5382,6 @@ TREEVIEW_Notify(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
     return DefWindowProcW(infoPtr->hwnd, WM_NOTIFY, wParam, lParam);
 }
 
-static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand)
-{
-    INT format;
-
-    TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand);
-
-    if (nCommand != NF_REQUERY) return 0;
-
-    format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY);
-    TRACE("format=%d\n", format);
-
-    if (format != NFR_ANSI && format != NFR_UNICODE) return 0;
-
-    infoPtr->bNtfUnicode = (format == NFR_UNICODE);
-
-    return format;
-}
-
 static LRESULT
 TREEVIEW_Size(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
@@ -5438,13 +5455,27 @@ TREEVIEW_SetCursor(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
     POINT pt;
     TREEVIEW_ITEM * item;
+    NMMOUSE nmmouse;
 
     GetCursorPos(&pt);
     ScreenToClient(infoPtr->hwnd, &pt);
 
     item = TREEVIEW_HitTestPoint(infoPtr, pt);
 
-    /* FIXME: send NM_SETCURSOR */
+    memset(&nmmouse, 0, sizeof(nmmouse));
+    nmmouse.hdr.hwndFrom = infoPtr->hwnd;
+    nmmouse.hdr.idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);
+    nmmouse.hdr.code = NM_SETCURSOR;
+    if (item)
+    {
+        nmmouse.dwItemSpec = (DWORD_PTR)item;
+        nmmouse.dwItemData = item->lParam;
+    }
+    nmmouse.pt.x = 0;
+    nmmouse.pt.y = 0;
+    nmmouse.dwHitInfo = lParam;
+    if (TREEVIEW_SendRealNotify(infoPtr, nmmouse.hdr.idFrom, (LPARAM)&nmmouse))
+        return 0;
 
     if (item && (infoPtr->dwStyle & TVS_TRACKSELECT))
     {
@@ -5483,7 +5514,7 @@ TREEVIEW_KillFocus(const TREEVIEW_INFO *infoPtr)
 }
 
 /* update theme after a WM_THEMECHANGED message */
-static LRESULT theme_changed(const TREEVIEW_INFO *infoPtr)
+static LRESULT TREEVIEW_ThemeChanged(const TREEVIEW_INFO *infoPtr)
 {
     HTHEME theme = GetWindowTheme (infoPtr->hwnd);
     CloseThemeData (theme);
@@ -5517,8 +5548,6 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return TREEVIEW_DeleteItem(infoPtr, (HTREEITEM)lParam);
 
     case TVM_EDITLABELA:
-       return (LRESULT)TREEVIEW_EditLabel(infoPtr, (HTREEITEM)lParam);
-
     case TVM_EDITLABELW:
        return (LRESULT)TREEVIEW_EditLabel(infoPtr, (HTREEITEM)lParam);
 
@@ -5558,11 +5587,9 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return 0;
 
     case TVM_GETITEMA:
-       return TREEVIEW_GetItemT(infoPtr, (LPTVITEMEXW)lParam, FALSE);
-
     case TVM_GETITEMW:
-       return TREEVIEW_GetItemT(infoPtr, (LPTVITEMEXW)lParam, TRUE);
-
+       return TREEVIEW_GetItemT(infoPtr, (LPTVITEMEXW)lParam,
+                                uMsg == TVM_GETITEMW);
     case TVM_GETITEMHEIGHT:
        return TREEVIEW_GetItemHeight(infoPtr);
 
@@ -5597,11 +5624,9 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return TREEVIEW_HitTest(infoPtr, (LPTVHITTESTINFO)lParam);
 
     case TVM_INSERTITEMA:
-       return TREEVIEW_InsertItemT(infoPtr, (LPTVINSERTSTRUCTW)lParam, FALSE);
-
     case TVM_INSERTITEMW:
-       return TREEVIEW_InsertItemT(infoPtr, (LPTVINSERTSTRUCTW)lParam, TRUE);
-
+       return TREEVIEW_InsertItemT(infoPtr, (LPTVINSERTSTRUCTW)lParam,
+                                   uMsg == TVM_INSERTITEMW);
     case TVM_SELECTITEM:
        return TREEVIEW_SelectItem(infoPtr, (INT)wParam, (HTREEITEM)lParam);
 
@@ -5621,11 +5646,9 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return TREEVIEW_SetInsertMarkColor(infoPtr, (COLORREF)lParam);
 
     case TVM_SETITEMA:
-       return TREEVIEW_SetItemT(infoPtr, (LPTVITEMEXW)lParam, FALSE);
-
     case TVM_SETITEMW:
-        return TREEVIEW_SetItemT(infoPtr, (LPTVITEMEXW)lParam, TRUE);
-
+        return TREEVIEW_SetItemT(infoPtr, (LPTVITEMEXW)lParam,
+                                uMsg == TVM_SETITEMW);
     case TVM_SETLINECOLOR:
        return TREEVIEW_SetLineColor(infoPtr, (COLORREF)lParam);
 
@@ -5651,7 +5674,7 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return TREEVIEW_SortChildrenCB(infoPtr, (LPTVSORTCB)lParam);
 
     case WM_CHAR:
-        return TREEVIEW_ProcessLetterKeys( hwnd, wParam, lParam );
+        return TREEVIEW_ProcessLetterKeys(infoPtr, wParam, lParam);
 
     case WM_COMMAND:
        return TREEVIEW_Command(infoPtr, wParam, lParam);
@@ -5691,10 +5714,7 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return TREEVIEW_MouseLeave(infoPtr);
 
     case WM_MOUSEMOVE:
-        if (infoPtr->dwStyle & TVS_TRACKSELECT)
-            return TREEVIEW_MouseMove(infoPtr, lParam);
-        else
-            return 0;
+       return TREEVIEW_MouseMove(infoPtr, lParam);
 
     case WM_NCLBUTTONDOWN:
         if (infoPtr->hwndEdit)
@@ -5702,9 +5722,7 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
         goto def;
 
     case WM_NCPAINT:
-        if (nc_paint (infoPtr, (HRGN)wParam))
-            return 0;
-        goto def;
+        return TREEVIEW_NCPaint (infoPtr, (HRGN)wParam, lParam);
 
     case WM_NOTIFY:
        return TREEVIEW_Notify(infoPtr, wParam, lParam);
@@ -5713,8 +5731,10 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return TREEVIEW_NotifyFormat(infoPtr, (HWND)wParam, (UINT)lParam);
 
     case WM_PRINTCLIENT:
+        return TREEVIEW_PrintClient(infoPtr, (HDC)wParam, lParam);
+
     case WM_PAINT:
-       return TREEVIEW_Paint(infoPtr, wParam);
+       return TREEVIEW_Paint(infoPtr, (HDC)wParam);
 
     case WM_RBUTTONDOWN:
        return TREEVIEW_RButtonDown(infoPtr, lParam);
@@ -5747,7 +5767,7 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return TREEVIEW_HandleTimer(infoPtr, wParam);
 
     case WM_THEMECHANGED:
-        return theme_changed (infoPtr);
+        return TREEVIEW_ThemeChanged (infoPtr);
 
     case WM_VSCROLL:
        return TREEVIEW_VScroll(infoPtr, wParam);
@@ -5755,9 +5775,7 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        /* WM_WININICHANGE */
 
     case WM_MOUSEWHEEL:
-       if (wParam & (MK_SHIFT | MK_CONTROL))
-           goto def;
-       return TREEVIEW_MouseWheel(infoPtr, wParam);
+       return TREEVIEW_MouseWheel(infoPtr, wParam, lParam);
 
     case WM_DRAWITEM:
        TRACE("drawItem\n");
index bb78903..75653e1 100644 (file)
@@ -71,7 +71,7 @@ typedef struct
 #define AUTOPRESS_DELAY        250    /* time to keep arrow pressed on KEY_DOWN */
 #define REPEAT_DELAY   50     /* delay between auto-increments */
 
-#define DEFAULT_WIDTH      14 /* default width of the ctrl */
+#define DEFAULT_WIDTH      16 /* default width of the ctrl */
 #define DEFAULT_XSEP         0 /* default separation between buddy and ctrl */
 #define DEFAULT_ADDTOP       0 /* amount to extend above the buddy window */
 #define DEFAULT_ADDBOT       0 /* amount to extend below the buddy window */
@@ -100,9 +100,9 @@ typedef struct
 #define UPDOWN_GetInfoPtr(hwnd) ((UPDOWN_INFO *)GetWindowLongPtrW (hwnd,0))
 #define COUNT_OF(a) (sizeof(a)/sizeof(a[0]))
 
-static const WCHAR BUDDY_UPDOWN_HWND[] = { 'b', 'u', 'd', 'd', 'y', 'U', 'p', 'D', 'o', 'w', 'n', 'H', 'W', 'N', 'D', 0 };
-static const WCHAR BUDDY_SUPERCLASS_WNDPROC[] = { 'b', 'u', 'd', 'd', 'y', 'S', 'u', 'p', 'p', 'e', 'r', 
-                                                 'C', 'l', 'a', 's', 's', 'W', 'n', 'd', 'P', 'r', 'o', 'c', 0 };
+/* id used for SetWindowSubclass */
+#define BUDDY_SUBCLASSID   1
+
 static void UPDOWN_DoAction (UPDOWN_INFO *infoPtr, int delta, int action);
 
 /***********************************************************************
@@ -200,7 +200,7 @@ static void UPDOWN_GetArrowRect (const UPDOWN_INFO* infoPtr, RECT *rect, int arr
     /* now figure out if we need a space away from the buddy */
     if (IsWindow(infoPtr->Buddy) ) {
        if (infoPtr->dwStyle & UDS_ALIGNLEFT) rect->right -= spacer;
-       else rect->left += spacer;
+       else if (infoPtr->dwStyle & UDS_ALIGNRIGHT) rect->left += spacer;
     }
 
     /*
@@ -309,8 +309,10 @@ static BOOL UPDOWN_GetBuddyInt (UPDOWN_INFO *infoPtr)
  */
 static BOOL UPDOWN_SetBuddyInt (const UPDOWN_INFO *infoPtr)
 {
-    WCHAR fmt[3] = { '%', 'd', '\0' };
-    WCHAR txt[20];
+    static const WCHAR fmt_hex[] = { '0', 'x', '%', '0', '4', 'X', 0 };
+    static const WCHAR fmt_dec_oct[] = { '%', 'd', '\0' };
+    const WCHAR *fmt;
+    WCHAR txt[20], txt_old[20] = { 0 };
     int len;
 
     if (!((infoPtr->Flags & FLAG_BUDDYINT) && IsWindow(infoPtr->Buddy)))
@@ -324,7 +326,7 @@ static BOOL UPDOWN_SetBuddyInt (const UPDOWN_INFO *infoPtr)
     }
 
     /* Regular window, so set caption to the number */
-    if (infoPtr->Base == 16) fmt[1] = 'X';
+    fmt = (infoPtr->Base == 16) ? fmt_hex : fmt_dec_oct;
     len = wsprintfW(txt, fmt, infoPtr->CurVal);
 
 
@@ -345,6 +347,10 @@ static BOOL UPDOWN_SetBuddyInt (const UPDOWN_INFO *infoPtr)
         *dst = 0;
     }
 
+    /* if nothing changed exit earlier */
+    GetWindowTextW(infoPtr->Buddy, txt_old, sizeof(txt_old)/sizeof(WCHAR));
+    if (lstrcmpiW(txt_old, txt) == 0) return 0;
+
     return SetWindowTextW(infoPtr->Buddy, txt);
 }
 
@@ -455,7 +461,7 @@ static LRESULT UPDOWN_Paint (const UPDOWN_INFO *infoPtr, HDC hdc)
  */
 static LRESULT UPDOWN_KeyPressed(UPDOWN_INFO *infoPtr, int key)
 {
-    int arrow;
+    int arrow, accel;
 
     if (key == VK_UP) arrow = FLAG_INCR;
     else if (key == VK_DOWN) arrow = FLAG_DECR;
@@ -466,7 +472,8 @@ static LRESULT UPDOWN_KeyPressed(UPDOWN_INFO *infoPtr, int key)
     infoPtr->Flags |= FLAG_PRESSED | arrow;
     InvalidateRect (infoPtr->Self, NULL, FALSE);
     SetTimer(infoPtr->Self, TIMER_AUTOPRESS, AUTOPRESS_DELAY, 0);
-    UPDOWN_DoAction (infoPtr, 1, arrow);
+    accel = (infoPtr->AccelCount && infoPtr->AccelVect) ? infoPtr->AccelVect[0].nInc : 1;
+    UPDOWN_DoAction (infoPtr, accel, arrow);
     return 0;
 }
 
@@ -518,14 +525,13 @@ static LRESULT UPDOWN_MouseWheel(UPDOWN_INFO *infoPtr, WPARAM wParam)
  *                           control.
  */
 static LRESULT CALLBACK
-UPDOWN_Buddy_SubclassProc(HWND  hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+UPDOWN_Buddy_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
+                          UINT_PTR uId, DWORD_PTR ref_data)
 {
-    WNDPROC superClassWndProc = (WNDPROC)GetPropW(hwnd, BUDDY_SUPERCLASS_WNDPROC);
-    HWND upDownHwnd = GetPropW(hwnd, BUDDY_UPDOWN_HWND);
-    UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(upDownHwnd);
+    UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr((HWND)ref_data);
 
-    TRACE("hwnd=%p, wndProc=%p, uMsg=%04x, wParam=%08lx, lParam=%08lx\n",
-          hwnd, superClassWndProc, uMsg, wParam, lParam);
+    TRACE("hwnd=%p, uMsg=%04x, wParam=%08lx, lParam=%08lx\n",
+          hwnd, uMsg, wParam, lParam);
 
     switch(uMsg)
     {
@@ -542,7 +548,7 @@ UPDOWN_Buddy_SubclassProc(HWND  hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        break;
     }
 
-    return CallWindowProcW( superClassWndProc, hwnd, uMsg, wParam, lParam);
+    return DefSubclassProc(hwnd, uMsg, wParam, lParam);
 }
 
 /***********************************************************************
@@ -550,18 +556,15 @@ UPDOWN_Buddy_SubclassProc(HWND  hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  *
  * Sets bud as a new Buddy.
  * Then, it should subclass the buddy
- * If window has the UDS_ARROWKEYS, it subcalsses the buddy window to
+ * If window has the UDS_ARROWKEYS, it subclasses the buddy window to
  * process the UP/DOWN arrow keys.
  * If window has the UDS_ALIGNLEFT or UDS_ALIGNRIGHT style
  * the size/pos of the buddy and the control are adjusted accordingly.
  */
 static HWND UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
 {
-    static const WCHAR editW[] = { 'E', 'd', 'i', 't', 0 };
-    static const WCHAR listboxW[] = { 'L', 'i', 's', 't', 'b', 'o', 'x', 0 };
     RECT  budRect;  /* new coord for the buddy */
     int   x, width;  /* new x position and width for the up-down */
-    WNDPROC baseWndProc;
     WCHAR buddyClass[40];
     HWND ret;
 
@@ -569,38 +572,27 @@ static HWND UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
 
     ret = infoPtr->Buddy;
 
-    /* there is already a body assigned */
-    if (infoPtr->Buddy)  RemovePropW(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
-
-    if(!IsWindow(bud))
-        bud = 0;
+    /* there is already a buddy assigned */
+    if (infoPtr->Buddy) RemoveWindowSubclass(infoPtr->Buddy, UPDOWN_Buddy_SubclassProc,
+                                             BUDDY_SUBCLASSID);
+    if (!IsWindow(bud)) bud = NULL;
 
     /* Store buddy window handle */
     infoPtr->Buddy = bud;
 
     if(bud) {
-
-        /* keep upDown ctrl hwnd in a buddy property */
-        SetPropW( bud, BUDDY_UPDOWN_HWND, infoPtr->Self);
-
         /* Store buddy window class type */
         infoPtr->BuddyType = BUDDY_TYPE_UNKNOWN;
         if (GetClassNameW(bud, buddyClass, COUNT_OF(buddyClass))) {
-            if (lstrcmpiW(buddyClass, editW) == 0)
+            if (lstrcmpiW(buddyClass, WC_EDITW) == 0)
                 infoPtr->BuddyType = BUDDY_TYPE_EDIT;
-            else if (lstrcmpiW(buddyClass, listboxW) == 0)
+            else if (lstrcmpiW(buddyClass, WC_LISTBOXW) == 0)
                 infoPtr->BuddyType = BUDDY_TYPE_LISTBOX;
         }
 
-        if (infoPtr->dwStyle & UDS_ARROWKEYS) {
-            /* Note that I don't clear the BUDDY_SUPERCLASS_WNDPROC property
-               when we reset the upDown ctrl buddy to another buddy because it is not
-               good to break the window proc chain. */
-            if (!GetPropW(bud, BUDDY_SUPERCLASS_WNDPROC)) {
-                baseWndProc = (WNDPROC)SetWindowLongPtrW(bud, GWLP_WNDPROC, (LPARAM)UPDOWN_Buddy_SubclassProc);
-                SetPropW(bud, BUDDY_SUPERCLASS_WNDPROC, baseWndProc);
-            }
-        }
+        if (infoPtr->dwStyle & UDS_ARROWKEYS)
+            SetWindowSubclass(bud, UPDOWN_Buddy_SubclassProc, BUDDY_SUBCLASSID,
+                              (DWORD_PTR)infoPtr->Self);
 
         /* Get the rect of the buddy relative to its parent */
         GetWindowRect(infoPtr->Buddy, &budRect);
@@ -661,7 +653,7 @@ static HWND UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
  * 'delta' amount according to the 'action' flag which can be a
  * combination of FLAG_INCR and FLAG_DECR
  * It notifies the parent as required.
- * It handles wraping and non-wraping correctly.
+ * It handles wrapping and non-wrapping correctly.
  * It is assumed that delta>0
  */
 static void UPDOWN_DoAction (UPDOWN_INFO *infoPtr, int delta, int action)
@@ -856,13 +848,16 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
     switch(message)
     {
         case WM_CREATE:
+           {
+           CREATESTRUCTW *pcs = (CREATESTRUCTW*)lParam;
+
             infoPtr = Alloc (sizeof(UPDOWN_INFO));
            SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
 
            /* initialize the info struct */
            infoPtr->Self = hwnd;
-           infoPtr->Notify = ((LPCREATESTRUCTW)lParam)->hwndParent;
-            infoPtr->dwStyle = ((LPCREATESTRUCTW)lParam)->style;
+           infoPtr->Notify  = pcs->hwndParent;
+           infoPtr->dwStyle = pcs->style;
            infoPtr->AccelCount = 0;
            infoPtr->AccelVect = 0;
            infoPtr->AccelIndex = -1;
@@ -874,21 +869,26 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
            infoPtr->Flags = (infoPtr->dwStyle & UDS_SETBUDDYINT) ? FLAG_BUDDYINT : 0;
 
             SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle & ~WS_BORDER);
+           if (!(infoPtr->dwStyle & UDS_HORZ))
+               SetWindowPos (hwnd, NULL, 0, 0, DEFAULT_WIDTH, pcs->cy,
+                             SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
 
             /* Do we pick the buddy win ourselves? */
            if (infoPtr->dwStyle & UDS_AUTOBUDDY)
                UPDOWN_SetBuddy (infoPtr, GetWindow (hwnd, GW_HWNDPREV));
 
-            OpenThemeData (hwnd, themeClass);
+           OpenThemeData (hwnd, themeClass);
 
            TRACE("UpDown Ctrl creation, hwnd=%p\n", hwnd);
+           }
            break;
 
        case WM_DESTROY:
            Free (infoPtr->AccelVect);
 
-           if(infoPtr->Buddy) RemovePropW(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
-
+           if (infoPtr->Buddy)
+              RemoveWindowSubclass(infoPtr->Buddy, UPDOWN_Buddy_SubclassProc,
+                                   BUDDY_SUBCLASSID);
            Free (infoPtr);
            SetWindowLongPtrW (hwnd, 0, 0);
             theme = GetWindowTheme (hwnd);
@@ -930,18 +930,18 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
 
           /* if initial timer, kill it and start the repeat timer */
           if(wParam == TIMER_AUTOREPEAT) {
-               int temp;
+               INT delay;
 
                KillTimer(hwnd, TIMER_AUTOREPEAT);
                /* if no accel info given, used default timer */
                if(infoPtr->AccelCount==0 || infoPtr->AccelVect==0) {
                    infoPtr->AccelIndex = -1;
-                   temp = REPEAT_DELAY;
+                   delay = REPEAT_DELAY;
                } else {
                    infoPtr->AccelIndex = 0; /* otherwise, use it */
-                   temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
+                   delay = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
                }
-               SetTimer(hwnd, TIMER_ACCEL, temp, 0);
+               SetTimer(hwnd, TIMER_ACCEL, delay, 0);
            }
 
            /* now, if the mouse is above us, do the thing...*/
@@ -1011,8 +1011,6 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
 
        case UDM_SETACCEL:
        {
-           unsigned temp;
-
            TRACE("UDM_SETACCEL\n");
 
            if(infoPtr->AccelVect) {
@@ -1026,8 +1024,14 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
            memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
             infoPtr->AccelCount = wParam;
 
-            for (temp = 0; temp < wParam; temp++)
-                TRACE("%d: nSec %u nInc %u\n", temp, infoPtr->AccelVect[temp].nSec, infoPtr->AccelVect[temp].nInc);
+            if (TRACE_ON(updown))
+            {
+                INT i;
+
+                for (i = 0; i < wParam; i++)
+                    TRACE("%d: nSec %u nInc %u\n", i,
+                        infoPtr->AccelVect[i].nSec, infoPtr->AccelVect[i].nInc);
+            }
 
            return TRUE;
        }
index 2067de5..64c341c 100644 (file)
@@ -530,7 +530,7 @@ KsAllocateDeviceHeader(
         return STATUS_INVALID_PARAMETER;
 
     /* allocate a device header */
-    Header = ExAllocatePoolWithTag(PagedPool, sizeof(KSIDEVICE_HEADER), TAG_DEVICE_HEADER);
+    Header = AllocateItem(PagedPool, sizeof(KSIDEVICE_HEADER));
 
     /* check for success */
     if (!Header)
@@ -597,7 +597,7 @@ KsFreeDeviceHeader(
         return;
 
     KspFreeCreateItems(&Header->ItemList);
-    ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
+    FreeItem(Header);
 }
 
 /*
@@ -641,7 +641,7 @@ KsAllocateObjectHeader(
     /* check for an file object */
 
     /* allocate the object header */
-    ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER);
+    ObjectHeader = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_HEADER));
     if (!ObjectHeader)
         return STATUS_INSUFFICIENT_RESOURCES;
 
@@ -659,10 +659,10 @@ KsAllocateObjectHeader(
     {
         /* copy object class */
         ObjectHeader->ObjectClass.MaximumLength = IoStack->FileObject->FileName.MaximumLength;
-        ObjectHeader->ObjectClass.Buffer = ExAllocatePoolWithTag(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength, TAG_DEVICE_HEADER);
+        ObjectHeader->ObjectClass.Buffer = AllocateItem(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength);
         if (!ObjectHeader->ObjectClass.Buffer)
         {
-            ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER);
+            FreeItem(ObjectHeader);
             return STATUS_INSUFFICIENT_RESOURCES;
         }
         RtlCopyUnicodeString(&ObjectHeader->ObjectClass, &IoStack->FileObject->FileName);
@@ -726,7 +726,7 @@ KsFreeObjectHeader(
     if (ObjectHeader->ObjectClass.Buffer)
     {
         /* release object class buffer */
-        ExFreePoolWithTag(ObjectHeader->ObjectClass.Buffer, TAG_DEVICE_HEADER);
+        FreeItem(ObjectHeader->ObjectClass.Buffer);
     }
 
     if (ObjectHeader->Unknown)
@@ -739,7 +739,7 @@ KsFreeObjectHeader(
     KspFreeCreateItems(&ObjectHeader->ItemList);
 
     /* free object header */
-    ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER);
+    FreeItem(ObjectHeader);
 
 }
 
@@ -914,11 +914,11 @@ KsAllocateObjectCreateItem(
     if (AllocateEntry)
     {
         /* allocate create item */
-        Item = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
+        Item = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
         if (!Item)
         {
             /* no memory */
-            ExFreePool(CreateEntry);
+            FreeItem(CreateEntry);
             return STATUS_INSUFFICIENT_RESOURCES;
         }
 
@@ -931,7 +931,7 @@ KsAllocateObjectCreateItem(
         Item->ObjectClass.MaximumLength = CreateItem->ObjectClass.MaximumLength;
 
         /* copy object class */
-        Item->ObjectClass.Buffer = ExAllocatePool(NonPagedPool, Item->ObjectClass.MaximumLength);
+        Item->ObjectClass.Buffer = AllocateItem(NonPagedPool, Item->ObjectClass.MaximumLength);
         if (!Item->ObjectClass.Buffer)
         {
             /* release resources */
@@ -1747,7 +1747,7 @@ KsCreateBusEnumObject(
     Length = wcslen(BusIdentifier) * sizeof(WCHAR);
     Length += sizeof(BUS_ENUM_DEVICE_EXTENSION);
 
-    BusDeviceExtension = ExAllocatePool(NonPagedPool, Length);
+    BusDeviceExtension = AllocateItem(NonPagedPool, Length);
     if (!BusDeviceExtension)
     {
         /* not enough memory */
@@ -1772,12 +1772,12 @@ KsCreateBusEnumObject(
 
     BusDeviceExtension->ServicePath.Length = 0;
     BusDeviceExtension->ServicePath.MaximumLength = Length;
-    BusDeviceExtension->ServicePath.Buffer = ExAllocatePool(NonPagedPool, Length);
+    BusDeviceExtension->ServicePath.Buffer = AllocateItem(NonPagedPool, Length);
 
     if (!BusDeviceExtension->ServicePath.Buffer)
     {
         /* not enough memory */
-        ExFreePool(BusDeviceExtension);
+        FreeItem(BusDeviceExtension);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -1798,8 +1798,8 @@ KsCreateBusEnumObject(
         /* check for success */
         if (!NT_SUCCESS(Status))
         {
-            ExFreePool(BusDeviceExtension->ServicePath.Buffer);
-            ExFreePool(BusDeviceExtension);
+            FreeItem(BusDeviceExtension->ServicePath.Buffer);
+            FreeItem(BusDeviceExtension);
             return Status;
         }
 
@@ -1808,8 +1808,8 @@ KsCreateBusEnumObject(
 
         if (!NT_SUCCESS(Status))
         {
-            ExFreePool(BusDeviceExtension->ServicePath.Buffer);
-            ExFreePool(BusDeviceExtension);
+            FreeItem(BusDeviceExtension->ServicePath.Buffer);
+            FreeItem(BusDeviceExtension);
             return Status;
         }
 
@@ -1836,8 +1836,8 @@ KsCreateBusEnumObject(
             }
 
             /* free device extension */
-            ExFreePool(BusDeviceExtension->ServicePath.Buffer);
-            ExFreePool(BusDeviceExtension);
+            FreeItem(BusDeviceExtension->ServicePath.Buffer);
+            FreeItem(BusDeviceExtension);
 
             return STATUS_DEVICE_REMOVED;
         }
@@ -2795,7 +2795,7 @@ KsRegisterFilterWithNoKSPins(
         }
 
         /* free the symbolic link list */
-        ExFreePool(SymbolicLinkList);
+        FreeItem(SymbolicLinkList);
     }
 
     return Status;
index bcc55cc..4993849 100644 (file)
@@ -239,7 +239,7 @@ KspReadMediaCategory(
     /* allocate buffer for the registry key */
     Path.Length = 0;
     Path.MaximumLength = MediaPath.MaximumLength + GuidString.MaximumLength;
-    Path.Buffer = ExAllocatePool(NonPagedPool, Path.MaximumLength);
+    Path.Buffer = AllocateItem(NonPagedPool, Path.MaximumLength);
     if (!Path.Buffer)
     {
         /* not enough memory */
@@ -262,7 +262,7 @@ KspReadMediaCategory(
     DPRINT("ZwOpenKey() status 0x%08lx %S\n", Status, Path.Buffer);
 
     /* free path buffer */
-    ExFreePool(Path.Buffer);
+    FreeItem(Path.Buffer);
 
     /* check for success */
     if (!NT_SUCCESS(Status))
@@ -281,7 +281,7 @@ KspReadMediaCategory(
     }
 
     /* allocate buffer to read key info */
-    KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePool(NonPagedPool, Size);
+    KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION) AllocateItem(NonPagedPool, Size);
     if (!KeyInfo)
     {
         /* not enough memory */
@@ -298,7 +298,7 @@ KspReadMediaCategory(
     if (!NT_SUCCESS(Status))
     {
         /* failed to read key */
-        ExFreePool(KeyInfo);
+        FreeItem(KeyInfo);
         return Status;
     }
 
@@ -545,13 +545,13 @@ KspPinPropertyHandler(
             if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
             {
                 Status = STATUS_BUFFER_OVERFLOW;
-                ExFreePool(KeyInfo);
+                FreeItem(KeyInfo);
                 break;
             }
 
             RtlMoveMemory(Irp->UserBuffer, &KeyInfo->Data, KeyInfo->DataLength);
             ((LPWSTR)Irp->UserBuffer)[KeyInfo->DataLength / sizeof(WCHAR)] = L'\0';
-            ExFreePool(KeyInfo);
+            FreeItem(KeyInfo);
             break;
         case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
             Size = sizeof(KSDATAFORMAT);
index 5ec2e85..aa3b5ef 100644 (file)
@@ -292,7 +292,7 @@ KspEnableEvent(
     else
     {
         /* allocate it from nonpaged pool */
-        EventEntry = ExAllocatePool(NonPagedPool, Size);
+        EventEntry = AllocateItem(NonPagedPool, Size);
     }
 
     if (!EventEntry)
@@ -529,7 +529,7 @@ KsDiscardEvent(
     }
 
     /* free event entry */
-    ExFreePool(EventEntry);
+    FreeItem(EventEntry);
 }
 
 
index f6c6bc1..dbdeca0 100644 (file)
@@ -45,7 +45,7 @@ KsLoadResource(
             if (NT_SUCCESS(Status))
             {
                 /* allocate resource buffer */
-                Result = ExAllocatePool(PoolType, Size);
+                Result = AllocateItem(PoolType, Size);
                 if (Result)
                 {
                     /* copy resource */
@@ -75,7 +75,7 @@ KsLoadResource(
         if (Result)
         {
             /* free resource buffer in case of a failure */
-            ExFreePool(Result);
+            FreeItem(Result);
         }
     }
     /* done */
@@ -127,7 +127,7 @@ KsGetImageNameAndResourceId(
 
     /* allocate image name buffer */
     ImageName->MaximumLength = sizeof(ImagePath) + ImageLength;
-    ImageName->Buffer = ExAllocatePool(PagedPool, ImageName->MaximumLength);
+    ImageName->Buffer = AllocateItem(PagedPool, ImageName->MaximumLength);
 
     /* check for success */
     if (!ImageName->Buffer)
@@ -145,7 +145,7 @@ KsGetImageNameAndResourceId(
     if (!NT_SUCCESS(Status))
     {
         /* unexpected error */
-        ExFreePool(ImageName->Buffer);
+        FreeItem(ImageName->Buffer);
         return Status;
     }
 
@@ -154,13 +154,13 @@ KsGetImageNameAndResourceId(
    Status = KspQueryRegValue(RegKey, L"ResourceId", NULL, &ImageLength, ValueType);
 
     /* allocate resource id buffer*/
-    *ResourceId = (ULONG_PTR)ExAllocatePool(PagedPool, ImageLength);
+    *ResourceId = (ULONG_PTR)AllocateItem(PagedPool, ImageLength);
 
     /* check for success */
     if (!*ResourceId)
     {
         /* insufficient memory */
-        ExFreePool(ImageName->Buffer);
+        FreeItem(ImageName->Buffer);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
     /* now query for resource id */
@@ -169,8 +169,8 @@ KsGetImageNameAndResourceId(
     if (!NT_SUCCESS(Status))
     {
         /* unexpected error */
-        ExFreePool(ImageName->Buffer);
-        ExFreePool((PVOID)*ResourceId);
+        FreeItem(ImageName->Buffer);
+        FreeItem((PVOID)*ResourceId);
     }
 
     /* return result */
@@ -209,7 +209,7 @@ KsMapModuleName(
     /* initialize subkey buffer */
     SubKeyName.Length = 0;
     SubKeyName.MaximumLength = Modules.MaximumLength + ModuleName->MaximumLength;
-    SubKeyName.Buffer = ExAllocatePool(PagedPool, SubKeyName.MaximumLength);
+    SubKeyName.Buffer = AllocateItem(PagedPool, SubKeyName.MaximumLength);
 
     /* check for success */
     if (!SubKeyName.Buffer)
@@ -240,7 +240,7 @@ KsMapModuleName(
     }
 
     /* free subkey string */
-    ExFreePool(SubKeyName.Buffer);
+    FreeItem(SubKeyName.Buffer);
 
     /* close device key */
     ZwClose(hKey);
index 0c6036e..32ba84d 100644 (file)
@@ -101,7 +101,7 @@ KsDispatchSetSecurity(
     if (NT_SUCCESS(Status))
     {
         /* free old descriptor */
-        ExFreePool(Descriptor);
+        FreeItem(Descriptor);
 
        /* mark create item as changed */
        CreateItem->Flags |= KSCREATE_ITEM_SECURITYCHANGED;
@@ -896,7 +896,7 @@ ProbeMdl:
     if (Length && ( (!HeaderSize) || (Length % HeaderSize == 0) || ((ProbeFlags & KSPROBE_ALLOWFORMATCHANGE) && (Length == sizeof(KSSTREAM_HEADER))) ) )
     {
         /* allocate stream header buffer */
-        Irp->AssociatedIrp.SystemBuffer = ExAllocatePool(NonPagedPool, Length);
+        Irp->AssociatedIrp.SystemBuffer = AllocateItem(NonPagedPool, Length);
 
         if (!Irp->AssociatedIrp.SystemBuffer)
         {
index dc814ea..d6b1e26 100644 (file)
@@ -26,7 +26,6 @@ VOID
 FreeItem(
     IN PVOID Item)
 {
-
     ExFreePool(Item);
 }
 
index a95755c..a6caeb3 100644 (file)
@@ -1560,7 +1560,7 @@ KsStreamPointerClone(
     Size = sizeof(KSISTREAM_POINTER) + ContextSize;
 
     /* allocate new stream pointer */
-    NewFrame = (PKSISTREAM_POINTER)ExAllocatePool(NonPagedPool, Size);
+    NewFrame = (PKSISTREAM_POINTER)AllocateItem(NonPagedPool, Size);
 
     if (!NewFrame)
         return STATUS_INSUFFICIENT_RESOURCES;
index cc4a888..e507eb7 100644 (file)
@@ -30,7 +30,7 @@ KspCreateObjectType(
     Name.MaximumLength = wcslen(ObjectType) * sizeof(WCHAR) + CreateParametersSize +  2 * sizeof(WCHAR);
     Name.MaximumLength += sizeof(WCHAR);
     /* acquire request buffer */
-    Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength);
+    Name.Buffer = AllocateItem(NonPagedPool, Name.MaximumLength);
     /* check for success */
     if (!Name.Buffer)
     {
@@ -68,7 +68,7 @@ KspCreateObjectType(
                           IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
 
     /* free request buffer */
-    ExFreePool(Name.Buffer);
+    FreeItem(Name.Buffer);
     return Status;
 }
 
@@ -200,29 +200,32 @@ KsTopologyPropertyHandler(
 
             KeyName.Length = 0;
             KeyName.MaximumLength = LocalMachine.Length + GuidString.Length + sizeof(WCHAR);
-            KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength);
+            KeyName.Buffer = AllocateItem(PagedPool, KeyName.MaximumLength);
             if (!KeyName.Buffer)
             {
                 Irp->IoStatus.Information = 0;
                 Status = STATUS_INSUFFICIENT_RESOURCES;
+                RtlFreeUnicodeString(&GuidString);
                 break;
             }
 
             RtlAppendUnicodeStringToString(&KeyName, &LocalMachine);
             RtlAppendUnicodeStringToString(&KeyName, &GuidString);
 
+            RtlFreeUnicodeString(&GuidString);
 
             InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
             Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
 
+            FreeItem(KeyName.Buffer);
+
             if (!NT_SUCCESS(Status))
             {
                 DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
-                ExFreePool(KeyName.Buffer);
                 Irp->IoStatus.Information = 0;
                 break;
             }
-            ExFreePool(KeyName.Buffer);
+
             Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, NULL, 0, &Size);
             if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
             {
@@ -231,7 +234,8 @@ KsTopologyPropertyHandler(
                 break;
             }
 
-            KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePool(NonPagedPool, Size);
+            ASSERT(Size);
+            KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION) AllocateItem(NonPagedPool, Size);
             if (!KeyInfo)
             {
                 Status = STATUS_NO_MEMORY;
@@ -241,7 +245,7 @@ KsTopologyPropertyHandler(
             Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, (PVOID)KeyInfo, Size, &Size);
             if (!NT_SUCCESS(Status))
             {
-                ExFreePool(KeyInfo);
+                FreeItem(KeyInfo);
                 ZwClose(hKey);
                 Irp->IoStatus.Information = 0;
                 break;
@@ -252,14 +256,14 @@ KsTopologyPropertyHandler(
             {
                 Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
                 Status = STATUS_MORE_ENTRIES;
-                ExFreePool(KeyInfo);
+                FreeItem(KeyInfo);
                 break;
             }
 
             RtlMoveMemory(Irp->UserBuffer, &KeyInfo->Data, KeyInfo->DataLength);
             ((LPWSTR)Irp->UserBuffer)[KeyInfo->DataLength / sizeof(WCHAR)] = L'\0';
              Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
-            ExFreePool(KeyInfo);
+            FreeItem(KeyInfo);
             break;
         default:
              Irp->IoStatus.Information = 0;
index f30f9de..35bc6b1 100644 (file)
@@ -118,11 +118,22 @@ PortClsPnp(
             // Clean up
             DPRINT("IRP_MN_REMOVE_DEVICE\n");
 
-            DeviceExt->resources->Release();
-            IoDeleteDevice(DeviceObject);
+            // sanity check
+            PC_ASSERT(DeviceExt);
+
+            // FIXME more cleanup */
+            if (DeviceExt->resources)
+            {
+                // free resource list */
+                DeviceExt->resources->Release();
+
+                // set to null
+                DeviceExt->resources = NULL;
+            }
 
             // Forward request
             Status = PcForwardIrpSynchronous(DeviceObject, Irp);
+
             return PcCompleteIrp(DeviceObject, Irp, Status);
 
         case IRP_MN_QUERY_INTERFACE:
index e033ff6..e8ea9bb 100644 (file)
@@ -25,7 +25,6 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
         NTSTATUS Status;
         PIRP Irp;
         PMDL Mdl;
-        ULONG SocketError = 0;
         KIRQL OldIrql;
         PTCP_COMPLETION_ROUTINE Complete;
 
@@ -35,69 +34,6 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
         TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
                                Connection, Connection->SocketContext));
 
-        if( Connection->SignalState & SEL_FIN ) {
-            TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
-
-            /* If OskitTCP initiated the disconnect, try to read the socket error that occurred */
-            if (Connection->SocketContext)
-                SocketError = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
-
-            /* Default to STATUS_CANCELLED if we initiated the disconnect or no socket error was reported */
-            if (!Connection->SocketContext || !SocketError)
-                SocketError = STATUS_CANCELLED;
-
-            while (!IsListEmpty(&Connection->ReceiveRequest))
-            {
-               Entry = RemoveHeadList( &Connection->ReceiveRequest );
-
-               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-               Bucket->Status = SocketError;
-               Bucket->Information = 0;
-
-               InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
-            }
-
-            while (!IsListEmpty(&Connection->SendRequest))
-            {
-               Entry = RemoveHeadList( &Connection->SendRequest );
-
-               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-               Bucket->Status = SocketError;
-               Bucket->Information = 0;
-
-               InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
-            }
-
-            while (!IsListEmpty(&Connection->ListenRequest))
-            {
-               Entry = RemoveHeadList( &Connection->ListenRequest );
-
-               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-               Bucket->Status = SocketError;
-               Bucket->Information = 0;
-               DereferenceObject(Bucket->AssociatedEndpoint);
-
-               InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
-            }
-
-            while (!IsListEmpty(&Connection->ConnectRequest))
-            {
-               Entry = RemoveHeadList( &Connection->ConnectRequest );
-
-               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-               Bucket->Status = SocketError;
-               Bucket->Information = 0;
-
-               InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
-            }
-
-            Connection->SignalState = SEL_FIN;
-        }
-
         /* Things that can happen when we try the initial connection */
         if( Connection->SignalState & SEL_CONNECT ) {
             while (!IsListEmpty(&Connection->ConnectRequest)) {
@@ -140,11 +76,11 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
 
                TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
 
-               if( Status == STATUS_PENDING ) {
+               if( Status == STATUS_PENDING && !(Connection->SignalState & SEL_FIN) ) {
                    InsertHeadList( &Connection->ListenRequest, &Bucket->Entry );
                    break;
                } else {
-                   Bucket->Status = Status;
+                   Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED : Status;
                    Bucket->Information = 0;
                    DereferenceObject(Bucket->AssociatedEndpoint);
 
@@ -194,7 +130,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
 
                TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
 
-               if( Status == STATUS_PENDING ) {
+               if( Status == STATUS_PENDING && !(Connection->SignalState & SEL_FIN) ) {
                    InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
                    break;
                } else {
@@ -202,8 +138,8 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
                                ("Completing Receive request: %x %x\n",
                                 Bucket->Request, Status));
 
-                   Bucket->Status = Status;
-                   Bucket->Information = (Status == STATUS_SUCCESS) ? Received : 0;
+                   Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED : Status;
+                   Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? Received : 0;
 
                    InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
                }
@@ -248,7 +184,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
 
                TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
 
-               if( Status == STATUS_PENDING ) {
+               if( Status == STATUS_PENDING && !(Connection->SignalState & SEL_FIN) ) {
                    InsertHeadList( &Connection->SendRequest, &Bucket->Entry );
                    break;
                } else {
@@ -256,8 +192,8 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
                                ("Completing Send request: %x %x\n",
                                Bucket->Request, Status));
 
-                   Bucket->Status = Status;
-                   Bucket->Information = (Status == STATUS_SUCCESS) ? Sent : 0;
+                   Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED : Status;
+                   Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? Sent : 0;
 
                    InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
                }
@@ -737,7 +673,7 @@ NTSTATUS TCPClose
     Connection->SocketContext = NULL;
 
     /* Don't try to close again if the other side closed us already */
-    if (Connection->SignalState != SEL_FIN)
+    if (!(Connection->SignalState & SEL_FIN))
     {
        /* We need to close here otherwise oskit will never indicate
         * SEL_FIN and we will never fully close the connection */
index 0b2e499..36794df 100644 (file)
@@ -385,6 +385,8 @@ MMixerAddMixerSourceLine(
         SrcLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
         SrcLine->Line.Target.vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
         InitializeListHead(&SrcLine->LineControlsExtraData);
+
+        ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == L'\0');
         wcscpy(SrcLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
 
     }
index a05f2a7..46e2c6d 100644 (file)
@@ -472,6 +472,13 @@ MMixerInitialize(
                 // enumeration has finished
                 break;
             }
+            else
+            {
+                DPRINT1("Failed to enumerate device %lu\n", DeviceIndex);
+
+                // TODO cleanup
+                return Status;
+            }
         }
         else
         {