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 FIXME("Invalid Message 0x%x!\n", uMsg);
213 /***********************************************************************
214 * ShowHideMenuCtl [COMCTL32.3]
216 * Shows or hides controls and updates the corresponding menu item.
219 * hwnd [I] handle to the client window.
220 * uFlags [I] menu command id.
221 * lpInfo [I] pointer to an array of integers. (See NOTES.)
228 * The official documentation is incomplete!
229 * This is the correct documentation:
232 * Handle to the window that contains the menu and controls.
235 * Identifier of the menu item to receive or loose a check mark.
238 * The array of integers contains pairs of values. BOTH values of
239 * the first pair must be the handles to the application's main menu.
240 * Each subsequent pair consists of a menu id and control id.
244 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
248 TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
253 if (!(lpInfo[0]) || !(lpInfo[1]))
256 /* search for control */
257 lpMenuId = &lpInfo[2];
258 while (*lpMenuId != uFlags)
261 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
262 /* uncheck menu item */
263 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
267 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
271 /* check menu item */
272 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
276 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
284 /***********************************************************************
285 * GetEffectiveClientRect [COMCTL32.4]
288 * hwnd [I] handle to the client window.
289 * lpRect [O] pointer to the rectangle of the client window
290 * lpInfo [I] pointer to an array of integers (see NOTES)
296 * The official documentation is incomplete!
297 * This is the correct documentation:
300 * (will be written...)
304 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
310 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
311 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
313 GetClientRect (hwnd, lpRect);
321 hwndCtrl = GetDlgItem (hwnd, *lpRun);
322 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
323 TRACE("control id 0x%x\n", *lpRun);
324 GetWindowRect (hwndCtrl, &rcCtrl);
325 MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2);
326 SubtractRect (lpRect, lpRect, &rcCtrl);
333 /***********************************************************************
334 * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
336 * Draws text with borders, like in a status bar.
339 * hdc [I] handle to the window's display context
340 * lprc [I] pointer to a rectangle
341 * text [I] pointer to the text
342 * style [I] drawing style
348 * The style variable can have one of the following values:
349 * (will be written ...)
353 DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
356 UINT border = BDR_SUNKENOUTER;
358 if (style & SBT_POPOUT)
359 border = BDR_RAISEDOUTER;
360 else if (style & SBT_NOBORDERS)
363 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
367 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
369 DrawTextA (hdc, text, lstrlenA(text),
370 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
371 if (oldbkmode != TRANSPARENT)
372 SetBkMode(hdc, oldbkmode);
377 /***********************************************************************
378 * DrawStatusText32W [COMCTL32.28]
380 * Draws text with borders, like in a status bar.
383 * hdc [I] handle to the window's display context
384 * lprc [I] pointer to a rectangle
385 * text [I] pointer to the text
386 * style [I] drawing style
393 DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
395 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
396 DrawStatusTextA (hdc, lprc, p, style);
397 HeapFree (GetProcessHeap (), 0, p );
401 /***********************************************************************
402 * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21]
404 * Creates a status bar
407 * style [I] window style
408 * text [I] pointer to the window text
409 * parent [I] handle to the parent window
410 * wid [I] control id of the status bar
413 * Success: handle to the status window
418 CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid)
420 return CreateWindowA(STATUSCLASSNAMEA, text, style,
421 CW_USEDEFAULT, CW_USEDEFAULT,
422 CW_USEDEFAULT, CW_USEDEFAULT,
427 /***********************************************************************
428 * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
431 * style [I] window style
432 * text [I] pointer to the window text
433 * parent [I] handle to the parent window
434 * wid [I] control id of the status bar
437 * Success: handle to the status window
442 CreateStatusWindowW (INT style, LPCWSTR text, HWND parent, UINT wid)
444 return CreateWindowW(STATUSCLASSNAMEW, text, style,
445 CW_USEDEFAULT, CW_USEDEFAULT,
446 CW_USEDEFAULT, CW_USEDEFAULT,
451 /***********************************************************************
452 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
455 * style [I] window styles
456 * x [I] horizontal position of the control
457 * y [I] vertical position of the control
458 * cx [I] with of the control
459 * cy [I] height of the control
460 * parent [I] handle to the parent window
461 * id [I] the control's identifier
462 * inst [I] handle to the application's module instance
463 * buddy [I] handle to the buddy window, can be NULL
464 * maxVal [I] upper limit of the control
465 * minVal [I] lower limit of the control
466 * curVal [I] current value of the control
469 * Success: handle to the updown control
474 CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
475 HWND parent, INT id, HINSTANCE inst,
476 HWND buddy, INT maxVal, INT minVal, INT curVal)
479 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
480 parent, id, inst, 0);
482 SendMessageA (hUD, UDM_SETBUDDY, buddy, 0);
483 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
484 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
491 /***********************************************************************
492 * InitCommonControls [COMCTL32.17]
494 * Registers the common controls.
503 * This function is just a dummy.
504 * The Win95 controls are registered at the DLL's initialization.
505 * To register other controls InitCommonControlsEx() must be used.
509 InitCommonControls (void)
514 /***********************************************************************
515 * InitCommonControlsEx [COMCTL32.81]
517 * Registers the common controls.
520 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
527 * Only the additinal common controls are registered by this function.
528 * The Win95 controls are registered at the DLL's initialization.
532 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
539 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
542 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
544 for (cCount = 0; cCount < 32; cCount++) {
545 dwMask = 1 << cCount;
546 if (!(lpInitCtrls->dwICC & dwMask))
549 switch (lpInitCtrls->dwICC & dwMask) {
550 /* dummy initialization */
551 case ICC_ANIMATE_CLASS:
552 case ICC_BAR_CLASSES:
553 case ICC_LISTVIEW_CLASSES:
554 case ICC_TREEVIEW_CLASSES:
555 case ICC_TAB_CLASSES:
556 case ICC_UPDOWN_CLASS:
557 case ICC_PROGRESS_CLASS:
558 case ICC_HOTKEY_CLASS:
561 /* advanced classes - not included in Win95 */
562 case ICC_DATE_CLASSES:
563 MONTHCAL_Register ();
564 DATETIME_Register ();
567 case ICC_USEREX_CLASSES:
571 case ICC_COOL_CLASSES:
575 case ICC_INTERNET_CLASSES:
576 IPADDRESS_Register ();
579 case ICC_PAGESCROLLER_CLASS:
583 case ICC_NATIVEFNTCTL_CLASS:
584 NATIVEFONT_Register ();
588 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
597 /***********************************************************************
598 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
616 * Success: handle to the tool bar control
621 CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
622 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
623 INT iNumButtons, INT dxButton, INT dyButton,
624 INT dxBitmap, INT dyBitmap, UINT uStructSize)
627 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style, 0, 0, 0, 0,
628 hwnd, (HMENU)wID, 0, NULL);
632 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
633 (WPARAM)uStructSize, 0);
635 /* set bitmap and button size */
636 /*If CreateToolbarEx receive 0, windows set default values*/
642 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
643 MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
644 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
645 MAKELPARAM((WORD)dyButton, (WORD)dxButton));
651 tbab.hInst = hBMInst;
654 SendMessageA (hwndTB, TB_ADDBITMAP,
655 (WPARAM)nBitmaps, (LPARAM)&tbab);
659 SendMessageA (hwndTB, TB_ADDBUTTONSA,
660 (WPARAM)iNumButtons, (LPARAM)lpButtons);
667 /***********************************************************************
668 * CreateMappedBitmap [COMCTL32.8]
678 * Success: handle to the new bitmap
683 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
684 LPCOLORMAP lpColorMap, INT iNumMaps)
688 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
689 UINT nSize, nColorTableSize;
691 INT iColor, i, iMaps, nWidth, nHeight;
694 LPCOLORMAP sysColorMap;
695 COLORMAP internalColorMap[4] =
696 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
698 /* initialize pointer to colortable and default color table */
701 sysColorMap = lpColorMap;
704 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
705 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
706 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
707 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
709 sysColorMap = (LPCOLORMAP)internalColorMap;
712 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
715 hglb = LoadResource (hInstance, hRsrc);
718 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
719 if (lpBitmap == NULL)
722 nColorTableSize = (1 << lpBitmap->biBitCount);
723 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
724 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
725 if (lpBitmapInfo == NULL)
727 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
729 pColorTable = (DWORD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
731 for (iColor = 0; iColor < nColorTableSize; iColor++) {
732 for (i = 0; i < iMaps; i++) {
733 if (pColorTable[iColor] == sysColorMap[i].from) {
735 if (wFlags & CBS_MASKED) {
736 if (sysColorMap[i].to != COLOR_BTNTEXT)
737 pColorTable[iColor] = RGB(255, 255, 255);
741 pColorTable[iColor] = sysColorMap[i].to;
747 nWidth = (INT)lpBitmapInfo->biWidth;
748 nHeight = (INT)lpBitmapInfo->biHeight;
749 hdcScreen = GetDC ((HWND)0);
750 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
752 HDC hdcDst = CreateCompatibleDC (hdcScreen);
753 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
754 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
755 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
756 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
757 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
759 SelectObject (hdcDst, hbmOld);
762 ReleaseDC ((HWND)0, hdcScreen);
763 GlobalFree ((HGLOBAL)lpBitmapInfo);
770 /***********************************************************************
771 * CreateToolbar [COMCTL32.7] Creates a tool bar control
784 * Success: handle to the tool bar control
788 * Do not use this functions anymore. Use CreateToolbarEx instead.
792 CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
793 HINSTANCE hBMInst, UINT wBMID,
794 LPCOLDTBBUTTON lpButtons,INT iNumButtons)
796 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
797 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
798 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
802 /***********************************************************************
803 * DllGetVersion [COMCTL32.25]
805 * Retrieves version information of the 'COMCTL32.DLL'
808 * pdvi [O] pointer to version information structure.
812 * Failure: E_INVALIDARG
815 * Returns version of a comctl32.dll from IE4.01 SP1.
819 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
821 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
822 WARN("wrong DLLVERSIONINFO size from app");
826 pdvi->dwMajorVersion = 4;
827 pdvi->dwMinorVersion = 72;
828 pdvi->dwBuildNumber = 3110;
829 pdvi->dwPlatformID = 1;
831 TRACE("%lu.%lu.%lu.%lu\n",
832 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
833 pdvi->dwBuildNumber, pdvi->dwPlatformID);