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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 * -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
33 * -- FIXMEs + BUGS (search for them)
36 * -- ICC_ANIMATE_CLASS
41 * -- ICC_INTERNET_CLASSES
43 * -- ICC_LISTVIEW_CLASSES
44 * -- ICC_NATIVEFNTCTL_CLASS
45 * -- ICC_PAGESCROLLER_CLASS
46 * -- ICC_PROGRESS_CLASS
47 * -- ICC_STANDARD_CLASSES (not yet implemented)
49 * -- ICC_TREEVIEW_CLASSES
51 * -- ICC_USEREX_CLASSES
52 * -- ICC_WIN95_CLASSES
67 #define NO_SHLWAPI_STREAM
70 #include "wine/debug.h"
72 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
75 #define NAME "microsoft.windows.common-controls"
76 #define FILE "comctl32.dll"
77 #define VERSION "6.0.2600.2982"
78 #define PUBLIC_KEY "6595b64144ccf1df"
82 #elif defined __x86_64__
88 static const char manifest[] =
89 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
90 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
91 " <assemblyIdentity type=\"win32\" name=\"" NAME "\" version=\"" VERSION "\" processorArchitecture=\"" ARCH "\" publicKeyToken=\"" PUBLIC_KEY "\"/>\n"
92 " <file name=\"" FILE "\">\n"
93 " <windowClass>Button</windowClass>\n"
94 " <windowClass>ButtonListBox</windowClass>\n"
95 " <windowClass>ComboBoxEx32</windowClass>\n"
96 " <windowClass>ComboLBox</windowClass>\n"
97 " <windowClass>Combobox</windowClass>\n"
98 " <windowClass>Edit</windowClass>\n"
99 " <windowClass>Listbox</windowClass>\n"
100 " <windowClass>NativeFontCtl</windowClass>\n"
101 " <windowClass>ReBarWindow32</windowClass>\n"
102 " <windowClass>ScrollBar</windowClass>\n"
103 " <windowClass>Static</windowClass>\n"
104 " <windowClass>SysAnimate32</windowClass>\n"
105 " <windowClass>SysDateTimePick32</windowClass>\n"
106 " <windowClass>SysHeader32</windowClass>\n"
107 " <windowClass>SysIPAddress32</windowClass>\n"
108 " <windowClass>SysLink</windowClass>\n"
109 " <windowClass>SysListView32</windowClass>\n"
110 " <windowClass>SysMonthCal32</windowClass>\n"
111 " <windowClass>SysPager</windowClass>\n"
112 " <windowClass>SysTabControl32</windowClass>\n"
113 " <windowClass>SysTreeView32</windowClass>\n"
114 " <windowClass>ToolbarWindow32</windowClass>\n"
115 " <windowClass>msctls_hotkey32</windowClass>\n"
116 " <windowClass>msctls_progress32</windowClass>\n"
117 " <windowClass>msctls_statusbar32</windowClass>\n"
118 " <windowClass>msctls_trackbar32</windowClass>\n"
119 " <windowClass>msctls_updown32</windowClass>\n"
120 " <windowClass>tooltips_class32</windowClass>\n"
124 static const char manifest_filename[] = ARCH "_" NAME "_" PUBLIC_KEY "_" VERSION "_none_deadbeef.manifest";
126 LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
128 LPWSTR COMCTL32_wSubclass = NULL;
129 HMODULE COMCTL32_hModule = 0;
130 LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
131 HBRUSH COMCTL32_hPattern55AABrush = NULL;
132 COMCTL32_SysColor comctl32_color;
134 static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
136 static const WORD wPattern55AA[] =
138 0x5555, 0xaaaa, 0x5555, 0xaaaa,
139 0x5555, 0xaaaa, 0x5555, 0xaaaa
142 static const WCHAR strCC32SubclassInfo[] = {
143 'C','C','3','2','S','u','b','c','l','a','s','s','I','n','f','o',0
146 static BOOL create_manifest( BOOL install )
148 static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s',0};
149 static const WCHAR manifestsW[] = {'\\','m','a','n','i','f','e','s','t','s','\\',0};
156 len = MultiByteToWideChar( CP_UTF8, 0, manifest_filename, sizeof(manifest_filename), NULL, 0 );
157 len += GetWindowsDirectoryW( NULL, 0 );
158 len += lstrlenW(winsxsW);
159 len += lstrlenW(manifestsW);
160 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
161 GetWindowsDirectoryW( buffer, len );
162 lstrcatW( buffer, winsxsW );
163 CreateDirectoryW( buffer, NULL );
164 lstrcatW( buffer, manifestsW );
165 CreateDirectoryW( buffer, NULL );
166 MultiByteToWideChar( CP_UTF8, 0, manifest_filename, sizeof(manifest_filename),
167 buffer + lstrlenW(buffer), len );
170 file = CreateFileW( buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL );
171 if (file != INVALID_HANDLE_VALUE)
173 ret = (WriteFile( file, manifest, sizeof(manifest)-1, &written, NULL ) &&
174 written == sizeof(manifest)-1);
176 if (!ret) DeleteFileW( buffer );
177 else TRACE("created %s\n", debugstr_w(buffer));
180 else ret = DeleteFileW( buffer );
182 HeapFree( GetProcessHeap(), 0, buffer );
187 /***********************************************************************
190 * Initializes the internal 'COMCTL32.DLL'.
193 * hinstDLL [I] handle to the 'dlls' instance
195 * lpvReserved [I] reserverd, must be NULL
202 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
204 TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);
207 case DLL_PROCESS_ATTACH:
208 DisableThreadLibraryCalls(hinstDLL);
210 COMCTL32_hModule = hinstDLL;
212 /* add global subclassing atom (used by 'tooltip' and 'updown') */
213 COMCTL32_wSubclass = (LPWSTR)(DWORD_PTR)GlobalAddAtomW (strCC32SubclassInfo);
214 TRACE("Subclassing atom added: %p\n", COMCTL32_wSubclass);
216 /* create local pattern brush */
217 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
218 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
220 /* Get all the colors at DLL load */
221 COMCTL32_RefreshSysColors();
223 /* like comctl32 5.82+ register all the common control classes */
226 DATETIME_Register ();
230 IPADDRESS_Register ();
231 LISTVIEW_Register ();
232 MONTHCAL_Register ();
233 NATIVEFONT_Register ();
235 PROGRESS_Register ();
241 TOOLTIPS_Register ();
242 TRACKBAR_Register ();
243 TREEVIEW_Register ();
246 /* subclass user32 controls */
247 THEMING_Initialize ();
250 case DLL_PROCESS_DETACH:
251 /* clean up subclassing */
252 THEMING_Uninitialize();
254 /* unregister all common control classes */
255 ANIMATE_Unregister ();
256 COMBOEX_Unregister ();
257 DATETIME_Unregister ();
258 FLATSB_Unregister ();
259 HEADER_Unregister ();
260 HOTKEY_Unregister ();
261 IPADDRESS_Unregister ();
262 LISTVIEW_Unregister ();
263 MONTHCAL_Unregister ();
264 NATIVEFONT_Unregister ();
266 PROGRESS_Unregister ();
268 STATUS_Unregister ();
269 SYSLINK_Unregister ();
271 TOOLBAR_Unregister ();
272 TOOLTIPS_Unregister ();
273 TRACKBAR_Unregister ();
274 TREEVIEW_Unregister ();
275 UPDOWN_Unregister ();
277 /* delete local pattern brush */
278 DeleteObject (COMCTL32_hPattern55AABrush);
279 COMCTL32_hPattern55AABrush = NULL;
280 DeleteObject (COMCTL32_hPattern55AABitmap);
281 COMCTL32_hPattern55AABitmap = NULL;
283 /* delete global subclassing atom */
284 GlobalDeleteAtom (LOWORD(COMCTL32_wSubclass));
285 TRACE("Subclassing atom deleted: %p\n", COMCTL32_wSubclass);
286 COMCTL32_wSubclass = NULL;
294 /***********************************************************************
295 * MenuHelp [COMCTL32.2]
297 * Handles the setting of status bar help messages when the user
298 * selects menu items.
301 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
302 * wParam [I] wParam of the message uMsg
303 * lParam [I] lParam of the message uMsg
304 * hMainMenu [I] handle to the application's main menu
305 * hInst [I] handle to the module that contains string resources
306 * hwndStatus [I] handle to the status bar window
307 * lpwIDs [I] pointer to an array of integers (see NOTES)
313 * The official documentation is incomplete!
314 * This is the correct documentation:
317 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
318 * WM_MENUSELECT messages.
321 * (will be written ...)
325 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
326 HINSTANCE hInst, HWND hwndStatus, UINT* lpwIDs)
330 if (!IsWindow (hwndStatus))
335 TRACE("WM_MENUSELECT wParam=0x%lX lParam=0x%lX\n",
338 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
339 /* menu was closed */
340 TRACE("menu was closed!\n");
341 SendMessageW (hwndStatus, SB_SIMPLE, FALSE, 0);
344 /* menu item was selected */
345 if (HIWORD(wParam) & MF_POPUP)
346 uMenuID = *(lpwIDs+1);
348 uMenuID = (UINT)LOWORD(wParam);
349 TRACE("uMenuID = %u\n", uMenuID);
354 if (!LoadStringW (hInst, uMenuID, szText, sizeof(szText)/sizeof(szText[0])))
357 SendMessageW (hwndStatus, SB_SETTEXTW,
358 255 | SBT_NOBORDERS, (LPARAM)szText);
359 SendMessageW (hwndStatus, SB_SIMPLE, TRUE, 0);
365 TRACE("WM_COMMAND wParam=0x%lX lParam=0x%lX\n",
367 /* WM_COMMAND is not invalid since it is documented
368 * in the windows api reference. So don't output
369 * any FIXME for WM_COMMAND
371 WARN("We don't care about the WM_COMMAND\n");
375 FIXME("Invalid Message 0x%x!\n", uMsg);
381 /***********************************************************************
382 * ShowHideMenuCtl [COMCTL32.3]
384 * Shows or hides controls and updates the corresponding menu item.
387 * hwnd [I] handle to the client window.
388 * uFlags [I] menu command id.
389 * lpInfo [I] pointer to an array of integers. (See NOTES.)
396 * The official documentation is incomplete!
397 * This is the correct documentation:
400 * Handle to the window that contains the menu and controls.
403 * Identifier of the menu item to receive or lose a check mark.
406 * The array of integers contains pairs of values. BOTH values of
407 * the first pair must be the handles to the application's main menu.
408 * Each subsequent pair consists of a menu id and control id.
412 ShowHideMenuCtl (HWND hwnd, UINT_PTR uFlags, LPINT lpInfo)
416 TRACE("%p, %lx, %p\n", hwnd, uFlags, lpInfo);
421 if (!(lpInfo[0]) || !(lpInfo[1]))
424 /* search for control */
425 lpMenuId = &lpInfo[2];
426 while (*lpMenuId != uFlags)
429 if (GetMenuState ((HMENU)(DWORD_PTR)lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
430 /* uncheck menu item */
431 CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
435 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
439 /* check menu item */
440 CheckMenuItem ((HMENU)(DWORD_PTR)lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
444 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
452 /***********************************************************************
453 * GetEffectiveClientRect [COMCTL32.4]
455 * Calculates the coordinates of a rectangle in the client area.
458 * hwnd [I] handle to the client window.
459 * lpRect [O] pointer to the rectangle of the client window
460 * lpInfo [I] pointer to an array of integers (see NOTES)
466 * The official documentation is incomplete!
467 * This is the correct documentation:
470 * (will be written ...)
474 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, const INT *lpInfo)
480 TRACE("(%p %p %p)\n",
481 hwnd, lpRect, lpInfo);
483 GetClientRect (hwnd, lpRect);
491 hwndCtrl = GetDlgItem (hwnd, *lpRun);
492 if (GetWindowLongW (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
493 TRACE("control id 0x%x\n", *lpRun);
494 GetWindowRect (hwndCtrl, &rcCtrl);
495 MapWindowPoints (NULL, hwnd, (LPPOINT)&rcCtrl, 2);
496 SubtractRect (lpRect, lpRect, &rcCtrl);
503 /***********************************************************************
504 * DrawStatusTextW [COMCTL32.@]
506 * Draws text with borders, like in a status bar.
509 * hdc [I] handle to the window's display context
510 * lprc [I] pointer to a rectangle
511 * text [I] pointer to the text
512 * style [I] drawing style
518 * The style variable can have one of the following values:
519 * (will be written ...)
522 void WINAPI DrawStatusTextW (HDC hdc, LPCRECT lprc, LPCWSTR text, UINT style)
525 UINT border = BDR_SUNKENOUTER;
527 if (style & SBT_POPOUT)
528 border = BDR_RAISEDOUTER;
529 else if (style & SBT_NOBORDERS)
532 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST);
536 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
537 UINT align = DT_LEFT;
547 if (style & SBT_RTLREADING)
548 FIXME("Unsupported RTL style!\n");
549 DrawTextW (hdc, text, -1, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
550 SetBkMode(hdc, oldbkmode);
555 /***********************************************************************
556 * DrawStatusText [COMCTL32.@]
557 * DrawStatusTextA [COMCTL32.5]
559 * Draws text with borders, like in a status bar.
562 * hdc [I] handle to the window's display context
563 * lprc [I] pointer to a rectangle
564 * text [I] pointer to the text
565 * style [I] drawing style
571 void WINAPI DrawStatusTextA (HDC hdc, LPCRECT lprc, LPCSTR text, UINT style)
577 if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
578 if ( (textW = Alloc( len * sizeof(WCHAR) )) )
579 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
582 DrawStatusTextW( hdc, lprc, textW, style );
587 /***********************************************************************
588 * CreateStatusWindow [COMCTL32.@]
589 * CreateStatusWindowA [COMCTL32.6]
591 * Creates a status bar
594 * style [I] window style
595 * text [I] pointer to the window text
596 * parent [I] handle to the parent window
597 * wid [I] control id of the status bar
600 * Success: handle to the status window
605 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
607 return CreateWindowA(STATUSCLASSNAMEA, text, style,
608 CW_USEDEFAULT, CW_USEDEFAULT,
609 CW_USEDEFAULT, CW_USEDEFAULT,
610 parent, (HMENU)(DWORD_PTR)wid, 0, 0);
614 /***********************************************************************
615 * CreateStatusWindowW [COMCTL32.@]
617 * Creates a status bar control
620 * style [I] window style
621 * text [I] pointer to the window text
622 * parent [I] handle to the parent window
623 * wid [I] control id of the status bar
626 * Success: handle to the status window
631 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
633 return CreateWindowW(STATUSCLASSNAMEW, text, style,
634 CW_USEDEFAULT, CW_USEDEFAULT,
635 CW_USEDEFAULT, CW_USEDEFAULT,
636 parent, (HMENU)(DWORD_PTR)wid, 0, 0);
640 /***********************************************************************
641 * CreateUpDownControl [COMCTL32.16]
643 * Creates an up-down control
646 * style [I] window styles
647 * x [I] horizontal position of the control
648 * y [I] vertical position of the control
649 * cx [I] with of the control
650 * cy [I] height of the control
651 * parent [I] handle to the parent window
652 * id [I] the control's identifier
653 * inst [I] handle to the application's module instance
654 * buddy [I] handle to the buddy window, can be NULL
655 * maxVal [I] upper limit of the control
656 * minVal [I] lower limit of the control
657 * curVal [I] current value of the control
660 * Success: handle to the updown control
665 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
666 HWND parent, INT id, HINSTANCE inst,
667 HWND buddy, INT maxVal, INT minVal, INT curVal)
670 CreateWindowW (UPDOWN_CLASSW, 0, style, x, y, cx, cy,
671 parent, (HMENU)(DWORD_PTR)id, inst, 0);
673 SendMessageW (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
674 SendMessageW (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
675 SendMessageW (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
682 /***********************************************************************
683 * InitCommonControls [COMCTL32.17]
685 * Registers the common controls.
694 * This function is just a dummy - all the controls are registered at
695 * the DLL's initialization. See InitCommonContolsEx for details.
699 InitCommonControls (void)
704 /***********************************************************************
705 * InitCommonControlsEx [COMCTL32.@]
707 * Registers the common controls.
710 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
717 * Probably all versions of comctl32 initializes the Win95 controls in DllMain
718 * during DLL initialization. Starting from comctl32 v5.82 all the controls
719 * are initialized there. We follow this behaviour and this function is just
722 * Note: when writing programs under Windows, if you don't call any function
723 * from comctl32 the linker may not link this DLL. If InitCommonControlsEx
724 * was the only comctl32 function you were calling and you remove it you may
725 * have a false impression that InitCommonControlsEx actually did something.
729 InitCommonControlsEx (const INITCOMMONCONTROLSEX *lpInitCtrls)
731 if (!lpInitCtrls || lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
734 TRACE("(0x%08x)\n", lpInitCtrls->dwICC);
739 /***********************************************************************
740 * CreateToolbarEx [COMCTL32.@]
742 * Creates a toolbar window.
760 * Success: handle to the tool bar control
765 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
766 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
767 INT iNumButtons, INT dxButton, INT dyButton,
768 INT dxBitmap, INT dyBitmap, UINT uStructSize)
773 CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style|WS_CHILD, 0,0,100,30,
774 hwnd, (HMENU)(DWORD_PTR)wID, COMCTL32_hModule, NULL);
778 SendMessageW (hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM)uStructSize, 0);
780 /* set bitmap and button size */
781 /*If CreateToolbarEx receives 0, windows sets default values*/
786 if (dxBitmap == 0 || dyBitmap == 0)
787 dxBitmap = dyBitmap = 16;
788 SendMessageW(hwndTB, TB_SETBITMAPSIZE, 0, MAKELPARAM(dxBitmap, dyBitmap));
794 /* TB_SETBUTTONSIZE -> TB_SETBITMAPSIZE bug introduced for Windows compatibility */
795 if (dxButton != 0 && dyButton != 0)
796 SendMessageW(hwndTB, TB_SETBITMAPSIZE, 0, MAKELPARAM(dxButton, dyButton));
800 if (nBitmaps > 0 || hBMInst == HINST_COMMCTRL)
802 tbab.hInst = hBMInst;
805 SendMessageW (hwndTB, TB_ADDBITMAP, (WPARAM)nBitmaps, (LPARAM)&tbab);
809 SendMessageW (hwndTB, TB_ADDBUTTONSW,
810 (WPARAM)iNumButtons, (LPARAM)lpButtons);
817 /***********************************************************************
818 * CreateMappedBitmap [COMCTL32.8]
820 * Loads a bitmap resource using a colour map.
823 * hInstance [I] Handle to the module containing the bitmap.
824 * idBitmap [I] The bitmap resource ID.
825 * wFlags [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
826 * lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
827 * iNumMaps [I] Number of COLORMAP's pointed to by lpColorMap.
830 * Success: handle to the new bitmap
835 CreateMappedBitmap (HINSTANCE hInstance, INT_PTR idBitmap, UINT wFlags,
836 LPCOLORMAP lpColorMap, INT iNumMaps)
840 const BITMAPINFOHEADER *lpBitmap;
841 LPBITMAPINFOHEADER lpBitmapInfo;
842 UINT nSize, nColorTableSize, iColor;
843 RGBQUAD *pColorTable;
844 INT i, iMaps, nWidth, nHeight;
847 LPCOLORMAP sysColorMap;
849 COLORMAP internalColorMap[4] =
850 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
852 /* initialize pointer to colortable and default color table */
855 sysColorMap = lpColorMap;
858 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
859 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
860 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
861 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
863 sysColorMap = (LPCOLORMAP)internalColorMap;
866 hRsrc = FindResourceW (hInstance, (LPWSTR)idBitmap, (LPWSTR)RT_BITMAP);
869 hglb = LoadResource (hInstance, hRsrc);
872 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
873 if (lpBitmap == NULL)
876 if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
877 nColorTableSize = lpBitmap->biClrUsed;
878 else if (lpBitmap->biBitCount <= 8)
879 nColorTableSize = (1 << lpBitmap->biBitCount);
882 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
883 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
884 if (lpBitmapInfo == NULL)
886 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
888 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo) + lpBitmapInfo->biSize);
890 for (iColor = 0; iColor < nColorTableSize; iColor++) {
891 for (i = 0; i < iMaps; i++) {
892 cRef = RGB(pColorTable[iColor].rgbRed,
893 pColorTable[iColor].rgbGreen,
894 pColorTable[iColor].rgbBlue);
895 if ( cRef == sysColorMap[i].from) {
897 if (wFlags & CBS_MASKED) {
898 if (sysColorMap[i].to != COLOR_BTNTEXT)
899 pColorTable[iColor] = RGB(255, 255, 255);
903 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
904 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
905 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
910 nWidth = lpBitmapInfo->biWidth;
911 nHeight = lpBitmapInfo->biHeight;
912 hdcScreen = GetDC (NULL);
913 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
915 HDC hdcDst = CreateCompatibleDC (hdcScreen);
916 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
917 const BYTE *lpBits = (const BYTE *)(lpBitmap + 1);
918 lpBits += nColorTableSize * sizeof(RGBQUAD);
919 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
920 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
922 SelectObject (hdcDst, hbmOld);
925 ReleaseDC (NULL, hdcScreen);
926 GlobalFree ((HGLOBAL)lpBitmapInfo);
933 /***********************************************************************
934 * CreateToolbar [COMCTL32.7]
936 * Creates a toolbar control.
949 * Success: handle to the tool bar control
953 * Do not use this functions anymore. Use CreateToolbarEx instead.
957 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
958 HINSTANCE hBMInst, UINT wBMID,
959 LPCTBBUTTON lpButtons,INT iNumButtons)
961 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
962 hBMInst, wBMID, lpButtons,
963 iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
967 /***********************************************************************
968 * DllGetVersion [COMCTL32.@]
970 * Retrieves version information of the 'COMCTL32.DLL'
973 * pdvi [O] pointer to version information structure.
977 * Failure: E_INVALIDARG
980 * Returns version of a comctl32.dll from IE4.01 SP1.
983 HRESULT WINAPI DllGetVersion (DLLVERSIONINFO *pdvi)
985 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
986 WARN("wrong DLLVERSIONINFO size from app\n");
990 pdvi->dwMajorVersion = COMCTL32_VERSION;
991 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
992 pdvi->dwBuildNumber = 2919;
993 pdvi->dwPlatformID = 6304;
995 TRACE("%u.%u.%u.%u\n",
996 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
997 pdvi->dwBuildNumber, pdvi->dwPlatformID);
1002 /***********************************************************************
1003 * DllInstall (COMCTL32.@)
1005 * Installs the ComCtl32 DLL.
1009 * Failure: A HRESULT error
1011 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
1013 TRACE("(%u, %s): stub\n", bInstall, debugstr_w(cmdline));
1014 if (!create_manifest( bInstall )) return HRESULT_FROM_WIN32(GetLastError());
1018 /***********************************************************************
1019 * _TrackMouseEvent [COMCTL32.@]
1021 * Requests notification of mouse events
1023 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1024 * to the hwnd specified in the ptme structure. After the event message
1025 * is posted to the hwnd, the entry in the queue is removed.
1027 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1028 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1029 * immediately and the TME_LEAVE flag being ignored.
1032 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1038 * IMPLEMENTATION moved to USER32.TrackMouseEvent
1043 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1045 return TrackMouseEvent (ptme);
1048 /*************************************************************************
1049 * GetMUILanguage [COMCTL32.@]
1051 * Returns the user interface language in use by the current process.
1054 * Language ID in use by the current process.
1056 LANGID WINAPI GetMUILanguage (VOID)
1058 return COMCTL32_uiLang;
1062 /*************************************************************************
1063 * InitMUILanguage [COMCTL32.@]
1065 * Sets the user interface language to be used by the current process.
1070 VOID WINAPI InitMUILanguage (LANGID uiLang)
1072 COMCTL32_uiLang = uiLang;
1076 /***********************************************************************
1077 * SetWindowSubclass [COMCTL32.410]
1079 * Starts a window subclass
1082 * hWnd [in] handle to window subclass.
1083 * pfnSubclass [in] Pointer to new window procedure.
1084 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1085 * dwRef [in] Reference data to pass to window procedure.
1092 * If an application manually subclasses a window after subclassing it with
1093 * this API and then with this API again, then none of the previous
1094 * subclasses get called or the original window procedure.
1097 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1098 UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1100 LPSUBCLASS_INFO stack;
1101 LPSUBCLASSPROCS proc;
1103 TRACE ("(%p, %p, %lx, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
1105 /* Since the window procedure that we set here has two additional arguments,
1106 * we can't simply set it as the new window procedure of the window. So we
1107 * set our own window procedure and then calculate the other two arguments
1110 /* See if we have been called for this window */
1111 stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
1113 /* allocate stack */
1114 stack = Alloc (sizeof(SUBCLASS_INFO));
1116 ERR ("Failed to allocate our Subclassing stack\n");
1119 SetPropW (hWnd, COMCTL32_wSubclass, (HANDLE)stack);
1121 /* set window procedure to our own and save the current one */
1122 if (IsWindowUnicode (hWnd))
1123 stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC,
1124 (DWORD_PTR)COMCTL32_SubclassProc);
1126 stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC,
1127 (DWORD_PTR)COMCTL32_SubclassProc);
1130 /* Check to see if we have called this function with the same uIDSubClass
1131 * and pfnSubclass */
1132 proc = stack->SubclassProcs;
1134 if ((proc->id == uIDSubclass) &&
1135 (proc->subproc == pfnSubclass)) {
1143 proc = Alloc(sizeof(SUBCLASSPROCS));
1145 ERR ("Failed to allocate subclass entry in stack\n");
1146 if (IsWindowUnicode (hWnd))
1147 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1149 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1151 RemovePropW( hWnd, COMCTL32_wSubclass );
1155 proc->subproc = pfnSubclass;
1157 proc->id = uIDSubclass;
1158 proc->next = stack->SubclassProcs;
1159 stack->SubclassProcs = proc;
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 const SUBCLASS_INFO *stack;
1185 const SUBCLASSPROCS *proc;
1187 TRACE ("(%p, %p, %lx, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
1189 /* See if we have been called for this window */
1190 stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
1194 proc = stack->SubclassProcs;
1196 if ((proc->id == uID) &&
1197 (proc->subproc == pfnSubclass)) {
1198 *pdwRef = proc->ref;
1208 /***********************************************************************
1209 * RemoveWindowSubclass [COMCTL32.412]
1211 * Removes a window subclass.
1214 * hWnd [in] Handle to the window were subclassing
1215 * pfnSubclass [in] Pointer to the subclass procedure
1216 * uID [in] Unique identifier of this subclass
1223 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1225 LPSUBCLASS_INFO stack;
1226 LPSUBCLASSPROCS prevproc = NULL;
1227 LPSUBCLASSPROCS proc;
1230 TRACE ("(%p, %p, %lx)\n", hWnd, pfnSubclass, uID);
1232 /* Find the Subclass to remove */
1233 stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
1237 proc = stack->SubclassProcs;
1239 if ((proc->id == uID) &&
1240 (proc->subproc == pfnSubclass)) {
1243 stack->SubclassProcs = proc->next;
1245 prevproc->next = proc->next;
1247 if (stack->stackpos == proc)
1248 stack->stackpos = stack->stackpos->next;
1258 if (!stack->SubclassProcs && !stack->running) {
1259 TRACE("Last Subclass removed, cleaning up\n");
1260 /* clean up our heap and reset the original window procedure */
1261 if (IsWindowUnicode (hWnd))
1262 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1264 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1266 RemovePropW( hWnd, COMCTL32_wSubclass );
1272 /***********************************************************************
1273 * COMCTL32_SubclassProc (internal)
1275 * Window procedure for all subclassed windows.
1276 * Saves the current subclassing stack position to support nested messages
1278 LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1280 LPSUBCLASS_INFO stack;
1281 LPSUBCLASSPROCS proc;
1284 TRACE ("(%p, 0x%08x, 0x%08lx, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
1286 stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
1288 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1292 /* Save our old stackpos to properly handle nested messages */
1293 proc = stack->stackpos;
1294 stack->stackpos = stack->SubclassProcs;
1296 ret = DefSubclassProc(hWnd, uMsg, wParam, lParam);
1298 stack->stackpos = proc;
1300 if (!stack->SubclassProcs && !stack->running) {
1301 TRACE("Last Subclass removed, cleaning up\n");
1302 /* clean up our heap and reset the original window procedure */
1303 if (IsWindowUnicode (hWnd))
1304 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1306 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1308 RemovePropW( hWnd, COMCTL32_wSubclass );
1313 /***********************************************************************
1314 * DefSubclassProc [COMCTL32.413]
1316 * Calls the next window procedure (ie. the one before this subclass)
1319 * hWnd [in] The window that we're subclassing
1321 * wParam [in] WPARAM
1322 * lParam [in] LPARAM
1329 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1331 LPSUBCLASS_INFO stack;
1334 TRACE ("(%p, 0x%08x, 0x%08lx, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
1336 /* retrieve our little stack from the Properties */
1337 stack = (LPSUBCLASS_INFO)GetPropW (hWnd, COMCTL32_wSubclass);
1339 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1343 /* If we are at the end of stack then we have to call the original
1344 * window procedure */
1345 if (!stack->stackpos) {
1346 if (IsWindowUnicode (hWnd))
1347 ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
1349 ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1351 const SUBCLASSPROCS *proc = stack->stackpos;
1352 stack->stackpos = stack->stackpos->next;
1353 /* call the Subclass procedure from the stack */
1354 ret = proc->subproc (hWnd, uMsg, wParam, lParam,
1355 proc->id, proc->ref);
1362 /***********************************************************************
1363 * COMCTL32_CreateToolTip [NOT AN API]
1365 * Creates a tooltip for the control specified in hwnd and does all
1366 * necessary setup and notifications.
1369 * hwndOwner [I] Handle to the window that will own the tool tip.
1372 * Success: Handle of tool tip window.
1377 COMCTL32_CreateToolTip(HWND hwndOwner)
1381 hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, WS_POPUP,
1382 CW_USEDEFAULT, CW_USEDEFAULT,
1383 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1386 /* Send NM_TOOLTIPSCREATED notification */
1389 NMTOOLTIPSCREATED nmttc;
1390 /* true owner can be different if hwndOwner is a child window */
1391 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1392 nmttc.hdr.hwndFrom = hwndTrueOwner;
1393 nmttc.hdr.idFrom = GetWindowLongPtrW(hwndTrueOwner, GWLP_ID);
1394 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1395 nmttc.hwndToolTips = hwndToolTip;
1397 SendMessageW(GetParent(hwndTrueOwner), WM_NOTIFY,
1398 (WPARAM)GetWindowLongPtrW(hwndTrueOwner, GWLP_ID),
1406 /***********************************************************************
1407 * COMCTL32_RefreshSysColors [NOT AN API]
1409 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1410 * refresh the color values in the color structure
1420 COMCTL32_RefreshSysColors(void)
1422 comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1423 comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1424 comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1425 comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1426 comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1427 comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
1428 comctl32_color.clrHotTrackingColor = GetSysColor (COLOR_HOTLIGHT);
1429 comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1430 comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1431 comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1432 comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1433 comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1434 comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1435 comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1436 comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1437 comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1438 comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);
1441 /***********************************************************************
1442 * COMCTL32_DrawInsertMark [NOT AN API]
1444 * Draws an insertion mark (which looks similar to an 'I').
1447 * hDC [I] Device context to draw onto.
1448 * lpRect [I] Co-ordinates of insertion mark.
1449 * clrInsertMark [I] Colour of the insertion mark.
1450 * bHorizontal [I] True if insert mark should be drawn horizontally,
1451 * vertical otherwise.
1457 * Draws up to but not including the bottom co-ordinate when drawing
1458 * vertically or the right co-ordinate when horizontal.
1460 void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal)
1462 HPEN hPen = CreatePen(PS_SOLID, 1, clrInsertMark);
1464 static const DWORD adwPolyPoints[] = {4,4,4};
1465 LONG lCentre = (bHorizontal ?
1466 lpRect->top + (lpRect->bottom - lpRect->top)/2 :
1467 lpRect->left + (lpRect->right - lpRect->left)/2);
1468 LONG l1 = (bHorizontal ? lpRect->left : lpRect->top);
1469 LONG l2 = (bHorizontal ? lpRect->right : lpRect->bottom);
1470 const POINT aptInsertMark[] =
1472 /* top (V) or left (H) arrow */
1476 {lCentre + 1, l1 + 2},
1480 {lCentre + 1, l1 - 1},
1481 {lCentre + 1, l2 - 2},
1482 /* bottom (V) or right (H) arrow */
1484 {lCentre - 2, l2 - 1},
1485 {lCentre + 3, l2 - 1},
1486 {lCentre + 1, l2 - 3},
1488 hOldPen = SelectObject(hDC, hPen);
1489 PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));
1490 SelectObject(hDC, hOldPen);
1494 /***********************************************************************
1495 * COMCTL32_EnsureBitmapSize [internal]
1497 * If needed, enlarge the bitmap so that the width is at least cxMinWidth and
1498 * the height is at least cyMinHeight. If the bitmap already has these
1499 * dimensions nothing changes.
1502 * hBitmap [I/O] Bitmap to modify. The handle may change
1503 * cxMinWidth [I] If the width of the bitmap is smaller, then it will
1504 * be enlarged to this value
1505 * cyMinHeight [I] If the height of the bitmap is smaller, then it will
1506 * be enlarged to this value
1507 * cyBackground [I] The color with which the new area will be filled
1512 void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground)
1517 HBITMAP hNewDCBitmap, hOldDCBitmap;
1521 if (!GetObjectW(*pBitmap, sizeof(BITMAP), &bmp))
1523 cxNew = (cxMinWidth > bmp.bmWidth ? cxMinWidth : bmp.bmWidth);
1524 cyNew = (cyMinHeight > bmp.bmHeight ? cyMinHeight : bmp.bmHeight);
1525 if (cxNew == bmp.bmWidth && cyNew == bmp.bmHeight)
1528 hdcNew = CreateCompatibleDC(NULL);
1529 hNewBitmap = CreateBitmap(cxNew, cyNew, bmp.bmPlanes, bmp.bmBitsPixel, NULL);
1530 hNewDCBitmap = SelectObject(hdcNew, hNewBitmap);
1531 hNewDCBrush = SelectObject(hdcNew, CreateSolidBrush(crBackground));
1533 hdcOld = CreateCompatibleDC(NULL);
1534 hOldDCBitmap = SelectObject(hdcOld, *pBitmap);
1536 BitBlt(hdcNew, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcOld, 0, 0, SRCCOPY);
1537 if (bmp.bmWidth < cxMinWidth)
1538 PatBlt(hdcNew, bmp.bmWidth, 0, cxNew, bmp.bmHeight, PATCOPY);
1539 if (bmp.bmHeight < cyMinHeight)
1540 PatBlt(hdcNew, 0, bmp.bmHeight, bmp.bmWidth, cyNew, PATCOPY);
1541 if (bmp.bmWidth < cxMinWidth && bmp.bmHeight < cyMinHeight)
1542 PatBlt(hdcNew, bmp.bmWidth, bmp.bmHeight, cxNew, cyNew, PATCOPY);
1544 SelectObject(hdcNew, hNewDCBitmap);
1545 DeleteObject(SelectObject(hdcNew, hNewDCBrush));
1547 SelectObject(hdcOld, hOldDCBitmap);
1550 DeleteObject(*pBitmap);
1551 *pBitmap = hNewBitmap;
1555 /***********************************************************************
1556 * MirrorIcon [COMCTL32.414]
1558 * Mirrors an icon so that it will appear correctly on a mirrored DC.
1561 * phicon1 [I/O] Icon.
1562 * phicon2 [I/O] Icon.
1568 BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2)
1570 FIXME("(%p, %p): stub\n", phicon1, phicon2);
1574 static inline int IsDelimiter(WCHAR c)
1587 static int CALLBACK PathWordBreakProc(LPCWSTR lpch, int ichCurrent, int cch, int code)
1589 if (code == WB_ISDELIMITER)
1590 return IsDelimiter(lpch[ichCurrent]);
1593 int dir = (code == WB_LEFT) ? -1 : 1;
1594 for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
1595 if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;
1600 /***********************************************************************
1601 * SetPathWordBreakProc [COMCTL32.384]
1603 * Sets the word break procedure for an edit control to one that understands
1604 * paths so that the user can jump over directories.
1607 * hwnd [I] Handle to edit control.
1608 * bSet [I] If this is TRUE then the word break proc is set, otherwise it is removed.
1611 * Result from EM_SETWORDBREAKPROC message.
1613 LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)
1615 return SendMessageW(hwnd, EM_SETWORDBREAKPROC, 0,
1616 (LPARAM)(bSet ? PathWordBreakProc : NULL));
1619 /***********************************************************************
1620 * DrawShadowText [COMCTL32.@]
1622 * Draw text with shadow.
1624 int WINAPI DrawShadowText(HDC hdc, LPCWSTR pszText, UINT cch, RECT *rect, DWORD dwFlags,
1625 COLORREF crText, COLORREF crShadow, int ixOffset, int iyOffset)
1627 FIXME("(%p, %s, %d, %p, %d, 0x%08x, 0x%08x, %d, %d): stub\n", hdc, debugstr_w(pszText), cch, rect, dwFlags,
1628 crText, crShadow, ixOffset, iyOffset);
1629 return DrawTextW(hdc, pszText, cch, rect, DT_LEFT);