2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998,2000 Eric Kohl
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * This code was audited for completeness against the documented features
24 * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.
26 * Unless otherwise noted, we belive this code to be complete, as per
27 * the specification mentioned above.
28 * If you discover missing features, or bugs, please note them below.
31 * -- implement GetMUILanguage + InitMUILanguage
32 * -- LibMain => DLLMain ("DLLMain takes over the functionality of both the
33 * LibMain and the WEP function.", MSDN)
34 * -- finish NOTES for MenuHelp, GetEffectiveClientRect and GetStatusTextW
35 * -- FIXMEs + BUGS (search for them)
38 * -- ICC_ANIMATE_CLASS
43 * -- ICC_INTERNET_CLASSES
44 * -- ICC_LINK_CLASS (not yet implemented)
45 * -- ICC_LISTVIEW_CLASSES
46 * -- ICC_NATIVEFNTCTL_CLASS
47 * -- ICC_PAGESCROLLER_CLASS
48 * -- ICC_PROGRESS_CLASS
49 * -- ICC_STANDARD_CLASSES (not yet implemented)
51 * -- ICC_TREEVIEW_CLASSES
53 * -- ICC_USEREX_CLASSES
54 * -- ICC_WIN95_CLASSES
64 #define NO_SHLWAPI_STREAM
67 #include "wine/debug.h"
69 WINE_DEFAULT_DEBUG_CHANNEL(commctrl
);
71 extern void ANIMATE_Register(void);
72 extern void ANIMATE_Unregister(void);
73 extern void COMBOEX_Register(void);
74 extern void COMBOEX_Unregister(void);
75 extern void DATETIME_Register(void);
76 extern void DATETIME_Unregister(void);
77 extern void FLATSB_Register(void);
78 extern void FLATSB_Unregister(void);
79 extern void HEADER_Register(void);
80 extern void HEADER_Unregister(void);
81 extern void HOTKEY_Register(void);
82 extern void HOTKEY_Unregister(void);
83 extern void IPADDRESS_Register(void);
84 extern void IPADDRESS_Unregister(void);
85 extern void LISTVIEW_Register(void);
86 extern void LISTVIEW_Unregister(void);
87 extern void MONTHCAL_Register(void);
88 extern void MONTHCAL_Unregister(void);
89 extern void NATIVEFONT_Register(void);
90 extern void NATIVEFONT_Unregister(void);
91 extern void PAGER_Register(void);
92 extern void PAGER_Unregister(void);
93 extern void PROGRESS_Register(void);
94 extern void PROGRESS_Unregister(void);
95 extern void REBAR_Register(void);
96 extern void REBAR_Unregister(void);
97 extern void STATUS_Register(void);
98 extern void STATUS_Unregister(void);
99 extern void TAB_Register(void);
100 extern void TAB_Unregister(void);
101 extern void TOOLBAR_Register(void);
102 extern void TOOLBAR_Unregister(void);
103 extern void TOOLTIPS_Register(void);
104 extern void TOOLTIPS_Unregister(void);
105 extern void TRACKBAR_Register(void);
106 extern void TRACKBAR_Unregister(void);
107 extern void TREEVIEW_Register(void);
108 extern void TREEVIEW_Unregister(void);
109 extern void UPDOWN_Register(void);
110 extern void UPDOWN_Unregister(void);
113 HANDLE COMCTL32_hHeap
= (HANDLE
)NULL
;
114 LPSTR COMCTL32_aSubclass
= (LPSTR
)NULL
;
115 HMODULE COMCTL32_hModule
= 0;
116 LANGID COMCTL32_uiLang
= MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
);
117 HBRUSH COMCTL32_hPattern55AABrush
= (HANDLE
)NULL
;
118 COMCTL32_SysColor comctl32_color
;
120 static HBITMAP COMCTL32_hPattern55AABitmap
= (HANDLE
)NULL
;
122 static const WORD wPattern55AA
[] =
124 0x5555, 0xaaaa, 0x5555, 0xaaaa,
125 0x5555, 0xaaaa, 0x5555, 0xaaaa
129 /***********************************************************************
130 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
133 * hinstDLL [I] handle to the 'dlls' instance
135 * lpvReserved [I] reserverd, must be NULL
143 COMCTL32_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
145 TRACE("%p,%lx,%p\n", hinstDLL
, fdwReason
, lpvReserved
);
148 case DLL_PROCESS_ATTACH
:
149 COMCTL32_hModule
= (HMODULE
)hinstDLL
;
151 /* create private heap */
152 COMCTL32_hHeap
= HeapCreate (0, 0x10000, 0);
153 TRACE("Heap created: %p\n", COMCTL32_hHeap
);
155 /* add global subclassing atom (used by 'tooltip' and 'updown') */
156 COMCTL32_aSubclass
= (LPSTR
)(DWORD
)GlobalAddAtomA ("CC32SubclassInfo");
157 TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass
);
159 /* create local pattern brush */
160 COMCTL32_hPattern55AABitmap
= CreateBitmap (8, 8, 1, 1, wPattern55AA
);
161 COMCTL32_hPattern55AABrush
= CreatePatternBrush (COMCTL32_hPattern55AABitmap
);
163 /* Get all the colors at DLL load */
164 COMCTL32_RefreshSysColors();
166 /* register all Win95 common control classes */
171 LISTVIEW_Register ();
172 PROGRESS_Register ();
176 TOOLTIPS_Register ();
177 TRACKBAR_Register ();
178 TREEVIEW_Register ();
182 case DLL_PROCESS_DETACH
:
183 /* unregister all common control classes */
184 ANIMATE_Unregister ();
185 COMBOEX_Unregister ();
186 DATETIME_Unregister ();
187 FLATSB_Unregister ();
188 HEADER_Unregister ();
189 HOTKEY_Unregister ();
190 IPADDRESS_Unregister ();
191 LISTVIEW_Unregister ();
192 MONTHCAL_Unregister ();
193 NATIVEFONT_Unregister ();
195 PROGRESS_Unregister ();
197 STATUS_Unregister ();
199 TOOLBAR_Unregister ();
200 TOOLTIPS_Unregister ();
201 TRACKBAR_Unregister ();
202 TREEVIEW_Unregister ();
203 UPDOWN_Unregister ();
205 /* delete local pattern brush */
206 DeleteObject (COMCTL32_hPattern55AABrush
);
207 COMCTL32_hPattern55AABrush
= (HANDLE
)NULL
;
208 DeleteObject (COMCTL32_hPattern55AABitmap
);
209 COMCTL32_hPattern55AABitmap
= (HANDLE
)NULL
;
211 /* delete global subclassing atom */
212 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass
));
213 TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass
);
214 COMCTL32_aSubclass
= (LPSTR
)NULL
;
216 /* destroy private heap */
217 HeapDestroy (COMCTL32_hHeap
);
218 TRACE("Heap destroyed: %p\n", COMCTL32_hHeap
);
219 COMCTL32_hHeap
= (HANDLE
)NULL
;
227 /***********************************************************************
228 * MenuHelp [COMCTL32.2]
231 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
232 * wParam [I] wParam of the message uMsg
233 * lParam [I] lParam of the message uMsg
234 * hMainMenu [I] handle to the application's main menu
235 * hInst [I] handle to the module that contains string resources
236 * hwndStatus [I] handle to the status bar window
237 * lpwIDs [I] pointer to an array of integers (see NOTES)
243 * The official documentation is incomplete!
244 * This is the correct documentation:
247 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
248 * WM_MENUSELECT messages.
251 * (will be written ...)
255 MenuHelp (UINT uMsg
, WPARAM wParam
, LPARAM lParam
, HMENU hMainMenu
,
256 HINSTANCE hInst
, HWND hwndStatus
, UINT
* lpwIDs
)
260 if (!IsWindow (hwndStatus
))
265 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
268 if ((HIWORD(wParam
) == 0xFFFF) && (lParam
== 0)) {
269 /* menu was closed */
270 TRACE("menu was closed!\n");
271 SendMessageA (hwndStatus
, SB_SIMPLE
, FALSE
, 0);
274 /* menu item was selected */
275 if (HIWORD(wParam
) & MF_POPUP
)
276 uMenuID
= (UINT
)*(lpwIDs
+1);
278 uMenuID
= (UINT
)LOWORD(wParam
);
279 TRACE("uMenuID = %u\n", uMenuID
);
284 if (!LoadStringA (hInst
, uMenuID
, szText
, 256))
287 SendMessageA (hwndStatus
, SB_SETTEXTA
,
288 255 | SBT_NOBORDERS
, (LPARAM
)szText
);
289 SendMessageA (hwndStatus
, SB_SIMPLE
, TRUE
, 0);
295 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
297 /* WM_COMMAND is not invalid since it is documented
298 * in the windows api reference. So don't output
299 * any FIXME for WM_COMMAND
301 WARN("We don't care about the WM_COMMAND\n");
305 FIXME("Invalid Message 0x%x!\n", uMsg
);
311 /***********************************************************************
312 * ShowHideMenuCtl [COMCTL32.3]
314 * Shows or hides controls and updates the corresponding menu item.
317 * hwnd [I] handle to the client window.
318 * uFlags [I] menu command id.
319 * lpInfo [I] pointer to an array of integers. (See NOTES.)
326 * The official documentation is incomplete!
327 * This is the correct documentation:
330 * Handle to the window that contains the menu and controls.
333 * Identifier of the menu item to receive or loose a check mark.
336 * The array of integers contains pairs of values. BOTH values of
337 * the first pair must be the handles to the application's main menu.
338 * Each subsequent pair consists of a menu id and control id.
342 ShowHideMenuCtl (HWND hwnd
, UINT uFlags
, LPINT lpInfo
)
346 TRACE("%p, %x, %p\n", hwnd
, uFlags
, lpInfo
);
351 if (!(lpInfo
[0]) || !(lpInfo
[1]))
354 /* search for control */
355 lpMenuId
= &lpInfo
[2];
356 while (*lpMenuId
!= uFlags
)
359 if (GetMenuState ((HMENU
)lpInfo
[1], uFlags
, MF_BYCOMMAND
) & MFS_CHECKED
) {
360 /* uncheck menu item */
361 CheckMenuItem ((HMENU
)lpInfo
[0], *lpMenuId
, MF_BYCOMMAND
| MF_UNCHECKED
);
365 SetWindowPos (GetDlgItem (hwnd
, *lpMenuId
), 0, 0, 0, 0, 0,
369 /* check menu item */
370 CheckMenuItem ((HMENU
)lpInfo
[0], *lpMenuId
, MF_BYCOMMAND
| MF_CHECKED
);
374 SetWindowPos (GetDlgItem (hwnd
, *lpMenuId
), 0, 0, 0, 0, 0,
382 /***********************************************************************
383 * GetEffectiveClientRect [COMCTL32.4]
386 * hwnd [I] handle to the client window.
387 * lpRect [O] pointer to the rectangle of the client window
388 * lpInfo [I] pointer to an array of integers (see NOTES)
394 * The official documentation is incomplete!
395 * This is the correct documentation:
398 * (will be written ...)
402 GetEffectiveClientRect (HWND hwnd
, LPRECT lpRect
, LPINT lpInfo
)
408 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
409 (DWORD
)hwnd
, (DWORD
)lpRect
, (DWORD
)lpInfo
);
411 GetClientRect (hwnd
, lpRect
);
419 hwndCtrl
= GetDlgItem (hwnd
, *lpRun
);
420 if (GetWindowLongA (hwndCtrl
, GWL_STYLE
) & WS_VISIBLE
) {
421 TRACE("control id 0x%x\n", *lpRun
);
422 GetWindowRect (hwndCtrl
, &rcCtrl
);
423 MapWindowPoints ((HWND
)0, hwnd
, (LPPOINT
)&rcCtrl
, 2);
424 SubtractRect (lpRect
, lpRect
, &rcCtrl
);
431 /***********************************************************************
432 * DrawStatusTextW [COMCTL32.@]
434 * Draws text with borders, like in a status bar.
437 * hdc [I] handle to the window's display context
438 * lprc [I] pointer to a rectangle
439 * text [I] pointer to the text
440 * style [I] drawing style
446 * The style variable can have one of the following values:
447 * (will be written ...)
450 void WINAPI
DrawStatusTextW (HDC hdc
, LPRECT lprc
, LPCWSTR text
, UINT style
)
453 UINT border
= BDR_SUNKENOUTER
;
455 if (style
& SBT_POPOUT
)
456 border
= BDR_RAISEDOUTER
;
457 else if (style
& SBT_NOBORDERS
)
460 DrawEdge (hdc
, &r
, border
, BF_RECT
|BF_ADJUST
);
464 int oldbkmode
= SetBkMode (hdc
, TRANSPARENT
);
465 UINT align
= DT_LEFT
;
466 if (*text
== L
'\t') {
469 if (*text
== L
'\t') {
475 if (style
& SBT_RTLREADING
)
476 FIXME("Unsupported RTL style!\n");
477 DrawTextW (hdc
, text
, -1, &r
, align
|DT_VCENTER
|DT_SINGLELINE
);
478 SetBkMode(hdc
, oldbkmode
);
483 /***********************************************************************
484 * DrawStatusText [COMCTL32.@]
485 * DrawStatusTextA [COMCTL32.5]
487 * Draws text with borders, like in a status bar.
490 * hdc [I] handle to the window's display context
491 * lprc [I] pointer to a rectangle
492 * text [I] pointer to the text
493 * style [I] drawing style
499 void WINAPI
DrawStatusTextA (HDC hdc
, LPRECT lprc
, LPCSTR text
, UINT style
)
505 if ( (len
= MultiByteToWideChar( CP_ACP
, 0, text
, -1, NULL
, 0 )) ) {
506 if ( (textW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )) )
507 MultiByteToWideChar( CP_ACP
, 0, text
, -1, textW
, len
);
510 DrawStatusTextW( hdc
, lprc
, textW
, style
);
511 HeapFree( GetProcessHeap(), 0, textW
);
515 /***********************************************************************
516 * CreateStatusWindow [COMCTL32.@]
517 * CreateStatusWindowA [COMCTL32.6]
519 * Creates a status bar
522 * style [I] window style
523 * text [I] pointer to the window text
524 * parent [I] handle to the parent window
525 * wid [I] control id of the status bar
528 * Success: handle to the status window
533 CreateStatusWindowA (INT style
, LPCSTR text
, HWND parent
, UINT wid
)
535 return CreateWindowA(STATUSCLASSNAMEA
, text
, style
,
536 CW_USEDEFAULT
, CW_USEDEFAULT
,
537 CW_USEDEFAULT
, CW_USEDEFAULT
,
538 parent
, (HMENU
)wid
, 0, 0);
542 /***********************************************************************
543 * CreateStatusWindowW [COMCTL32.@] Creates a status bar control
546 * style [I] window style
547 * text [I] pointer to the window text
548 * parent [I] handle to the parent window
549 * wid [I] control id of the status bar
552 * Success: handle to the status window
557 CreateStatusWindowW (INT style
, LPCWSTR text
, HWND parent
, UINT wid
)
559 return CreateWindowW(STATUSCLASSNAMEW
, text
, style
,
560 CW_USEDEFAULT
, CW_USEDEFAULT
,
561 CW_USEDEFAULT
, CW_USEDEFAULT
,
562 parent
, (HMENU
)wid
, 0, 0);
566 /***********************************************************************
567 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
570 * style [I] window styles
571 * x [I] horizontal position of the control
572 * y [I] vertical position of the control
573 * cx [I] with of the control
574 * cy [I] height of the control
575 * parent [I] handle to the parent window
576 * id [I] the control's identifier
577 * inst [I] handle to the application's module instance
578 * buddy [I] handle to the buddy window, can be NULL
579 * maxVal [I] upper limit of the control
580 * minVal [I] lower limit of the control
581 * curVal [I] current value of the control
584 * Success: handle to the updown control
589 CreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
590 HWND parent
, INT id
, HINSTANCE inst
,
591 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
594 CreateWindowA (UPDOWN_CLASSA
, 0, style
, x
, y
, cx
, cy
,
595 parent
, (HMENU
)id
, inst
, 0);
597 SendMessageA (hUD
, UDM_SETBUDDY
, (WPARAM
)buddy
, 0);
598 SendMessageA (hUD
, UDM_SETRANGE
, 0, MAKELONG(maxVal
, minVal
));
599 SendMessageA (hUD
, UDM_SETPOS
, 0, MAKELONG(curVal
, 0));
606 /***********************************************************************
607 * InitCommonControls [COMCTL32.17]
609 * Registers the common controls.
618 * This function is just a dummy.
619 * The Win95 controls are registered at the DLL's initialization.
620 * To register other controls InitCommonControlsEx() must be used.
624 InitCommonControls (void)
629 /***********************************************************************
630 * InitCommonControlsEx [COMCTL32.@]
632 * Registers the common controls.
635 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
642 * Only the additional common controls are registered by this function.
643 * The Win95 controls are registered at the DLL's initialization.
646 * implement the following control classes:
648 * ICC_STANDARD_CLASSES
652 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls
)
659 if (lpInitCtrls
->dwSize
!= sizeof(INITCOMMONCONTROLSEX
))
662 TRACE("(0x%08lx)\n", lpInitCtrls
->dwICC
);
664 for (cCount
= 0; cCount
< 32; cCount
++) {
665 dwMask
= 1 << cCount
;
666 if (!(lpInitCtrls
->dwICC
& dwMask
))
669 switch (lpInitCtrls
->dwICC
& dwMask
) {
670 /* dummy initialization */
671 case ICC_ANIMATE_CLASS
:
672 case ICC_BAR_CLASSES
:
673 case ICC_LISTVIEW_CLASSES
:
674 case ICC_TREEVIEW_CLASSES
:
675 case ICC_TAB_CLASSES
:
676 case ICC_UPDOWN_CLASS
:
677 case ICC_PROGRESS_CLASS
:
678 case ICC_HOTKEY_CLASS
:
681 /* advanced classes - not included in Win95 */
682 case ICC_DATE_CLASSES
:
683 MONTHCAL_Register ();
684 DATETIME_Register ();
687 case ICC_USEREX_CLASSES
:
691 case ICC_COOL_CLASSES
:
695 case ICC_INTERNET_CLASSES
:
696 IPADDRESS_Register ();
699 case ICC_PAGESCROLLER_CLASS
:
703 case ICC_NATIVEFNTCTL_CLASS
:
704 NATIVEFONT_Register ();
708 FIXME("Unknown class! dwICC=0x%lX\n", dwMask
);
717 /***********************************************************************
718 * CreateToolbarEx [COMCTL32.@] Creates a tool bar window
736 * Success: handle to the tool bar control
741 CreateToolbarEx (HWND hwnd
, DWORD style
, UINT wID
, INT nBitmaps
,
742 HINSTANCE hBMInst
, UINT wBMID
, LPCTBBUTTON lpButtons
,
743 INT iNumButtons
, INT dxButton
, INT dyButton
,
744 INT dxBitmap
, INT dyBitmap
, UINT uStructSize
)
748 /* If not position is specified then put it at the top */
749 if ((style
& CCS_BOTTOM
) == 0) {
754 CreateWindowExA (0, TOOLBARCLASSNAMEA
, "", style
|WS_CHILD
, 0, 0, 0, 0,
755 hwnd
, (HMENU
)wID
, 0, NULL
);
759 SendMessageA (hwndTB
, TB_BUTTONSTRUCTSIZE
,
760 (WPARAM
)uStructSize
, 0);
762 /* set bitmap and button size */
763 /*If CreateToolbarEx receives 0, windows sets default values*/
768 SendMessageA (hwndTB
, TB_SETBITMAPSIZE
, 0,
769 MAKELPARAM((WORD
)dxBitmap
, (WORD
)dyBitmap
));
775 SendMessageA (hwndTB
, TB_SETBUTTONSIZE
, 0,
776 MAKELPARAM((WORD
)dxButton
, (WORD
)dyButton
));
782 tbab
.hInst
= hBMInst
;
785 SendMessageA (hwndTB
, TB_ADDBITMAP
,
786 (WPARAM
)nBitmaps
, (LPARAM
)&tbab
);
790 SendMessageA (hwndTB
, TB_ADDBUTTONSA
,
791 (WPARAM
)iNumButtons
, (LPARAM
)lpButtons
);
798 /***********************************************************************
799 * CreateMappedBitmap [COMCTL32.8]
809 * Success: handle to the new bitmap
814 CreateMappedBitmap (HINSTANCE hInstance
, INT idBitmap
, UINT wFlags
,
815 LPCOLORMAP lpColorMap
, INT iNumMaps
)
819 LPBITMAPINFOHEADER lpBitmap
, lpBitmapInfo
;
820 UINT nSize
, nColorTableSize
;
821 RGBQUAD
*pColorTable
;
822 INT iColor
, i
, iMaps
, nWidth
, nHeight
;
825 LPCOLORMAP sysColorMap
;
827 COLORMAP internalColorMap
[4] =
828 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
830 /* initialize pointer to colortable and default color table */
833 sysColorMap
= lpColorMap
;
836 internalColorMap
[0].to
= GetSysColor (COLOR_BTNTEXT
);
837 internalColorMap
[1].to
= GetSysColor (COLOR_BTNSHADOW
);
838 internalColorMap
[2].to
= GetSysColor (COLOR_BTNFACE
);
839 internalColorMap
[3].to
= GetSysColor (COLOR_BTNHIGHLIGHT
);
841 sysColorMap
= (LPCOLORMAP
)internalColorMap
;
844 hRsrc
= FindResourceA (hInstance
, (LPSTR
)idBitmap
, RT_BITMAPA
);
847 hglb
= LoadResource (hInstance
, hRsrc
);
850 lpBitmap
= (LPBITMAPINFOHEADER
)LockResource (hglb
);
851 if (lpBitmap
== NULL
)
854 nColorTableSize
= (1 << lpBitmap
->biBitCount
);
855 nSize
= lpBitmap
->biSize
+ nColorTableSize
* sizeof(RGBQUAD
);
856 lpBitmapInfo
= (LPBITMAPINFOHEADER
)GlobalAlloc (GMEM_FIXED
, nSize
);
857 if (lpBitmapInfo
== NULL
)
859 RtlMoveMemory (lpBitmapInfo
, lpBitmap
, nSize
);
861 pColorTable
= (RGBQUAD
*)(((LPBYTE
)lpBitmapInfo
)+(UINT
)lpBitmapInfo
->biSize
);
863 for (iColor
= 0; iColor
< nColorTableSize
; iColor
++) {
864 for (i
= 0; i
< iMaps
; i
++) {
865 cRef
= RGB(pColorTable
[iColor
].rgbRed
,
866 pColorTable
[iColor
].rgbGreen
,
867 pColorTable
[iColor
].rgbBlue
);
868 if ( cRef
== sysColorMap
[i
].from
) {
870 if (wFlags
& CBS_MASKED
) {
871 if (sysColorMap
[i
].to
!= COLOR_BTNTEXT
)
872 pColorTable
[iColor
] = RGB(255, 255, 255);
876 pColorTable
[iColor
].rgbBlue
= GetBValue(sysColorMap
[i
].to
);
877 pColorTable
[iColor
].rgbGreen
= GetGValue(sysColorMap
[i
].to
);
878 pColorTable
[iColor
].rgbRed
= GetRValue(sysColorMap
[i
].to
);
883 nWidth
= (INT
)lpBitmapInfo
->biWidth
;
884 nHeight
= (INT
)lpBitmapInfo
->biHeight
;
885 hdcScreen
= GetDC ((HWND
)0);
886 hbm
= CreateCompatibleBitmap (hdcScreen
, nWidth
, nHeight
);
888 HDC hdcDst
= CreateCompatibleDC (hdcScreen
);
889 HBITMAP hbmOld
= SelectObject (hdcDst
, hbm
);
890 LPBYTE lpBits
= (LPBYTE
)(lpBitmap
+ 1);
891 lpBits
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
);
892 StretchDIBits (hdcDst
, 0, 0, nWidth
, nHeight
, 0, 0, nWidth
, nHeight
,
893 lpBits
, (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
,
895 SelectObject (hdcDst
, hbmOld
);
898 ReleaseDC ((HWND
)0, hdcScreen
);
899 GlobalFree ((HGLOBAL
)lpBitmapInfo
);
906 /***********************************************************************
907 * CreateToolbar [COMCTL32.7] Creates a tool bar control
920 * Success: handle to the tool bar control
924 * Do not use this functions anymore. Use CreateToolbarEx instead.
928 CreateToolbar (HWND hwnd
, DWORD style
, UINT wID
, INT nBitmaps
,
929 HINSTANCE hBMInst
, UINT wBMID
,
930 LPCOLDTBBUTTON lpButtons
,INT iNumButtons
)
932 return CreateToolbarEx (hwnd
, style
| CCS_NODIVIDER
, wID
, nBitmaps
,
933 hBMInst
, wBMID
, (LPCTBBUTTON
)lpButtons
,
934 iNumButtons
, 0, 0, 0, 0, sizeof (OLDTBBUTTON
));
938 /***********************************************************************
939 * DllGetVersion [COMCTL32.@]
941 * Retrieves version information of the 'COMCTL32.DLL'
944 * pdvi [O] pointer to version information structure.
948 * Failure: E_INVALIDARG
951 * Returns version of a comctl32.dll from IE4.01 SP1.
955 COMCTL32_DllGetVersion (DLLVERSIONINFO
*pdvi
)
957 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
)) {
958 WARN("wrong DLLVERSIONINFO size from app\n");
962 pdvi
->dwMajorVersion
= COMCTL32_VERSION
;
963 pdvi
->dwMinorVersion
= COMCTL32_VERSION_MINOR
;
964 pdvi
->dwBuildNumber
= 2919;
965 pdvi
->dwPlatformID
= 6304;
967 TRACE("%lu.%lu.%lu.%lu\n",
968 pdvi
->dwMajorVersion
, pdvi
->dwMinorVersion
,
969 pdvi
->dwBuildNumber
, pdvi
->dwPlatformID
);
974 /***********************************************************************
975 * DllInstall (COMCTL32.@)
977 HRESULT WINAPI
COMCTL32_DllInstall(BOOL bInstall
, LPCWSTR cmdline
)
979 FIXME("(%s, %s): stub\n", bInstall
?"TRUE":"FALSE",
980 debugstr_w(cmdline
));
985 /***********************************************************************
986 * _TrackMouseEvent [COMCTL32.@]
988 * Requests notification of mouse events
990 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
991 * to the hwnd specified in the ptme structure. After the event message
992 * is posted to the hwnd, the entry in the queue is removed.
994 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
995 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
996 * immediately and the TME_LEAVE flag being ignored.
999 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1005 * IMPLEMENTATION moved to USER32.TrackMouseEvent
1010 _TrackMouseEvent (TRACKMOUSEEVENT
*ptme
)
1012 return TrackMouseEvent (ptme
);
1015 /*************************************************************************
1016 * GetMUILanguage [COMCTL32.@]
1018 * FIXME: "Returns the language currently in use by the common controls
1019 * for a particular process." (MSDN)
1022 LANGID WINAPI
GetMUILanguage (VOID
)
1024 return COMCTL32_uiLang
;
1028 /*************************************************************************
1029 * InitMUILanguage [COMCTL32.@]
1031 * FIXME: "Enables an application to specify a language to be used with
1032 * the common controls that is different than the system language." (MSDN)
1036 VOID WINAPI
InitMUILanguage (LANGID uiLang
)
1038 COMCTL32_uiLang
= uiLang
;
1042 /***********************************************************************
1043 * SetWindowSubclass [COMCTL32.@]
1045 * Starts a window subclass
1048 * hWnd [in] handle to window subclass.
1049 * pfnSubclass [in] Pointer to new window procedure.
1050 * uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
1051 * dwRef [in] Reference data to pass to window procedure.
1058 * If an application manually subclasses a window after subclassing it with
1059 * this API and then with this API again, then none of the previous
1060 * subclasses get called or the origional window procedure.
1063 BOOL WINAPI
SetWindowSubclass (HWND hWnd
, SUBCLASSPROC pfnSubclass
,
1064 UINT_PTR uIDSubclass
, DWORD_PTR dwRef
)
1066 LPSUBCLASS_INFO stack
;
1069 TRACE ("(%p, %p, %x, %lx)\n", hWnd
, pfnSubclass
, uIDSubclass
, dwRef
);
1071 /* Since the window procedure that we set here has two additional arguments,
1072 * we can't simply set it as the new window procedure of the window. So we
1073 * set our own window procedure and then calculate the other two arguments
1076 /* See if we have been called for this window */
1077 stack
= (LPSUBCLASS_INFO
)GetPropA (hWnd
, COMCTL32_aSubclass
);
1079 /* allocate stack */
1080 stack
= (LPSUBCLASS_INFO
)HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY
,
1081 sizeof(SUBCLASS_INFO
));
1083 ERR ("Failed to allocate our Subclassing stack");
1086 SetPropA (hWnd
, COMCTL32_aSubclass
, (HANDLE
)stack
);
1088 /* set window procedure to our own and save the current one */
1089 if (IsWindowUnicode (hWnd
))
1090 stack
->origproc
= (WNDPROC
)SetWindowLongW (hWnd
, GWL_WNDPROC
,
1091 (LONG
)DefSubclassProc
);
1093 stack
->origproc
= (WNDPROC
)SetWindowLongA (hWnd
, GWL_WNDPROC
,
1094 (LONG
)DefSubclassProc
);
1097 if (IsWindowUnicode (hWnd
))
1098 current
= (WNDPROC
)GetWindowLongW (hWnd
, GWL_WNDPROC
);
1100 current
= (WNDPROC
)GetWindowLongA (hWnd
, GWL_WNDPROC
);
1102 if (current
!= DefSubclassProc
) {
1103 ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n");
1108 /* Check to see if we have called this function with the same uIDSubClass
1109 * and pfnSubclass */
1110 for (n
= 0; n
<= stack
->stacknum
+ stack
->stacknew
- 1; n
++)
1111 if ((stack
->SubclassProcs
[n
].id
== uIDSubclass
) &&
1112 (stack
->SubclassProcs
[n
].subproc
== pfnSubclass
)) {
1113 stack
->SubclassProcs
[n
].ref
= dwRef
;
1117 if ((stack
->stacknum
+ stack
->stacknew
) >= 32) {
1118 ERR ("We have a Subclass stack overflow, please increment size");
1122 /* we can't simply increment both stackpos and stacknum because there might
1123 * be a window procedure running lower in the stack, we can only get them
1124 * up to date once the last window procedure has run */
1125 if (stack
->stacknum
== stack
->stackpos
) {
1131 newnum
= stack
->stacknew
+ stack
->stacknum
- 1;
1133 stack
->SubclassProcs
[newnum
].subproc
= pfnSubclass
;
1134 stack
->SubclassProcs
[newnum
].ref
= dwRef
;
1135 stack
->SubclassProcs
[newnum
].id
= uIDSubclass
;
1141 /***********************************************************************
1142 * GetWindowSubclass [COMCTL32.@]
1144 * Gets the Reference data from a subclass.
1147 * hWnd [in] Handle to window which were subclassing
1148 * pfnSubclass [in] Pointer to the subclass procedure
1149 * iID [in] Unique indentifier of the subclassing procedure
1150 * pdwRef [out] Pointer to the reference data
1157 BOOL WINAPI
GetWindowSubclass (HWND hWnd
, SUBCLASSPROC pfnSubclass
,
1158 UINT_PTR uID
, DWORD_PTR
*pdwRef
)
1160 LPSUBCLASS_INFO stack
;
1163 TRACE ("(%p, %p, %x, %p)\n", hWnd
, pfnSubclass
, uID
, pdwRef
);
1165 /* See if we have been called for this window */
1166 stack
= (LPSUBCLASS_INFO
)GetPropA (hWnd
, COMCTL32_aSubclass
);
1170 for (n
= 0; n
<= stack
->stacknum
+ stack
->stacknew
- 1; n
++)
1171 if ((stack
->SubclassProcs
[n
].id
== uID
) &&
1172 (stack
->SubclassProcs
[n
].subproc
== pfnSubclass
)) {
1173 *pdwRef
= stack
->SubclassProcs
[n
].ref
;
1181 /***********************************************************************
1182 * RemoveWindowSubclass [COMCTL32.@]
1184 * Removes a window subclass.
1187 * hWnd [in] Handle to the window were subclassing
1188 * pfnSubclass [in] Pointer to the subclass procedure
1189 * uID [in] Unique identifier of this subclass
1196 BOOL WINAPI
RemoveWindowSubclass(HWND hWnd
, SUBCLASSPROC pfnSubclass
, UINT_PTR uID
)
1198 LPSUBCLASS_INFO stack
;
1201 TRACE ("(%p, %p, %x)\n", hWnd
, pfnSubclass
, uID
);
1203 /* Find the Subclass to remove */
1204 stack
= (LPSUBCLASS_INFO
)GetPropA (hWnd
, COMCTL32_aSubclass
);
1208 if ((stack
->stacknum
== stack
->stackpos
== 1) && !stack
->stacknew
) {
1209 TRACE("Last Subclass removed, cleaning up\n");
1210 /* clean up our heap and reset the origional window procedure */
1211 if (IsWindowUnicode (hWnd
))
1212 SetWindowLongW (hWnd
, GWL_WNDPROC
, (LONG
)stack
->origproc
);
1214 SetWindowLongA (hWnd
, GWL_WNDPROC
, (LONG
)stack
->origproc
);
1215 HeapFree (GetProcessHeap (), 0, stack
);
1216 RemovePropA( hWnd
, COMCTL32_aSubclass
);
1220 for (n
= stack
->stacknum
+ stack
->stacknew
- 1; n
>= 0; n
--)
1221 if ((stack
->SubclassProcs
[n
].id
== uID
) &&
1222 (stack
->SubclassProcs
[n
].subproc
== pfnSubclass
)) {
1223 if (n
!= (stack
->stacknum
+ stack
->stacknew
))
1224 /* Fill the hole in the stack */
1225 memmove (&stack
->SubclassProcs
[n
], &stack
->SubclassProcs
[n
+ 1],
1226 sizeof(stack
->SubclassProcs
[0]) * (stack
->stacknew
+ stack
->stacknum
- n
));
1227 stack
->SubclassProcs
[n
].subproc
= NULL
;
1228 stack
->SubclassProcs
[n
].ref
= 0;
1229 stack
->SubclassProcs
[n
].id
= 0;
1231 /* If we are currently running a window procedure we have to manipulate
1232 * the stack position pointers so that we don't corrupt the stack */
1233 if ((n
< stack
->stackpos
) || (stack
->stackpos
== stack
->stacknum
)) {
1236 } else if (n
>= stack
->stackpos
)
1245 /***********************************************************************
1246 * DefSubclassProc [COMCTL32.@]
1248 * Calls the next window procedure (ie. the one before this subclass)
1251 * hWnd [in] The window that we're subclassing
1253 * wParam [in] WPARAM
1254 * lParam [in] LPARAM
1261 LRESULT WINAPI
DefSubclassProc (HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1263 LPSUBCLASS_INFO stack
;
1267 /* retrieve our little stack from the Properties */
1268 stack
= (LPSUBCLASS_INFO
)GetPropA (hWnd
, COMCTL32_aSubclass
);
1270 ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd
);
1274 /* If we are at pos 0 then we have to call the origional window procedure */
1275 if (stack
->stackpos
== 0) {
1276 if (IsWindowUnicode (hWnd
))
1277 return CallWindowProcW (stack
->origproc
, hWnd
, uMsg
, wParam
, lParam
);
1279 return CallWindowProcA (stack
->origproc
, hWnd
, uMsg
, wParam
, lParam
);
1282 stackpos
= --stack
->stackpos
;
1283 /* call the Subclass procedure from the stack */
1284 ret
= stack
->SubclassProcs
[stackpos
].subproc (hWnd
, uMsg
, wParam
, lParam
,
1285 stack
->SubclassProcs
[stackpos
].id
, stack
->SubclassProcs
[stackpos
].ref
);
1288 if ((stack
->stackpos
== stack
->stacknum
) && stack
->stacknew
) {
1289 stack
->stacknum
+= stack
->stacknew
;
1290 stack
->stackpos
+= stack
->stacknew
;
1291 stack
->stacknew
= 0;
1294 /* If we removed the last entry in our stack while a window procedure was
1295 * running then we have to clean up */
1296 if (stack
->stackpos
== stack
->stacknum
== 0) {
1297 TRACE("Last Subclass removed, cleaning up\n");
1298 /* clean up our heap and reset the origional window procedure */
1299 if (IsWindowUnicode (hWnd
))
1300 SetWindowLongW (hWnd
, GWL_WNDPROC
, (LONG
)stack
->origproc
);
1302 SetWindowLongA (hWnd
, GWL_WNDPROC
, (LONG
)stack
->origproc
);
1303 HeapFree (GetProcessHeap (), 0, stack
);
1304 RemovePropA( hWnd
, COMCTL32_aSubclass
);
1312 /***********************************************************************
1313 * COMCTL32_CreateToolTip [NOT AN API]
1315 * Creates a tooltip for the control specified in hwnd and does all
1316 * necessary setup and notifications.
1319 * hwndOwner [I] Handle to the window that will own the tool tip.
1322 * Success: Handle of tool tip window.
1327 COMCTL32_CreateToolTip(HWND hwndOwner
)
1331 hwndToolTip
= CreateWindowExA(0, TOOLTIPS_CLASSA
, NULL
, 0,
1332 CW_USEDEFAULT
, CW_USEDEFAULT
,
1333 CW_USEDEFAULT
, CW_USEDEFAULT
, hwndOwner
,
1336 /* Send NM_TOOLTIPSCREATED notification */
1339 NMTOOLTIPSCREATED nmttc
;
1340 /* true owner can be different if hwndOwner is a child window */
1341 HWND hwndTrueOwner
= GetWindow(hwndToolTip
, GW_OWNER
);
1342 nmttc
.hdr
.hwndFrom
= hwndTrueOwner
;
1343 nmttc
.hdr
.idFrom
= GetWindowLongA(hwndTrueOwner
, GWL_ID
);
1344 nmttc
.hdr
.code
= NM_TOOLTIPSCREATED
;
1345 nmttc
.hwndToolTips
= hwndToolTip
;
1347 SendMessageA(GetParent(hwndTrueOwner
), WM_NOTIFY
,
1348 (WPARAM
)GetWindowLongA(hwndTrueOwner
, GWL_ID
),
1356 /***********************************************************************
1357 * COMCTL32_RefreshSysColors [NOT AN API]
1359 * Invoked on any control recognizing a WM_SYSCOLORCHANGE message to
1360 * refresh the color values in the color structure
1370 COMCTL32_RefreshSysColors(void)
1372 comctl32_color
.clrBtnHighlight
= GetSysColor (COLOR_BTNHIGHLIGHT
);
1373 comctl32_color
.clrBtnShadow
= GetSysColor (COLOR_BTNSHADOW
);
1374 comctl32_color
.clrBtnText
= GetSysColor (COLOR_BTNTEXT
);
1375 comctl32_color
.clrBtnFace
= GetSysColor (COLOR_BTNFACE
);
1376 comctl32_color
.clrHighlight
= GetSysColor (COLOR_HIGHLIGHT
);
1377 comctl32_color
.clrHighlightText
= GetSysColor (COLOR_HIGHLIGHTTEXT
);
1378 comctl32_color
.clr3dHilight
= GetSysColor (COLOR_3DHILIGHT
);
1379 comctl32_color
.clr3dShadow
= GetSysColor (COLOR_3DSHADOW
);
1380 comctl32_color
.clr3dDkShadow
= GetSysColor (COLOR_3DDKSHADOW
);
1381 comctl32_color
.clr3dFace
= GetSysColor (COLOR_3DFACE
);
1382 comctl32_color
.clrWindow
= GetSysColor (COLOR_WINDOW
);
1383 comctl32_color
.clrWindowText
= GetSysColor (COLOR_WINDOWTEXT
);
1384 comctl32_color
.clrGrayText
= GetSysColor (COLOR_GRAYTEXT
);
1385 comctl32_color
.clrActiveCaption
= GetSysColor (COLOR_ACTIVECAPTION
);
1386 comctl32_color
.clrInfoBk
= GetSysColor (COLOR_INFOBK
);
1387 comctl32_color
.clrInfoText
= GetSysColor (COLOR_INFOTEXT
);