2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998,2000 Eric Kohl
14 #include "debugtools.h"
17 DEFAULT_DEBUG_CHANNEL(commctrl);
19 extern void ANIMATE_Register(void);
20 extern void ANIMATE_Unregister(void);
21 extern void COMBOEX_Register(void);
22 extern void COMBOEX_Unregister(void);
23 extern void DATETIME_Register(void);
24 extern void DATETIME_Unregister(void);
25 extern void FLATSB_Register(void);
26 extern void FLATSB_Unregister(void);
27 extern void HEADER_Register(void);
28 extern void HEADER_Unregister(void);
29 extern void HOTKEY_Register(void);
30 extern void HOTKEY_Unregister(void);
31 extern void IPADDRESS_Register(void);
32 extern void IPADDRESS_Unregister(void);
33 extern void LISTVIEW_Register(void);
34 extern void LISTVIEW_Unregister(void);
35 extern void MONTHCAL_Register(void);
36 extern void MONTHCAL_Unregister(void);
37 extern void NATIVEFONT_Register(void);
38 extern void NATIVEFONT_Unregister(void);
39 extern void PAGER_Register(void);
40 extern void PAGER_Unregister(void);
41 extern void PROGRESS_Register(void);
42 extern void PROGRESS_Unregister(void);
43 extern void REBAR_Register(void);
44 extern void REBAR_Unregister(void);
45 extern void STATUS_Register(void);
46 extern void STATUS_Unregister(void);
47 extern void TAB_Register(void);
48 extern void TAB_Unregister(void);
49 extern void TOOLBAR_Register(void);
50 extern void TOOLBAR_Unregister(void);
51 extern void TOOLTIPS_Register(void);
52 extern void TOOLTIPS_Unregister(void);
53 extern void TRACKBAR_Register(void);
54 extern void TRACKBAR_Unregister(void);
55 extern void TREEVIEW_Register(void);
56 extern void TREEVIEW_Unregister(void);
57 extern void UPDOWN_Register(void);
58 extern void UPDOWN_Unregister(void);
61 HANDLE COMCTL32_hHeap = (HANDLE)NULL;
62 DWORD COMCTL32_dwProcessesAttached = 0;
63 LPSTR COMCTL32_aSubclass = (LPSTR)NULL;
64 HMODULE COMCTL32_hModule = 0;
65 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
68 /***********************************************************************
69 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
72 * hinstDLL [I] handle to the 'dlls' instance
74 * lpvReserved [I] reserverd, must be NULL
82 COMCTL32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
84 TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
87 case DLL_PROCESS_ATTACH:
88 if (COMCTL32_dwProcessesAttached == 0) {
90 /* This will be wrong for any other process attching in this address-space! */
91 COMCTL32_hModule = (HMODULE)hinstDLL;
93 /* create private heap */
94 COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
95 TRACE("Heap created: 0x%x\n", COMCTL32_hHeap);
97 /* add global subclassing atom (used by 'tooltip' and 'updown') */
98 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
99 TRACE("Subclassing atom added: %p\n",
102 /* register all Win95 common control classes */
107 LISTVIEW_Register ();
108 PROGRESS_Register ();
112 TOOLTIPS_Register ();
113 TRACKBAR_Register ();
114 TREEVIEW_Register ();
117 COMCTL32_dwProcessesAttached++;
120 case DLL_PROCESS_DETACH:
121 COMCTL32_dwProcessesAttached--;
122 if (COMCTL32_dwProcessesAttached == 0) {
123 /* unregister all common control classes */
124 ANIMATE_Unregister ();
125 COMBOEX_Unregister ();
126 DATETIME_Unregister ();
127 FLATSB_Unregister ();
128 HEADER_Unregister ();
129 HOTKEY_Unregister ();
130 IPADDRESS_Unregister ();
131 LISTVIEW_Unregister ();
132 MONTHCAL_Unregister ();
133 NATIVEFONT_Unregister ();
135 PROGRESS_Unregister ();
137 STATUS_Unregister ();
139 TOOLBAR_Unregister ();
140 TOOLTIPS_Unregister ();
141 TRACKBAR_Unregister ();
142 TREEVIEW_Unregister ();
143 UPDOWN_Unregister ();
145 /* delete global subclassing atom */
146 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
147 TRACE("Subclassing atom deleted: %p\n",
149 COMCTL32_aSubclass = (LPSTR)NULL;
151 /* destroy private heap */
152 HeapDestroy (COMCTL32_hHeap);
153 TRACE("Heap destroyed: 0x%x\n", COMCTL32_hHeap);
154 COMCTL32_hHeap = (HANDLE)NULL;
163 /***********************************************************************
164 * MenuHelp [COMCTL32.2]
167 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
168 * wParam [I] wParam of the message uMsg
169 * lParam [I] lParam of the message uMsg
170 * hMainMenu [I] handle to the application's main menu
171 * hInst [I] handle to the module that contains string resources
172 * hwndStatus [I] handle to the status bar window
173 * lpwIDs [I] pointer to an array of intergers (see NOTES)
179 * The official documentation is incomplete!
180 * This is the correct documentation:
183 * MenuHelp() does NOT handle WM_COMMAND messages! It only handes
184 * WM_MENUSELECT messages.
187 * (will be written ...)
191 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
192 HINSTANCE hInst, HWND hwndStatus, LPUINT lpwIDs)
196 if (!IsWindow (hwndStatus))
201 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
204 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
205 /* menu was closed */
206 TRACE("menu was closed!\n");
207 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
210 /* menu item was selected */
211 if (HIWORD(wParam) & MF_POPUP)
212 uMenuID = (UINT)*(lpwIDs+1);
214 uMenuID = (UINT)LOWORD(wParam);
215 TRACE("uMenuID = %u\n", uMenuID);
220 if (!LoadStringA (hInst, uMenuID, szText, 256))
223 SendMessageA (hwndStatus, SB_SETTEXTA,
224 255 | SBT_NOBORDERS, (LPARAM)szText);
225 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
231 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
233 /* WM_COMMAND is not invalid since it is documented
234 * in the windows api reference. So don't output
235 * any FIXME for WM_COMMAND
237 WARN("We don't care about the WM_COMMAND\n");
241 FIXME("Invalid Message 0x%x!\n", uMsg);
247 /***********************************************************************
248 * ShowHideMenuCtl [COMCTL32.3]
250 * Shows or hides controls and updates the corresponding menu item.
253 * hwnd [I] handle to the client window.
254 * uFlags [I] menu command id.
255 * lpInfo [I] pointer to an array of integers. (See NOTES.)
262 * The official documentation is incomplete!
263 * This is the correct documentation:
266 * Handle to the window that contains the menu and controls.
269 * Identifier of the menu item to receive or loose a check mark.
272 * The array of integers contains pairs of values. BOTH values of
273 * the first pair must be the handles to the application's main menu.
274 * Each subsequent pair consists of a menu id and control id.
278 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
282 TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
287 if (!(lpInfo[0]) || !(lpInfo[1]))
290 /* search for control */
291 lpMenuId = &lpInfo[2];
292 while (*lpMenuId != uFlags)
295 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
296 /* uncheck menu item */
297 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
301 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
305 /* check menu item */
306 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
310 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
318 /***********************************************************************
319 * GetEffectiveClientRect [COMCTL32.4]
322 * hwnd [I] handle to the client window.
323 * lpRect [O] pointer to the rectangle of the client window
324 * lpInfo [I] pointer to an array of integers (see NOTES)
330 * The official documentation is incomplete!
331 * This is the correct documentation:
334 * (will be written...)
338 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
344 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
345 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
347 GetClientRect (hwnd, lpRect);
355 hwndCtrl = GetDlgItem (hwnd, *lpRun);
356 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
357 TRACE("control id 0x%x\n", *lpRun);
358 GetWindowRect (hwndCtrl, &rcCtrl);
359 MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2);
360 SubtractRect (lpRect, lpRect, &rcCtrl);
367 /***********************************************************************
368 * DrawStatusTextA [COMCTL32.5][COMCTL32.27]
370 * Draws text with borders, like in a status bar.
373 * hdc [I] handle to the window's display context
374 * lprc [I] pointer to a rectangle
375 * text [I] pointer to the text
376 * style [I] drawing style
382 * The style variable can have one of the following values:
383 * (will be written ...)
387 DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
390 UINT border = BDR_SUNKENOUTER;
392 if (style & SBT_POPOUT)
393 border = BDR_RAISEDOUTER;
394 else if (style & SBT_NOBORDERS)
397 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
401 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
403 DrawTextA (hdc, text, lstrlenA(text),
404 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
405 if (oldbkmode != TRANSPARENT)
406 SetBkMode(hdc, oldbkmode);
411 /***********************************************************************
412 * DrawStatusTextW [COMCTL32.28]
414 * Draws text with borders, like in a status bar.
417 * hdc [I] handle to the window's display context
418 * lprc [I] pointer to a rectangle
419 * text [I] pointer to the text
420 * style [I] drawing style
427 DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
429 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
430 DrawStatusTextA (hdc, lprc, p, style);
431 HeapFree (GetProcessHeap (), 0, p );
435 /***********************************************************************
436 * CreateStatusWindowA [COMCTL32.6][COMCTL32.21]
438 * Creates a status bar
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
447 * Success: handle to the status window
452 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid)
454 return CreateWindowA(STATUSCLASSNAMEA, text, style,
455 CW_USEDEFAULT, CW_USEDEFAULT,
456 CW_USEDEFAULT, CW_USEDEFAULT,
461 /***********************************************************************
462 * CreateStatusWindowW [COMCTL32.22] Creates a status bar control
465 * style [I] window style
466 * text [I] pointer to the window text
467 * parent [I] handle to the parent window
468 * wid [I] control id of the status bar
471 * Success: handle to the status window
476 CreateStatusWindowW (INT style, LPCWSTR text, HWND parent, UINT wid)
478 return CreateWindowW(STATUSCLASSNAMEW, text, style,
479 CW_USEDEFAULT, CW_USEDEFAULT,
480 CW_USEDEFAULT, CW_USEDEFAULT,
485 /***********************************************************************
486 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
489 * style [I] window styles
490 * x [I] horizontal position of the control
491 * y [I] vertical position of the control
492 * cx [I] with of the control
493 * cy [I] height of the control
494 * parent [I] handle to the parent window
495 * id [I] the control's identifier
496 * inst [I] handle to the application's module instance
497 * buddy [I] handle to the buddy window, can be NULL
498 * maxVal [I] upper limit of the control
499 * minVal [I] lower limit of the control
500 * curVal [I] current value of the control
503 * Success: handle to the updown control
508 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
509 HWND parent, INT id, HINSTANCE inst,
510 HWND buddy, INT maxVal, INT minVal, INT curVal)
513 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
514 parent, id, inst, 0);
516 SendMessageA (hUD, UDM_SETBUDDY, buddy, 0);
517 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
518 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
525 /***********************************************************************
526 * InitCommonControls [COMCTL32.17]
528 * Registers the common controls.
537 * This function is just a dummy.
538 * The Win95 controls are registered at the DLL's initialization.
539 * To register other controls InitCommonControlsEx() must be used.
543 InitCommonControls (void)
548 /***********************************************************************
549 * InitCommonControlsEx [COMCTL32.81]
551 * Registers the common controls.
554 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
561 * Only the additinal common controls are registered by this function.
562 * The Win95 controls are registered at the DLL's initialization.
566 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
573 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
576 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
578 for (cCount = 0; cCount < 32; cCount++) {
579 dwMask = 1 << cCount;
580 if (!(lpInitCtrls->dwICC & dwMask))
583 switch (lpInitCtrls->dwICC & dwMask) {
584 /* dummy initialization */
585 case ICC_ANIMATE_CLASS:
586 case ICC_BAR_CLASSES:
587 case ICC_LISTVIEW_CLASSES:
588 case ICC_TREEVIEW_CLASSES:
589 case ICC_TAB_CLASSES:
590 case ICC_UPDOWN_CLASS:
591 case ICC_PROGRESS_CLASS:
592 case ICC_HOTKEY_CLASS:
595 /* advanced classes - not included in Win95 */
596 case ICC_DATE_CLASSES:
597 MONTHCAL_Register ();
598 DATETIME_Register ();
601 case ICC_USEREX_CLASSES:
605 case ICC_COOL_CLASSES:
609 case ICC_INTERNET_CLASSES:
610 IPADDRESS_Register ();
613 case ICC_PAGESCROLLER_CLASS:
617 case ICC_NATIVEFNTCTL_CLASS:
618 NATIVEFONT_Register ();
622 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
631 /***********************************************************************
632 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
650 * Success: handle to the tool bar control
655 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
656 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
657 INT iNumButtons, INT dxButton, INT dyButton,
658 INT dxBitmap, INT dyBitmap, UINT uStructSize)
661 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style, 0, 0, 0, 0,
662 hwnd, (HMENU)wID, 0, NULL);
666 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
667 (WPARAM)uStructSize, 0);
669 /* set bitmap and button size */
670 /*If CreateToolbarEx receive 0, windows set default values*/
676 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
677 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
678 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
679 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
685 tbab.hInst = hBMInst;
688 SendMessageA (hwndTB, TB_ADDBITMAP,
689 (WPARAM)nBitmaps, (LPARAM)&tbab);
693 SendMessageA (hwndTB, TB_ADDBUTTONSA,
694 (WPARAM)iNumButtons, (LPARAM)lpButtons);
701 /***********************************************************************
702 * CreateMappedBitmap [COMCTL32.8]
712 * Success: handle to the new bitmap
717 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
718 LPCOLORMAP lpColorMap, INT iNumMaps)
722 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
723 UINT nSize, nColorTableSize;
724 RGBQUAD *pColorTable;
725 INT iColor, i, iMaps, nWidth, nHeight;
728 LPCOLORMAP sysColorMap;
730 COLORMAP internalColorMap[4] =
731 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
733 /* initialize pointer to colortable and default color table */
736 sysColorMap = lpColorMap;
739 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
740 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
741 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
742 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
744 sysColorMap = (LPCOLORMAP)internalColorMap;
747 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
750 hglb = LoadResource (hInstance, hRsrc);
753 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
754 if (lpBitmap == NULL)
757 nColorTableSize = (1 << lpBitmap->biBitCount);
758 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
759 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
760 if (lpBitmapInfo == NULL)
762 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
764 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
766 for (iColor = 0; iColor < nColorTableSize; iColor++) {
767 for (i = 0; i < iMaps; i++) {
768 cRef = RGB(pColorTable[iColor].rgbRed,
769 pColorTable[iColor].rgbGreen,
770 pColorTable[iColor].rgbBlue);
771 if ( cRef == sysColorMap[i].from) {
773 if (wFlags & CBS_MASKED) {
774 if (sysColorMap[i].to != COLOR_BTNTEXT)
775 pColorTable[iColor] = RGB(255, 255, 255);
779 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
780 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
781 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
786 nWidth = (INT)lpBitmapInfo->biWidth;
787 nHeight = (INT)lpBitmapInfo->biHeight;
788 hdcScreen = GetDC ((HWND)0);
789 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
791 HDC hdcDst = CreateCompatibleDC (hdcScreen);
792 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
793 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
794 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
795 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
796 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
798 SelectObject (hdcDst, hbmOld);
801 ReleaseDC ((HWND)0, hdcScreen);
802 GlobalFree ((HGLOBAL)lpBitmapInfo);
809 /***********************************************************************
810 * CreateToolbar [COMCTL32.7] Creates a tool bar control
823 * Success: handle to the tool bar control
827 * Do not use this functions anymore. Use CreateToolbarEx instead.
831 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
832 HINSTANCE hBMInst, UINT wBMID,
833 LPCOLDTBBUTTON lpButtons,INT iNumButtons)
835 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
836 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
837 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
841 /***********************************************************************
842 * DllGetVersion [COMCTL32.25]
844 * Retrieves version information of the 'COMCTL32.DLL'
847 * pdvi [O] pointer to version information structure.
851 * Failure: E_INVALIDARG
854 * Returns version of a comctl32.dll from IE4.01 SP1.
858 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
860 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
861 WARN("wrong DLLVERSIONINFO size from app");
865 pdvi->dwMajorVersion = 5;
866 pdvi->dwMinorVersion = 0;
867 pdvi->dwBuildNumber = 2919;
868 pdvi->dwPlatformID = 6304;
870 TRACE("%lu.%lu.%lu.%lu\n",
871 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
872 pdvi->dwBuildNumber, pdvi->dwPlatformID);
877 /***********************************************************************
878 * DllInstall (COMCTL32.@)
880 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
882 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
883 debugstr_w(cmdline));
889 typedef struct __TRACKINGLIST {
891 POINT pos; /* center of hover rectangle */
892 INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */
895 static _TRACKINGLIST TrackingList[10];
896 static int iTrackMax = 0;
897 static UINT_PTR timer;
898 static const INT iTimerInterval = 50; /* msec for timer interval */
900 /* FIXME: need to implement WM_NCMOUSELEAVE and WM_NCMOUSEHOVER for */
901 /* TrackMouseEventProc and _TrackMouseEvent */
902 static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
908 INT hoverwidth = 0, hoverheight = 0;
911 hwnd = WindowFromPoint(pos);
913 SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
914 SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
916 /* loop through tracking events we are processing */
917 while (i < iTrackMax) {
918 /* see if this tracking event is looking for TME_LEAVE and that the */
919 /* mouse has left the window */
920 if ((TrackingList[i].tme.dwFlags & TME_LEAVE) &&
921 (TrackingList[i].tme.hwndTrack != hwnd)) {
922 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
924 /* remove the TME_LEAVE flag */
925 TrackingList[i].tme.dwFlags ^= TME_LEAVE;
928 /* see if we are tracking hovering for this hwnd */
929 if(TrackingList[i].tme.dwFlags & TME_HOVER) {
930 /* add the timer interval to the hovering time */
931 TrackingList[i].iHoverTime+=iTimerInterval;
933 /* has the cursor moved outside the rectangle centered around pos? */
934 if((abs(pos.x - TrackingList[i].pos.x) > (hoverwidth / 2.0))
935 || (abs(pos.y - TrackingList[i].pos.y) > (hoverheight / 2.0)))
937 /* record this new position as the current position and reset */
938 /* the iHoverTime variable to 0 */
939 TrackingList[i].pos = pos;
940 TrackingList[i].iHoverTime = 0;
943 /* has the mouse hovered long enough? */
944 if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
946 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER, 0, 0);
948 /* stop tracking mouse hover */
949 TrackingList[i].tme.dwFlags ^= TME_HOVER;
953 /* see if we are still tracking TME_HOVER or TME_LEAVE for this entry */
954 if((TrackingList[i].tme.dwFlags & TME_HOVER) ||
955 (TrackingList[i].tme.dwFlags & TME_LEAVE)) {
957 } else { /* remove this entry from the tracking list */
958 TrackingList[i] = TrackingList[--iTrackMax];
962 /* stop the timer if the tracking list is empty */
969 /***********************************************************************
970 * _TrackMouseEvent [COMCTL32.25]
972 * Requests notification of mouse events
974 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
975 * to the hwnd specified in the ptme structure. After the event message
976 * is posted to the hwnd, the entry in the queue is removed.
978 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
979 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
980 * immediately and the TME_LEAVE flag being ignored.
983 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
992 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
996 BOOL cancel = 0, hover = 0, leave = 0, query = 0;
1003 TRACE("%lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
1005 if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
1006 WARN("wrong TRACKMOUSEEVENT size from app");
1007 SetLastError(ERROR_INVALID_PARAMETER); /* FIXME not sure if this is correct */
1011 flags = ptme->dwFlags;
1013 /* if HOVER_DEFAULT was specified replace this with the systems current value */
1014 if(ptme->dwHoverTime == HOVER_DEFAULT)
1015 SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &(ptme->dwHoverTime), 0);
1018 hwnd = WindowFromPoint(pos);
1020 if ( flags & TME_CANCEL ) {
1021 flags &= ~ TME_CANCEL;
1025 if ( flags & TME_HOVER ) {
1026 flags &= ~ TME_HOVER;
1030 if ( flags & TME_LEAVE ) {
1031 flags &= ~ TME_LEAVE;
1035 /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
1036 if ( flags & TME_QUERY ) {
1037 flags &= ~ TME_QUERY;
1041 /* Find the tracking list entry with the matching hwnd */
1042 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
1046 /* hwnd found, fill in the ptme struct */
1048 *ptme = TrackingList[i].tme;
1052 return TRUE; /* return here, TME_QUERY is retrieving information */
1056 FIXME("Unknown flag(s) %08lx\n", flags );
1059 /* find a matching hwnd if one exists */
1062 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
1067 TrackingList[i].tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
1069 /* if we aren't tracking on hover or leave remove this entry */
1070 if(!((TrackingList[i].tme.dwFlags & TME_HOVER) ||
1071 (TrackingList[i].tme.dwFlags & TME_LEAVE)))
1073 TrackingList[i] = TrackingList[--iTrackMax];
1075 if(iTrackMax == 0) {
1076 KillTimer(0, timer);
1082 /* see if hwndTrack isn't the current window */
1083 if(ptme->hwndTrack != hwnd) {
1085 PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
1088 /* See if this hwnd is already being tracked and update the tracking flags */
1089 for(i = 0; i < iTrackMax; i++) {
1090 if(TrackingList[i].tme.hwndTrack == ptme->hwndTrack) {
1092 TrackingList[i].tme.dwFlags |= TME_HOVER;
1093 TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime;
1097 TrackingList[i].tme.dwFlags |= TME_LEAVE;
1099 /* reset iHoverTime as per winapi specs */
1100 TrackingList[i].iHoverTime = 0;
1106 /* if the tracking list is full return FALSE */
1107 if (iTrackMax == sizeof (TrackingList) / sizeof(*TrackingList)) {
1111 /* Adding new mouse event to the tracking list */
1112 TrackingList[iTrackMax].tme = *ptme;
1114 /* Initialize HoverInfo variables even if not hover tracking */
1115 TrackingList[iTrackMax].iHoverTime = 0;
1116 TrackingList[iTrackMax].pos = pos;
1121 timer = SetTimer(0, 0, iTimerInterval, TrackMouseEventProc);
1130 /*************************************************************************
1131 * GetMUILanguage [COMCTL32.39]
1133 * FIXME: What's this supposed to do? Apparently some i18n thing.
1136 LANGID WINAPI GetMUILanguage (VOID)
1138 return COMCTL32_uiLang;
1142 /*************************************************************************
1143 * InitMUILanguage [COMCTL32.85]
1145 * FIXME: What's this supposed to do? Apparently some i18n thing.
1149 VOID WINAPI InitMUILanguage (LANGID uiLang)
1151 COMCTL32_uiLang = uiLang;