Release 980913
[wine/multimedia.git] / dlls / comctl32 / commctrl.c
blob0c6f00e0daee30629b5919f423a658a24f3389de
1 /*
2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998 Eric Kohl
7 */
9 #include "win.h"
10 #include "heap.h"
11 #include "commctrl.h"
12 #include "animate.h"
13 #include "comboex.h"
14 #include "header.h"
15 #include "hotkey.h"
16 #include "listview.h"
17 #include "pager.h"
18 #include "progress.h"
19 #include "rebar.h"
20 #include "status.h"
21 #include "tab.h"
22 #include "toolbar.h"
23 #include "tooltips.h"
24 #include "trackbar.h"
25 #include "treeview.h"
26 #include "updown.h"
27 #include "debug.h"
28 #include "winerror.h"
31 /***********************************************************************
32 * ComCtl32LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
34 * PARAMS
35 * hinstDLL [I]
36 * fdwReason [I]
37 * lpvReserved [I]
41 BOOL32 WINAPI
42 ComCtl32LibMain (HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
44 TRACE (commctrl, "%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
46 switch (fdwReason) {
47 case DLL_PROCESS_ATTACH:
48 ANIMATE_Register ();
49 HEADER_Register ();
50 HOTKEY_Register ();
51 LISTVIEW_Register ();
52 PROGRESS_Register ();
53 STATUS_Register ();
54 TAB_Register ();
55 TOOLBAR_Register ();
56 TOOLTIPS_Register ();
57 TRACKBAR_Register ();
58 TREEVIEW_Register ();
59 UPDOWN_Register ();
60 break;
63 return TRUE;
67 /***********************************************************************
68 * MenuHelp [COMCTL32.2]
70 * PARAMS
71 * uMsg
72 * wParam
73 * lParam
74 * hMainMenu
75 * hInst
76 * hwndStatus
77 * lpwIDs
79 * RETURNS
80 * None
82 * NOTES
83 * Some features are still missing because of incomplete WM_MENUSELECT
84 * messages (16->32 bit conversion).
87 VOID WINAPI
88 MenuHelp (UINT32 uMsg, WPARAM32 wParam, LPARAM lParam, HMENU32 hMainMenu,
89 HINSTANCE32 hInst, HWND32 hwndStatus, LPUINT32 lpwIDs)
91 char szStatusText[128];
93 if (!IsWindow32 (hwndStatus)) return;
95 switch (uMsg) {
96 case WM_MENUSELECT:
97 TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
98 wParam, lParam);
100 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
101 /* menu was closed */
102 SendMessage32A (hwndStatus, SB_SIMPLE, FALSE, 0);
104 else {
105 if (HIWORD(wParam) & MF_POPUP) {
106 FIXME (commctrl, "popup 0x%08x 0x%08lx\n", wParam, lParam);
108 szStatusText[0] = 0;
110 else {
111 TRACE (commctrl, "menu item selected!\n");
112 if (!LoadString32A (hInst, LOWORD(wParam), szStatusText, 128))
113 szStatusText[0] = 0;
115 SendMessage32A (hwndStatus, SB_SETTEXT32A, 255 | SBT_NOBORDERS,
116 (LPARAM)szStatusText);
117 SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0);
119 break;
121 default:
122 WARN (commctrl, "Invalid Message!\n");
123 break;
128 /***********************************************************************
129 * ShowHideMenuCtl [COMCTL32.3]
131 * Shows or hides controls and updates the corresponding menu item.
133 * PARAMS
134 * hwnd [I] handle to the client window.
135 * uFlags [I] menu command id.
136 * lpInfo [I] pointer to an array of integers. (See NOTES.)
138 * RETURNS
139 * Success: TRUE
140 * Failure: FALSE
142 * NOTES
143 * The official documentation is incomplete! This has been fixed.
145 * lpInfo
146 * The array of integers contains pairs of values. BOTH values of
147 * the first pair must be the handles to application's main menu.
148 * Each subsequent pair consists of a menu id and control id.
151 BOOL32 WINAPI
152 ShowHideMenuCtl (HWND32 hwnd, UINT32 uFlags, LPINT32 lpInfo)
154 LPINT32 lpMenuId;
156 TRACE (commctrl, "%x, %x, %p\n", hwnd, uFlags, lpInfo);
158 if (lpInfo == NULL)
159 return FALSE;
161 if (!(lpInfo[0]) || !(lpInfo[1]))
162 return FALSE;
164 /* search for control */
165 lpMenuId = &lpInfo[2];
166 while (*lpMenuId != uFlags)
167 lpMenuId += 2;
169 if (GetMenuState32 (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
170 /* uncheck menu item */
171 CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
173 /* hide control */
174 lpMenuId++;
175 SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
176 SWP_HIDEWINDOW);
178 else {
179 /* check menu item */
180 CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
182 /* show control */
183 lpMenuId++;
184 SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
185 SWP_SHOWWINDOW);
188 return TRUE;
192 /***********************************************************************
193 * GetEffectiveClientRect [COMCTL32.4]
195 * PARAMS
196 * hwnd [I] handle to the client window.
197 * lpRect [O] pointer to the rectangle of the client window
198 * lpInfo [I] pointer to an array of integers
200 * RETURNS
201 * None.
203 * NOTES
207 VOID WINAPI
208 GetEffectiveClientRect (HWND32 hwnd, LPRECT32 lpRect, LPINT32 lpInfo)
210 RECT32 rcCtrl;
211 INT32 *lpRun;
212 HWND32 hwndCtrl;
214 TRACE (commctrl, "(0x%08lx 0x%08lx 0x%08lx)\n",
215 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
217 GetClientRect32 (hwnd, lpRect);
218 lpRun = lpInfo;
220 do {
221 lpRun += 2;
222 if (*lpRun == 0)
223 return;
224 lpRun++;
225 hwndCtrl = GetDlgItem32 (hwnd, *lpRun);
226 if (GetWindowLong32A (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
227 TRACE (commctrl, "control id 0x%x\n", *lpRun);
228 GetWindowRect32 (hwndCtrl, &rcCtrl);
229 MapWindowPoints32 ((HWND32)0, hwnd, (LPPOINT32)&rcCtrl, 2);
230 SubtractRect32 (lpRect, lpRect, &rcCtrl);
232 lpRun++;
233 } while (*lpRun);
237 /***********************************************************************
238 * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
240 * Draws text with borders, like in a status bar.
242 * PARAMS
243 * hdc [I] handle to the window's display context
244 * lprc [I] pointer to a rectangle
245 * text [I] pointer to the text
246 * style [I]
249 VOID WINAPI
250 DrawStatusText32A (HDC32 hdc, LPRECT32 lprc, LPCSTR text, UINT32 style)
252 RECT32 r = *lprc;
253 UINT32 border = BDR_SUNKENOUTER;
255 if (style == SBT_POPOUT)
256 border = BDR_RAISEDOUTER;
257 else if (style == SBT_NOBORDERS)
258 border = 0;
260 DrawEdge32 (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
262 /* now draw text */
263 if (text) {
264 int oldbkmode = SetBkMode32 (hdc, TRANSPARENT);
265 r.left += 3;
266 DrawText32A (hdc, text, lstrlen32A(text),
267 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
268 if (oldbkmode != TRANSPARENT)
269 SetBkMode32(hdc, oldbkmode);
274 /***********************************************************************
275 * DrawStatusText32W [COMCTL32.28]
277 * Draws text with borders, like in a status bar.
279 * PARAMS
280 * hdc [I] handle to the window's display context
281 * lprc [I] pointer to a rectangle
282 * text [I] pointer to the text
283 * style [I]
286 VOID WINAPI
287 DrawStatusText32W (HDC32 hdc, LPRECT32 lprc, LPCWSTR text, UINT32 style)
289 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
290 DrawStatusText32A (hdc, lprc, p, style);
291 HeapFree (GetProcessHeap (), 0, p );
295 /***********************************************************************
296 * CreateStatusWindow32A [COMCTL32.6][COMCTL32.21]
298 HWND32 WINAPI
299 CreateStatusWindow32A (INT32 style, LPCSTR text, HWND32 parent, UINT32 wid)
301 return CreateWindow32A(STATUSCLASSNAME32A, text, style,
302 CW_USEDEFAULT32, CW_USEDEFAULT32,
303 CW_USEDEFAULT32, CW_USEDEFAULT32,
304 parent, wid, 0, 0);
308 /***********************************************************************
309 * CreateStatusWindow32W (COMCTL32.22)
311 HWND32 WINAPI CreateStatusWindow32W( INT32 style, LPCWSTR text, HWND32 parent,
312 UINT32 wid )
314 return CreateWindow32W((LPCWSTR)STATUSCLASSNAME32W, text, style,
315 CW_USEDEFAULT32, CW_USEDEFAULT32,
316 CW_USEDEFAULT32, CW_USEDEFAULT32,
317 parent, wid, 0, 0);
320 /***********************************************************************
321 * CreateUpDownControl (COMCTL32.16)
323 HWND32 WINAPI
324 CreateUpDownControl (DWORD style, INT32 x, INT32 y, INT32 cx, INT32 cy,
325 HWND32 parent, INT32 id, HINSTANCE32 inst,
326 HWND32 buddy, INT32 maxVal, INT32 minVal, INT32 curVal)
328 HWND32 hUD =
329 CreateWindow32A (UPDOWN_CLASS32A, 0, style, x, y, cx, cy,
330 parent, id, inst, 0);
331 if (hUD) {
332 SendMessage32A (hUD, UDM_SETBUDDY, buddy, 0);
333 SendMessage32A (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
334 SendMessage32A (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
337 return hUD;
341 /***********************************************************************
342 * InitCommonControls [COMCTL32.17]
344 * Registers the common controls.
346 * PARAMS
347 * None.
349 * NOTES
350 * This function is just a dummy.
351 * The Win95 controls are registered at the DLL's initialization.
352 * To register other controls InitCommonControlsEx must be used.
355 VOID WINAPI
356 InitCommonControls (VOID)
361 /***********************************************************************
362 * InitCommonControlsEx [COMCTL32.81]
364 * Registers the common controls.
366 * PARAMS
367 * lpInitCtrls [I] pointer to a INITCOMMONCONTROLS structure.
369 * NOTES
370 * Only the additinal common controls are registered by this function.
371 * The Win95 controls are registered at the DLL's initialization.
374 BOOL32 WINAPI
375 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
377 INT32 cCount;
378 DWORD dwMask;
380 TRACE(commctrl,"\n");
382 if (lpInitCtrls == NULL) return FALSE;
383 if (lpInitCtrls->dwSize < sizeof(INITCOMMONCONTROLSEX)) return FALSE;
385 for (cCount = 0; cCount < 32; cCount++) {
386 dwMask = 1 << cCount;
387 if (!(lpInitCtrls->dwICC & dwMask))
388 continue;
390 switch (lpInitCtrls->dwICC & dwMask) {
391 /* dummy initialization */
392 case ICC_ANIMATE_CLASS:
393 case ICC_BAR_CLASSES:
394 case ICC_LISTVIEW_CLASSES:
395 case ICC_TREEVIEW_CLASSES:
396 case ICC_TAB_CLASSES:
397 case ICC_UPDOWN_CLASS:
398 case ICC_PROGRESS_CLASS:
399 case ICC_HOTKEY_CLASS:
400 break;
402 /* advanced classes - not included in Win95 */
403 case ICC_DATE_CLASSES:
404 TRACE (commctrl, "No month calendar class implemented!\n");
405 TRACE (commctrl, "No date picker class implemented!\n");
406 TRACE (commctrl, "No time picker class implemented!\n");
407 UPDOWN_Register ();
408 break;
410 case ICC_USEREX_CLASSES:
411 COMBOEX_Register ();
412 break;
414 case ICC_COOL_CLASSES:
415 REBAR_Register ();
416 break;
418 case ICC_INTERNET_CLASSES:
419 TRACE (commctrl, "No IPAddress class implemented!\n");
420 break;
422 case ICC_PAGESCROLLER_CLASS:
423 PAGER_Register ();
424 break;
426 case ICC_NATIVEFNTCTL_CLASS:
427 TRACE (commctrl, "No native font class implemented!\n");
428 break;
430 default:
431 WARN (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask);
432 break;
436 return TRUE;
440 /***********************************************************************
441 * CreateToolbarEx [COMCTL32.32]
447 HWND32 WINAPI
448 CreateToolbarEx (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
449 HINSTANCE32 hBMInst, UINT32 wBMID, LPCTBBUTTON lpButtons,
450 INT32 iNumButtons, INT32 dxButton, INT32 dyButton,
451 INT32 dxBitmap, INT32 dyBitmap, UINT32 uStructSize)
453 HWND32 hwndTB =
454 CreateWindowEx32A (0, TOOLBARCLASSNAME32A, "", style, 0, 0, 0, 0,
455 hwnd, (HMENU32)wID, 0, NULL);
456 if(hwndTB) {
457 TBADDBITMAP tbab;
459 SendMessage32A (hwndTB, TB_BUTTONSTRUCTSIZE,
460 (WPARAM32)uStructSize, 0);
462 /* set bitmap and button size */
463 if (hBMInst == HINST_COMMCTRL) {
464 if (wBMID & 1) {
465 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
466 MAKELPARAM(26, 25));
467 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
468 MAKELPARAM(33, 32));
470 else {
471 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
472 MAKELPARAM(16, 15));
473 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
474 MAKELPARAM(23, 22));
477 else {
478 SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
479 MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
480 SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
481 MAKELPARAM((WORD)dyButton, (WORD)dxButton));
484 /* add bitmaps */
485 tbab.hInst = hBMInst;
486 tbab.nID = wBMID;
487 SendMessage32A (hwndTB, TB_ADDBITMAP,
488 (WPARAM32)nBitmaps, (LPARAM)&tbab);
490 /* add buttons */
491 SendMessage32A (hwndTB, TB_ADDBUTTONS32A,
492 (WPARAM32)iNumButtons, (LPARAM)lpButtons);
495 return hwndTB;
499 /***********************************************************************
500 * CreateMappedBitmap [COMCTL32.8]
502 * PARAMS
503 * hInstance
504 * idBitmap
505 * wFlags
506 * lpColorMap
507 * iNumMaps
509 * RETURNS
510 * Success: bitmap handle
511 * Failure: 0
514 HBITMAP32 WINAPI
515 CreateMappedBitmap (HINSTANCE32 hInstance, INT32 idBitmap, UINT32 wFlags,
516 LPCOLORMAP lpColorMap, INT32 iNumMaps)
518 HGLOBAL32 hglb;
519 HRSRC32 hRsrc;
520 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
521 UINT32 nSize, nColorTableSize;
522 DWORD *pColorTable;
523 INT32 iColor, i, iMaps, nWidth, nHeight;
524 HDC32 hdcScreen;
525 HBITMAP32 hbm;
526 LPCOLORMAP sysColorMap;
527 COLORMAP internalColorMap[4] =
528 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
530 /* initialize pointer to colortable and default color table */
531 if (lpColorMap) {
532 iMaps = iNumMaps;
533 sysColorMap = lpColorMap;
535 else {
536 internalColorMap[0].to = GetSysColor32 (COLOR_BTNTEXT);
537 internalColorMap[1].to = GetSysColor32 (COLOR_BTNSHADOW);
538 internalColorMap[2].to = GetSysColor32 (COLOR_BTNFACE);
539 internalColorMap[3].to = GetSysColor32 (COLOR_BTNHIGHLIGHT);
540 iMaps = 4;
541 sysColorMap = (LPCOLORMAP)internalColorMap;
544 hRsrc = FindResource32A (hInstance, (LPSTR)idBitmap, RT_BITMAP32A);
545 if (hRsrc == 0)
546 return 0;
547 hglb = LoadResource32 (hInstance, hRsrc);
548 if (hglb == 0)
549 return 0;
550 lpBitmap = (LPBITMAPINFOHEADER)LockResource32 (hglb);
551 if (lpBitmap == NULL)
552 return 0;
554 nColorTableSize = (1 << lpBitmap->biBitCount);
555 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
556 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc32 (GMEM_FIXED, nSize);
557 if (lpBitmapInfo == NULL)
558 return 0;
559 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
561 pColorTable = (DWORD*)(((LPBYTE)lpBitmapInfo)+(UINT32)lpBitmapInfo->biSize);
563 for (iColor = 0; iColor < nColorTableSize; iColor++) {
564 for (i = 0; i < iMaps; i++) {
565 if (pColorTable[iColor] == sysColorMap[i].from) {
566 #if 0
567 if (wFlags & CBS_MASKED) {
568 if (sysColorMap[i].to != COLOR_BTNTEXT)
569 pColorTable[iColor] = RGB(255, 255, 255);
571 else
572 #endif
573 pColorTable[iColor] = sysColorMap[i].to;
574 break;
579 nWidth = (INT32)lpBitmapInfo->biWidth;
580 nHeight = (INT32)lpBitmapInfo->biHeight;
581 hdcScreen = GetDC32 ((HWND32)0);
582 hbm = CreateCompatibleBitmap32 (hdcScreen, nWidth, nHeight);
583 if (hbm) {
584 HDC32 hdcDst = CreateCompatibleDC32 (hdcScreen);
585 HBITMAP32 hbmOld = SelectObject32 (hdcDst, hbm);
586 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
587 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
588 StretchDIBits32 (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
589 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
590 SRCCOPY);
591 SelectObject32 (hdcDst, hbmOld);
592 DeleteDC32 (hdcDst);
594 ReleaseDC32 ((HWND32)0, hdcScreen);
595 GlobalFree32 ((HGLOBAL32)lpBitmapInfo);
596 FreeResource32 (hglb);
598 return hbm;
602 /***********************************************************************
603 * CreateToolbar [COMCTL32.7]
609 HWND32 WINAPI
610 CreateToolbar (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
611 HINSTANCE32 hBMInst, UINT32 wBMID,
612 LPCOLDTBBUTTON lpButtons,INT32 iNumButtons)
614 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
615 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
616 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
620 /***********************************************************************
621 * DllGetVersion [COMCTL32.25]
623 * Retrieves version information of the 'COMCTL32.DLL'
625 * PARAMS
626 * pdvi [O] pointer to version information structure.
628 * REURNS
629 * Success: S_OK
630 * Failure: E_INVALIDARG
633 HRESULT WINAPI
634 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
636 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
637 WARN(ver, "wrong DLLVERSIONINFO size from app");
638 return E_INVALIDARG;
641 pdvi->dwMajorVersion = 4;
642 pdvi->dwMinorVersion = 72;
643 pdvi->dwBuildNumber = 2106;
644 pdvi->dwPlatformID = 1;
646 TRACE (commctrl, "%lu.%lu.%lu.%lu\n",
647 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
648 pdvi->dwBuildNumber, pdvi->dwPlatformID);
650 return S_OK;