2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998 Eric Kohl
16 #include "ipaddress.h"
18 #include "nativefont.h"
33 HANDLE32 COMCTL32_hHeap = (HANDLE32)NULL;
34 DWORD COMCTL32_dwProcessesAttached = 0;
37 /***********************************************************************
38 * ComCtl32LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
41 * hinstDLL [I] handle to the 'dlls' instance
43 * lpvReserved [I] reserverd, must be NULL
51 ComCtl32LibMain (HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
53 TRACE (commctrl, "%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
56 case DLL_PROCESS_ATTACH:
57 if (COMCTL32_dwProcessesAttached == 0) {
58 /* create private heap */
59 COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
60 TRACE (commctrl, "Heap created: 0x%x\n", COMCTL32_hHeap);
62 /* register all Win95 common control classes */
76 COMCTL32_dwProcessesAttached++;
79 case DLL_PROCESS_DETACH:
80 COMCTL32_dwProcessesAttached--;
81 if (COMCTL32_dwProcessesAttached == 0) {
82 /* unregister all common control classes */
83 IPADDRESS_Unregister ();
85 NATIVEFONT_Unregister ();
87 TOOLTIPS_Unregister ();
89 /* destroy private heap */
90 HeapDestroy (COMCTL32_hHeap);
91 TRACE (commctrl, "Heap destroyed: 0x%x\n", COMCTL32_hHeap);
92 COMCTL32_hHeap = (HANDLE32)NULL;
101 /***********************************************************************
102 * MenuHelp [COMCTL32.2]
108 * hMainMenu [I] handle to the applications main menu
110 * hwndStatus [I] handle to the status bar window
111 * lpwIDs [I] pointer to an array of intergers (see NOTES)
117 * The official documentation is incomplete!
121 MenuHelp (UINT32 uMsg, WPARAM32 wParam, LPARAM lParam, HMENU32 hMainMenu,
122 HINSTANCE32 hInst, HWND32 hwndStatus, LPUINT32 lpwIDs)
126 if (!IsWindow32 (hwndStatus))
131 TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
134 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
135 /* menu was closed */
136 TRACE (commctrl, "menu was closed!\n");
137 SendMessage32A (hwndStatus, SB_SIMPLE, FALSE, 0);
140 /* menu item was selected */
141 if (HIWORD(wParam) & MF_POPUP)
142 uMenuID = (UINT32)*(lpwIDs+1);
144 uMenuID = (UINT32)LOWORD(wParam);
145 TRACE (commctrl, "uMenuID = %u\n", uMenuID);
150 if (!LoadString32A (hInst, uMenuID, szText, 256))
153 SendMessage32A (hwndStatus, SB_SETTEXT32A,
154 255 | SBT_NOBORDERS, (LPARAM)szText);
155 SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0);
161 FIXME (commctrl, "Invalid Message!\n");
167 /***********************************************************************
168 * ShowHideMenuCtl [COMCTL32.3]
170 * Shows or hides controls and updates the corresponding menu item.
173 * hwnd [I] handle to the client window.
174 * uFlags [I] menu command id.
175 * lpInfo [I] pointer to an array of integers. (See NOTES.)
182 * The official documentation is incomplete! This has been fixed.
185 * The array of integers contains pairs of values. BOTH values of
186 * the first pair must be the handles to application's main menu.
187 * Each subsequent pair consists of a menu id and control id.
191 ShowHideMenuCtl (HWND32 hwnd, UINT32 uFlags, LPINT32 lpInfo)
195 TRACE (commctrl, "%x, %x, %p\n", hwnd, uFlags, lpInfo);
200 if (!(lpInfo[0]) || !(lpInfo[1]))
203 /* search for control */
204 lpMenuId = &lpInfo[2];
205 while (*lpMenuId != uFlags)
208 if (GetMenuState32 (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
209 /* uncheck menu item */
210 CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
214 SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
218 /* check menu item */
219 CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
223 SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
231 /***********************************************************************
232 * GetEffectiveClientRect [COMCTL32.4]
235 * hwnd [I] handle to the client window.
236 * lpRect [O] pointer to the rectangle of the client window
237 * lpInfo [I] pointer to an array of integers
243 * The official documentation is incomplete!
247 GetEffectiveClientRect (HWND32 hwnd, LPRECT32 lpRect, LPINT32 lpInfo)
253 TRACE (commctrl, "(0x%08lx 0x%08lx 0x%08lx)\n",
254 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
256 GetClientRect32 (hwnd, lpRect);
264 hwndCtrl = GetDlgItem32 (hwnd, *lpRun);
265 if (GetWindowLong32A (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
266 TRACE (commctrl, "control id 0x%x\n", *lpRun);
267 GetWindowRect32 (hwndCtrl, &rcCtrl);
268 MapWindowPoints32 ((HWND32)0, hwnd, (LPPOINT32)&rcCtrl, 2);
269 SubtractRect32 (lpRect, lpRect, &rcCtrl);
276 /***********************************************************************
277 * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
279 * Draws text with borders, like in a status bar.
282 * hdc [I] handle to the window's display context
283 * lprc [I] pointer to a rectangle
284 * text [I] pointer to the text
292 DrawStatusText32A (HDC32 hdc, LPRECT32 lprc, LPCSTR text, UINT32 style)
295 UINT32 border = BDR_SUNKENOUTER;
297 if (style == SBT_POPOUT)
298 border = BDR_RAISEDOUTER;
299 else if (style == SBT_NOBORDERS)
302 DrawEdge32 (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
306 int oldbkmode = SetBkMode32 (hdc, TRANSPARENT);
308 DrawText32A (hdc, text, lstrlen32A(text),
309 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
310 if (oldbkmode != TRANSPARENT)
311 SetBkMode32(hdc, oldbkmode);
316 /***********************************************************************
317 * DrawStatusText32W [COMCTL32.28]
319 * Draws text with borders, like in a status bar.
322 * hdc [I] handle to the window's display context
323 * lprc [I] pointer to a rectangle
324 * text [I] pointer to the text
332 DrawStatusText32W (HDC32 hdc, LPRECT32 lprc, LPCWSTR text, UINT32 style)
334 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
335 DrawStatusText32A (hdc, lprc, p, style);
336 HeapFree (GetProcessHeap (), 0, p );
340 /***********************************************************************
341 * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21] Creates a status bar
346 * parent [I] handle to the parent window
350 * Success: handle to the control
355 CreateStatusWindow32A (INT32 style, LPCSTR text, HWND32 parent, UINT32 wid)
357 return CreateWindow32A(STATUSCLASSNAME32A, text, style,
358 CW_USEDEFAULT32, CW_USEDEFAULT32,
359 CW_USEDEFAULT32, CW_USEDEFAULT32,
364 /***********************************************************************
365 * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
370 * parent [I] handle to the parent window
371 * wid [I] control id of the status bar
374 * Success: handle to the control
379 CreateStatusWindow32W (INT32 style, LPCWSTR text, HWND32 parent, UINT32 wid)
381 return CreateWindow32W((LPCWSTR)STATUSCLASSNAME32W, text, style,
382 CW_USEDEFAULT32, CW_USEDEFAULT32,
383 CW_USEDEFAULT32, CW_USEDEFAULT32,
388 /***********************************************************************
389 * CreateUpDownControl [COMCTL32.16] Creates an Up-Down control
406 * Success: handle to the control
411 CreateUpDownControl (DWORD style, INT32 x, INT32 y, INT32 cx, INT32 cy,
412 HWND32 parent, INT32 id, HINSTANCE32 inst,
413 HWND32 buddy, INT32 maxVal, INT32 minVal, INT32 curVal)
416 CreateWindow32A (UPDOWN_CLASS32A, 0, style, x, y, cx, cy,
417 parent, id, inst, 0);
419 SendMessage32A (hUD, UDM_SETBUDDY, buddy, 0);
420 SendMessage32A (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
421 SendMessage32A (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
428 /***********************************************************************
429 * InitCommonControls [COMCTL32.17]
431 * Registers the common controls.
440 * This function is just a dummy.
441 * The Win95 controls are registered at the DLL's initialization.
442 * To register other controls InitCommonControlsEx must be used.
446 InitCommonControls (VOID)
451 /***********************************************************************
452 * InitCommonControlsEx [COMCTL32.81]
454 * Registers the common controls.
457 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
464 * Only the additinal common controls are registered by this function.
465 * The Win95 controls are registered at the DLL's initialization.
469 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
476 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
479 TRACE(commctrl,"(0x%08lx)\n", lpInitCtrls->dwICC);
481 for (cCount = 0; cCount < 32; cCount++) {
482 dwMask = 1 << cCount;
483 if (!(lpInitCtrls->dwICC & dwMask))
486 switch (lpInitCtrls->dwICC & dwMask) {
487 /* dummy initialization */
488 case ICC_ANIMATE_CLASS:
489 case ICC_BAR_CLASSES:
490 case ICC_LISTVIEW_CLASSES:
491 case ICC_TREEVIEW_CLASSES:
492 case ICC_TAB_CLASSES:
493 case ICC_UPDOWN_CLASS:
494 case ICC_PROGRESS_CLASS:
495 case ICC_HOTKEY_CLASS:
498 /* advanced classes - not included in Win95 */
499 case ICC_DATE_CLASSES:
500 FIXME (commctrl, "No month calendar class implemented!\n");
501 FIXME (commctrl, "No date and time picker class implemented!\n");
504 case ICC_USEREX_CLASSES:
508 case ICC_COOL_CLASSES:
512 case ICC_INTERNET_CLASSES:
513 IPADDRESS_Register ();
516 case ICC_PAGESCROLLER_CLASS:
520 case ICC_NATIVEFNTCTL_CLASS:
521 NATIVEFONT_Register ();
525 FIXME (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask);
534 /***********************************************************************
535 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
553 * Success: handle to the tool bar control
558 CreateToolbarEx (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
559 HINSTANCE32 hBMInst, UINT32 wBMID, LPCTBBUTTON lpButtons,
560 INT32 iNumButtons, INT32 dxButton, INT32 dyButton,
561 INT32 dxBitmap, INT32 dyBitmap, UINT32 uStructSize)
564 CreateWindowEx32A (0, TOOLBARCLASSNAME32A, "", style, 0, 0, 0, 0,
565 hwnd, (HMENU32)wID, 0, NULL);
569 SendMessage32A (hwndTB, TB_BUTTONSTRUCTSIZE,
570 (WPARAM32)uStructSize, 0);
572 /* set bitmap and button size */
573 if (hBMInst == HINST_COMMCTRL) {
575 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
577 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
581 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
583 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
588 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
589 MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
590 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
591 MAKELPARAM((WORD)dyButton, (WORD)dxButton));
595 tbab.hInst = hBMInst;
597 SendMessage32A (hwndTB, TB_ADDBITMAP,
598 (WPARAM32)nBitmaps, (LPARAM)&tbab);
601 SendMessage32A (hwndTB, TB_ADDBUTTONS32A,
602 (WPARAM32)iNumButtons, (LPARAM)lpButtons);
609 /***********************************************************************
610 * CreateMappedBitmap [COMCTL32.8]
620 * Success: bitmap handle
625 CreateMappedBitmap (HINSTANCE32 hInstance, INT32 idBitmap, UINT32 wFlags,
626 LPCOLORMAP lpColorMap, INT32 iNumMaps)
630 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
631 UINT32 nSize, nColorTableSize;
633 INT32 iColor, i, iMaps, nWidth, nHeight;
636 LPCOLORMAP sysColorMap;
637 COLORMAP internalColorMap[4] =
638 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
640 /* initialize pointer to colortable and default color table */
643 sysColorMap = lpColorMap;
646 internalColorMap[0].to = GetSysColor32 (COLOR_BTNTEXT);
647 internalColorMap[1].to = GetSysColor32 (COLOR_BTNSHADOW);
648 internalColorMap[2].to = GetSysColor32 (COLOR_BTNFACE);
649 internalColorMap[3].to = GetSysColor32 (COLOR_BTNHIGHLIGHT);
651 sysColorMap = (LPCOLORMAP)internalColorMap;
654 hRsrc = FindResource32A (hInstance, (LPSTR)idBitmap, RT_BITMAP32A);
657 hglb = LoadResource32 (hInstance, hRsrc);
660 lpBitmap = (LPBITMAPINFOHEADER)LockResource32 (hglb);
661 if (lpBitmap == NULL)
664 nColorTableSize = (1 << lpBitmap->biBitCount);
665 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
666 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc32 (GMEM_FIXED, nSize);
667 if (lpBitmapInfo == NULL)
669 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
671 pColorTable = (DWORD*)(((LPBYTE)lpBitmapInfo)+(UINT32)lpBitmapInfo->biSize);
673 for (iColor = 0; iColor < nColorTableSize; iColor++) {
674 for (i = 0; i < iMaps; i++) {
675 if (pColorTable[iColor] == sysColorMap[i].from) {
677 if (wFlags & CBS_MASKED) {
678 if (sysColorMap[i].to != COLOR_BTNTEXT)
679 pColorTable[iColor] = RGB(255, 255, 255);
683 pColorTable[iColor] = sysColorMap[i].to;
689 nWidth = (INT32)lpBitmapInfo->biWidth;
690 nHeight = (INT32)lpBitmapInfo->biHeight;
691 hdcScreen = GetDC32 ((HWND32)0);
692 hbm = CreateCompatibleBitmap32 (hdcScreen, nWidth, nHeight);
694 HDC32 hdcDst = CreateCompatibleDC32 (hdcScreen);
695 HBITMAP32 hbmOld = SelectObject32 (hdcDst, hbm);
696 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
697 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
698 StretchDIBits32 (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
699 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
701 SelectObject32 (hdcDst, hbmOld);
704 ReleaseDC32 ((HWND32)0, hdcScreen);
705 GlobalFree32 ((HGLOBAL32)lpBitmapInfo);
706 FreeResource32 (hglb);
712 /***********************************************************************
713 * CreateToolbar [COMCTL32.7] Creates a tool bar control
726 * Success: handle to the tool bar control
730 * Do not use this functions anymore. Use CreateToolbarEx instead.
734 CreateToolbar (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
735 HINSTANCE32 hBMInst, UINT32 wBMID,
736 LPCOLDTBBUTTON lpButtons,INT32 iNumButtons)
738 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
739 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
740 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
744 /***********************************************************************
745 * DllGetVersion [COMCTL32.25]
747 * Retrieves version information of the 'COMCTL32.DLL'
750 * pdvi [O] pointer to version information structure.
754 * Failure: E_INVALIDARG
757 * Returns version of a comctl32.dll from IE4.01 SP1.
761 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
763 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
764 WARN (commctrl, "wrong DLLVERSIONINFO size from app");
768 pdvi->dwMajorVersion = 4;
769 pdvi->dwMinorVersion = 72;
770 pdvi->dwBuildNumber = 3110;
771 pdvi->dwPlatformID = 1;
773 TRACE (commctrl, "%lu.%lu.%lu.%lu\n",
774 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
775 pdvi->dwBuildNumber, pdvi->dwPlatformID);