Better context menus.
[wine.git] / dlls / comctl32 / commctrl.c
blobb6bfa1352fa6fdaff28fe6d70049e2657434b03a
1 /*
2 * Common controls functions
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998 Eric Kohl
7 */
9 #include "winbase.h"
10 #include "heap.h"
11 #include "commctrl.h"
12 #include "animate.h"
13 #include "comboex.h"
14 #include "datetime.h"
15 #include "flatsb.h"
16 #include "header.h"
17 #include "hotkey.h"
18 #include "ipaddress.h"
19 #include "listview.h"
20 #include "monthcal.h"
21 #include "nativefont.h"
22 #include "pager.h"
23 #include "progress.h"
24 #include "rebar.h"
25 #include "status.h"
26 #include "tab.h"
27 #include "toolbar.h"
28 #include "tooltips.h"
29 #include "trackbar.h"
30 #include "treeview.h"
31 #include "updown.h"
32 #include "debugtools.h"
33 #include "winerror.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'.
47 * PARAMS
48 * hinstDLL [I] handle to the 'dlls' instance
49 * fdwReason [I]
50 * lpvReserved [I] reserverd, must be NULL
52 * RETURNS
53 * Success: TRUE
54 * Failure: FALSE
57 BOOL WINAPI
58 COMCTL32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
60 TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
62 switch (fdwReason) {
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",
76 COMCTL32_aSubclass);
78 /* register all Win95 common control classes */
79 ANIMATE_Register ();
80 FLATSB_Register ();
81 HEADER_Register ();
82 HOTKEY_Register ();
83 LISTVIEW_Register ();
84 PROGRESS_Register ();
85 STATUS_Register ();
86 TAB_Register ();
87 TOOLBAR_Register ();
88 TOOLTIPS_Register ();
89 TRACKBAR_Register ();
90 TREEVIEW_Register ();
91 UPDOWN_Register ();
93 COMCTL32_dwProcessesAttached++;
94 break;
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 ();
110 PAGER_Unregister ();
111 PROGRESS_Unregister ();
112 REBAR_Unregister ();
113 STATUS_Unregister ();
114 TAB_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",
124 COMCTL32_aSubclass);
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;
132 break;
135 return TRUE;
139 /***********************************************************************
140 * MenuHelp [COMCTL32.2]
142 * PARAMS
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)
151 * RETURNS
152 * No return value
154 * NOTES
155 * The official documentation is incomplete!
156 * This is the correct documentation:
158 * uMsg:
159 * MenuHelp() does NOT handle WM_COMMAND messages! It only handes
160 * WM_MENUSELECT messages.
162 * lpwIDs:
163 * (will be written ...)
166 VOID WINAPI
167 MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
168 HINSTANCE hInst, HWND hwndStatus, LPUINT lpwIDs)
170 UINT uMenuID = 0;
172 if (!IsWindow (hwndStatus))
173 return;
175 switch (uMsg) {
176 case WM_MENUSELECT:
177 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
178 wParam, lParam);
180 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
181 /* menu was closed */
182 TRACE("menu was closed!\n");
183 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
185 else {
186 /* menu item was selected */
187 if (HIWORD(wParam) & MF_POPUP)
188 uMenuID = (UINT)*(lpwIDs+1);
189 else
190 uMenuID = (UINT)LOWORD(wParam);
191 TRACE("uMenuID = %u\n", uMenuID);
193 if (uMenuID) {
194 CHAR szText[256];
196 if (!LoadStringA (hInst, uMenuID, szText, 256))
197 szText[0] = '\0';
199 SendMessageA (hwndStatus, SB_SETTEXTA,
200 255 | SBT_NOBORDERS, (LPARAM)szText);
201 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
204 break;
206 case WM_COMMAND :
207 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
208 wParam, lParam);
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");
214 break;
216 default:
217 FIXME("Invalid Message 0x%x!\n", uMsg);
218 break;
223 /***********************************************************************
224 * ShowHideMenuCtl [COMCTL32.3]
226 * Shows or hides controls and updates the corresponding menu item.
228 * PARAMS
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.)
233 * RETURNS
234 * Success: TRUE
235 * Failure: FALSE
237 * NOTES
238 * The official documentation is incomplete!
239 * This is the correct documentation:
241 * hwnd
242 * Handle to the window that contains the menu and controls.
244 * uFlags
245 * Identifier of the menu item to receive or loose a check mark.
247 * lpInfo
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.
253 BOOL WINAPI
254 ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
256 LPINT lpMenuId;
258 TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
260 if (lpInfo == NULL)
261 return FALSE;
263 if (!(lpInfo[0]) || !(lpInfo[1]))
264 return FALSE;
266 /* search for control */
267 lpMenuId = &lpInfo[2];
268 while (*lpMenuId != uFlags)
269 lpMenuId += 2;
271 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
272 /* uncheck menu item */
273 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
275 /* hide control */
276 lpMenuId++;
277 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
278 SWP_HIDEWINDOW);
280 else {
281 /* check menu item */
282 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
284 /* show control */
285 lpMenuId++;
286 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
287 SWP_SHOWWINDOW);
290 return TRUE;
294 /***********************************************************************
295 * GetEffectiveClientRect [COMCTL32.4]
297 * PARAMS
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)
302 * RETURNS
303 * No return value.
305 * NOTES
306 * The official documentation is incomplete!
307 * This is the correct documentation:
309 * lpInfo
310 * (will be written...)
313 VOID WINAPI
314 GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
316 RECT rcCtrl;
317 INT *lpRun;
318 HWND hwndCtrl;
320 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
321 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
323 GetClientRect (hwnd, lpRect);
324 lpRun = lpInfo;
326 do {
327 lpRun += 2;
328 if (*lpRun == 0)
329 return;
330 lpRun++;
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);
338 lpRun++;
339 } while (*lpRun);
343 /***********************************************************************
344 * DrawStatusText32A [COMCTL32.5][COMCTL32.27]
346 * Draws text with borders, like in a status bar.
348 * PARAMS
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
354 * RETURNS
355 * No return value.
357 * NOTES
358 * The style variable can have one of the following values:
359 * (will be written ...)
362 VOID WINAPI
363 DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
365 RECT r = *lprc;
366 UINT border = BDR_SUNKENOUTER;
368 if (style & SBT_POPOUT)
369 border = BDR_RAISEDOUTER;
370 else if (style & SBT_NOBORDERS)
371 border = 0;
373 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
375 /* now draw text */
376 if (text) {
377 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
378 r.left += 3;
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.
392 * PARAMS
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
398 * RETURNS
399 * No return value.
402 VOID WINAPI
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
416 * PARAMS
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
422 * RETURNS
423 * Success: handle to the status window
424 * Failure: 0
427 HWND WINAPI
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,
433 parent, wid, 0, 0);
437 /***********************************************************************
438 * CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
440 * PARAMS
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
446 * RETURNS
447 * Success: handle to the status window
448 * Failure: 0
451 HWND WINAPI
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,
457 parent, wid, 0, 0);
461 /***********************************************************************
462 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
464 * PARAMS
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
478 * RETURNS
479 * Success: handle to the updown control
480 * Failure: 0
483 HWND WINAPI
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)
488 HWND hUD =
489 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
490 parent, id, inst, 0);
491 if (hUD) {
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));
497 return hUD;
501 /***********************************************************************
502 * InitCommonControls [COMCTL32.17]
504 * Registers the common controls.
506 * PARAMS
507 * No parameters.
509 * RETURNS
510 * No return values.
512 * NOTES
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.
518 VOID WINAPI
519 InitCommonControls (void)
524 /***********************************************************************
525 * InitCommonControlsEx [COMCTL32.81]
527 * Registers the common controls.
529 * PARAMS
530 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
532 * RETURNS
533 * Success: TRUE
534 * Failure: FALSE
536 * NOTES
537 * Only the additinal common controls are registered by this function.
538 * The Win95 controls are registered at the DLL's initialization.
541 BOOL WINAPI
542 InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
544 INT cCount;
545 DWORD dwMask;
547 if (!lpInitCtrls)
548 return FALSE;
549 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
550 return FALSE;
552 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
554 for (cCount = 0; cCount < 32; cCount++) {
555 dwMask = 1 << cCount;
556 if (!(lpInitCtrls->dwICC & dwMask))
557 continue;
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:
569 break;
571 /* advanced classes - not included in Win95 */
572 case ICC_DATE_CLASSES:
573 MONTHCAL_Register ();
574 DATETIME_Register ();
575 break;
577 case ICC_USEREX_CLASSES:
578 COMBOEX_Register ();
579 break;
581 case ICC_COOL_CLASSES:
582 REBAR_Register ();
583 break;
585 case ICC_INTERNET_CLASSES:
586 IPADDRESS_Register ();
587 break;
589 case ICC_PAGESCROLLER_CLASS:
590 PAGER_Register ();
591 break;
593 case ICC_NATIVEFNTCTL_CLASS:
594 NATIVEFONT_Register ();
595 break;
597 default:
598 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
599 break;
603 return TRUE;
607 /***********************************************************************
608 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
610 * PARAMS
611 * hwnd
612 * style
613 * wID
614 * nBitmaps
615 * hBMInst
616 * wBMID
617 * lpButtons
618 * iNumButtons
619 * dxButton
620 * dyButton
621 * dxBitmap
622 * dyBitmap
623 * uStructSize
625 * RETURNS
626 * Success: handle to the tool bar control
627 * Failure: 0
630 HWND WINAPI
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)
636 HWND hwndTB =
637 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style, 0, 0, 0, 0,
638 hwnd, (HMENU)wID, 0, NULL);
639 if(hwndTB) {
640 TBADDBITMAP tbab;
642 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
643 (WPARAM)uStructSize, 0);
645 /* set bitmap and button size */
646 /*If CreateToolbarEx receive 0, windows set default values*/
647 if (dyBitmap < 0)
648 dyBitmap = 16;
649 if (dxBitmap < 0)
650 dxBitmap = 16;
652 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
653 MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
654 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
655 MAKELPARAM((WORD)dyButton, (WORD)dxButton));
658 /* add bitmaps */
659 if (nBitmaps > 0)
661 tbab.hInst = hBMInst;
662 tbab.nID = wBMID;
664 SendMessageA (hwndTB, TB_ADDBITMAP,
665 (WPARAM)nBitmaps, (LPARAM)&tbab);
667 /* add buttons */
668 if(iNumButtons > 0)
669 SendMessageA (hwndTB, TB_ADDBUTTONSA,
670 (WPARAM)iNumButtons, (LPARAM)lpButtons);
673 return hwndTB;
677 /***********************************************************************
678 * CreateMappedBitmap [COMCTL32.8]
680 * PARAMS
681 * hInstance [I]
682 * idBitmap [I]
683 * wFlags [I]
684 * lpColorMap [I]
685 * iNumMaps [I]
687 * RETURNS
688 * Success: handle to the new bitmap
689 * Failure: 0
692 HBITMAP WINAPI
693 CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
694 LPCOLORMAP lpColorMap, INT iNumMaps)
696 HGLOBAL hglb;
697 HRSRC hRsrc;
698 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
699 UINT nSize, nColorTableSize;
700 RGBQUAD *pColorTable;
701 INT iColor, i, iMaps, nWidth, nHeight;
702 HDC hdcScreen;
703 HBITMAP hbm;
704 LPCOLORMAP sysColorMap;
705 COLORREF cRef;
706 COLORMAP internalColorMap[4] =
707 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
709 /* initialize pointer to colortable and default color table */
710 if (lpColorMap) {
711 iMaps = iNumMaps;
712 sysColorMap = lpColorMap;
714 else {
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);
719 iMaps = 4;
720 sysColorMap = (LPCOLORMAP)internalColorMap;
723 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
724 if (hRsrc == 0)
725 return 0;
726 hglb = LoadResource (hInstance, hRsrc);
727 if (hglb == 0)
728 return 0;
729 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
730 if (lpBitmap == NULL)
731 return 0;
733 nColorTableSize = (1 << lpBitmap->biBitCount);
734 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
735 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
736 if (lpBitmapInfo == NULL)
737 return 0;
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) {
748 #if 0
749 if (wFlags & CBS_MASKED) {
750 if (sysColorMap[i].to != COLOR_BTNTEXT)
751 pColorTable[iColor] = RGB(255, 255, 255);
753 else
754 #endif
755 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
756 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
757 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
758 break;
762 nWidth = (INT)lpBitmapInfo->biWidth;
763 nHeight = (INT)lpBitmapInfo->biHeight;
764 hdcScreen = GetDC ((HWND)0);
765 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
766 if (hbm) {
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,
773 SRCCOPY);
774 SelectObject (hdcDst, hbmOld);
775 DeleteDC (hdcDst);
777 ReleaseDC ((HWND)0, hdcScreen);
778 GlobalFree ((HGLOBAL)lpBitmapInfo);
779 FreeResource (hglb);
781 return hbm;
785 /***********************************************************************
786 * CreateToolbar [COMCTL32.7] Creates a tool bar control
788 * PARAMS
789 * hwnd
790 * style
791 * wID
792 * nBitmaps
793 * hBMInst
794 * wBMID
795 * lpButtons
796 * iNumButtons
798 * RETURNS
799 * Success: handle to the tool bar control
800 * Failure: 0
802 * NOTES
803 * Do not use this functions anymore. Use CreateToolbarEx instead.
806 HWND WINAPI
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'
822 * PARAMS
823 * pdvi [O] pointer to version information structure.
825 * RETURNS
826 * Success: S_OK
827 * Failure: E_INVALIDARG
829 * NOTES
830 * Returns version of a comctl32.dll from IE4.01 SP1.
833 HRESULT WINAPI
834 COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
836 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
837 WARN("wrong DLLVERSIONINFO size from app");
838 return E_INVALIDARG;
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);
850 return S_OK;
854 static int iTrackMax = 0;
855 static HWND TrackingList[10];
856 static UINT_PTR timer;
858 static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
859 int i = 0;
860 POINT pos;
861 HWND hwnd;
862 BOOL keepTracking = FALSE;
863 GetCursorPos(&pos);
864 hwnd = WindowFromPoint(pos);
865 /* Loop through the list of windows waiting on mouse exit */
866 while (i < iTrackMax) {
867 if (TrackingList[i] != hwnd)
868 PostMessageA(TrackingList[i], WM_MOUSELEAVE, 0, 0);
869 else
870 keepTracking = TRUE;
873 i++;
876 if (keepTracking) {
877 iTrackMax = 1;
878 TrackingList[0] = hwnd;
880 else
881 KillTimer(0, timer);
884 /***********************************************************************
885 * _TrackMouseEvent [COMCTL32.25]
887 * Requests notification of mouse events
889 * PARAMS
890 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
892 * RETURNS
893 * Success: non-zero
894 * Failure: zero
898 BOOL WINAPI
899 _TrackMouseEvent (TRACKMOUSEEVENT *ptme)
901 DWORD flags = 0;
902 int i;
903 BOOL cancel = 0, hover = 0, leave = 0, query = 0;
904 if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
905 WARN("wrong TRACKMOUSEEVENT size from app");
906 return E_INVALIDARG;
909 TRACE("%lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
911 flags = ptme->dwFlags;
912 if ( flags & TME_CANCEL ) {
913 cancel = 1;
914 flags &= ~ TME_CANCEL;
916 if ( flags & TME_HOVER ) {
917 hover = 1;
918 flags &= ~ TME_HOVER;
919 FIXME("TME_HOVER unimplemented\n" );
921 if ( flags & TME_LEAVE ) {
922 leave = 1;
923 flags &= ~ TME_LEAVE;
925 if ( flags & TME_QUERY ) {
926 query = 1;
927 flags &= ~ TME_QUERY;
928 FIXME("TME_QUERY unimplemented\n" );
931 if ( flags )
932 FIXME("Unknown flag(s) %ld\n", flags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_QUERY) );
934 if (leave) {
935 if (cancel) {
936 for (i = 0; i < iTrackMax; i++)
937 if (TrackingList[i] == ptme->hwndTrack)
938 TrackingList[i] = TrackingList[--iTrackMax];
940 else {
941 if (iTrackMax == sizeof (TrackingList) / sizeof *TrackingList)
942 return FALSE;
944 /* Add hwndTrack to the track list */
945 TrackingList[iTrackMax++] = ptme->hwndTrack;
946 if (!timer)
947 timer = SetTimer(0, 0, 50, TrackMouseEventProc);
951 return TRUE;