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"
37 HANDLE COMCTL32_hHeap
= (HANDLE
)NULL
;
38 DWORD COMCTL32_dwProcessesAttached
= 0;
39 LPSTR COMCTL32_aSubclass
= (LPSTR
)NULL
;
42 /***********************************************************************
43 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
46 * hinstDLL [I] handle to the 'dlls' instance
48 * lpvReserved [I] reserverd, must be NULL
56 COMCTL32_LibMain (HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
58 TRACE (commctrl
, "%x,%lx,%p\n", hinstDLL
, fdwReason
, lpvReserved
);
61 case DLL_PROCESS_ATTACH
:
62 if (COMCTL32_dwProcessesAttached
== 0) {
63 /* create private heap */
64 COMCTL32_hHeap
= HeapCreate (0, 0x10000, 0);
65 TRACE (commctrl
, "Heap created: 0x%x\n", COMCTL32_hHeap
);
67 /* add global subclassing atom (used by 'tooltip' and 'updown') */
68 COMCTL32_aSubclass
= (LPSTR
)(DWORD
)GlobalAddAtomA ("CC32SubclassInfo");
69 TRACE (commctrl
, "Subclassing atom added: %p\n",
72 /* register all Win95 common control classes */
79 PROPSHEET_Register ();
88 COMCTL32_dwProcessesAttached
++;
91 case DLL_PROCESS_DETACH
:
92 COMCTL32_dwProcessesAttached
--;
93 if (COMCTL32_dwProcessesAttached
== 0) {
94 /* unregister all common control classes */
95 ANIMATE_Unregister ();
96 COMBOEX_Unregister ();
97 DATETIME_Unregister ();
100 HOTKEY_Unregister ();
101 IPADDRESS_Unregister ();
102 LISTVIEW_Unregister ();
103 MONTHCAL_Unregister ();
104 NATIVEFONT_Unregister ();
106 PROGRESS_Unregister ();
107 PROPSHEET_UnRegister ();
109 STATUS_Unregister ();
111 TOOLBAR_Unregister ();
112 TOOLTIPS_Unregister ();
113 TRACKBAR_Unregister ();
114 TREEVIEW_Unregister ();
115 UPDOWN_Unregister ();
117 /* delete global subclassing atom */
118 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass
));
119 TRACE (commctrl
, "Subclassing atom deleted: %p\n",
121 COMCTL32_aSubclass
= (LPSTR
)NULL
;
123 /* destroy private heap */
124 HeapDestroy (COMCTL32_hHeap
);
125 TRACE (commctrl
, "Heap destroyed: 0x%x\n", COMCTL32_hHeap
);
126 COMCTL32_hHeap
= (HANDLE
)NULL
;
135 /***********************************************************************
136 * MenuHelp [COMCTL32.2]
139 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
140 * wParam [I] wParam of the message uMsg
141 * lParam [I] lParam of the message uMsg
142 * hMainMenu [I] handle to the application's main menu
143 * hInst [I] handle to the module that contains string resources
144 * hwndStatus [I] handle to the status bar window
145 * lpwIDs [I] pointer to an array of intergers (see NOTES)
151 * The official documentation is incomplete!
152 * This is the correct documentation:
155 * MenuHelp() does NOT handle WM_COMMAND messages! It only handes
156 * WM_MENUSELECT messages.
159 * (will be written ...)
163 MenuHelp (UINT uMsg
, WPARAM wParam
, LPARAM lParam
, HMENU hMainMenu
,
164 HINSTANCE hInst
, HWND hwndStatus
, LPUINT lpwIDs
)
168 if (!IsWindow (hwndStatus
))
173 TRACE (commctrl
, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
176 if ((HIWORD(wParam
) == 0xFFFF) && (lParam
== 0)) {
177 /* menu was closed */
178 TRACE (commctrl
, "menu was closed!\n");
179 SendMessageA (hwndStatus
, SB_SIMPLE
, FALSE
, 0);
182 /* menu item was selected */
183 if (HIWORD(wParam
) & MF_POPUP
)
184 uMenuID
= (UINT
)*(lpwIDs
+1);
186 uMenuID
= (UINT
)LOWORD(wParam
);
187 TRACE (commctrl
, "uMenuID = %u\n", uMenuID
);
192 if (!LoadStringA (hInst
, uMenuID
, szText
, 256))
195 SendMessageA (hwndStatus
, SB_SETTEXTA
,
196 255 | SBT_NOBORDERS
, (LPARAM
)szText
);
197 SendMessageA (hwndStatus
, SB_SIMPLE
, TRUE
, 0);
203 FIXME (commctrl
, "Invalid Message 0x%x!\n", uMsg
);
209 /***********************************************************************
210 * ShowHideMenuCtl [COMCTL32.3]
212 * Shows or hides controls and updates the corresponding menu item.
215 * hwnd [I] handle to the client window.
216 * uFlags [I] menu command id.
217 * lpInfo [I] pointer to an array of integers. (See NOTES.)
224 * The official documentation is incomplete!
225 * This is the correct documentation:
228 * Handle to the window that contains the menu and controls.
231 * Identifier of the menu item to receive or loose a check mark.
234 * The array of integers contains pairs of values. BOTH values of
235 * the first pair must be the handles to the application's main menu.
236 * Each subsequent pair consists of a menu id and control id.
240 ShowHideMenuCtl (HWND hwnd
, UINT uFlags
, LPINT lpInfo
)
244 TRACE (commctrl
, "%x, %x, %p\n", hwnd
, uFlags
, lpInfo
);
249 if (!(lpInfo
[0]) || !(lpInfo
[1]))
252 /* search for control */
253 lpMenuId
= &lpInfo
[2];
254 while (*lpMenuId
!= uFlags
)
257 if (GetMenuState (lpInfo
[1], uFlags
, MF_BYCOMMAND
) & MFS_CHECKED
) {
258 /* uncheck menu item */
259 CheckMenuItem (lpInfo
[0], *lpMenuId
, MF_BYCOMMAND
| MF_UNCHECKED
);
263 SetWindowPos (GetDlgItem (hwnd
, *lpMenuId
), 0, 0, 0, 0, 0,
267 /* check menu item */
268 CheckMenuItem (lpInfo
[0], *lpMenuId
, MF_BYCOMMAND
| MF_CHECKED
);
272 SetWindowPos (GetDlgItem (hwnd
, *lpMenuId
), 0, 0, 0, 0, 0,
280 /***********************************************************************
281 * GetEffectiveClientRect [COMCTL32.4]
284 * hwnd [I] handle to the client window.
285 * lpRect [O] pointer to the rectangle of the client window
286 * lpInfo [I] pointer to an array of integers (see NOTES)
292 * The official documentation is incomplete!
293 * This is the correct documentation:
296 * (will be written...)
300 GetEffectiveClientRect (HWND hwnd
, LPRECT lpRect
, LPINT lpInfo
)
306 TRACE (commctrl
, "(0x%08lx 0x%08lx 0x%08lx)\n",
307 (DWORD
)hwnd
, (DWORD
)lpRect
, (DWORD
)lpInfo
);
309 GetClientRect (hwnd
, lpRect
);
317 hwndCtrl
= GetDlgItem (hwnd
, *lpRun
);
318 if (GetWindowLongA (hwndCtrl
, GWL_STYLE
) & WS_VISIBLE
) {
319 TRACE (commctrl
, "control id 0x%x\n", *lpRun
);
320 GetWindowRect (hwndCtrl
, &rcCtrl
);
321 MapWindowPoints ((HWND
)0, hwnd
, (LPPOINT
)&rcCtrl
, 2);
322 SubtractRect (lpRect
, lpRect
, &rcCtrl
);
329 /***********************************************************************
330 * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
332 * Draws text with borders, like in a status bar.
335 * hdc [I] handle to the window's display context
336 * lprc [I] pointer to a rectangle
337 * text [I] pointer to the text
338 * style [I] drawing style
344 * The style variable can have one of the following values:
345 * (will be written ...)
349 DrawStatusTextA (HDC hdc
, LPRECT lprc
, LPCSTR text
, UINT style
)
352 UINT border
= BDR_SUNKENOUTER
;
354 if (style
== SBT_POPOUT
)
355 border
= BDR_RAISEDOUTER
;
356 else if (style
== SBT_NOBORDERS
)
359 DrawEdge (hdc
, &r
, border
, BF_RECT
|BF_ADJUST
|BF_MIDDLE
);
363 int oldbkmode
= SetBkMode (hdc
, TRANSPARENT
);
365 DrawTextA (hdc
, text
, lstrlenA(text
),
366 &r
, DT_LEFT
|DT_VCENTER
|DT_SINGLELINE
);
367 if (oldbkmode
!= TRANSPARENT
)
368 SetBkMode(hdc
, oldbkmode
);
373 /***********************************************************************
374 * DrawStatusText32W [COMCTL32.28]
376 * Draws text with borders, like in a status bar.
379 * hdc [I] handle to the window's display context
380 * lprc [I] pointer to a rectangle
381 * text [I] pointer to the text
382 * style [I] drawing style
389 DrawStatusTextW (HDC hdc
, LPRECT lprc
, LPCWSTR text
, UINT style
)
391 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, text
);
392 DrawStatusTextA (hdc
, lprc
, p
, style
);
393 HeapFree (GetProcessHeap (), 0, p
);
397 /***********************************************************************
398 * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21]
400 * Creates a status bar
403 * style [I] window style
404 * text [I] pointer to the window text
405 * parent [I] handle to the parent window
406 * wid [I] control id of the status bar
409 * Success: handle to the status window
414 CreateStatusWindowA (INT style
, LPCSTR text
, HWND parent
, UINT wid
)
416 return CreateWindowA(STATUSCLASSNAMEA
, text
, style
,
417 CW_USEDEFAULT
, CW_USEDEFAULT
,
418 CW_USEDEFAULT
, CW_USEDEFAULT
,
423 /***********************************************************************
424 * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
427 * style [I] window style
428 * text [I] pointer to the window text
429 * parent [I] handle to the parent window
430 * wid [I] control id of the status bar
433 * Success: handle to the status window
438 CreateStatusWindowW (INT style
, LPCWSTR text
, HWND parent
, UINT wid
)
440 return CreateWindowW(STATUSCLASSNAMEW
, text
, style
,
441 CW_USEDEFAULT
, CW_USEDEFAULT
,
442 CW_USEDEFAULT
, CW_USEDEFAULT
,
447 /***********************************************************************
448 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
451 * style [I] window styles
452 * x [I] horizontal position of the control
453 * y [I] vertical position of the control
454 * cx [I] with of the control
455 * cy [I] height of the control
456 * parent [I] handle to the parent window
457 * id [I] the control's identifier
458 * inst [I] handle to the application's module instance
459 * buddy [I] handle to the buddy window, can be NULL
460 * maxVal [I] upper limit of the control
461 * minVal [I] lower limit of the control
462 * curVal [I] current value of the control
465 * Success: handle to the updown control
470 CreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
471 HWND parent
, INT id
, HINSTANCE inst
,
472 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
475 CreateWindowA (UPDOWN_CLASSA
, 0, style
, x
, y
, cx
, cy
,
476 parent
, id
, inst
, 0);
478 SendMessageA (hUD
, UDM_SETBUDDY
, buddy
, 0);
479 SendMessageA (hUD
, UDM_SETRANGE
, 0, MAKELONG(maxVal
, minVal
));
480 SendMessageA (hUD
, UDM_SETPOS
, 0, MAKELONG(curVal
, 0));
487 /***********************************************************************
488 * InitCommonControls [COMCTL32.17]
490 * Registers the common controls.
499 * This function is just a dummy.
500 * The Win95 controls are registered at the DLL's initialization.
501 * To register other controls InitCommonControlsEx() must be used.
505 InitCommonControls (VOID
)
510 /***********************************************************************
511 * InitCommonControlsEx [COMCTL32.81]
513 * Registers the common controls.
516 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
523 * Only the additinal common controls are registered by this function.
524 * The Win95 controls are registered at the DLL's initialization.
528 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls
)
535 if (lpInitCtrls
->dwSize
!= sizeof(INITCOMMONCONTROLSEX
))
538 TRACE(commctrl
,"(0x%08lx)\n", lpInitCtrls
->dwICC
);
540 for (cCount
= 0; cCount
< 32; cCount
++) {
541 dwMask
= 1 << cCount
;
542 if (!(lpInitCtrls
->dwICC
& dwMask
))
545 switch (lpInitCtrls
->dwICC
& dwMask
) {
546 /* dummy initialization */
547 case ICC_ANIMATE_CLASS
:
548 case ICC_BAR_CLASSES
:
549 case ICC_LISTVIEW_CLASSES
:
550 case ICC_TREEVIEW_CLASSES
:
551 case ICC_TAB_CLASSES
:
552 case ICC_UPDOWN_CLASS
:
553 case ICC_PROGRESS_CLASS
:
554 case ICC_HOTKEY_CLASS
:
557 /* advanced classes - not included in Win95 */
558 case ICC_DATE_CLASSES
:
559 MONTHCAL_Register ();
560 DATETIME_Register ();
563 case ICC_USEREX_CLASSES
:
567 case ICC_COOL_CLASSES
:
571 case ICC_INTERNET_CLASSES
:
572 IPADDRESS_Register ();
575 case ICC_PAGESCROLLER_CLASS
:
579 case ICC_NATIVEFNTCTL_CLASS
:
580 NATIVEFONT_Register ();
584 FIXME (commctrl
, "Unknown class! dwICC=0x%lX\n", dwMask
);
593 /***********************************************************************
594 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
612 * Success: handle to the tool bar control
617 CreateToolbarEx (HWND hwnd
, DWORD style
, UINT wID
, INT nBitmaps
,
618 HINSTANCE hBMInst
, UINT wBMID
, LPCTBBUTTON lpButtons
,
619 INT iNumButtons
, INT dxButton
, INT dyButton
,
620 INT dxBitmap
, INT dyBitmap
, UINT uStructSize
)
623 CreateWindowExA (0, TOOLBARCLASSNAMEA
, "", style
, 0, 0, 0, 0,
624 hwnd
, (HMENU
)wID
, 0, NULL
);
628 SendMessageA (hwndTB
, TB_BUTTONSTRUCTSIZE
,
629 (WPARAM
)uStructSize
, 0);
631 /* set bitmap and button size */
632 if (hBMInst
== HINST_COMMCTRL
) {
634 SendMessageA (hwndTB
, TB_SETBITMAPSIZE
, 0,
636 SendMessageA (hwndTB
, TB_SETBUTTONSIZE
, 0,
640 SendMessageA (hwndTB
, TB_SETBITMAPSIZE
, 0,
642 SendMessageA (hwndTB
, TB_SETBUTTONSIZE
, 0,
647 SendMessageA (hwndTB
, TB_SETBITMAPSIZE
, 0,
648 MAKELPARAM((WORD
)dyBitmap
, (WORD
)dxBitmap
));
649 SendMessageA (hwndTB
, TB_SETBUTTONSIZE
, 0,
650 MAKELPARAM((WORD
)dyButton
, (WORD
)dxButton
));
654 tbab
.hInst
= hBMInst
;
656 SendMessageA (hwndTB
, TB_ADDBITMAP
,
657 (WPARAM
)nBitmaps
, (LPARAM
)&tbab
);
660 SendMessageA (hwndTB
, TB_ADDBUTTONSA
,
661 (WPARAM
)iNumButtons
, (LPARAM
)lpButtons
);
668 /***********************************************************************
669 * CreateMappedBitmap [COMCTL32.8]
679 * Success: handle to the new bitmap
684 CreateMappedBitmap (HINSTANCE hInstance
, INT idBitmap
, UINT wFlags
,
685 LPCOLORMAP lpColorMap
, INT iNumMaps
)
689 LPBITMAPINFOHEADER lpBitmap
, lpBitmapInfo
;
690 UINT nSize
, nColorTableSize
;
692 INT iColor
, i
, iMaps
, nWidth
, nHeight
;
695 LPCOLORMAP sysColorMap
;
696 COLORMAP internalColorMap
[4] =
697 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
699 /* initialize pointer to colortable and default color table */
702 sysColorMap
= lpColorMap
;
705 internalColorMap
[0].to
= GetSysColor (COLOR_BTNTEXT
);
706 internalColorMap
[1].to
= GetSysColor (COLOR_BTNSHADOW
);
707 internalColorMap
[2].to
= GetSysColor (COLOR_BTNFACE
);
708 internalColorMap
[3].to
= GetSysColor (COLOR_BTNHIGHLIGHT
);
710 sysColorMap
= (LPCOLORMAP
)internalColorMap
;
713 hRsrc
= FindResourceA (hInstance
, (LPSTR
)idBitmap
, RT_BITMAPA
);
716 hglb
= LoadResource (hInstance
, hRsrc
);
719 lpBitmap
= (LPBITMAPINFOHEADER
)LockResource (hglb
);
720 if (lpBitmap
== NULL
)
723 nColorTableSize
= (1 << lpBitmap
->biBitCount
);
724 nSize
= lpBitmap
->biSize
+ nColorTableSize
* sizeof(RGBQUAD
);
725 lpBitmapInfo
= (LPBITMAPINFOHEADER
)GlobalAlloc (GMEM_FIXED
, nSize
);
726 if (lpBitmapInfo
== NULL
)
728 RtlMoveMemory (lpBitmapInfo
, lpBitmap
, nSize
);
730 pColorTable
= (DWORD
*)(((LPBYTE
)lpBitmapInfo
)+(UINT
)lpBitmapInfo
->biSize
);
732 for (iColor
= 0; iColor
< nColorTableSize
; iColor
++) {
733 for (i
= 0; i
< iMaps
; i
++) {
734 if (pColorTable
[iColor
] == sysColorMap
[i
].from
) {
736 if (wFlags
& CBS_MASKED
) {
737 if (sysColorMap
[i
].to
!= COLOR_BTNTEXT
)
738 pColorTable
[iColor
] = RGB(255, 255, 255);
742 pColorTable
[iColor
] = sysColorMap
[i
].to
;
748 nWidth
= (INT
)lpBitmapInfo
->biWidth
;
749 nHeight
= (INT
)lpBitmapInfo
->biHeight
;
750 hdcScreen
= GetDC ((HWND
)0);
751 hbm
= CreateCompatibleBitmap (hdcScreen
, nWidth
, nHeight
);
753 HDC hdcDst
= CreateCompatibleDC (hdcScreen
);
754 HBITMAP hbmOld
= SelectObject (hdcDst
, hbm
);
755 LPBYTE lpBits
= (LPBYTE
)(lpBitmap
+ 1);
756 lpBits
+= (1 << (lpBitmapInfo
->biBitCount
)) * sizeof(RGBQUAD
);
757 StretchDIBits (hdcDst
, 0, 0, nWidth
, nHeight
, 0, 0, nWidth
, nHeight
,
758 lpBits
, (LPBITMAPINFO
)lpBitmapInfo
, DIB_RGB_COLORS
,
760 SelectObject (hdcDst
, hbmOld
);
763 ReleaseDC ((HWND
)0, hdcScreen
);
764 GlobalFree ((HGLOBAL
)lpBitmapInfo
);
771 /***********************************************************************
772 * CreateToolbar [COMCTL32.7] Creates a tool bar control
785 * Success: handle to the tool bar control
789 * Do not use this functions anymore. Use CreateToolbarEx instead.
793 CreateToolbar (HWND hwnd
, DWORD style
, UINT wID
, INT nBitmaps
,
794 HINSTANCE hBMInst
, UINT wBMID
,
795 LPCOLDTBBUTTON lpButtons
,INT iNumButtons
)
797 return CreateToolbarEx (hwnd
, style
| CCS_NODIVIDER
, wID
, nBitmaps
,
798 hBMInst
, wBMID
, (LPCTBBUTTON
)lpButtons
,
799 iNumButtons
, 0, 0, 0, 0, sizeof (OLDTBBUTTON
));
803 /***********************************************************************
804 * DllGetVersion [COMCTL32.25]
806 * Retrieves version information of the 'COMCTL32.DLL'
809 * pdvi [O] pointer to version information structure.
813 * Failure: E_INVALIDARG
816 * Returns version of a comctl32.dll from IE4.01 SP1.
820 COMCTL32_DllGetVersion (DLLVERSIONINFO
*pdvi
)
822 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
)) {
823 WARN (commctrl
, "wrong DLLVERSIONINFO size from app");
827 pdvi
->dwMajorVersion
= 4;
828 pdvi
->dwMinorVersion
= 72;
829 pdvi
->dwBuildNumber
= 3110;
830 pdvi
->dwPlatformID
= 1;
832 TRACE (commctrl
, "%lu.%lu.%lu.%lu\n",
833 pdvi
->dwMajorVersion
, pdvi
->dwMinorVersion
,
834 pdvi
->dwBuildNumber
, pdvi
->dwPlatformID
);