Documentation ordinal fixes.
[wine/dcerpc.git] / dlls / comctl32 / commctrl.c
blob31be5e5b24dca08f0030c6df597da26841df6091
1 /*
2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998,2000 Eric Kohl
7 */
9 #include <string.h>
11 #include "winbase.h"
12 #include "heap.h"
13 #include "commctrl.h"
14 #include "debugtools.h"
15 #include "winerror.h"
16 #include "shlwapi.h"
17 #include "comctl32.h"
19 DEFAULT_DEBUG_CHANNEL(commctrl);
21 extern void ANIMATE_Register(void);
22 extern void ANIMATE_Unregister(void);
23 extern void COMBOEX_Register(void);
24 extern void COMBOEX_Unregister(void);
25 extern void DATETIME_Register(void);
26 extern void DATETIME_Unregister(void);
27 extern void FLATSB_Register(void);
28 extern void FLATSB_Unregister(void);
29 extern void HEADER_Register(void);
30 extern void HEADER_Unregister(void);
31 extern void HOTKEY_Register(void);
32 extern void HOTKEY_Unregister(void);
33 extern void IPADDRESS_Register(void);
34 extern void IPADDRESS_Unregister(void);
35 extern void LISTVIEW_Register(void);
36 extern void LISTVIEW_Unregister(void);
37 extern void MONTHCAL_Register(void);
38 extern void MONTHCAL_Unregister(void);
39 extern void NATIVEFONT_Register(void);
40 extern void NATIVEFONT_Unregister(void);
41 extern void PAGER_Register(void);
42 extern void PAGER_Unregister(void);
43 extern void PROGRESS_Register(void);
44 extern void PROGRESS_Unregister(void);
45 extern void REBAR_Register(void);
46 extern void REBAR_Unregister(void);
47 extern void STATUS_Register(void);
48 extern void STATUS_Unregister(void);
49 extern void TAB_Register(void);
50 extern void TAB_Unregister(void);
51 extern void TOOLBAR_Register(void);
52 extern void TOOLBAR_Unregister(void);
53 extern void TOOLTIPS_Register(void);
54 extern void TOOLTIPS_Unregister(void);
55 extern void TRACKBAR_Register(void);
56 extern void TRACKBAR_Unregister(void);
57 extern void TREEVIEW_Register(void);
58 extern void TREEVIEW_Unregister(void);
59 extern void UPDOWN_Register(void);
60 extern void UPDOWN_Unregister(void);
63 HANDLE COMCTL32_hHeap = (HANDLE)NULL;
64 LPSTR COMCTL32_aSubclass = (LPSTR)NULL;
65 HMODULE COMCTL32_hModule = 0;
66 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
67 HBRUSH COMCTL32_hPattern55AABrush = (HANDLE)NULL;
69 static HBITMAP COMCTL32_hPattern55AABitmap = (HANDLE)NULL;
71 static const WORD wPattern55AA[] =
73 0x5555, 0xaaaa, 0x5555, 0xaaaa,
74 0x5555, 0xaaaa, 0x5555, 0xaaaa
78 /***********************************************************************
79 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
81 * PARAMS
82 * hinstDLL [I] handle to the 'dlls' instance
83 * fdwReason [I]
84 * lpvReserved [I] reserverd, must be NULL
86 * RETURNS
87 * Success: TRUE
88 * Failure: FALSE
91 BOOL WINAPI
92 COMCTL32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
94 TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
96 switch (fdwReason) {
97 case DLL_PROCESS_ATTACH:
98 COMCTL32_hModule = (HMODULE)hinstDLL;
100 /* create private heap */
101 COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
102 TRACE("Heap created: 0x%x\n", COMCTL32_hHeap);
104 /* add global subclassing atom (used by 'tooltip' and 'updown') */
105 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
106 TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
108 /* create local pattern brush */
109 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
110 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
112 /* register all Win95 common control classes */
113 ANIMATE_Register ();
114 FLATSB_Register ();
115 HEADER_Register ();
116 HOTKEY_Register ();
117 LISTVIEW_Register ();
118 PROGRESS_Register ();
119 STATUS_Register ();
120 TAB_Register ();
121 TOOLBAR_Register ();
122 TOOLTIPS_Register ();
123 TRACKBAR_Register ();
124 TREEVIEW_Register ();
125 UPDOWN_Register ();
126 break;
128 case DLL_PROCESS_DETACH:
129 /* unregister all common control classes */
130 ANIMATE_Unregister ();
131 COMBOEX_Unregister ();
132 DATETIME_Unregister ();
133 FLATSB_Unregister ();
134 HEADER_Unregister ();
135 HOTKEY_Unregister ();
136 IPADDRESS_Unregister ();
137 LISTVIEW_Unregister ();
138 MONTHCAL_Unregister ();
139 NATIVEFONT_Unregister ();
140 PAGER_Unregister ();
141 PROGRESS_Unregister ();
142 REBAR_Unregister ();
143 STATUS_Unregister ();
144 TAB_Unregister ();
145 TOOLBAR_Unregister ();
146 TOOLTIPS_Unregister ();
147 TRACKBAR_Unregister ();
148 TREEVIEW_Unregister ();
149 UPDOWN_Unregister ();
151 /* delete local pattern brush */
152 DeleteObject (COMCTL32_hPattern55AABrush);
153 COMCTL32_hPattern55AABrush = (HANDLE)NULL;
154 DeleteObject (COMCTL32_hPattern55AABitmap);
155 COMCTL32_hPattern55AABitmap = (HANDLE)NULL;
157 /* delete global subclassing atom */
158 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
159 TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
160 COMCTL32_aSubclass = (LPSTR)NULL;
162 /* destroy private heap */
163 HeapDestroy (COMCTL32_hHeap);
164 TRACE("Heap destroyed: 0x%x\n", COMCTL32_hHeap);
165 COMCTL32_hHeap = (HANDLE)NULL;
166 break;
169 return TRUE;
173 /***********************************************************************
174 * MenuHelp [COMCTL32.2]
176 * PARAMS
177 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
178 * wParam [I] wParam of the message uMsg
179 * lParam [I] lParam of the message uMsg
180 * hMainMenu [I] handle to the application's main menu
181 * hInst [I] handle to the module that contains string resources
182 * hwndStatus [I] handle to the status bar window
183 * lpwIDs [I] pointer to an array of integers (see NOTES)
185 * RETURNS
186 * No return value
188 * NOTES
189 * The official documentation is incomplete!
190 * This is the correct documentation:
192 * uMsg:
193 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
194 * WM_MENUSELECT messages.
196 * lpwIDs:
197 * (will be written ...)
200 VOID WINAPI
201 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
202 HINSTANCE hInst, HWND hwndStatus, LPUINT lpwIDs)
204 UINT uMenuID = 0;
206 if (!IsWindow (hwndStatus))
207 return;
209 switch (uMsg) {
210 case WM_MENUSELECT:
211 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
212 wParam, lParam);
214 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
215 /* menu was closed */
216 TRACE("menu was closed!\n");
217 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
219 else {
220 /* menu item was selected */
221 if (HIWORD(wParam) & MF_POPUP)
222 uMenuID = (UINT)*(lpwIDs+1);
223 else
224 uMenuID = (UINT)LOWORD(wParam);
225 TRACE("uMenuID = %u\n", uMenuID);
227 if (uMenuID) {
228 CHAR szText[256];
230 if (!LoadStringA (hInst, uMenuID, szText, 256))
231 szText[0] = '\0';
233 SendMessageA (hwndStatus, SB_SETTEXTA,
234 255 | SBT_NOBORDERS, (LPARAM)szText);
235 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
238 break;
240 case WM_COMMAND :
241 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
242 wParam, lParam);
243 /* WM_COMMAND is not invalid since it is documented
244 * in the windows api reference. So don't output
245 * any FIXME for WM_COMMAND
247 WARN("We don't care about the WM_COMMAND\n");
248 break;
250 default:
251 FIXME("Invalid Message 0x%x!\n", uMsg);
252 break;
257 /***********************************************************************
258 * ShowHideMenuCtl [COMCTL32.3]
260 * Shows or hides controls and updates the corresponding menu item.
262 * PARAMS
263 * hwnd [I] handle to the client window.
264 * uFlags [I] menu command id.
265 * lpInfo [I] pointer to an array of integers. (See NOTES.)
267 * RETURNS
268 * Success: TRUE
269 * Failure: FALSE
271 * NOTES
272 * The official documentation is incomplete!
273 * This is the correct documentation:
275 * hwnd
276 * Handle to the window that contains the menu and controls.
278 * uFlags
279 * Identifier of the menu item to receive or loose a check mark.
281 * lpInfo
282 * The array of integers contains pairs of values. BOTH values of
283 * the first pair must be the handles to the application's main menu.
284 * Each subsequent pair consists of a menu id and control id.
287 BOOL WINAPI
288 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
290 LPINT lpMenuId;
292 TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
294 if (lpInfo == NULL)
295 return FALSE;
297 if (!(lpInfo[0]) || !(lpInfo[1]))
298 return FALSE;
300 /* search for control */
301 lpMenuId = &lpInfo[2];
302 while (*lpMenuId != uFlags)
303 lpMenuId += 2;
305 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
306 /* uncheck menu item */
307 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
309 /* hide control */
310 lpMenuId++;
311 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
312 SWP_HIDEWINDOW);
314 else {
315 /* check menu item */
316 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
318 /* show control */
319 lpMenuId++;
320 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
321 SWP_SHOWWINDOW);
324 return TRUE;
328 /***********************************************************************
329 * GetEffectiveClientRect [COMCTL32.4]
331 * PARAMS
332 * hwnd [I] handle to the client window.
333 * lpRect [O] pointer to the rectangle of the client window
334 * lpInfo [I] pointer to an array of integers (see NOTES)
336 * RETURNS
337 * No return value.
339 * NOTES
340 * The official documentation is incomplete!
341 * This is the correct documentation:
343 * lpInfo
344 * (will be written...)
347 VOID WINAPI
348 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
350 RECT rcCtrl;
351 INT *lpRun;
352 HWND hwndCtrl;
354 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
355 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
357 GetClientRect (hwnd, lpRect);
358 lpRun = lpInfo;
360 do {
361 lpRun += 2;
362 if (*lpRun == 0)
363 return;
364 lpRun++;
365 hwndCtrl = GetDlgItem (hwnd, *lpRun);
366 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
367 TRACE("control id 0x%x\n", *lpRun);
368 GetWindowRect (hwndCtrl, &rcCtrl);
369 MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2);
370 SubtractRect (lpRect, lpRect, &rcCtrl);
372 lpRun++;
373 } while (*lpRun);
377 /***********************************************************************
378 * DrawStatusText [COMCTL32.27]
379 * DrawStatusTextA [COMCTL32.5]
381 * Draws text with borders, like in a status bar.
383 * PARAMS
384 * hdc [I] handle to the window's display context
385 * lprc [I] pointer to a rectangle
386 * text [I] pointer to the text
387 * style [I] drawing style
389 * RETURNS
390 * No return value.
392 * NOTES
393 * The style variable can have one of the following values:
394 * (will be written ...)
397 VOID WINAPI
398 DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
400 RECT r = *lprc;
401 UINT border = BDR_SUNKENOUTER;
403 if (style & SBT_POPOUT)
404 border = BDR_RAISEDOUTER;
405 else if (style & SBT_NOBORDERS)
406 border = 0;
408 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
410 /* now draw text */
411 if (text) {
412 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
413 r.left += 3;
414 DrawTextA (hdc, text, lstrlenA(text),
415 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
416 if (oldbkmode != TRANSPARENT)
417 SetBkMode(hdc, oldbkmode);
422 /***********************************************************************
423 * DrawStatusTextW [COMCTL32.28]
425 * Draws text with borders, like in a status bar.
427 * PARAMS
428 * hdc [I] handle to the window's display context
429 * lprc [I] pointer to a rectangle
430 * text [I] pointer to the text
431 * style [I] drawing style
433 * RETURNS
434 * No return value.
437 VOID WINAPI
438 DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
440 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
441 DrawStatusTextA (hdc, lprc, p, style);
442 HeapFree (GetProcessHeap (), 0, p );
446 /***********************************************************************
447 * CreateStatusWindow [COMCTL32.21]
448 * CreateStatusWindowA [COMCTL32.6]
450 * Creates a status bar
452 * PARAMS
453 * style [I] window style
454 * text [I] pointer to the window text
455 * parent [I] handle to the parent window
456 * wid [I] control id of the status bar
458 * RETURNS
459 * Success: handle to the status window
460 * Failure: 0
463 HWND WINAPI
464 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid)
466 return CreateWindowA(STATUSCLASSNAMEA, text, style,
467 CW_USEDEFAULT, CW_USEDEFAULT,
468 CW_USEDEFAULT, CW_USEDEFAULT,
469 parent, wid, 0, 0);
473 /***********************************************************************
474 * CreateStatusWindowW [COMCTL32.22] Creates a status bar control
476 * PARAMS
477 * style [I] window style
478 * text [I] pointer to the window text
479 * parent [I] handle to the parent window
480 * wid [I] control id of the status bar
482 * RETURNS
483 * Success: handle to the status window
484 * Failure: 0
487 HWND WINAPI
488 CreateStatusWindowW (INT style, LPCWSTR text, HWND parent, UINT wid)
490 return CreateWindowW(STATUSCLASSNAMEW, text, style,
491 CW_USEDEFAULT, CW_USEDEFAULT,
492 CW_USEDEFAULT, CW_USEDEFAULT,
493 parent, wid, 0, 0);
497 /***********************************************************************
498 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
500 * PARAMS
501 * style [I] window styles
502 * x [I] horizontal position of the control
503 * y [I] vertical position of the control
504 * cx [I] with of the control
505 * cy [I] height of the control
506 * parent [I] handle to the parent window
507 * id [I] the control's identifier
508 * inst [I] handle to the application's module instance
509 * buddy [I] handle to the buddy window, can be NULL
510 * maxVal [I] upper limit of the control
511 * minVal [I] lower limit of the control
512 * curVal [I] current value of the control
514 * RETURNS
515 * Success: handle to the updown control
516 * Failure: 0
519 HWND WINAPI
520 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
521 HWND parent, INT id, HINSTANCE inst,
522 HWND buddy, INT maxVal, INT minVal, INT curVal)
524 HWND hUD =
525 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
526 parent, id, inst, 0);
527 if (hUD) {
528 SendMessageA (hUD, UDM_SETBUDDY, buddy, 0);
529 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
530 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
533 return hUD;
537 /***********************************************************************
538 * InitCommonControls [COMCTL32.17]
540 * Registers the common controls.
542 * PARAMS
543 * No parameters.
545 * RETURNS
546 * No return values.
548 * NOTES
549 * This function is just a dummy.
550 * The Win95 controls are registered at the DLL's initialization.
551 * To register other controls InitCommonControlsEx() must be used.
554 VOID WINAPI
555 InitCommonControls (void)
560 /***********************************************************************
561 * InitCommonControlsEx [COMCTL32.84]
563 * Registers the common controls.
565 * PARAMS
566 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
568 * RETURNS
569 * Success: TRUE
570 * Failure: FALSE
572 * NOTES
573 * Only the additional common controls are registered by this function.
574 * The Win95 controls are registered at the DLL's initialization.
577 BOOL WINAPI
578 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
580 INT cCount;
581 DWORD dwMask;
583 if (!lpInitCtrls)
584 return FALSE;
585 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
586 return FALSE;
588 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
590 for (cCount = 0; cCount < 32; cCount++) {
591 dwMask = 1 << cCount;
592 if (!(lpInitCtrls->dwICC & dwMask))
593 continue;
595 switch (lpInitCtrls->dwICC & dwMask) {
596 /* dummy initialization */
597 case ICC_ANIMATE_CLASS:
598 case ICC_BAR_CLASSES:
599 case ICC_LISTVIEW_CLASSES:
600 case ICC_TREEVIEW_CLASSES:
601 case ICC_TAB_CLASSES:
602 case ICC_UPDOWN_CLASS:
603 case ICC_PROGRESS_CLASS:
604 case ICC_HOTKEY_CLASS:
605 break;
607 /* advanced classes - not included in Win95 */
608 case ICC_DATE_CLASSES:
609 MONTHCAL_Register ();
610 DATETIME_Register ();
611 break;
613 case ICC_USEREX_CLASSES:
614 COMBOEX_Register ();
615 break;
617 case ICC_COOL_CLASSES:
618 REBAR_Register ();
619 break;
621 case ICC_INTERNET_CLASSES:
622 IPADDRESS_Register ();
623 break;
625 case ICC_PAGESCROLLER_CLASS:
626 PAGER_Register ();
627 break;
629 case ICC_NATIVEFNTCTL_CLASS:
630 NATIVEFONT_Register ();
631 break;
633 default:
634 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
635 break;
639 return TRUE;
643 /***********************************************************************
644 * CreateToolbarEx [COMCTL32.23] Creates a tool bar window
646 * PARAMS
647 * hwnd
648 * style
649 * wID
650 * nBitmaps
651 * hBMInst
652 * wBMID
653 * lpButtons
654 * iNumButtons
655 * dxButton
656 * dyButton
657 * dxBitmap
658 * dyBitmap
659 * uStructSize
661 * RETURNS
662 * Success: handle to the tool bar control
663 * Failure: 0
666 HWND WINAPI
667 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
668 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
669 INT iNumButtons, INT dxButton, INT dyButton,
670 INT dxBitmap, INT dyBitmap, UINT uStructSize)
672 HWND hwndTB;
674 /* If not position is specified then put it at the top */
675 if ((style & CCS_BOTTOM) == 0) {
676 style|=CCS_TOP;
679 hwndTB =
680 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style|WS_CHILD, 0, 0, 0, 0,
681 hwnd, (HMENU)wID, 0, NULL);
682 if(hwndTB) {
683 TBADDBITMAP tbab;
685 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
686 (WPARAM)uStructSize, 0);
688 /* set bitmap and button size */
689 /*If CreateToolbarEx receives 0, windows sets default values*/
690 if (dxBitmap <= 0)
691 dxBitmap = 16;
692 if (dyBitmap <= 0)
693 dyBitmap = 15;
694 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
695 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
697 if (dxButton <= 0)
698 dxButton = 24;
699 if (dyButton <= 0)
700 dyButton = 22;
701 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
702 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
705 /* add bitmaps */
706 if (nBitmaps > 0)
708 tbab.hInst = hBMInst;
709 tbab.nID = wBMID;
711 SendMessageA (hwndTB, TB_ADDBITMAP,
712 (WPARAM)nBitmaps, (LPARAM)&tbab);
714 /* add buttons */
715 if(iNumButtons > 0)
716 SendMessageA (hwndTB, TB_ADDBUTTONSA,
717 (WPARAM)iNumButtons, (LPARAM)lpButtons);
720 return hwndTB;
724 /***********************************************************************
725 * CreateMappedBitmap [COMCTL32.8]
727 * PARAMS
728 * hInstance [I]
729 * idBitmap [I]
730 * wFlags [I]
731 * lpColorMap [I]
732 * iNumMaps [I]
734 * RETURNS
735 * Success: handle to the new bitmap
736 * Failure: 0
739 HBITMAP WINAPI
740 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
741 LPCOLORMAP lpColorMap, INT iNumMaps)
743 HGLOBAL hglb;
744 HRSRC hRsrc;
745 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
746 UINT nSize, nColorTableSize;
747 RGBQUAD *pColorTable;
748 INT iColor, i, iMaps, nWidth, nHeight;
749 HDC hdcScreen;
750 HBITMAP hbm;
751 LPCOLORMAP sysColorMap;
752 COLORREF cRef;
753 COLORMAP internalColorMap[4] =
754 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
756 /* initialize pointer to colortable and default color table */
757 if (lpColorMap) {
758 iMaps = iNumMaps;
759 sysColorMap = lpColorMap;
761 else {
762 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
763 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
764 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
765 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
766 iMaps = 4;
767 sysColorMap = (LPCOLORMAP)internalColorMap;
770 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
771 if (hRsrc == 0)
772 return 0;
773 hglb = LoadResource (hInstance, hRsrc);
774 if (hglb == 0)
775 return 0;
776 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
777 if (lpBitmap == NULL)
778 return 0;
780 nColorTableSize = (1 << lpBitmap->biBitCount);
781 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
782 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
783 if (lpBitmapInfo == NULL)
784 return 0;
785 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
787 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
789 for (iColor = 0; iColor < nColorTableSize; iColor++) {
790 for (i = 0; i < iMaps; i++) {
791 cRef = RGB(pColorTable[iColor].rgbRed,
792 pColorTable[iColor].rgbGreen,
793 pColorTable[iColor].rgbBlue);
794 if ( cRef == sysColorMap[i].from) {
795 #if 0
796 if (wFlags & CBS_MASKED) {
797 if (sysColorMap[i].to != COLOR_BTNTEXT)
798 pColorTable[iColor] = RGB(255, 255, 255);
800 else
801 #endif
802 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
803 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
804 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
805 break;
809 nWidth = (INT)lpBitmapInfo->biWidth;
810 nHeight = (INT)lpBitmapInfo->biHeight;
811 hdcScreen = GetDC ((HWND)0);
812 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
813 if (hbm) {
814 HDC hdcDst = CreateCompatibleDC (hdcScreen);
815 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
816 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
817 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
818 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
819 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
820 SRCCOPY);
821 SelectObject (hdcDst, hbmOld);
822 DeleteDC (hdcDst);
824 ReleaseDC ((HWND)0, hdcScreen);
825 GlobalFree ((HGLOBAL)lpBitmapInfo);
826 FreeResource (hglb);
828 return hbm;
832 /***********************************************************************
833 * CreateToolbar [COMCTL32.7] Creates a tool bar control
835 * PARAMS
836 * hwnd
837 * style
838 * wID
839 * nBitmaps
840 * hBMInst
841 * wBMID
842 * lpButtons
843 * iNumButtons
845 * RETURNS
846 * Success: handle to the tool bar control
847 * Failure: 0
849 * NOTES
850 * Do not use this functions anymore. Use CreateToolbarEx instead.
853 HWND WINAPI
854 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
855 HINSTANCE hBMInst, UINT wBMID,
856 LPCOLDTBBUTTON lpButtons,INT iNumButtons)
858 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
859 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
860 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
864 /***********************************************************************
865 * DllGetVersion [COMCTL32.@]
867 * Retrieves version information of the 'COMCTL32.DLL'
869 * PARAMS
870 * pdvi [O] pointer to version information structure.
872 * RETURNS
873 * Success: S_OK
874 * Failure: E_INVALIDARG
876 * NOTES
877 * Returns version of a comctl32.dll from IE4.01 SP1.
880 HRESULT WINAPI
881 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
883 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
884 WARN("wrong DLLVERSIONINFO size from app\n");
885 return E_INVALIDARG;
888 pdvi->dwMajorVersion = COMCTL32_VERSION;
889 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
890 pdvi->dwBuildNumber = 2919;
891 pdvi->dwPlatformID = 6304;
893 TRACE("%lu.%lu.%lu.%lu\n",
894 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
895 pdvi->dwBuildNumber, pdvi->dwPlatformID);
897 return S_OK;
900 /***********************************************************************
901 * DllInstall (COMCTL32.@)
903 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
905 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
906 debugstr_w(cmdline));
908 return S_OK;
912 typedef struct __TRACKINGLIST {
913 TRACKMOUSEEVENT tme;
914 POINT pos; /* center of hover rectangle */
915 INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */
916 } _TRACKINGLIST;
918 static _TRACKINGLIST TrackingList[10];
919 static int iTrackMax = 0;
920 static UINT_PTR timer;
921 static const INT iTimerInterval = 50; /* msec for timer interval */
923 /* FIXME: need to implement WM_NCMOUSELEAVE and WM_NCMOUSEHOVER for */
924 /* TrackMouseEventProc and _TrackMouseEvent */
925 static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
926 DWORD dwTime)
928 int i = 0;
929 POINT pos;
930 HWND hwnd;
931 INT hoverwidth = 0, hoverheight = 0;
933 GetCursorPos(&pos);
934 hwnd = WindowFromPoint(pos);
936 SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
937 SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
939 /* loop through tracking events we are processing */
940 while (i < iTrackMax) {
941 /* see if this tracking event is looking for TME_LEAVE and that the */
942 /* mouse has left the window */
943 if ((TrackingList[i].tme.dwFlags & TME_LEAVE) &&
944 (TrackingList[i].tme.hwndTrack != hwnd)) {
945 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
947 /* remove the TME_LEAVE flag */
948 TrackingList[i].tme.dwFlags ^= TME_LEAVE;
951 /* see if we are tracking hovering for this hwnd */
952 if(TrackingList[i].tme.dwFlags & TME_HOVER) {
953 /* add the timer interval to the hovering time */
954 TrackingList[i].iHoverTime+=iTimerInterval;
956 /* has the cursor moved outside the rectangle centered around pos? */
957 if((abs(pos.x - TrackingList[i].pos.x) > (hoverwidth / 2.0))
958 || (abs(pos.y - TrackingList[i].pos.y) > (hoverheight / 2.0)))
960 /* record this new position as the current position and reset */
961 /* the iHoverTime variable to 0 */
962 TrackingList[i].pos = pos;
963 TrackingList[i].iHoverTime = 0;
966 /* has the mouse hovered long enough? */
967 if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
969 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER, 0, 0);
971 /* stop tracking mouse hover */
972 TrackingList[i].tme.dwFlags ^= TME_HOVER;
976 /* see if we are still tracking TME_HOVER or TME_LEAVE for this entry */
977 if((TrackingList[i].tme.dwFlags & TME_HOVER) ||
978 (TrackingList[i].tme.dwFlags & TME_LEAVE)) {
979 i++;
980 } else { /* remove this entry from the tracking list */
981 TrackingList[i] = TrackingList[--iTrackMax];
985 /* stop the timer if the tracking list is empty */
986 if(iTrackMax == 0) {
987 KillTimer(0, timer);
988 timer = 0;
992 /***********************************************************************
993 * _TrackMouseEvent [COMCTL32.91]
995 * Requests notification of mouse events
997 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
998 * to the hwnd specified in the ptme structure. After the event message
999 * is posted to the hwnd, the entry in the queue is removed.
1001 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1002 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1003 * immediately and the TME_LEAVE flag being ignored.
1005 * PARAMS
1006 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1008 * RETURNS
1009 * Success: non-zero
1010 * Failure: zero
1014 BOOL WINAPI
1015 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1017 DWORD flags = 0;
1018 int i = 0;
1019 BOOL cancel = 0, hover = 0, leave = 0, query = 0;
1020 HWND hwnd;
1021 POINT pos;
1023 pos.x = 0;
1024 pos.y = 0;
1026 TRACE("%lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
1028 if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
1029 WARN("wrong TRACKMOUSEEVENT size from app\n");
1030 SetLastError(ERROR_INVALID_PARAMETER); /* FIXME not sure if this is correct */
1031 return FALSE;
1034 flags = ptme->dwFlags;
1036 /* if HOVER_DEFAULT was specified replace this with the systems current value */
1037 if(ptme->dwHoverTime == HOVER_DEFAULT)
1038 SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &(ptme->dwHoverTime), 0);
1040 GetCursorPos(&pos);
1041 hwnd = WindowFromPoint(pos);
1043 if ( flags & TME_CANCEL ) {
1044 flags &= ~ TME_CANCEL;
1045 cancel = 1;
1048 if ( flags & TME_HOVER ) {
1049 flags &= ~ TME_HOVER;
1050 hover = 1;
1053 if ( flags & TME_LEAVE ) {
1054 flags &= ~ TME_LEAVE;
1055 leave = 1;
1058 /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
1059 if ( flags & TME_QUERY ) {
1060 flags &= ~ TME_QUERY;
1061 query = 1;
1062 i = 0;
1064 /* Find the tracking list entry with the matching hwnd */
1065 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
1066 i++;
1069 /* hwnd found, fill in the ptme struct */
1070 if(i < iTrackMax)
1071 *ptme = TrackingList[i].tme;
1072 else
1073 ptme->dwFlags = 0;
1075 return TRUE; /* return here, TME_QUERY is retrieving information */
1078 if ( flags )
1079 FIXME("Unknown flag(s) %08lx\n", flags );
1081 if(cancel) {
1082 /* find a matching hwnd if one exists */
1083 i = 0;
1085 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
1086 i++;
1089 if(i < iTrackMax) {
1090 TrackingList[i].tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
1092 /* if we aren't tracking on hover or leave remove this entry */
1093 if(!((TrackingList[i].tme.dwFlags & TME_HOVER) ||
1094 (TrackingList[i].tme.dwFlags & TME_LEAVE)))
1096 TrackingList[i] = TrackingList[--iTrackMax];
1098 if(iTrackMax == 0) {
1099 KillTimer(0, timer);
1100 timer = 0;
1104 } else {
1105 /* see if hwndTrack isn't the current window */
1106 if(ptme->hwndTrack != hwnd) {
1107 if(leave) {
1108 PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
1110 } else {
1111 /* See if this hwnd is already being tracked and update the tracking flags */
1112 for(i = 0; i < iTrackMax; i++) {
1113 if(TrackingList[i].tme.hwndTrack == ptme->hwndTrack) {
1114 if(hover) {
1115 TrackingList[i].tme.dwFlags |= TME_HOVER;
1116 TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime;
1119 if(leave)
1120 TrackingList[i].tme.dwFlags |= TME_LEAVE;
1122 /* reset iHoverTime as per winapi specs */
1123 TrackingList[i].iHoverTime = 0;
1125 return TRUE;
1129 /* if the tracking list is full return FALSE */
1130 if (iTrackMax == sizeof (TrackingList) / sizeof(*TrackingList)) {
1131 return FALSE;
1134 /* Adding new mouse event to the tracking list */
1135 TrackingList[iTrackMax].tme = *ptme;
1137 /* Initialize HoverInfo variables even if not hover tracking */
1138 TrackingList[iTrackMax].iHoverTime = 0;
1139 TrackingList[iTrackMax].pos = pos;
1141 iTrackMax++;
1143 if (!timer) {
1144 timer = SetTimer(0, 0, iTimerInterval, TrackMouseEventProc);
1149 return TRUE;
1153 /*************************************************************************
1154 * GetMUILanguage [COMCTL32.39]
1156 * FIXME: What's this supposed to do? Apparently some i18n thing.
1159 LANGID WINAPI GetMUILanguage (VOID)
1161 return COMCTL32_uiLang;
1165 /*************************************************************************
1166 * InitMUILanguage [COMCTL32.85]
1168 * FIXME: What's this supposed to do? Apparently some i18n thing.
1172 VOID WINAPI InitMUILanguage (LANGID uiLang)
1174 COMCTL32_uiLang = uiLang;
1178 /***********************************************************************
1179 * COMCTL32_CreateToolTip [NOT AN API]
1181 * Creates a tooltip for the control specified in hwnd and does all
1182 * necessary setup and notifications.
1184 * PARAMS
1185 * hwndOwner [I] Handle to the window that will own the tool tip.
1187 * RETURNS
1188 * Success: Handle of tool tip window.
1189 * Failure: NULL
1191 HWND
1192 COMCTL32_CreateToolTip(HWND hwndOwner)
1194 HWND hwndToolTip;
1196 hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1197 CW_USEDEFAULT, CW_USEDEFAULT,
1198 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1199 0, 0, 0);
1201 /* Send NM_TOOLTIPSCREATED notification */
1202 if (hwndToolTip)
1204 NMTOOLTIPSCREATED nmttc;
1205 /* true owner can be different if hwndOwner is a child window */
1206 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1207 nmttc.hdr.hwndFrom = hwndTrueOwner;
1208 nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID);
1209 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1210 nmttc.hwndToolTips = hwndToolTip;
1212 SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1213 (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID),
1214 (LPARAM)&nmttc);
1217 return hwndToolTip;