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 static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
128 static LPWSTR COMCTL32_wSubclass = NULL;
129 HMODULE COMCTL32_hModule = 0;
130 static 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;
540 if (style & SBT_RTLREADING)
541 FIXME("Unsupported RTL style!\n");
546 DrawTextW (hdc, text - strCnt, strCnt, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
549 if (align==DT_RIGHT) {
552 align = (align==DT_LEFT ? DT_CENTER : DT_RIGHT);
558 if (strCnt) DrawTextW (hdc, text - strCnt, -1, &r, align|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
559 SetBkMode(hdc, oldbkmode);
564 /***********************************************************************
565 * DrawStatusText [COMCTL32.@]
566 * DrawStatusTextA [COMCTL32.5]
568 * Draws text with borders, like in a status bar.
571 * hdc [I] handle to the window's display context
572 * lprc [I] pointer to a rectangle
573 * text [I] pointer to the text
574 * style [I] drawing style
580 void WINAPI DrawStatusTextA (HDC hdc, LPCRECT lprc, LPCSTR text, UINT style)
586 if ( (len = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 )) ) {
587 if ( (textW = Alloc( len * sizeof(WCHAR) )) )
588 MultiByteToWideChar( CP_ACP, 0, text, -1, textW, len );
591 DrawStatusTextW( hdc, lprc, textW, style );
596 /***********************************************************************
597 * CreateStatusWindow [COMCTL32.@]
598 * CreateStatusWindowA [COMCTL32.6]
600 * Creates a status bar
603 * style [I] window style
604 * text [I] pointer to the window text
605 * parent [I] handle to the parent window
606 * wid [I] control id of the status bar
609 * Success: handle to the status window
614 CreateStatusWindowA (LONG style, LPCSTR text, HWND parent, UINT wid)
616 return CreateWindowA(STATUSCLASSNAMEA, text, style,
617 CW_USEDEFAULT, CW_USEDEFAULT,
618 CW_USEDEFAULT, CW_USEDEFAULT,
619 parent, (HMENU)(DWORD_PTR)wid, 0, 0);
623 /***********************************************************************
624 * CreateStatusWindowW [COMCTL32.@]
626 * Creates a status bar control
629 * style [I] window style
630 * text [I] pointer to the window text
631 * parent [I] handle to the parent window
632 * wid [I] control id of the status bar
635 * Success: handle to the status window
640 CreateStatusWindowW (LONG style, LPCWSTR text, HWND parent, UINT wid)
642 return CreateWindowW(STATUSCLASSNAMEW, text, style,
643 CW_USEDEFAULT, CW_USEDEFAULT,
644 CW_USEDEFAULT, CW_USEDEFAULT,
645 parent, (HMENU)(DWORD_PTR)wid, 0, 0);
649 /***********************************************************************
650 * CreateUpDownControl [COMCTL32.16]
652 * Creates an up-down control
655 * style [I] window styles
656 * x [I] horizontal position of the control
657 * y [I] vertical position of the control
658 * cx [I] with of the control
659 * cy [I] height of the control
660 * parent [I] handle to the parent window
661 * id [I] the control's identifier
662 * inst [I] handle to the application's module instance
663 * buddy [I] handle to the buddy window, can be NULL
664 * maxVal [I] upper limit of the control
665 * minVal [I] lower limit of the control
666 * curVal [I] current value of the control
669 * Success: handle to the updown control
674 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
675 HWND parent, INT id, HINSTANCE inst,
676 HWND buddy, INT maxVal, INT minVal, INT curVal)
679 CreateWindowW (UPDOWN_CLASSW, 0, style, x, y, cx, cy,
680 parent, (HMENU)(DWORD_PTR)id, inst, 0);
682 SendMessageW (hUD, UDM_SETBUDDY, (WPARAM)buddy, 0);
683 SendMessageW (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
684 SendMessageW (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
691 /***********************************************************************
692 * InitCommonControls [COMCTL32.17]
694 * Registers the common controls.
703 * This function is just a dummy - all the controls are registered at
704 * the DLL's initialization. See InitCommonContolsEx for details.
708 InitCommonControls (void)
713 /***********************************************************************
714 * InitCommonControlsEx [COMCTL32.@]
716 * Registers the common controls.
719 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
726 * Probably all versions of comctl32 initializes the Win95 controls in DllMain
727 * during DLL initialization. Starting from comctl32 v5.82 all the controls
728 * are initialized there. We follow this behaviour and this function is just
731 * Note: when writing programs under Windows, if you don't call any function
732 * from comctl32 the linker may not link this DLL. If InitCommonControlsEx
733 * was the only comctl32 function you were calling and you remove it you may
734 * have a false impression that InitCommonControlsEx actually did something.
738 InitCommonControlsEx (const INITCOMMONCONTROLSEX *lpInitCtrls)
740 if (!lpInitCtrls || lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
743 TRACE("(0x%08x)\n", lpInitCtrls->dwICC);
748 /***********************************************************************
749 * CreateToolbarEx [COMCTL32.@]
751 * Creates a toolbar window.
769 * Success: handle to the tool bar control
774 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
775 HINSTANCE hBMInst, UINT_PTR wBMID, LPCTBBUTTON lpButtons,
776 INT iNumButtons, INT dxButton, INT dyButton,
777 INT dxBitmap, INT dyBitmap, UINT uStructSize)
782 CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style|WS_CHILD, 0,0,100,30,
783 hwnd, (HMENU)(DWORD_PTR)wID, COMCTL32_hModule, NULL);
787 SendMessageW (hwndTB, TB_BUTTONSTRUCTSIZE, uStructSize, 0);
789 /* set bitmap and button size */
790 /*If CreateToolbarEx receives 0, windows sets default values*/
795 if (dxBitmap == 0 || dyBitmap == 0)
796 dxBitmap = dyBitmap = 16;
797 SendMessageW(hwndTB, TB_SETBITMAPSIZE, 0, MAKELPARAM(dxBitmap, dyBitmap));
803 /* TB_SETBUTTONSIZE -> TB_SETBITMAPSIZE bug introduced for Windows compatibility */
804 if (dxButton != 0 && dyButton != 0)
805 SendMessageW(hwndTB, TB_SETBITMAPSIZE, 0, MAKELPARAM(dxButton, dyButton));
809 if (nBitmaps > 0 || hBMInst == HINST_COMMCTRL)
811 tbab.hInst = hBMInst;
814 SendMessageW (hwndTB, TB_ADDBITMAP, nBitmaps, (LPARAM)&tbab);
818 SendMessageW (hwndTB, TB_ADDBUTTONSW, iNumButtons, (LPARAM)lpButtons);
825 /***********************************************************************
826 * CreateMappedBitmap [COMCTL32.8]
828 * Loads a bitmap resource using a colour map.
831 * hInstance [I] Handle to the module containing the bitmap.
832 * idBitmap [I] The bitmap resource ID.
833 * wFlags [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
834 * lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
835 * iNumMaps [I] Number of COLORMAP's pointed to by lpColorMap.
838 * Success: handle to the new bitmap
843 CreateMappedBitmap (HINSTANCE hInstance, INT_PTR idBitmap, UINT wFlags,
844 LPCOLORMAP lpColorMap, INT iNumMaps)
848 const BITMAPINFOHEADER *lpBitmap;
849 LPBITMAPINFOHEADER lpBitmapInfo;
850 UINT nSize, nColorTableSize, iColor;
851 RGBQUAD *pColorTable;
852 INT i, iMaps, nWidth, nHeight;
855 LPCOLORMAP sysColorMap;
857 COLORMAP internalColorMap[4] =
858 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
860 /* initialize pointer to colortable and default color table */
863 sysColorMap = lpColorMap;
866 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
867 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
868 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
869 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
871 sysColorMap = internalColorMap;
874 hRsrc = FindResourceW (hInstance, (LPWSTR)idBitmap, (LPWSTR)RT_BITMAP);
877 hglb = LoadResource (hInstance, hRsrc);
880 lpBitmap = LockResource (hglb);
881 if (lpBitmap == NULL)
884 if (lpBitmap->biSize >= sizeof(BITMAPINFOHEADER) && lpBitmap->biClrUsed)
885 nColorTableSize = lpBitmap->biClrUsed;
886 else if (lpBitmap->biBitCount <= 8)
887 nColorTableSize = (1 << lpBitmap->biBitCount);
890 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
891 lpBitmapInfo = GlobalAlloc (GMEM_FIXED, nSize);
892 if (lpBitmapInfo == NULL)
894 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
896 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo) + lpBitmapInfo->biSize);
898 for (iColor = 0; iColor < nColorTableSize; iColor++) {
899 for (i = 0; i < iMaps; i++) {
900 cRef = RGB(pColorTable[iColor].rgbRed,
901 pColorTable[iColor].rgbGreen,
902 pColorTable[iColor].rgbBlue);
903 if ( cRef == sysColorMap[i].from) {
905 if (wFlags & CBS_MASKED) {
906 if (sysColorMap[i].to != COLOR_BTNTEXT)
907 pColorTable[iColor] = RGB(255, 255, 255);
911 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
912 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
913 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
918 nWidth = lpBitmapInfo->biWidth;
919 nHeight = lpBitmapInfo->biHeight;
920 hdcScreen = GetDC (NULL);
921 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
923 HDC hdcDst = CreateCompatibleDC (hdcScreen);
924 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
925 const BYTE *lpBits = (const BYTE *)lpBitmap + nSize;
926 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
927 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
929 SelectObject (hdcDst, hbmOld);
932 ReleaseDC (NULL, hdcScreen);
933 GlobalFree (lpBitmapInfo);
940 /***********************************************************************
941 * CreateToolbar [COMCTL32.7]
943 * Creates a toolbar control.
956 * Success: handle to the tool bar control
960 * Do not use this functions anymore. Use CreateToolbarEx instead.
964 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
965 HINSTANCE hBMInst, UINT wBMID,
966 LPCTBBUTTON lpButtons,INT iNumButtons)
968 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
969 hBMInst, wBMID, lpButtons,
970 iNumButtons, 0, 0, 0, 0, CCSIZEOF_STRUCT(TBBUTTON, dwData));
974 /***********************************************************************
975 * DllGetVersion [COMCTL32.@]
977 * Retrieves version information of the 'COMCTL32.DLL'
980 * pdvi [O] pointer to version information structure.
984 * Failure: E_INVALIDARG
987 * Returns version of a comctl32.dll from IE4.01 SP1.
990 HRESULT WINAPI DllGetVersion (DLLVERSIONINFO *pdvi)
992 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
993 WARN("wrong DLLVERSIONINFO size from app\n");
997 pdvi->dwMajorVersion = COMCTL32_VERSION;
998 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
999 pdvi->dwBuildNumber = 2919;
1000 pdvi->dwPlatformID = 6304;
1002 TRACE("%u.%u.%u.%u\n",
1003 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
1004 pdvi->dwBuildNumber, pdvi->dwPlatformID);
1009 /***********************************************************************
1010 * DllInstall (COMCTL32.@)
1012 * Installs the ComCtl32 DLL.
1016 * Failure: A HRESULT error
1018 HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
1020 TRACE("(%u, %s): stub\n", bInstall, debugstr_w(cmdline));
1021 if (!create_manifest( bInstall )) return HRESULT_FROM_WIN32(GetLastError());
1025 /***********************************************************************
1026 * _TrackMouseEvent [COMCTL32.@]
1028 * Requests notification of mouse events
1030 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1031 * to the hwnd specified in the ptme structure. After the event message
1032 * is posted to the hwnd, the entry in the queue is removed.
1034 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1035 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1036 * immediately and the TME_LEAVE flag being ignored.
1039 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1045 * IMPLEMENTATION moved to USER32.TrackMouseEvent
1050 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1052 return TrackMouseEvent (ptme);
1055 /*************************************************************************
1056 * GetMUILanguage [COMCTL32.@]
1058 * Returns the user interface language in use by the current process.
1061 * Language ID in use by the current process.
1063 LANGID WINAPI GetMUILanguage (VOID)
1065 return COMCTL32_uiLang;
1069 /*************************************************************************
1070 * InitMUILanguage [COMCTL32.@]
1072 * Sets the user interface language to be used by the current process.
1077 VOID WINAPI InitMUILanguage (LANGID uiLang)
1079 COMCTL32_uiLang = uiLang;
1083 /***********************************************************************
1084 * SetWindowSubclass [COMCTL32.410]
1086 * Starts a window subclass
1089 * hWnd [in] handle to window subclass.
1090 * pfnSubclass [in] Pointer to new window procedure.
1091 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1092 * dwRef [in] Reference data to pass to window procedure.
1099 * If an application manually subclasses a window after subclassing it with
1100 * this API and then with this API again, then none of the previous
1101 * subclasses get called or the original window procedure.
1104 BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1105 UINT_PTR uIDSubclass, DWORD_PTR dwRef)
1107 LPSUBCLASS_INFO stack;
1108 LPSUBCLASSPROCS proc;
1110 TRACE ("(%p, %p, %lx, %lx)\n", hWnd, pfnSubclass, uIDSubclass, dwRef);
1112 /* Since the window procedure that we set here has two additional arguments,
1113 * we can't simply set it as the new window procedure of the window. So we
1114 * set our own window procedure and then calculate the other two arguments
1117 /* See if we have been called for this window */
1118 stack = GetPropW (hWnd, COMCTL32_wSubclass);
1120 /* allocate stack */
1121 stack = Alloc (sizeof(SUBCLASS_INFO));
1123 ERR ("Failed to allocate our Subclassing stack\n");
1126 SetPropW (hWnd, COMCTL32_wSubclass, stack);
1128 /* set window procedure to our own and save the current one */
1129 if (IsWindowUnicode (hWnd))
1130 stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC,
1131 (DWORD_PTR)COMCTL32_SubclassProc);
1133 stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC,
1134 (DWORD_PTR)COMCTL32_SubclassProc);
1137 /* Check to see if we have called this function with the same uIDSubClass
1138 * and pfnSubclass */
1139 proc = stack->SubclassProcs;
1141 if ((proc->id == uIDSubclass) &&
1142 (proc->subproc == pfnSubclass)) {
1150 proc = Alloc(sizeof(SUBCLASSPROCS));
1152 ERR ("Failed to allocate subclass entry in stack\n");
1153 if (IsWindowUnicode (hWnd))
1154 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1156 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1158 RemovePropW( hWnd, COMCTL32_wSubclass );
1162 proc->subproc = pfnSubclass;
1164 proc->id = uIDSubclass;
1165 proc->next = stack->SubclassProcs;
1166 stack->SubclassProcs = proc;
1172 /***********************************************************************
1173 * GetWindowSubclass [COMCTL32.411]
1175 * Gets the Reference data from a subclass.
1178 * hWnd [in] Handle to window which were subclassing
1179 * pfnSubclass [in] Pointer to the subclass procedure
1180 * uID [in] Unique indentifier of the subclassing procedure
1181 * pdwRef [out] Pointer to the reference data
1188 BOOL WINAPI GetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
1189 UINT_PTR uID, DWORD_PTR *pdwRef)
1191 const SUBCLASS_INFO *stack;
1192 const SUBCLASSPROCS *proc;
1194 TRACE ("(%p, %p, %lx, %p)\n", hWnd, pfnSubclass, uID, pdwRef);
1196 /* See if we have been called for this window */
1197 stack = GetPropW (hWnd, COMCTL32_wSubclass);
1201 proc = stack->SubclassProcs;
1203 if ((proc->id == uID) &&
1204 (proc->subproc == pfnSubclass)) {
1205 *pdwRef = proc->ref;
1215 /***********************************************************************
1216 * RemoveWindowSubclass [COMCTL32.412]
1218 * Removes a window subclass.
1221 * hWnd [in] Handle to the window were subclassing
1222 * pfnSubclass [in] Pointer to the subclass procedure
1223 * uID [in] Unique identifier of this subclass
1230 BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
1232 LPSUBCLASS_INFO stack;
1233 LPSUBCLASSPROCS prevproc = NULL;
1234 LPSUBCLASSPROCS proc;
1237 TRACE ("(%p, %p, %lx)\n", hWnd, pfnSubclass, uID);
1239 /* Find the Subclass to remove */
1240 stack = GetPropW (hWnd, COMCTL32_wSubclass);
1244 proc = stack->SubclassProcs;
1246 if ((proc->id == uID) &&
1247 (proc->subproc == pfnSubclass)) {
1250 stack->SubclassProcs = proc->next;
1252 prevproc->next = proc->next;
1254 if (stack->stackpos == proc)
1255 stack->stackpos = stack->stackpos->next;
1265 if (!stack->SubclassProcs && !stack->running) {
1266 TRACE("Last Subclass removed, cleaning up\n");
1267 /* clean up our heap and reset the original window procedure */
1268 if (IsWindowUnicode (hWnd))
1269 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1271 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1273 RemovePropW( hWnd, COMCTL32_wSubclass );
1279 /***********************************************************************
1280 * COMCTL32_SubclassProc (internal)
1282 * Window procedure for all subclassed windows.
1283 * Saves the current subclassing stack position to support nested messages
1285 static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1287 LPSUBCLASS_INFO stack;
1288 LPSUBCLASSPROCS proc;
1291 TRACE ("(%p, 0x%08x, 0x%08lx, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
1293 stack = GetPropW (hWnd, COMCTL32_wSubclass);
1295 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1299 /* Save our old stackpos to properly handle nested messages */
1300 proc = stack->stackpos;
1301 stack->stackpos = stack->SubclassProcs;
1303 ret = DefSubclassProc(hWnd, uMsg, wParam, lParam);
1305 stack->stackpos = proc;
1307 if (!stack->SubclassProcs && !stack->running) {
1308 TRACE("Last Subclass removed, cleaning up\n");
1309 /* clean up our heap and reset the original window procedure */
1310 if (IsWindowUnicode (hWnd))
1311 SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1313 SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc);
1315 RemovePropW( hWnd, COMCTL32_wSubclass );
1320 /***********************************************************************
1321 * DefSubclassProc [COMCTL32.413]
1323 * Calls the next window procedure (ie. the one before this subclass)
1326 * hWnd [in] The window that we're subclassing
1328 * wParam [in] WPARAM
1329 * lParam [in] LPARAM
1336 LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1338 LPSUBCLASS_INFO stack;
1341 TRACE ("(%p, 0x%08x, 0x%08lx, 0x%08lx)\n", hWnd, uMsg, wParam, lParam);
1343 /* retrieve our little stack from the Properties */
1344 stack = GetPropW (hWnd, COMCTL32_wSubclass);
1346 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
1350 /* If we are at the end of stack then we have to call the original
1351 * window procedure */
1352 if (!stack->stackpos) {
1353 if (IsWindowUnicode (hWnd))
1354 ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam);
1356 ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
1358 const SUBCLASSPROCS *proc = stack->stackpos;
1359 stack->stackpos = stack->stackpos->next;
1360 /* call the Subclass procedure from the stack */
1361 ret = proc->subproc (hWnd, uMsg, wParam, lParam,
1362 proc->id, proc->ref);
1369 /***********************************************************************
1370 * COMCTL32_CreateToolTip [NOT AN API]
1372 * Creates a tooltip for the control specified in hwnd and does all
1373 * necessary setup and notifications.
1376 * hwndOwner [I] Handle to the window that will own the tool tip.
1379 * Success: Handle of tool tip window.
1384 COMCTL32_CreateToolTip(HWND hwndOwner)
1388 hwndToolTip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, WS_POPUP,
1389 CW_USEDEFAULT, CW_USEDEFAULT,
1390 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1393 /* Send NM_TOOLTIPSCREATED notification */
1396 NMTOOLTIPSCREATED nmttc;
1397 /* true owner can be different if hwndOwner is a child window */
1398 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1399 nmttc.hdr.hwndFrom = hwndTrueOwner;
1400 nmttc.hdr.idFrom = GetWindowLongPtrW(hwndTrueOwner, GWLP_ID);
1401 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1402 nmttc.hwndToolTips = hwndToolTip;
1404 SendMessageW(GetParent(hwndTrueOwner), WM_NOTIFY,
1405 GetWindowLongPtrW(hwndTrueOwner, GWLP_ID), (LPARAM)&nmttc);
1412 /***********************************************************************
1413 * COMCTL32_RefreshSysColors [NOT AN API]
1415 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1416 * refresh the color values in the color structure
1426 COMCTL32_RefreshSysColors(void)
1428 comctl32_color.clrBtnHighlight = GetSysColor (COLOR_BTNHIGHLIGHT);
1429 comctl32_color.clrBtnShadow = GetSysColor (COLOR_BTNSHADOW);
1430 comctl32_color.clrBtnText = GetSysColor (COLOR_BTNTEXT);
1431 comctl32_color.clrBtnFace = GetSysColor (COLOR_BTNFACE);
1432 comctl32_color.clrHighlight = GetSysColor (COLOR_HIGHLIGHT);
1433 comctl32_color.clrHighlightText = GetSysColor (COLOR_HIGHLIGHTTEXT);
1434 comctl32_color.clrHotTrackingColor = GetSysColor (COLOR_HOTLIGHT);
1435 comctl32_color.clr3dHilight = GetSysColor (COLOR_3DHILIGHT);
1436 comctl32_color.clr3dShadow = GetSysColor (COLOR_3DSHADOW);
1437 comctl32_color.clr3dDkShadow = GetSysColor (COLOR_3DDKSHADOW);
1438 comctl32_color.clr3dFace = GetSysColor (COLOR_3DFACE);
1439 comctl32_color.clrWindow = GetSysColor (COLOR_WINDOW);
1440 comctl32_color.clrWindowText = GetSysColor (COLOR_WINDOWTEXT);
1441 comctl32_color.clrGrayText = GetSysColor (COLOR_GRAYTEXT);
1442 comctl32_color.clrActiveCaption = GetSysColor (COLOR_ACTIVECAPTION);
1443 comctl32_color.clrInfoBk = GetSysColor (COLOR_INFOBK);
1444 comctl32_color.clrInfoText = GetSysColor (COLOR_INFOTEXT);
1447 /***********************************************************************
1448 * COMCTL32_DrawInsertMark [NOT AN API]
1450 * Draws an insertion mark (which looks similar to an 'I').
1453 * hDC [I] Device context to draw onto.
1454 * lpRect [I] Co-ordinates of insertion mark.
1455 * clrInsertMark [I] Colour of the insertion mark.
1456 * bHorizontal [I] True if insert mark should be drawn horizontally,
1457 * vertical otherwise.
1463 * Draws up to but not including the bottom co-ordinate when drawing
1464 * vertically or the right co-ordinate when horizontal.
1466 void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal)
1468 HPEN hPen = CreatePen(PS_SOLID, 1, clrInsertMark);
1470 static const DWORD adwPolyPoints[] = {4,4,4};
1471 LONG lCentre = (bHorizontal ?
1472 lpRect->top + (lpRect->bottom - lpRect->top)/2 :
1473 lpRect->left + (lpRect->right - lpRect->left)/2);
1474 LONG l1 = (bHorizontal ? lpRect->left : lpRect->top);
1475 LONG l2 = (bHorizontal ? lpRect->right : lpRect->bottom);
1476 const POINT aptInsertMark[] =
1478 /* top (V) or left (H) arrow */
1482 {lCentre + 1, l1 + 2},
1486 {lCentre + 1, l1 - 1},
1487 {lCentre + 1, l2 - 2},
1488 /* bottom (V) or right (H) arrow */
1490 {lCentre - 2, l2 - 1},
1491 {lCentre + 3, l2 - 1},
1492 {lCentre + 1, l2 - 3},
1494 hOldPen = SelectObject(hDC, hPen);
1495 PolyPolyline(hDC, aptInsertMark, adwPolyPoints, sizeof(adwPolyPoints)/sizeof(adwPolyPoints[0]));
1496 SelectObject(hDC, hOldPen);
1500 /***********************************************************************
1501 * COMCTL32_EnsureBitmapSize [internal]
1503 * If needed, enlarge the bitmap so that the width is at least cxMinWidth and
1504 * the height is at least cyMinHeight. If the bitmap already has these
1505 * dimensions nothing changes.
1508 * hBitmap [I/O] Bitmap to modify. The handle may change
1509 * cxMinWidth [I] If the width of the bitmap is smaller, then it will
1510 * be enlarged to this value
1511 * cyMinHeight [I] If the height of the bitmap is smaller, then it will
1512 * be enlarged to this value
1513 * cyBackground [I] The color with which the new area will be filled
1518 void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground)
1523 HBITMAP hNewDCBitmap, hOldDCBitmap;
1527 if (!GetObjectW(*pBitmap, sizeof(BITMAP), &bmp))
1529 cxNew = (cxMinWidth > bmp.bmWidth ? cxMinWidth : bmp.bmWidth);
1530 cyNew = (cyMinHeight > bmp.bmHeight ? cyMinHeight : bmp.bmHeight);
1531 if (cxNew == bmp.bmWidth && cyNew == bmp.bmHeight)
1534 hdcNew = CreateCompatibleDC(NULL);
1535 hNewBitmap = CreateBitmap(cxNew, cyNew, bmp.bmPlanes, bmp.bmBitsPixel, NULL);
1536 hNewDCBitmap = SelectObject(hdcNew, hNewBitmap);
1537 hNewDCBrush = SelectObject(hdcNew, CreateSolidBrush(crBackground));
1539 hdcOld = CreateCompatibleDC(NULL);
1540 hOldDCBitmap = SelectObject(hdcOld, *pBitmap);
1542 BitBlt(hdcNew, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcOld, 0, 0, SRCCOPY);
1543 if (bmp.bmWidth < cxMinWidth)
1544 PatBlt(hdcNew, bmp.bmWidth, 0, cxNew, bmp.bmHeight, PATCOPY);
1545 if (bmp.bmHeight < cyMinHeight)
1546 PatBlt(hdcNew, 0, bmp.bmHeight, bmp.bmWidth, cyNew, PATCOPY);
1547 if (bmp.bmWidth < cxMinWidth && bmp.bmHeight < cyMinHeight)
1548 PatBlt(hdcNew, bmp.bmWidth, bmp.bmHeight, cxNew, cyNew, PATCOPY);
1550 SelectObject(hdcNew, hNewDCBitmap);
1551 DeleteObject(SelectObject(hdcNew, hNewDCBrush));
1553 SelectObject(hdcOld, hOldDCBitmap);
1556 DeleteObject(*pBitmap);
1557 *pBitmap = hNewBitmap;
1561 void COMCTL32_GetFontMetrics(HFONT hFont, TEXTMETRICW *ptm)
1563 HDC hdc = GetDC(NULL);
1566 hOldFont = SelectObject(hdc, hFont);
1567 GetTextMetricsW(hdc, ptm);
1568 SelectObject(hdc, hOldFont);
1569 ReleaseDC(NULL, hdc);
1572 #ifndef OCM__BASE /* avoid including olectl.h */
1573 #define OCM__BASE (WM_USER+0x1c00)
1576 /***********************************************************************
1577 * COMCTL32_IsReflectedMessage [internal]
1579 * Some parents reflect notify messages - for some messages sent by the child,
1580 * they send it back with the message code increased by OCM__BASE (0x2000).
1581 * This allows better subclassing of controls. We don't need to handle such
1582 * messages but we don't want to print ERRs for them, so this helper function
1585 * Some of the codes are in the CCM_FIRST..CCM_LAST range, but there is no
1586 * colision with defined CCM_ codes.
1588 BOOL COMCTL32_IsReflectedMessage(UINT uMsg)
1592 case OCM__BASE + WM_COMMAND:
1593 case OCM__BASE + WM_CTLCOLORBTN:
1594 case OCM__BASE + WM_CTLCOLOREDIT:
1595 case OCM__BASE + WM_CTLCOLORDLG:
1596 case OCM__BASE + WM_CTLCOLORLISTBOX:
1597 case OCM__BASE + WM_CTLCOLORMSGBOX:
1598 case OCM__BASE + WM_CTLCOLORSCROLLBAR:
1599 case OCM__BASE + WM_CTLCOLORSTATIC:
1600 case OCM__BASE + WM_DRAWITEM:
1601 case OCM__BASE + WM_MEASUREITEM:
1602 case OCM__BASE + WM_DELETEITEM:
1603 case OCM__BASE + WM_VKEYTOITEM:
1604 case OCM__BASE + WM_CHARTOITEM:
1605 case OCM__BASE + WM_COMPAREITEM:
1606 case OCM__BASE + WM_HSCROLL:
1607 case OCM__BASE + WM_VSCROLL:
1608 case OCM__BASE + WM_PARENTNOTIFY:
1609 case OCM__BASE + WM_NOTIFY:
1616 /***********************************************************************
1617 * MirrorIcon [COMCTL32.414]
1619 * Mirrors an icon so that it will appear correctly on a mirrored DC.
1622 * phicon1 [I/O] Icon.
1623 * phicon2 [I/O] Icon.
1629 BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2)
1631 FIXME("(%p, %p): stub\n", phicon1, phicon2);
1635 static inline int IsDelimiter(WCHAR c)
1648 static int CALLBACK PathWordBreakProc(LPCWSTR lpch, int ichCurrent, int cch, int code)
1650 if (code == WB_ISDELIMITER)
1651 return IsDelimiter(lpch[ichCurrent]);
1654 int dir = (code == WB_LEFT) ? -1 : 1;
1655 for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
1656 if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;
1661 /***********************************************************************
1662 * SetPathWordBreakProc [COMCTL32.384]
1664 * Sets the word break procedure for an edit control to one that understands
1665 * paths so that the user can jump over directories.
1668 * hwnd [I] Handle to edit control.
1669 * bSet [I] If this is TRUE then the word break proc is set, otherwise it is removed.
1672 * Result from EM_SETWORDBREAKPROC message.
1674 LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)
1676 return SendMessageW(hwnd, EM_SETWORDBREAKPROC, 0,
1677 (LPARAM)(bSet ? PathWordBreakProc : NULL));
1680 /***********************************************************************
1681 * DrawShadowText [COMCTL32.@]
1683 * Draw text with shadow.
1685 int WINAPI DrawShadowText(HDC hdc, LPCWSTR pszText, UINT cch, RECT *rect, DWORD dwFlags,
1686 COLORREF crText, COLORREF crShadow, int ixOffset, int iyOffset)
1688 FIXME("(%p, %s, %d, %p, %d, 0x%08x, 0x%08x, %d, %d): stub\n", hdc, debugstr_w(pszText), cch, rect, dwFlags,
1689 crText, crShadow, ixOffset, iyOffset);
1690 return DrawTextW(hdc, pszText, cch, rect, DT_LEFT);
1693 /***********************************************************************
1694 * TaskDialogIndirect [COMCTL32.@]
1696 HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton,
1697 int *pnRadioButton, BOOL *pfVerificationFlagChecked)
1699 FIXME("%p, %p, %p, %p\n", pTaskConfig, pnButton, pnRadioButton, pfVerificationFlagChecked);
1701 if (pnButton) *pnButton = IDYES;
1702 if (pnRadioButton) *pnRadioButton = pTaskConfig->nDefaultButton;
1703 if (pfVerificationFlagChecked) *pfVerificationFlagChecked = TRUE;