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