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