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 SYSLINK_Register(void);
105 extern void SYSLINK_Unregister(void);
106 extern void TAB_Register(void);
107 extern void TAB_Unregister(void);
108 extern void TOOLBAR_Register(void);
109 extern void TOOLBAR_Unregister(void);
110 extern void TOOLTIPS_Register(void);
111 extern void TOOLTIPS_Unregister(void);
112 extern void TRACKBAR_Register(void);
113 extern void TRACKBAR_Unregister(void);
114 extern void TREEVIEW_Register(void);
115 extern void TREEVIEW_Unregister(void);
116 extern void UPDOWN_Register(void);
117 extern void UPDOWN_Unregister(void);
120 LPSTR COMCTL32_aSubclass = NULL;
121 HMODULE COMCTL32_hModule = 0;
122 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
123 HBRUSH COMCTL32_hPattern55AABrush = NULL;
124 COMCTL32_SysColor comctl32_color;
126 static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
128 static const WORD wPattern55AA[] =
130 0x5555, 0xaaaa, 0x5555, 0xaaaa,
131 0x5555, 0xaaaa, 0x5555, 0xaaaa
135 /***********************************************************************
138 * Initializes the internal 'COMCTL32.DLL'.
141 * hinstDLL [I] handle to the 'dlls' instance
143 * lpvReserved [I] reserverd, must be NULL
150 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
152 TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
155 case DLL_PROCESS_ATTACH:
156 DisableThreadLibraryCalls(hinstDLL);
158 COMCTL32_hModule = (HMODULE)hinstDLL;
160 /* add global subclassing atom (used by 'tooltip' and 'updown') */
161 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
162 TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
164 /* create local pattern brush */
165 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
166 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
168 /* Get all the colors at DLL load */
169 COMCTL32_RefreshSysColors();
171 /* register all Win95 common control classes */
176 LISTVIEW_Register ();
177 PROGRESS_Register ();
182 TOOLTIPS_Register ();
183 TRACKBAR_Register ();
184 TREEVIEW_Register ();
188 case DLL_PROCESS_DETACH:
189 /* unregister all common control classes */
190 ANIMATE_Unregister ();
191 COMBOEX_Unregister ();
192 DATETIME_Unregister ();
193 FLATSB_Unregister ();
194 HEADER_Unregister ();
195 HOTKEY_Unregister ();
196 IPADDRESS_Unregister ();
197 LISTVIEW_Unregister ();
198 MONTHCAL_Unregister ();
199 NATIVEFONT_Unregister ();
201 PROGRESS_Unregister ();
203 STATUS_Unregister ();
204 SYSLINK_Unregister ();
206 TOOLBAR_Unregister ();
207 TOOLTIPS_Unregister ();
208 TRACKBAR_Unregister ();
209 TREEVIEW_Unregister ();
210 UPDOWN_Unregister ();
212 /* delete local pattern brush */
213 DeleteObject (COMCTL32_hPattern55AABrush);
214 COMCTL32_hPattern55AABrush = NULL;
215 DeleteObject (COMCTL32_hPattern55AABitmap);
216 COMCTL32_hPattern55AABitmap = NULL;
218 /* delete global subclassing atom */
219 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
220 TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
221 COMCTL32_aSubclass = NULL;
229 /***********************************************************************
230 * MenuHelp [COMCTL32.2]
232 * Handles the setting of status bar help messages when the user
233 * selects menu items.
236 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
237 * wParam [I] wParam of the message uMsg
238 * lParam [I] lParam of the message uMsg
239 * hMainMenu [I] handle to the application's main menu
240 * hInst [I] handle to the module that contains string resources
241 * hwndStatus [I] handle to the status bar window
242 * lpwIDs [I] pointer to an array of integers (see NOTES)
248 * The official documentation is incomplete!
249 * This is the correct documentation:
252 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
253 * WM_MENUSELECT messages.
256 * (will be written ...)
260 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
261 HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
265 if (!IsWindow (hwndStatus))
270 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
273 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
274 /* menu was closed */
275 TRACE("menu was closed!\n");
276 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
279 /* menu item was selected */
280 if (HIWORD(wParam) & MF_POPUP)
281 uMenuID = (UINT)*(lpwIDs+1);
283 uMenuID = (UINT)LOWORD(wParam);
284 TRACE("uMenuID = %u\n", uMenuID);
289 if (!LoadStringA (hInst, uMenuID, szText, 256))
292 SendMessageA (hwndStatus, SB_SETTEXTA,
293 255 | SBT_NOBORDERS, (LPARAM)szText);
294 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
300 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
302 /* WM_COMMAND is not invalid since it is documented
303 * in the windows api reference. So don't output
304 * any FIXME for WM_COMMAND
306 WARN("We don't care about the WM_COMMAND\n");
310 FIXME("Invalid Message 0x%x!\n", uMsg);
316 /***********************************************************************
317 * ShowHideMenuCtl [COMCTL32.3]
319 * Shows or hides controls and updates the corresponding menu item.
322 * hwnd [I] handle to the client window.
323 * uFlags [I] menu command id.
324 * lpInfo [I] pointer to an array of integers. (See NOTES.)
331 * The official documentation is incomplete!
332 * This is the correct documentation:
335 * Handle to the window that contains the menu and controls.
338 * Identifier of the menu item to receive or loose a check mark.
341 * The array of integers contains pairs of values. BOTH values of
342 * the first pair must be the handles to the application's main menu.
343 * Each subsequent pair consists of a menu id and control id.
347 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
351 TRACE("%p, %x, %p\n", hwnd, uFlags, lpInfo);
356 if (!(lpInfo[0]) || !(lpInfo[1]))
359 /* search for control */
360 lpMenuId = &lpInfo[2];
361 while (*lpMenuId != uFlags)
364 if (GetMenuState ((HMENU)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
365 /* uncheck menu item */
366 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
370 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
374 /* check menu item */
375 CheckMenuItem ((HMENU)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
379 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
387 /***********************************************************************
388 * GetEffectiveClientRect [COMCTL32.4]
390 * Calculates the coordinates of a rectangle in the client area.
393 * hwnd [I] handle to the client window.
394 * lpRect [O] pointer to the rectangle of the client window
395 * lpInfo [I] pointer to an array of integers (see NOTES)
401 * The official documentation is incomplete!
402 * This is the correct documentation:
405 * (will be written ...)
409 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
415 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
416 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
418 GetClientRect (hwnd, lpRect);
426 hwndCtrl = GetDlgItem (hwnd, *lpRun);
427 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
428 TRACE("control id 0x%x\n", *lpRun);
429 GetWindowRect (hwndCtrl, &rcCtrl);
430 MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
431 SubtractRect (lpRect, lpRect, &rcCtrl);
438 /***********************************************************************
439 * DrawStatusTextW [COMCTL32.@]
441 * Draws text with borders, like in a status bar.
444 * hdc [I] handle to the window's display context
445 * lprc [I] pointer to a rectangle
446 * text [I] pointer to the text
447 * style [I] drawing style
453 * The style variable can have one of the following values:
454 * (will be written ...)
457 void WINAPI DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
460 UINT border = BDR_SUNKENOUTER;
462 if (style & SBT_POPOUT)
463 border = BDR_RAISEDOUTER;
464 else if (style & SBT_NOBORDERS)
467 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
471 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
472 UINT align = DT_LEFT;
473 if (*text == L'\t') {
476 if (*text == L'\t') {
482 if (style & SBT_RTLREADING)
483 FIXME("Unsupported RTL style!\n");
484 DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE);
485 SetBkMode(hdc, oldbkmode);
490 /***********************************************************************
491 * DrawStatusText [COMCTL32.@]
492 * DrawStatusTextA [COMCTL32.5]
494 * Draws text with borders, like in a status bar.
497 * hdc [I] handle to the window's display context
498 * lprc [I] pointer to a rectangle
499 * text [I] pointer to the text
500 * style [I] drawing style
506 void WINAPI DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
512 if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
513 if ( (textW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )) )
514 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
517 DrawStatusTextW( hdc, lprc, textW, style );
518 HeapFree( GetProcessHeap(), 0, textW );
522 /***********************************************************************
523 * CreateStatusWindow [COMCTL32.@]
524 * CreateStatusWindowA [COMCTL32.6]
526 * Creates a status bar
529 * style [I] window style
530 * text [I] pointer to the window text
531 * parent [I] handle to the parent window
532 * wid [I] control id of the status bar
535 * Success: handle to the status window
540 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
542 return CreateWindowA(STATUSCLASSNAMEA, text, style,
543 CW_USEDEFAULT, CW_USEDEFAULT,
544 CW_USEDEFAULT, CW_USEDEFAULT,
545 parent, (HMENU)wid, 0, 0);
549 /***********************************************************************
550 * CreateStatusWindowW [COMCTL32.@]
552 * Creates a status bar control
555 * style [I] window style
556 * text [I] pointer to the window text
557 * parent [I] handle to the parent window
558 * wid [I] control id of the status bar
561 * Success: handle to the status window
566 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
568 return CreateWindowW(STATUSCLASSNAMEW, text, style,
569 CW_USEDEFAULT, CW_USEDEFAULT,
570 CW_USEDEFAULT, CW_USEDEFAULT,
571 parent, (HMENU)wid, 0, 0);
575 /***********************************************************************
576 * CreateUpDownControl [COMCTL32.16]
578 * Creates an up-down control
581 * style [I] window styles
582 * x [I] horizontal position of the control
583 * y [I] vertical position of the control
584 * cx [I] with of the control
585 * cy [I] height of the control
586 * parent [I] handle to the parent window
587 * id [I] the control's identifier
588 * inst [I] handle to the application's module instance
589 * buddy [I] handle to the buddy window, can be NULL
590 * maxVal [I] upper limit of the control
591 * minVal [I] lower limit of the control
592 * curVal [I] current value of the control
595 * Success: handle to the updown control
600 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
601 HWND parent, INT id, HINSTANCE inst,
602 HWND buddy, INT maxVal, INT minVal, INT curVal)
605 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
606 parent, (HMENU)id, inst, 0);
608 SendMessageA (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
609 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
610 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
617 /***********************************************************************
618 * InitCommonControls [COMCTL32.17]
620 * Registers the common controls.
629 * This function is just a dummy.
630 * The Win95 controls are registered at the DLL's initialization.
631 * To register other controls InitCommonControlsEx() must be used.
635 InitCommonControls (void)
640 /***********************************************************************
641 * InitCommonControlsEx [COMCTL32.@]
643 * Registers the common controls.
646 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
653 * Only the additional common controls are registered by this function.
654 * The Win95 controls are registered at the DLL's initialization.
657 * implement the following control classes:
659 * ICC_STANDARD_CLASSES
663 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
670 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
673 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
675 for (cCount = 0; cCount < 32; cCount++) {
676 dwMask = 1 << cCount;
677 if (!(lpInitCtrls->dwICC & dwMask))
680 switch (lpInitCtrls->dwICC & dwMask) {
681 /* dummy initialization */
682 case ICC_ANIMATE_CLASS:
683 case ICC_BAR_CLASSES:
684 case ICC_LISTVIEW_CLASSES:
685 case ICC_TREEVIEW_CLASSES:
686 case ICC_TAB_CLASSES:
687 case ICC_UPDOWN_CLASS:
688 case ICC_PROGRESS_CLASS:
689 case ICC_HOTKEY_CLASS:
692 /* advanced classes - not included in Win95 */
693 case ICC_DATE_CLASSES:
694 MONTHCAL_Register ();
695 DATETIME_Register ();
698 case ICC_USEREX_CLASSES:
702 case ICC_COOL_CLASSES:
706 case ICC_INTERNET_CLASSES:
707 IPADDRESS_Register ();
710 case ICC_PAGESCROLLER_CLASS:
714 case ICC_NATIVEFNTCTL_CLASS:
715 NATIVEFONT_Register ();
723 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
732 /***********************************************************************
733 * CreateToolbarEx [COMCTL32.@]
735 * Creates a toolbar window.
753 * Success: handle to the tool bar control
758 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
759 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
760 INT iNumButtons, INT dxButton, INT dyButton,
761 INT dxBitmap, INT dyBitmap, UINT uStructSize)
766 CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL, style|WS_CHILD, 0,0,100,30,
767 hwnd, (HMENU)wID, COMCTL32_hModule, NULL);
771 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
772 (WPARAM)uStructSize, 0);
774 /* set bitmap and button size */
775 /*If CreateToolbarEx receives 0, windows sets default values*/
780 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
781 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
787 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
788 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
794 tbab.hInst = hBMInst;
797 SendMessageA (hwndTB, TB_ADDBITMAP,
798 (WPARAM)nBitmaps, (LPARAM)&tbab);
802 SendMessageA (hwndTB, TB_ADDBUTTONSA,
803 (WPARAM)iNumButtons, (LPARAM)lpButtons);
810 /***********************************************************************
811 * CreateMappedBitmap [COMCTL32.8]
813 * Loads a bitmap resource using a colour map.
816 * hInstance [I] Handle to the module containing the bitmap.
817 * idBitmap [I] The bitmap resource ID.
818 * wFlags [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
819 * lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
820 * iNumMaps [I] Number of COLORMAP's pointed to by lpColorMap.
823 * Success: handle to the new bitmap
828 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
829 LPCOLORMAP lpColorMap, INT iNumMaps)
833 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
834 UINT nSize, nColorTableSize;
835 RGBQUAD *pColorTable;
836 INT iColor, i, iMaps, nWidth, nHeight;
839 LPCOLORMAP sysColorMap;
841 COLORMAP internalColorMap[4] =
842 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
844 /* initialize pointer to colortable and default color table */
847 sysColorMap = lpColorMap;
850 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
851 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
852 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
853 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
855 sysColorMap = (LPCOLORMAP)internalColorMap;
858 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, (LPSTR)RT_BITMAP);
861 hglb = LoadResource (hInstance, hRsrc);
864 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
865 if (lpBitmap == NULL)
868 if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
869 nColorTableSize = lpBitmap->biClrUsed;
870 else if (lpBitmap->biBitCount <= 8)
871 nColorTableSize = (1 << lpBitmap->biBitCount);
874 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
875 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
876 if (lpBitmapInfo == NULL)
878 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
880 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
882 for (iColor = 0; iColor < nColorTableSize; iColor++) {
883 for (i = 0; i < iMaps; i++) {
884 cRef = RGB(pColorTable[iColor].rgbRed,
885 pColorTable[iColor].rgbGreen,
886 pColorTable[iColor].rgbBlue);
887 if ( cRef == sysColorMap[i].from) {
889 if (wFlags & CBS_MASKED) {
890 if (sysColorMap[i].to != COLOR_BTNTEXT)
891 pColorTable[iColor] = RGB(255, 255, 255);
895 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
896 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
897 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
902 nWidth = (INT)lpBitmapInfo->biWidth;
903 nHeight = (INT)lpBitmapInfo->biHeight;
904 hdcScreen = GetDC (NULL);
905 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
907 HDC hdcDst = CreateCompatibleDC (hdcScreen);
908 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
909 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
910 lpBits += nColorTableSize * sizeof(RGBQUAD);
911 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
912 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
914 SelectObject (hdcDst, hbmOld);
917 ReleaseDC (NULL, hdcScreen);
918 GlobalFree ((HGLOBAL)lpBitmapInfo);
925 /***********************************************************************
926 * CreateToolbar [COMCTL32.7]
928 * Creates a toolbar control.
941 * Success: handle to the tool bar control
945 * Do not use this functions anymore. Use CreateToolbarEx instead.
949 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
950 HINSTANCE hBMInst, UINT wBMID,
951 LPCTBBUTTON lpButtons,INT iNumButtons)
953 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
954 hBMInst, wBMID, lpButtons,
955 iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
959 /***********************************************************************
960 * DllGetVersion [COMCTL32.@]
962 * Retrieves version information of the 'COMCTL32.DLL'
965 * pdvi [O] pointer to version information structure.
969 * Failure: E_INVALIDARG
972 * Returns version of a comctl32.dll from IE4.01 SP1.
976 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
978 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
979 WARN("wrong DLLVERSIONINFO size from app\n");
983 pdvi->dwMajorVersion = COMCTL32_VERSION;
984 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
985 pdvi->dwBuildNumber = 2919;
986 pdvi->dwPlatformID = 6304;
988 TRACE("%lu.%lu.%lu.%lu\n",
989 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
990 pdvi->dwBuildNumber, pdvi->dwPlatformID);
995 /***********************************************************************
996 * DllInstall (COMCTL32.@)
998 * Installs the ComCtl32 DLL.
1002 * Failure: A HRESULT error
1004 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
1006 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
1007 debugstr_w(cmdline));
1012 /***********************************************************************
1013 * _TrackMouseEvent [COMCTL32.@]
1015 * Requests notification of mouse events
1017 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1018 * to the hwnd specified in the ptme structure. After the event message
1019 * is posted to the hwnd, the entry in the queue is removed.
1021 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1022 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1023 * immediately and the TME_LEAVE flag being ignored.
1026 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1032 * IMPLEMENTATION moved to USER32.TrackMouseEvent
1037 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1039 return TrackMouseEvent (ptme);
1042 /*************************************************************************
1043 * GetMUILanguage [COMCTL32.@]
1045 * Returns the user interface language in use by the current process.
1048 * Language ID in use by the current process.
1050 LANGID WINAPI GetMUILanguage (VOID)
1052 return COMCTL32_uiLang;
1056 /*************************************************************************
1057 * InitMUILanguage [COMCTL32.@]
1059 * Sets the user interface language to be used by the current process.
1064 VOID WINAPI InitMUILanguage (LANGID uiLang)
1066 COMCTL32_uiLang = uiLang;
1070 /***********************************************************************
1071 * SetWindowSubclass [COMCTL32.410]
1073 * Starts a window subclass
1076 * hWnd [in] handle to window subclass.
1077 * pfnSubclass [in] Pointer to new window procedure.
1078 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1079 * dwRef [in] Reference data to pass to window procedure.
1086 * If an application manually subclasses a window after subclassing it with
1087 * this API and then with this API again, then none of the previous
1088 * subclasses get called or the origional window procedure.
1091 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1092 UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1094 LPSUBCLASS_INFO stack;
1097 TRACE ("(%p, %p, %x, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
1099 /* Since the window procedure that we set here has two additional arguments,
1100 * we can't simply set it as the new window procedure of the window. So we
1101 * set our own window procedure and then calculate the other two arguments
1104 /* See if we have been called for this window */
1105 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1107 /* allocate stack */
1108 stack = (LPSUBCLASS_INFO)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY,
1109 sizeof(SUBCLASS_INFO));
1111 ERR ("Failed to allocate our Subclassing stack\n");
1114 SetPropA (hWnd, COMCTL32_aSubclass, (HANDLE)stack);
1116 /* set window procedure to our own and save the current one */
1117 if (IsWindowUnicode (hWnd))
1118 stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC,
1119 (LONG)DefSubclassProc);
1121 stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC,
1122 (LONG)DefSubclassProc);
1125 if (IsWindowUnicode (hWnd))
1126 current = (WNDPROC)GetWindowLongW (hWnd, GWL_WNDPROC);
1128 current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC);
1130 if (current != DefSubclassProc) {
1131 ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n");
1136 /* Check to see if we have called this function with the same uIDSubClass
1137 * and pfnSubclass */
1138 for (n = 0; n < stack->stacknum; n++)
1139 if ((stack->SubclassProcs[n].id == uIDSubclass) &&
1140 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1141 stack->SubclassProcs[n].ref = dwRef;
1145 if (stack->stacknum >= 32) {
1146 ERR ("We have a Subclass stack overflow, please increment size\n");
1150 memmove (&stack->SubclassProcs[1], &stack->SubclassProcs[0],
1151 sizeof(stack->SubclassProcs[0]) * stack->stacknum);
1154 if (stack->wndprocrecursion)
1157 stack->SubclassProcs[0].subproc = pfnSubclass;
1158 stack->SubclassProcs[0].ref = dwRef;
1159 stack->SubclassProcs[0].id = uIDSubclass;
1165 /***********************************************************************
1166 * GetWindowSubclass [COMCTL32.411]
1168 * Gets the Reference data from a subclass.
1171 * hWnd [in] Handle to window which were subclassing
1172 * pfnSubclass [in] Pointer to the subclass procedure
1173 * uID [in] Unique indentifier of the subclassing procedure
1174 * pdwRef [out] Pointer to the reference data
1181 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1182 UINT_PTR uID, DWORD_PTR *pdwRef)
1184 LPSUBCLASS_INFO stack;
1187 TRACE ("(%p, %p, %x, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
1189 /* See if we have been called for this window */
1190 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1194 for (n = 0; n < stack->stacknum; n++)
1195 if ((stack->SubclassProcs[n].id == uID) &&
1196 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1197 *pdwRef = stack->SubclassProcs[n].ref;
1205 /***********************************************************************
1206 * RemoveWindowSubclass [COMCTL32.412]
1208 * Removes a window subclass.
1211 * hWnd [in] Handle to the window were subclassing
1212 * pfnSubclass [in] Pointer to the subclass procedure
1213 * uID [in] Unique identifier of this subclass
1220 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1222 LPSUBCLASS_INFO stack;
1225 TRACE ("(%p, %p, %x)\n", hWnd, pfnSubclass, uID);
1227 /* Find the Subclass to remove */
1228 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1232 if ((stack->stacknum == 1) && (stack->stackpos == 1) &&
1233 !stack->wndprocrecursion) {
1234 TRACE("Last Subclass removed, cleaning up\n");
1235 /* clean up our heap and reset the origional window procedure */
1236 if (IsWindowUnicode (hWnd))
1237 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1239 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1240 HeapFree (GetProcessHeap (), 0, stack);
1241 RemovePropA( hWnd, COMCTL32_aSubclass );
1245 for (n = stack->stacknum - 1; n >= 0; n--)
1246 if ((stack->SubclassProcs[n].id == uID) &&
1247 (stack->SubclassProcs[n].subproc == pfnSubclass)) {
1248 if (n != stack->stacknum)
1249 /* Fill the hole in the stack */
1250 memmove (&stack->SubclassProcs[n], &stack->SubclassProcs[n + 1],
1251 sizeof(stack->SubclassProcs[0]) * (stack->stacknum - n));
1252 stack->SubclassProcs[n].subproc = NULL;
1253 stack->SubclassProcs[n].ref = 0;
1254 stack->SubclassProcs[n].id = 0;
1257 if (n < stack->stackpos && stack->wndprocrecursion)
1267 /***********************************************************************
1268 * DefSubclassProc [COMCTL32.413]
1270 * Calls the next window procedure (ie. the one before this subclass)
1273 * hWnd [in] The window that we're subclassing
1275 * wParam [in] WPARAM
1276 * lParam [in] LPARAM
1283 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1285 LPSUBCLASS_INFO stack;
1288 /* retrieve our little stack from the Properties */
1289 stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
1291 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1295 stack->wndprocrecursion++;
1297 /* If we are at the end of stack then we have to call the original
1298 * window procedure */
1299 if (stack->stackpos == stack->stacknum) {
1300 if (IsWindowUnicode (hWnd))
1301 ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
1303 ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1306 /* call the Subclass procedure from the stack */
1307 ret = stack->SubclassProcs[stack->stackpos - 1].subproc (hWnd, uMsg, wParam, lParam,
1308 stack->SubclassProcs[stack->stackpos - 1].id, stack->SubclassProcs[stack->stackpos - 1].ref);
1312 /* We finished the recursion, so let's reinitalize the stack position to
1314 if ((--stack->wndprocrecursion) == 0) {
1315 stack->stackpos = 0;
1318 /* If we removed the last entry in our stack while a window procedure was
1319 * running then we have to clean up */
1320 if ((stack->stackpos == 0) && (stack->stacknum == 0)) {
1321 TRACE("Last Subclass removed, cleaning up\n");
1322 /* clean up our heap and reset the origional window procedure */
1323 if (IsWindowUnicode (hWnd))
1324 SetWindowLongW (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1326 SetWindowLongA (hWnd, GWL_WNDPROC, (LONG)stack->origproc);
1327 HeapFree (GetProcessHeap (), 0, stack);
1328 RemovePropA( hWnd, COMCTL32_aSubclass );
1336 /***********************************************************************
1337 * COMCTL32_CreateToolTip [NOT AN API]
1339 * Creates a tooltip for the control specified in hwnd and does all
1340 * necessary setup and notifications.
1343 * hwndOwner [I] Handle to the window that will own the tool tip.
1346 * Success: Handle of tool tip window.
1351 COMCTL32_CreateToolTip(HWND hwndOwner)
1355 hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1356 CW_USEDEFAULT, CW_USEDEFAULT,
1357 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1360 /* Send NM_TOOLTIPSCREATED notification */
1363 NMTOOLTIPSCREATED nmttc;
1364 /* true owner can be different if hwndOwner is a child window */
1365 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1366 nmttc.hdr.hwndFrom = hwndTrueOwner;
1367 nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID);
1368 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1369 nmttc.hwndToolTips = hwndToolTip;
1371 SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1372 (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID),
1380 /***********************************************************************
1381 * COMCTL32_RefreshSysColors [NOT AN API]
1383 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1384 * refresh the color values in the color structure
1394 COMCTL32_RefreshSysColors(void)
1396 comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1397 comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1398 comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1399 comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1400 comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1401 comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
1402 comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1403 comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1404 comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1405 comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1406 comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1407 comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1408 comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1409 comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1410 comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1411 comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);