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 HANDLE32 COMCTL32_hHeap = (HANDLE32)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 (HINSTANCE32 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)GlobalAddAtom32A ("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 = (HANDLE32)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 (UINT32 uMsg, WPARAM32 wParam, LPARAM lParam, HMENU32 hMainMenu,
164 HINSTANCE32 hInst, HWND32 hwndStatus, LPUINT32 lpwIDs)
168 if (!IsWindow32 (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 SendMessage32A (hwndStatus, SB_SIMPLE, FALSE, 0);
182 /* menu item was selected */
183 if (HIWORD(wParam) & MF_POPUP)
184 uMenuID = (UINT32)*(lpwIDs+1);
186 uMenuID = (UINT32)LOWORD(wParam);
187 TRACE (commctrl, "uMenuID = %u\n", uMenuID);
192 if (!LoadString32A (hInst, uMenuID, szText, 256))
195 SendMessage32A (hwndStatus, SB_SETTEXT32A,
196 255 | SBT_NOBORDERS, (LPARAM)szText);
197 SendMessage32A (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 (HWND32 hwnd, UINT32 uFlags, LPINT32 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 (GetMenuState32 (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
258 /* uncheck menu item */
259 CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
263 SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
267 /* check menu item */
268 CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
272 SetWindowPos32 (GetDlgItem32 (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 (HWND32 hwnd, LPRECT32 lpRect, LPINT32 lpInfo)
306 TRACE (commctrl, "(0x%08lx 0x%08lx 0x%08lx)\n",
307 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
309 GetClientRect32 (hwnd, lpRect);
317 hwndCtrl = GetDlgItem32 (hwnd, *lpRun);
318 if (GetWindowLong32A (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
319 TRACE (commctrl, "control id 0x%x\n", *lpRun);
320 GetWindowRect32 (hwndCtrl, &rcCtrl);
321 MapWindowPoints32 ((HWND32)0, hwnd, (LPPOINT32)&rcCtrl, 2);
322 SubtractRect32 (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 DrawStatusText32A (HDC32 hdc, LPRECT32 lprc, LPCSTR text, UINT32 style)
352 UINT32 border = BDR_SUNKENOUTER;
354 if (style == SBT_POPOUT)
355 border = BDR_RAISEDOUTER;
356 else if (style == SBT_NOBORDERS)
359 DrawEdge32 (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
363 int oldbkmode = SetBkMode32 (hdc, TRANSPARENT);
365 DrawText32A (hdc, text, lstrlen32A(text),
366 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
367 if (oldbkmode != TRANSPARENT)
368 SetBkMode32(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 DrawStatusText32W (HDC32 hdc, LPRECT32 lprc, LPCWSTR text, UINT32 style)
391 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
392 DrawStatusText32A (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 CreateStatusWindow32A (INT32 style, LPCSTR text, HWND32 parent, UINT32 wid)
416 return CreateWindow32A(STATUSCLASSNAME32A, text, style,
417 CW_USEDEFAULT32, CW_USEDEFAULT32,
418 CW_USEDEFAULT32, CW_USEDEFAULT32,
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 CreateStatusWindow32W (INT32 style, LPCWSTR text, HWND32 parent, UINT32 wid)
440 return CreateWindow32W(STATUSCLASSNAME32W, text, style,
441 CW_USEDEFAULT32, CW_USEDEFAULT32,
442 CW_USEDEFAULT32, CW_USEDEFAULT32,
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, INT32 x, INT32 y, INT32 cx, INT32 cy,
471 HWND32 parent, INT32 id, HINSTANCE32 inst,
472 HWND32 buddy, INT32 maxVal, INT32 minVal, INT32 curVal)
475 CreateWindow32A (UPDOWN_CLASS32A, 0, style, x, y, cx, cy,
476 parent, id, inst, 0);
478 SendMessage32A (hUD, UDM_SETBUDDY, buddy, 0);
479 SendMessage32A (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
480 SendMessage32A (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 (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
618 HINSTANCE32 hBMInst, UINT32 wBMID, LPCTBBUTTON lpButtons,
619 INT32 iNumButtons, INT32 dxButton, INT32 dyButton,
620 INT32 dxBitmap, INT32 dyBitmap, UINT32 uStructSize)
623 CreateWindowEx32A (0, TOOLBARCLASSNAME32A, "", style, 0, 0, 0, 0,
624 hwnd, (HMENU32)wID, 0, NULL);
628 SendMessage32A (hwndTB, TB_BUTTONSTRUCTSIZE,
629 (WPARAM32)uStructSize, 0);
631 /* set bitmap and button size */
632 if (hBMInst == HINST_COMMCTRL) {
634 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
636 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
640 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
642 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
647 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
648 MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
649 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
650 MAKELPARAM((WORD)dyButton, (WORD)dxButton));
654 tbab.hInst = hBMInst;
656 SendMessage32A (hwndTB, TB_ADDBITMAP,
657 (WPARAM32)nBitmaps, (LPARAM)&tbab);
660 SendMessage32A (hwndTB, TB_ADDBUTTONS32A,
661 (WPARAM32)iNumButtons, (LPARAM)lpButtons);
668 /***********************************************************************
669 * CreateMappedBitmap [COMCTL32.8]
679 * Success: handle to the new bitmap
684 CreateMappedBitmap (HINSTANCE32 hInstance, INT32 idBitmap, UINT32 wFlags,
685 LPCOLORMAP lpColorMap, INT32 iNumMaps)
689 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
690 UINT32 nSize, nColorTableSize;
692 INT32 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 = GetSysColor32 (COLOR_BTNTEXT);
706 internalColorMap[1].to = GetSysColor32 (COLOR_BTNSHADOW);
707 internalColorMap[2].to = GetSysColor32 (COLOR_BTNFACE);
708 internalColorMap[3].to = GetSysColor32 (COLOR_BTNHIGHLIGHT);
710 sysColorMap = (LPCOLORMAP)internalColorMap;
713 hRsrc = FindResource32A (hInstance, (LPSTR)idBitmap, RT_BITMAP32A);
716 hglb = LoadResource32 (hInstance, hRsrc);
719 lpBitmap = (LPBITMAPINFOHEADER)LockResource32 (hglb);
720 if (lpBitmap == NULL)
723 nColorTableSize = (1 << lpBitmap->biBitCount);
724 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
725 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc32 (GMEM_FIXED, nSize);
726 if (lpBitmapInfo == NULL)
728 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
730 pColorTable = (DWORD*)(((LPBYTE)lpBitmapInfo)+(UINT32)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 = (INT32)lpBitmapInfo->biWidth;
749 nHeight = (INT32)lpBitmapInfo->biHeight;
750 hdcScreen = GetDC32 ((HWND32)0);
751 hbm = CreateCompatibleBitmap32 (hdcScreen, nWidth, nHeight);
753 HDC32 hdcDst = CreateCompatibleDC32 (hdcScreen);
754 HBITMAP32 hbmOld = SelectObject32 (hdcDst, hbm);
755 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
756 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
757 StretchDIBits32 (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
758 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
760 SelectObject32 (hdcDst, hbmOld);
763 ReleaseDC32 ((HWND32)0, hdcScreen);
764 GlobalFree32 ((HGLOBAL32)lpBitmapInfo);
765 FreeResource32 (hglb);
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 (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
794 HINSTANCE32 hBMInst, UINT32 wBMID,
795 LPCOLDTBBUTTON lpButtons,INT32 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);