Recovery of release 990110 after disk crash.
[wine] / dlls / comctl32 / commctrl.c
1 /*              
2  * Common controls functions
3  *
4  * Copyright 1997 Dimitrie O. Paun
5  * Copyright 1998 Eric Kohl
6  *
7  */
8
9 #include "win.h"
10 #include "heap.h"
11 #include "commctrl.h"
12 #include "animate.h"
13 #include "comboex.h"
14 #include "datetime.h"
15 #include "flatsb.h"
16 #include "header.h"
17 #include "hotkey.h"
18 #include "ipaddress.h"
19 #include "listview.h"
20 #include "monthcal.h"
21 #include "nativefont.h"
22 #include "pager.h"
23 #include "progress.h"
24 #include "propsheet.h"
25 #include "rebar.h"
26 #include "status.h"
27 #include "tab.h"
28 #include "toolbar.h"
29 #include "tooltips.h"
30 #include "trackbar.h"
31 #include "treeview.h"
32 #include "updown.h"
33 #include "winversion.h"
34 #include "debug.h"
35 #include "winerror.h"
36
37
38 HANDLE32 COMCTL32_hHeap = (HANDLE32)NULL;
39 DWORD    COMCTL32_dwProcessesAttached = 0;
40 LPSTR    COMCTL32_aSubclass = (LPSTR)NULL;
41
42
43 /***********************************************************************
44  * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
45  *
46  * PARAMS
47  *     hinstDLL    [I] handle to the 'dlls' instance
48  *     fdwReason   [I]
49  *     lpvReserved [I] reserverd, must be NULL
50  *
51  * RETURNS
52  *     Success: TRUE
53  *     Failure: FALSE
54  */
55
56 BOOL32 WINAPI
57 COMCTL32_LibMain (HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
58 {
59     TRACE (commctrl, "%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
60
61     switch (fdwReason) {
62         case DLL_PROCESS_ATTACH:
63             if (COMCTL32_dwProcessesAttached == 0) {
64                 /* create private heap */
65                 COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
66                 TRACE (commctrl, "Heap created: 0x%x\n", COMCTL32_hHeap);
67
68                 /* add global subclassing atom (used by 'tooltip' and 'updown') */
69                 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtom32A ("CC32SubclassInfo");
70                 TRACE (commctrl, "Subclassing atom added: %p\n",
71                        COMCTL32_aSubclass);
72
73                 /* register all Win95 common control classes */
74                 ANIMATE_Register ();
75                 FLATSB_Register ();
76                 HEADER_Register ();
77                 HOTKEY_Register ();
78                 LISTVIEW_Register ();
79                 PROPSHEET_Register ();
80                 PROGRESS_Register ();
81                 STATUS_Register ();
82                 TAB_Register ();
83                 TOOLBAR_Register ();
84                 TOOLTIPS_Register ();
85                 TRACKBAR_Register ();
86                 TREEVIEW_Register ();
87                 UPDOWN_Register ();
88             }
89             COMCTL32_dwProcessesAttached++;
90             break;
91
92         case DLL_PROCESS_DETACH:
93             COMCTL32_dwProcessesAttached--;
94             if (COMCTL32_dwProcessesAttached == 0) {
95                 /* unregister all common control classes */
96                 ANIMATE_Unregister ();
97                 COMBOEX_Unregister ();
98                 DATETIME_Unregister ();
99                 FLATSB_Unregister ();
100                 HEADER_Unregister ();
101                 HOTKEY_Unregister ();
102                 IPADDRESS_Unregister ();
103                 LISTVIEW_Unregister ();
104                 MONTHCAL_Unregister ();
105                 NATIVEFONT_Unregister ();
106                 PAGER_Unregister ();
107                 PROPSHEET_UnRegister ();
108                 PROGRESS_Unregister ();
109                 REBAR_Unregister ();
110                 STATUS_Unregister ();
111                 TAB_Unregister ();
112                 TOOLBAR_Unregister ();
113                 TOOLTIPS_Unregister ();
114                 TRACKBAR_Unregister ();
115                 TREEVIEW_Unregister ();
116                 UPDOWN_Unregister ();
117
118                 /* delete global subclassing atom */
119                 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
120                 TRACE (commctrl, "Subclassing atom deleted: %p\n",
121                        COMCTL32_aSubclass);
122                 COMCTL32_aSubclass = (LPSTR)NULL;
123
124                 /* destroy private heap */
125                 HeapDestroy (COMCTL32_hHeap);
126                 TRACE (commctrl, "Heap destroyed: 0x%x\n", COMCTL32_hHeap);
127                 COMCTL32_hHeap = (HANDLE32)NULL;
128             }
129             break;
130     }
131
132     return TRUE;
133 }
134
135
136 /***********************************************************************
137  * MenuHelp [COMCTL32.2]
138  *
139  * PARAMS
140  *     uMsg       [I]
141  *     wParam     [I]
142  *     lParam     [I]
143  *     hMainMenu  [I] handle to the applications main menu
144  *     hInst      [I]
145  *     hwndStatus [I] handle to the status bar window
146  *     lpwIDs     [I] pointer to an array of intergers (see NOTES)
147  *
148  * RETURNS
149  *     No return value
150  *
151  * NOTES
152  *     The official documentation is incomplete!
153  */
154
155 VOID WINAPI
156 MenuHelp (UINT32 uMsg, WPARAM32 wParam, LPARAM lParam, HMENU32 hMainMenu,
157           HINSTANCE32 hInst, HWND32 hwndStatus, LPUINT32 lpwIDs)
158 {
159     UINT32 uMenuID = 0;
160
161     if (!IsWindow32 (hwndStatus))
162         return;
163
164     switch (uMsg) {
165         case WM_MENUSELECT:
166             TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
167                    wParam, lParam);
168
169             if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
170                 /* menu was closed */
171                 TRACE (commctrl, "menu was closed!\n");
172                 SendMessage32A (hwndStatus, SB_SIMPLE, FALSE, 0);
173             }
174             else {
175                 /* menu item was selected */
176                 if (HIWORD(wParam) & MF_POPUP)
177                     uMenuID = (UINT32)*(lpwIDs+1);
178                 else
179                     uMenuID = (UINT32)LOWORD(wParam);
180                 TRACE (commctrl, "uMenuID = %u\n", uMenuID);
181
182                 if (uMenuID) {
183                     CHAR szText[256];
184
185                     if (!LoadString32A (hInst, uMenuID, szText, 256))
186                         szText[0] = '\0';
187
188                     SendMessage32A (hwndStatus, SB_SETTEXT32A,
189                                     255 | SBT_NOBORDERS, (LPARAM)szText);
190                     SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0);
191                 }
192             }
193             break;
194
195         default:
196             FIXME (commctrl, "Invalid Message 0x%x!\n", uMsg);
197             break;
198     }
199 }
200
201
202 /***********************************************************************
203  * ShowHideMenuCtl [COMCTL32.3] 
204  *
205  * Shows or hides controls and updates the corresponding menu item.
206  *
207  * PARAMS
208  *     hwnd   [I] handle to the client window.
209  *     uFlags [I] menu command id.
210  *     lpInfo [I] pointer to an array of integers. (See NOTES.)
211  *
212  * RETURNS
213  *     Success: TRUE
214  *     Failure: FALSE
215  *
216  * NOTES
217  *     The official documentation is incomplete! This has been fixed.
218  *
219  *     lpInfo
220  *     The array of integers contains pairs of values. BOTH values of
221  *     the first pair must be the handles to application's main menu.
222  *     Each subsequent pair consists of a menu id and control id.
223  */
224
225 BOOL32 WINAPI
226 ShowHideMenuCtl (HWND32 hwnd, UINT32 uFlags, LPINT32 lpInfo)
227 {
228     LPINT32 lpMenuId;
229
230     TRACE (commctrl, "%x, %x, %p\n", hwnd, uFlags, lpInfo);
231
232     if (lpInfo == NULL)
233         return FALSE;
234
235     if (!(lpInfo[0]) || !(lpInfo[1]))
236         return FALSE;
237
238     /* search for control */
239     lpMenuId = &lpInfo[2];
240     while (*lpMenuId != uFlags)
241         lpMenuId += 2;
242
243     if (GetMenuState32 (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
244         /* uncheck menu item */
245         CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
246
247         /* hide control */
248         lpMenuId++;
249         SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
250                         SWP_HIDEWINDOW);
251     }
252     else {
253         /* check menu item */
254         CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
255
256         /* show control */
257         lpMenuId++;
258         SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
259                         SWP_SHOWWINDOW);
260     }
261
262     return TRUE;
263 }
264
265
266 /***********************************************************************
267  * GetEffectiveClientRect [COMCTL32.4]
268  *
269  * PARAMS
270  *     hwnd   [I] handle to the client window.
271  *     lpRect [O] pointer to the rectangle of the client window
272  *     lpInfo [I] pointer to an array of integers
273  *
274  * RETURNS
275  *     No return value.
276  *
277  * NOTES
278  *     The official documentation is incomplete!
279  */
280
281 VOID WINAPI
282 GetEffectiveClientRect (HWND32 hwnd, LPRECT32 lpRect, LPINT32 lpInfo)
283 {
284     RECT32 rcCtrl;
285     INT32  *lpRun;
286     HWND32 hwndCtrl;
287
288     TRACE (commctrl, "(0x%08lx 0x%08lx 0x%08lx)\n",
289            (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
290
291     GetClientRect32 (hwnd, lpRect);
292     lpRun = lpInfo;
293
294     do {
295         lpRun += 2;
296         if (*lpRun == 0)
297             return;
298         lpRun++;
299         hwndCtrl = GetDlgItem32 (hwnd, *lpRun);
300         if (GetWindowLong32A (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
301             TRACE (commctrl, "control id 0x%x\n", *lpRun);
302             GetWindowRect32 (hwndCtrl, &rcCtrl);
303             MapWindowPoints32 ((HWND32)0, hwnd, (LPPOINT32)&rcCtrl, 2);
304             SubtractRect32 (lpRect, lpRect, &rcCtrl);
305         }
306         lpRun++;
307     } while (*lpRun);
308 }
309
310
311 /***********************************************************************
312  * DrawStatusText32A [COMCTL32.5]
313  *
314  * Draws text with borders, like in a status bar.
315  *
316  * PARAMS
317  *     hdc   [I] handle to the window's display context
318  *     lprc  [I] pointer to a rectangle
319  *     text  [I] pointer to the text
320  *     style [I]
321  *
322  * RETURNS
323  *     No return value.
324  */
325
326 VOID WINAPI
327 DrawStatusText32A (HDC32 hdc, LPRECT32 lprc, LPCSTR text, UINT32 style)
328 {
329     RECT32 r = *lprc;
330     UINT32 border = BDR_SUNKENOUTER;
331
332     if (style == SBT_POPOUT)
333       border = BDR_RAISEDOUTER;
334     else if (style == SBT_NOBORDERS)
335       border = 0;
336
337     DrawEdge32 (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
338
339     /* now draw text */
340     if (text) {
341       int oldbkmode = SetBkMode32 (hdc, TRANSPARENT);
342       r.left += 3;
343       DrawText32A (hdc, text, lstrlen32A(text),
344                    &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);  
345       if (oldbkmode != TRANSPARENT)
346         SetBkMode32(hdc, oldbkmode);
347     }
348 }
349
350
351 /***********************************************************************
352  * DrawStatusText32W [COMCTL32.28]
353  *
354  * Draws text with borders, like in a status bar.
355  *
356  * PARAMS
357  *     hdc   [I] handle to the window's display context
358  *     lprc  [I] pointer to a rectangle
359  *     text  [I] pointer to the text
360  *     style [I]
361  *
362  * RETURNS
363  *     No return value.
364  */
365
366 VOID WINAPI
367 DrawStatusText32W (HDC32 hdc, LPRECT32 lprc, LPCWSTR text, UINT32 style)
368 {
369     LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
370     DrawStatusText32A (hdc, lprc, p, style);
371     HeapFree (GetProcessHeap (), 0, p );
372 }
373
374
375 /***********************************************************************
376  * DrawStatusText32AW [COMCTL32.27]
377  *
378  * Draws text with borders, like in a status bar.
379  *
380  * PARAMS
381  *     hdc   [I] handle to the window's display context
382  *     lprc  [I] pointer to a rectangle
383  *     text  [I] pointer to the text
384  *     style [I]
385  *
386  * RETURNS
387  *     No return value.
388  *
389  * NOTES
390  *     Calls DrawStatusText32A() or DrawStatusText32W().
391  */
392
393 VOID WINAPI
394 DrawStatusText32AW (HDC32 hdc, LPRECT32 lprc, LPVOID text, UINT32 style)
395 {
396     if (VERSION_OsIsUnicode())
397         DrawStatusText32W (hdc, lprc, (LPCWSTR)text, style);
398     DrawStatusText32A (hdc, lprc, (LPCSTR)text, style);
399 }
400
401
402 /***********************************************************************
403  * CreateStatusWindow32A [COMCTL32.6]
404  *
405  * Creates a status bar
406  *
407  * PARAMS
408  *     style  [I]
409  *     text   [I]
410  *     parent [I] handle to the parent window
411  *     wid    [I] control id of the status bar
412  *
413  * RETURNS
414  *     Success: handle to the control
415  *     Failure: 0
416  */
417
418 HWND32 WINAPI
419 CreateStatusWindow32A (INT32 style, LPCSTR text, HWND32 parent, UINT32 wid)
420 {
421     return CreateWindow32A(STATUSCLASSNAME32A, text, style, 
422                            CW_USEDEFAULT32, CW_USEDEFAULT32,
423                            CW_USEDEFAULT32, CW_USEDEFAULT32, 
424                            parent, wid, 0, 0);
425 }
426
427
428 /***********************************************************************
429  * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
430  *
431  * PARAMS
432  *     style  [I]
433  *     text   [I]
434  *     parent [I] handle to the parent window
435  *     wid    [I] control id of the status bar
436  *
437  * RETURNS
438  *     Success: handle to the control
439  *     Failure: 0
440  */
441
442 HWND32 WINAPI
443 CreateStatusWindow32W (INT32 style, LPCWSTR text, HWND32 parent, UINT32 wid)
444 {
445     return CreateWindow32W(STATUSCLASSNAME32W, text, style,
446                            CW_USEDEFAULT32, CW_USEDEFAULT32,
447                            CW_USEDEFAULT32, CW_USEDEFAULT32,
448                            parent, wid, 0, 0);
449 }
450
451
452 /***********************************************************************
453  * CreateStatusWindow32AW [COMCTL32.21] Creates a status bar control
454  *
455  * PARAMS
456  *     style  [I]
457  *     text   [I]
458  *     parent [I] handle to the parent window
459  *     wid    [I] control id of the status bar
460  *
461  * RETURNS
462  *     Success: handle to the control
463  *     Failure: 0
464  */
465
466 HWND32 WINAPI
467 CreateStatusWindow32AW (INT32 style, LPVOID text, HWND32 parent, UINT32 wid)
468 {
469     if (VERSION_OsIsUnicode())
470         return CreateStatusWindow32W (style, (LPCWSTR)text, parent, wid);
471     return CreateStatusWindow32A (style, (LPCSTR)text, parent, wid);
472 }
473
474
475 /***********************************************************************
476  * CreateUpDownControl [COMCTL32.16] Creates an Up-Down control
477  *
478  * PARAMS
479  *     style
480  *     x
481  *     y
482  *     cx
483  *     cy
484  *     parent
485  *     id
486  *     inst
487  *     buddy
488  *     maxVal [I]
489  *     minVal [I]
490  *     curVal [I]
491  *
492  * RETURNS
493  *     Success: handle to the control
494  *     Failure: 0
495  */
496
497 HWND32 WINAPI
498 CreateUpDownControl (DWORD style, INT32 x, INT32 y, INT32 cx, INT32 cy,
499                      HWND32 parent, INT32 id, HINSTANCE32 inst,
500                      HWND32 buddy, INT32 maxVal, INT32 minVal, INT32 curVal)
501 {
502     HWND32 hUD =
503         CreateWindow32A (UPDOWN_CLASS32A, 0, style, x, y, cx, cy,
504                          parent, id, inst, 0);
505     if (hUD) {
506         SendMessage32A (hUD, UDM_SETBUDDY, buddy, 0);
507         SendMessage32A (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
508         SendMessage32A (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));     
509     }
510
511     return hUD;
512 }
513
514
515 /***********************************************************************
516  * InitCommonControls [COMCTL32.17]
517  *
518  * Registers the common controls.
519  *
520  * PARAMS
521  *     No parameters.
522  *
523  * RETURNS
524  *     No return values.
525  *
526  * NOTES
527  *     This function is just a dummy.
528  *     The Win95 controls are registered at the DLL's initialization.
529  *     To register other controls InitCommonControlsEx must be used.
530  */
531
532 VOID WINAPI
533 InitCommonControls (VOID)
534 {
535 }
536
537
538 /***********************************************************************
539  * InitCommonControlsEx [COMCTL32.81]
540  *
541  * Registers the common controls.
542  *
543  * PARAMS
544  *     lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
545  *
546  * RETURNS
547  *     Success: TRUE
548  *     Failure: FALSE
549  *
550  * NOTES
551  *     Only the additinal common controls are registered by this function.
552  *     The Win95 controls are registered at the DLL's initialization.
553  */
554
555 BOOL32 WINAPI
556 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
557 {
558     INT32 cCount;
559     DWORD dwMask;
560
561     if (!lpInitCtrls)
562         return FALSE;
563     if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
564         return FALSE;
565
566     TRACE(commctrl,"(0x%08lx)\n", lpInitCtrls->dwICC);
567
568     for (cCount = 0; cCount < 32; cCount++) {
569         dwMask = 1 << cCount;
570         if (!(lpInitCtrls->dwICC & dwMask))
571             continue;
572
573         switch (lpInitCtrls->dwICC & dwMask) {
574             /* dummy initialization */
575             case ICC_ANIMATE_CLASS:
576             case ICC_BAR_CLASSES:
577             case ICC_LISTVIEW_CLASSES:
578             case ICC_TREEVIEW_CLASSES:
579             case ICC_TAB_CLASSES:
580             case ICC_UPDOWN_CLASS:
581             case ICC_PROGRESS_CLASS:
582             case ICC_HOTKEY_CLASS:
583                 break;
584
585             /* advanced classes - not included in Win95 */
586             case ICC_DATE_CLASSES:
587                 MONTHCAL_Register ();
588                 DATETIME_Register ();
589                 break;
590
591             case ICC_USEREX_CLASSES:
592                 COMBOEX_Register ();
593                 break;
594
595             case ICC_COOL_CLASSES:
596                 REBAR_Register ();
597                 break;
598
599             case ICC_INTERNET_CLASSES:
600                 IPADDRESS_Register ();
601                 break;
602
603             case ICC_PAGESCROLLER_CLASS:
604                 PAGER_Register ();
605                 break;
606
607             case ICC_NATIVEFNTCTL_CLASS:
608                 NATIVEFONT_Register ();
609                 break;
610
611             default:
612                 FIXME (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask);
613                 break;
614         }
615     }
616
617     return TRUE;
618 }
619
620
621 /***********************************************************************
622  * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
623  *
624  * PARAMS
625  *     hwnd
626  *     style
627  *     wID
628  *     nBitmaps
629  *     hBMInst
630  *     wBMID
631  *     lpButtons
632  *     iNumButtons
633  *     dxButton
634  *     dyButton
635  *     dxBitmap
636  *     dyBitmap
637  *     uStructSize
638  *
639  * RETURNS
640  *     Success: handle to the tool bar control
641  *     Failure: 0
642  */
643
644 HWND32 WINAPI
645 CreateToolbarEx (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
646                  HINSTANCE32 hBMInst, UINT32 wBMID, LPCTBBUTTON lpButtons,
647                  INT32 iNumButtons, INT32 dxButton, INT32 dyButton,
648                  INT32 dxBitmap, INT32 dyBitmap, UINT32 uStructSize)
649 {
650     HWND32 hwndTB =
651         CreateWindowEx32A (0, TOOLBARCLASSNAME32A, "", style, 0, 0, 0, 0,
652                            hwnd, (HMENU32)wID, 0, NULL);
653     if(hwndTB) {
654         TBADDBITMAP tbab;
655
656         SendMessage32A (hwndTB, TB_BUTTONSTRUCTSIZE,
657                         (WPARAM32)uStructSize, 0);
658
659         /* set bitmap and button size */
660         if (hBMInst == HINST_COMMCTRL) {
661             if (wBMID & 1) {
662                 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
663                                 MAKELPARAM(26, 25));
664                 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
665                                 MAKELPARAM(33, 32));
666             }
667             else {
668                 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
669                                 MAKELPARAM(16, 15));
670                 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
671                                 MAKELPARAM(23, 22));
672             }
673         }
674         else {
675             SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
676                             MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
677             SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
678                             MAKELPARAM((WORD)dyButton, (WORD)dxButton));
679         }
680
681         /* add bitmaps */
682         tbab.hInst = hBMInst;
683         tbab.nID   = wBMID;
684         SendMessage32A (hwndTB, TB_ADDBITMAP,
685                         (WPARAM32)nBitmaps, (LPARAM)&tbab);
686
687         /* add buttons */
688         SendMessage32A (hwndTB, TB_ADDBUTTONS32A,
689                         (WPARAM32)iNumButtons, (LPARAM)lpButtons);
690     }
691
692     return hwndTB;
693 }
694
695
696 /***********************************************************************
697  * CreateMappedBitmap [COMCTL32.8]
698  *
699  * PARAMS
700  *     hInstance
701  *     idBitmap
702  *     wFlags
703  *     lpColorMap
704  *     iNumMaps
705  *
706  * RETURNS
707  *     Success: bitmap handle
708  *     Failure: 0
709  */
710
711 HBITMAP32 WINAPI
712 CreateMappedBitmap (HINSTANCE32 hInstance, INT32 idBitmap, UINT32 wFlags,
713                     LPCOLORMAP lpColorMap, INT32 iNumMaps)
714 {
715     HGLOBAL32 hglb;
716     HRSRC32 hRsrc;
717     LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
718     UINT32 nSize, nColorTableSize;
719     DWORD *pColorTable;
720     INT32 iColor, i, iMaps, nWidth, nHeight;
721     HDC32 hdcScreen;
722     HBITMAP32 hbm;
723     LPCOLORMAP sysColorMap;
724     COLORMAP internalColorMap[4] =
725         {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
726
727     /* initialize pointer to colortable and default color table */
728     if (lpColorMap) {
729         iMaps = iNumMaps;
730         sysColorMap = lpColorMap;
731     }
732     else {
733         internalColorMap[0].to = GetSysColor32 (COLOR_BTNTEXT);
734         internalColorMap[1].to = GetSysColor32 (COLOR_BTNSHADOW);
735         internalColorMap[2].to = GetSysColor32 (COLOR_BTNFACE);
736         internalColorMap[3].to = GetSysColor32 (COLOR_BTNHIGHLIGHT);
737         iMaps = 4;
738         sysColorMap = (LPCOLORMAP)internalColorMap;
739     }
740
741     hRsrc = FindResource32A (hInstance, (LPSTR)idBitmap, RT_BITMAP32A);
742     if (hRsrc == 0)
743         return 0;
744     hglb = LoadResource32 (hInstance, hRsrc);
745     if (hglb == 0)
746         return 0;
747     lpBitmap = (LPBITMAPINFOHEADER)LockResource32 (hglb);
748     if (lpBitmap == NULL)
749         return 0;
750
751     nColorTableSize = (1 << lpBitmap->biBitCount);
752     nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
753     lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc32 (GMEM_FIXED, nSize);
754     if (lpBitmapInfo == NULL)
755         return 0;
756     RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
757
758     pColorTable = (DWORD*)(((LPBYTE)lpBitmapInfo)+(UINT32)lpBitmapInfo->biSize);
759
760     for (iColor = 0; iColor < nColorTableSize; iColor++) {
761         for (i = 0; i < iMaps; i++) {
762             if (pColorTable[iColor] == sysColorMap[i].from) {
763 #if 0
764                 if (wFlags & CBS_MASKED) {
765                     if (sysColorMap[i].to != COLOR_BTNTEXT)
766                         pColorTable[iColor] = RGB(255, 255, 255);
767                 }
768                 else
769 #endif
770                     pColorTable[iColor] = sysColorMap[i].to;
771                 break;
772             }
773         }
774     }
775
776     nWidth  = (INT32)lpBitmapInfo->biWidth;
777     nHeight = (INT32)lpBitmapInfo->biHeight;
778     hdcScreen = GetDC32 ((HWND32)0);
779     hbm = CreateCompatibleBitmap32 (hdcScreen, nWidth, nHeight);
780     if (hbm) {
781         HDC32 hdcDst = CreateCompatibleDC32 (hdcScreen);
782         HBITMAP32 hbmOld = SelectObject32 (hdcDst, hbm);
783         LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
784         lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
785         StretchDIBits32 (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
786                          lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
787                          SRCCOPY);
788         SelectObject32 (hdcDst, hbmOld);
789         DeleteDC32 (hdcDst);
790     }
791     ReleaseDC32 ((HWND32)0, hdcScreen);
792     GlobalFree32 ((HGLOBAL32)lpBitmapInfo);
793     FreeResource32 (hglb);
794
795     return hbm;
796 }
797
798
799 /***********************************************************************
800  * CreateToolbar [COMCTL32.7] Creates a tool bar control
801  *
802  * PARAMS
803  *     hwnd
804  *     style
805  *     wID
806  *     nBitmaps
807  *     hBMInst
808  *     wBMID
809  *     lpButtons
810  *     iNumButtons
811  *
812  * RETURNS
813  *     Success: handle to the tool bar control
814  *     Failure: 0
815  *
816  * NOTES
817  *     Do not use this functions anymore. Use CreateToolbarEx instead.
818  */
819
820 HWND32 WINAPI
821 CreateToolbar (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
822                HINSTANCE32 hBMInst, UINT32 wBMID,
823                LPCOLDTBBUTTON lpButtons,INT32 iNumButtons)
824 {
825     return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
826                             hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
827                             iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
828 }
829
830
831 /***********************************************************************
832  * DllGetVersion [COMCTL32.25]
833  *
834  * Retrieves version information of the 'COMCTL32.DLL'
835  *
836  * PARAMS
837  *     pdvi [O] pointer to version information structure.
838  *
839  * RETURNS
840  *     Success: S_OK
841  *     Failure: E_INVALIDARG
842  *
843  * NOTES
844  *     Returns version of a comctl32.dll from IE4.01 SP1.
845  */
846
847 HRESULT WINAPI
848 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
849 {
850     if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
851         WARN (commctrl, "wrong DLLVERSIONINFO size from app");
852         return E_INVALIDARG;
853     }
854
855     pdvi->dwMajorVersion = 4;
856     pdvi->dwMinorVersion = 72;
857     pdvi->dwBuildNumber = 3110;
858     pdvi->dwPlatformID = 1;
859
860     TRACE (commctrl, "%lu.%lu.%lu.%lu\n",
861            pdvi->dwMajorVersion, pdvi->dwMinorVersion,
862            pdvi->dwBuildNumber, pdvi->dwPlatformID);
863
864     return S_OK;
865 }