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