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