2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998,2000 Eric Kohl
20 #include "ipaddress.h"
23 #include "nativefont.h"
34 #include "debugtools.h"
37 DEFAULT_DEBUG_CHANNEL(commctrl)
40 HANDLE COMCTL32_hHeap = (HANDLE)NULL;
41 DWORD COMCTL32_dwProcessesAttached = 0;
42 LPSTR COMCTL32_aSubclass = (LPSTR)NULL;
43 HMODULE COMCTL32_hModule = 0;
44 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
47 /***********************************************************************
48 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
51 * hinstDLL [I] handle to the 'dlls' instance
53 * lpvReserved [I] reserverd, must be NULL
61 COMCTL32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
63 TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
66 case DLL_PROCESS_ATTACH:
67 if (COMCTL32_dwProcessesAttached == 0) {
69 /* This will be wrong for any other process attching in this address-space! */
70 COMCTL32_hModule = (HMODULE)hinstDLL;
72 /* create private heap */
73 COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
74 TRACE("Heap created: 0x%x\n", COMCTL32_hHeap);
76 /* add global subclassing atom (used by 'tooltip' and 'updown') */
77 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
78 TRACE("Subclassing atom added: %p\n",
81 /* register all Win95 common control classes */
96 COMCTL32_dwProcessesAttached++;
99 case DLL_PROCESS_DETACH:
100 COMCTL32_dwProcessesAttached--;
101 if (COMCTL32_dwProcessesAttached == 0) {
102 /* unregister all common control classes */
103 ANIMATE_Unregister ();
104 COMBOEX_Unregister ();
105 DATETIME_Unregister ();
106 FLATSB_Unregister ();
107 HEADER_Unregister ();
108 HOTKEY_Unregister ();
109 IPADDRESS_Unregister ();
110 LISTVIEW_Unregister ();
111 MONTHCAL_Unregister ();
112 NATIVEFONT_Unregister ();
114 PROGRESS_Unregister ();
116 STATUS_Unregister ();
118 TOOLBAR_Unregister ();
119 TOOLTIPS_Unregister ();
120 TRACKBAR_Unregister ();
121 TREEVIEW_Unregister ();
122 UPDOWN_Unregister ();
124 /* delete global subclassing atom */
125 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
126 TRACE("Subclassing atom deleted: %p\n",
128 COMCTL32_aSubclass = (LPSTR)NULL;
130 /* destroy private heap */
131 HeapDestroy (COMCTL32_hHeap);
132 TRACE("Heap destroyed: 0x%x\n", COMCTL32_hHeap);
133 COMCTL32_hHeap = (HANDLE)NULL;
142 /***********************************************************************
143 * MenuHelp [COMCTL32.2]
146 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
147 * wParam [I] wParam of the message uMsg
148 * lParam [I] lParam of the message uMsg
149 * hMainMenu [I] handle to the application's main menu
150 * hInst [I] handle to the module that contains string resources
151 * hwndStatus [I] handle to the status bar window
152 * lpwIDs [I] pointer to an array of intergers (see NOTES)
158 * The official documentation is incomplete!
159 * This is the correct documentation:
162 * MenuHelp() does NOT handle WM_COMMAND messages! It only handes
163 * WM_MENUSELECT messages.
166 * (will be written ...)
170 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
171 HINSTANCE hInst, HWND hwndStatus, LPUINT lpwIDs)
175 if (!IsWindow (hwndStatus))
180 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
183 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
184 /* menu was closed */
185 TRACE("menu was closed!\n");
186 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
189 /* menu item was selected */
190 if (HIWORD(wParam) & MF_POPUP)
191 uMenuID = (UINT)*(lpwIDs+1);
193 uMenuID = (UINT)LOWORD(wParam);
194 TRACE("uMenuID = %u\n", uMenuID);
199 if (!LoadStringA (hInst, uMenuID, szText, 256))
202 SendMessageA (hwndStatus, SB_SETTEXTA,
203 255 | SBT_NOBORDERS, (LPARAM)szText);
204 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
210 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
212 /* WM_COMMAND is not invalid since it is documented
213 * in the windows api reference. So don't output
214 * any FIXME for WM_COMMAND
216 WARN("We don't care about the WM_COMMAND\n");
220 FIXME("Invalid Message 0x%x!\n", uMsg);
226 /***********************************************************************
227 * ShowHideMenuCtl [COMCTL32.3]
229 * Shows or hides controls and updates the corresponding menu item.
232 * hwnd [I] handle to the client window.
233 * uFlags [I] menu command id.
234 * lpInfo [I] pointer to an array of integers. (See NOTES.)
241 * The official documentation is incomplete!
242 * This is the correct documentation:
245 * Handle to the window that contains the menu and controls.
248 * Identifier of the menu item to receive or loose a check mark.
251 * The array of integers contains pairs of values. BOTH values of
252 * the first pair must be the handles to the application's main menu.
253 * Each subsequent pair consists of a menu id and control id.
257 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
261 TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
266 if (!(lpInfo[0]) || !(lpInfo[1]))
269 /* search for control */
270 lpMenuId = &lpInfo[2];
271 while (*lpMenuId != uFlags)
274 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
275 /* uncheck menu item */
276 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
280 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
284 /* check menu item */
285 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
289 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
297 /***********************************************************************
298 * GetEffectiveClientRect [COMCTL32.4]
301 * hwnd [I] handle to the client window.
302 * lpRect [O] pointer to the rectangle of the client window
303 * lpInfo [I] pointer to an array of integers (see NOTES)
309 * The official documentation is incomplete!
310 * This is the correct documentation:
313 * (will be written...)
317 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
323 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
324 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
326 GetClientRect (hwnd, lpRect);
334 hwndCtrl = GetDlgItem (hwnd, *lpRun);
335 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
336 TRACE("control id 0x%x\n", *lpRun);
337 GetWindowRect (hwndCtrl, &rcCtrl);
338 MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2);
339 SubtractRect (lpRect, lpRect, &rcCtrl);
346 /***********************************************************************
347 * DrawStatusTextA [COMCTL32.5][COMCTL32.27]
349 * Draws text with borders, like in a status bar.
352 * hdc [I] handle to the window's display context
353 * lprc [I] pointer to a rectangle
354 * text [I] pointer to the text
355 * style [I] drawing style
361 * The style variable can have one of the following values:
362 * (will be written ...)
366 DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
369 UINT border = BDR_SUNKENOUTER;
371 if (style & SBT_POPOUT)
372 border = BDR_RAISEDOUTER;
373 else if (style & SBT_NOBORDERS)
376 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
380 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
382 DrawTextA (hdc, text, lstrlenA(text),
383 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
384 if (oldbkmode != TRANSPARENT)
385 SetBkMode(hdc, oldbkmode);
390 /***********************************************************************
391 * DrawStatusTextW [COMCTL32.28]
393 * Draws text with borders, like in a status bar.
396 * hdc [I] handle to the window's display context
397 * lprc [I] pointer to a rectangle
398 * text [I] pointer to the text
399 * style [I] drawing style
406 DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
408 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
409 DrawStatusTextA (hdc, lprc, p, style);
410 HeapFree (GetProcessHeap (), 0, p );
414 /***********************************************************************
415 * CreateStatusWindowA [COMCTL32.6][COMCTL32.21]
417 * Creates a status bar
420 * style [I] window style
421 * text [I] pointer to the window text
422 * parent [I] handle to the parent window
423 * wid [I] control id of the status bar
426 * Success: handle to the status window
431 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid)
433 return CreateWindowA(STATUSCLASSNAMEA, text, style,
434 CW_USEDEFAULT, CW_USEDEFAULT,
435 CW_USEDEFAULT, CW_USEDEFAULT,
440 /***********************************************************************
441 * CreateStatusWindowW [COMCTL32.22] Creates a status bar control
444 * style [I] window style
445 * text [I] pointer to the window text
446 * parent [I] handle to the parent window
447 * wid [I] control id of the status bar
450 * Success: handle to the status window
455 CreateStatusWindowW (INT style, LPCWSTR text, HWND parent, UINT wid)
457 return CreateWindowW(STATUSCLASSNAMEW, text, style,
458 CW_USEDEFAULT, CW_USEDEFAULT,
459 CW_USEDEFAULT, CW_USEDEFAULT,
464 /***********************************************************************
465 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
468 * style [I] window styles
469 * x [I] horizontal position of the control
470 * y [I] vertical position of the control
471 * cx [I] with of the control
472 * cy [I] height of the control
473 * parent [I] handle to the parent window
474 * id [I] the control's identifier
475 * inst [I] handle to the application's module instance
476 * buddy [I] handle to the buddy window, can be NULL
477 * maxVal [I] upper limit of the control
478 * minVal [I] lower limit of the control
479 * curVal [I] current value of the control
482 * Success: handle to the updown control
487 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
488 HWND parent, INT id, HINSTANCE inst,
489 HWND buddy, INT maxVal, INT minVal, INT curVal)
492 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
493 parent, id, inst, 0);
495 SendMessageA (hUD, UDM_SETBUDDY, buddy, 0);
496 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
497 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
504 /***********************************************************************
505 * InitCommonControls [COMCTL32.17]
507 * Registers the common controls.
516 * This function is just a dummy.
517 * The Win95 controls are registered at the DLL's initialization.
518 * To register other controls InitCommonControlsEx() must be used.
522 InitCommonControls (void)
527 /***********************************************************************
528 * InitCommonControlsEx [COMCTL32.81]
530 * Registers the common controls.
533 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
540 * Only the additinal common controls are registered by this function.
541 * The Win95 controls are registered at the DLL's initialization.
545 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
552 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
555 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
557 for (cCount = 0; cCount < 32; cCount++) {
558 dwMask = 1 << cCount;
559 if (!(lpInitCtrls->dwICC & dwMask))
562 switch (lpInitCtrls->dwICC & dwMask) {
563 /* dummy initialization */
564 case ICC_ANIMATE_CLASS:
565 case ICC_BAR_CLASSES:
566 case ICC_LISTVIEW_CLASSES:
567 case ICC_TREEVIEW_CLASSES:
568 case ICC_TAB_CLASSES:
569 case ICC_UPDOWN_CLASS:
570 case ICC_PROGRESS_CLASS:
571 case ICC_HOTKEY_CLASS:
574 /* advanced classes - not included in Win95 */
575 case ICC_DATE_CLASSES:
576 MONTHCAL_Register ();
577 DATETIME_Register ();
580 case ICC_USEREX_CLASSES:
584 case ICC_COOL_CLASSES:
588 case ICC_INTERNET_CLASSES:
589 IPADDRESS_Register ();
592 case ICC_PAGESCROLLER_CLASS:
596 case ICC_NATIVEFNTCTL_CLASS:
597 NATIVEFONT_Register ();
601 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
610 /***********************************************************************
611 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
629 * Success: handle to the tool bar control
634 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
635 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
636 INT iNumButtons, INT dxButton, INT dyButton,
637 INT dxBitmap, INT dyBitmap, UINT uStructSize)
640 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style, 0, 0, 0, 0,
641 hwnd, (HMENU)wID, 0, NULL);
645 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
646 (WPARAM)uStructSize, 0);
648 /* set bitmap and button size */
649 /*If CreateToolbarEx receive 0, windows set default values*/
655 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
656 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
657 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
658 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
664 tbab.hInst = hBMInst;
667 SendMessageA (hwndTB, TB_ADDBITMAP,
668 (WPARAM)nBitmaps, (LPARAM)&tbab);
672 SendMessageA (hwndTB, TB_ADDBUTTONSA,
673 (WPARAM)iNumButtons, (LPARAM)lpButtons);
680 /***********************************************************************
681 * CreateMappedBitmap [COMCTL32.8]
691 * Success: handle to the new bitmap
696 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
697 LPCOLORMAP lpColorMap, INT iNumMaps)
701 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
702 UINT nSize, nColorTableSize;
703 RGBQUAD *pColorTable;
704 INT iColor, i, iMaps, nWidth, nHeight;
707 LPCOLORMAP sysColorMap;
709 COLORMAP internalColorMap[4] =
710 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
712 /* initialize pointer to colortable and default color table */
715 sysColorMap = lpColorMap;
718 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
719 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
720 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
721 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
723 sysColorMap = (LPCOLORMAP)internalColorMap;
726 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
729 hglb = LoadResource (hInstance, hRsrc);
732 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
733 if (lpBitmap == NULL)
736 nColorTableSize = (1 << lpBitmap->biBitCount);
737 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
738 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
739 if (lpBitmapInfo == NULL)
741 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
743 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
745 for (iColor = 0; iColor < nColorTableSize; iColor++) {
746 for (i = 0; i < iMaps; i++) {
747 cRef = RGB(pColorTable[iColor].rgbRed,
748 pColorTable[iColor].rgbGreen,
749 pColorTable[iColor].rgbBlue);
750 if ( cRef == sysColorMap[i].from) {
752 if (wFlags & CBS_MASKED) {
753 if (sysColorMap[i].to != COLOR_BTNTEXT)
754 pColorTable[iColor] = RGB(255, 255, 255);
758 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
759 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
760 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
765 nWidth = (INT)lpBitmapInfo->biWidth;
766 nHeight = (INT)lpBitmapInfo->biHeight;
767 hdcScreen = GetDC ((HWND)0);
768 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
770 HDC hdcDst = CreateCompatibleDC (hdcScreen);
771 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
772 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
773 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
774 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
775 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
777 SelectObject (hdcDst, hbmOld);
780 ReleaseDC ((HWND)0, hdcScreen);
781 GlobalFree ((HGLOBAL)lpBitmapInfo);
788 /***********************************************************************
789 * CreateToolbar [COMCTL32.7] Creates a tool bar control
802 * Success: handle to the tool bar control
806 * Do not use this functions anymore. Use CreateToolbarEx instead.
810 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
811 HINSTANCE hBMInst, UINT wBMID,
812 LPCOLDTBBUTTON lpButtons,INT iNumButtons)
814 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
815 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
816 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
820 /***********************************************************************
821 * DllGetVersion [COMCTL32.25]
823 * Retrieves version information of the 'COMCTL32.DLL'
826 * pdvi [O] pointer to version information structure.
830 * Failure: E_INVALIDARG
833 * Returns version of a comctl32.dll from IE4.01 SP1.
837 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
839 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
840 WARN("wrong DLLVERSIONINFO size from app");
844 pdvi->dwMajorVersion = 5;
845 pdvi->dwMinorVersion = 0;
846 pdvi->dwBuildNumber = 2919;
847 pdvi->dwPlatformID = 6304;
849 TRACE("%lu.%lu.%lu.%lu\n",
850 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
851 pdvi->dwBuildNumber, pdvi->dwPlatformID);
856 /***********************************************************************
857 * DllInstall (COMCTL32.@)
859 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
861 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
862 debugstr_w(cmdline));
868 typedef struct __TRACKINGLIST {
870 POINT pos; /* center of hover rectangle */
871 INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */
874 static _TRACKINGLIST TrackingList[10];
875 static int iTrackMax = 0;
876 static UINT_PTR timer;
877 static const INT iTimerInterval = 50; /* msec for timer interval */
879 /* FIXME: need to implement WM_NCMOUSELEAVE and WM_NCMOUSEHOVER for */
880 /* TrackMouseEventProc and _TrackMouseEvent */
881 static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
887 INT hoverwidth = 0, hoverheight = 0;
890 hwnd = WindowFromPoint(pos);
892 SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
893 SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
895 /* loop through tracking events we are processing */
896 while (i < iTrackMax) {
897 /* see if this tracking event is looking for TME_LEAVE and that the */
898 /* mouse has left the window */
899 if ((TrackingList[i].tme.dwFlags & TME_LEAVE) &&
900 (TrackingList[i].tme.hwndTrack != hwnd)) {
901 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
903 /* remove the TME_LEAVE flag */
904 TrackingList[i].tme.dwFlags ^= TME_LEAVE;
907 /* see if we are tracking hovering for this hwnd */
908 if(TrackingList[i].tme.dwFlags & TME_HOVER) {
909 /* add the timer interval to the hovering time */
910 TrackingList[i].iHoverTime+=iTimerInterval;
912 /* has the cursor moved outside the rectangle centered around pos? */
913 if((abs(pos.x - TrackingList[i].pos.x) > (hoverwidth / 2.0))
914 || (abs(pos.y - TrackingList[i].pos.y) > (hoverheight / 2.0)))
916 /* record this new position as the current position and reset */
917 /* the iHoverTime variable to 0 */
918 TrackingList[i].pos = pos;
919 TrackingList[i].iHoverTime = 0;
922 /* has the mouse hovered long enough? */
923 if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
925 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER, 0, 0);
927 /* stop tracking mouse hover */
928 TrackingList[i].tme.dwFlags ^= TME_HOVER;
932 /* see if we are still tracking TME_HOVER or TME_LEAVE for this entry */
933 if((TrackingList[i].tme.dwFlags & TME_HOVER) ||
934 (TrackingList[i].tme.dwFlags & TME_LEAVE)) {
936 } else { /* remove this entry from the tracking list */
937 TrackingList[i] = TrackingList[--iTrackMax];
941 /* stop the timer if the tracking list is empty */
948 /***********************************************************************
949 * _TrackMouseEvent [COMCTL32.25]
951 * Requests notification of mouse events
953 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
954 * to the hwnd specified in the ptme structure. After the event message
955 * is posted to the hwnd, the entry in the queue is removed.
957 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
958 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
959 * immediately and the TME_LEAVE flag being ignored.
962 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
971 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
975 BOOL cancel = 0, hover = 0, leave = 0, query = 0;
982 TRACE("%lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
984 if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
985 WARN("wrong TRACKMOUSEEVENT size from app");
986 SetLastError(ERROR_INVALID_PARAMETER); /* FIXME not sure if this is correct */
990 flags = ptme->dwFlags;
992 /* if HOVER_DEFAULT was specified replace this with the systems current value */
993 if(ptme->dwHoverTime == HOVER_DEFAULT)
994 SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &(ptme->dwHoverTime), 0);
997 hwnd = WindowFromPoint(pos);
999 if ( flags & TME_CANCEL ) {
1000 flags &= ~ TME_CANCEL;
1004 if ( flags & TME_HOVER ) {
1005 flags &= ~ TME_HOVER;
1009 if ( flags & TME_LEAVE ) {
1010 flags &= ~ TME_LEAVE;
1014 /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
1015 if ( flags & TME_QUERY ) {
1016 flags &= ~ TME_QUERY;
1020 /* Find the tracking list entry with the matching hwnd */
1021 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
1025 /* hwnd found, fill in the ptme struct */
1027 *ptme = TrackingList[i].tme;
1031 return TRUE; /* return here, TME_QUERY is retrieving information */
1035 FIXME("Unknown flag(s) %08lx\n", flags );
1038 /* find a matching hwnd if one exists */
1041 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
1046 TrackingList[i].tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
1048 /* if we aren't tracking on hover or leave remove this entry */
1049 if(!((TrackingList[i].tme.dwFlags & TME_HOVER) ||
1050 (TrackingList[i].tme.dwFlags & TME_LEAVE)))
1052 TrackingList[i] = TrackingList[--iTrackMax];
1054 if(iTrackMax == 0) {
1055 KillTimer(0, timer);
1061 /* see if hwndTrack isn't the current window */
1062 if(ptme->hwndTrack != hwnd) {
1064 PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
1067 /* See if this hwnd is already being tracked and update the tracking flags */
1068 for(i = 0; i < iTrackMax; i++) {
1069 if(TrackingList[i].tme.hwndTrack == ptme->hwndTrack) {
1071 TrackingList[i].tme.dwFlags |= TME_HOVER;
1072 TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime;
1076 TrackingList[i].tme.dwFlags |= TME_LEAVE;
1078 /* reset iHoverTime as per winapi specs */
1079 TrackingList[i].iHoverTime = 0;
1085 /* if the tracking list is full return FALSE */
1086 if (iTrackMax == sizeof (TrackingList) / sizeof(*TrackingList)) {
1090 /* Adding new mouse event to the tracking list */
1091 TrackingList[iTrackMax].tme = *ptme;
1093 /* Initialize HoverInfo variables even if not hover tracking */
1094 TrackingList[iTrackMax].iHoverTime = 0;
1095 TrackingList[iTrackMax].pos = pos;
1100 timer = SetTimer(0, 0, iTimerInterval, TrackMouseEventProc);
1109 /*************************************************************************
1110 * GetMUILanguage [COMCTL32.39]
1112 * FIXME: What's this supposed to do? Apparently some i18n thing.
1115 LANGID WINAPI GetMUILanguage (VOID)
1117 return COMCTL32_uiLang;
1121 /*************************************************************************
1122 * InitMUILanguage [COMCTL32.85]
1124 * FIXME: What's this supposed to do? Apparently some i18n thing.
1128 VOID WINAPI InitMUILanguage (LANGID uiLang)
1130 COMCTL32_uiLang = uiLang;