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
);