2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998 Eric Kohl
18 #include "ipaddress.h"
21 #include "nativefont.h"
24 #include "propsheet.h"
33 #include "winversion.h"
38 HANDLE32 COMCTL32_hHeap
= (HANDLE32
)NULL
;
39 DWORD COMCTL32_dwProcessesAttached
= 0;
40 LPSTR COMCTL32_aSubclass
= (LPSTR
)NULL
;
43 /***********************************************************************
44 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
47 * hinstDLL [I] handle to the 'dlls' instance
49 * lpvReserved [I] reserverd, must be NULL
57 COMCTL32_LibMain (HINSTANCE32 hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
59 TRACE (commctrl
, "%x,%lx,%p\n", hinstDLL
, fdwReason
, lpvReserved
);
62 case DLL_PROCESS_ATTACH
:
63 if (COMCTL32_dwProcessesAttached
== 0) {
64 /* create private heap */
65 COMCTL32_hHeap
= HeapCreate (0, 0x10000, 0);
66 TRACE (commctrl
, "Heap created: 0x%x\n", COMCTL32_hHeap
);
68 /* add global subclassing atom (used by 'tooltip' and 'updown') */
69 COMCTL32_aSubclass
= (LPSTR
)(DWORD
)GlobalAddAtom32A ("CC32SubclassInfo");
70 TRACE (commctrl
, "Subclassing atom added: %p\n",
73 /* register all Win95 common control classes */
79 PROPSHEET_Register ();
89 COMCTL32_dwProcessesAttached
++;
92 case DLL_PROCESS_DETACH
:
93 COMCTL32_dwProcessesAttached
--;
94 if (COMCTL32_dwProcessesAttached
== 0) {
95 /* unregister all common control classes */
96 ANIMATE_Unregister ();
97 COMBOEX_Unregister ();
98 DATETIME_Unregister ();
100 HEADER_Unregister ();
101 HOTKEY_Unregister ();
102 IPADDRESS_Unregister ();
103 LISTVIEW_Unregister ();
104 MONTHCAL_Unregister ();
105 NATIVEFONT_Unregister ();
107 PROPSHEET_UnRegister ();
108 PROGRESS_Unregister ();
110 STATUS_Unregister ();
112 TOOLBAR_Unregister ();
113 TOOLTIPS_Unregister ();
114 TRACKBAR_Unregister ();
115 TREEVIEW_Unregister ();
116 UPDOWN_Unregister ();
118 /* delete global subclassing atom */
119 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass
));
120 TRACE (commctrl
, "Subclassing atom deleted: %p\n",
122 COMCTL32_aSubclass
= (LPSTR
)NULL
;
124 /* destroy private heap */
125 HeapDestroy (COMCTL32_hHeap
);
126 TRACE (commctrl
, "Heap destroyed: 0x%x\n", COMCTL32_hHeap
);
127 COMCTL32_hHeap
= (HANDLE32
)NULL
;
136 /***********************************************************************
137 * MenuHelp [COMCTL32.2]
143 * hMainMenu [I] handle to the applications main menu
145 * hwndStatus [I] handle to the status bar window
146 * lpwIDs [I] pointer to an array of intergers (see NOTES)
152 * The official documentation is incomplete!
156 MenuHelp (UINT32 uMsg
, WPARAM32 wParam
, LPARAM lParam
, HMENU32 hMainMenu
,
157 HINSTANCE32 hInst
, HWND32 hwndStatus
, LPUINT32 lpwIDs
)
161 if (!IsWindow32 (hwndStatus
))
166 TRACE (commctrl
, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
169 if ((HIWORD(wParam
) == 0xFFFF) && (lParam
== 0)) {
170 /* menu was closed */
171 TRACE (commctrl
, "menu was closed!\n");
172 SendMessage32A (hwndStatus
, SB_SIMPLE
, FALSE
, 0);
175 /* menu item was selected */
176 if (HIWORD(wParam
) & MF_POPUP
)
177 uMenuID
= (UINT32
)*(lpwIDs
+1);
179 uMenuID
= (UINT32
)LOWORD(wParam
);
180 TRACE (commctrl
, "uMenuID = %u\n", uMenuID
);
185 if (!LoadString32A (hInst
, uMenuID
, szText
, 256))
188 SendMessage32A (hwndStatus
, SB_SETTEXT32A
,
189 255 | SBT_NOBORDERS
, (LPARAM
)szText
);
190 SendMessage32A (hwndStatus
, SB_SIMPLE
, TRUE
, 0);
196 FIXME (commctrl
, "Invalid Message 0x%x!\n", uMsg
);
202 /***********************************************************************
203 * ShowHideMenuCtl [COMCTL32.3]
205 * Shows or hides controls and updates the corresponding menu item.
208 * hwnd [I] handle to the client window.
209 * uFlags [I] menu command id.
210 * lpInfo [I] pointer to an array of integers. (See NOTES.)
217 * The official documentation is incomplete! This has been fixed.
220 * The array of integers contains pairs of values. BOTH values of
221 * the first pair must be the handles to application's main menu.
222 * Each subsequent pair consists of a menu id and control id.
226 ShowHideMenuCtl (HWND32 hwnd
, UINT32 uFlags
, LPINT32 lpInfo
)
230 TRACE (commctrl
, "%x, %x, %p\n", hwnd
, uFlags
, lpInfo
);
235 if (!(lpInfo
[0]) || !(lpInfo
[1]))
238 /* search for control */
239 lpMenuId
= &lpInfo
[2];
240 while (*lpMenuId
!= uFlags
)
243 if (GetMenuState32 (lpInfo
[1], uFlags
, MF_BYCOMMAND
) & MFS_CHECKED
) {
244 /* uncheck menu item */
245 CheckMenuItem32 (lpInfo
[0], *lpMenuId
, MF_BYCOMMAND
| MF_UNCHECKED
);
249 SetWindowPos32 (GetDlgItem32 (hwnd
, *lpMenuId
), 0, 0, 0, 0, 0,
253 /* check menu item */
254 CheckMenuItem32 (lpInfo
[0], *lpMenuId
, MF_BYCOMMAND
| MF_CHECKED
);
258 SetWindowPos32 (GetDlgItem32 (hwnd
, *lpMenuId
), 0, 0, 0, 0, 0,
266 /***********************************************************************
267 * GetEffectiveClientRect [COMCTL32.4]
270 * hwnd [I] handle to the client window.
271 * lpRect [O] pointer to the rectangle of the client window
272 * lpInfo [I] pointer to an array of integers
278 * The official documentation is incomplete!
282 GetEffectiveClientRect (HWND32 hwnd
, LPRECT32 lpRect
, LPINT32 lpInfo
)
288 TRACE (commctrl
, "(0x%08lx 0x%08lx 0x%08lx)\n",
289 (DWORD
)hwnd
, (DWORD
)lpRect
, (DWORD
)lpInfo
);
291 GetClientRect32 (hwnd
, lpRect
);
299 hwndCtrl
= GetDlgItem32 (hwnd
, *lpRun
);
300 if (GetWindowLong32A (hwndCtrl
, GWL_STYLE
) & WS_VISIBLE
) {
301 TRACE (commctrl
, "control id 0x%x\n", *lpRun
);
302 GetWindowRect32 (hwndCtrl
, &rcCtrl
);
303 MapWindowPoints32 ((HWND32
)0, hwnd
, (LPPOINT32
)&rcCtrl
, 2);
304 SubtractRect32 (lpRect
, lpRect
, &rcCtrl
);
311 /***********************************************************************
312 * DrawStatusText32A [COMCTL32.5]
314 * Draws text with borders, like in a status bar.
317 * hdc [I] handle to the window's display context
318 * lprc [I] pointer to a rectangle
319 * text [I] pointer to the text
327 DrawStatusText32A (HDC32 hdc
, LPRECT32 lprc
, LPCSTR text
, UINT32 style
)
330 UINT32 border
= BDR_SUNKENOUTER
;
332 if (style
== SBT_POPOUT
)
333 border
= BDR_RAISEDOUTER
;
334 else if (style
== SBT_NOBORDERS
)
337 DrawEdge32 (hdc
, &r
, border
, BF_RECT
|BF_ADJUST
|BF_MIDDLE
);
341 int oldbkmode
= SetBkMode32 (hdc
, TRANSPARENT
);
343 DrawText32A (hdc
, text
, lstrlen32A(text
),
344 &r
, DT_LEFT
|DT_VCENTER
|DT_SINGLELINE
);
345 if (oldbkmode
!= TRANSPARENT
)
346 SetBkMode32(hdc
, oldbkmode
);
351 /***********************************************************************
352 * DrawStatusText32W [COMCTL32.28]
354 * Draws text with borders, like in a status bar.
357 * hdc [I] handle to the window's display context
358 * lprc [I] pointer to a rectangle
359 * text [I] pointer to the text
367 DrawStatusText32W (HDC32 hdc
, LPRECT32 lprc
, LPCWSTR text
, UINT32 style
)
369 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, text
);
370 DrawStatusText32A (hdc
, lprc
, p
, style
);
371 HeapFree (GetProcessHeap (), 0, p
);
375 /***********************************************************************
376 * DrawStatusText32AW [COMCTL32.27]
378 * Draws text with borders, like in a status bar.
381 * hdc [I] handle to the window's display context
382 * lprc [I] pointer to a rectangle
383 * text [I] pointer to the text
390 * Calls DrawStatusText32A() or DrawStatusText32W().
394 DrawStatusText32AW (HDC32 hdc
, LPRECT32 lprc
, LPVOID text
, UINT32 style
)
396 if (VERSION_OsIsUnicode())
397 DrawStatusText32W (hdc
, lprc
, (LPCWSTR
)text
, style
);
398 DrawStatusText32A (hdc
, lprc
, (LPCSTR
)text
, style
);
402 /***********************************************************************
403 * CreateStatusWindow32A [COMCTL32.6]
405 * Creates a status bar
410 * parent [I] handle to the parent window
411 * wid [I] control id of the status bar
414 * Success: handle to the control
419 CreateStatusWindow32A (INT32 style
, LPCSTR text
, HWND32 parent
, UINT32 wid
)
421 return CreateWindow32A(STATUSCLASSNAME32A
, text
, style
,
422 CW_USEDEFAULT32
, CW_USEDEFAULT32
,
423 CW_USEDEFAULT32
, CW_USEDEFAULT32
,
428 /***********************************************************************
429 * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
434 * parent [I] handle to the parent window
435 * wid [I] control id of the status bar
438 * Success: handle to the control
443 CreateStatusWindow32W (INT32 style
, LPCWSTR text
, HWND32 parent
, UINT32 wid
)
445 return CreateWindow32W(STATUSCLASSNAME32W
, text
, style
,
446 CW_USEDEFAULT32
, CW_USEDEFAULT32
,
447 CW_USEDEFAULT32
, CW_USEDEFAULT32
,
452 /***********************************************************************
453 * CreateStatusWindow32AW [COMCTL32.21] Creates a status bar control
458 * parent [I] handle to the parent window
459 * wid [I] control id of the status bar
462 * Success: handle to the control
467 CreateStatusWindow32AW (INT32 style
, LPVOID text
, HWND32 parent
, UINT32 wid
)
469 if (VERSION_OsIsUnicode())
470 return CreateStatusWindow32W (style
, (LPCWSTR
)text
, parent
, wid
);
471 return CreateStatusWindow32A (style
, (LPCSTR
)text
, parent
, wid
);
475 /***********************************************************************
476 * CreateUpDownControl [COMCTL32.16] Creates an Up-Down control
493 * Success: handle to the control
498 CreateUpDownControl (DWORD style
, INT32 x
, INT32 y
, INT32 cx
, INT32 cy
,
499 HWND32 parent
, INT32 id
, HINSTANCE32 inst
,
500 HWND32 buddy
, INT32 maxVal
, INT32 minVal
, INT32 curVal
)
503 CreateWindow32A (UPDOWN_CLASS32A
, 0, style
, x
, y
, cx
, cy
,
504 parent
, id
, inst
, 0);
506 SendMessage32A (hUD
, UDM_SETBUDDY
, buddy
, 0);
507 SendMessage32A (hUD
, UDM_SETRANGE
, 0, MAKELONG(maxVal
, minVal
));
508 SendMessage32A (hUD
, UDM_SETPOS
, 0, MAKELONG(curVal
, 0));
515 /***********************************************************************
516 * InitCommonControls [COMCTL32.17]
518 * Registers the common controls.
527 * This function is just a dummy.
528 * The Win95 controls are registered at the DLL's initialization.
529 * To register other controls InitCommonControlsEx must be used.
533 InitCommonControls (VOID
)
538 /***********************************************************************
539 * InitCommonControlsEx [COMCTL32.81]
541 * Registers the common controls.
544 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
551 * Only the additinal common controls are registered by this function.
552 * The Win95 controls are registered at the DLL's initialization.
556 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls
)
563 if (lpInitCtrls
->dwSize
!= sizeof(INITCOMMONCONTROLSEX
))
566 TRACE(commctrl
,"(0x%08lx)\n", lpInitCtrls
->dwICC
);
568 for (cCount
= 0; cCount
< 32; cCount
++) {
569 dwMask
= 1 << cCount
;
570 if (!(lpInitCtrls
->dwICC
& dwMask
))
573 switch (lpInitCtrls
->dwICC
& dwMask
) {
574 /* dummy initialization */
575 case ICC_ANIMATE_CLASS
:
576 case ICC_BAR_CLASSES
:
577 case ICC_LISTVIEW_CLASSES
:
578 case ICC_TREEVIEW_CLASSES
:
579 case ICC_TAB_CLASSES
:
580 case ICC_UPDOWN_CLASS
:
581 case ICC_PROGRESS_CLASS
:
582 case ICC_HOTKEY_CLASS
:
585 /* advanced classes - not included in Win95 */
586 case ICC_DATE_CLASSES
:
587 MONTHCAL_Register ();
588 DATETIME_Register ();
591 case ICC_USEREX_CLASSES
:
595 case ICC_COOL_CLASSES
:
599 case ICC_INTERNET_CLASSES
:
600 IPADDRESS_Register ();
603 case ICC_PAGESCROLLER_CLASS
:
607 case ICC_NATIVEFNTCTL_CLASS
:
608 NATIVEFONT_Register ();
612 FIXME (commctrl
, "Unknown class! dwICC=0x%lX\n", dwMask
);
621 /***********************************************************************
622 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
640 * Success: handle to the tool bar control
645 CreateToolbarEx (HWND32 hwnd
, DWORD style
, UINT32 wID
, INT32 nBitmaps
,
646 HINSTANCE32 hBMInst
, UINT32 wBMID
, LPCTBBUTTON lpButtons
,
647 INT32 iNumButtons
, INT32 dxButton
, INT32 dyButton
,
648 INT32 dxBitmap
, INT32 dyBitmap
, UINT32 uStructSize
)
651 CreateWindowEx32A (0, TOOLBARCLASSNAME32A
, "", style
, 0, 0, 0, 0,
652 hwnd
, (HMENU32
)wID
, 0, NULL
);
656 SendMessage32A (hwndTB
, TB_BUTTONSTRUCTSIZE
,
657 (WPARAM32
)uStructSize
, 0);
659 /* set bitmap and button size */
660 if (hBMInst
== HINST_COMMCTRL
) {
662 SendMessage32A (hwndTB
, TB_SETBITMAPSIZE
, 0,
664 SendMessage32A (hwndTB
, TB_SETBUTTONSIZE
, 0,
668 SendMessage32A (hwndTB
, TB_SETBITMAPSIZE
, 0,
670 SendMessage32A (hwndTB
, TB_SETBUTTONSIZE
, 0,
675 SendMessage32A (hwndTB
, TB_SETBITMAPSIZE
, 0,
676 MAKELPARAM((WORD
)dyBitmap
, (WORD
)dxBitmap
));
677 SendMessage32A (hwndTB
, TB_SETBUTTONSIZE
, 0,
678 MAKELPARAM((WORD
)dyButton
, (WORD
)dxButton
));
682 tbab
.hInst
= hBMInst
;
684 SendMessage32A (hwndTB
, TB_ADDBITMAP
,
685 (WPARAM32
)nBitmaps
, (LPARAM
)&tbab
);
688 SendMessage32A (hwndTB
, TB_ADDBUTTONS32A
,
689 (WPARAM32
)iNumButtons
, (LPARAM
)lpButtons
);
696 /***********************************************************************
697 * CreateMappedBitmap [COMCTL32.8]
707 * Success: bitmap handle
712 CreateMappedBitmap (HINSTANCE32 hInstance
, INT32 idBitmap
, UINT32 wFlags
,
713 LPCOLORMAP lpColorMap
, INT32 iNumMaps
)
717 LPBITMAPINFOHEADER lpBitmap
, lpBitmapInfo
;
718 UINT32 nSize
, nColorTableSize
;
720 INT32 iColor
, i
, iMaps
, nWidth
, nHeight
;
723 LPCOLORMAP sysColorMap
;
724 COLORMAP internalColorMap
[4] =
725 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
727 /* initialize pointer to colortable and default color table */
730 sysColorMap
= lpColorMap
;
733 internalColorMap
[0].to
= GetSysColor32 (COLOR_BTNTEXT
);
734 internalColorMap
[1].to
= GetSysColor32 (COLOR_BTNSHADOW
);
735 internalColorMap
[2].to
= GetSysColor32 (COLOR_BTNFACE
);
736 internalColorMap
[3].to
= GetSysColor32 (COLOR_BTNHIGHLIGHT
);
738 sysColorMap
= (LPCOLORMAP
)internalColorMap
;
741 hRsrc
= FindResource32A (hInstance
, (LPSTR
)idBitmap
, RT_BITMAP32A
);
744 hglb
= LoadResource32 (hInstance
, hRsrc
);
747 lpBitmap
= (LPBITMAPINFOHEADER
)LockResource32 (hglb
);
748 if (lpBitmap
== NULL
)
751 nColorTableSize
= (1 << lpBitmap
->biBitCount
);
752 nSize
= lpBitmap
->biSize
+ nColorTableSize
* sizeof(RGBQUAD
);
753 lpBitmapInfo
= (LPBITMAPINFOHEADER
)GlobalAlloc32 (GMEM_FIXED
, nSize
);
754 if (lpBitmapInfo
== NULL
)
756 RtlMoveMemory (lpBitmapInfo
, lpBitmap
, nSize
);
758 pColorTable
= (DWORD
*)(((LPBYTE
)lpBitmapInfo
)+(UINT32
)lpBitmapInfo
->biSize
);
760 for (iColor
= 0; iColor
< nColorTableSize
; iColor
++) {
761 for (i
= 0; i
< iMaps
; i
++) {
762 if (pColorTable
[iColor
] == sysColorMap
[i
].from
) {
764 if (wFlags
& CBS_MASKED
) {
765 if (sysColorMap
[i
].to
!= COLOR_BTNTEXT
)
766 pColorTable
[iColor
] = RGB(255, 255, 255);
770 pColorTable
[iColor
] = sysColorMap
[i
].to
;
776 nWidth
= (INT32
)lpBitmapInfo
->biWidth
;
777 nHeight
= (INT32
)lpBitmapInfo
->biHeight
;
778 hdcScreen
= GetDC32 ((HWND32
)0);
779 hbm
= CreateCompatibleBitmap32 (hdcScreen
, nWidth
, nHeight
);
781 HDC32 hdcDst
= CreateCompatibleDC32 (hdcScreen
);
782 HBITMAP32 hbmOld
= SelectObject32 (hdcDst
, hbm
);
783 LPBYTE lpBits
= (LPBYTE
)(lpBitmap
+ 1);
784 lpBits
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
);
785 StretchDIBits32 (hdcDst
, 0, 0, nWidth
, nHeight
, 0, 0, nWidth
, nHeight
,
786 lpBits
, (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
,
788 SelectObject32 (hdcDst
, hbmOld
);
791 ReleaseDC32 ((HWND32
)0, hdcScreen
);
792 GlobalFree32 ((HGLOBAL32
)lpBitmapInfo
);
793 FreeResource32 (hglb
);
799 /***********************************************************************
800 * CreateToolbar [COMCTL32.7] Creates a tool bar control
813 * Success: handle to the tool bar control
817 * Do not use this functions anymore. Use CreateToolbarEx instead.
821 CreateToolbar (HWND32 hwnd
, DWORD style
, UINT32 wID
, INT32 nBitmaps
,
822 HINSTANCE32 hBMInst
, UINT32 wBMID
,
823 LPCOLDTBBUTTON lpButtons
,INT32 iNumButtons
)
825 return CreateToolbarEx (hwnd
, style
| CCS_NODIVIDER
, wID
, nBitmaps
,
826 hBMInst
, wBMID
, (LPCTBBUTTON
)lpButtons
,
827 iNumButtons
, 0, 0, 0, 0, sizeof (OLDTBBUTTON
));
831 /***********************************************************************
832 * DllGetVersion [COMCTL32.25]
834 * Retrieves version information of the 'COMCTL32.DLL'
837 * pdvi [O] pointer to version information structure.
841 * Failure: E_INVALIDARG
844 * Returns version of a comctl32.dll from IE4.01 SP1.
848 COMCTL32_DllGetVersion (DLLVERSIONINFO
*pdvi
)
850 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
)) {
851 WARN (commctrl
, "wrong DLLVERSIONINFO size from app");
855 pdvi
->dwMajorVersion
= 4;
856 pdvi
->dwMinorVersion
= 72;
857 pdvi
->dwBuildNumber
= 3110;
858 pdvi
->dwPlatformID
= 1;
860 TRACE (commctrl
, "%lu.%lu.%lu.%lu\n",
861 pdvi
->dwMajorVersion
, pdvi
->dwMinorVersion
,
862 pdvi
->dwBuildNumber
, pdvi
->dwPlatformID
);