set svn:eol-style to native
[reactos.git] / reactos / lib / comctl32 / commctrl.c
index 0d315e9..4c1ea8a 100644 (file)
-/*\r
- * Common controls functions\r
- *\r
- * Copyright 1997 Dimitrie O. Paun\r
- * Copyright 1998,2000 Eric Kohl\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * NOTES\r
- * \r
- * This code was audited for completeness against the documented features\r
- * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.\r
- *\r
- * Unless otherwise noted, we believe this code to be complete, as per\r
- * the specification mentioned above.\r
- * If you discover missing features, or bugs, please note them below.\r
- *\r
- * TODO\r
- *   -- implement GetMUILanguage + InitMUILanguage\r
- *   -- LibMain => DLLMain ("DLLMain takes over the functionality of both the\r
- *                           LibMain and the WEP function.", MSDN)\r
- *   -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW\r
- *   -- FIXMEs + BUGS (search for them)\r
- *\r
- * Control Classes\r
- *   -- ICC_ANIMATE_CLASS\r
- *   -- ICC_BAR_CLASSES\r
- *   -- ICC_COOL_CLASSES\r
- *   -- ICC_DATE_CLASSES\r
- *   -- ICC_HOTKEY_CLASS\r
- *   -- ICC_INTERNET_CLASSES\r
- *   -- ICC_LINK_CLASS\r
- *   -- ICC_LISTVIEW_CLASSES\r
- *   -- ICC_NATIVEFNTCTL_CLASS\r
- *   -- ICC_PAGESCROLLER_CLASS\r
- *   -- ICC_PROGRESS_CLASS\r
- *   -- ICC_STANDARD_CLASSES (not yet implemented)\r
- *   -- ICC_TAB_CLASSES\r
- *   -- ICC_TREEVIEW_CLASSES\r
- *   -- ICC_UPDOWN_CLASS\r
- *   -- ICC_USEREX_CLASSES\r
- *   -- ICC_WIN95_CLASSES\r
- */\r
-\r
-#include <stdarg.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "wingdi.h"\r
-#include "winuser.h"\r
-#include "winnls.h"\r
-#include "commctrl.h"\r
-#include "winerror.h"\r
-#include "winreg.h"\r
-#define NO_SHLWAPI_STREAM\r
-#include "shlwapi.h"\r
-#include "comctl32.h"\r
-#include "wine/debug.h"\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(commctrl);\r
-\r
-LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
-\r
-LPWSTR  COMCTL32_wSubclass = NULL;\r
-HMODULE COMCTL32_hModule = 0;\r
-LANGID  COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);\r
-HBRUSH  COMCTL32_hPattern55AABrush = NULL;\r
-COMCTL32_SysColor  comctl32_color;\r
-\r
-static HBITMAP COMCTL32_hPattern55AABitmap = NULL;\r
-\r
-static const WORD wPattern55AA[] =\r
-{\r
-    0x5555, 0xaaaa, 0x5555, 0xaaaa,\r
-    0x5555, 0xaaaa, 0x5555, 0xaaaa\r
-};\r
-\r
-static const WCHAR strCC32SubclassInfo[] = {\r
-    'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0\r
-};\r
-\r
-/***********************************************************************\r
- * DllMain [Internal]\r
- *\r
- * Initializes the internal 'COMCTL32.DLL'.\r
- *\r
- * PARAMS\r
- *     hinstDLL    [I] handle to the 'dlls' instance\r
- *     fdwReason   [I]\r
- *     lpvReserved [I] reserverd, must be NULL\r
- *\r
- * RETURNS\r
- *     Success: TRUE\r
- *     Failure: FALSE\r
- */\r
-\r
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
-{\r
-    TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);\r
-\r
-    switch (fdwReason) {\r
-       case DLL_PROCESS_ATTACH:\r
-            DisableThreadLibraryCalls(hinstDLL);\r
-\r
-            COMCTL32_hModule = (HMODULE)hinstDLL;\r
-\r
-            /* add global subclassing atom (used by 'tooltip' and 'updown') */\r
-            COMCTL32_wSubclass = (LPWSTR)(DWORD)GlobalAddAtomW (strCC32SubclassInfo);\r
-            TRACE("Subclassing atom added: %p\n", COMCTL32_wSubclass);\r
-\r
-            /* create local pattern brush */\r
-            COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);\r
-            COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);\r
-\r
-           /* Get all the colors at DLL load */\r
-           COMCTL32_RefreshSysColors();\r
-\r
-            /* register all Win95 common control classes */\r
-            ANIMATE_Register ();\r
-            FLATSB_Register ();\r
-            HEADER_Register ();\r
-            HOTKEY_Register ();\r
-            LISTVIEW_Register ();\r
-            PROGRESS_Register ();\r
-            STATUS_Register ();\r
-            SYSLINK_Register ();\r
-            TAB_Register ();\r
-            TOOLBAR_Register ();\r
-            TOOLTIPS_Register ();\r
-            TRACKBAR_Register ();\r
-            TREEVIEW_Register ();\r
-            UPDOWN_Register ();\r
-            break;\r
-\r
-       case DLL_PROCESS_DETACH:\r
-            /* unregister all common control classes */\r
-            ANIMATE_Unregister ();\r
-            COMBOEX_Unregister ();\r
-            DATETIME_Unregister ();\r
-            FLATSB_Unregister ();\r
-            HEADER_Unregister ();\r
-            HOTKEY_Unregister ();\r
-            IPADDRESS_Unregister ();\r
-            LISTVIEW_Unregister ();\r
-            MONTHCAL_Unregister ();\r
-            NATIVEFONT_Unregister ();\r
-            PAGER_Unregister ();\r
-            PROGRESS_Unregister ();\r
-            REBAR_Unregister ();\r
-            STATUS_Unregister ();\r
-            SYSLINK_Unregister ();\r
-            TAB_Unregister ();\r
-            TOOLBAR_Unregister ();\r
-            TOOLTIPS_Unregister ();\r
-            TRACKBAR_Unregister ();\r
-            TREEVIEW_Unregister ();\r
-            UPDOWN_Unregister ();\r
-\r
-            /* delete local pattern brush */\r
-            DeleteObject (COMCTL32_hPattern55AABrush);\r
-            COMCTL32_hPattern55AABrush = NULL;\r
-            DeleteObject (COMCTL32_hPattern55AABitmap);\r
-            COMCTL32_hPattern55AABitmap = NULL;\r
-\r
-            /* delete global subclassing atom */\r
-            GlobalDeleteAtom (LOWORD(COMCTL32_wSubclass));\r
-            TRACE("Subclassing atom deleted: %p\n", COMCTL32_wSubclass);\r
-            COMCTL32_wSubclass = NULL;\r
-            break;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * MenuHelp [COMCTL32.2]\r
- *\r
- * Handles the setting of status bar help messages when the user\r
- * selects menu items.\r
- *\r
- * PARAMS\r
- *     uMsg       [I] message (WM_MENUSELECT) (see NOTES)\r
- *     wParam     [I] wParam of the message uMsg\r
- *     lParam     [I] lParam of the message uMsg\r
- *     hMainMenu  [I] handle to the application's main menu\r
- *     hInst      [I] handle to the module that contains string resources\r
- *     hwndStatus [I] handle to the status bar window\r
- *     lpwIDs     [I] pointer to an array of integers (see NOTES)\r
- *\r
- * RETURNS\r
- *     No return value\r
- *\r
- * NOTES\r
- *     The official documentation is incomplete!\r
- *     This is the correct documentation:\r
- *\r
- *     uMsg:\r
- *     MenuHelp() does NOT handle WM_COMMAND messages! It only handles\r
- *     WM_MENUSELECT messages.\r
- *\r
- *     lpwIDs:\r
- *     (will be written ...)\r
- */\r
-\r
-VOID WINAPI\r
-MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,\r
-         HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)\r
-{\r
-    UINT uMenuID = 0;\r
-\r
-    if (!IsWindow (hwndStatus))\r
-       return;\r
-\r
-    switch (uMsg) {\r
-       case WM_MENUSELECT:\r
-           TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",\r
-                  wParam, lParam);\r
-\r
-            if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {\r
-                /* menu was closed */\r
-               TRACE("menu was closed!\n");\r
-                SendMessageW (hwndStatus, SB_SIMPLE, FALSE, 0);\r
-            }\r
-           else {\r
-               /* menu item was selected */\r
-               if (HIWORD(wParam) & MF_POPUP)\r
-                   uMenuID = (UINT)*(lpwIDs+1);\r
-               else\r
-                   uMenuID = (UINT)LOWORD(wParam);\r
-               TRACE("uMenuID = %u\n", uMenuID);\r
-\r
-               if (uMenuID) {\r
-                   WCHAR szText[256];\r
-\r
-                   if (!LoadStringW (hInst, uMenuID, szText, sizeof(szText)/sizeof(szText[0])))\r
-                       szText[0] = '\0';\r
-\r
-                   SendMessageW (hwndStatus, SB_SETTEXTW,\r
-                                   255 | SBT_NOBORDERS, (LPARAM)szText);\r
-                   SendMessageW (hwndStatus, SB_SIMPLE, TRUE, 0);\r
-               }\r
-           }\r
-           break;\r
-\r
-        case WM_COMMAND :\r
-           TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",\r
-                  wParam, lParam);\r
-           /* WM_COMMAND is not invalid since it is documented\r
-            * in the windows api reference. So don't output\r
-             * any FIXME for WM_COMMAND\r
-             */\r
-           WARN("We don't care about the WM_COMMAND\n");\r
-           break;\r
-\r
-       default:\r
-           FIXME("Invalid Message 0x%x!\n", uMsg);\r
-           break;\r
-    }\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * ShowHideMenuCtl [COMCTL32.3]\r
- *\r
- * Shows or hides controls and updates the corresponding menu item.\r
- *\r
- * PARAMS\r
- *     hwnd   [I] handle to the client window.\r
- *     uFlags [I] menu command id.\r
- *     lpInfo [I] pointer to an array of integers. (See NOTES.)\r
- *\r
- * RETURNS\r
- *     Success: TRUE\r
- *     Failure: FALSE\r
- *\r
- * NOTES\r
- *     The official documentation is incomplete!\r
- *     This is the correct documentation:\r
- *\r
- *     hwnd\r
- *     Handle to the window that contains the menu and controls.\r
- *\r
- *     uFlags\r
- *     Identifier of the menu item to receive or lose a check mark.\r
- *\r
- *     lpInfo\r
- *     The array of integers contains pairs of values. BOTH values of\r
- *     the first pair must be the handles to the application's main menu.\r
- *     Each subsequent pair consists of a menu id and control id.\r
- */\r
-\r
-BOOL WINAPI\r
-ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)\r
-{\r
-    LPINT lpMenuId;\r
-\r
-    TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo);\r
-\r
-    if (lpInfo == NULL)\r
-       return FALSE;\r
-\r
-    if (!(lpInfo[0]) || !(lpInfo[1]))\r
-       return FALSE;\r
-\r
-    /* search for control */\r
-    lpMenuId = &lpInfo[2];\r
-    while (*lpMenuId != uFlags)\r
-       lpMenuId += 2;\r
-\r
-    if (GetMenuState ((HMENU)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {\r
-       /* uncheck menu item */\r
-       CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);\r
-\r
-       /* hide control */\r
-       lpMenuId++;\r
-       SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,\r
-                       SWP_HIDEWINDOW);\r
-    }\r
-    else {\r
-       /* check menu item */\r
-       CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);\r
-\r
-       /* show control */\r
-       lpMenuId++;\r
-       SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,\r
-                       SWP_SHOWWINDOW);\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * GetEffectiveClientRect [COMCTL32.4]\r
- *\r
- * Calculates the coordinates of a rectangle in the client area.\r
- *\r
- * PARAMS\r
- *     hwnd   [I] handle to the client window.\r
- *     lpRect [O] pointer to the rectangle of the client window\r
- *     lpInfo [I] pointer to an array of integers (see NOTES)\r
- *\r
- * RETURNS\r
- *     No return value.\r
- *\r
- * NOTES\r
- *     The official documentation is incomplete!\r
- *     This is the correct documentation:\r
- *\r
- *     lpInfo\r
- *     (will be written ...)\r
- */\r
-\r
-VOID WINAPI\r
-GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)\r
-{\r
-    RECT rcCtrl;\r
-    INT  *lpRun;\r
-    HWND hwndCtrl;\r
-\r
-    TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",\r
-          (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);\r
-\r
-    GetClientRect (hwnd, lpRect);\r
-    lpRun = lpInfo;\r
-\r
-    do {\r
-       lpRun += 2;\r
-       if (*lpRun == 0)\r
-           return;\r
-       lpRun++;\r
-       hwndCtrl = GetDlgItem (hwnd, *lpRun);\r
-       if (GetWindowLongW (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {\r
-           TRACE("control id 0x%x\n", *lpRun);\r
-           GetWindowRect (hwndCtrl, &rcCtrl);\r
-           MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);\r
-           SubtractRect (lpRect, lpRect, &rcCtrl);\r
-       }\r
-       lpRun++;\r
-    } while (*lpRun);\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * DrawStatusTextW [COMCTL32.@]\r
- *\r
- * Draws text with borders, like in a status bar.\r
- *\r
- * PARAMS\r
- *     hdc   [I] handle to the window's display context\r
- *     lprc  [I] pointer to a rectangle\r
- *     text  [I] pointer to the text\r
- *     style [I] drawing style\r
- *\r
- * RETURNS\r
- *     No return value.\r
- *\r
- * NOTES\r
- *     The style variable can have one of the following values:\r
- *     (will be written ...)\r
- */\r
-\r
-void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)\r
-{\r
-    RECT r = *lprc;\r
-    UINT border = BDR_SUNKENOUTER;\r
-\r
-    if (style & SBT_POPOUT)\r
-        border = BDR_RAISEDOUTER;\r
-    else if (style & SBT_NOBORDERS)\r
-        border = 0;\r
-\r
-    DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);\r
-\r
-    /* now draw text */\r
-    if (text) {\r
-        int oldbkmode = SetBkMode (hdc, TRANSPARENT);\r
-        UINT align = DT_LEFT;\r
-        if (*text == L'\t') {\r
-           text++;\r
-           align = DT_CENTER;\r
-           if (*text == L'\t') {\r
-               text++;\r
-               align = DT_RIGHT;\r
-           }\r
-        }\r
-        r.left += 3;\r
-        if (style & SBT_RTLREADING)\r
-           FIXME("Unsupported RTL style!\n");\r
-        DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);\r
-       SetBkMode(hdc, oldbkmode);\r
-    }\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * DrawStatusText  [COMCTL32.@]\r
- * DrawStatusTextA [COMCTL32.5]\r
- *\r
- * Draws text with borders, like in a status bar.\r
- *\r
- * PARAMS\r
- *     hdc   [I] handle to the window's display context\r
- *     lprc  [I] pointer to a rectangle\r
- *     text  [I] pointer to the text\r
- *     style [I] drawing style\r
- *\r
- * RETURNS\r
- *     No return value.\r
- */\r
-\r
-void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)\r
-{\r
-    INT len;\r
-    LPWSTR textW = NULL;\r
-\r
-    if ( text ) {\r
-       if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {\r
-           if ( (textW = Alloc( len * sizeof(WCHAR) )) )\r
-               MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );\r
-       }\r
-    }\r
-    DrawStatusTextW( hdc, lprc, textW, style );\r
-    Free( textW );\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * CreateStatusWindow  [COMCTL32.@]\r
- * CreateStatusWindowA [COMCTL32.6]\r
- *\r
- * Creates a status bar\r
- *\r
- * PARAMS\r
- *     style  [I] window style\r
- *     text   [I] pointer to the window text\r
- *     parent [I] handle to the parent window\r
- *     wid    [I] control id of the status bar\r
- *\r
- * RETURNS\r
- *     Success: handle to the status window\r
- *     Failure: 0\r
- */\r
-\r
-HWND WINAPI\r
-CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)\r
-{\r
-    return CreateWindowA(STATUSCLASSNAMEA, text, style,\r
-                          CW_USEDEFAULT, CW_USEDEFAULT,\r
-                          CW_USEDEFAULT, CW_USEDEFAULT,\r
-                          parent, (HMENU)wid, 0, 0);\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * CreateStatusWindowW [COMCTL32.@]\r
- *\r
- * Creates a status bar control\r
- *\r
- * PARAMS\r
- *     style  [I] window style\r
- *     text   [I] pointer to the window text\r
- *     parent [I] handle to the parent window\r
- *     wid    [I] control id of the status bar\r
- *\r
- * RETURNS\r
- *     Success: handle to the status window\r
- *     Failure: 0\r
- */\r
-\r
-HWND WINAPI\r
-CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)\r
-{\r
-    return CreateWindowW(STATUSCLASSNAMEW, text, style,\r
-                          CW_USEDEFAULT, CW_USEDEFAULT,\r
-                          CW_USEDEFAULT, CW_USEDEFAULT,\r
-                          parent, (HMENU)wid, 0, 0);\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * CreateUpDownControl [COMCTL32.16]\r
- *\r
- * Creates an up-down control\r
- *\r
- * PARAMS\r
- *     style  [I] window styles\r
- *     x      [I] horizontal position of the control\r
- *     y      [I] vertical position of the control\r
- *     cx     [I] with of the control\r
- *     cy     [I] height of the control\r
- *     parent [I] handle to the parent window\r
- *     id     [I] the control's identifier\r
- *     inst   [I] handle to the application's module instance\r
- *     buddy  [I] handle to the buddy window, can be NULL\r
- *     maxVal [I] upper limit of the control\r
- *     minVal [I] lower limit of the control\r
- *     curVal [I] current value of the control\r
- *\r
- * RETURNS\r
- *     Success: handle to the updown control\r
- *     Failure: 0\r
- */\r
-\r
-HWND WINAPI\r
-CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,\r
-                    HWND parent, INT id, HINSTANCE inst,\r
-                    HWND buddy, INT maxVal, INT minVal, INT curVal)\r
-{\r
-    HWND hUD =\r
-       CreateWindowW (UPDOWN_CLASSW, 0, style, x, y, cx, cy,\r
-                        parent, (HMENU)id, inst, 0);\r
-    if (hUD) {\r
-       SendMessageW (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);\r
-       SendMessageW (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));\r
-       SendMessageW (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));\r
-    }\r
-\r
-    return hUD;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * InitCommonControls [COMCTL32.17]\r
- *\r
- * Registers the common controls.\r
- *\r
- * PARAMS\r
- *     No parameters.\r
- *\r
- * RETURNS\r
- *     No return values.\r
- *\r
- * NOTES\r
- *     This function is just a dummy.\r
- *     The Win95 controls are registered at the DLL's initialization.\r
- *     To register other controls InitCommonControlsEx() must be used.\r
- */\r
-\r
-VOID WINAPI\r
-InitCommonControls (void)\r
-{\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * InitCommonControlsEx [COMCTL32.@]\r
- *\r
- * Registers the common controls.\r
- *\r
- * PARAMS\r
- *     lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.\r
- *\r
- * RETURNS\r
- *     Success: TRUE\r
- *     Failure: FALSE\r
- *\r
- * NOTES\r
- *     Only the additional common controls are registered by this function.\r
- *     The Win95 controls are registered at the DLL's initialization.\r
- *\r
- * FIXME\r
- *     implement the following control classes:\r
- *       ICC_LINK_CLASS\r
- *       ICC_STANDARD_CLASSES\r
- */\r
-\r
-BOOL WINAPI\r
-InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)\r
-{\r
-    INT cCount;\r
-    DWORD dwMask;\r
-\r
-    if (!lpInitCtrls)\r
-       return FALSE;\r
-    if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))\r
-       return FALSE;\r
-\r
-    TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);\r
-\r
-    for (cCount = 0; cCount < 32; cCount++) {\r
-       dwMask = 1 << cCount;\r
-       if (!(lpInitCtrls->dwICC & dwMask))\r
-           continue;\r
-\r
-       switch (lpInitCtrls->dwICC & dwMask) {\r
-           /* dummy initialization */\r
-           case ICC_ANIMATE_CLASS:\r
-           case ICC_BAR_CLASSES:\r
-           case ICC_LISTVIEW_CLASSES:\r
-           case ICC_TREEVIEW_CLASSES:\r
-           case ICC_TAB_CLASSES:\r
-           case ICC_UPDOWN_CLASS:\r
-           case ICC_PROGRESS_CLASS:\r
-           case ICC_HOTKEY_CLASS:\r
-               break;\r
-\r
-           /* advanced classes - not included in Win95 */\r
-           case ICC_DATE_CLASSES:\r
-               MONTHCAL_Register ();\r
-               DATETIME_Register ();\r
-               break;\r
-\r
-           case ICC_USEREX_CLASSES:\r
-               COMBOEX_Register ();\r
-               break;\r
-\r
-           case ICC_COOL_CLASSES:\r
-               REBAR_Register ();\r
-               break;\r
-\r
-           case ICC_INTERNET_CLASSES:\r
-               IPADDRESS_Register ();\r
-               break;\r
-\r
-           case ICC_PAGESCROLLER_CLASS:\r
-               PAGER_Register ();\r
-               break;\r
-\r
-           case ICC_NATIVEFNTCTL_CLASS:\r
-               NATIVEFONT_Register ();\r
-               break;\r
-\r
-           case ICC_LINK_CLASS:\r
-               SYSLINK_Register ();\r
-               break;\r
-\r
-           default:\r
-               FIXME("Unknown class! dwICC=0x%lX\n", dwMask);\r
-               break;\r
-       }\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * CreateToolbarEx [COMCTL32.@]\r
- *\r
- * Creates a toolbar window.\r
- *\r
- * PARAMS\r
- *     hwnd\r
- *     style\r
- *     wID\r
- *     nBitmaps\r
- *     hBMInst\r
- *     wBMID\r
- *     lpButtons\r
- *     iNumButtons\r
- *     dxButton\r
- *     dyButton\r
- *     dxBitmap\r
- *     dyBitmap\r
- *     uStructSize\r
- *\r
- * RETURNS\r
- *     Success: handle to the tool bar control\r
- *     Failure: 0\r
- */\r
-\r
-HWND WINAPI\r
-CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,\r
-                 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,\r
-                 INT iNumButtons, INT dxButton, INT dyButton,\r
-                 INT dxBitmap, INT dyBitmap, UINT uStructSize)\r
-{\r
-    HWND hwndTB;\r
-\r
-    hwndTB =\r
-        CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style|WS_CHILD, 0,0,100,30,\r
-                        hwnd, (HMENU)wID, COMCTL32_hModule, NULL);\r
-    if(hwndTB) {\r
-       TBADDBITMAP tbab;\r
-\r
-        SendMessageW (hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM)uStructSize, 0);\r
-\r
-       /* set bitmap and button size */\r
-       /*If CreateToolbarEx receives 0, windows sets default values*/\r
-       if (dxBitmap <= 0)\r
-           dxBitmap = 16;\r
-       if (dyBitmap <= 0)\r
-           dyBitmap = 15;\r
-       SendMessageW (hwndTB, TB_SETBITMAPSIZE, 0,\r
-                     MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));\r
-\r
-       if (dxButton <= 0)\r
-           dxButton = 24;\r
-       if (dyButton <= 0)\r
-           dyButton = 22;\r
-       SendMessageW (hwndTB, TB_SETBUTTONSIZE, 0,\r
-                     MAKELPARAM((WORD)dxButton, (WORD)dyButton));\r
-\r
-\r
-       /* add bitmaps */\r
-       if (nBitmaps > 0)\r
-       {\r
-           tbab.hInst = hBMInst;\r
-           tbab.nID   = wBMID;\r
-\r
-           SendMessageW (hwndTB, TB_ADDBITMAP, (WPARAM)nBitmaps, (LPARAM)&tbab);\r
-       }\r
-       /* add buttons */\r
-       if(iNumButtons > 0)\r
-       SendMessageW (hwndTB, TB_ADDBUTTONSW,\r
-                       (WPARAM)iNumButtons, (LPARAM)lpButtons);\r
-    }\r
-\r
-    return hwndTB;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * CreateMappedBitmap [COMCTL32.8]\r
- *\r
- * Loads a bitmap resource using a colour map.\r
- *\r
- * PARAMS\r
- *     hInstance  [I] Handle to the module containing the bitmap.\r
- *     idBitmap   [I] The bitmap resource ID.\r
- *     wFlags     [I] CMB_MASKED for using bitmap as a mask or 0 for normal.\r
- *     lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).\r
- *     iNumMaps   [I] Number of COLORMAP's pointed to by lpColorMap.\r
- *\r
- * RETURNS\r
- *     Success: handle to the new bitmap\r
- *     Failure: 0\r
- */\r
-\r
-HBITMAP WINAPI\r
-CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,\r
-                   LPCOLORMAP lpColorMap, INT iNumMaps)\r
-{\r
-    HGLOBAL hglb;\r
-    HRSRC hRsrc;\r
-    LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;\r
-    UINT nSize, nColorTableSize, iColor;\r
-    RGBQUAD *pColorTable;\r
-    INT i, iMaps, nWidth, nHeight;\r
-    HDC hdcScreen;\r
-    HBITMAP hbm;\r
-    LPCOLORMAP sysColorMap;\r
-    COLORREF cRef;\r
-    COLORMAP internalColorMap[4] =\r
-       {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};\r
-\r
-    /* initialize pointer to colortable and default color table */\r
-    if (lpColorMap) {\r
-       iMaps = iNumMaps;\r
-       sysColorMap = lpColorMap;\r
-    }\r
-    else {\r
-       internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);\r
-       internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);\r
-       internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);\r
-       internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);\r
-       iMaps = 4;\r
-       sysColorMap = (LPCOLORMAP)internalColorMap;\r
-    }\r
-\r
-    hRsrc = FindResourceW (hInstance, (LPWSTR)idBitmap, (LPWSTR)RT_BITMAP);\r
-    if (hRsrc == 0)\r
-       return 0;\r
-    hglb = LoadResource (hInstance, hRsrc);\r
-    if (hglb == 0)\r
-       return 0;\r
-    lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);\r
-    if (lpBitmap == NULL)\r
-       return 0;\r
-\r
-    if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)\r
-        nColorTableSize = lpBitmap->biClrUsed;\r
-    else if (lpBitmap->biBitCount <= 8)        \r
-        nColorTableSize = (1 << lpBitmap->biBitCount);\r
-    else\r
-        nColorTableSize = 0;\r
-    nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);\r
-    lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);\r
-    if (lpBitmapInfo == NULL)\r
-       return 0;\r
-    RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);\r
-\r
-    pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);\r
-\r
-    for (iColor = 0; iColor < nColorTableSize; iColor++) {\r
-       for (i = 0; i < iMaps; i++) {\r
-            cRef = RGB(pColorTable[iColor].rgbRed,\r
-                       pColorTable[iColor].rgbGreen,\r
-                       pColorTable[iColor].rgbBlue);\r
-           if ( cRef  == sysColorMap[i].from) {\r
-#if 0\r
-               if (wFlags & CBS_MASKED) {\r
-                   if (sysColorMap[i].to != COLOR_BTNTEXT)\r
-                       pColorTable[iColor] = RGB(255, 255, 255);\r
-               }\r
-               else\r
-#endif\r
-                    pColorTable[iColor].rgbBlue  = GetBValue(sysColorMap[i].to);\r
-                    pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);\r
-                    pColorTable[iColor].rgbRed   = GetRValue(sysColorMap[i].to);\r
-               break;\r
-           }\r
-       }\r
-    }\r
-    nWidth  = (INT)lpBitmapInfo->biWidth;\r
-    nHeight = (INT)lpBitmapInfo->biHeight;\r
-    hdcScreen = GetDC (NULL);\r
-    hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);\r
-    if (hbm) {\r
-       HDC hdcDst = CreateCompatibleDC (hdcScreen);\r
-       HBITMAP hbmOld = SelectObject (hdcDst, hbm);\r
-       LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);\r
-       lpBits += nColorTableSize * sizeof(RGBQUAD);\r
-       StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,\r
-                        lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,\r
-                        SRCCOPY);\r
-       SelectObject (hdcDst, hbmOld);\r
-       DeleteDC (hdcDst);\r
-    }\r
-    ReleaseDC (NULL, hdcScreen);\r
-    GlobalFree ((HGLOBAL)lpBitmapInfo);\r
-    FreeResource (hglb);\r
-\r
-    return hbm;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * CreateToolbar [COMCTL32.7]\r
- *\r
- * Creates a toolbar control.\r
- *\r
- * PARAMS\r
- *     hwnd\r
- *     style\r
- *     wID\r
- *     nBitmaps\r
- *     hBMInst\r
- *     wBMID\r
- *     lpButtons\r
- *     iNumButtons\r
- *\r
- * RETURNS\r
- *     Success: handle to the tool bar control\r
- *     Failure: 0\r
- *\r
- * NOTES\r
- *     Do not use this functions anymore. Use CreateToolbarEx instead.\r
- */\r
-\r
-HWND WINAPI\r
-CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,\r
-              HINSTANCE hBMInst, UINT wBMID,\r
-              LPCTBBUTTON lpButtons,INT iNumButtons)\r
-{\r
-    return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,\r
-                           hBMInst, wBMID, lpButtons,\r
-                           iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * DllGetVersion [COMCTL32.@]\r
- *\r
- * Retrieves version information of the 'COMCTL32.DLL'\r
- *\r
- * PARAMS\r
- *     pdvi [O] pointer to version information structure.\r
- *\r
- * RETURNS\r
- *     Success: S_OK\r
- *     Failure: E_INVALIDARG\r
- *\r
- * NOTES\r
- *     Returns version of a comctl32.dll from IE4.01 SP1.\r
- */\r
-\r
-HRESULT WINAPI\r
-COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)\r
-{\r
-    if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {\r
-        WARN("wrong DLLVERSIONINFO size from app\n");\r
-       return E_INVALIDARG;\r
-    }\r
-\r
-    pdvi->dwMajorVersion = COMCTL32_VERSION;\r
-    pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;\r
-    pdvi->dwBuildNumber = 2919;\r
-    pdvi->dwPlatformID = 6304;\r
-\r
-    TRACE("%lu.%lu.%lu.%lu\n",\r
-          pdvi->dwMajorVersion, pdvi->dwMinorVersion,\r
-          pdvi->dwBuildNumber, pdvi->dwPlatformID);\r
-\r
-    return S_OK;\r
-}\r
-\r
-/***********************************************************************\r
- *             DllInstall (COMCTL32.@)\r
- *\r
- * Installs the ComCtl32 DLL.\r
- *\r
- * RETURNS\r
- *     Success: S_OK\r
- *     Failure: A HRESULT error\r
- */\r
-HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)\r
-{\r
-  FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",\r
-       debugstr_w(cmdline));\r
-\r
-  return S_OK;\r
-}\r
-\r
-/***********************************************************************\r
- * _TrackMouseEvent [COMCTL32.@]\r
- *\r
- * Requests notification of mouse events\r
- *\r
- * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted\r
- * to the hwnd specified in the ptme structure.  After the event message\r
- * is posted to the hwnd, the entry in the queue is removed.\r
- *\r
- * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely\r
- * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted\r
- * immediately and the TME_LEAVE flag being ignored.\r
- *\r
- * PARAMS\r
- *     ptme [I,O] pointer to TRACKMOUSEEVENT information structure.\r
- *\r
- * RETURNS\r
- *     Success: non-zero\r
- *     Failure: zero\r
- *\r
- * IMPLEMENTATION moved to USER32.TrackMouseEvent\r
- *\r
- */\r
-\r
-BOOL WINAPI\r
-_TrackMouseEvent (TRACKMOUSEEVENT *ptme)\r
-{\r
-    return TrackMouseEvent (ptme);\r
-}\r
-\r
-/*************************************************************************\r
- * GetMUILanguage [COMCTL32.@]\r
- *\r
- * Returns the user interface language in use by the current process.\r
- *\r
- * RETURNS\r
- *      Language ID in use by the current process.\r
- */\r
-LANGID WINAPI GetMUILanguage (VOID)\r
-{\r
-    return COMCTL32_uiLang;\r
-}\r
-\r
-\r
-/*************************************************************************\r
- * InitMUILanguage [COMCTL32.@]\r
- *\r
- * Sets the user interface language to be used by the current process.\r
- *\r
- * RETURNS\r
- *      Nothing.\r
- */\r
-VOID WINAPI InitMUILanguage (LANGID uiLang)\r
-{\r
-   COMCTL32_uiLang = uiLang;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * SetWindowSubclass [COMCTL32.410]\r
- *\r
- * Starts a window subclass\r
- *\r
- * PARAMS\r
- *     hWnd [in] handle to window subclass.\r
- *     pfnSubclass [in] Pointer to new window procedure.\r
- *     uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.\r
- *     dwRef [in] Reference data to pass to window procedure.\r
- *\r
- * RETURNS\r
- *     Success: non-zero\r
- *     Failure: zero\r
- *\r
- * BUGS\r
- *     If an application manually subclasses a window after subclassing it with\r
- *     this API and then with this API again, then none of the previous \r
- *     subclasses get called or the origional window procedure.\r
- */\r
-\r
-BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,\r
-                        UINT_PTR uIDSubclass, DWORD_PTR dwRef)\r
-{\r
-   LPSUBCLASS_INFO stack;\r
-   LPSUBCLASSPROCS proc;\r
-\r
-   TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);\r
-\r
-   /* Since the window procedure that we set here has two additional arguments,\r
-    * we can't simply set it as the new window procedure of the window. So we\r
-    * set our own window procedure and then calculate the other two arguments\r
-    * from there. */\r
-\r
-   /* See if we have been called for this window */\r
-   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);\r
-   if (!stack) {\r
-      /* allocate stack */\r
-      stack = Alloc (sizeof(SUBCLASS_INFO));\r
-      if (!stack) {\r
-         ERR ("Failed to allocate our Subclassing stack\n");\r
-         return FALSE;\r
-      }\r
-      SetPropW (hWnd, COMCTL32_wSubclass, (HANDLE)stack);\r
-\r
-      /* set window procedure to our own and save the current one */\r
-      if (IsWindowUnicode (hWnd))\r
-         stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC,\r
-                                                   (DWORD_PTR)COMCTL32_SubclassProc);\r
-      else\r
-         stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC,\r
-                                                   (DWORD_PTR)COMCTL32_SubclassProc);\r
-   }\r
-   else {\r
-      /* Check to see if we have called this function with the same uIDSubClass\r
-       * and pfnSubclass */\r
-      proc = stack->SubclassProcs;\r
-      while (proc) {\r
-         if ((proc->id == uIDSubclass) &&\r
-            (proc->subproc == pfnSubclass)) {\r
-            proc->ref = dwRef;\r
-            return TRUE;\r
-         }\r
-         proc = proc->next;\r
-      }\r
-   }\r
-   \r
-   proc = Alloc(sizeof(SUBCLASSPROCS));\r
-   if (!proc) {\r
-      ERR ("Failed to allocate subclass entry in stack\n");\r
-      if (IsWindowUnicode (hWnd))\r
-         SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);\r
-      else\r
-         SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);\r
-      Free (stack);\r
-      RemovePropW( hWnd, COMCTL32_wSubclass );\r
-      return FALSE;\r
-   }\r
-   \r
-   proc->subproc = pfnSubclass;\r
-   proc->ref = dwRef;\r
-   proc->id = uIDSubclass;\r
-   proc->next = stack->SubclassProcs;\r
-   stack->SubclassProcs = proc;\r
-\r
-   return TRUE;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * GetWindowSubclass [COMCTL32.411]\r
- *\r
- * Gets the Reference data from a subclass.\r
- *\r
- * PARAMS\r
- *     hWnd [in] Handle to window which were subclassing\r
- *     pfnSubclass [in] Pointer to the subclass procedure\r
- *     uID [in] Unique indentifier of the subclassing procedure\r
- *     pdwRef [out] Pointer to the reference data\r
- *\r
- * RETURNS\r
- *     Success: Non-zero\r
- *     Failure: 0\r
- */\r
-\r
-BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,\r
-                              UINT_PTR uID, DWORD_PTR *pdwRef)\r
-{\r
-   LPSUBCLASS_INFO stack;\r
-   LPSUBCLASSPROCS proc;\r
-\r
-   TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);\r
-\r
-   /* See if we have been called for this window */\r
-   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);\r
-   if (!stack)\r
-      return FALSE;\r
-\r
-   proc = stack->SubclassProcs;\r
-   while (proc) {\r
-      if ((proc->id == uID) &&\r
-         (proc->subproc == pfnSubclass)) {\r
-         *pdwRef = proc->ref;\r
-         return TRUE;\r
-      }\r
-      proc = proc->next;\r
-   }\r
-\r
-   return FALSE;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * RemoveWindowSubclass [COMCTL32.412]\r
- *\r
- * Removes a window subclass.\r
- *\r
- * PARAMS\r
- *     hWnd [in] Handle to the window were subclassing\r
- *     pfnSubclass [in] Pointer to the subclass procedure\r
- *     uID [in] Unique identifier of this subclass\r
- *\r
- * RETURNS\r
- *     Success: non-zero\r
- *     Failure: zero\r
- */\r
-\r
-BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)\r
-{\r
-   LPSUBCLASS_INFO stack;\r
-   LPSUBCLASSPROCS prevproc = NULL;\r
-   LPSUBCLASSPROCS proc;\r
-   BOOL ret = FALSE;\r
-\r
-   TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID);\r
-\r
-   /* Find the Subclass to remove */\r
-   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);\r
-   if (!stack)\r
-      return FALSE;\r
-\r
-   proc = stack->SubclassProcs;\r
-   while (proc) {\r
-      if ((proc->id == uID) &&\r
-         (proc->subproc == pfnSubclass)) {\r
-         \r
-         if (!prevproc)\r
-            stack->SubclassProcs = proc->next;\r
-         else\r
-            prevproc->next = proc->next;\r
-          \r
-         if (stack->stackpos == proc)\r
-            stack->stackpos = stack->stackpos->next;\r
-            \r
-         Free (proc);\r
-         ret = TRUE;\r
-         break;\r
-      }\r
-      prevproc = proc;\r
-      proc = proc->next;\r
-   }\r
-   \r
-   if (!stack->SubclassProcs && !stack->running) {\r
-      TRACE("Last Subclass removed, cleaning up\n");\r
-      /* clean up our heap and reset the origional window procedure */\r
-      if (IsWindowUnicode (hWnd))\r
-         SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);\r
-      else\r
-         SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);\r
-      Free (stack);\r
-      RemovePropW( hWnd, COMCTL32_wSubclass );\r
-   }\r
-   \r
-   return ret;\r
-}\r
-\r
-/***********************************************************************\r
- * COMCTL32_SubclassProc (internal)\r
- *\r
- * Window procedure for all subclassed windows. \r
- * Saves the current subclassing stack position to support nested messages\r
- */\r
-LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
-   LPSUBCLASS_INFO stack;\r
-   LPSUBCLASSPROCS proc;\r
-   LRESULT ret;\r
-    \r
-   TRACE ("(%p, 0x%08x, 0x%08x, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);\r
-\r
-   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);\r
-   if (!stack) {\r
-      ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);\r
-      return 0;\r
-   }\r
-    \r
-   /* Save our old stackpos to properly handle nested messages */\r
-   proc = stack->stackpos;\r
-   stack->stackpos = stack->SubclassProcs;\r
-   stack->running++;\r
-   ret = DefSubclassProc(hWnd, uMsg, wParam, lParam);\r
-   stack->running--;\r
-   stack->stackpos = proc;\r
-    \r
-   if (!stack->SubclassProcs && !stack->running) {\r
-      TRACE("Last Subclass removed, cleaning up\n");\r
-      /* clean up our heap and reset the origional window procedure */\r
-      if (IsWindowUnicode (hWnd))\r
-         SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);\r
-      else\r
-         SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);\r
-      Free (stack);\r
-      RemovePropW( hWnd, COMCTL32_wSubclass );\r
-   }\r
-   return ret;\r
-}\r
-\r
-/***********************************************************************\r
- * DefSubclassProc [COMCTL32.413]\r
- *\r
- * Calls the next window procedure (ie. the one before this subclass)\r
- *\r
- * PARAMS\r
- *     hWnd [in] The window that we're subclassing\r
- *     uMsg [in] Message\r
- *     wParam [in] WPARAM\r
- *     lParam [in] LPARAM\r
- *\r
- * RETURNS\r
- *     Success: non-zero\r
- *     Failure: zero\r
- */\r
-\r
-LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
-   LPSUBCLASS_INFO stack;\r
-   LRESULT ret;\r
-   \r
-   TRACE ("(%p, 0x%08x, 0x%08x, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);\r
-\r
-   /* retrieve our little stack from the Properties */\r
-   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);\r
-   if (!stack) {\r
-      ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);\r
-      return 0;\r
-   }\r
-\r
-   /* If we are at the end of stack then we have to call the original\r
-    * window procedure */\r
-   if (!stack->stackpos) {\r
-      if (IsWindowUnicode (hWnd))\r
-         ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);\r
-      else\r
-         ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);\r
-   } else {\r
-      LPSUBCLASSPROCS proc = stack->stackpos;\r
-      stack->stackpos = stack->stackpos->next; \r
-      /* call the Subclass procedure from the stack */\r
-      ret = proc->subproc (hWnd, uMsg, wParam, lParam,\r
-            proc->id, proc->ref);\r
-   }\r
-\r
-   return ret;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * COMCTL32_CreateToolTip [NOT AN API]\r
- *\r
- * Creates a tooltip for the control specified in hwnd and does all\r
- * necessary setup and notifications.\r
- *\r
- * PARAMS\r
- *     hwndOwner [I] Handle to the window that will own the tool tip.\r
- *\r
- * RETURNS\r
- *     Success: Handle of tool tip window.\r
- *     Failure: NULL\r
- */\r
-\r
-HWND\r
-COMCTL32_CreateToolTip(HWND hwndOwner)\r
-{\r
-    HWND hwndToolTip;\r
-\r
-    hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0,\r
-                                 CW_USEDEFAULT, CW_USEDEFAULT,\r
-                                 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,\r
-                                 0, 0, 0);\r
-\r
-    /* Send NM_TOOLTIPSCREATED notification */\r
-    if (hwndToolTip)\r
-    {\r
-       NMTOOLTIPSCREATED nmttc;\r
-        /* true owner can be different if hwndOwner is a child window */\r
-        HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);\r
-        nmttc.hdr.hwndFrom = hwndTrueOwner;\r
-        nmttc.hdr.idFrom = GetWindowLongPtrW(hwndTrueOwner, GWLP_ID);\r
-       nmttc.hdr.code = NM_TOOLTIPSCREATED;\r
-       nmttc.hwndToolTips = hwndToolTip;\r
-\r
-       SendMessageW(GetParent(hwndTrueOwner), WM_NOTIFY,\r
-                    (WPARAM)GetWindowLongPtrW(hwndTrueOwner, GWLP_ID),\r
-                   (LPARAM)&nmttc);\r
-    }\r
-\r
-    return hwndToolTip;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * COMCTL32_RefreshSysColors [NOT AN API]\r
- *\r
- * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to\r
- * refresh the color values in the color structure\r
- *\r
- * PARAMS\r
- *     none\r
- *\r
- * RETURNS\r
- *     none\r
- */\r
-\r
-VOID\r
-COMCTL32_RefreshSysColors(void)\r
-{\r
-    comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);\r
-    comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);\r
-    comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);\r
-    comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);\r
-    comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);\r
-    comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);\r
-    comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);\r
-    comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);\r
-    comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);\r
-    comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);\r
-    comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);\r
-    comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);\r
-    comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);\r
-    comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);\r
-    comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);\r
-    comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);\r
-}\r
-\r
-/***********************************************************************\r
- * COMCTL32_DrawInsertMark [NOT AN API]\r
- *\r
- * Draws an insertion mark (which looks similar to an 'I').\r
- *\r
- * PARAMS\r
- *     hDC           [I] Device context to draw onto.\r
- *     lpRect        [I] Co-ordinates of insertion mark.\r
- *     clrInsertMark [I] Colour of the insertion mark.\r
- *     bHorizontal   [I] True if insert mark should be drawn horizontally,\r
- *                       vertical otherwise.\r
- *\r
- * RETURNS\r
- *     none\r
- *\r
- * NOTES\r
- *     Draws up to but not including the bottom co-ordinate when drawing\r
- *     vertically or the right co-ordinate when horizontal.\r
- */\r
-void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal)\r
-{\r
-    HPEN hPen = CreatePen(PS_SOLID, 1, clrInsertMark);\r
-    HPEN hOldPen;\r
-    static const DWORD adwPolyPoints[] = {4,4,4};\r
-    LONG lCentre = (bHorizontal ? \r
-        lpRect->top + (lpRect->bottom - lpRect->top)/2 : \r
-        lpRect->left + (lpRect->right - lpRect->left)/2);\r
-    LONG l1 = (bHorizontal ? lpRect->left : lpRect->top);\r
-    LONG l2 = (bHorizontal ? lpRect->right : lpRect->bottom);\r
-    const POINT aptInsertMark[] =\r
-    {\r
-        /* top (V) or left (H) arrow */\r
-        {lCentre    , l1 + 2},\r
-        {lCentre - 2, l1    },\r
-        {lCentre + 3, l1    },\r
-        {lCentre + 1, l1 + 2},\r
-        /* middle line */\r
-        {lCentre    , l2 - 2},\r
-        {lCentre    , l1 - 1},\r
-        {lCentre + 1, l1 - 1},\r
-        {lCentre + 1, l2 - 2},\r
-        /* bottom (V) or right (H) arrow */\r
-        {lCentre    , l2 - 3},\r
-        {lCentre - 2, l2 - 1},\r
-        {lCentre + 3, l2 - 1},\r
-        {lCentre + 1, l2 - 3},\r
-    };\r
-    hOldPen = SelectObject(hDC, hPen);\r
-    PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));\r
-    SelectObject(hDC, hOldPen);\r
-    DeleteObject(hPen);\r
-}\r
-\r
-/***********************************************************************\r
- * MirrorIcon [COMCTL32.414]\r
- *\r
- * Mirrors an icon so that it will appear correctly on a mirrored DC.\r
- *\r
- * PARAMS\r
- *     phicon1 [I/O] Icon.\r
- *     phicon2 [I/O] Icon.\r
- *\r
- * RETURNS\r
- *     Success: TRUE.\r
- *     Failure: FALSE.\r
- */\r
-BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2)\r
-{\r
-    FIXME("(%p, %p): stub\n", phicon1, phicon2);\r
-    return FALSE;\r
-}\r
-\r
-static inline int IsDelimiter(WCHAR c)\r
-{\r
-    switch(c)\r
-    {\r
-       case '/':\r
-       case '\\':\r
-       case '.':\r
-       case ' ':\r
-           return TRUE;\r
-    }\r
-    return FALSE;\r
-}\r
-\r
-static int CALLBACK PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code)\r
-{\r
-    if (code == WB_ISDELIMITER)\r
-        return IsDelimiter(lpch[ichCurrent]);\r
-    else\r
-    {\r
-        int dir = (code == WB_LEFT) ? -1 : 1;\r
-        for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)\r
-            if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;\r
-    }\r
-    return ichCurrent;\r
-}\r
-\r
-/***********************************************************************\r
- * SetPathWordBreakProc [COMCTL32.384]\r
- *\r
- * Sets the word break procedure for an edit control to one that understands\r
- * paths so that the user can jump over directories.\r
- *\r
- * PARAMS\r
- *     hwnd [I] Handle to edit control.\r
- *     bSet [I] If this is TRUE then the word break proc is set, otherwise it is removed.\r
- *\r
- * RETURNS\r
- *     Result from EM_SETWORDBREAKPROC message.\r
- */\r
-LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)\r
-{\r
-    return SendMessageW(hwnd, EM_SETWORDBREAKPROC, 0,\r
-        (LPARAM)(bSet ? PathWordBreakProc : NULL));\r
-}\r
+/*
+ * Common controls functions
+ *
+ * Copyright 1997 Dimitrie O. Paun
+ * Copyright 1998,2000 Eric Kohl
+ *
+ * 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
+ *
+ * NOTES
+ * 
+ * This code was audited for completeness against the documented features
+ * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.
+ *
+ * Unless otherwise noted, we believe this code to be complete, as per
+ * the specification mentioned above.
+ * If you discover missing features, or bugs, please note them below.
+ *
+ * TODO
+ *   -- implement GetMUILanguage + InitMUILanguage
+ *   -- LibMain => DLLMain ("DLLMain takes over the functionality of both the
+ *                           LibMain and the WEP function.", MSDN)
+ *   -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
+ *   -- FIXMEs + BUGS (search for them)
+ *
+ * Control Classes
+ *   -- ICC_ANIMATE_CLASS
+ *   -- ICC_BAR_CLASSES
+ *   -- ICC_COOL_CLASSES
+ *   -- ICC_DATE_CLASSES
+ *   -- ICC_HOTKEY_CLASS
+ *   -- ICC_INTERNET_CLASSES
+ *   -- ICC_LINK_CLASS
+ *   -- ICC_LISTVIEW_CLASSES
+ *   -- ICC_NATIVEFNTCTL_CLASS
+ *   -- ICC_PAGESCROLLER_CLASS
+ *   -- ICC_PROGRESS_CLASS
+ *   -- ICC_STANDARD_CLASSES (not yet implemented)
+ *   -- ICC_TAB_CLASSES
+ *   -- ICC_TREEVIEW_CLASSES
+ *   -- ICC_UPDOWN_CLASS
+ *   -- ICC_USEREX_CLASSES
+ *   -- ICC_WIN95_CLASSES
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "commctrl.h"
+#include "winerror.h"
+#include "winreg.h"
+#define NO_SHLWAPI_STREAM
+#include "shlwapi.h"
+#include "comctl32.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
+
+LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+LPWSTR  COMCTL32_wSubclass = NULL;
+HMODULE COMCTL32_hModule = 0;
+LANGID  COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
+HBRUSH  COMCTL32_hPattern55AABrush = NULL;
+COMCTL32_SysColor  comctl32_color;
+
+static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
+
+static const WORD wPattern55AA[] =
+{
+    0x5555, 0xaaaa, 0x5555, 0xaaaa,
+    0x5555, 0xaaaa, 0x5555, 0xaaaa
+};
+
+static const WCHAR strCC32SubclassInfo[] = {
+    'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
+};
+
+/***********************************************************************
+ * DllMain [Internal]
+ *
+ * Initializes the internal 'COMCTL32.DLL'.
+ *
+ * PARAMS
+ *     hinstDLL    [I] handle to the 'dlls' instance
+ *     fdwReason   [I]
+ *     lpvReserved [I] reserverd, must be NULL
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
+
+    switch (fdwReason) {
+       case DLL_PROCESS_ATTACH:
+            DisableThreadLibraryCalls(hinstDLL);
+
+            COMCTL32_hModule = (HMODULE)hinstDLL;
+
+            /* add global subclassing atom (used by 'tooltip' and 'updown') */
+            COMCTL32_wSubclass = (LPWSTR)(DWORD)GlobalAddAtomW (strCC32SubclassInfo);
+            TRACE("Subclassing atom added: %p\n", COMCTL32_wSubclass);
+
+            /* create local pattern brush */
+            COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
+            COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
+
+           /* Get all the colors at DLL load */
+           COMCTL32_RefreshSysColors();
+
+            /* register all Win95 common control classes */
+            ANIMATE_Register ();
+            FLATSB_Register ();
+            HEADER_Register ();
+            HOTKEY_Register ();
+            LISTVIEW_Register ();
+            PROGRESS_Register ();
+            STATUS_Register ();
+            SYSLINK_Register ();
+            TAB_Register ();
+            TOOLBAR_Register ();
+            TOOLTIPS_Register ();
+            TRACKBAR_Register ();
+            TREEVIEW_Register ();
+            UPDOWN_Register ();
+            break;
+
+       case DLL_PROCESS_DETACH:
+            /* unregister all common control classes */
+            ANIMATE_Unregister ();
+            COMBOEX_Unregister ();
+            DATETIME_Unregister ();
+            FLATSB_Unregister ();
+            HEADER_Unregister ();
+            HOTKEY_Unregister ();
+            IPADDRESS_Unregister ();
+            LISTVIEW_Unregister ();
+            MONTHCAL_Unregister ();
+            NATIVEFONT_Unregister ();
+            PAGER_Unregister ();
+            PROGRESS_Unregister ();
+            REBAR_Unregister ();
+            STATUS_Unregister ();
+            SYSLINK_Unregister ();
+            TAB_Unregister ();
+            TOOLBAR_Unregister ();
+            TOOLTIPS_Unregister ();
+            TRACKBAR_Unregister ();
+            TREEVIEW_Unregister ();
+            UPDOWN_Unregister ();
+
+            /* delete local pattern brush */
+            DeleteObject (COMCTL32_hPattern55AABrush);
+            COMCTL32_hPattern55AABrush = NULL;
+            DeleteObject (COMCTL32_hPattern55AABitmap);
+            COMCTL32_hPattern55AABitmap = NULL;
+
+            /* delete global subclassing atom */
+            GlobalDeleteAtom (LOWORD(COMCTL32_wSubclass));
+            TRACE("Subclassing atom deleted: %p\n", COMCTL32_wSubclass);
+            COMCTL32_wSubclass = NULL;
+            break;
+    }
+
+    return TRUE;
+}
+
+
+/***********************************************************************
+ * MenuHelp [COMCTL32.2]
+ *
+ * Handles the setting of status bar help messages when the user
+ * selects menu items.
+ *
+ * PARAMS
+ *     uMsg       [I] message (WM_MENUSELECT) (see NOTES)
+ *     wParam     [I] wParam of the message uMsg
+ *     lParam     [I] lParam of the message uMsg
+ *     hMainMenu  [I] handle to the application's main menu
+ *     hInst      [I] handle to the module that contains string resources
+ *     hwndStatus [I] handle to the status bar window
+ *     lpwIDs     [I] pointer to an array of integers (see NOTES)
+ *
+ * RETURNS
+ *     No return value
+ *
+ * NOTES
+ *     The official documentation is incomplete!
+ *     This is the correct documentation:
+ *
+ *     uMsg:
+ *     MenuHelp() does NOT handle WM_COMMAND messages! It only handles
+ *     WM_MENUSELECT messages.
+ *
+ *     lpwIDs:
+ *     (will be written ...)
+ */
+
+VOID WINAPI
+MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
+         HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
+{
+    UINT uMenuID = 0;
+
+    if (!IsWindow (hwndStatus))
+       return;
+
+    switch (uMsg) {
+       case WM_MENUSELECT:
+           TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
+                  wParam, lParam);
+
+            if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
+                /* menu was closed */
+               TRACE("menu was closed!\n");
+                SendMessageW (hwndStatus, SB_SIMPLE, FALSE, 0);
+            }
+           else {
+               /* menu item was selected */
+               if (HIWORD(wParam) & MF_POPUP)
+                   uMenuID = (UINT)*(lpwIDs+1);
+               else
+                   uMenuID = (UINT)LOWORD(wParam);
+               TRACE("uMenuID = %u\n", uMenuID);
+
+               if (uMenuID) {
+                   WCHAR szText[256];
+
+                   if (!LoadStringW (hInst, uMenuID, szText, sizeof(szText)/sizeof(szText[0])))
+                       szText[0] = '\0';
+
+                   SendMessageW (hwndStatus, SB_SETTEXTW,
+                                   255 | SBT_NOBORDERS, (LPARAM)szText);
+                   SendMessageW (hwndStatus, SB_SIMPLE, TRUE, 0);
+               }
+           }
+           break;
+
+        case WM_COMMAND :
+           TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
+                  wParam, lParam);
+           /* WM_COMMAND is not invalid since it is documented
+            * in the windows api reference. So don't output
+             * any FIXME for WM_COMMAND
+             */
+           WARN("We don't care about the WM_COMMAND\n");
+           break;
+
+       default:
+           FIXME("Invalid Message 0x%x!\n", uMsg);
+           break;
+    }
+}
+
+
+/***********************************************************************
+ * ShowHideMenuCtl [COMCTL32.3]
+ *
+ * Shows or hides controls and updates the corresponding menu item.
+ *
+ * PARAMS
+ *     hwnd   [I] handle to the client window.
+ *     uFlags [I] menu command id.
+ *     lpInfo [I] pointer to an array of integers. (See NOTES.)
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * NOTES
+ *     The official documentation is incomplete!
+ *     This is the correct documentation:
+ *
+ *     hwnd
+ *     Handle to the window that contains the menu and controls.
+ *
+ *     uFlags
+ *     Identifier of the menu item to receive or lose a check mark.
+ *
+ *     lpInfo
+ *     The array of integers contains pairs of values. BOTH values of
+ *     the first pair must be the handles to the application's main menu.
+ *     Each subsequent pair consists of a menu id and control id.
+ */
+
+BOOL WINAPI
+ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
+{
+    LPINT lpMenuId;
+
+    TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo);
+
+    if (lpInfo == NULL)
+       return FALSE;
+
+    if (!(lpInfo[0]) || !(lpInfo[1]))
+       return FALSE;
+
+    /* search for control */
+    lpMenuId = &lpInfo[2];
+    while (*lpMenuId != uFlags)
+       lpMenuId += 2;
+
+    if (GetMenuState ((HMENU)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
+       /* uncheck menu item */
+       CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
+
+       /* hide control */
+       lpMenuId++;
+       SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
+                       SWP_HIDEWINDOW);
+    }
+    else {
+       /* check menu item */
+       CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
+
+       /* show control */
+       lpMenuId++;
+       SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
+                       SWP_SHOWWINDOW);
+    }
+
+    return TRUE;
+}
+
+
+/***********************************************************************
+ * GetEffectiveClientRect [COMCTL32.4]
+ *
+ * Calculates the coordinates of a rectangle in the client area.
+ *
+ * PARAMS
+ *     hwnd   [I] handle to the client window.
+ *     lpRect [O] pointer to the rectangle of the client window
+ *     lpInfo [I] pointer to an array of integers (see NOTES)
+ *
+ * RETURNS
+ *     No return value.
+ *
+ * NOTES
+ *     The official documentation is incomplete!
+ *     This is the correct documentation:
+ *
+ *     lpInfo
+ *     (will be written ...)
+ */
+
+VOID WINAPI
+GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
+{
+    RECT rcCtrl;
+    INT  *lpRun;
+    HWND hwndCtrl;
+
+    TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
+          (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
+
+    GetClientRect (hwnd, lpRect);
+    lpRun = lpInfo;
+
+    do {
+       lpRun += 2;
+       if (*lpRun == 0)
+           return;
+       lpRun++;
+       hwndCtrl = GetDlgItem (hwnd, *lpRun);
+       if (GetWindowLongW (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
+           TRACE("control id 0x%x\n", *lpRun);
+           GetWindowRect (hwndCtrl, &rcCtrl);
+           MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
+           SubtractRect (lpRect, lpRect, &rcCtrl);
+       }
+       lpRun++;
+    } while (*lpRun);
+}
+
+
+/***********************************************************************
+ * DrawStatusTextW [COMCTL32.@]
+ *
+ * Draws text with borders, like in a status bar.
+ *
+ * PARAMS
+ *     hdc   [I] handle to the window's display context
+ *     lprc  [I] pointer to a rectangle
+ *     text  [I] pointer to the text
+ *     style [I] drawing style
+ *
+ * RETURNS
+ *     No return value.
+ *
+ * NOTES
+ *     The style variable can have one of the following values:
+ *     (will be written ...)
+ */
+
+void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
+{
+    RECT r = *lprc;
+    UINT border = BDR_SUNKENOUTER;
+
+    if (style & SBT_POPOUT)
+        border = BDR_RAISEDOUTER;
+    else if (style & SBT_NOBORDERS)
+        border = 0;
+
+    DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
+
+    /* now draw text */
+    if (text) {
+        int oldbkmode = SetBkMode (hdc, TRANSPARENT);
+        UINT align = DT_LEFT;
+        if (*text == L'\t') {
+           text++;
+           align = DT_CENTER;
+           if (*text == L'\t') {
+               text++;
+               align = DT_RIGHT;
+           }
+        }
+        r.left += 3;
+        if (style & SBT_RTLREADING)
+           FIXME("Unsupported RTL style!\n");
+        DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
+       SetBkMode(hdc, oldbkmode);
+    }
+}
+
+
+/***********************************************************************
+ * DrawStatusText  [COMCTL32.@]
+ * DrawStatusTextA [COMCTL32.5]
+ *
+ * Draws text with borders, like in a status bar.
+ *
+ * PARAMS
+ *     hdc   [I] handle to the window's display context
+ *     lprc  [I] pointer to a rectangle
+ *     text  [I] pointer to the text
+ *     style [I] drawing style
+ *
+ * RETURNS
+ *     No return value.
+ */
+
+void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
+{
+    INT len;
+    LPWSTR textW = NULL;
+
+    if ( text ) {
+       if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
+           if ( (textW = Alloc( len * sizeof(WCHAR) )) )
+               MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
+       }
+    }
+    DrawStatusTextW( hdc, lprc, textW, style );
+    Free( textW );
+}
+
+
+/***********************************************************************
+ * CreateStatusWindow  [COMCTL32.@]
+ * CreateStatusWindowA [COMCTL32.6]
+ *
+ * Creates a status bar
+ *
+ * PARAMS
+ *     style  [I] window style
+ *     text   [I] pointer to the window text
+ *     parent [I] handle to the parent window
+ *     wid    [I] control id of the status bar
+ *
+ * RETURNS
+ *     Success: handle to the status window
+ *     Failure: 0
+ */
+
+HWND WINAPI
+CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
+{
+    return CreateWindowA(STATUSCLASSNAMEA, text, style,
+                          CW_USEDEFAULT, CW_USEDEFAULT,
+                          CW_USEDEFAULT, CW_USEDEFAULT,
+                          parent, (HMENU)wid, 0, 0);
+}
+
+
+/***********************************************************************
+ * CreateStatusWindowW [COMCTL32.@]
+ *
+ * Creates a status bar control
+ *
+ * PARAMS
+ *     style  [I] window style
+ *     text   [I] pointer to the window text
+ *     parent [I] handle to the parent window
+ *     wid    [I] control id of the status bar
+ *
+ * RETURNS
+ *     Success: handle to the status window
+ *     Failure: 0
+ */
+
+HWND WINAPI
+CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
+{
+    return CreateWindowW(STATUSCLASSNAMEW, text, style,
+                          CW_USEDEFAULT, CW_USEDEFAULT,
+                          CW_USEDEFAULT, CW_USEDEFAULT,
+                          parent, (HMENU)wid, 0, 0);
+}
+
+
+/***********************************************************************
+ * CreateUpDownControl [COMCTL32.16]
+ *
+ * Creates an up-down control
+ *
+ * PARAMS
+ *     style  [I] window styles
+ *     x      [I] horizontal position of the control
+ *     y      [I] vertical position of the control
+ *     cx     [I] with of the control
+ *     cy     [I] height of the control
+ *     parent [I] handle to the parent window
+ *     id     [I] the control's identifier
+ *     inst   [I] handle to the application's module instance
+ *     buddy  [I] handle to the buddy window, can be NULL
+ *     maxVal [I] upper limit of the control
+ *     minVal [I] lower limit of the control
+ *     curVal [I] current value of the control
+ *
+ * RETURNS
+ *     Success: handle to the updown control
+ *     Failure: 0
+ */
+
+HWND WINAPI
+CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
+                    HWND parent, INT id, HINSTANCE inst,
+                    HWND buddy, INT maxVal, INT minVal, INT curVal)
+{
+    HWND hUD =
+       CreateWindowW (UPDOWN_CLASSW, 0, style, x, y, cx, cy,
+                        parent, (HMENU)id, inst, 0);
+    if (hUD) {
+       SendMessageW (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
+       SendMessageW (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
+       SendMessageW (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
+    }
+
+    return hUD;
+}
+
+
+/***********************************************************************
+ * InitCommonControls [COMCTL32.17]
+ *
+ * Registers the common controls.
+ *
+ * PARAMS
+ *     No parameters.
+ *
+ * RETURNS
+ *     No return values.
+ *
+ * NOTES
+ *     This function is just a dummy.
+ *     The Win95 controls are registered at the DLL's initialization.
+ *     To register other controls InitCommonControlsEx() must be used.
+ */
+
+VOID WINAPI
+InitCommonControls (void)
+{
+}
+
+
+/***********************************************************************
+ * InitCommonControlsEx [COMCTL32.@]
+ *
+ * Registers the common controls.
+ *
+ * PARAMS
+ *     lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * NOTES
+ *     Only the additional common controls are registered by this function.
+ *     The Win95 controls are registered at the DLL's initialization.
+ *
+ * FIXME
+ *     implement the following control classes:
+ *       ICC_LINK_CLASS
+ *       ICC_STANDARD_CLASSES
+ */
+
+BOOL WINAPI
+InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
+{
+    INT cCount;
+    DWORD dwMask;
+
+    if (!lpInitCtrls)
+       return FALSE;
+    if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
+       return FALSE;
+
+    TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
+
+    for (cCount = 0; cCount < 32; cCount++) {
+       dwMask = 1 << cCount;
+       if (!(lpInitCtrls->dwICC & dwMask))
+           continue;
+
+       switch (lpInitCtrls->dwICC & dwMask) {
+           /* dummy initialization */
+           case ICC_ANIMATE_CLASS:
+           case ICC_BAR_CLASSES:
+           case ICC_LISTVIEW_CLASSES:
+           case ICC_TREEVIEW_CLASSES:
+           case ICC_TAB_CLASSES:
+           case ICC_UPDOWN_CLASS:
+           case ICC_PROGRESS_CLASS:
+           case ICC_HOTKEY_CLASS:
+               break;
+
+           /* advanced classes - not included in Win95 */
+           case ICC_DATE_CLASSES:
+               MONTHCAL_Register ();
+               DATETIME_Register ();
+               break;
+
+           case ICC_USEREX_CLASSES:
+               COMBOEX_Register ();
+               break;
+
+           case ICC_COOL_CLASSES:
+               REBAR_Register ();
+               break;
+
+           case ICC_INTERNET_CLASSES:
+               IPADDRESS_Register ();
+               break;
+
+           case ICC_PAGESCROLLER_CLASS:
+               PAGER_Register ();
+               break;
+
+           case ICC_NATIVEFNTCTL_CLASS:
+               NATIVEFONT_Register ();
+               break;
+
+           case ICC_LINK_CLASS:
+               SYSLINK_Register ();
+               break;
+
+           default:
+               FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
+               break;
+       }
+    }
+
+    return TRUE;
+}
+
+
+/***********************************************************************
+ * CreateToolbarEx [COMCTL32.@]
+ *
+ * Creates a toolbar window.
+ *
+ * PARAMS
+ *     hwnd
+ *     style
+ *     wID
+ *     nBitmaps
+ *     hBMInst
+ *     wBMID
+ *     lpButtons
+ *     iNumButtons
+ *     dxButton
+ *     dyButton
+ *     dxBitmap
+ *     dyBitmap
+ *     uStructSize
+ *
+ * RETURNS
+ *     Success: handle to the tool bar control
+ *     Failure: 0
+ */
+
+HWND WINAPI
+CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
+                 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
+                 INT iNumButtons, INT dxButton, INT dyButton,
+                 INT dxBitmap, INT dyBitmap, UINT uStructSize)
+{
+    HWND hwndTB;
+
+    hwndTB =
+        CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style|WS_CHILD, 0,0,100,30,
+                        hwnd, (HMENU)wID, COMCTL32_hModule, NULL);
+    if(hwndTB) {
+       TBADDBITMAP tbab;
+
+        SendMessageW (hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM)uStructSize, 0);
+
+       /* set bitmap and button size */
+       /*If CreateToolbarEx receives 0, windows sets default values*/
+       if (dxBitmap <= 0)
+           dxBitmap = 16;
+       if (dyBitmap <= 0)
+           dyBitmap = 15;
+       SendMessageW (hwndTB, TB_SETBITMAPSIZE, 0,
+                     MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
+
+       if (dxButton <= 0)
+           dxButton = 24;
+       if (dyButton <= 0)
+           dyButton = 22;
+       SendMessageW (hwndTB, TB_SETBUTTONSIZE, 0,
+                     MAKELPARAM((WORD)dxButton, (WORD)dyButton));
+
+
+       /* add bitmaps */
+       if (nBitmaps > 0)
+       {
+           tbab.hInst = hBMInst;
+           tbab.nID   = wBMID;
+
+           SendMessageW (hwndTB, TB_ADDBITMAP, (WPARAM)nBitmaps, (LPARAM)&tbab);
+       }
+       /* add buttons */
+       if(iNumButtons > 0)
+       SendMessageW (hwndTB, TB_ADDBUTTONSW,
+                       (WPARAM)iNumButtons, (LPARAM)lpButtons);
+    }
+
+    return hwndTB;
+}
+
+
+/***********************************************************************
+ * CreateMappedBitmap [COMCTL32.8]
+ *
+ * Loads a bitmap resource using a colour map.
+ *
+ * PARAMS
+ *     hInstance  [I] Handle to the module containing the bitmap.
+ *     idBitmap   [I] The bitmap resource ID.
+ *     wFlags     [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
+ *     lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
+ *     iNumMaps   [I] Number of COLORMAP's pointed to by lpColorMap.
+ *
+ * RETURNS
+ *     Success: handle to the new bitmap
+ *     Failure: 0
+ */
+
+HBITMAP WINAPI
+CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
+                   LPCOLORMAP lpColorMap, INT iNumMaps)
+{
+    HGLOBAL hglb;
+    HRSRC hRsrc;
+    LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
+    UINT nSize, nColorTableSize, iColor;
+    RGBQUAD *pColorTable;
+    INT i, iMaps, nWidth, nHeight;
+    HDC hdcScreen;
+    HBITMAP hbm;
+    LPCOLORMAP sysColorMap;
+    COLORREF cRef;
+    COLORMAP internalColorMap[4] =
+       {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
+
+    /* initialize pointer to colortable and default color table */
+    if (lpColorMap) {
+       iMaps = iNumMaps;
+       sysColorMap = lpColorMap;
+    }
+    else {
+       internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
+       internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
+       internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
+       internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
+       iMaps = 4;
+       sysColorMap = (LPCOLORMAP)internalColorMap;
+    }
+
+    hRsrc = FindResourceW (hInstance, (LPWSTR)idBitmap, (LPWSTR)RT_BITMAP);
+    if (hRsrc == 0)
+       return 0;
+    hglb = LoadResource (hInstance, hRsrc);
+    if (hglb == 0)
+       return 0;
+    lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
+    if (lpBitmap == NULL)
+       return 0;
+
+    if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
+        nColorTableSize = lpBitmap->biClrUsed;
+    else if (lpBitmap->biBitCount <= 8)        
+        nColorTableSize = (1 << lpBitmap->biBitCount);
+    else
+        nColorTableSize = 0;
+    nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
+    lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
+    if (lpBitmapInfo == NULL)
+       return 0;
+    RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
+
+    pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
+
+    for (iColor = 0; iColor < nColorTableSize; iColor++) {
+       for (i = 0; i < iMaps; i++) {
+            cRef = RGB(pColorTable[iColor].rgbRed,
+                       pColorTable[iColor].rgbGreen,
+                       pColorTable[iColor].rgbBlue);
+           if ( cRef  == sysColorMap[i].from) {
+#if 0
+               if (wFlags & CBS_MASKED) {
+                   if (sysColorMap[i].to != COLOR_BTNTEXT)
+                       pColorTable[iColor] = RGB(255, 255, 255);
+               }
+               else
+#endif
+                    pColorTable[iColor].rgbBlue  = GetBValue(sysColorMap[i].to);
+                    pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
+                    pColorTable[iColor].rgbRed   = GetRValue(sysColorMap[i].to);
+               break;
+           }
+       }
+    }
+    nWidth  = (INT)lpBitmapInfo->biWidth;
+    nHeight = (INT)lpBitmapInfo->biHeight;
+    hdcScreen = GetDC (NULL);
+    hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
+    if (hbm) {
+       HDC hdcDst = CreateCompatibleDC (hdcScreen);
+       HBITMAP hbmOld = SelectObject (hdcDst, hbm);
+       LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
+       lpBits += nColorTableSize * sizeof(RGBQUAD);
+       StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
+                        lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
+                        SRCCOPY);
+       SelectObject (hdcDst, hbmOld);
+       DeleteDC (hdcDst);
+    }
+    ReleaseDC (NULL, hdcScreen);
+    GlobalFree ((HGLOBAL)lpBitmapInfo);
+    FreeResource (hglb);
+
+    return hbm;
+}
+
+
+/***********************************************************************
+ * CreateToolbar [COMCTL32.7]
+ *
+ * Creates a toolbar control.
+ *
+ * PARAMS
+ *     hwnd
+ *     style
+ *     wID
+ *     nBitmaps
+ *     hBMInst
+ *     wBMID
+ *     lpButtons
+ *     iNumButtons
+ *
+ * RETURNS
+ *     Success: handle to the tool bar control
+ *     Failure: 0
+ *
+ * NOTES
+ *     Do not use this functions anymore. Use CreateToolbarEx instead.
+ */
+
+HWND WINAPI
+CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
+              HINSTANCE hBMInst, UINT wBMID,
+              LPCTBBUTTON lpButtons,INT iNumButtons)
+{
+    return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
+                           hBMInst, wBMID, lpButtons,
+                           iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
+}
+
+
+/***********************************************************************
+ * DllGetVersion [COMCTL32.@]
+ *
+ * Retrieves version information of the 'COMCTL32.DLL'
+ *
+ * PARAMS
+ *     pdvi [O] pointer to version information structure.
+ *
+ * RETURNS
+ *     Success: S_OK
+ *     Failure: E_INVALIDARG
+ *
+ * NOTES
+ *     Returns version of a comctl32.dll from IE4.01 SP1.
+ */
+
+HRESULT WINAPI
+COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
+{
+    if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
+        WARN("wrong DLLVERSIONINFO size from app\n");
+       return E_INVALIDARG;
+    }
+
+    pdvi->dwMajorVersion = COMCTL32_VERSION;
+    pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
+    pdvi->dwBuildNumber = 2919;
+    pdvi->dwPlatformID = 6304;
+
+    TRACE("%lu.%lu.%lu.%lu\n",
+          pdvi->dwMajorVersion, pdvi->dwMinorVersion,
+          pdvi->dwBuildNumber, pdvi->dwPlatformID);
+
+    return S_OK;
+}
+
+/***********************************************************************
+ *             DllInstall (COMCTL32.@)
+ *
+ * Installs the ComCtl32 DLL.
+ *
+ * RETURNS
+ *     Success: S_OK
+ *     Failure: A HRESULT error
+ */
+HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
+{
+  FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
+       debugstr_w(cmdline));
+
+  return S_OK;
+}
+
+/***********************************************************************
+ * _TrackMouseEvent [COMCTL32.@]
+ *
+ * Requests notification of mouse events
+ *
+ * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
+ * to the hwnd specified in the ptme structure.  After the event message
+ * is posted to the hwnd, the entry in the queue is removed.
+ *
+ * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
+ * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
+ * immediately and the TME_LEAVE flag being ignored.
+ *
+ * PARAMS
+ *     ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
+ *
+ * RETURNS
+ *     Success: non-zero
+ *     Failure: zero
+ *
+ * IMPLEMENTATION moved to USER32.TrackMouseEvent
+ *
+ */
+
+BOOL WINAPI
+_TrackMouseEvent (TRACKMOUSEEVENT *ptme)
+{
+    return TrackMouseEvent (ptme);
+}
+
+/*************************************************************************
+ * GetMUILanguage [COMCTL32.@]
+ *
+ * Returns the user interface language in use by the current process.
+ *
+ * RETURNS
+ *      Language ID in use by the current process.
+ */
+LANGID WINAPI GetMUILanguage (VOID)
+{
+    return COMCTL32_uiLang;
+}
+
+
+/*************************************************************************
+ * InitMUILanguage [COMCTL32.@]
+ *
+ * Sets the user interface language to be used by the current process.
+ *
+ * RETURNS
+ *      Nothing.
+ */
+VOID WINAPI InitMUILanguage (LANGID uiLang)
+{
+   COMCTL32_uiLang = uiLang;
+}
+
+
+/***********************************************************************
+ * SetWindowSubclass [COMCTL32.410]
+ *
+ * Starts a window subclass
+ *
+ * PARAMS
+ *     hWnd [in] handle to window subclass.
+ *     pfnSubclass [in] Pointer to new window procedure.
+ *     uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
+ *     dwRef [in] Reference data to pass to window procedure.
+ *
+ * RETURNS
+ *     Success: non-zero
+ *     Failure: zero
+ *
+ * BUGS
+ *     If an application manually subclasses a window after subclassing it with
+ *     this API and then with this API again, then none of the previous 
+ *     subclasses get called or the origional window procedure.
+ */
+
+BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
+                        UINT_PTR uIDSubclass, DWORD_PTR dwRef)
+{
+   LPSUBCLASS_INFO stack;
+   LPSUBCLASSPROCS proc;
+
+   TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
+
+   /* Since the window procedure that we set here has two additional arguments,
+    * we can't simply set it as the new window procedure of the window. So we
+    * set our own window procedure and then calculate the other two arguments
+    * from there. */
+
+   /* See if we have been called for this window */
+   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
+   if (!stack) {
+      /* allocate stack */
+      stack = Alloc (sizeof(SUBCLASS_INFO));
+      if (!stack) {
+         ERR ("Failed to allocate our Subclassing stack\n");
+         return FALSE;
+      }
+      SetPropW (hWnd, COMCTL32_wSubclass, (HANDLE)stack);
+
+      /* set window procedure to our own and save the current one */
+      if (IsWindowUnicode (hWnd))
+         stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC,
+                                                   (DWORD_PTR)COMCTL32_SubclassProc);
+      else
+         stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC,
+                                                   (DWORD_PTR)COMCTL32_SubclassProc);
+   }
+   else {
+      /* Check to see if we have called this function with the same uIDSubClass
+       * and pfnSubclass */
+      proc = stack->SubclassProcs;
+      while (proc) {
+         if ((proc->id == uIDSubclass) &&
+            (proc->subproc == pfnSubclass)) {
+            proc->ref = dwRef;
+            return TRUE;
+         }
+         proc = proc->next;
+      }
+   }
+   
+   proc = Alloc(sizeof(SUBCLASSPROCS));
+   if (!proc) {
+      ERR ("Failed to allocate subclass entry in stack\n");
+      if (IsWindowUnicode (hWnd))
+         SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
+      else
+         SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
+      Free (stack);
+      RemovePropW( hWnd, COMCTL32_wSubclass );
+      return FALSE;
+   }
+   
+   proc->subproc = pfnSubclass;
+   proc->ref = dwRef;
+   proc->id = uIDSubclass;
+   proc->next = stack->SubclassProcs;
+   stack->SubclassProcs = proc;
+
+   return TRUE;
+}
+
+
+/***********************************************************************
+ * GetWindowSubclass [COMCTL32.411]
+ *
+ * Gets the Reference data from a subclass.
+ *
+ * PARAMS
+ *     hWnd [in] Handle to window which were subclassing
+ *     pfnSubclass [in] Pointer to the subclass procedure
+ *     uID [in] Unique indentifier of the subclassing procedure
+ *     pdwRef [out] Pointer to the reference data
+ *
+ * RETURNS
+ *     Success: Non-zero
+ *     Failure: 0
+ */
+
+BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
+                              UINT_PTR uID, DWORD_PTR *pdwRef)
+{
+   LPSUBCLASS_INFO stack;
+   LPSUBCLASSPROCS proc;
+
+   TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
+
+   /* See if we have been called for this window */
+   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
+   if (!stack)
+      return FALSE;
+
+   proc = stack->SubclassProcs;
+   while (proc) {
+      if ((proc->id == uID) &&
+         (proc->subproc == pfnSubclass)) {
+         *pdwRef = proc->ref;
+         return TRUE;
+      }
+      proc = proc->next;
+   }
+
+   return FALSE;
+}
+
+
+/***********************************************************************
+ * RemoveWindowSubclass [COMCTL32.412]
+ *
+ * Removes a window subclass.
+ *
+ * PARAMS
+ *     hWnd [in] Handle to the window were subclassing
+ *     pfnSubclass [in] Pointer to the subclass procedure
+ *     uID [in] Unique identifier of this subclass
+ *
+ * RETURNS
+ *     Success: non-zero
+ *     Failure: zero
+ */
+
+BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
+{
+   LPSUBCLASS_INFO stack;
+   LPSUBCLASSPROCS prevproc = NULL;
+   LPSUBCLASSPROCS proc;
+   BOOL ret = FALSE;
+
+   TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID);
+
+   /* Find the Subclass to remove */
+   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
+   if (!stack)
+      return FALSE;
+
+   proc = stack->SubclassProcs;
+   while (proc) {
+      if ((proc->id == uID) &&
+         (proc->subproc == pfnSubclass)) {
+         
+         if (!prevproc)
+            stack->SubclassProcs = proc->next;
+         else
+            prevproc->next = proc->next;
+          
+         if (stack->stackpos == proc)
+            stack->stackpos = stack->stackpos->next;
+            
+         Free (proc);
+         ret = TRUE;
+         break;
+      }
+      prevproc = proc;
+      proc = proc->next;
+   }
+   
+   if (!stack->SubclassProcs && !stack->running) {
+      TRACE("Last Subclass removed, cleaning up\n");
+      /* clean up our heap and reset the origional window procedure */
+      if (IsWindowUnicode (hWnd))
+         SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
+      else
+         SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
+      Free (stack);
+      RemovePropW( hWnd, COMCTL32_wSubclass );
+   }
+   
+   return ret;
+}
+
+/***********************************************************************
+ * COMCTL32_SubclassProc (internal)
+ *
+ * Window procedure for all subclassed windows. 
+ * Saves the current subclassing stack position to support nested messages
+ */
+LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+   LPSUBCLASS_INFO stack;
+   LPSUBCLASSPROCS proc;
+   LRESULT ret;
+    
+   TRACE ("(%p, 0x%08x, 0x%08x, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
+
+   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
+   if (!stack) {
+      ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
+      return 0;
+   }
+    
+   /* Save our old stackpos to properly handle nested messages */
+   proc = stack->stackpos;
+   stack->stackpos = stack->SubclassProcs;
+   stack->running++;
+   ret = DefSubclassProc(hWnd, uMsg, wParam, lParam);
+   stack->running--;
+   stack->stackpos = proc;
+    
+   if (!stack->SubclassProcs && !stack->running) {
+      TRACE("Last Subclass removed, cleaning up\n");
+      /* clean up our heap and reset the origional window procedure */
+      if (IsWindowUnicode (hWnd))
+         SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
+      else
+         SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
+      Free (stack);
+      RemovePropW( hWnd, COMCTL32_wSubclass );
+   }
+   return ret;
+}
+
+/***********************************************************************
+ * DefSubclassProc [COMCTL32.413]
+ *
+ * Calls the next window procedure (ie. the one before this subclass)
+ *
+ * PARAMS
+ *     hWnd [in] The window that we're subclassing
+ *     uMsg [in] Message
+ *     wParam [in] WPARAM
+ *     lParam [in] LPARAM
+ *
+ * RETURNS
+ *     Success: non-zero
+ *     Failure: zero
+ */
+
+LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+   LPSUBCLASS_INFO stack;
+   LRESULT ret;
+   
+   TRACE ("(%p, 0x%08x, 0x%08x, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
+
+   /* retrieve our little stack from the Properties */
+   stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
+   if (!stack) {
+      ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
+      return 0;
+   }
+
+   /* If we are at the end of stack then we have to call the original
+    * window procedure */
+   if (!stack->stackpos) {
+      if (IsWindowUnicode (hWnd))
+         ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
+      else
+         ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
+   } else {
+      LPSUBCLASSPROCS proc = stack->stackpos;
+      stack->stackpos = stack->stackpos->next; 
+      /* call the Subclass procedure from the stack */
+      ret = proc->subproc (hWnd, uMsg, wParam, lParam,
+            proc->id, proc->ref);
+   }
+
+   return ret;
+}
+
+
+/***********************************************************************
+ * COMCTL32_CreateToolTip [NOT AN API]
+ *
+ * Creates a tooltip for the control specified in hwnd and does all
+ * necessary setup and notifications.
+ *
+ * PARAMS
+ *     hwndOwner [I] Handle to the window that will own the tool tip.
+ *
+ * RETURNS
+ *     Success: Handle of tool tip window.
+ *     Failure: NULL
+ */
+
+HWND
+COMCTL32_CreateToolTip(HWND hwndOwner)
+{
+    HWND hwndToolTip;
+
+    hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0,
+                                 CW_USEDEFAULT, CW_USEDEFAULT,
+                                 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
+                                 0, 0, 0);
+
+    /* Send NM_TOOLTIPSCREATED notification */
+    if (hwndToolTip)
+    {
+       NMTOOLTIPSCREATED nmttc;
+        /* true owner can be different if hwndOwner is a child window */
+        HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
+        nmttc.hdr.hwndFrom = hwndTrueOwner;
+        nmttc.hdr.idFrom = GetWindowLongPtrW(hwndTrueOwner, GWLP_ID);
+       nmttc.hdr.code = NM_TOOLTIPSCREATED;
+       nmttc.hwndToolTips = hwndToolTip;
+
+       SendMessageW(GetParent(hwndTrueOwner), WM_NOTIFY,
+                    (WPARAM)GetWindowLongPtrW(hwndTrueOwner, GWLP_ID),
+                   (LPARAM)&nmttc);
+    }
+
+    return hwndToolTip;
+}
+
+
+/***********************************************************************
+ * COMCTL32_RefreshSysColors [NOT AN API]
+ *
+ * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
+ * refresh the color values in the color structure
+ *
+ * PARAMS
+ *     none
+ *
+ * RETURNS
+ *     none
+ */
+
+VOID
+COMCTL32_RefreshSysColors(void)
+{
+    comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
+    comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
+    comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
+    comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
+    comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
+    comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
+    comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
+    comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
+    comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
+    comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
+    comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
+    comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
+    comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
+    comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
+    comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
+    comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);
+}
+
+/***********************************************************************
+ * COMCTL32_DrawInsertMark [NOT AN API]
+ *
+ * Draws an insertion mark (which looks similar to an 'I').
+ *
+ * PARAMS
+ *     hDC           [I] Device context to draw onto.
+ *     lpRect        [I] Co-ordinates of insertion mark.
+ *     clrInsertMark [I] Colour of the insertion mark.
+ *     bHorizontal   [I] True if insert mark should be drawn horizontally,
+ *                       vertical otherwise.
+ *
+ * RETURNS
+ *     none
+ *
+ * NOTES
+ *     Draws up to but not including the bottom co-ordinate when drawing
+ *     vertically or the right co-ordinate when horizontal.
+ */
+void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal)
+{
+    HPEN hPen = CreatePen(PS_SOLID, 1, clrInsertMark);
+    HPEN hOldPen;
+    static const DWORD adwPolyPoints[] = {4,4,4};
+    LONG lCentre = (bHorizontal ? 
+        lpRect->top + (lpRect->bottom - lpRect->top)/2 : 
+        lpRect->left + (lpRect->right - lpRect->left)/2);
+    LONG l1 = (bHorizontal ? lpRect->left : lpRect->top);
+    LONG l2 = (bHorizontal ? lpRect->right : lpRect->bottom);
+    const POINT aptInsertMark[] =
+    {
+        /* top (V) or left (H) arrow */
+        {lCentre    , l1 + 2},
+        {lCentre - 2, l1    },
+        {lCentre + 3, l1    },
+        {lCentre + 1, l1 + 2},
+        /* middle line */
+        {lCentre    , l2 - 2},
+        {lCentre    , l1 - 1},
+        {lCentre + 1, l1 - 1},
+        {lCentre + 1, l2 - 2},
+        /* bottom (V) or right (H) arrow */
+        {lCentre    , l2 - 3},
+        {lCentre - 2, l2 - 1},
+        {lCentre + 3, l2 - 1},
+        {lCentre + 1, l2 - 3},
+    };
+    hOldPen = SelectObject(hDC, hPen);
+    PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));
+    SelectObject(hDC, hOldPen);
+    DeleteObject(hPen);
+}
+
+/***********************************************************************
+ * MirrorIcon [COMCTL32.414]
+ *
+ * Mirrors an icon so that it will appear correctly on a mirrored DC.
+ *
+ * PARAMS
+ *     phicon1 [I/O] Icon.
+ *     phicon2 [I/O] Icon.
+ *
+ * RETURNS
+ *     Success: TRUE.
+ *     Failure: FALSE.
+ */
+BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2)
+{
+    FIXME("(%p, %p): stub\n", phicon1, phicon2);
+    return FALSE;
+}
+
+static inline int IsDelimiter(WCHAR c)
+{
+    switch(c)
+    {
+       case '/':
+       case '\\':
+       case '.':
+       case ' ':
+           return TRUE;
+    }
+    return FALSE;
+}
+
+static int CALLBACK PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code)
+{
+    if (code == WB_ISDELIMITER)
+        return IsDelimiter(lpch[ichCurrent]);
+    else
+    {
+        int dir = (code == WB_LEFT) ? -1 : 1;
+        for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
+            if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;
+    }
+    return ichCurrent;
+}
+
+/***********************************************************************
+ * SetPathWordBreakProc [COMCTL32.384]
+ *
+ * Sets the word break procedure for an edit control to one that understands
+ * paths so that the user can jump over directories.
+ *
+ * PARAMS
+ *     hwnd [I] Handle to edit control.
+ *     bSet [I] If this is TRUE then the word break proc is set, otherwise it is removed.
+ *
+ * RETURNS
+ *     Result from EM_SETWORDBREAKPROC message.
+ */
+LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)
+{
+    return SendMessageW(hwnd, EM_SETWORDBREAKPROC, 0,
+        (LPARAM)(bSet ? PathWordBreakProc : NULL));
+}