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
23 * This code was audited for completeness against the documented features
24 * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.
26 * Unless otherwise noted, we believe this code to be complete, as per
27 * the specification mentioned above.
28 * If you discover missing features, or bugs, please note them below.
31 * -- implement GetMUILanguage + InitMUILanguage
32 * -- LibMain => DLLMain ("DLLMain takes over the functionality of both the
33 * LibMain and the WEP function.", MSDN)
34 * -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
35 * -- FIXMEs + BUGS (search for them)
38 * -- ICC_ANIMATE_CLASS
43 * -- ICC_INTERNET_CLASSES
44 * -- ICC_LINK_CLASS (not yet implemented)
45 * -- ICC_LISTVIEW_CLASSES
46 * -- ICC_NATIVEFNTCTL_CLASS
47 * -- ICC_PAGESCROLLER_CLASS
48 * -- ICC_PROGRESS_CLASS
49 * -- ICC_STANDARD_CLASSES (not yet implemented)
51 * -- ICC_TREEVIEW_CLASSES
53 * -- ICC_USEREX_CLASSES
54 * -- ICC_WIN95_CLASSES
69 #define NO_SHLWAPI_STREAM
72 #include "wine/debug.h"
74 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
76 extern void ANIMATE_Register(void);
77 extern void ANIMATE_Unregister(void);
78 extern void COMBOEX_Register(void);
79 extern void COMBOEX_Unregister(void);
80 extern void DATETIME_Register(void);
81 extern void DATETIME_Unregister(void);
82 extern void FLATSB_Register(void);
83 extern void FLATSB_Unregister(void);
84 extern void HEADER_Register(void);
85 extern void HEADER_Unregister(void);
86 extern void HOTKEY_Register(void);
87 extern void HOTKEY_Unregister(void);
88 extern void IPADDRESS_Register(void);
89 extern void IPADDRESS_Unregister(void);
90 extern void LISTVIEW_Register(void);
91 extern void LISTVIEW_Unregister(void);
92 extern void MONTHCAL_Register(void);
93 extern void MONTHCAL_Unregister(void);
94 extern void NATIVEFONT_Register(void);
95 extern void NATIVEFONT_Unregister(void);
96 extern void PAGER_Register(void);
97 extern void PAGER_Unregister(void);
98 extern void PROGRESS_Register(void);
99 extern void PROGRESS_Unregister(void);
100 extern void REBAR_Register(void);
101 extern void REBAR_Unregister(void);
102 extern void STATUS_Register(void);
103 extern void STATUS_Unregister(void);
104 extern void TAB_Register(void);
105 extern void TAB_Unregister(void);
106 extern void TOOLBAR_Register(void);
107 extern void TOOLBAR_Unregister(void);
108 extern void TOOLTIPS_Register(void);
109 extern void TOOLTIPS_Unregister(void);
110 extern void TRACKBAR_Register(void);
111 extern void TRACKBAR_Unregister(void);
112 extern void TREEVIEW_Register(void);
113 extern void TREEVIEW_Unregister(void);
114 extern void UPDOWN_Register(void);
115 extern void UPDOWN_Unregister(void);
118 LPSTR COMCTL32_aSubclass = NULL;
119 HMODULE COMCTL32_hModule = 0;
120 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
121 HBRUSH COMCTL32_hPattern55AABrush = NULL;
122 COMCTL32_SysColor comctl32_color;
124 static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
126 static const WORD wPattern55AA[] =
128 0x5555, 0xaaaa, 0x5555, 0xaaaa,
129 0x5555, 0xaaaa, 0x5555, 0xaaaa
133 /***********************************************************************
136 * Initializes the internal 'COMCTL32.DLL'.
139 * hinstDLL [I] handle to the 'dlls' instance
141 * lpvReserved [I] reserverd, must be NULL
148 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
150 TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
153 case DLL_PROCESS_ATTACH:
154 DisableThreadLibraryCalls(hinstDLL);
156 COMCTL32_hModule = (HMODULE)hinstDLL;
158 /* add global subclassing atom (used by 'tooltip' and 'updown') */
159 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
160 TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
162 /* create local pattern brush */
163 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
164 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
166 /* Get all the colors at DLL load */
167 COMCTL32_RefreshSysColors();
169 /* register all Win95 common control classes */
174 LISTVIEW_Register ();
175 PROGRESS_Register ();
179 TOOLTIPS_Register ();
180 TRACKBAR_Register ();
181 TREEVIEW_Register ();
185 case DLL_PROCESS_DETACH:
186 /* unregister all common control classes */
187 ANIMATE_Unregister ();
188 COMBOEX_Unregister ();
189 DATETIME_Unregister ();
190 FLATSB_Unregister ();
191 HEADER_Unregister ();
192 HOTKEY_Unregister ();
193 IPADDRESS_Unregister ();
194 LISTVIEW_Unregister ();
195 MONTHCAL_Unregister ();
196 NATIVEFONT_Unregister ();
198 PROGRESS_Unregister ();
200 STATUS_Unregister ();
202 TOOLBAR_Unregister ();
203 TOOLTIPS_Unregister ();
204 TRACKBAR_Unregister ();
205 TREEVIEW_Unregister ();
206 UPDOWN_Unregister ();
208 /* delete local pattern brush */
209 DeleteObject (COMCTL32_hPattern55AABrush);
210 COMCTL32_hPattern55AABrush = NULL;
211 DeleteObject (COMCTL32_hPattern55AABitmap);
212 COMCTL32_hPattern55AABitmap = NULL;
214 /* delete global subclassing atom */
215 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
216 TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
217 COMCTL32_aSubclass = NULL;
225 /***********************************************************************
226 * MenuHelp [COMCTL32.2]
228 * Handles the setting of status bar help messages when the user
229 * selects menu items.
232 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
233 * wParam [I] wParam of the message uMsg
234 * lParam [I] lParam of the message uMsg
235 * hMainMenu [I] handle to the application's main menu
236 * hInst [I] handle to the module that contains string resources
237 * hwndStatus [I] handle to the status bar window
238 * lpwIDs [I] pointer to an array of integers (see NOTES)
244 * The official documentation is incomplete!
245 * This is the correct documentation:
248 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
249 * WM_MENUSELECT messages.
252 * (will be written ...)
256 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
257 HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
261 if (!IsWindow (hwndStatus))
266 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
269 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
270 /* menu was closed */
271 TRACE("menu was closed!\n");
272 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
275 /* menu item was selected */
276 if (HIWORD(wParam) & MF_POPUP)
277 uMenuID = (UINT)*(lpwIDs+1);
279 uMenuID = (UINT)LOWORD(wParam);
280 TRACE("uMenuID = %u\n", uMenuID);
285 if (!LoadStringA (hInst, uMenuID, szText, 256))
288 SendMessageA (hwndStatus, SB_SETTEXTA,
289 255 | SBT_NOBORDERS, (LPARAM)szText);
290 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
296 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
298 /* WM_COMMAND is not invalid since it is documented
299 * in the windows api reference. So don't output
300 * any FIXME for WM_COMMAND
302 WARN("We don't care about the WM_COMMAND\n");
306 FIXME("Invalid Message 0x%x!\n", uMsg);
312 /***********************************************************************
313 * ShowHideMenuCtl [COMCTL32.3]
315 * Shows or hides controls and updates the corresponding menu item.
318 * hwnd [I] handle to the client window.
319 * uFlags [I] menu command id.
320 * lpInfo [I] pointer to an array of integers. (See NOTES.)
327 * The official documentation is incomplete!
328 * This is the correct documentation:
331 * Handle to the window that contains the menu and controls.
334 * Identifier of the menu item to receive or loose a check mark.
337 * The array of integers contains pairs of values. BOTH values of
338 * the first pair must be the handles to the application's main menu.
339 * Each subsequent pair consists of a menu id and control id.
343 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
347 TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo);
352 if (!(lpInfo[0]) || !(lpInfo[1]))
355 /* search for control */
356 lpMenuId = &lpInfo[2];
357 while (*lpMenuId != uFlags)
360 if (GetMenuState ((HMENU)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
361 /* uncheck menu item */
362 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
366 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
370 /* check menu item */
371 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
375 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
383 /***********************************************************************
384 * GetEffectiveClientRect [COMCTL32.4]
386 * Calculates the coordinates of a rectangle in the client area.
389 * hwnd [I] handle to the client window.
390 * lpRect [O] pointer to the rectangle of the client window
391 * lpInfo [I] pointer to an array of integers (see NOTES)
397 * The official documentation is incomplete!
398 * This is the correct documentation:
401 * (will be written ...)
405 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
411 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
412 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
414 GetClientRect (hwnd, lpRect);
422 hwndCtrl = GetDlgItem (hwnd, *lpRun);
423 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
424 TRACE("control id 0x%x\n", *lpRun);
425 GetWindowRect (hwndCtrl, &rcCtrl);
426 MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
427 SubtractRect (lpRect, lpRect, &rcCtrl);
434 /***********************************************************************
435 * DrawStatusTextW [COMCTL32.@]
437 * Draws text with borders, like in a status bar.
440 * hdc [I] handle to the window's display context
441 * lprc [I] pointer to a rectangle
442 * text [I] pointer to the text
443 * style [I] drawing style
449 * The style variable can have one of the following values:
450 * (will be written ...)
453 void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
456 UINT border = BDR_SUNKENOUTER;
458 if (style & SBT_POPOUT)
459 border = BDR_RAISEDOUTER;
460 else if (style & SBT_NOBORDERS)
463 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
467 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
468 UINT align = DT_LEFT;
469 if (*text == L'\t') {
472 if (*text == L'\t') {
478 if (style & SBT_RTLREADING)
479 FIXME("Unsupported RTL style!\n");
480 DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
481 SetBkMode(hdc, oldbkmode);
486 /***********************************************************************
487 * DrawStatusText [COMCTL32.@]
488 * DrawStatusTextA [COMCTL32.5]
490 * Draws text with borders, like in a status bar.
493 * hdc [I] handle to the window's display context
494 * lprc [I] pointer to a rectangle
495 * text [I] pointer to the text
496 * style [I] drawing style
502 void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
508 if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
509 if ( (textW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )) )
510 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
513 DrawStatusTextW( hdc, lprc, textW, style );
514 HeapFree( GetProcessHeap(), 0, textW );
518 /***********************************************************************
519 * CreateStatusWindow [COMCTL32.@]
520 * CreateStatusWindowA [COMCTL32.6]
522 * Creates a status bar
525 * style [I] window style
526 * text [I] pointer to the window text
527 * parent [I] handle to the parent window
528 * wid [I] control id of the status bar
531 * Success: handle to the status window
536 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
538 return CreateWindowA(STATUSCLASSNAMEA, text, style,
539 CW_USEDEFAULT, CW_USEDEFAULT,
540 CW_USEDEFAULT, CW_USEDEFAULT,
541 parent, (HMENU)wid, 0, 0);
545 /***********************************************************************
546 * CreateStatusWindowW [COMCTL32.@]
548 * Creates a status bar control
551 * style [I] window style
552 * text [I] pointer to the window text
553 * parent [I] handle to the parent window
554 * wid [I] control id of the status bar
557 * Success: handle to the status window
562 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
564 return CreateWindowW(STATUSCLASSNAMEW, text, style,
565 CW_USEDEFAULT, CW_USEDEFAULT,
566 CW_USEDEFAULT, CW_USEDEFAULT,
567 parent, (HMENU)wid, 0, 0);
571 /***********************************************************************
572 * CreateUpDownControl [COMCTL32.16]
574 * Creates an up-down control
577 * style [I] window styles
578 * x [I] horizontal position of the control
579 * y [I] vertical position of the control
580 * cx [I] with of the control
581 * cy [I] height of the control
582 * parent [I] handle to the parent window
583 * id [I] the control's identifier
584 * inst [I] handle to the application's module instance
585 * buddy [I] handle to the buddy window, can be NULL
586 * maxVal [I] upper limit of the control
587 * minVal [I] lower limit of the control
588 * curVal [I] current value of the control
591 * Success: handle to the updown control
596 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
597 HWND parent, INT id, HINSTANCE inst,
598 HWND buddy, INT maxVal, INT minVal, INT curVal)
601 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
602 parent, (HMENU)id, inst, 0);
604 SendMessageA (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
605 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
606 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
613 /***********************************************************************
614 * InitCommonControls [COMCTL32.17]
616 * Registers the common controls.
625 * This function is just a dummy.
626 * The Win95 controls are registered at the DLL's initialization.
627 * To register other controls InitCommonControlsEx() must be used.
631 InitCommonControls (void)
636 /***********************************************************************
637 * InitCommonControlsEx [COMCTL32.@]
639 * Registers the common controls.
642 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
649 * Only the additional common controls are registered by this function.
650 * The Win95 controls are registered at the DLL's initialization.
653 * implement the following control classes:
655 * ICC_STANDARD_CLASSES
659 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
666 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
669 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
671 for (cCount = 0; cCount < 32; cCount++) {
672 dwMask = 1 << cCount;
673 if (!(lpInitCtrls->dwICC & dwMask))
676 switch (lpInitCtrls->dwICC & dwMask) {
677 /* dummy initialization */
678 case ICC_ANIMATE_CLASS:
679 case ICC_BAR_CLASSES:
680 case ICC_LISTVIEW_CLASSES:
681 case ICC_TREEVIEW_CLASSES:
682 case ICC_TAB_CLASSES:
683 case ICC_UPDOWN_CLASS:
684 case ICC_PROGRESS_CLASS:
685 case ICC_HOTKEY_CLASS:
688 /* advanced classes - not included in Win95 */
689 case ICC_DATE_CLASSES:
690 MONTHCAL_Register ();
691 DATETIME_Register ();
694 case ICC_USEREX_CLASSES:
698 case ICC_COOL_CLASSES:
702 case ICC_INTERNET_CLASSES:
703 IPADDRESS_Register ();
706 case ICC_PAGESCROLLER_CLASS:
710 case ICC_NATIVEFNTCTL_CLASS:
711 NATIVEFONT_Register ();
715 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
724 /***********************************************************************
725 * CreateToolbarEx [COMCTL32.@]
727 * Creates a toolbar window.
745 * Success: handle to the tool bar control
750 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
751 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
752 INT iNumButtons, INT dxButton, INT dyButton,
753 INT dxBitmap, INT dyBitmap, UINT uStructSize)
758 CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL, style|WS_CHILD, 0,0,100,30,
759 hwnd, (HMENU)wID, COMCTL32_hModule, NULL);
763 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
764 (WPARAM)uStructSize, 0);
766 /* set bitmap and button size */
767 /*If CreateToolbarEx receives 0, windows sets default values*/
772 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
773 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
779 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
780 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
786 tbab.hInst = hBMInst;
789 SendMessageA (hwndTB, TB_ADDBITMAP,
790 (WPARAM)nBitmaps, (LPARAM)&tbab);
794 SendMessageA (hwndTB, TB_ADDBUTTONSA,
795 (WPARAM)iNumButtons, (LPARAM)lpButtons);
802 /***********************************************************************
803 * CreateMappedBitmap [COMCTL32.8]
805 * Loads a bitmap resource using a colour map.
808 * hInstance [I] Handle to the module containing the bitmap.
809 * idBitmap [I] The bitmap resource ID.
810 * wFlags [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
811 * lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
812 * iNumMaps [I] Number of COLORMAP's pointed to by lpColorMap.
815 * Success: handle to the new bitmap
820 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
821 LPCOLORMAP lpColorMap, INT iNumMaps)
825 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
826 UINT nSize, nColorTableSize;
827 RGBQUAD *pColorTable;
828 INT iColor, i, iMaps, nWidth, nHeight;
831 LPCOLORMAP sysColorMap;
833 COLORMAP internalColorMap[4] =
834 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
836 /* initialize pointer to colortable and default color table */
839 sysColorMap = lpColorMap;
842 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
843 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
844 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
845 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
847 sysColorMap = (LPCOLORMAP)internalColorMap;
850 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, (LPSTR)RT_BITMAP);
853 hglb = LoadResource (hInstance, hRsrc);
856 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
857 if (lpBitmap == NULL)
860 if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
861 nColorTableSize = lpBitmap->biClrUsed;
862 else if (lpBitmap->biBitCount <= 8)
863 nColorTableSize = (1 << lpBitmap->biBitCount);
866 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
867 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
868 if (lpBitmapInfo == NULL)
870 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
872 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
874 for (iColor = 0; iColor < nColorTableSize; iColor++) {
875 for (i = 0; i < iMaps; i++) {
876 cRef = RGB(pColorTable[iColor].rgbRed,
877 pColorTable[iColor].rgbGreen,
878 pColorTable[iColor].rgbBlue);
879 if ( cRef == sysColorMap[i].from) {
881 if (wFlags & CBS_MASKED) {
882 if (sysColorMap[i].to != COLOR_BTNTEXT)
883 pColorTable[iColor] = RGB(255, 255, 255);
887 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
888 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
889 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
894 nWidth = (INT)lpBitmapInfo->biWidth;
895 nHeight = (INT)lpBitmapInfo->biHeight;
896 hdcScreen = GetDC (NULL);
897 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
899 HDC hdcDst = CreateCompatibleDC (hdcScreen);
900 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
901 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
902 lpBits += nColorTableSize * sizeof(RGBQUAD);
903 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
904 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
906 SelectObject (hdcDst, hbmOld);
909 ReleaseDC (NULL, hdcScreen);
910 GlobalFree ((HGLOBAL)lpBitmapInfo);
917 /***********************************************************************
918 * CreateToolbar [COMCTL32.7]
920 * Creates a toolbar control.
933 * Success: handle to the tool bar control
937 * Do not use this functions anymore. Use CreateToolbarEx instead.
941 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
942 HINSTANCE hBMInst, UINT wBMID,
943 LPCTBBUTTON lpButtons,INT iNumButtons)
945 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
946 hBMInst, wBMID, lpButtons,
947 iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
951 /***********************************************************************
952 * DllGetVersion [COMCTL32.@]
954 * Retrieves version information of the 'COMCTL32.DLL'
957 * pdvi [O] pointer to version information structure.
961 * Failure: E_INVALIDARG
964 * Returns version of a comctl32.dll from IE4.01 SP1.
968 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
970 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
971 WARN("wrong DLLVERSIONINFO size from app\n");
975 pdvi->dwMajorVersion = COMCTL32_VERSION;
976 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
977 pdvi->dwBuildNumber = 2919;
978 pdvi->dwPlatformID = 6304;
980 TRACE("%lu.%lu.%lu.%lu\n",
981 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
982 pdvi->dwBuildNumber, pdvi->dwPlatformID);
987 /***********************************************************************
988 * DllInstall (COMCTL32.@)
990 * Installs the ComCtl32 DLL.
994 * Failure: A HRESULT error
996 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
998 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
999 debugstr_w(cmdline));
1004 /***********************************************************************
1005 * _TrackMouseEvent [COMCTL32.@]
1007 * Requests notification of mouse events
1009 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1010 * to the hwnd specified in the ptme structure. After the event message
1011 * is posted to the hwnd, the entry in the queue is removed.
1013 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1014 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1015 * immediately and the TME_LEAVE flag being ignored.
1018 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1024 * IMPLEMENTATION moved to USER32.TrackMouseEvent
1029 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1031 return TrackMouseEvent (ptme);
1034 /*************************************************************************
1035 * GetMUILanguage [COMCTL32.@]
1037 * Returns the user interface language in use by the current process.
1040 * Language ID in use by the current process.
1042 LANGID WINAPI GetMUILanguage (VOID)
1044 return COMCTL32_uiLang;
1048 /*************************************************************************
1049 * InitMUILanguage [COMCTL32.@]
1051 * Sets the user interface language to be used by the current process.
1056 VOID WINAPI InitMUILanguage (LANGID uiLang)
1058 COMCTL32_uiLang = uiLang;
1062 /***********************************************************************
1063 * SetWindowSubclass [COMCTL32.410]
1065 * Starts a window subclass
1068 * hWnd [in] handle to window subclass.
1069 * pfnSubclass [in] Pointer to new window procedure.
1070 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1071 * dwRef [in] Reference data to pass to window procedure.
1078 * If an application manually subclasses a window after subclassing it with
1079 * this API and then with this API again, then none of the previous
1080 * subclasses get called or the origional window procedure.
1083 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1084 UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1086 LPSUBCLASS_INFO stack;
1089 TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
1091 /* Since the window procedure that we set here has two additional arguments,
1092 * we can't simply set it as the new window procedure of the window. So we
1093 * set our own window procedure and then calculate the other two arguments
1096 /* See if we have been called for this window */
1097 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1099 /* allocate stack */
1100 stack = (LPSUBCLASS_INFO)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY,
1101 sizeof(SUBCLASS_INFO));
1103 ERR ("Failed to allocate our Subclassing stack\n");
1106 SetPropA (hWnd, COMCTL32_aSubclass, (HANDLE)stack);
1108 /* set window procedure to our own and save the current one */
1109 if (IsWindowUnicode (hWnd))
1110 stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC,
1111 (LONG)DefSubclassProc);
1113 stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC,
1114 (LONG)DefSubclassProc);
1117 if (IsWindowUnicode (hWnd))
1118 current = (WNDPROC)GetWindowLongW (hWnd, GWL_WNDPROC);
1120 current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC);
1122 if (current != DefSubclassProc) {
1123 ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n");
1128 /* Check to see if we have called this function with the same uIDSubClass
1129 * and pfnSubclass */
1130 for (n = 0; n < stack->stacknum; n++)
1131 if ((stack->SubclassProcs[n].id == uIDSubclass) &&
1132 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1133 stack->SubclassProcs[n].ref = dwRef;
1137 if (stack->stacknum >= 32) {
1138 ERR ("We have a Subclass stack overflow, please increment size\n");
1142 memmove (&stack->SubclassProcs[1], &stack->SubclassProcs[0],
1143 sizeof(stack->SubclassProcs[0]) * stack->stacknum);
1146 if (stack->wndprocrecursion)
1149 stack->SubclassProcs[0].subproc = pfnSubclass;
1150 stack->SubclassProcs[0].ref = dwRef;
1151 stack->SubclassProcs[0].id = uIDSubclass;
1157 /***********************************************************************
1158 * GetWindowSubclass [COMCTL32.411]
1160 * Gets the Reference data from a subclass.
1163 * hWnd [in] Handle to window which were subclassing
1164 * pfnSubclass [in] Pointer to the subclass procedure
1165 * uID [in] Unique indentifier of the subclassing procedure
1166 * pdwRef [out] Pointer to the reference data
1173 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1174 UINT_PTR uID, DWORD_PTR *pdwRef)
1176 LPSUBCLASS_INFO stack;
1179 TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
1181 /* See if we have been called for this window */
1182 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1186 for (n = 0; n < stack->stacknum; n++)
1187 if ((stack->SubclassProcs[n].id == uID) &&
1188 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1189 *pdwRef = stack->SubclassProcs[n].ref;
1197 /***********************************************************************
1198 * RemoveWindowSubclass [COMCTL32.412]
1200 * Removes a window subclass.
1203 * hWnd [in] Handle to the window were subclassing
1204 * pfnSubclass [in] Pointer to the subclass procedure
1205 * uID [in] Unique identifier of this subclass
1212 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1214 LPSUBCLASS_INFO stack;
1217 TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID);
1219 /* Find the Subclass to remove */
1220 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1224 if ((stack->stacknum == 1) && (stack->stackpos == 1) &&
1225 !stack->wndprocrecursion) {
1226 TRACE("Last Subclass removed, cleaning up\n");
1227 /* clean up our heap and reset the origional window procedure */
1228 if (IsWindowUnicode (hWnd))
1229 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1231 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1232 HeapFree (GetProcessHeap (), 0, stack);
1233 RemovePropA( hWnd, COMCTL32_aSubclass );
1237 for (n = stack->stacknum - 1; n >= 0; n--)
1238 if ((stack->SubclassProcs[n].id == uID) &&
1239 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1240 if (n != stack->stacknum)
1241 /* Fill the hole in the stack */
1242 memmove (&stack->SubclassProcs[n], &stack->SubclassProcs[n + 1],
1243 sizeof(stack->SubclassProcs[0]) * (stack->stacknum - n));
1244 stack->SubclassProcs[n].subproc = NULL;
1245 stack->SubclassProcs[n].ref = 0;
1246 stack->SubclassProcs[n].id = 0;
1249 if (n < stack->stackpos && stack->wndprocrecursion)
1259 /***********************************************************************
1260 * DefSubclassProc [COMCTL32.413]
1262 * Calls the next window procedure (ie. the one before this subclass)
1265 * hWnd [in] The window that we're subclassing
1267 * wParam [in] WPARAM
1268 * lParam [in] LPARAM
1275 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1277 LPSUBCLASS_INFO stack;
1280 /* retrieve our little stack from the Properties */
1281 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1283 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1287 stack->wndprocrecursion++;
1289 /* If we are at the end of stack then we have to call the original
1290 * window procedure */
1291 if (stack->stackpos == stack->stacknum) {
1292 if (IsWindowUnicode (hWnd))
1293 ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
1295 ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1298 /* call the Subclass procedure from the stack */
1299 ret = stack->SubclassProcs[stack->stackpos - 1].subproc (hWnd, uMsg, wParam, lParam,
1300 stack->SubclassProcs[stack->stackpos - 1].id, stack->SubclassProcs[stack->stackpos - 1].ref);
1304 /* We finished the recursion, so let's reinitalize the stack position to
1306 if ((--stack->wndprocrecursion) == 0) {
1307 stack->stackpos = 0;
1310 /* If we removed the last entry in our stack while a window procedure was
1311 * running then we have to clean up */
1312 if ((stack->stackpos == 0) && (stack->stacknum == 0)) {
1313 TRACE("Last Subclass removed, cleaning up\n");
1314 /* clean up our heap and reset the origional window procedure */
1315 if (IsWindowUnicode (hWnd))
1316 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1318 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1319 HeapFree (GetProcessHeap (), 0, stack);
1320 RemovePropA( hWnd, COMCTL32_aSubclass );
1328 /***********************************************************************
1329 * COMCTL32_CreateToolTip [NOT AN API]
1331 * Creates a tooltip for the control specified in hwnd and does all
1332 * necessary setup and notifications.
1335 * hwndOwner [I] Handle to the window that will own the tool tip.
1338 * Success: Handle of tool tip window.
1343 COMCTL32_CreateToolTip(HWND hwndOwner)
1347 hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1348 CW_USEDEFAULT, CW_USEDEFAULT,
1349 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1352 /* Send NM_TOOLTIPSCREATED notification */
1355 NMTOOLTIPSCREATED nmttc;
1356 /* true owner can be different if hwndOwner is a child window */
1357 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1358 nmttc.hdr.hwndFrom = hwndTrueOwner;
1359 nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID);
1360 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1361 nmttc.hwndToolTips = hwndToolTip;
1363 SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1364 (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID),
1372 /***********************************************************************
1373 * COMCTL32_RefreshSysColors [NOT AN API]
1375 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1376 * refresh the color values in the color structure
1386 COMCTL32_RefreshSysColors(void)
1388 comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1389 comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1390 comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1391 comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1392 comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1393 comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
1394 comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1395 comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1396 comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1397 comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1398 comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1399 comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1400 comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1401 comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1402 comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1403 comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);