Implement A->W call for GetNamedSecurityInfo.
[wine] / dlls / comctl32 / commctrl.c
1 /*
2  * Common controls functions
3  *
4  * Copyright 1997 Dimitrie O. Paun
5  * Copyright 1998,2000 Eric Kohl
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * NOTES
22  * 
23  * This code was audited for completeness against the documented features
24  * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.
25  *
26  * Unless otherwise noted, we believe this code to be complete, as per
27  * the specification mentioned above.
28  * If you discover missing features, or bugs, please note them below.
29  *
30  * TODO
31  *   -- implement GetMUILanguage + InitMUILanguage
32  *   -- LibMain => DLLMain ("DLLMain takes over the functionality of both the
33  *                           LibMain and the WEP function.", MSDN)
34  *   -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
35  *   -- FIXMEs + BUGS (search for them)
36  *
37  * Control Classes
38  *   -- ICC_ANIMATE_CLASS
39  *   -- ICC_BAR_CLASSES
40  *   -- ICC_COOL_CLASSES
41  *   -- ICC_DATE_CLASSES
42  *   -- ICC_HOTKEY_CLASS
43  *   -- ICC_INTERNET_CLASSES
44  *   -- ICC_LINK_CLASS (not yet implemented)
45  *   -- ICC_LISTVIEW_CLASSES
46  *   -- ICC_NATIVEFNTCTL_CLASS
47  *   -- ICC_PAGESCROLLER_CLASS
48  *   -- ICC_PROGRESS_CLASS
49  *   -- ICC_STANDARD_CLASSES (not yet implemented)
50  *   -- ICC_TAB_CLASSES
51  *   -- ICC_TREEVIEW_CLASSES
52  *   -- ICC_UPDOWN_CLASS
53  *   -- ICC_USEREX_CLASSES
54  *   -- ICC_WIN95_CLASSES
55  */
56
57 #include <stdarg.h>
58 #include <string.h>
59 #include <stdlib.h>
60
61 #include "windef.h"
62 #include "winbase.h"
63 #include "wingdi.h"
64 #include "winuser.h"
65 #include "winnls.h"
66 #include "commctrl.h"
67 #include "winerror.h"
68 #include "winreg.h"
69 #define NO_SHLWAPI_STREAM
70 #include "shlwapi.h"
71 #include "comctl32.h"
72 #include "wine/debug.h"
73
74 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
75
76 extern void ANIMATE_Register(void);
77 extern void ANIMATE_Unregister(void);
78 extern void COMBOEX_Register(void);
79 extern void COMBOEX_Unregister(void);
80 extern void DATETIME_Register(void);
81 extern void DATETIME_Unregister(void);
82 extern void FLATSB_Register(void);
83 extern void FLATSB_Unregister(void);
84 extern void HEADER_Register(void);
85 extern void HEADER_Unregister(void);
86 extern void HOTKEY_Register(void);
87 extern void HOTKEY_Unregister(void);
88 extern void IPADDRESS_Register(void);
89 extern void IPADDRESS_Unregister(void);
90 extern void LISTVIEW_Register(void);
91 extern void LISTVIEW_Unregister(void);
92 extern void MONTHCAL_Register(void);
93 extern void MONTHCAL_Unregister(void);
94 extern void NATIVEFONT_Register(void);
95 extern void NATIVEFONT_Unregister(void);
96 extern void PAGER_Register(void);
97 extern void PAGER_Unregister(void);
98 extern void PROGRESS_Register(void);
99 extern void PROGRESS_Unregister(void);
100 extern void REBAR_Register(void);
101 extern void REBAR_Unregister(void);
102 extern void STATUS_Register(void);
103 extern void STATUS_Unregister(void);
104 extern void TAB_Register(void);
105 extern void TAB_Unregister(void);
106 extern void TOOLBAR_Register(void);
107 extern void TOOLBAR_Unregister(void);
108 extern void TOOLTIPS_Register(void);
109 extern void TOOLTIPS_Unregister(void);
110 extern void TRACKBAR_Register(void);
111 extern void TRACKBAR_Unregister(void);
112 extern void TREEVIEW_Register(void);
113 extern void TREEVIEW_Unregister(void);
114 extern void UPDOWN_Register(void);
115 extern void UPDOWN_Unregister(void);
116
117
118 LPSTR    COMCTL32_aSubclass = NULL;
119 HMODULE COMCTL32_hModule = 0;
120 LANGID  COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
121 HBRUSH  COMCTL32_hPattern55AABrush = NULL;
122 COMCTL32_SysColor  comctl32_color;
123
124 static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
125
126 static const WORD wPattern55AA[] =
127 {
128     0x5555, 0xaaaa, 0x5555, 0xaaaa,
129     0x5555, 0xaaaa, 0x5555, 0xaaaa
130 };
131
132
133 /***********************************************************************
134  * DllMain [Internal]
135  *
136  * Initializes the internal 'COMCTL32.DLL'.
137  *
138  * PARAMS
139  *     hinstDLL    [I] handle to the 'dlls' instance
140  *     fdwReason   [I]
141  *     lpvReserved [I] reserverd, must be NULL
142  *
143  * RETURNS
144  *     Success: TRUE
145  *     Failure: FALSE
146  */
147
148 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
149 {
150     TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
151
152     switch (fdwReason) {
153         case DLL_PROCESS_ATTACH:
154             DisableThreadLibraryCalls(hinstDLL);
155
156             COMCTL32_hModule = (HMODULE)hinstDLL;
157
158             /* add global subclassing atom (used by 'tooltip' and 'updown') */
159             COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
160             TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
161
162             /* create local pattern brush */
163             COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
164             COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
165
166             /* Get all the colors at DLL load */
167             COMCTL32_RefreshSysColors();
168
169             /* register all Win95 common control classes */
170             ANIMATE_Register ();
171             FLATSB_Register ();
172             HEADER_Register ();
173             HOTKEY_Register ();
174             LISTVIEW_Register ();
175             PROGRESS_Register ();
176             STATUS_Register ();
177             TAB_Register ();
178             TOOLBAR_Register ();
179             TOOLTIPS_Register ();
180             TRACKBAR_Register ();
181             TREEVIEW_Register ();
182             UPDOWN_Register ();
183             break;
184
185         case DLL_PROCESS_DETACH:
186             /* unregister all common control classes */
187             ANIMATE_Unregister ();
188             COMBOEX_Unregister ();
189             DATETIME_Unregister ();
190             FLATSB_Unregister ();
191             HEADER_Unregister ();
192             HOTKEY_Unregister ();
193             IPADDRESS_Unregister ();
194             LISTVIEW_Unregister ();
195             MONTHCAL_Unregister ();
196             NATIVEFONT_Unregister ();
197             PAGER_Unregister ();
198             PROGRESS_Unregister ();
199             REBAR_Unregister ();
200             STATUS_Unregister ();
201             TAB_Unregister ();
202             TOOLBAR_Unregister ();
203             TOOLTIPS_Unregister ();
204             TRACKBAR_Unregister ();
205             TREEVIEW_Unregister ();
206             UPDOWN_Unregister ();
207
208             /* delete local pattern brush */
209             DeleteObject (COMCTL32_hPattern55AABrush);
210             COMCTL32_hPattern55AABrush = NULL;
211             DeleteObject (COMCTL32_hPattern55AABitmap);
212             COMCTL32_hPattern55AABitmap = NULL;
213
214             /* delete global subclassing atom */
215             GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
216             TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
217             COMCTL32_aSubclass = NULL;
218             break;
219     }
220
221     return TRUE;
222 }
223
224
225 /***********************************************************************
226  * MenuHelp [COMCTL32.2]
227  *
228  * Handles the setting of status bar help messages when the user
229  * selects menu items.
230  *
231  * PARAMS
232  *     uMsg       [I] message (WM_MENUSELECT) (see NOTES)
233  *     wParam     [I] wParam of the message uMsg
234  *     lParam     [I] lParam of the message uMsg
235  *     hMainMenu  [I] handle to the application's main menu
236  *     hInst      [I] handle to the module that contains string resources
237  *     hwndStatus [I] handle to the status bar window
238  *     lpwIDs     [I] pointer to an array of integers (see NOTES)
239  *
240  * RETURNS
241  *     No return value
242  *
243  * NOTES
244  *     The official documentation is incomplete!
245  *     This is the correct documentation:
246  *
247  *     uMsg:
248  *     MenuHelp() does NOT handle WM_COMMAND messages! It only handles
249  *     WM_MENUSELECT messages.
250  *
251  *     lpwIDs:
252  *     (will be written ...)
253  */
254
255 VOID WINAPI
256 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
257           HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
258 {
259     UINT uMenuID = 0;
260
261     if (!IsWindow (hwndStatus))
262         return;
263
264     switch (uMsg) {
265         case WM_MENUSELECT:
266             TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
267                    wParam, lParam);
268
269             if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
270                 /* menu was closed */
271                 TRACE("menu was closed!\n");
272                 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
273             }
274             else {
275                 /* menu item was selected */
276                 if (HIWORD(wParam) & MF_POPUP)
277                     uMenuID = (UINT)*(lpwIDs+1);
278                 else
279                     uMenuID = (UINT)LOWORD(wParam);
280                 TRACE("uMenuID = %u\n", uMenuID);
281
282                 if (uMenuID) {
283                     CHAR szText[256];
284
285                     if (!LoadStringA (hInst, uMenuID, szText, 256))
286                         szText[0] = '\0';
287
288                     SendMessageA (hwndStatus, SB_SETTEXTA,
289                                     255 | SBT_NOBORDERS, (LPARAM)szText);
290                     SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
291                 }
292             }
293             break;
294
295         case WM_COMMAND :
296             TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
297                    wParam, lParam);
298             /* WM_COMMAND is not invalid since it is documented
299              * in the windows api reference. So don't output
300              * any FIXME for WM_COMMAND
301              */
302             WARN("We don't care about the WM_COMMAND\n");
303             break;
304
305         default:
306             FIXME("Invalid Message 0x%x!\n", uMsg);
307             break;
308     }
309 }
310
311
312 /***********************************************************************
313  * ShowHideMenuCtl [COMCTL32.3]
314  *
315  * Shows or hides controls and updates the corresponding menu item.
316  *
317  * PARAMS
318  *     hwnd   [I] handle to the client window.
319  *     uFlags [I] menu command id.
320  *     lpInfo [I] pointer to an array of integers. (See NOTES.)
321  *
322  * RETURNS
323  *     Success: TRUE
324  *     Failure: FALSE
325  *
326  * NOTES
327  *     The official documentation is incomplete!
328  *     This is the correct documentation:
329  *
330  *     hwnd
331  *     Handle to the window that contains the menu and controls.
332  *
333  *     uFlags
334  *     Identifier of the menu item to receive or loose a check mark.
335  *
336  *     lpInfo
337  *     The array of integers contains pairs of values. BOTH values of
338  *     the first pair must be the handles to the application's main menu.
339  *     Each subsequent pair consists of a menu id and control id.
340  */
341
342 BOOL WINAPI
343 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
344 {
345     LPINT lpMenuId;
346
347     TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo);
348
349     if (lpInfo == NULL)
350         return FALSE;
351
352     if (!(lpInfo[0]) || !(lpInfo[1]))
353         return FALSE;
354
355     /* search for control */
356     lpMenuId = &lpInfo[2];
357     while (*lpMenuId != uFlags)
358         lpMenuId += 2;
359
360     if (GetMenuState ((HMENU)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
361         /* uncheck menu item */
362         CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
363
364         /* hide control */
365         lpMenuId++;
366         SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
367                         SWP_HIDEWINDOW);
368     }
369     else {
370         /* check menu item */
371         CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
372
373         /* show control */
374         lpMenuId++;
375         SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
376                         SWP_SHOWWINDOW);
377     }
378
379     return TRUE;
380 }
381
382
383 /***********************************************************************
384  * GetEffectiveClientRect [COMCTL32.4]
385  *
386  * Calculates the coordinates of a rectangle in the client area.
387  *
388  * PARAMS
389  *     hwnd   [I] handle to the client window.
390  *     lpRect [O] pointer to the rectangle of the client window
391  *     lpInfo [I] pointer to an array of integers (see NOTES)
392  *
393  * RETURNS
394  *     No return value.
395  *
396  * NOTES
397  *     The official documentation is incomplete!
398  *     This is the correct documentation:
399  *
400  *     lpInfo
401  *     (will be written ...)
402  */
403
404 VOID WINAPI
405 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
406 {
407     RECT rcCtrl;
408     INT  *lpRun;
409     HWND hwndCtrl;
410
411     TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
412            (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
413
414     GetClientRect (hwnd, lpRect);
415     lpRun = lpInfo;
416
417     do {
418         lpRun += 2;
419         if (*lpRun == 0)
420             return;
421         lpRun++;
422         hwndCtrl = GetDlgItem (hwnd, *lpRun);
423         if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
424             TRACE("control id 0x%x\n", *lpRun);
425             GetWindowRect (hwndCtrl, &rcCtrl);
426             MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
427             SubtractRect (lpRect, lpRect, &rcCtrl);
428         }
429         lpRun++;
430     } while (*lpRun);
431 }
432
433
434 /***********************************************************************
435  * DrawStatusTextW [COMCTL32.@]
436  *
437  * Draws text with borders, like in a status bar.
438  *
439  * PARAMS
440  *     hdc   [I] handle to the window's display context
441  *     lprc  [I] pointer to a rectangle
442  *     text  [I] pointer to the text
443  *     style [I] drawing style
444  *
445  * RETURNS
446  *     No return value.
447  *
448  * NOTES
449  *     The style variable can have one of the following values:
450  *     (will be written ...)
451  */
452
453 void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
454 {
455     RECT r = *lprc;
456     UINT border = BDR_SUNKENOUTER;
457
458     if (style & SBT_POPOUT)
459         border = BDR_RAISEDOUTER;
460     else if (style & SBT_NOBORDERS)
461         border = 0;
462
463     DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
464
465     /* now draw text */
466     if (text) {
467         int oldbkmode = SetBkMode (hdc, TRANSPARENT);
468         UINT align = DT_LEFT;
469         if (*text == L'\t') {
470             text++;
471             align = DT_CENTER;
472             if (*text == L'\t') {
473                 text++;
474                 align = DT_RIGHT;
475             }
476         }
477         r.left += 3;
478         if (style & SBT_RTLREADING)
479             FIXME("Unsupported RTL style!\n");
480         DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
481         SetBkMode(hdc, oldbkmode);
482     }
483 }
484
485
486 /***********************************************************************
487  * DrawStatusText  [COMCTL32.@]
488  * DrawStatusTextA [COMCTL32.5]
489  *
490  * Draws text with borders, like in a status bar.
491  *
492  * PARAMS
493  *     hdc   [I] handle to the window's display context
494  *     lprc  [I] pointer to a rectangle
495  *     text  [I] pointer to the text
496  *     style [I] drawing style
497  *
498  * RETURNS
499  *     No return value.
500  */
501
502 void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
503 {
504     INT len;
505     LPWSTR textW = NULL;
506
507     if ( text ) {
508         if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
509             if ( (textW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )) )
510                 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
511         }
512     }
513     DrawStatusTextW( hdc, lprc, textW, style );
514     HeapFree( GetProcessHeap(), 0, textW );
515 }
516
517
518 /***********************************************************************
519  * CreateStatusWindow  [COMCTL32.@]
520  * CreateStatusWindowA [COMCTL32.6]
521  *
522  * Creates a status bar
523  *
524  * PARAMS
525  *     style  [I] window style
526  *     text   [I] pointer to the window text
527  *     parent [I] handle to the parent window
528  *     wid    [I] control id of the status bar
529  *
530  * RETURNS
531  *     Success: handle to the status window
532  *     Failure: 0
533  */
534
535 HWND WINAPI
536 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
537 {
538     return CreateWindowA(STATUSCLASSNAMEA, text, style,
539                            CW_USEDEFAULT, CW_USEDEFAULT,
540                            CW_USEDEFAULT, CW_USEDEFAULT,
541                            parent, (HMENU)wid, 0, 0);
542 }
543
544
545 /***********************************************************************
546  * CreateStatusWindowW [COMCTL32.@]
547  *
548  * Creates a status bar control
549  *
550  * PARAMS
551  *     style  [I] window style
552  *     text   [I] pointer to the window text
553  *     parent [I] handle to the parent window
554  *     wid    [I] control id of the status bar
555  *
556  * RETURNS
557  *     Success: handle to the status window
558  *     Failure: 0
559  */
560
561 HWND WINAPI
562 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
563 {
564     return CreateWindowW(STATUSCLASSNAMEW, text, style,
565                            CW_USEDEFAULT, CW_USEDEFAULT,
566                            CW_USEDEFAULT, CW_USEDEFAULT,
567                            parent, (HMENU)wid, 0, 0);
568 }
569
570
571 /***********************************************************************
572  * CreateUpDownControl [COMCTL32.16]
573  *
574  * Creates an up-down control
575  *
576  * PARAMS
577  *     style  [I] window styles
578  *     x      [I] horizontal position of the control
579  *     y      [I] vertical position of the control
580  *     cx     [I] with of the control
581  *     cy     [I] height of the control
582  *     parent [I] handle to the parent window
583  *     id     [I] the control's identifier
584  *     inst   [I] handle to the application's module instance
585  *     buddy  [I] handle to the buddy window, can be NULL
586  *     maxVal [I] upper limit of the control
587  *     minVal [I] lower limit of the control
588  *     curVal [I] current value of the control
589  *
590  * RETURNS
591  *     Success: handle to the updown control
592  *     Failure: 0
593  */
594
595 HWND WINAPI
596 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
597                      HWND parent, INT id, HINSTANCE inst,
598                      HWND buddy, INT maxVal, INT minVal, INT curVal)
599 {
600     HWND hUD =
601         CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
602                          parent, (HMENU)id, inst, 0);
603     if (hUD) {
604         SendMessageA (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
605         SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
606         SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
607     }
608
609     return hUD;
610 }
611
612
613 /***********************************************************************
614  * InitCommonControls [COMCTL32.17]
615  *
616  * Registers the common controls.
617  *
618  * PARAMS
619  *     No parameters.
620  *
621  * RETURNS
622  *     No return values.
623  *
624  * NOTES
625  *     This function is just a dummy.
626  *     The Win95 controls are registered at the DLL's initialization.
627  *     To register other controls InitCommonControlsEx() must be used.
628  */
629
630 VOID WINAPI
631 InitCommonControls (void)
632 {
633 }
634
635
636 /***********************************************************************
637  * InitCommonControlsEx [COMCTL32.@]
638  *
639  * Registers the common controls.
640  *
641  * PARAMS
642  *     lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
643  *
644  * RETURNS
645  *     Success: TRUE
646  *     Failure: FALSE
647  *
648  * NOTES
649  *     Only the additional common controls are registered by this function.
650  *     The Win95 controls are registered at the DLL's initialization.
651  *
652  * FIXME
653  *     implement the following control classes:
654  *       ICC_LINK_CLASS
655  *       ICC_STANDARD_CLASSES
656  */
657
658 BOOL WINAPI
659 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
660 {
661     INT cCount;
662     DWORD dwMask;
663
664     if (!lpInitCtrls)
665         return FALSE;
666     if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
667         return FALSE;
668
669     TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
670
671     for (cCount = 0; cCount < 32; cCount++) {
672         dwMask = 1 << cCount;
673         if (!(lpInitCtrls->dwICC & dwMask))
674             continue;
675
676         switch (lpInitCtrls->dwICC & dwMask) {
677             /* dummy initialization */
678             case ICC_ANIMATE_CLASS:
679             case ICC_BAR_CLASSES:
680             case ICC_LISTVIEW_CLASSES:
681             case ICC_TREEVIEW_CLASSES:
682             case ICC_TAB_CLASSES:
683             case ICC_UPDOWN_CLASS:
684             case ICC_PROGRESS_CLASS:
685             case ICC_HOTKEY_CLASS:
686                 break;
687
688             /* advanced classes - not included in Win95 */
689             case ICC_DATE_CLASSES:
690                 MONTHCAL_Register ();
691                 DATETIME_Register ();
692                 break;
693
694             case ICC_USEREX_CLASSES:
695                 COMBOEX_Register ();
696                 break;
697
698             case ICC_COOL_CLASSES:
699                 REBAR_Register ();
700                 break;
701
702             case ICC_INTERNET_CLASSES:
703                 IPADDRESS_Register ();
704                 break;
705
706             case ICC_PAGESCROLLER_CLASS:
707                 PAGER_Register ();
708                 break;
709
710             case ICC_NATIVEFNTCTL_CLASS:
711                 NATIVEFONT_Register ();
712                 break;
713
714             default:
715                 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
716                 break;
717         }
718     }
719
720     return TRUE;
721 }
722
723
724 /***********************************************************************
725  * CreateToolbarEx [COMCTL32.@]
726  *
727  * Creates a toolbar window.
728  *
729  * PARAMS
730  *     hwnd
731  *     style
732  *     wID
733  *     nBitmaps
734  *     hBMInst
735  *     wBMID
736  *     lpButtons
737  *     iNumButtons
738  *     dxButton
739  *     dyButton
740  *     dxBitmap
741  *     dyBitmap
742  *     uStructSize
743  *
744  * RETURNS
745  *     Success: handle to the tool bar control
746  *     Failure: 0
747  */
748
749 HWND WINAPI
750 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
751                  HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
752                  INT iNumButtons, INT dxButton, INT dyButton,
753                  INT dxBitmap, INT dyBitmap, UINT uStructSize)
754 {
755     HWND hwndTB;
756
757     hwndTB =
758         CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL, style|WS_CHILD, 0,0,100,30,
759                         hwnd, (HMENU)wID, COMCTL32_hModule, NULL);
760     if(hwndTB) {
761         TBADDBITMAP tbab;
762
763         SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
764                         (WPARAM)uStructSize, 0);
765
766        /* set bitmap and button size */
767        /*If CreateToolbarEx receives 0, windows sets default values*/
768        if (dxBitmap <= 0)
769            dxBitmap = 16;
770        if (dyBitmap <= 0)
771            dyBitmap = 15;
772        SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
773                        MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
774
775        if (dxButton <= 0)
776            dxButton = 24;
777        if (dyButton <= 0)
778            dyButton = 22;
779        SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
780                        MAKELPARAM((WORD)dxButton, (WORD)dyButton));
781
782
783         /* add bitmaps */
784         if (nBitmaps > 0)
785         {
786         tbab.hInst = hBMInst;
787         tbab.nID   = wBMID;
788
789         SendMessageA (hwndTB, TB_ADDBITMAP,
790                         (WPARAM)nBitmaps, (LPARAM)&tbab);
791         }
792         /* add buttons */
793         if(iNumButtons > 0)
794         SendMessageA (hwndTB, TB_ADDBUTTONSA,
795                         (WPARAM)iNumButtons, (LPARAM)lpButtons);
796     }
797
798     return hwndTB;
799 }
800
801
802 /***********************************************************************
803  * CreateMappedBitmap [COMCTL32.8]
804  *
805  * Loads a bitmap resource using a colour map.
806  *
807  * PARAMS
808  *     hInstance  [I] Handle to the module containing the bitmap.
809  *     idBitmap   [I] The bitmap resource ID.
810  *     wFlags     [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
811  *     lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
812  *     iNumMaps   [I] Number of COLORMAP's pointed to by lpColorMap.
813  *
814  * RETURNS
815  *     Success: handle to the new bitmap
816  *     Failure: 0
817  */
818
819 HBITMAP WINAPI
820 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
821                     LPCOLORMAP lpColorMap, INT iNumMaps)
822 {
823     HGLOBAL hglb;
824     HRSRC hRsrc;
825     LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
826     UINT nSize, nColorTableSize;
827     RGBQUAD *pColorTable;
828     INT iColor, i, iMaps, nWidth, nHeight;
829     HDC hdcScreen;
830     HBITMAP hbm;
831     LPCOLORMAP sysColorMap;
832     COLORREF cRef;
833     COLORMAP internalColorMap[4] =
834         {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
835
836     /* initialize pointer to colortable and default color table */
837     if (lpColorMap) {
838         iMaps = iNumMaps;
839         sysColorMap = lpColorMap;
840     }
841     else {
842         internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
843         internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
844         internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
845         internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
846         iMaps = 4;
847         sysColorMap = (LPCOLORMAP)internalColorMap;
848     }
849
850     hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, (LPSTR)RT_BITMAP);
851     if (hRsrc == 0)
852         return 0;
853     hglb = LoadResource (hInstance, hRsrc);
854     if (hglb == 0)
855         return 0;
856     lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
857     if (lpBitmap == NULL)
858         return 0;
859
860     if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
861         nColorTableSize = lpBitmap->biClrUsed;
862     else if (lpBitmap->biBitCount <= 8) 
863         nColorTableSize = (1 << lpBitmap->biBitCount);
864     else
865         nColorTableSize = 0;
866     nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
867     lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
868     if (lpBitmapInfo == NULL)
869         return 0;
870     RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
871
872     pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
873
874     for (iColor = 0; iColor < nColorTableSize; iColor++) {
875         for (i = 0; i < iMaps; i++) {
876             cRef = RGB(pColorTable[iColor].rgbRed,
877                        pColorTable[iColor].rgbGreen,
878                        pColorTable[iColor].rgbBlue);
879             if ( cRef  == sysColorMap[i].from) {
880 #if 0
881                 if (wFlags & CBS_MASKED) {
882                     if (sysColorMap[i].to != COLOR_BTNTEXT)
883                         pColorTable[iColor] = RGB(255, 255, 255);
884                 }
885                 else
886 #endif
887                     pColorTable[iColor].rgbBlue  = GetBValue(sysColorMap[i].to);
888                     pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
889                     pColorTable[iColor].rgbRed   = GetRValue(sysColorMap[i].to);
890                 break;
891             }
892         }
893     }
894     nWidth  = (INT)lpBitmapInfo->biWidth;
895     nHeight = (INT)lpBitmapInfo->biHeight;
896     hdcScreen = GetDC (NULL);
897     hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
898     if (hbm) {
899         HDC hdcDst = CreateCompatibleDC (hdcScreen);
900         HBITMAP hbmOld = SelectObject (hdcDst, hbm);
901         LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
902         lpBits += nColorTableSize * sizeof(RGBQUAD);
903         StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
904                          lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
905                          SRCCOPY);
906         SelectObject (hdcDst, hbmOld);
907         DeleteDC (hdcDst);
908     }
909     ReleaseDC (NULL, hdcScreen);
910     GlobalFree ((HGLOBAL)lpBitmapInfo);
911     FreeResource (hglb);
912
913     return hbm;
914 }
915
916
917 /***********************************************************************
918  * CreateToolbar [COMCTL32.7]
919  *
920  * Creates a toolbar control.
921  *
922  * PARAMS
923  *     hwnd
924  *     style
925  *     wID
926  *     nBitmaps
927  *     hBMInst
928  *     wBMID
929  *     lpButtons
930  *     iNumButtons
931  *
932  * RETURNS
933  *     Success: handle to the tool bar control
934  *     Failure: 0
935  *
936  * NOTES
937  *     Do not use this functions anymore. Use CreateToolbarEx instead.
938  */
939
940 HWND WINAPI
941 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
942                HINSTANCE hBMInst, UINT wBMID,
943                LPCTBBUTTON lpButtons,INT iNumButtons)
944 {
945     return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
946                             hBMInst, wBMID, lpButtons,
947                             iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
948 }
949
950
951 /***********************************************************************
952  * DllGetVersion [COMCTL32.@]
953  *
954  * Retrieves version information of the 'COMCTL32.DLL'
955  *
956  * PARAMS
957  *     pdvi [O] pointer to version information structure.
958  *
959  * RETURNS
960  *     Success: S_OK
961  *     Failure: E_INVALIDARG
962  *
963  * NOTES
964  *     Returns version of a comctl32.dll from IE4.01 SP1.
965  */
966
967 HRESULT WINAPI
968 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
969 {
970     if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
971         WARN("wrong DLLVERSIONINFO size from app\n");
972         return E_INVALIDARG;
973     }
974
975     pdvi->dwMajorVersion = COMCTL32_VERSION;
976     pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
977     pdvi->dwBuildNumber = 2919;
978     pdvi->dwPlatformID = 6304;
979
980     TRACE("%lu.%lu.%lu.%lu\n",
981            pdvi->dwMajorVersion, pdvi->dwMinorVersion,
982            pdvi->dwBuildNumber, pdvi->dwPlatformID);
983
984     return S_OK;
985 }
986
987 /***********************************************************************
988  *              DllInstall (COMCTL32.@)
989  *
990  * Installs the ComCtl32 DLL.
991  *
992  * RETURNS
993  *     Success: S_OK
994  *     Failure: A HRESULT error
995  */
996 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
997 {
998   FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
999         debugstr_w(cmdline));
1000
1001   return S_OK;
1002 }
1003
1004 /***********************************************************************
1005  * _TrackMouseEvent [COMCTL32.@]
1006  *
1007  * Requests notification of mouse events
1008  *
1009  * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1010  * to the hwnd specified in the ptme structure.  After the event message
1011  * is posted to the hwnd, the entry in the queue is removed.
1012  *
1013  * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1014  * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1015  * immediately and the TME_LEAVE flag being ignored.
1016  *
1017  * PARAMS
1018  *     ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1019  *
1020  * RETURNS
1021  *     Success: non-zero
1022  *     Failure: zero
1023  *
1024  * IMPLEMENTATION moved to USER32.TrackMouseEvent
1025  *
1026  */
1027
1028 BOOL WINAPI
1029 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1030 {
1031     return TrackMouseEvent (ptme);
1032 }
1033
1034 /*************************************************************************
1035  * GetMUILanguage [COMCTL32.@]
1036  *
1037  * Returns the user interface language in use by the current process.
1038  *
1039  * RETURNS
1040  *      Language ID in use by the current process.
1041  */
1042 LANGID WINAPI GetMUILanguage (VOID)
1043 {
1044     return COMCTL32_uiLang;
1045 }
1046
1047
1048 /*************************************************************************
1049  * InitMUILanguage [COMCTL32.@]
1050  *
1051  * Sets the user interface language to be used by the current process.
1052  *
1053  * RETURNS
1054  *      Nothing.
1055  */
1056 VOID WINAPI InitMUILanguage (LANGID uiLang)
1057 {
1058    COMCTL32_uiLang = uiLang;
1059 }
1060
1061
1062 /***********************************************************************
1063  * SetWindowSubclass [COMCTL32.410]
1064  *
1065  * Starts a window subclass
1066  *
1067  * PARAMS
1068  *     hWnd [in] handle to window subclass.
1069  *     pfnSubclass [in] Pointer to new window procedure.
1070  *     uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1071  *     dwRef [in] Reference data to pass to window procedure.
1072  *
1073  * RETURNS
1074  *     Success: non-zero
1075  *     Failure: zero
1076  *
1077  * BUGS
1078  *     If an application manually subclasses a window after subclassing it with
1079  *     this API and then with this API again, then none of the previous 
1080  *     subclasses get called or the origional window procedure.
1081  */
1082
1083 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1084                         UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1085 {
1086    LPSUBCLASS_INFO stack;
1087    int n;
1088
1089    TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
1090
1091    /* Since the window procedure that we set here has two additional arguments,
1092     * we can't simply set it as the new window procedure of the window. So we
1093     * set our own window procedure and then calculate the other two arguments
1094     * from there. */
1095
1096    /* See if we have been called for this window */
1097    stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1098    if (!stack) {
1099       /* allocate stack */
1100       stack = (LPSUBCLASS_INFO)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY,
1101                                          sizeof(SUBCLASS_INFO));
1102       if (!stack) {
1103          ERR ("Failed to allocate our Subclassing stack\n");
1104          return FALSE;
1105       }
1106       SetPropA (hWnd, COMCTL32_aSubclass, (HANDLE)stack);
1107
1108       /* set window procedure to our own and save the current one */
1109       if (IsWindowUnicode (hWnd))
1110          stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC,
1111                                                    (LONG)DefSubclassProc);
1112       else
1113          stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC,
1114                                                    (LONG)DefSubclassProc);
1115    } else {
1116       WNDPROC current;
1117       if (IsWindowUnicode (hWnd))
1118          current = (WNDPROC)GetWindowLongW (hWnd, GWL_WNDPROC);
1119       else
1120          current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC);
1121
1122       if (current != DefSubclassProc) {
1123          ERR ("Application has subclassed with our procedure, then manually, then with us again.  The current implementation can't handle this.\n");
1124          return FALSE;
1125       }
1126    }
1127
1128    /* Check to see if we have called this function with the same uIDSubClass
1129     * and pfnSubclass */
1130    for (n = 0; n < stack->stacknum; n++)
1131       if ((stack->SubclassProcs[n].id == uIDSubclass) && 
1132          (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1133          stack->SubclassProcs[n].ref = dwRef;
1134          return TRUE;
1135       }
1136
1137    if (stack->stacknum >= 32) {
1138       ERR ("We have a Subclass stack overflow, please increment size\n");
1139       return FALSE;
1140    }
1141
1142    memmove (&stack->SubclassProcs[1], &stack->SubclassProcs[0],
1143             sizeof(stack->SubclassProcs[0]) * stack->stacknum);
1144
1145    stack->stacknum++;
1146    if (stack->wndprocrecursion)
1147       stack->stackpos++;
1148
1149    stack->SubclassProcs[0].subproc = pfnSubclass;
1150    stack->SubclassProcs[0].ref = dwRef;
1151    stack->SubclassProcs[0].id = uIDSubclass;
1152    
1153    return TRUE;
1154 }
1155
1156
1157 /***********************************************************************
1158  * GetWindowSubclass [COMCTL32.411]
1159  *
1160  * Gets the Reference data from a subclass.
1161  *
1162  * PARAMS
1163  *     hWnd [in] Handle to window which were subclassing
1164  *     pfnSubclass [in] Pointer to the subclass procedure
1165  *     uID [in] Unique indentifier of the subclassing procedure
1166  *     pdwRef [out] Pointer to the reference data
1167  *
1168  * RETURNS
1169  *     Success: Non-zero
1170  *     Failure: 0
1171  */
1172
1173 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1174                               UINT_PTR uID, DWORD_PTR *pdwRef)
1175 {
1176    LPSUBCLASS_INFO stack;
1177    int n;
1178
1179    TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
1180
1181    /* See if we have been called for this window */
1182    stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1183    if (!stack)
1184       return FALSE;
1185
1186    for (n = 0; n < stack->stacknum; n++)
1187       if ((stack->SubclassProcs[n].id == uID) &&
1188          (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1189          *pdwRef = stack->SubclassProcs[n].ref;
1190          return TRUE;
1191       }
1192
1193    return FALSE;
1194 }
1195
1196
1197 /***********************************************************************
1198  * RemoveWindowSubclass [COMCTL32.412]
1199  *
1200  * Removes a window subclass.
1201  *
1202  * PARAMS
1203  *     hWnd [in] Handle to the window were subclassing
1204  *     pfnSubclass [in] Pointer to the subclass procedure
1205  *     uID [in] Unique identifier of this subclass
1206  *
1207  * RETURNS
1208  *     Success: non-zero
1209  *     Failure: zero
1210  */
1211
1212 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1213 {
1214    LPSUBCLASS_INFO stack;
1215    int n;
1216
1217    TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID);
1218
1219    /* Find the Subclass to remove */
1220    stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1221    if (!stack)
1222       return FALSE;
1223
1224    if ((stack->stacknum == 1) && (stack->stackpos == 1) &&
1225        !stack->wndprocrecursion) {
1226       TRACE("Last Subclass removed, cleaning up\n");
1227       /* clean up our heap and reset the origional window procedure */
1228       if (IsWindowUnicode (hWnd))
1229          SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1230       else
1231          SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1232       HeapFree (GetProcessHeap (), 0, stack);
1233       RemovePropA( hWnd, COMCTL32_aSubclass );
1234       return TRUE;
1235    }
1236  
1237    for (n = stack->stacknum - 1; n >= 0; n--)
1238       if ((stack->SubclassProcs[n].id == uID) &&
1239          (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1240          if (n != stack->stacknum)
1241             /* Fill the hole in the stack */
1242             memmove (&stack->SubclassProcs[n], &stack->SubclassProcs[n + 1],
1243                     sizeof(stack->SubclassProcs[0]) * (stack->stacknum - n));
1244          stack->SubclassProcs[n].subproc = NULL;
1245          stack->SubclassProcs[n].ref = 0;
1246          stack->SubclassProcs[n].id = 0;
1247
1248          stack->stacknum--;
1249          if (n < stack->stackpos && stack->wndprocrecursion)
1250             stack->stackpos--;
1251
1252          return TRUE;
1253       }
1254
1255    return FALSE;
1256 }
1257
1258
1259 /***********************************************************************
1260  * DefSubclassProc [COMCTL32.413]
1261  *
1262  * Calls the next window procedure (ie. the one before this subclass)
1263  *
1264  * PARAMS
1265  *     hWnd [in] The window that we're subclassing
1266  *     uMsg [in] Message
1267  *     wParam [in] WPARAM
1268  *     lParam [in] LPARAM
1269  *
1270  * RETURNS
1271  *     Success: non-zero
1272  *     Failure: zero
1273  */
1274
1275 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1276 {
1277    LPSUBCLASS_INFO stack;
1278    LRESULT ret;
1279
1280    /* retrieve our little stack from the Properties */
1281    stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1282    if (!stack) {
1283       ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1284       return 0;
1285    }
1286
1287    stack->wndprocrecursion++;
1288
1289    /* If we are at the end of stack then we have to call the original
1290     * window procedure */
1291    if (stack->stackpos == stack->stacknum) {
1292       if (IsWindowUnicode (hWnd))
1293          ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
1294       else
1295          ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1296    } else {
1297       stack->stackpos++;
1298       /* call the Subclass procedure from the stack */
1299       ret = stack->SubclassProcs[stack->stackpos - 1].subproc (hWnd, uMsg, wParam, lParam,
1300             stack->SubclassProcs[stack->stackpos - 1].id, stack->SubclassProcs[stack->stackpos - 1].ref);
1301       stack->stackpos--;
1302    }
1303
1304    /* We finished the recursion, so let's reinitalize the stack position to
1305     * beginning */
1306    if ((--stack->wndprocrecursion) == 0) {
1307       stack->stackpos = 0;
1308    }
1309
1310    /* If we removed the last entry in our stack while a window procedure was
1311     * running then we have to clean up */
1312    if ((stack->stackpos == 0) && (stack->stacknum == 0)) {
1313       TRACE("Last Subclass removed, cleaning up\n");
1314       /* clean up our heap and reset the origional window procedure */
1315       if (IsWindowUnicode (hWnd))
1316          SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1317       else
1318          SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1319       HeapFree (GetProcessHeap (), 0, stack);
1320       RemovePropA( hWnd, COMCTL32_aSubclass );
1321       return TRUE;
1322    }
1323
1324    return ret;
1325 }
1326
1327
1328 /***********************************************************************
1329  * COMCTL32_CreateToolTip [NOT AN API]
1330  *
1331  * Creates a tooltip for the control specified in hwnd and does all
1332  * necessary setup and notifications.
1333  *
1334  * PARAMS
1335  *     hwndOwner [I] Handle to the window that will own the tool tip.
1336  *
1337  * RETURNS
1338  *     Success: Handle of tool tip window.
1339  *     Failure: NULL
1340  */
1341
1342 HWND
1343 COMCTL32_CreateToolTip(HWND hwndOwner)
1344 {
1345     HWND hwndToolTip;
1346
1347     hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1348                                   CW_USEDEFAULT, CW_USEDEFAULT,
1349                                   CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1350                                   0, 0, 0);
1351
1352     /* Send NM_TOOLTIPSCREATED notification */
1353     if (hwndToolTip)
1354     {
1355         NMTOOLTIPSCREATED nmttc;
1356         /* true owner can be different if hwndOwner is a child window */
1357         HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1358         nmttc.hdr.hwndFrom = hwndTrueOwner;
1359         nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID);
1360         nmttc.hdr.code = NM_TOOLTIPSCREATED;
1361         nmttc.hwndToolTips = hwndToolTip;
1362
1363        SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1364                     (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID),
1365                      (LPARAM)&nmttc);
1366     }
1367
1368     return hwndToolTip;
1369 }
1370
1371
1372 /***********************************************************************
1373  * COMCTL32_RefreshSysColors [NOT AN API]
1374  *
1375  * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1376  * refresh the color values in the color structure
1377  *
1378  * PARAMS
1379  *     none
1380  *
1381  * RETURNS
1382  *     none
1383  */
1384
1385 VOID
1386 COMCTL32_RefreshSysColors(void)
1387 {
1388     comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1389     comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1390     comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1391     comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1392     comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1393     comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
1394     comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1395     comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1396     comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1397     comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1398     comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1399     comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1400     comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1401     comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1402     comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1403     comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);
1404 }