Added some generic code to allow subclassing (for the purpose of
theming) of standard controls.

diff --git a/dlls/comctl32/Makefile.in b/dlls/comctl32/Makefile.in
index f679073..b7f43ef 100644
--- a/dlls/comctl32/Makefile.in
+++ b/dlls/comctl32/Makefile.in
@@ -35,6 +35,7 @@
 	status.c \
 	syslink.c \
 	tab.c \
+	theming.c \
 	toolbar.c \
 	tooltips.c \
 	trackbar.c \
diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h
index 1f7e0ad..10f1b8c 100644
--- a/dlls/comctl32/comctl32.h
+++ b/dlls/comctl32/comctl32.h
@@ -249,4 +249,8 @@
   to->wMilliseconds = from->wMilliseconds;
 }
 
+extern void THEMING_Initialize(void);
+extern LRESULT THEMING_CallOriginalClass(HWND, UINT, WPARAM, LPARAM);
+extern void THEMING_SetSubclassData(HWND, ULONG_PTR);
+
 #endif  /* __WINE_COMCTL32_H */
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c
index 4c1ea8a..697aabe 100644
--- a/dlls/comctl32/commctrl.c
+++ b/dlls/comctl32/commctrl.c
@@ -144,6 +144,9 @@
             TRACKBAR_Register ();
             TREEVIEW_Register ();
             UPDOWN_Register ();
+
+            /* subclass user32 controls */
+            THEMING_Initialize ();
             break;
 
 	case DLL_PROCESS_DETACH:
diff --git a/dlls/comctl32/theming.c b/dlls/comctl32/theming.c
new file mode 100644
index 0000000..ff3be61
--- /dev/null
+++ b/dlls/comctl32/theming.c
@@ -0,0 +1,158 @@
+/*
+ * Theming - Initialization
+ *
+ * Copyright (c) 2005 by Frank Richter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "comctl32.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(theming);
+
+typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM,
+    ULONG_PTR);
+
+static const struct ThemingSubclass
+{
+    const WCHAR* className;
+    THEMING_SUBCLASSPROC subclassProc;
+} subclasses[] = {
+    /* Note: list must be sorted by class name */
+};
+
+#define NUM_SUBCLASSES        (sizeof(subclasses)/sizeof(subclasses[0]))
+
+static WNDPROC originalProcs[NUM_SUBCLASSES];
+static ATOM atRefDataProp;
+static ATOM atSubclassProp;
+
+/***********************************************************************
+ * THEMING_SubclassProc
+ *
+ * The window proc registered to the subclasses. Fetches the subclass
+ * proc and ref data and call the proc.
+ */
+static LRESULT CALLBACK THEMING_SubclassProc (HWND wnd, UINT msg,
+                                              WPARAM wParam, LPARAM lParam)
+{
+    int subclass = (int)GetPropW (wnd, MAKEINTATOMW (atSubclassProp)) - 1;
+    LRESULT result;
+    ULONG_PTR refData;
+
+    if (subclass == -1)
+    {
+        /* Means this is the first time this proc is called for this window.
+         * Determine the index of the subclass */
+        WCHAR className[32];
+        int l = 0, r = NUM_SUBCLASSES;
+
+        GetClassNameW (wnd, className, sizeof(className)/sizeof(WCHAR));
+        while (l < r)
+        {
+            int d, m = (l+r) / 2;
+            d = lstrcmpiW (className, subclasses[m].className);
+            if (d == 0)
+            {
+                subclass = m;
+                break;
+            }
+            if (d < 0)
+                r = m;
+            else
+                l = m + 1;
+        }
+        if (subclass == -1)
+            ERR("Couldn't find subclass info for %s!\n", debugstr_w (className));
+        SetPropW (wnd, MAKEINTATOMW (atSubclassProp), (HANDLE)(subclass + 1));
+    }
+    refData = (ULONG_PTR)GetPropW (wnd, MAKEINTATOMW (atRefDataProp));
+
+    TRACE ("%d; (%p, %x, %x, %lx, %lx)", subclass, wnd, msg, wParam, lParam, 
+        refData);
+    result = subclasses[subclass].subclassProc (wnd, msg, wParam, lParam, refData);
+    TRACE (" = %lx\n", result);
+    return result;
+}
+
+/***********************************************************************
+ * THEMING_Initialize
+ *
+ * Register classes for standard controls that will shadow the system
+ * classes.
+ */
+void THEMING_Initialize (void)
+{
+    int i;
+    static const WCHAR subclassPropName[] = 
+        { 'C','C','3','2','T','h','e','m','i','n','g','S','u','b','C','l',0 };
+    static const WCHAR refDataPropName[] = 
+        { 'C','C','3','2','T','h','e','m','i','n','g','D','a','t','a',0 };
+
+    atSubclassProp = GlobalAddAtomW (subclassPropName);
+    atRefDataProp = GlobalAddAtomW (refDataPropName);
+
+    for (i = 0; i < NUM_SUBCLASSES; i++)
+    {
+        WNDCLASSEXW class;
+
+        class.cbSize = sizeof(class);
+        class.style |= CS_GLOBALCLASS;
+        GetClassInfoExW (NULL, subclasses[i].className, &class);
+        originalProcs[i] = class.lpfnWndProc;
+        class.lpfnWndProc = THEMING_SubclassProc;
+
+        if (!RegisterClassExW (&class))
+        {
+            ERR("Could not re-register class %s: %lx\n", 
+                debugstr_w (subclasses[i].className), GetLastError ());
+        }
+        else
+        {
+            TRACE("Re-registered class %s\n", 
+                debugstr_w (subclasses[i].className));
+        }
+    }
+}
+
+/***********************************************************************
+ * THEMING_CallOriginalClass
+ *
+ * Determines the original window proc and calls it.
+ */
+LRESULT THEMING_CallOriginalClass (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    int subclass = (int)GetPropW (wnd, MAKEINTATOMW (atSubclassProp)) - 1;
+    WNDPROC oldProc = originalProcs[subclass];
+    return CallWindowProcW (oldProc, wnd, msg, wParam, lParam);
+}
+
+/***********************************************************************
+ * THEMING_SetSubclassData
+ *
+ * Update the "refData" value of the subclassed window.
+ */
+void THEMING_SetSubclassData (HWND wnd, ULONG_PTR refData)
+{
+    SetPropW (wnd, MAKEINTATOMW (atRefDataProp), (HANDLE)refData);
+}