2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998 Eric Kohl
18 #include "ipaddress.h"
21 #include "nativefont.h"
32 #include "debugtools.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("%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("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("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("Subclassing atom deleted: %p\n",
125 COMCTL32_aSubclass = (LPSTR)NULL;
127 /* destroy private heap */
128 HeapDestroy (COMCTL32_hHeap);
129 TRACE("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("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
180 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
181 /* menu was closed */
182 TRACE("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("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 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
209 /* WM_COMMAND is not invalid since it is documented
210 * in the windows api reference. So don't output
211 * any FIXME for WM_COMMAND
213 WARN("We don't care about the WM_COMMAND\n");
217 FIXME("Invalid Message 0x%x!\n", uMsg);
223 /***********************************************************************
224 * ShowHideMenuCtl [COMCTL32.3]
226 * Shows or hides controls and updates the corresponding menu item.
229 * hwnd [I] handle to the client window.
230 * uFlags [I] menu command id.
231 * lpInfo [I] pointer to an array of integers. (See NOTES.)
238 * The official documentation is incomplete!
239 * This is the correct documentation:
242 * Handle to the window that contains the menu and controls.
245 * Identifier of the menu item to receive or loose a check mark.
248 * The array of integers contains pairs of values. BOTH values of
249 * the first pair must be the handles to the application's main menu.
250 * Each subsequent pair consists of a menu id and control id.
254 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
258 TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
263 if (!(lpInfo[0]) || !(lpInfo[1]))
266 /* search for control */
267 lpMenuId = &lpInfo[2];
268 while (*lpMenuId != uFlags)
271 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
272 /* uncheck menu item */
273 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
277 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
281 /* check menu item */
282 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
286 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
294 /***********************************************************************
295 * GetEffectiveClientRect [COMCTL32.4]
298 * hwnd [I] handle to the client window.
299 * lpRect [O] pointer to the rectangle of the client window
300 * lpInfo [I] pointer to an array of integers (see NOTES)
306 * The official documentation is incomplete!
307 * This is the correct documentation:
310 * (will be written...)
314 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
320 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
321 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
323 GetClientRect (hwnd, lpRect);
331 hwndCtrl = GetDlgItem (hwnd, *lpRun);
332 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
333 TRACE("control id 0x%x\n", *lpRun);
334 GetWindowRect (hwndCtrl, &rcCtrl);
335 MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2);
336 SubtractRect (lpRect, lpRect, &rcCtrl);
343 /***********************************************************************
344 * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
346 * Draws text with borders, like in a status bar.
349 * hdc [I] handle to the window's display context
350 * lprc [I] pointer to a rectangle
351 * text [I] pointer to the text
352 * style [I] drawing style
358 * The style variable can have one of the following values:
359 * (will be written ...)
363 DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
366 UINT border = BDR_SUNKENOUTER;
368 if (style & SBT_POPOUT)
369 border = BDR_RAISEDOUTER;
370 else if (style & SBT_NOBORDERS)
373 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
377 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
379 DrawTextA (hdc, text, lstrlenA(text),
380 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
381 if (oldbkmode != TRANSPARENT)
382 SetBkMode(hdc, oldbkmode);
387 /***********************************************************************
388 * DrawStatusText32W [COMCTL32.28]
390 * Draws text with borders, like in a status bar.
393 * hdc [I] handle to the window's display context
394 * lprc [I] pointer to a rectangle
395 * text [I] pointer to the text
396 * style [I] drawing style
403 DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
405 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
406 DrawStatusTextA (hdc, lprc, p, style);
407 HeapFree (GetProcessHeap (), 0, p );
411 /***********************************************************************
412 * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21]
414 * Creates a status bar
417 * style [I] window style
418 * text [I] pointer to the window text
419 * parent [I] handle to the parent window
420 * wid [I] control id of the status bar
423 * Success: handle to the status window
428 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid)
430 return CreateWindowA(STATUSCLASSNAMEA, text, style,
431 CW_USEDEFAULT, CW_USEDEFAULT,
432 CW_USEDEFAULT, CW_USEDEFAULT,
437 /***********************************************************************
438 * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
441 * style [I] window style
442 * text [I] pointer to the window text
443 * parent [I] handle to the parent window
444 * wid [I] control id of the status bar
447 * Success: handle to the status window
452 CreateStatusWindowW (INT style, LPCWSTR text, HWND parent, UINT wid)
454 return CreateWindowW(STATUSCLASSNAMEW, text, style,
455 CW_USEDEFAULT, CW_USEDEFAULT,
456 CW_USEDEFAULT, CW_USEDEFAULT,
461 /***********************************************************************
462 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
465 * style [I] window styles
466 * x [I] horizontal position of the control
467 * y [I] vertical position of the control
468 * cx [I] with of the control
469 * cy [I] height of the control
470 * parent [I] handle to the parent window
471 * id [I] the control's identifier
472 * inst [I] handle to the application's module instance
473 * buddy [I] handle to the buddy window, can be NULL
474 * maxVal [I] upper limit of the control
475 * minVal [I] lower limit of the control
476 * curVal [I] current value of the control
479 * Success: handle to the updown control
484 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
485 HWND parent, INT id, HINSTANCE inst,
486 HWND buddy, INT maxVal, INT minVal, INT curVal)
489 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
490 parent, id, inst, 0);
492 SendMessageA (hUD, UDM_SETBUDDY, buddy, 0);
493 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
494 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
501 /***********************************************************************
502 * InitCommonControls [COMCTL32.17]
504 * Registers the common controls.
513 * This function is just a dummy.
514 * The Win95 controls are registered at the DLL's initialization.
515 * To register other controls InitCommonControlsEx() must be used.
519 InitCommonControls (void)
524 /***********************************************************************
525 * InitCommonControlsEx [COMCTL32.81]
527 * Registers the common controls.
530 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
537 * Only the additinal common controls are registered by this function.
538 * The Win95 controls are registered at the DLL's initialization.
542 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
549 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
552 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
554 for (cCount = 0; cCount < 32; cCount++) {
555 dwMask = 1 << cCount;
556 if (!(lpInitCtrls->dwICC & dwMask))
559 switch (lpInitCtrls->dwICC & dwMask) {
560 /* dummy initialization */
561 case ICC_ANIMATE_CLASS:
562 case ICC_BAR_CLASSES:
563 case ICC_LISTVIEW_CLASSES:
564 case ICC_TREEVIEW_CLASSES:
565 case ICC_TAB_CLASSES:
566 case ICC_UPDOWN_CLASS:
567 case ICC_PROGRESS_CLASS:
568 case ICC_HOTKEY_CLASS:
571 /* advanced classes - not included in Win95 */
572 case ICC_DATE_CLASSES:
573 MONTHCAL_Register ();
574 DATETIME_Register ();
577 case ICC_USEREX_CLASSES:
581 case ICC_COOL_CLASSES:
585 case ICC_INTERNET_CLASSES:
586 IPADDRESS_Register ();
589 case ICC_PAGESCROLLER_CLASS:
593 case ICC_NATIVEFNTCTL_CLASS:
594 NATIVEFONT_Register ();
598 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
607 /***********************************************************************
608 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
626 * Success: handle to the tool bar control
631 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
632 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
633 INT iNumButtons, INT dxButton, INT dyButton,
634 INT dxBitmap, INT dyBitmap, UINT uStructSize)
637 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style, 0, 0, 0, 0,
638 hwnd, (HMENU)wID, 0, NULL);
642 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
643 (WPARAM)uStructSize, 0);
645 /* set bitmap and button size */
646 /*If CreateToolbarEx receive 0, windows set default values*/
652 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
653 MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
654 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
655 MAKELPARAM((WORD)dyButton, (WORD)dxButton));
661 tbab.hInst = hBMInst;
664 SendMessageA (hwndTB, TB_ADDBITMAP,
665 (WPARAM)nBitmaps, (LPARAM)&tbab);
669 SendMessageA (hwndTB, TB_ADDBUTTONSA,
670 (WPARAM)iNumButtons, (LPARAM)lpButtons);
677 /***********************************************************************
678 * CreateMappedBitmap [COMCTL32.8]
688 * Success: handle to the new bitmap
693 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
694 LPCOLORMAP lpColorMap, INT iNumMaps)
698 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
699 UINT nSize, nColorTableSize;
700 RGBQUAD *pColorTable;
701 INT iColor, i, iMaps, nWidth, nHeight;
704 LPCOLORMAP sysColorMap;
706 COLORMAP internalColorMap[4] =
707 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
709 /* initialize pointer to colortable and default color table */
712 sysColorMap = lpColorMap;
715 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
716 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
717 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
718 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
720 sysColorMap = (LPCOLORMAP)internalColorMap;
723 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
726 hglb = LoadResource (hInstance, hRsrc);
729 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
730 if (lpBitmap == NULL)
733 nColorTableSize = (1 << lpBitmap->biBitCount);
734 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
735 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
736 if (lpBitmapInfo == NULL)
738 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
740 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
742 for (iColor = 0; iColor < nColorTableSize; iColor++) {
743 for (i = 0; i < iMaps; i++) {
744 cRef = RGB(pColorTable[iColor].rgbRed,
745 pColorTable[iColor].rgbGreen,
746 pColorTable[iColor].rgbBlue);
747 if ( cRef == sysColorMap[i].from) {
749 if (wFlags & CBS_MASKED) {
750 if (sysColorMap[i].to != COLOR_BTNTEXT)
751 pColorTable[iColor] = RGB(255, 255, 255);
755 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
756 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
757 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
762 nWidth = (INT)lpBitmapInfo->biWidth;
763 nHeight = (INT)lpBitmapInfo->biHeight;
764 hdcScreen = GetDC ((HWND)0);
765 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
767 HDC hdcDst = CreateCompatibleDC (hdcScreen);
768 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
769 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
770 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
771 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
772 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
774 SelectObject (hdcDst, hbmOld);
777 ReleaseDC ((HWND)0, hdcScreen);
778 GlobalFree ((HGLOBAL)lpBitmapInfo);
785 /***********************************************************************
786 * CreateToolbar [COMCTL32.7] Creates a tool bar control
799 * Success: handle to the tool bar control
803 * Do not use this functions anymore. Use CreateToolbarEx instead.
807 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
808 HINSTANCE hBMInst, UINT wBMID,
809 LPCOLDTBBUTTON lpButtons,INT iNumButtons)
811 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
812 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
813 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
817 /***********************************************************************
818 * DllGetVersion [COMCTL32.25]
820 * Retrieves version information of the 'COMCTL32.DLL'
823 * pdvi [O] pointer to version information structure.
827 * Failure: E_INVALIDARG
830 * Returns version of a comctl32.dll from IE4.01 SP1.
834 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
836 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
837 WARN("wrong DLLVERSIONINFO size from app");
841 pdvi->dwMajorVersion = 4;
842 pdvi->dwMinorVersion = 72;
843 pdvi->dwBuildNumber = 3110;
844 pdvi->dwPlatformID = 1;
846 TRACE("%lu.%lu.%lu.%lu\n",
847 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
848 pdvi->dwBuildNumber, pdvi->dwPlatformID);