Update shell xxxAW wrapper prototypes for fixed SHLWAPI functions.
[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
22 #include <string.h>
23 #include <stdlib.h>
24
25 #include "winbase.h"
26 #include "commctrl.h"
27 #include "winerror.h"
28 #include "winreg.h"
29 #define NO_SHLWAPI_STREAM
30 #include "shlwapi.h"
31 #include "comctl32.h"
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
35
36 extern void ANIMATE_Register(void);
37 extern void ANIMATE_Unregister(void);
38 extern void COMBOEX_Register(void);
39 extern void COMBOEX_Unregister(void);
40 extern void DATETIME_Register(void);
41 extern void DATETIME_Unregister(void);
42 extern void FLATSB_Register(void);
43 extern void FLATSB_Unregister(void);
44 extern void HEADER_Register(void);
45 extern void HEADER_Unregister(void);
46 extern void HOTKEY_Register(void);
47 extern void HOTKEY_Unregister(void);
48 extern void IPADDRESS_Register(void);
49 extern void IPADDRESS_Unregister(void);
50 extern void LISTVIEW_Register(void);
51 extern void LISTVIEW_Unregister(void);
52 extern void MONTHCAL_Register(void);
53 extern void MONTHCAL_Unregister(void);
54 extern void NATIVEFONT_Register(void);
55 extern void NATIVEFONT_Unregister(void);
56 extern void PAGER_Register(void);
57 extern void PAGER_Unregister(void);
58 extern void PROGRESS_Register(void);
59 extern void PROGRESS_Unregister(void);
60 extern void REBAR_Register(void);
61 extern void REBAR_Unregister(void);
62 extern void STATUS_Register(void);
63 extern void STATUS_Unregister(void);
64 extern void TAB_Register(void);
65 extern void TAB_Unregister(void);
66 extern void TOOLBAR_Register(void);
67 extern void TOOLBAR_Unregister(void);
68 extern void TOOLTIPS_Register(void);
69 extern void TOOLTIPS_Unregister(void);
70 extern void TRACKBAR_Register(void);
71 extern void TRACKBAR_Unregister(void);
72 extern void TREEVIEW_Register(void);
73 extern void TREEVIEW_Unregister(void);
74 extern void UPDOWN_Register(void);
75 extern void UPDOWN_Unregister(void);
76
77
78 HANDLE COMCTL32_hHeap = (HANDLE)NULL;
79 LPSTR    COMCTL32_aSubclass = (LPSTR)NULL;
80 HMODULE COMCTL32_hModule = 0;
81 LANGID  COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
82 HBRUSH  COMCTL32_hPattern55AABrush = (HANDLE)NULL;
83
84 static HBITMAP COMCTL32_hPattern55AABitmap = (HANDLE)NULL;
85
86 static const WORD wPattern55AA[] =
87 {
88     0x5555, 0xaaaa, 0x5555, 0xaaaa,
89     0x5555, 0xaaaa, 0x5555, 0xaaaa
90 };
91
92
93 /***********************************************************************
94  * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
95  *
96  * PARAMS
97  *     hinstDLL    [I] handle to the 'dlls' instance
98  *     fdwReason   [I]
99  *     lpvReserved [I] reserverd, must be NULL
100  *
101  * RETURNS
102  *     Success: TRUE
103  *     Failure: FALSE
104  */
105
106 BOOL WINAPI
107 COMCTL32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
108 {
109     TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
110
111     switch (fdwReason) {
112         case DLL_PROCESS_ATTACH:
113             COMCTL32_hModule = (HMODULE)hinstDLL;
114
115             /* create private heap */
116             COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
117             TRACE("Heap created: 0x%x\n", COMCTL32_hHeap);
118
119             /* add global subclassing atom (used by 'tooltip' and 'updown') */
120             COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
121             TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
122
123             /* create local pattern brush */
124             COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
125             COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
126
127             /* register all Win95 common control classes */
128             ANIMATE_Register ();
129             FLATSB_Register ();
130             HEADER_Register ();
131             HOTKEY_Register ();
132             LISTVIEW_Register ();
133             PROGRESS_Register ();
134             STATUS_Register ();
135             TAB_Register ();
136             TOOLBAR_Register ();
137             TOOLTIPS_Register ();
138             TRACKBAR_Register ();
139             TREEVIEW_Register ();
140             UPDOWN_Register ();
141             break;
142
143         case DLL_PROCESS_DETACH:
144             /* unregister all common control classes */
145             ANIMATE_Unregister ();
146             COMBOEX_Unregister ();
147             DATETIME_Unregister ();
148             FLATSB_Unregister ();
149             HEADER_Unregister ();
150             HOTKEY_Unregister ();
151             IPADDRESS_Unregister ();
152             LISTVIEW_Unregister ();
153             MONTHCAL_Unregister ();
154             NATIVEFONT_Unregister ();
155             PAGER_Unregister ();
156             PROGRESS_Unregister ();
157             REBAR_Unregister ();
158             STATUS_Unregister ();
159             TAB_Unregister ();
160             TOOLBAR_Unregister ();
161             TOOLTIPS_Unregister ();
162             TRACKBAR_Unregister ();
163             TREEVIEW_Unregister ();
164             UPDOWN_Unregister ();
165
166             /* delete local pattern brush */
167             DeleteObject (COMCTL32_hPattern55AABrush);
168             COMCTL32_hPattern55AABrush = (HANDLE)NULL;
169             DeleteObject (COMCTL32_hPattern55AABitmap);
170             COMCTL32_hPattern55AABitmap = (HANDLE)NULL;
171
172             /* delete global subclassing atom */
173             GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
174             TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
175             COMCTL32_aSubclass = (LPSTR)NULL;
176
177             /* destroy private heap */
178             HeapDestroy (COMCTL32_hHeap);
179             TRACE("Heap destroyed: 0x%x\n", COMCTL32_hHeap);
180             COMCTL32_hHeap = (HANDLE)NULL;
181             break;
182     }
183
184     return TRUE;
185 }
186
187
188 /***********************************************************************
189  * MenuHelp [COMCTL32.2]
190  *
191  * PARAMS
192  *     uMsg       [I] message (WM_MENUSELECT) (see NOTES)
193  *     wParam     [I] wParam of the message uMsg
194  *     lParam     [I] lParam of the message uMsg
195  *     hMainMenu  [I] handle to the application's main menu
196  *     hInst      [I] handle to the module that contains string resources
197  *     hwndStatus [I] handle to the status bar window
198  *     lpwIDs     [I] pointer to an array of integers (see NOTES)
199  *
200  * RETURNS
201  *     No return value
202  *
203  * NOTES
204  *     The official documentation is incomplete!
205  *     This is the correct documentation:
206  *
207  *     uMsg:
208  *     MenuHelp() does NOT handle WM_COMMAND messages! It only handles
209  *     WM_MENUSELECT messages.
210  *
211  *     lpwIDs:
212  *     (will be written ...)
213  */
214
215 VOID WINAPI
216 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
217           HINSTANCE hInst, HWND hwndStatus, LPUINT lpwIDs)
218 {
219     UINT uMenuID = 0;
220
221     if (!IsWindow (hwndStatus))
222         return;
223
224     switch (uMsg) {
225         case WM_MENUSELECT:
226             TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
227                    wParam, lParam);
228
229             if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
230                 /* menu was closed */
231                 TRACE("menu was closed!\n");
232                 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
233             }
234             else {
235                 /* menu item was selected */
236                 if (HIWORD(wParam) & MF_POPUP)
237                     uMenuID = (UINT)*(lpwIDs+1);
238                 else
239                     uMenuID = (UINT)LOWORD(wParam);
240                 TRACE("uMenuID = %u\n", uMenuID);
241
242                 if (uMenuID) {
243                     CHAR szText[256];
244
245                     if (!LoadStringA (hInst, uMenuID, szText, 256))
246                         szText[0] = '\0';
247
248                     SendMessageA (hwndStatus, SB_SETTEXTA,
249                                     255 | SBT_NOBORDERS, (LPARAM)szText);
250                     SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
251                 }
252             }
253             break;
254
255         case WM_COMMAND :
256             TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
257                    wParam, lParam);
258             /* WM_COMMAND is not invalid since it is documented
259              * in the windows api reference. So don't output
260              * any FIXME for WM_COMMAND
261              */
262             WARN("We don't care about the WM_COMMAND\n");
263             break;
264
265         default:
266             FIXME("Invalid Message 0x%x!\n", uMsg);
267             break;
268     }
269 }
270
271
272 /***********************************************************************
273  * ShowHideMenuCtl [COMCTL32.3] 
274  *
275  * Shows or hides controls and updates the corresponding menu item.
276  *
277  * PARAMS
278  *     hwnd   [I] handle to the client window.
279  *     uFlags [I] menu command id.
280  *     lpInfo [I] pointer to an array of integers. (See NOTES.)
281  *
282  * RETURNS
283  *     Success: TRUE
284  *     Failure: FALSE
285  *
286  * NOTES
287  *     The official documentation is incomplete!
288  *     This is the correct documentation:
289  *
290  *     hwnd
291  *     Handle to the window that contains the menu and controls.
292  *
293  *     uFlags
294  *     Identifier of the menu item to receive or loose a check mark.
295  *
296  *     lpInfo
297  *     The array of integers contains pairs of values. BOTH values of
298  *     the first pair must be the handles to the application's main menu.
299  *     Each subsequent pair consists of a menu id and control id.
300  */
301
302 BOOL WINAPI
303 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
304 {
305     LPINT lpMenuId;
306
307     TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
308
309     if (lpInfo == NULL)
310         return FALSE;
311
312     if (!(lpInfo[0]) || !(lpInfo[1]))
313         return FALSE;
314
315     /* search for control */
316     lpMenuId = &lpInfo[2];
317     while (*lpMenuId != uFlags)
318         lpMenuId += 2;
319
320     if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
321         /* uncheck menu item */
322         CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
323
324         /* hide control */
325         lpMenuId++;
326         SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
327                         SWP_HIDEWINDOW);
328     }
329     else {
330         /* check menu item */
331         CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
332
333         /* show control */
334         lpMenuId++;
335         SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
336                         SWP_SHOWWINDOW);
337     }
338
339     return TRUE;
340 }
341
342
343 /***********************************************************************
344  * GetEffectiveClientRect [COMCTL32.4]
345  *
346  * PARAMS
347  *     hwnd   [I] handle to the client window.
348  *     lpRect [O] pointer to the rectangle of the client window
349  *     lpInfo [I] pointer to an array of integers (see NOTES)
350  *
351  * RETURNS
352  *     No return value.
353  *
354  * NOTES
355  *     The official documentation is incomplete!
356  *     This is the correct documentation:
357  *
358  *     lpInfo
359  *     (will be written...)
360  */
361
362 VOID WINAPI
363 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
364 {
365     RECT rcCtrl;
366     INT  *lpRun;
367     HWND hwndCtrl;
368
369     TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
370            (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
371
372     GetClientRect (hwnd, lpRect);
373     lpRun = lpInfo;
374
375     do {
376         lpRun += 2;
377         if (*lpRun == 0)
378             return;
379         lpRun++;
380         hwndCtrl = GetDlgItem (hwnd, *lpRun);
381         if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
382             TRACE("control id 0x%x\n", *lpRun);
383             GetWindowRect (hwndCtrl, &rcCtrl);
384             MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2);
385             SubtractRect (lpRect, lpRect, &rcCtrl);
386         }
387         lpRun++;
388     } while (*lpRun);
389 }
390
391
392 /***********************************************************************
393  * DrawStatusTextW [COMCTL32.28]
394  *
395  * Draws text with borders, like in a status bar.
396  *
397  * PARAMS
398  *     hdc   [I] handle to the window's display context
399  *     lprc  [I] pointer to a rectangle
400  *     text  [I] pointer to the text
401  *     style [I] drawing style
402  *
403  * RETURNS
404  *     No return value.
405  *
406  * NOTES
407  *     The style variable can have one of the following values:
408  *     (will be written ...)
409  */
410
411 VOID WINAPI
412 DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
413 {
414     RECT r = *lprc;
415     UINT border = BDR_SUNKENOUTER;
416
417     if (style & SBT_POPOUT)
418       border = BDR_RAISEDOUTER;
419     else if (style & SBT_NOBORDERS)
420       border = 0;
421
422     DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
423
424     /* now draw text */
425     if (text) {
426       int oldbkmode = SetBkMode (hdc, TRANSPARENT);
427       r.left += 3;
428       DrawTextW (hdc, text, lstrlenW(text),
429                    &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);  
430       if (oldbkmode != TRANSPARENT)
431         SetBkMode(hdc, oldbkmode);
432     }
433 }
434
435
436 /***********************************************************************
437  * DrawStatusText  [COMCTL32.27]
438  * DrawStatusTextA [COMCTL32.5]
439  *
440  * Draws text with borders, like in a status bar.
441  *
442  * PARAMS
443  *     hdc   [I] handle to the window's display context
444  *     lprc  [I] pointer to a rectangle
445  *     text  [I] pointer to the text
446  *     style [I] drawing style
447  *
448  * RETURNS
449  *     No return value.
450  */
451
452 VOID WINAPI
453 DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
454 {
455     INT len;
456     LPWSTR textW = NULL;
457
458     if ( text ) {
459         if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
460             if ( (textW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )) )
461                 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
462         }
463     }
464     DrawStatusTextW( hdc, lprc, textW, style );
465     HeapFree( GetProcessHeap(), 0, textW );
466 }
467
468
469 /***********************************************************************
470  * CreateStatusWindow  [COMCTL32.21]
471  * CreateStatusWindowA [COMCTL32.6]
472  *
473  * Creates a status bar
474  *
475  * PARAMS
476  *     style  [I] window style
477  *     text   [I] pointer to the window text
478  *     parent [I] handle to the parent window
479  *     wid    [I] control id of the status bar
480  *
481  * RETURNS
482  *     Success: handle to the status window
483  *     Failure: 0
484  */
485
486 HWND WINAPI
487 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid)
488 {
489     return CreateWindowA(STATUSCLASSNAMEA, text, style, 
490                            CW_USEDEFAULT, CW_USEDEFAULT,
491                            CW_USEDEFAULT, CW_USEDEFAULT, 
492                            parent, wid, 0, 0);
493 }
494
495
496 /***********************************************************************
497  * CreateStatusWindowW [COMCTL32.22] Creates a status bar control
498  *
499  * PARAMS
500  *     style  [I] window style
501  *     text   [I] pointer to the window text
502  *     parent [I] handle to the parent window
503  *     wid    [I] control id of the status bar
504  *
505  * RETURNS
506  *     Success: handle to the status window
507  *     Failure: 0
508  */
509
510 HWND WINAPI
511 CreateStatusWindowW (INT style, LPCWSTR text, HWND parent, UINT wid)
512 {
513     return CreateWindowW(STATUSCLASSNAMEW, text, style,
514                            CW_USEDEFAULT, CW_USEDEFAULT,
515                            CW_USEDEFAULT, CW_USEDEFAULT,
516                            parent, wid, 0, 0);
517 }
518
519
520 /***********************************************************************
521  * CreateUpDownControl [COMCTL32.16] Creates an up-down control
522  *
523  * PARAMS
524  *     style  [I] window styles
525  *     x      [I] horizontal position of the control
526  *     y      [I] vertical position of the control
527  *     cx     [I] with of the control
528  *     cy     [I] height of the control
529  *     parent [I] handle to the parent window
530  *     id     [I] the control's identifier
531  *     inst   [I] handle to the application's module instance
532  *     buddy  [I] handle to the buddy window, can be NULL
533  *     maxVal [I] upper limit of the control
534  *     minVal [I] lower limit of the control
535  *     curVal [I] current value of the control
536  *
537  * RETURNS
538  *     Success: handle to the updown control
539  *     Failure: 0
540  */
541
542 HWND WINAPI
543 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
544                      HWND parent, INT id, HINSTANCE inst,
545                      HWND buddy, INT maxVal, INT minVal, INT curVal)
546 {
547     HWND hUD =
548         CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
549                          parent, id, inst, 0);
550     if (hUD) {
551         SendMessageA (hUD, UDM_SETBUDDY, buddy, 0);
552         SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
553         SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));     
554     }
555
556     return hUD;
557 }
558
559
560 /***********************************************************************
561  * InitCommonControls [COMCTL32.17]
562  *
563  * Registers the common controls.
564  *
565  * PARAMS
566  *     No parameters.
567  *
568  * RETURNS
569  *     No return values.
570  *
571  * NOTES
572  *     This function is just a dummy.
573  *     The Win95 controls are registered at the DLL's initialization.
574  *     To register other controls InitCommonControlsEx() must be used.
575  */
576
577 VOID WINAPI
578 InitCommonControls (void)
579 {
580 }
581
582
583 /***********************************************************************
584  * InitCommonControlsEx [COMCTL32.84]
585  *
586  * Registers the common controls.
587  *
588  * PARAMS
589  *     lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
590  *
591  * RETURNS
592  *     Success: TRUE
593  *     Failure: FALSE
594  *
595  * NOTES
596  *     Only the additional common controls are registered by this function.
597  *     The Win95 controls are registered at the DLL's initialization.
598  */
599
600 BOOL WINAPI
601 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
602 {
603     INT cCount;
604     DWORD dwMask;
605
606     if (!lpInitCtrls)
607         return FALSE;
608     if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
609         return FALSE;
610
611     TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
612
613     for (cCount = 0; cCount < 32; cCount++) {
614         dwMask = 1 << cCount;
615         if (!(lpInitCtrls->dwICC & dwMask))
616             continue;
617
618         switch (lpInitCtrls->dwICC & dwMask) {
619             /* dummy initialization */
620             case ICC_ANIMATE_CLASS:
621             case ICC_BAR_CLASSES:
622             case ICC_LISTVIEW_CLASSES:
623             case ICC_TREEVIEW_CLASSES:
624             case ICC_TAB_CLASSES:
625             case ICC_UPDOWN_CLASS:
626             case ICC_PROGRESS_CLASS:
627             case ICC_HOTKEY_CLASS:
628                 break;
629
630             /* advanced classes - not included in Win95 */
631             case ICC_DATE_CLASSES:
632                 MONTHCAL_Register ();
633                 DATETIME_Register ();
634                 break;
635
636             case ICC_USEREX_CLASSES:
637                 COMBOEX_Register ();
638                 break;
639
640             case ICC_COOL_CLASSES:
641                 REBAR_Register ();
642                 break;
643
644             case ICC_INTERNET_CLASSES:
645                 IPADDRESS_Register ();
646                 break;
647
648             case ICC_PAGESCROLLER_CLASS:
649                 PAGER_Register ();
650                 break;
651
652             case ICC_NATIVEFNTCTL_CLASS:
653                 NATIVEFONT_Register ();
654                 break;
655
656             default:
657                 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
658                 break;
659         }
660     }
661
662     return TRUE;
663 }
664
665
666 /***********************************************************************
667  * CreateToolbarEx [COMCTL32.23] Creates a tool bar window
668  *
669  * PARAMS
670  *     hwnd
671  *     style
672  *     wID
673  *     nBitmaps
674  *     hBMInst
675  *     wBMID
676  *     lpButtons
677  *     iNumButtons
678  *     dxButton
679  *     dyButton
680  *     dxBitmap
681  *     dyBitmap
682  *     uStructSize
683  *
684  * RETURNS
685  *     Success: handle to the tool bar control
686  *     Failure: 0
687  */
688
689 HWND WINAPI
690 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
691                  HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
692                  INT iNumButtons, INT dxButton, INT dyButton,
693                  INT dxBitmap, INT dyBitmap, UINT uStructSize)
694 {
695     HWND hwndTB;
696
697     /* If not position is specified then put it at the top */
698     if ((style & CCS_BOTTOM) == 0) {
699       style|=CCS_TOP;
700     }
701
702     hwndTB =
703         CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style|WS_CHILD, 0, 0, 0, 0,
704                            hwnd, (HMENU)wID, 0, NULL);
705     if(hwndTB) {
706         TBADDBITMAP tbab;
707
708         SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
709                         (WPARAM)uStructSize, 0);
710
711        /* set bitmap and button size */
712        /*If CreateToolbarEx receives 0, windows sets default values*/
713        if (dxBitmap <= 0)
714            dxBitmap = 16;
715        if (dyBitmap <= 0)
716            dyBitmap = 15;
717        SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
718                        MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
719
720        if (dxButton <= 0)
721            dxButton = 24;
722        if (dyButton <= 0)
723            dyButton = 22;
724        SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
725                        MAKELPARAM((WORD)dxButton, (WORD)dyButton));
726
727
728         /* add bitmaps */
729         if (nBitmaps > 0)
730         {
731         tbab.hInst = hBMInst;
732         tbab.nID   = wBMID;
733
734         SendMessageA (hwndTB, TB_ADDBITMAP,
735                         (WPARAM)nBitmaps, (LPARAM)&tbab);
736         }
737         /* add buttons */
738         if(iNumButtons > 0)
739         SendMessageA (hwndTB, TB_ADDBUTTONSA,
740                         (WPARAM)iNumButtons, (LPARAM)lpButtons);
741     }
742
743     return hwndTB;
744 }
745
746
747 /***********************************************************************
748  * CreateMappedBitmap [COMCTL32.8]
749  *
750  * PARAMS
751  *     hInstance  [I]
752  *     idBitmap   [I]
753  *     wFlags     [I]
754  *     lpColorMap [I]
755  *     iNumMaps   [I]
756  *
757  * RETURNS
758  *     Success: handle to the new bitmap
759  *     Failure: 0
760  */
761
762 HBITMAP WINAPI
763 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
764                     LPCOLORMAP lpColorMap, INT iNumMaps)
765 {
766     HGLOBAL hglb;
767     HRSRC hRsrc;
768     LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
769     UINT nSize, nColorTableSize;
770     RGBQUAD *pColorTable;
771     INT iColor, i, iMaps, nWidth, nHeight;
772     HDC hdcScreen;
773     HBITMAP hbm;
774     LPCOLORMAP sysColorMap;
775     COLORREF cRef;
776     COLORMAP internalColorMap[4] =
777         {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
778
779     /* initialize pointer to colortable and default color table */
780     if (lpColorMap) {
781         iMaps = iNumMaps;
782         sysColorMap = lpColorMap;
783     }
784     else {
785         internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
786         internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
787         internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
788         internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
789         iMaps = 4;
790         sysColorMap = (LPCOLORMAP)internalColorMap;
791     }
792
793     hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
794     if (hRsrc == 0)
795         return 0;
796     hglb = LoadResource (hInstance, hRsrc);
797     if (hglb == 0)
798         return 0;
799     lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
800     if (lpBitmap == NULL)
801         return 0;
802
803     nColorTableSize = (1 << lpBitmap->biBitCount);
804     nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
805     lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
806     if (lpBitmapInfo == NULL)
807         return 0;
808     RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
809
810     pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
811
812     for (iColor = 0; iColor < nColorTableSize; iColor++) {
813         for (i = 0; i < iMaps; i++) {
814             cRef = RGB(pColorTable[iColor].rgbRed,
815                        pColorTable[iColor].rgbGreen,
816                        pColorTable[iColor].rgbBlue);
817             if ( cRef  == sysColorMap[i].from) {
818 #if 0
819                 if (wFlags & CBS_MASKED) {
820                     if (sysColorMap[i].to != COLOR_BTNTEXT)
821                         pColorTable[iColor] = RGB(255, 255, 255);
822                 }
823                 else
824 #endif
825                     pColorTable[iColor].rgbBlue  = GetBValue(sysColorMap[i].to);
826                     pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
827                     pColorTable[iColor].rgbRed   = GetRValue(sysColorMap[i].to);
828                 break;
829             }
830         }
831     }
832     nWidth  = (INT)lpBitmapInfo->biWidth;
833     nHeight = (INT)lpBitmapInfo->biHeight;
834     hdcScreen = GetDC ((HWND)0);
835     hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
836     if (hbm) {
837         HDC hdcDst = CreateCompatibleDC (hdcScreen);
838         HBITMAP hbmOld = SelectObject (hdcDst, hbm);
839         LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
840         lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
841         StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
842                          lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
843                          SRCCOPY);
844         SelectObject (hdcDst, hbmOld);
845         DeleteDC (hdcDst);
846     }
847     ReleaseDC ((HWND)0, hdcScreen);
848     GlobalFree ((HGLOBAL)lpBitmapInfo);
849     FreeResource (hglb);
850
851     return hbm;
852 }
853
854
855 /***********************************************************************
856  * CreateToolbar [COMCTL32.7] Creates a tool bar control
857  *
858  * PARAMS
859  *     hwnd
860  *     style
861  *     wID
862  *     nBitmaps
863  *     hBMInst
864  *     wBMID
865  *     lpButtons
866  *     iNumButtons
867  *
868  * RETURNS
869  *     Success: handle to the tool bar control
870  *     Failure: 0
871  *
872  * NOTES
873  *     Do not use this functions anymore. Use CreateToolbarEx instead.
874  */
875
876 HWND WINAPI
877 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
878                HINSTANCE hBMInst, UINT wBMID,
879                LPCOLDTBBUTTON lpButtons,INT iNumButtons)
880 {
881     return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
882                             hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
883                             iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
884 }
885
886
887 /***********************************************************************
888  * DllGetVersion [COMCTL32.25]
889  *
890  * Retrieves version information of the 'COMCTL32.DLL'
891  *
892  * PARAMS
893  *     pdvi [O] pointer to version information structure.
894  *
895  * RETURNS
896  *     Success: S_OK
897  *     Failure: E_INVALIDARG
898  *
899  * NOTES
900  *     Returns version of a comctl32.dll from IE4.01 SP1.
901  */
902
903 HRESULT WINAPI
904 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
905 {
906     if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
907         WARN("wrong DLLVERSIONINFO size from app\n");
908         return E_INVALIDARG;
909     }
910
911     pdvi->dwMajorVersion = COMCTL32_VERSION;
912     pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
913     pdvi->dwBuildNumber = 2919;
914     pdvi->dwPlatformID = 6304;
915
916     TRACE("%lu.%lu.%lu.%lu\n",
917            pdvi->dwMajorVersion, pdvi->dwMinorVersion,
918            pdvi->dwBuildNumber, pdvi->dwPlatformID);
919
920     return S_OK;
921 }
922
923 /***********************************************************************
924  *              DllInstall (COMCTL32.26)
925  */
926 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
927 {
928   FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE", 
929         debugstr_w(cmdline));
930
931   return S_OK;
932 }
933
934 /***********************************************************************
935  * _TrackMouseEvent [COMCTL32.91]
936  *
937  * Requests notification of mouse events
938  *
939  * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
940  * to the hwnd specified in the ptme structure.  After the event message
941  * is posted to the hwnd, the entry in the queue is removed.
942  *
943  * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
944  * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
945  * immediately and the TME_LEAVE flag being ignored.
946  *
947  * PARAMS
948  *     ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
949  *
950  * RETURNS
951  *     Success: non-zero
952  *     Failure: zero
953  *
954  * IMPLEMENTATION moved to USER32.TrackMouseEvent
955  *
956  */
957
958 BOOL WINAPI
959 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
960 {
961     return TrackMouseEvent (ptme);
962 }
963
964 /*************************************************************************
965  * GetMUILanguage [COMCTL32.39]
966  *
967  * FIXME: What's this supposed to do?  Apparently some i18n thing.
968  *
969  */
970 LANGID WINAPI GetMUILanguage (VOID)
971 {
972     return COMCTL32_uiLang;
973 }
974
975
976 /*************************************************************************
977  * InitMUILanguage [COMCTL32.85]
978  *
979  * FIXME: What's this supposed to do?  Apparently some i18n thing.
980  *
981  */
982
983 VOID WINAPI InitMUILanguage (LANGID uiLang)
984 {
985    COMCTL32_uiLang = uiLang;
986 }
987
988
989 /***********************************************************************
990  * COMCTL32_CreateToolTip [NOT AN API]
991  *
992  * Creates a tooltip for the control specified in hwnd and does all
993  * necessary setup and notifications.
994  *
995  * PARAMS
996  *     hwndOwner [I] Handle to the window that will own the tool tip.
997  *
998  * RETURNS
999  *     Success: Handle of tool tip window.
1000  *     Failure: NULL
1001  */
1002 HWND
1003 COMCTL32_CreateToolTip(HWND hwndOwner)
1004 {
1005     HWND hwndToolTip;
1006
1007     hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1008                                   CW_USEDEFAULT, CW_USEDEFAULT,
1009                                   CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1010                                   0, 0, 0);
1011
1012     /* Send NM_TOOLTIPSCREATED notification */
1013     if (hwndToolTip)
1014     {
1015         NMTOOLTIPSCREATED nmttc;
1016         /* true owner can be different if hwndOwner is a child window */
1017         HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1018         nmttc.hdr.hwndFrom = hwndTrueOwner;
1019         nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID);
1020         nmttc.hdr.code = NM_TOOLTIPSCREATED;
1021         nmttc.hwndToolTips = hwndToolTip;
1022
1023        SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1024                     (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID),
1025                      (LPARAM)&nmttc);
1026     }
1027
1028     return hwndToolTip;
1029 }