source: trunk/src/comctl32/comctl32.c@ 7342

Last change on this file since 7342 was 7342, checked in by sandervl, 24 years ago

removed unnecessary changes

File size: 33.0 KB
Line 
1/*
2 * Common controls functions
3 *
4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998,2000 Eric Kohl
6 *
7 */
8
9#ifdef __WIN32OS2__
10#include <odin.h>
11#endif
12
13#include <string.h>
14#include "winbase.h"
15#include "heap.h"
16#include "commctrl.h"
17#include "debugtools.h"
18#include "winerror.h"
19#include "shlwapi.h"
20#include "comctl32.h"
21
22DEFAULT_DEBUG_CHANNEL(commctrl);
23
24#ifndef __WIN32OS2__
25extern void ANIMATE_Register(void);
26extern void ANIMATE_Unregister(void);
27extern void COMBOEX_Register(void);
28extern void COMBOEX_Unregister(void);
29extern void DATETIME_Register(void);
30extern void DATETIME_Unregister(void);
31extern void FLATSB_Register(void);
32extern void FLATSB_Unregister(void);
33extern void HEADER_Register(void);
34extern void HEADER_Unregister(void);
35extern void HOTKEY_Register(void);
36extern void HOTKEY_Unregister(void);
37extern void IPADDRESS_Register(void);
38extern void IPADDRESS_Unregister(void);
39extern void LISTVIEW_Register(void);
40extern void LISTVIEW_Unregister(void);
41extern void MONTHCAL_Register(void);
42extern void MONTHCAL_Unregister(void);
43extern void NATIVEFONT_Register(void);
44extern void NATIVEFONT_Unregister(void);
45extern void PAGER_Register(void);
46extern void PAGER_Unregister(void);
47extern void PROGRESS_Register(void);
48extern void PROGRESS_Unregister(void);
49extern void REBAR_Register(void);
50extern void REBAR_Unregister(void);
51extern void STATUS_Register(void);
52extern void STATUS_Unregister(void);
53extern void TAB_Register(void);
54extern void TAB_Unregister(void);
55extern void TOOLBAR_Register(void);
56extern void TOOLBAR_Unregister(void);
57extern void TOOLTIPS_Register(void);
58extern void TOOLTIPS_Unregister(void);
59extern void TRACKBAR_Register(void);
60extern void TRACKBAR_Unregister(void);
61extern void TREEVIEW_Register(void);
62extern void TREEVIEW_Unregister(void);
63extern void UPDOWN_Register(void);
64extern void UPDOWN_Unregister(void);
65#endif
66
67HANDLE COMCTL32_hHeap = (HANDLE)NULL;
68LPSTR COMCTL32_aSubclass = (LPSTR)NULL;
69HMODULE COMCTL32_hModule = 0;
70LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
71HBRUSH COMCTL32_hPattern55AABrush = (HANDLE)NULL;
72
73static HBITMAP COMCTL32_hPattern55AABitmap = (HANDLE)NULL;
74
75static const WORD wPattern55AA[] =
76{
77 0x5555, 0xaaaa, 0x5555, 0xaaaa,
78 0x5555, 0xaaaa, 0x5555, 0xaaaa
79};
80
81
82/***********************************************************************
83 * COMCTL32_LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
84 *
85 * PARAMS
86 * hinstDLL [I] handle to the 'dlls' instance
87 * fdwReason [I]
88 * lpvReserved [I] reserverd, must be NULL
89 *
90 * RETURNS
91 * Success: TRUE
92 * Failure: FALSE
93 */
94
95BOOL WINAPI
96COMCTL32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
97{
98 TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
99
100 switch (fdwReason) {
101 case DLL_PROCESS_ATTACH:
102 COMCTL32_hModule = (HMODULE)hinstDLL;
103
104 /* create private heap */
105 COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
106 TRACE("Heap created: 0x%x\n", COMCTL32_hHeap);
107
108 /* add global subclassing atom (used by 'tooltip' and 'updown') */
109 COMCTL32_aSubclass = (LPSTR)(DWORD)GlobalAddAtomA ("CC32SubclassInfo");
110 TRACE("Subclassing atom added: %p\n", COMCTL32_aSubclass);
111
112 /* create local pattern brush */
113 COMCTL32_hPattern55AABitmap = CreateBitmap (8, 8, 1, 1, wPattern55AA);
114 COMCTL32_hPattern55AABrush = CreatePatternBrush (COMCTL32_hPattern55AABitmap);
115
116 /* register all Win95 common control classes */
117 ANIMATE_Register ();
118 FLATSB_Register ();
119 HEADER_Register ();
120 HOTKEY_Register ();
121 LISTVIEW_Register ();
122 PROGRESS_Register ();
123 STATUS_Register ();
124 TAB_Register ();
125 TOOLBAR_Register ();
126 TOOLTIPS_Register ();
127 TRACKBAR_Register ();
128 TREEVIEW_Register ();
129 UPDOWN_Register ();
130 break;
131
132 case DLL_PROCESS_DETACH:
133 /* unregister all common control classes */
134 ANIMATE_Unregister ();
135 COMBOEX_Unregister ();
136 DATETIME_Unregister ();
137 FLATSB_Unregister ();
138 HEADER_Unregister ();
139 HOTKEY_Unregister ();
140 IPADDRESS_Unregister ();
141 LISTVIEW_Unregister ();
142 MONTHCAL_Unregister ();
143 NATIVEFONT_Unregister ();
144 PAGER_Unregister ();
145 PROGRESS_Unregister ();
146 REBAR_Unregister ();
147 STATUS_Unregister ();
148 TAB_Unregister ();
149 TOOLBAR_Unregister ();
150 TOOLTIPS_Unregister ();
151 TRACKBAR_Unregister ();
152 TREEVIEW_Unregister ();
153 UPDOWN_Unregister ();
154
155 /* delete local pattern brush */
156 DeleteObject (COMCTL32_hPattern55AABrush);
157 COMCTL32_hPattern55AABrush = (HANDLE)NULL;
158 DeleteObject (COMCTL32_hPattern55AABitmap);
159 COMCTL32_hPattern55AABitmap = (HANDLE)NULL;
160
161 /* delete global subclassing atom */
162 GlobalDeleteAtom (LOWORD(COMCTL32_aSubclass));
163 TRACE("Subclassing atom deleted: %p\n", COMCTL32_aSubclass);
164 COMCTL32_aSubclass = (LPSTR)NULL;
165
166 /* destroy private heap */
167 HeapDestroy (COMCTL32_hHeap);
168 TRACE("Heap destroyed: 0x%x\n", COMCTL32_hHeap);
169 COMCTL32_hHeap = (HANDLE)NULL;
170 break;
171 }
172
173 return TRUE;
174}
175
176
177/***********************************************************************
178 * MenuHelp [COMCTL32.2]
179 *
180 * PARAMS
181 * uMsg [I] message (WM_MENUSELECT) (see NOTES)
182 * wParam [I] wParam of the message uMsg
183 * lParam [I] lParam of the message uMsg
184 * hMainMenu [I] handle to the application's main menu
185 * hInst [I] handle to the module that contains string resources
186 * hwndStatus [I] handle to the status bar window
187 * lpwIDs [I] pointer to an array of integers (see NOTES)
188 *
189 * RETURNS
190 * No return value
191 *
192 * NOTES
193 * The official documentation is incomplete!
194 * This is the correct documentation:
195 *
196 * uMsg:
197 * MenuHelp() does NOT handle WM_COMMAND messages! It only handles
198 * WM_MENUSELECT messages.
199 *
200 * lpwIDs:
201 * (will be written ...)
202 */
203
204VOID WINAPI
205MenuHelp (UINT uMsg, WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
206 HINSTANCE hInst, HWND hwndStatus, LPUINT lpwIDs)
207{
208 UINT uMenuID = 0;
209
210 if (!IsWindow (hwndStatus))
211 return;
212
213 switch (uMsg) {
214 case WM_MENUSELECT:
215 TRACE("WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
216 wParam, lParam);
217
218 if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
219 /* menu was closed */
220 TRACE("menu was closed!\n");
221 SendMessageA (hwndStatus, SB_SIMPLE, FALSE, 0);
222 }
223 else {
224 /* menu item was selected */
225 if (HIWORD(wParam) & MF_POPUP)
226 uMenuID = (UINT)*(lpwIDs+1);
227 else
228 uMenuID = (UINT)LOWORD(wParam);
229 TRACE("uMenuID = %u\n", uMenuID);
230
231 if (uMenuID) {
232 CHAR szText[256];
233
234 if (!LoadStringA (hInst, uMenuID, szText, 256))
235 szText[0] = '\0';
236
237 SendMessageA (hwndStatus, SB_SETTEXTA,
238 255 | SBT_NOBORDERS, (LPARAM)szText);
239 SendMessageA (hwndStatus, SB_SIMPLE, TRUE, 0);
240 }
241 }
242 break;
243
244 case WM_COMMAND :
245 TRACE("WM_COMMAND wParam=0x%X lParam=0x%lX\n",
246 wParam, lParam);
247 /* WM_COMMAND is not invalid since it is documented
248 * in the windows api reference. So don't output
249 * any FIXME for WM_COMMAND
250 */
251 WARN("We don't care about the WM_COMMAND\n");
252 break;
253
254 default:
255 FIXME("Invalid Message 0x%x!\n", uMsg);
256 break;
257 }
258}
259
260
261/***********************************************************************
262 * ShowHideMenuCtl [COMCTL32.3]
263 *
264 * Shows or hides controls and updates the corresponding menu item.
265 *
266 * PARAMS
267 * hwnd [I] handle to the client window.
268 * uFlags [I] menu command id.
269 * lpInfo [I] pointer to an array of integers. (See NOTES.)
270 *
271 * RETURNS
272 * Success: TRUE
273 * Failure: FALSE
274 *
275 * NOTES
276 * The official documentation is incomplete!
277 * This is the correct documentation:
278 *
279 * hwnd
280 * Handle to the window that contains the menu and controls.
281 *
282 * uFlags
283 * Identifier of the menu item to receive or loose a check mark.
284 *
285 * lpInfo
286 * The array of integers contains pairs of values. BOTH values of
287 * the first pair must be the handles to the application's main menu.
288 * Each subsequent pair consists of a menu id and control id.
289 */
290
291BOOL WINAPI
292ShowHideMenuCtl (HWND hwnd, UINT uFlags, LPINT lpInfo)
293{
294 LPINT lpMenuId;
295
296 TRACE("%x, %x, %p\n", hwnd, uFlags, lpInfo);
297
298 if (lpInfo == NULL)
299 return FALSE;
300
301 if (!(lpInfo[0]) || !(lpInfo[1]))
302 return FALSE;
303
304 /* search for control */
305 lpMenuId = &lpInfo[2];
306 while (*lpMenuId != uFlags)
307 lpMenuId += 2;
308
309 if (GetMenuState (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
310 /* uncheck menu item */
311 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
312
313 /* hide control */
314 lpMenuId++;
315 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
316 SWP_HIDEWINDOW);
317 }
318 else {
319 /* check menu item */
320 CheckMenuItem (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
321
322 /* show control */
323 lpMenuId++;
324 SetWindowPos (GetDlgItem (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
325 SWP_SHOWWINDOW);
326 }
327
328 return TRUE;
329}
330
331
332/***********************************************************************
333 * GetEffectiveClientRect [COMCTL32.4]
334 *
335 * PARAMS
336 * hwnd [I] handle to the client window.
337 * lpRect [O] pointer to the rectangle of the client window
338 * lpInfo [I] pointer to an array of integers (see NOTES)
339 *
340 * RETURNS
341 * No return value.
342 *
343 * NOTES
344 * The official documentation is incomplete!
345 * This is the correct documentation:
346 *
347 * lpInfo
348 * (will be written...)
349 */
350
351VOID WINAPI
352GetEffectiveClientRect (HWND hwnd, LPRECT lpRect, LPINT lpInfo)
353{
354 RECT rcCtrl;
355 INT *lpRun;
356 HWND hwndCtrl;
357
358 TRACE("(0x%08lx 0x%08lx 0x%08lx)\n",
359 (DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
360
361 GetClientRect (hwnd, lpRect);
362 lpRun = lpInfo;
363
364 do {
365 lpRun += 2;
366 if (*lpRun == 0)
367 return;
368 lpRun++;
369 hwndCtrl = GetDlgItem (hwnd, *lpRun);
370 if (GetWindowLongA (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
371 TRACE("control id 0x%x\n", *lpRun);
372 GetWindowRect (hwndCtrl, &rcCtrl);
373 MapWindowPoints ((HWND)0, hwnd, (LPPOINT)&rcCtrl, 2);
374 SubtractRect (lpRect, lpRect, &rcCtrl);
375 }
376 lpRun++;
377 } while (*lpRun);
378}
379
380
381/***********************************************************************
382 * DrawStatusTextA [COMCTL32.5][COMCTL32.27]
383 *
384 * Draws text with borders, like in a status bar.
385 *
386 * PARAMS
387 * hdc [I] handle to the window's display context
388 * lprc [I] pointer to a rectangle
389 * text [I] pointer to the text
390 * style [I] drawing style
391 *
392 * RETURNS
393 * No return value.
394 *
395 * NOTES
396 * The style variable can have one of the following values:
397 * (will be written ...)
398 */
399
400VOID WINAPI
401DrawStatusTextA (HDC hdc, LPRECT lprc, LPCSTR text, UINT style)
402{
403 RECT r = *lprc;
404 UINT border = BDR_SUNKENOUTER;
405
406 if (style & SBT_POPOUT)
407 border = BDR_RAISEDOUTER;
408 else if (style & SBT_NOBORDERS)
409 border = 0;
410
411 DrawEdge (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
412
413 /* now draw text */
414 if (text) {
415 int oldbkmode = SetBkMode (hdc, TRANSPARENT);
416 r.left += 3;
417 DrawTextA (hdc, text, lstrlenA(text),
418 &r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
419 if (oldbkmode != TRANSPARENT)
420 SetBkMode(hdc, oldbkmode);
421 }
422}
423
424
425/***********************************************************************
426 * DrawStatusTextW [COMCTL32.28]
427 *
428 * Draws text with borders, like in a status bar.
429 *
430 * PARAMS
431 * hdc [I] handle to the window's display context
432 * lprc [I] pointer to a rectangle
433 * text [I] pointer to the text
434 * style [I] drawing style
435 *
436 * RETURNS
437 * No return value.
438 */
439
440VOID WINAPI
441DrawStatusTextW (HDC hdc, LPRECT lprc, LPCWSTR text, UINT style)
442{
443 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
444 DrawStatusTextA (hdc, lprc, p, style);
445 HeapFree (GetProcessHeap (), 0, p );
446}
447
448
449/***********************************************************************
450 * CreateStatusWindowA [COMCTL32.6][COMCTL32.21]
451 *
452 * Creates a status bar
453 *
454 * PARAMS
455 * style [I] window style
456 * text [I] pointer to the window text
457 * parent [I] handle to the parent window
458 * wid [I] control id of the status bar
459 *
460 * RETURNS
461 * Success: handle to the status window
462 * Failure: 0
463 */
464
465HWND WINAPI
466CreateStatusWindowA (INT style, LPCSTR text, HWND parent, UINT wid)
467{
468 return CreateWindowA(STATUSCLASSNAMEA, text, style,
469 CW_USEDEFAULT, CW_USEDEFAULT,
470 CW_USEDEFAULT, CW_USEDEFAULT,
471 parent, wid, 0, 0);
472}
473
474
475/***********************************************************************
476 * CreateStatusWindowW [COMCTL32.22] Creates a status bar control
477 *
478 * PARAMS
479 * style [I] window style
480 * text [I] pointer to the window text
481 * parent [I] handle to the parent window
482 * wid [I] control id of the status bar
483 *
484 * RETURNS
485 * Success: handle to the status window
486 * Failure: 0
487 */
488
489HWND WINAPI
490CreateStatusWindowW (INT style, LPCWSTR text, HWND parent, UINT wid)
491{
492 return CreateWindowW(STATUSCLASSNAMEW, text, style,
493 CW_USEDEFAULT, CW_USEDEFAULT,
494 CW_USEDEFAULT, CW_USEDEFAULT,
495 parent, wid, 0, 0);
496}
497
498
499/***********************************************************************
500 * CreateUpDownControl [COMCTL32.16] Creates an up-down control
501 *
502 * PARAMS
503 * style [I] window styles
504 * x [I] horizontal position of the control
505 * y [I] vertical position of the control
506 * cx [I] with of the control
507 * cy [I] height of the control
508 * parent [I] handle to the parent window
509 * id [I] the control's identifier
510 * inst [I] handle to the application's module instance
511 * buddy [I] handle to the buddy window, can be NULL
512 * maxVal [I] upper limit of the control
513 * minVal [I] lower limit of the control
514 * curVal [I] current value of the control
515 *
516 * RETURNS
517 * Success: handle to the updown control
518 * Failure: 0
519 */
520
521HWND WINAPI
522CreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
523 HWND parent, INT id, HINSTANCE inst,
524 HWND buddy, INT maxVal, INT minVal, INT curVal)
525{
526 HWND hUD =
527 CreateWindowA (UPDOWN_CLASSA, 0, style, x, y, cx, cy,
528 parent, id, inst, 0);
529 if (hUD) {
530 SendMessageA (hUD, UDM_SETBUDDY, buddy, 0);
531 SendMessageA (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
532 SendMessageA (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
533 }
534
535 return hUD;
536}
537
538
539/***********************************************************************
540 * InitCommonControls [COMCTL32.17]
541 *
542 * Registers the common controls.
543 *
544 * PARAMS
545 * No parameters.
546 *
547 * RETURNS
548 * No return values.
549 *
550 * NOTES
551 * This function is just a dummy.
552 * The Win95 controls are registered at the DLL's initialization.
553 * To register other controls InitCommonControlsEx() must be used.
554 */
555
556VOID WINAPI
557InitCommonControls (void)
558{
559}
560
561
562/***********************************************************************
563 * InitCommonControlsEx [COMCTL32.81]
564 *
565 * Registers the common controls.
566 *
567 * PARAMS
568 * lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
569 *
570 * RETURNS
571 * Success: TRUE
572 * Failure: FALSE
573 *
574 * NOTES
575 * Only the additional common controls are registered by this function.
576 * The Win95 controls are registered at the DLL's initialization.
577 */
578
579BOOL WINAPI
580InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
581{
582 INT cCount;
583 DWORD dwMask;
584
585 if (!lpInitCtrls)
586 return FALSE;
587 if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
588 return FALSE;
589
590 TRACE("(0x%08lx)\n", lpInitCtrls->dwICC);
591
592 for (cCount = 0; cCount < 32; cCount++) {
593 dwMask = 1 << cCount;
594 if (!(lpInitCtrls->dwICC & dwMask))
595 continue;
596
597 switch (lpInitCtrls->dwICC & dwMask) {
598 /* dummy initialization */
599 case ICC_ANIMATE_CLASS:
600 case ICC_BAR_CLASSES:
601 case ICC_LISTVIEW_CLASSES:
602 case ICC_TREEVIEW_CLASSES:
603 case ICC_TAB_CLASSES:
604 case ICC_UPDOWN_CLASS:
605 case ICC_PROGRESS_CLASS:
606 case ICC_HOTKEY_CLASS:
607 break;
608
609 /* advanced classes - not included in Win95 */
610 case ICC_DATE_CLASSES:
611 MONTHCAL_Register ();
612 DATETIME_Register ();
613 break;
614
615 case ICC_USEREX_CLASSES:
616 COMBOEX_Register ();
617 break;
618
619 case ICC_COOL_CLASSES:
620 REBAR_Register ();
621 break;
622
623 case ICC_INTERNET_CLASSES:
624 IPADDRESS_Register ();
625 break;
626
627 case ICC_PAGESCROLLER_CLASS:
628 PAGER_Register ();
629 break;
630
631 case ICC_NATIVEFNTCTL_CLASS:
632 NATIVEFONT_Register ();
633 break;
634
635 default:
636 FIXME("Unknown class! dwICC=0x%lX\n", dwMask);
637 break;
638 }
639 }
640
641 return TRUE;
642}
643
644
645/***********************************************************************
646 * CreateToolbarEx [COMCTL32.32] Creates a tool bar window
647 *
648 * PARAMS
649 * hwnd
650 * style
651 * wID
652 * nBitmaps
653 * hBMInst
654 * wBMID
655 * lpButtons
656 * iNumButtons
657 * dxButton
658 * dyButton
659 * dxBitmap
660 * dyBitmap
661 * uStructSize
662 *
663 * RETURNS
664 * Success: handle to the tool bar control
665 * Failure: 0
666 */
667
668HWND WINAPI
669CreateToolbarEx (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
670 HINSTANCE hBMInst, UINT wBMID, LPCTBBUTTON lpButtons,
671 INT iNumButtons, INT dxButton, INT dyButton,
672 INT dxBitmap, INT dyBitmap, UINT uStructSize)
673{
674 HWND hwndTB;
675
676 /* If not position is specified then put it at the top */
677 if ((style & CCS_BOTTOM) == 0) {
678 style|=CCS_TOP;
679 }
680
681 hwndTB =
682 CreateWindowExA (0, TOOLBARCLASSNAMEA, "", style|WS_CHILD, 0, 0, 0, 0,
683 hwnd, (HMENU)wID, 0, NULL);
684 if(hwndTB) {
685 TBADDBITMAP tbab;
686
687 SendMessageA (hwndTB, TB_BUTTONSTRUCTSIZE,
688 (WPARAM)uStructSize, 0);
689
690 /* set bitmap and button size */
691 /*If CreateToolbarEx receives 0, windows sets default values*/
692 if (dxBitmap <= 0)
693 dxBitmap = 16;
694 if (dyBitmap <= 0)
695 dyBitmap = 15;
696 SendMessageA (hwndTB, TB_SETBITMAPSIZE, 0,
697 MAKELPARAM((WORD)dxBitmap, (WORD)dyBitmap));
698
699 if (dxButton <= 0)
700 dxButton = 24;
701 if (dyButton <= 0)
702 dyButton = 22;
703 SendMessageA (hwndTB, TB_SETBUTTONSIZE, 0,
704 MAKELPARAM((WORD)dxButton, (WORD)dyButton));
705
706
707 /* add bitmaps */
708 if (nBitmaps > 0)
709 {
710 tbab.hInst = hBMInst;
711 tbab.nID = wBMID;
712
713 SendMessageA (hwndTB, TB_ADDBITMAP,
714 (WPARAM)nBitmaps, (LPARAM)&tbab);
715 }
716 /* add buttons */
717 if(iNumButtons > 0)
718 SendMessageA (hwndTB, TB_ADDBUTTONSA,
719 (WPARAM)iNumButtons, (LPARAM)lpButtons);
720 }
721
722 return hwndTB;
723}
724
725
726/***********************************************************************
727 * CreateMappedBitmap [COMCTL32.8]
728 *
729 * PARAMS
730 * hInstance [I]
731 * idBitmap [I]
732 * wFlags [I]
733 * lpColorMap [I]
734 * iNumMaps [I]
735 *
736 * RETURNS
737 * Success: handle to the new bitmap
738 * Failure: 0
739 */
740
741HBITMAP WINAPI
742CreateMappedBitmap (HINSTANCE hInstance, INT idBitmap, UINT wFlags,
743 LPCOLORMAP lpColorMap, INT iNumMaps)
744{
745 HGLOBAL hglb;
746 HRSRC hRsrc;
747 LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
748 UINT nSize, nColorTableSize;
749 RGBQUAD *pColorTable;
750 INT iColor, i, iMaps, nWidth, nHeight;
751 HDC hdcScreen;
752 HBITMAP hbm;
753 LPCOLORMAP sysColorMap;
754 COLORREF cRef;
755 COLORMAP internalColorMap[4] =
756 {{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
757
758 /* initialize pointer to colortable and default color table */
759 if (lpColorMap) {
760 iMaps = iNumMaps;
761 sysColorMap = lpColorMap;
762 }
763 else {
764 internalColorMap[0].to = GetSysColor (COLOR_BTNTEXT);
765 internalColorMap[1].to = GetSysColor (COLOR_BTNSHADOW);
766 internalColorMap[2].to = GetSysColor (COLOR_BTNFACE);
767 internalColorMap[3].to = GetSysColor (COLOR_BTNHIGHLIGHT);
768 iMaps = 4;
769 sysColorMap = (LPCOLORMAP)internalColorMap;
770 }
771
772 hRsrc = FindResourceA (hInstance, (LPSTR)idBitmap, RT_BITMAPA);
773 if (hRsrc == 0)
774 return 0;
775 hglb = LoadResource (hInstance, hRsrc);
776 if (hglb == 0)
777 return 0;
778 lpBitmap = (LPBITMAPINFOHEADER)LockResource (hglb);
779 if (lpBitmap == NULL)
780 return 0;
781
782 nColorTableSize = (1 << lpBitmap->biBitCount);
783 nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
784 lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc (GMEM_FIXED, nSize);
785 if (lpBitmapInfo == NULL)
786 return 0;
787 RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
788
789 pColorTable = (RGBQUAD*)(((LPBYTE)lpBitmapInfo)+(UINT)lpBitmapInfo->biSize);
790
791 for (iColor = 0; iColor < nColorTableSize; iColor++) {
792 for (i = 0; i < iMaps; i++) {
793 cRef = RGB(pColorTable[iColor].rgbRed,
794 pColorTable[iColor].rgbGreen,
795 pColorTable[iColor].rgbBlue);
796 if ( cRef == sysColorMap[i].from) {
797#if 0
798 if (wFlags & CBS_MASKED) {
799 if (sysColorMap[i].to != COLOR_BTNTEXT)
800 pColorTable[iColor] = RGB(255, 255, 255);
801 }
802 else
803#endif
804 pColorTable[iColor].rgbBlue = GetBValue(sysColorMap[i].to);
805 pColorTable[iColor].rgbGreen = GetGValue(sysColorMap[i].to);
806 pColorTable[iColor].rgbRed = GetRValue(sysColorMap[i].to);
807 break;
808 }
809 }
810 }
811 nWidth = (INT)lpBitmapInfo->biWidth;
812 nHeight = (INT)lpBitmapInfo->biHeight;
813 hdcScreen = GetDC ((HWND)0);
814 hbm = CreateCompatibleBitmap (hdcScreen, nWidth, nHeight);
815 if (hbm) {
816 HDC hdcDst = CreateCompatibleDC (hdcScreen);
817 HBITMAP hbmOld = SelectObject (hdcDst, hbm);
818 LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
819 lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
820 StretchDIBits (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
821 lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
822 SRCCOPY);
823 SelectObject (hdcDst, hbmOld);
824 DeleteDC (hdcDst);
825 }
826 ReleaseDC ((HWND)0, hdcScreen);
827 GlobalFree ((HGLOBAL)lpBitmapInfo);
828 FreeResource (hglb);
829
830 return hbm;
831}
832
833
834/***********************************************************************
835 * CreateToolbar [COMCTL32.7] Creates a tool bar control
836 *
837 * PARAMS
838 * hwnd
839 * style
840 * wID
841 * nBitmaps
842 * hBMInst
843 * wBMID
844 * lpButtons
845 * iNumButtons
846 *
847 * RETURNS
848 * Success: handle to the tool bar control
849 * Failure: 0
850 *
851 * NOTES
852 * Do not use this functions anymore. Use CreateToolbarEx instead.
853 */
854
855HWND WINAPI
856CreateToolbar (HWND hwnd, DWORD style, UINT wID, INT nBitmaps,
857 HINSTANCE hBMInst, UINT wBMID,
858 LPCOLDTBBUTTON lpButtons,INT iNumButtons)
859{
860 return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
861 hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
862 iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
863}
864
865
866/***********************************************************************
867 * DllGetVersion [COMCTL32.25]
868 *
869 * Retrieves version information of the 'COMCTL32.DLL'
870 *
871 * PARAMS
872 * pdvi [O] pointer to version information structure.
873 *
874 * RETURNS
875 * Success: S_OK
876 * Failure: E_INVALIDARG
877 *
878 * NOTES
879 * Returns version of a comctl32.dll from IE4.01 SP1.
880 */
881
882HRESULT WINAPI
883COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
884{
885 if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
886 WARN("wrong DLLVERSIONINFO size from app");
887 return E_INVALIDARG;
888 }
889
890 pdvi->dwMajorVersion = COMCTL32_VERSION;
891 pdvi->dwMinorVersion = COMCTL32_VERSION_MINOR;
892 pdvi->dwBuildNumber = 2919;
893 pdvi->dwPlatformID = 6304;
894
895 TRACE("%lu.%lu.%lu.%lu\n",
896 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
897 pdvi->dwBuildNumber, pdvi->dwPlatformID);
898
899 return S_OK;
900}
901
902/***********************************************************************
903 * DllInstall (COMCTL32.@)
904 */
905HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
906{
907 FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
908 debugstr_w(cmdline));
909
910 return S_OK;
911}
912
913
914typedef struct __TRACKINGLIST {
915 TRACKMOUSEEVENT tme;
916 POINT pos; /* center of hover rectangle */
917 INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */
918} _TRACKINGLIST;
919
920static _TRACKINGLIST TrackingList[10];
921static int iTrackMax = 0;
922static UINT_PTR timer;
923
924static const INT iTimerInterval = 50; /* msec for timer interval */
925
926/* FIXME: need to implement WM_NCMOUSELEAVE and WM_NCMOUSEHOVER for */
927/* TrackMouseEventProc and _TrackMouseEvent */
928static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
929 DWORD dwTime)
930{
931 int i = 0;
932 POINT pos;
933 HWND hwnd;
934 INT hoverwidth = 0, hoverheight = 0;
935
936 GetCursorPos(&pos);
937 hwnd = WindowFromPoint(pos);
938
939 SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
940 SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
941
942 /* loop through tracking events we are processing */
943 while (i < iTrackMax) {
944 /* see if this tracking event is looking for TME_LEAVE and that the */
945 /* mouse has left the window */
946 if ((TrackingList[i].tme.dwFlags & TME_LEAVE) &&
947 (TrackingList[i].tme.hwndTrack != hwnd)) {
948 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
949
950 /* remove the TME_LEAVE flag */
951 TrackingList[i].tme.dwFlags ^= TME_LEAVE;
952 }
953
954 /* see if we are tracking hovering for this hwnd */
955 if(TrackingList[i].tme.dwFlags & TME_HOVER) {
956 /* add the timer interval to the hovering time */
957 TrackingList[i].iHoverTime+=iTimerInterval;
958
959 /* has the cursor moved outside the rectangle centered around pos? */
960 if((abs(pos.x - TrackingList[i].pos.x) > (hoverwidth / 2.0))
961 || (abs(pos.y - TrackingList[i].pos.y) > (hoverheight / 2.0)))
962 {
963 /* record this new position as the current position and reset */
964 /* the iHoverTime variable to 0 */
965 TrackingList[i].pos = pos;
966 TrackingList[i].iHoverTime = 0;
967 }
968
969 /* has the mouse hovered long enough? */
970 if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
971 {
972 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER, 0, 0);
973
974 /* stop tracking mouse hover */
975 TrackingList[i].tme.dwFlags ^= TME_HOVER;
976 }
977 }
978
979 /* see if we are still tracking TME_HOVER or TME_LEAVE for this entry */
980 if((TrackingList[i].tme.dwFlags & TME_HOVER) ||
981 (TrackingList[i].tme.dwFlags & TME_LEAVE)) {
982 i++;
983 } else { /* remove this entry from the tracking list */
984 TrackingList[i] = TrackingList[--iTrackMax];
985 }
986 }
987
988 /* stop the timer if the tracking list is empty */
989 if(iTrackMax == 0) {
990 KillTimer(0, timer);
991 timer = 0;
992 }
993}
994
995/***********************************************************************
996 * _TrackMouseEvent [COMCTL32.25]
997 *
998 * Requests notification of mouse events
999 *
1000 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
1001 * to the hwnd specified in the ptme structure. After the event message
1002 * is posted to the hwnd, the entry in the queue is removed.
1003 *
1004 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
1005 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
1006 * immediately and the TME_LEAVE flag being ignored.
1007 *
1008 * PARAMS
1009 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
1010 *
1011 * RETURNS
1012 * Success: non-zero
1013 * Failure: zero
1014 *
1015 */
1016
1017BOOL WINAPI
1018_TrackMouseEvent (TRACKMOUSEEVENT *ptme)
1019{
1020 DWORD flags = 0;
1021 int i = 0;
1022 BOOL cancel = 0, hover = 0, leave = 0, query = 0;
1023 HWND hwnd;
1024 POINT pos;
1025
1026 pos.x = 0;
1027 pos.y = 0;
1028
1029 TRACE("%lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
1030
1031 if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
1032 WARN("wrong TRACKMOUSEEVENT size from app");
1033 SetLastError(ERROR_INVALID_PARAMETER); /* FIXME not sure if this is correct */
1034 return FALSE;
1035 }
1036
1037 flags = ptme->dwFlags;
1038
1039 /* if HOVER_DEFAULT was specified replace this with the systems current value */
1040 if(ptme->dwHoverTime == HOVER_DEFAULT)
1041 SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &(ptme->dwHoverTime), 0);
1042
1043 GetCursorPos(&pos);
1044 hwnd = WindowFromPoint(pos);
1045
1046 if ( flags & TME_CANCEL ) {
1047 flags &= ~ TME_CANCEL;
1048 cancel = 1;
1049 }
1050
1051 if ( flags & TME_HOVER ) {
1052 flags &= ~ TME_HOVER;
1053 hover = 1;
1054 }
1055
1056 if ( flags & TME_LEAVE ) {
1057 flags &= ~ TME_LEAVE;
1058 leave = 1;
1059 }
1060
1061 /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
1062 if ( flags & TME_QUERY ) {
1063 flags &= ~ TME_QUERY;
1064 query = 1;
1065 i = 0;
1066
1067 /* Find the tracking list entry with the matching hwnd */
1068 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
1069 i++;
1070 }
1071
1072 /* hwnd found, fill in the ptme struct */
1073 if(i < iTrackMax)
1074 *ptme = TrackingList[i].tme;
1075 else
1076 ptme->dwFlags = 0;
1077
1078 return TRUE; /* return here, TME_QUERY is retrieving information */
1079 }
1080
1081 if ( flags )
1082 FIXME("Unknown flag(s) %08lx\n", flags );
1083
1084 if(cancel) {
1085 /* find a matching hwnd if one exists */
1086 i = 0;
1087
1088 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
1089 i++;
1090 }
1091
1092 if(i < iTrackMax) {
1093 TrackingList[i].tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
1094
1095 /* if we aren't tracking on hover or leave remove this entry */
1096 if(!((TrackingList[i].tme.dwFlags & TME_HOVER) ||
1097 (TrackingList[i].tme.dwFlags & TME_LEAVE)))
1098 {
1099 TrackingList[i] = TrackingList[--iTrackMax];
1100
1101 if(iTrackMax == 0) {
1102 KillTimer(0, timer);
1103 timer = 0;
1104 }
1105 }
1106 }
1107 } else {
1108 /* see if hwndTrack isn't the current window */
1109 if(ptme->hwndTrack != hwnd) {
1110 if(leave) {
1111 PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
1112 }
1113 } else {
1114 /* See if this hwnd is already being tracked and update the tracking flags */
1115 for(i = 0; i < iTrackMax; i++) {
1116 if(TrackingList[i].tme.hwndTrack == ptme->hwndTrack) {
1117 if(hover) {
1118 TrackingList[i].tme.dwFlags |= TME_HOVER;
1119 TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime;
1120 }
1121
1122 if(leave)
1123 TrackingList[i].tme.dwFlags |= TME_LEAVE;
1124
1125 /* reset iHoverTime as per winapi specs */
1126 TrackingList[i].iHoverTime = 0;
1127
1128 return TRUE;
1129 }
1130 }
1131
1132 /* if the tracking list is full return FALSE */
1133 if (iTrackMax == sizeof (TrackingList) / sizeof(*TrackingList)) {
1134 return FALSE;
1135 }
1136
1137 /* Adding new mouse event to the tracking list */
1138 TrackingList[iTrackMax].tme = *ptme;
1139
1140 /* Initialize HoverInfo variables even if not hover tracking */
1141 TrackingList[iTrackMax].iHoverTime = 0;
1142 TrackingList[iTrackMax].pos = pos;
1143
1144 iTrackMax++;
1145
1146 if (!timer) {
1147 timer = SetTimer(0, 0, iTimerInterval, TrackMouseEventProc);
1148 }
1149 }
1150 }
1151
1152 return TRUE;
1153}
1154
1155
1156/*************************************************************************
1157 * GetMUILanguage [COMCTL32.39]
1158 *
1159 * FIXME: What's this supposed to do? Apparently some i18n thing.
1160 *
1161 */
1162LANGID WINAPI GetMUILanguage (VOID)
1163{
1164 return COMCTL32_uiLang;
1165}
1166
1167
1168/*************************************************************************
1169 * InitMUILanguage [COMCTL32.85]
1170 *
1171 * FIXME: What's this supposed to do? Apparently some i18n thing.
1172 *
1173 */
1174
1175VOID WINAPI InitMUILanguage (LANGID uiLang)
1176{
1177 COMCTL32_uiLang = uiLang;
1178}
1179
1180
1181/***********************************************************************
1182 * COMCTL32_CreateToolTip [NOT AN API]
1183 *
1184 * Creates a tooltip for the control specified in hwnd and does all
1185 * necessary setup and notifications.
1186 *
1187 * PARAMS
1188 * hwndOwner [I] Handle to the window that will own the tool tip.
1189 *
1190 * RETURNS
1191 * Success: Handle of tool tip window.
1192 * Failure: NULL
1193 */
1194HWND
1195COMCTL32_CreateToolTip(HWND hwndOwner)
1196{
1197 HWND hwndToolTip;
1198
1199 hwndToolTip = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
1200 CW_USEDEFAULT, CW_USEDEFAULT,
1201 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner,
1202 0, 0, 0);
1203
1204 /* Send NM_TOOLTIPSCREATED notification */
1205 if (hwndToolTip)
1206 {
1207 NMTOOLTIPSCREATED nmttc;
1208 /* true owner can be different if hwndOwner is a child window */
1209 HWND hwndTrueOwner = GetWindow(hwndToolTip, GW_OWNER);
1210 nmttc.hdr.hwndFrom = hwndTrueOwner;
1211 nmttc.hdr.idFrom = GetWindowLongA(hwndTrueOwner, GWL_ID);
1212 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1213 nmttc.hwndToolTips = hwndToolTip;
1214
1215 SendMessageA(GetParent(hwndTrueOwner), WM_NOTIFY,
1216 (WPARAM)GetWindowLongA(hwndTrueOwner, GWL_ID),
1217 (LPARAM)&nmttc);
1218 }
1219
1220 return hwndToolTip;
1221}
Note: See TracBrowser for help on using the repository browser.