2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998 Eric Kohl
18 #include "ipaddress.h"
21 #include "nativefont.h"
35 DEFAULT_DEBUG_CHANNEL(commctrl
)
38 HANDLE COMCTL32_hHeap
= (HANDLE
)NULL
;
39 DWORD COMCTL32_dwProcessesAttached
= 0;
40 LPSTR COMCTL32_aSubclass
= (LPSTR
)NULL
;
41 HMODULE COMCTL32_hModule
= 0;
44 /***********************************************************************
45 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
48 * hinstDLL [I] handle to the 'dlls' instance
50 * lpvReserved [I] reserverd, must be NULL
58 COMCTL32_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
60 TRACE (commctrl
, "%x,%lx,%p\n", hinstDLL
, fdwReason
, lpvReserved
);
63 case DLL_PROCESS_ATTACH
:
64 if (COMCTL32_dwProcessesAttached
== 0) {
66 /* This will be wrong for any other process attching in this address-space! */
67 COMCTL32_hModule
= (HMODULE
)hinstDLL
;
69 /* create private heap */
70 COMCTL32_hHeap
= HeapCreate (0, 0x10000, 0);
71 TRACE (commctrl
, "Heap created: 0x%x\n", COMCTL32_hHeap
);
73 /* add global subclassing atom (used by 'tooltip' and 'updown') */
74 COMCTL32_aSubclass
= (LPSTR
)(DWORD
)GlobalAddAtomA ("CC32SubclassInfo");
75 TRACE (commctrl
, "Subclassing atom added: %p\n",
78 /* register all Win95 common control classes */
93 COMCTL32_dwProcessesAttached
++;
96 case DLL_PROCESS_DETACH
:
97 COMCTL32_dwProcessesAttached
--;
98 if (COMCTL32_dwProcessesAttached
== 0) {
99 /* unregister all common control classes */
100 ANIMATE_Unregister ();
101 COMBOEX_Unregister ();
102 DATETIME_Unregister ();
103 FLATSB_Unregister ();
104 HEADER_Unregister ();
105 HOTKEY_Unregister ();
106 IPADDRESS_Unregister ();
107 LISTVIEW_Unregister ();
108 MONTHCAL_Unregister ();
109 NATIVEFONT_Unregister ();
111 PROGRESS_Unregister ();
113 STATUS_Unregister ();
115 TOOLBAR_Unregister ();
116 TOOLTIPS_Unregister ();
117 TRACKBAR_Unregister ();
118 TREEVIEW_Unregister ();
119 UPDOWN_Unregister ();
121 /* delete global subclassing atom */
122 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass
));
123 TRACE (commctrl
, "Subclassing atom deleted: %p\n",
125 COMCTL32_aSubclass
= (LPSTR
)NULL
;
127 /* destroy private heap */
128 HeapDestroy (COMCTL32_hHeap
);
129 TRACE (commctrl
, "Heap destroyed: 0x%x\n", COMCTL32_hHeap
);
130 COMCTL32_hHeap
= (HANDLE
)NULL
;
139 /***********************************************************************
140 * MenuHelp [COMCTL32.2]
143 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
144 * wParam [I] wParam of the message uMsg
145 * lParam [I] lParam of the message uMsg
146 * hMainMenu [I] handle to the application's main menu
147 * hInst [I] handle to the module that contains string resources
148 * hwndStatus [I] handle to the status bar window
149 * lpwIDs [I] pointer to an array of intergers (see NOTES)
155 * The official documentation is incomplete!
156 * This is the correct documentation:
159 * MenuHelp() does NOT handle WM_COMMAND messages! It only handes
160 * WM_MENUSELECT messages.
163 * (will be written ...)
167 MenuHelp (UINT uMsg
, WPARAM wParam
, LPARAM lParam
, HMENU hMainMenu
,
168 HINSTANCE hInst
, HWND hwndStatus
, LPUINT lpwIDs
)
172 if (!IsWindow (hwndStatus
))
177 TRACE (commctrl
, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
180 if ((HIWORD(wParam
) == 0xFFFF) && (lParam
== 0)) {
181 /* menu was closed */
182 TRACE (commctrl
, "menu was closed!\n");
183 SendMessageA (hwndStatus
, SB_SIMPLE
, FALSE
, 0);
186 /* menu item was selected */
187 if (HIWORD(wParam
) & MF_POPUP
)
188 uMenuID
= (UINT
)*(lpwIDs
+1);
190 uMenuID
= (UINT
)LOWORD(wParam
);
191 TRACE (commctrl
, "uMenuID = %u\n", uMenuID
);
196 if (!LoadStringA (hInst
, uMenuID
, szText
, 256))
199 SendMessageA (hwndStatus
, SB_SETTEXTA
,
200 255 | SBT_NOBORDERS
, (LPARAM
)szText
);
201 SendMessageA (hwndStatus
, SB_SIMPLE
, TRUE
, 0);
207 FIXME (commctrl
, "Invalid Message 0x%x!\n", uMsg
);
213 /***********************************************************************
214 * ShowHideMenuCtl [COMCTL32.3]
216 * Shows or hides controls and updates the corresponding menu item.
219 * hwnd [I] handle to the client window.
220 * uFlags [I] menu command id.
221 * lpInfo [I] pointer to an array of integers. (See NOTES.)
228 * The official documentation is incomplete!
229 * This is the correct documentation:
232 * Handle to the window that contains the menu and controls.
235 * Identifier of the menu item to receive or loose a check mark.
238 * The array of integers contains pairs of values. BOTH values of
239 * the first pair must be the handles to the application's main menu.
240 * Each subsequent pair consists of a menu id and control id.
244 ShowHideMenuCtl (HWND hwnd
, UINT uFlags
, LPINT lpInfo
)
248 TRACE (commctrl
, "%x, %x, %p\n", hwnd
, uFlags
, lpInfo
);
253 if (!(lpInfo
[0]) || !(lpInfo
[1]))
256 /* search for control */
257 lpMenuId
= &lpInfo
[2];
258 while (*lpMenuId
!= uFlags
)
261 if (GetMenuState (lpInfo
[1], uFlags
, MF_BYCOMMAND
) & MFS_CHECKED
) {
262 /* uncheck menu item */
263 CheckMenuItem (lpInfo
[0], *lpMenuId
, MF_BYCOMMAND
| MF_UNCHECKED
);
267 SetWindowPos (GetDlgItem (hwnd
, *lpMenuId
), 0, 0, 0, 0, 0,
271 /* check menu item */
272 CheckMenuItem (lpInfo
[0], *lpMenuId
, MF_BYCOMMAND
| MF_CHECKED
);
276 SetWindowPos (GetDlgItem (hwnd
, *lpMenuId
), 0, 0, 0, 0, 0,
284 /***********************************************************************
285 * GetEffectiveClientRect [COMCTL32.4]
288 * hwnd [I] handle to the client window.
289 * lpRect [O] pointer to the rectangle of the client window
290 * lpInfo [I] pointer to an array of integers (see NOTES)
296 * The official documentation is incomplete!
297 * This is the correct documentation:
300 * (will be written...)
304 GetEffectiveClientRect (HWND hwnd
, LPRECT lpRect
, LPINT lpInfo
)
310 TRACE (commctrl
, "(0x%08lx 0x%08lx 0x%08lx)\n",
311 (DWORD
)hwnd
, (DWORD
)lpRect
, (DWORD
)lpInfo
);
313 GetClientRect (hwnd
, lpRect
);
321 hwndCtrl
= GetDlgItem (hwnd
, *lpRun
);
322 if (GetWindowLongA (hwndCtrl
, GWL_STYLE
) & WS_VISIBLE
) {
323 TRACE (commctrl
, "control id 0x%x\n", *lpRun
);
324 GetWindowRect (hwndCtrl
, &rcCtrl
);
325 MapWindowPoints ((HWND
)0, hwnd
, (LPPOINT
)&rcCtrl
, 2);
326 SubtractRect (lpRect
, lpRect
, &rcCtrl
);
333 /***********************************************************************
334 * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
336 * Draws text with borders, like in a status bar.
339 * hdc [I] handle to the window's display context
340 * lprc [I] pointer to a rectangle
341 * text [I] pointer to the text
342 * style [I] drawing style
348 * The style variable can have one of the following values:
349 * (will be written ...)
353 DrawStatusTextA (HDC hdc
, LPRECT lprc
, LPCSTR text
, UINT style
)
356 UINT border
= BDR_SUNKENOUTER
;
358 if (style
& SBT_POPOUT
)
359 border
= BDR_RAISEDOUTER
;
360 else if (style
& SBT_NOBORDERS
)
363 DrawEdge (hdc
, &r
, border
, BF_RECT
|BF_ADJUST
|BF_MIDDLE
);
367 int oldbkmode
= SetBkMode (hdc
, TRANSPARENT
);
369 DrawTextA (hdc
, text
, lstrlenA(text
),
370 &r
, DT_LEFT
|DT_VCENTER
|DT_SINGLELINE
);
371 if (oldbkmode
!= TRANSPARENT
)
372 SetBkMode(hdc
, oldbkmode
);
377 /***********************************************************************
378 * DrawStatusText32W [COMCTL32.28]
380 * Draws text with borders, like in a status bar.
383 * hdc [I] handle to the window's display context
384 * lprc [I] pointer to a rectangle
385 * text [I] pointer to the text
386 * style [I] drawing style
393 DrawStatusTextW (HDC hdc
, LPRECT lprc
, LPCWSTR text
, UINT style
)
395 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, text
);
396 DrawStatusTextA (hdc
, lprc
, p
, style
);
397 HeapFree (GetProcessHeap (), 0, p
);
401 /***********************************************************************
402 * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21]
404 * Creates a status bar
407 * style [I] window style
408 * text [I] pointer to the window text
409 * parent [I] handle to the parent window
410 * wid [I] control id of the status bar
413 * Success: handle to the status window
418 CreateStatusWindowA (INT style
, LPCSTR text
, HWND parent
, UINT wid
)
420 return CreateWindowA(STATUSCLASSNAMEA
, text
, style
,
421 CW_USEDEFAULT
, CW_USEDEFAULT
,
422 CW_USEDEFAULT
, CW_USEDEFAULT
,
427 /***********************************************************************
428 * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
431 * style [I] window style
432 * text [I] pointer to the window text
433 * parent [I] handle to the parent window
434 * wid [I] control id of the status bar
437 * Success: handle to the status window
442 CreateStatusWindowW (INT style
, LPCWSTR text
, HWND parent
, UINT wid
)
444 return CreateWindowW(STATUSCLASSNAMEW
, text
, style
,
445 CW_USEDEFAULT
, CW_USEDEFAULT
,
446 CW_USEDEFAULT
, CW_USEDEFAULT
,
451 /***********************************************************************
452 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
455 * style [I] window styles
456 * x [I] horizontal position of the control
457 * y [I] vertical position of the control
458 * cx [I] with of the control
459 * cy [I] height of the control
460 * parent [I] handle to the parent window
461 * id [I] the control's identifier
462 * inst [I] handle to the application's module instance
463 * buddy [I] handle to the buddy window, can be NULL
464 * maxVal [I] upper limit of the control
465 * minVal [I] lower limit of the control
466 * curVal [I] current value of the control
469 * Success: handle to the updown control
474 CreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
475 HWND parent
, INT id
, HINSTANCE inst
,
476 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
479 CreateWindowA (UPDOWN_CLASSA
, 0, style
, x
, y
, cx
, cy
,
480 parent
, id
, inst
, 0);
482 SendMessageA (hUD
, UDM_SETBUDDY
, buddy
, 0);
483 SendMessageA (hUD
, UDM_SETRANGE
, 0, MAKELONG(maxVal
, minVal
));
484 SendMessageA (hUD
, UDM_SETPOS
, 0, MAKELONG(curVal
, 0));
491 /***********************************************************************
492 * InitCommonControls [COMCTL32.17]
494 * Registers the common controls.
503 * This function is just a dummy.
504 * The Win95 controls are registered at the DLL's initialization.
505 * To register other controls InitCommonControlsEx() must be used.
509 InitCommonControls (VOID
)
514 /***********************************************************************
515 * InitCommonControlsEx [COMCTL32.81]
517 * Registers the common controls.
520 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
527 * Only the additinal common controls are registered by this function.
528 * The Win95 controls are registered at the DLL's initialization.
532 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls
)
539 if (lpInitCtrls
->dwSize
!= sizeof(INITCOMMONCONTROLSEX
))
542 TRACE(commctrl
,"(0x%08lx)\n", lpInitCtrls
->dwICC
);
544 for (cCount
= 0; cCount
< 32; cCount
++) {
545 dwMask
= 1 << cCount
;
546 if (!(lpInitCtrls
->dwICC
& dwMask
))
549 switch (lpInitCtrls
->dwICC
& dwMask
) {
550 /* dummy initialization */
551 case ICC_ANIMATE_CLASS
:
552 case ICC_BAR_CLASSES
:
553 case ICC_LISTVIEW_CLASSES
:
554 case ICC_TREEVIEW_CLASSES
:
555 case ICC_TAB_CLASSES
:
556 case ICC_UPDOWN_CLASS
:
557 case ICC_PROGRESS_CLASS
:
558 case ICC_HOTKEY_CLASS
:
561 /* advanced classes - not included in Win95 */
562 case ICC_DATE_CLASSES
:
563 MONTHCAL_Register ();
564 DATETIME_Register ();
567 case ICC_USEREX_CLASSES
:
571 case ICC_COOL_CLASSES
:
575 case ICC_INTERNET_CLASSES
:
576 IPADDRESS_Register ();
579 case ICC_PAGESCROLLER_CLASS
:
583 case ICC_NATIVEFNTCTL_CLASS
:
584 NATIVEFONT_Register ();
588 FIXME (commctrl
, "Unknown class! dwICC=0x%lX\n", dwMask
);
597 /***********************************************************************
598 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
616 * Success: handle to the tool bar control
621 CreateToolbarEx (HWND hwnd
, DWORD style
, UINT wID
, INT nBitmaps
,
622 HINSTANCE hBMInst
, UINT wBMID
, LPCTBBUTTON lpButtons
,
623 INT iNumButtons
, INT dxButton
, INT dyButton
,
624 INT dxBitmap
, INT dyBitmap
, UINT uStructSize
)
627 CreateWindowExA (0, TOOLBARCLASSNAMEA
, "", style
, 0, 0, 0, 0,
628 hwnd
, (HMENU
)wID
, 0, NULL
);
632 SendMessageA (hwndTB
, TB_BUTTONSTRUCTSIZE
,
633 (WPARAM
)uStructSize
, 0);
635 /* set bitmap and button size */
636 /*If CreateToolbarEx receive 0, windows set default values*/
642 SendMessageA (hwndTB
, TB_SETBITMAPSIZE
, 0,
643 MAKELPARAM((WORD
)dyBitmap
, (WORD
)dxBitmap
));
644 SendMessageA (hwndTB
, TB_SETBUTTONSIZE
, 0,
645 MAKELPARAM((WORD
)dyButton
, (WORD
)dxButton
));
651 tbab
.hInst
= hBMInst
;
654 SendMessageA (hwndTB
, TB_ADDBITMAP
,
655 (WPARAM
)nBitmaps
, (LPARAM
)&tbab
);
659 SendMessageA (hwndTB
, TB_ADDBUTTONSA
,
660 (WPARAM
)iNumButtons
, (LPARAM
)lpButtons
);
667 /***********************************************************************
668 * CreateMappedBitmap [COMCTL32.8]
678 * Success: handle to the new bitmap
683 CreateMappedBitmap (HINSTANCE hInstance
, INT idBitmap
, UINT wFlags
,
684 LPCOLORMAP lpColorMap
, INT iNumMaps
)
688 LPBITMAPINFOHEADER lpBitmap
, lpBitmapInfo
;
689 UINT nSize
, nColorTableSize
;
691 INT iColor
, i
, iMaps
, nWidth
, nHeight
;
694 LPCOLORMAP sysColorMap
;
695 COLORMAP internalColorMap
[4] =
696 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
698 /* initialize pointer to colortable and default color table */
701 sysColorMap
= lpColorMap
;
704 internalColorMap
[0].to
= GetSysColor (COLOR_BTNTEXT
);
705 internalColorMap
[1].to
= GetSysColor (COLOR_BTNSHADOW
);
706 internalColorMap
[2].to
= GetSysColor (COLOR_BTNFACE
);
707 internalColorMap
[3].to
= GetSysColor (COLOR_BTNHIGHLIGHT
);
709 sysColorMap
= (LPCOLORMAP
)internalColorMap
;
712 hRsrc
= FindResourceA (hInstance
, (LPSTR
)idBitmap
, RT_BITMAPA
);
715 hglb
= LoadResource (hInstance
, hRsrc
);
718 lpBitmap
= (LPBITMAPINFOHEADER
)LockResource (hglb
);
719 if (lpBitmap
== NULL
)
722 nColorTableSize
= (1 << lpBitmap
->biBitCount
);
723 nSize
= lpBitmap
->biSize
+ nColorTableSize
* sizeof(RGBQUAD
);
724 lpBitmapInfo
= (LPBITMAPINFOHEADER
)GlobalAlloc (GMEM_FIXED
, nSize
);
725 if (lpBitmapInfo
== NULL
)
727 RtlMoveMemory (lpBitmapInfo
, lpBitmap
, nSize
);
729 pColorTable
= (DWORD
*)(((LPBYTE
)lpBitmapInfo
)+(UINT
)lpBitmapInfo
->biSize
);
731 for (iColor
= 0; iColor
< nColorTableSize
; iColor
++) {
732 for (i
= 0; i
< iMaps
; i
++) {
733 if (pColorTable
[iColor
] == sysColorMap
[i
].from
) {
735 if (wFlags
& CBS_MASKED
) {
736 if (sysColorMap
[i
].to
!= COLOR_BTNTEXT
)
737 pColorTable
[iColor
] = RGB(255, 255, 255);
741 pColorTable
[iColor
] = sysColorMap
[i
].to
;
747 nWidth
= (INT
)lpBitmapInfo
->biWidth
;
748 nHeight
= (INT
)lpBitmapInfo
->biHeight
;
749 hdcScreen
= GetDC ((HWND
)0);
750 hbm
= CreateCompatibleBitmap (hdcScreen
, nWidth
, nHeight
);
752 HDC hdcDst
= CreateCompatibleDC (hdcScreen
);
753 HBITMAP hbmOld
= SelectObject (hdcDst
, hbm
);
754 LPBYTE lpBits
= (LPBYTE
)(lpBitmap
+ 1);
755 lpBits
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
);
756 StretchDIBits (hdcDst
, 0, 0, nWidth
, nHeight
, 0, 0, nWidth
, nHeight
,
757 lpBits
, (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
,
759 SelectObject (hdcDst
, hbmOld
);
762 ReleaseDC ((HWND
)0, hdcScreen
);
763 GlobalFree ((HGLOBAL
)lpBitmapInfo
);
770 /***********************************************************************
771 * CreateToolbar [COMCTL32.7] Creates a tool bar control
784 * Success: handle to the tool bar control
788 * Do not use this functions anymore. Use CreateToolbarEx instead.
792 CreateToolbar (HWND hwnd
, DWORD style
, UINT wID
, INT nBitmaps
,
793 HINSTANCE hBMInst
, UINT wBMID
,
794 LPCOLDTBBUTTON lpButtons
,INT iNumButtons
)
796 return CreateToolbarEx (hwnd
, style
| CCS_NODIVIDER
, wID
, nBitmaps
,
797 hBMInst
, wBMID
, (LPCTBBUTTON
)lpButtons
,
798 iNumButtons
, 0, 0, 0, 0, sizeof (OLDTBBUTTON
));
802 /***********************************************************************
803 * DllGetVersion [COMCTL32.25]
805 * Retrieves version information of the 'COMCTL32.DLL'
808 * pdvi [O] pointer to version information structure.
812 * Failure: E_INVALIDARG
815 * Returns version of a comctl32.dll from IE4.01 SP1.
819 COMCTL32_DllGetVersion (DLLVERSIONINFO
*pdvi
)
821 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
)) {
822 WARN (commctrl
, "wrong DLLVERSIONINFO size from app");
826 pdvi
->dwMajorVersion
= 4;
827 pdvi
->dwMinorVersion
= 72;
828 pdvi
->dwBuildNumber
= 3110;
829 pdvi
->dwPlatformID
= 1;
831 TRACE (commctrl
, "%lu.%lu.%lu.%lu\n",
832 pdvi
->dwMajorVersion
, pdvi
->dwMinorVersion
,
833 pdvi
->dwBuildNumber
, pdvi
->dwPlatformID
);