2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998,2000 Eric Kohl
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #define NO_SHLWAPI_STREAM
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
36 extern void ANIMATE_Register(void);
37 extern void ANIMATE_Unregister(void);
38 extern void COMBOEX_Register(void);
39 extern void COMBOEX_Unregister(void);
40 extern void DATETIME_Register(void);
41 extern void DATETIME_Unregister(void);
42 extern void FLATSB_Register(void);
43 extern void FLATSB_Unregister(void);
44 extern void HEADER_Register(void);
45 extern void HEADER_Unregister(void);
46 extern void HOTKEY_Register(void);
47 extern void HOTKEY_Unregister(void);
48 extern void IPADDRESS_Register(void);
49 extern void IPADDRESS_Unregister(void);
50 extern void LISTVIEW_Register(void);
51 extern void LISTVIEW_Unregister(void);
52 extern void MONTHCAL_Register(void);
53 extern void MONTHCAL_Unregister(void);
54 extern void NATIVEFONT_Register(void);
55 extern void NATIVEFONT_Unregister(void);
56 extern void PAGER_Register(void);
57 extern void PAGER_Unregister(void);
58 extern void PROGRESS_Register(void);
59 extern void PROGRESS_Unregister(void);
60 extern void REBAR_Register(void);
61 extern void REBAR_Unregister(void);
62 extern void STATUS_Register(void);
63 extern void STATUS_Unregister(void);
64 extern void TAB_Register(void);
65 extern void TAB_Unregister(void);
66 extern void TOOLBAR_Register(void);
67 extern void TOOLBAR_Unregister(void);
68 extern void TOOLTIPS_Register(void);
69 extern void TOOLTIPS_Unregister(void);
70 extern void TRACKBAR_Register(void);
71 extern void TRACKBAR_Unregister(void);
72 extern void TREEVIEW_Register(void);
73 extern void TREEVIEW_Unregister(void);
74 extern void UPDOWN_Register(void);
75 extern void UPDOWN_Unregister(void);
78 HANDLE COMCTL32_hHeap = (HANDLE)NULL;
79 LPSTR COMCTL32_aSubclass = (LPSTR)NULL;
80 HMODULE COMCTL32_hModule = 0;
81 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
82 HBRUSH COMCTL32_hPattern55AABrush = (HANDLE)NULL;
83 COMCTL32_SysColor comctl32_color;
85 static HBITMAP COMCTL32_hPattern55AABitmap = (HANDLE)NULL;
87 static const WORD wPattern55AA[] =
89 0x5555, 0xaaaa, 0x5555, 0xaaaa,
90 0x5555, 0xaaaa, 0x5555, 0xaaaa
94 /***********************************************************************
95 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
98 * hinstDLL [I] handle to the 'dlls' instance
100 * lpvReserved [I] reserverd, must be NULL
108 COMCTL32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
110 TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
113 case DLL_PROCESS_ATTACH:
114 COMCTL32_hModule = (HMODULE)hinstDLL;
116 /* create private heap */
117 COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
118 TRACE("Heap created: 0x%x\n", COMCTL32_hHeap);
120 /* add global subclassing atom (used by 'tooltip' and 'updown') */
121 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
122 TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
124 /* create local pattern brush */
125 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
126 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
128 /* Get all the colors at DLL load */
129 COMCTL32_RefreshSysColors();
131 /* register all Win95 common control classes */
136 LISTVIEW_Register ();
137 PROGRESS_Register ();
141 TOOLTIPS_Register ();
142 TRACKBAR_Register ();
143 TREEVIEW_Register ();
147 case DLL_PROCESS_DETACH:
148 /* unregister all common control classes */
149 ANIMATE_Unregister ();
150 COMBOEX_Unregister ();
151 DATETIME_Unregister ();
152 FLATSB_Unregister ();
153 HEADER_Unregister ();
154 HOTKEY_Unregister ();
155 IPADDRESS_Unregister ();
156 LISTVIEW_Unregister ();
157 MONTHCAL_Unregister ();
158 NATIVEFONT_Unregister ();
160 PROGRESS_Unregister ();
162 STATUS_Unregister ();
164 TOOLBAR_Unregister ();
165 TOOLTIPS_Unregister ();
166 TRACKBAR_Unregister ();
167 TREEVIEW_Unregister ();
168 UPDOWN_Unregister ();
170 /* delete local pattern brush */
171 DeleteObject (COMCTL32_hPattern55AABrush);
172 COMCTL32_hPattern55AABrush = (HANDLE)NULL;
173 DeleteObject (COMCTL32_hPattern55AABitmap);
174 COMCTL32_hPattern55AABitmap = (HANDLE)NULL;
176 /* delete global subclassing atom */
177 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
178 TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
179 COMCTL32_aSubclass = (LPSTR)NULL;
181 /* destroy private heap */
182 HeapDestroy (COMCTL32_hHeap);
183 TRACE("Heap destroyed: 0x%x\n", COMCTL32_hHeap);
184 COMCTL32_hHeap = (HANDLE)NULL;
192 /***********************************************************************
193 * MenuHelp [COMCTL32.2]
196 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
197 * wParam [I] wParam of the message uMsg
198 * lParam [I] lParam of the message uMsg
199 * hMainMenu [I] handle to the application's main menu
200 * hInst [I] handle to the module that contains string resources
201 * hwndStatus [I] handle to the status bar window
202 * lpwIDs [I] pointer to an array of integers (see NOTES)
208 * The official documentation is incomplete!
209 * This is the correct documentation:
212 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
213 * WM_MENUSELECT messages.
216 * (will be written ...)
220 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
221 HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
225 if (!IsWindow (hwndStatus))
230 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
233 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
234 /* menu was closed */
235 TRACE("menu was closed!\n");
236 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
239 /* menu item was selected */
240 if (HIWORD(wParam) & MF_POPUP)
241 uMenuID = (UINT)*(lpwIDs+1);
243 uMenuID = (UINT)LOWORD(wParam);
244 TRACE("uMenuID = %u\n", uMenuID);
249 if (!LoadStringA (hInst, uMenuID, szText, 256))
252 SendMessageA (hwndStatus, SB_SETTEXTA,
253 255 | SBT_NOBORDERS, (LPARAM)szText);
254 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
260 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
262 /* WM_COMMAND is not invalid since it is documented
263 * in the windows api reference. So don't output
264 * any FIXME for WM_COMMAND
266 WARN("We don't care about the WM_COMMAND\n");
270 FIXME("Invalid Message 0x%x!\n", uMsg);
276 /***********************************************************************
277 * ShowHideMenuCtl [COMCTL32.3]
279 * Shows or hides controls and updates the corresponding menu item.
282 * hwnd [I] handle to the client window.
283 * uFlags [I] menu command id.
284 * lpInfo [I] pointer to an array of integers. (See NOTES.)
291 * The official documentation is incomplete!
292 * This is the correct documentation:
295 * Handle to the window that contains the menu and controls.
298 * Identifier of the menu item to receive or loose a check mark.
301 * The array of integers contains pairs of values. BOTH values of
302 * the first pair must be the handles to the application's main menu.
303 * Each subsequent pair consists of a menu id and control id.
307 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
311 TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
316 if (!(lpInfo[0]) || !(lpInfo[1]))
319 /* search for control */
320 lpMenuId = &lpInfo[2];
321 while (*lpMenuId != uFlags)
324 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
325 /* uncheck menu item */
326 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
330 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
334 /* check menu item */
335 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
339 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
347 /***********************************************************************
348 * GetEffectiveClientRect [COMCTL32.4]
351 * hwnd [I] handle to the client window.
352 * lpRect [O] pointer to the rectangle of the client window
353 * lpInfo [I] pointer to an array of integers (see NOTES)
359 * The official documentation is incomplete!
360 * This is the correct documentation:
363 * (will be written...)
367 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
373 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
374 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
376 GetClientRect (hwnd, lpRect);
384 hwndCtrl = GetDlgItem (hwnd, *lpRun);
385 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
386 TRACE("control id 0x%x\n", *lpRun);
387 GetWindowRect (hwndCtrl, &rcCtrl);
388 MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2);
389 SubtractRect (lpRect, lpRect, &rcCtrl);
396 /***********************************************************************
397 * DrawStatusTextW [COMCTL32.@]
399 * Draws text with borders, like in a status bar.
402 * hdc [I] handle to the window's display context
403 * lprc [I] pointer to a rectangle
404 * text [I] pointer to the text
405 * style [I] drawing style
411 * The style variable can have one of the following values:
412 * (will be written ...)
415 void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
418 UINT border = BDR_SUNKENOUTER;
420 if (style & SBT_POPOUT)
421 border = BDR_RAISEDOUTER;
422 else if (style & SBT_NOBORDERS)
425 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
429 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
430 UINT align = DT_LEFT;
431 if (*text == L'\t') {
434 if (*text == L'\t') {
440 if (style & SBT_RTLREADING)
441 FIXME("Unsupported RTL style!\n");
442 DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
443 SetBkMode(hdc, oldbkmode);
448 /***********************************************************************
449 * DrawStatusText [COMCTL32.@]
450 * DrawStatusTextA [COMCTL32.5]
452 * Draws text with borders, like in a status bar.
455 * hdc [I] handle to the window's display context
456 * lprc [I] pointer to a rectangle
457 * text [I] pointer to the text
458 * style [I] drawing style
464 void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
470 if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
471 if ( (textW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )) )
472 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
475 DrawStatusTextW( hdc, lprc, textW, style );
476 HeapFree( GetProcessHeap(), 0, textW );
480 /***********************************************************************
481 * CreateStatusWindow [COMCTL32.@]
482 * CreateStatusWindowA [COMCTL32.6]
484 * Creates a status bar
487 * style [I] window style
488 * text [I] pointer to the window text
489 * parent [I] handle to the parent window
490 * wid [I] control id of the status bar
493 * Success: handle to the status window
498 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid)
500 return CreateWindowA(STATUSCLASSNAMEA, text, style,
501 CW_USEDEFAULT, CW_USEDEFAULT,
502 CW_USEDEFAULT, CW_USEDEFAULT,
507 /***********************************************************************
508 * CreateStatusWindowW [COMCTL32.@] Creates a status bar control
511 * style [I] window style
512 * text [I] pointer to the window text
513 * parent [I] handle to the parent window
514 * wid [I] control id of the status bar
517 * Success: handle to the status window
522 CreateStatusWindowW (INT style, LPCWSTR text, HWND parent, UINT wid)
524 return CreateWindowW(STATUSCLASSNAMEW, text, style,
525 CW_USEDEFAULT, CW_USEDEFAULT,
526 CW_USEDEFAULT, CW_USEDEFAULT,
531 /***********************************************************************
532 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
535 * style [I] window styles
536 * x [I] horizontal position of the control
537 * y [I] vertical position of the control
538 * cx [I] with of the control
539 * cy [I] height of the control
540 * parent [I] handle to the parent window
541 * id [I] the control's identifier
542 * inst [I] handle to the application's module instance
543 * buddy [I] handle to the buddy window, can be NULL
544 * maxVal [I] upper limit of the control
545 * minVal [I] lower limit of the control
546 * curVal [I] current value of the control
549 * Success: handle to the updown control
554 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
555 HWND parent, INT id, HINSTANCE inst,
556 HWND buddy, INT maxVal, INT minVal, INT curVal)
559 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
560 parent, id, inst, 0);
562 SendMessageA (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
563 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
564 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
571 /***********************************************************************
572 * InitCommonControls [COMCTL32.17]
574 * Registers the common controls.
583 * This function is just a dummy.
584 * The Win95 controls are registered at the DLL's initialization.
585 * To register other controls InitCommonControlsEx() must be used.
589 InitCommonControls (void)
594 /***********************************************************************
595 * InitCommonControlsEx [COMCTL32.@]
597 * Registers the common controls.
600 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
607 * Only the additional common controls are registered by this function.
608 * The Win95 controls are registered at the DLL's initialization.
612 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
619 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
622 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
624 for (cCount = 0; cCount < 32; cCount++) {
625 dwMask = 1 << cCount;
626 if (!(lpInitCtrls->dwICC & dwMask))
629 switch (lpInitCtrls->dwICC & dwMask) {
630 /* dummy initialization */
631 case ICC_ANIMATE_CLASS:
632 case ICC_BAR_CLASSES:
633 case ICC_LISTVIEW_CLASSES:
634 case ICC_TREEVIEW_CLASSES:
635 case ICC_TAB_CLASSES:
636 case ICC_UPDOWN_CLASS:
637 case ICC_PROGRESS_CLASS:
638 case ICC_HOTKEY_CLASS:
641 /* advanced classes - not included in Win95 */
642 case ICC_DATE_CLASSES:
643 MONTHCAL_Register ();
644 DATETIME_Register ();
647 case ICC_USEREX_CLASSES:
651 case ICC_COOL_CLASSES:
655 case ICC_INTERNET_CLASSES:
656 IPADDRESS_Register ();
659 case ICC_PAGESCROLLER_CLASS:
663 case ICC_NATIVEFNTCTL_CLASS:
664 NATIVEFONT_Register ();
668 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
677 /***********************************************************************
678 * CreateToolbarEx [COMCTL32.@] Creates a tool bar window
696 * Success: handle to the tool bar control
701 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
702 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
703 INT iNumButtons, INT dxButton, INT dyButton,
704 INT dxBitmap, INT dyBitmap, UINT uStructSize)
708 /* If not position is specified then put it at the top */
709 if ((style & CCS_BOTTOM) == 0) {
714 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style|WS_CHILD, 0, 0, 0, 0,
715 hwnd, (HMENU)wID, 0, NULL);
719 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
720 (WPARAM)uStructSize, 0);
722 /* set bitmap and button size */
723 /*If CreateToolbarEx receives 0, windows sets default values*/
728 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
729 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
735 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
736 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
742 tbab.hInst = hBMInst;
745 SendMessageA (hwndTB, TB_ADDBITMAP,
746 (WPARAM)nBitmaps, (LPARAM)&tbab);
750 SendMessageA (hwndTB, TB_ADDBUTTONSA,
751 (WPARAM)iNumButtons, (LPARAM)lpButtons);
758 /***********************************************************************
759 * CreateMappedBitmap [COMCTL32.8]
769 * Success: handle to the new bitmap
774 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
775 LPCOLORMAP lpColorMap, INT iNumMaps)
779 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
780 UINT nSize, nColorTableSize;
781 RGBQUAD *pColorTable;
782 INT iColor, i, iMaps, nWidth, nHeight;
785 LPCOLORMAP sysColorMap;
787 COLORMAP internalColorMap[4] =
788 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
790 /* initialize pointer to colortable and default color table */
793 sysColorMap = lpColorMap;
796 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
797 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
798 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
799 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
801 sysColorMap = (LPCOLORMAP)internalColorMap;
804 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
807 hglb = LoadResource (hInstance, hRsrc);
810 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
811 if (lpBitmap == NULL)
814 nColorTableSize = (1 << lpBitmap->biBitCount);
815 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
816 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
817 if (lpBitmapInfo == NULL)
819 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
821 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
823 for (iColor = 0; iColor < nColorTableSize; iColor++) {
824 for (i = 0; i < iMaps; i++) {
825 cRef = RGB(pColorTable[iColor].rgbRed,
826 pColorTable[iColor].rgbGreen,
827 pColorTable[iColor].rgbBlue);
828 if ( cRef == sysColorMap[i].from) {
830 if (wFlags & CBS_MASKED) {
831 if (sysColorMap[i].to != COLOR_BTNTEXT)
832 pColorTable[iColor] = RGB(255, 255, 255);
836 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
837 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
838 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
843 nWidth = (INT)lpBitmapInfo->biWidth;
844 nHeight = (INT)lpBitmapInfo->biHeight;
845 hdcScreen = GetDC ((HWND)0);
846 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
848 HDC hdcDst = CreateCompatibleDC (hdcScreen);
849 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
850 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
851 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
852 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
853 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
855 SelectObject (hdcDst, hbmOld);
858 ReleaseDC ((HWND)0, hdcScreen);
859 GlobalFree ((HGLOBAL)lpBitmapInfo);
866 /***********************************************************************
867 * CreateToolbar [COMCTL32.7] Creates a tool bar control
880 * Success: handle to the tool bar control
884 * Do not use this functions anymore. Use CreateToolbarEx instead.
888 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
889 HINSTANCE hBMInst, UINT wBMID,
890 LPCOLDTBBUTTON lpButtons,INT iNumButtons)
892 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
893 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
894 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
898 /***********************************************************************
899 * DllGetVersion [COMCTL32.@]
901 * Retrieves version information of the 'COMCTL32.DLL'
904 * pdvi [O] pointer to version information structure.
908 * Failure: E_INVALIDARG
911 * Returns version of a comctl32.dll from IE4.01 SP1.
915 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
917 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
918 WARN("wrong DLLVERSIONINFO size from app\n");
922 pdvi->dwMajorVersion = COMCTL32_VERSION;
923 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
924 pdvi->dwBuildNumber = 2919;
925 pdvi->dwPlatformID = 6304;
927 TRACE("%lu.%lu.%lu.%lu\n",
928 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
929 pdvi->dwBuildNumber, pdvi->dwPlatformID);
934 /***********************************************************************
935 * DllInstall (COMCTL32.@)
937 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
939 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
940 debugstr_w(cmdline));
945 /***********************************************************************
946 * _TrackMouseEvent [COMCTL32.@]
948 * Requests notification of mouse events
950 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
951 * to the hwnd specified in the ptme structure. After the event message
952 * is posted to the hwnd, the entry in the queue is removed.
954 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
955 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
956 * immediately and the TME_LEAVE flag being ignored.
959 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
965 * IMPLEMENTATION moved to USER32.TrackMouseEvent
970 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
972 return TrackMouseEvent (ptme);
975 /*************************************************************************
976 * GetMUILanguage [COMCTL32.@]
978 * FIXME: What's this supposed to do? Apparently some i18n thing.
981 LANGID WINAPI GetMUILanguage (VOID)
983 return COMCTL32_uiLang;
987 /*************************************************************************
988 * InitMUILanguage [COMCTL32.@]
990 * FIXME: What's this supposed to do? Apparently some i18n thing.
994 VOID WINAPI InitMUILanguage (LANGID uiLang)
996 COMCTL32_uiLang = uiLang;
1000 /***********************************************************************
1001 * SetWindowSubclass [COMCTL32.@]
1003 * Starts a window subclass
1006 * hWnd [in] handle to window subclass.
1007 * pfnSubclass [in] Pointer to new window procedure.
1008 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1009 * dwRef [in] Reference data to pass to window procedure.
1016 * If an application manually subclasses a window after subclassing it with
1017 * this API and then with this API again, then none of the previous
1018 * subclasses get called or the origional window procedure.
1020 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1021 UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1023 LPSUBCLASS_INFO stack;
1026 TRACE ("(%x, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
1028 /* Since the window procedure that we set here has two additional arguments,
1029 * we can't simply set it as the new window procedure of the window. So we
1030 * set our own window procedure and then calculate the other two arguments
1033 /* See if we have been called for this window */
1034 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1036 /* allocate stack */
1037 stack = (LPSUBCLASS_INFO)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY,
1038 sizeof(SUBCLASS_INFO));
1040 ERR ("Failed to allocate our Subclassing stack");
1043 SetPropA (hWnd, COMCTL32_aSubclass, (HANDLE)stack);
1045 /* set window procedure to our own and save the current one */
1046 if (IsWindowUnicode (hWnd))
1047 stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC,
1048 (LONG)DefSubclassProc);
1050 stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC,
1051 (LONG)DefSubclassProc);
1054 if (IsWindowUnicode (hWnd))
1055 current = (WNDPROC)GetWindowLongW (hWnd, GWL_WNDPROC);
1057 current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC);
1059 if (current != DefSubclassProc) {
1060 ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n");
1065 /* Check to see if we have called this function with the same uIDSubClass
1066 * and pfnSubclass */
1067 for (n = 0; n <= stack->stacknum + stack->stacknew - 1; n++)
1068 if ((stack->SubclassProcs[n].id == uIDSubclass) &&
1069 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1070 stack->SubclassProcs[n].ref = dwRef;
1074 if ((stack->stacknum + stack->stacknew) >= 32) {
1075 ERR ("We have a Subclass stack overflow, please increment size");
1079 /* we can't simply increment both stackpos and stacknum because there might
1080 * be a window procedure running lower in the stack, we can only get them
1081 * up to date once the last window procedure has run */
1082 if (stack->stacknum == stack->stackpos) {
1088 newnum = stack->stacknew + stack->stacknum - 1;
1090 stack->SubclassProcs[newnum].subproc = pfnSubclass;
1091 stack->SubclassProcs[newnum].ref = dwRef;
1092 stack->SubclassProcs[newnum].id = uIDSubclass;
1098 /***********************************************************************
1099 * GetWindowSubclass [COMCTL32.@]
1101 * Gets the Reference data from a subclass.
1104 * hWnd [in] Handle to window which were subclassing
1105 * pfnSubclass [in] Pointer to the subclass procedure
1106 * iID [in] Unique indentifier of the subclassing procedure
1107 * pdwRef [out] Pointer to the reference data
1113 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1114 UINT_PTR uID, DWORD_PTR *pdwRef)
1116 LPSUBCLASS_INFO stack;
1119 TRACE ("(%x, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
1121 /* See if we have been called for this window */
1122 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1126 for (n = 0; n <= stack->stacknum + stack->stacknew - 1; n++)
1127 if ((stack->SubclassProcs[n].id == uID) &&
1128 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1129 *pdwRef = stack->SubclassProcs[n].ref;
1137 /***********************************************************************
1138 * RemoveWindowSubclass [COMCTL32.@]
1140 * Removes a window subclass.
1143 * hWnd [in] Handle to the window were subclassing
1144 * pfnSubclass [in] Pointer to the subclass procedure
1145 * uID [in] Unique identifier of this subclass
1151 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1153 LPSUBCLASS_INFO stack;
1156 TRACE ("(%x, %p, %x)\n", hWnd, pfnSubclass, uID);
1158 /* Find the Subclass to remove */
1159 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1163 if ((stack->stacknum == stack->stackpos == 1) && !stack->stacknew) {
1164 TRACE("Last Subclass removed, cleaning up\n");
1165 /* clean up our heap and reset the origional window procedure */
1166 if (IsWindowUnicode (hWnd))
1167 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1169 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1170 HeapFree (GetProcessHeap (), 0, stack);
1174 for (n = stack->stacknum + stack->stacknew - 1; n >= 0; n--)
1175 if ((stack->SubclassProcs[n].id == uID) &&
1176 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1177 if (n != (stack->stacknum + stack->stacknew))
1178 /* Fill the hole in the stack */
1179 memmove (&stack->SubclassProcs[n], &stack->SubclassProcs[n + 1],
1180 sizeof(stack->SubclassProcs[0]) * (stack->stacknew + stack->stacknum - n));
1181 stack->SubclassProcs[n].subproc = NULL;
1182 stack->SubclassProcs[n].ref = 0;
1183 stack->SubclassProcs[n].id = 0;
1185 /* If we are currently running a window procedure we have to manipulate
1186 * the stack position pointers so that we don't corrupt the stack */
1187 if ((n < stack->stackpos) || (stack->stackpos == stack->stacknum)) {
1190 } else if (n >= stack->stackpos)
1199 /***********************************************************************
1200 * DefSubclassProc [COMCTL32.@]
1202 * Calls the next window procedure (ie. the one before this subclass)
1205 * hWnd [in] The window that we're subclassing
1207 * wParam [in] WPARAM
1208 * lParam [in] LPARAM
1214 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1216 LPSUBCLASS_INFO stack;
1220 /* retrieve our little stack from the Properties */
1221 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1223 ERR ("Our sub classing stack got erased for %x!! Nothing we can do\n", hWnd);
1227 /* If we are at pos 0 then we have to call the origional window procedure */
1228 if (stack->stackpos == 0) {
1229 if (IsWindowUnicode (hWnd))
1230 return CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
1232 return CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1235 stackpos = --stack->stackpos;
1236 /* call the Subclass procedure from the stack */
1237 ret = stack->SubclassProcs[stackpos].subproc (hWnd, uMsg, wParam, lParam,
1238 stack->SubclassProcs[stackpos].id, stack->SubclassProcs[stackpos].ref);
1241 if ((stack->stackpos == stack->stacknum) && stack->stacknew) {
1242 stack->stacknum += stack->stacknew;
1243 stack->stackpos += stack->stacknew;
1244 stack->stacknew = 0;
1247 /* If we removed the last entry in our stack while a window procedure was
1248 * running then we have to clean up */
1249 if (stack->stackpos == stack->stacknum == 0) {
1250 TRACE("Last Subclass removed, cleaning up\n");
1251 /* clean up our heap and reset the origional window procedure */
1252 if (IsWindowUnicode (hWnd))
1253 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1255 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1256 HeapFree (GetProcessHeap (), 0, stack);
1264 /***********************************************************************
1265 * COMCTL32_CreateToolTip [NOT AN API]
1267 * Creates a tooltip for the control specified in hwnd and does all
1268 * necessary setup and notifications.
1271 * hwndOwner [I] Handle to the window that will own the tool tip.
1274 * Success: Handle of tool tip window.
1278 COMCTL32_CreateToolTip(HWND hwndOwner)
1282 hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1283 CW_USEDEFAULT, CW_USEDEFAULT,
1284 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1287 /* Send NM_TOOLTIPSCREATED notification */
1290 NMTOOLTIPSCREATED nmttc;
1291 /* true owner can be different if hwndOwner is a child window */
1292 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1293 nmttc.hdr.hwndFrom = hwndTrueOwner;
1294 nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID);
1295 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1296 nmttc.hwndToolTips = hwndToolTip;
1298 SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1299 (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID),
1307 /***********************************************************************
1308 * COMCTL32_RefreshSysColors [NOT AN API]
1310 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1311 * refresh the color values in the color structure
1320 COMCTL32_RefreshSysColors(void)
1322 comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1323 comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1324 comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1325 comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1326 comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1327 comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
1328 comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1329 comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1330 comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1331 comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1332 comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1333 comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1334 comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1335 comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1336 comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1337 comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);