source: trunk/src/user32/winmouse.cpp@ 10185

Last change on this file since 10185 was 10185, checked in by sandervl, 22 years ago

Updates

File size: 23.4 KB
Line 
1/* $Id: winmouse.cpp,v 1.27 2003-07-28 11:27:50 sandervl Exp $ */
2/*
3 * Win32 mouse functions
4 *
5 * Copyright 1999-2002 Sander van Leeuwen
6 *
7 * Parts based on Wine code (windows\input.c) (TrackMouseEvent)
8 *
9 * Copyright 1993 Bob Amstadt
10 * Copyright 1996 Albrecht Kleine
11 * Copyright 1997 David Faure
12 * Copyright 1998 Morten Welinder
13 * Copyright 1998 Ulrich Weigand
14 *
15 * TODO: SwapMouseButton:
16 * We shouldn't let win32 apps change this for the whole system
17 * better to change mouse button message translation instead
18 *
19 * Project Odin Software License can be found in LICENSE.TXT
20 *
21 */
22
23#include <odin.h>
24#include <odinwrap.h>
25#include <os2sel.h>
26
27#include <os2win.h>
28#include <misc.h>
29#include "win32wbase.h"
30#include <winuser32.h>
31#include <winuser.h>
32#include <commctrl.h>
33#include <debugtools.h>
34#include <win\mouse.h>
35#include "winmouse.h"
36#include "oslibmsg.h"
37#include "oslibres.h"
38#include "pmwindow.h"
39#include "oslibwin.h"
40#include "hook.h"
41
42#include <winkeyboard.h>
43
44#define DBG_LOCALLOG DBG_winmouse
45#include "dbglocal.h"
46
47
48ODINDEBUGCHANNEL(USER32-WINMOUSE)
49
50
51/****************************************************************************
52 * local variables
53 ****************************************************************************/
54
55//******************************************************************************
56//******************************************************************************
57BOOL WIN32API GetCursorPos( PPOINT lpPoint)
58{
59 if (!lpPoint) return FALSE;
60
61 if (OSLibWinQueryPointerPos(lpPoint)) //POINT == POINTL
62 {
63 mapScreenPoint((OSLIBPOINT*)lpPoint);
64 dprintf2(("USER32: GetCursorPos (%d,%d)", lpPoint->x, lpPoint->y));
65 return TRUE;
66 }
67 else return FALSE;
68}
69//******************************************************************************
70//******************************************************************************
71BOOL WIN32API SetCursorPos( int X, int Y)
72{
73 BOOL ret;
74 POINT point;
75 MSLLHOOKSTRUCT hook;
76
77 GetCursorPos(&point);
78 dprintf(("USER32: SetCursorPos (%d,%d)->(%d,%d)", point.x, point.y, X,Y));
79
80 //The current cursor position may not have been passed to the application
81 //just yet. The position change discards any previous events which may
82 //lead to inconsistent mouse behaviour (like in DirectInput).
83 //To fix this, we pass down a mouse move event to any hook handlers.
84 hook.pt.x = point.x;
85 hook.pt.y = point.y;
86 hook.mouseData = 0;
87 hook.flags = 0;
88 hook.time = GetCurrentTime();
89 hook.dwExtraInfo = 0;
90 HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, WM_MOUSEMOVE, (LPARAM)&hook);
91
92 ret = OSLibWinSetPointerPos(X, mapScreenY(Y));
93 if(ret == TRUE) {
94 hook.pt.x = X;
95 hook.pt.y = Y;
96 hook.mouseData = 0;
97 //signal to dinput hook that it only needs to modify the last
98 //known position (not treat it as a new event)
99 hook.flags = LLMHF_INJECTED;
100 hook.time = GetCurrentTime();
101 hook.dwExtraInfo = 0;
102
103 HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, WM_MOUSEMOVE, (LPARAM)&hook);
104 }
105 return ret;
106}
107//******************************************************************************
108//******************************************************************************
109BOOL WIN32API ClipCursor(const RECT * lpRect)
110{
111 if(lpRect) {
112 dprintf(("USER32: ClipCursor (%d,%d)(%d,%d)", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom));
113 }
114 else dprintf(("USER32: ClipCursor NULL"));
115 return OSLibWinClipCursor(lpRect);
116}
117//******************************************************************************
118//******************************************************************************
119BOOL WIN32API GetClipCursor( LPRECT lpRect)
120{
121 dprintf(("USER32: GetClipCursor %x", lpRect));
122 return OSLibWinGetClipCursor(lpRect);
123}
124//******************************************************************************
125// capture handle "cache"
126static HWND hwndWin32Capture = 0;
127//******************************************************************************
128HWND WIN32API GetCapture()
129{
130 if (0 == hwndWin32Capture)
131 hwndWin32Capture = OS2ToWin32Handle(OSLibWinQueryCapture());
132
133 return hwndWin32Capture;
134}
135//******************************************************************************
136//******************************************************************************
137HWND WIN32API SetCapture(HWND hwnd)
138{
139 HWND hwndPrev = GetCapture();
140 BOOL rc;
141
142 // invalidate capture "cache"
143 hwndWin32Capture = 0;
144
145 if(hwnd == 0)
146 {
147 ReleaseCapture();
148 return hwndPrev;
149 }
150
151 if(hwnd == hwndPrev)
152 {
153 dprintf(("USER32: SetCapture %x; already set to that window; ignore", hwnd));
154 //TODO: NT4 SP6 sends this message even now
155//////// SendMessageA(hwndPrev, WM_CAPTURECHANGED, 0L, hwnd);
156 return hwndPrev;
157 }
158
159 if(hwndPrev != NULL)
160 {
161 //SvL: WinSetCapture returns an error if mouse is already captured
162 OSLibWinSetCapture(0);
163 }
164
165 rc = OSLibWinSetCapture(Win32ToOS2Handle(hwnd));
166 dprintf(("USER32: SetCapture %x (prev %x) returned %d", hwnd, hwndPrev, rc));
167 if(hwndPrev)
168 {
169 SendMessageA(hwndPrev, WM_CAPTURECHANGED, 0L, hwnd);
170 }
171 return hwndPrev;
172}
173//******************************************************************************
174//******************************************************************************
175BOOL WIN32API ReleaseCapture()
176{
177 HWND hwndPrev;
178 BOOL ret;
179
180 hwndPrev = GetCapture();
181
182 // invalidate capture "cache"
183 hwndWin32Capture = 0;
184
185 ret = OSLibWinSetCapture(0);
186 if(hwndPrev)
187 {
188 SendMessageA(hwndPrev, WM_CAPTURECHANGED, 0L, 0L);
189 }
190 return ret;
191}
192//******************************************************************************
193//******************************************************************************
194UINT WIN32API GetDoubleClickTime()
195{
196 UINT result = OSLibWinQuerySysValue(SVOS_DBLCLKTIME);
197 if(result == 0)
198 SetLastError(ERROR_INVALID_PARAMETER); //TODO: ????
199
200 return result;
201}
202//******************************************************************************
203//******************************************************************************
204BOOL WIN32API SetDoubleClickTime(UINT uInterval)
205{
206 BOOL ret = TRUE;
207
208 ret = OSLibWinSetSysValue(SVOS_DBLCLKTIME, uInterval);
209 if(ret == FALSE )
210 {
211 SetLastError(ERROR_INVALID_PARAMETER); //TODO: ????
212 }
213 return (ret);
214}
215//******************************************************************************
216//TODO: we shouldn't let win32 apps change this for the whole system
217// better to change mouse button message translation instead
218BOOL OPEN32API __SwapMouseButton(BOOL swapFlag);
219
220inline BOOL _SwapMouseButton(BOOL swapFlag)
221{
222 BOOL yyrc;
223 USHORT sel = RestoreOS2FS();
224
225 yyrc = __SwapMouseButton(swapFlag);
226 SetFS(sel);
227
228 return yyrc;
229}
230
231//******************************************************************************
232BOOL WIN32API SwapMouseButton(BOOL fSwap)
233{
234 return _SwapMouseButton(fSwap);
235}
236
237/*****************************************************************************
238 * Name : VOID WIN32API mouse_event
239 * Purpose : The mouse_event function synthesizes mouse motion and button clicks.
240 * Parameters: DWORD dwFlags flags specifying various motion/click variants
241 * DWORD dx horizontal mouse position or position change
242 * DWORD dy vertical mouse position or position change
243 * DWORD cButtons unused, reserved for future use, set to zero
244 * DWORD dwExtraInfo 32 bits of application-defined information
245 * Variables :
246 * Result :
247 * Remark :
248 * Status : UNTESTED STUB
249 *
250 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
251 *****************************************************************************/
252
253VOID WIN32API mouse_event(DWORD dwFlags, DWORD dx, DWORD dy, DWORD cButtons,
254 DWORD dwExtraInfo)
255{
256 INPUT i;
257
258 i.type = INPUT_MOUSE;
259 i.mi.dx = dx;
260 i.mi.dy = dy;
261 i.mi.mouseData = cButtons; // PH: is this really correct?
262 i.mi.dwFlags = dwFlags;
263 i.mi.dwExtraInfo = dwExtraInfo;
264
265 // forward to more modern API
266 SendInput(1, &i, sizeof(i) );
267}
268
269
270/*****************************************************************************
271 * Name : UINT SendInput
272 * Purpose : The SendInput function synthesizes keystrokes, mouse motions,
273 * and button clicks
274 * Parameters: UINT nInputs // count if input events
275 * LPINPUT pInputs // array of input structures
276 * int chSize // size of structure
277 * Variables :
278 * Result : number of events successfully inserted,
279 * 0 if the input was already blocked by another thread
280 * Remark :
281 * Status : UNTESTED STUB
282 * TODO: call hooks!!
283 *
284 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
285 *****************************************************************************/
286
287UINT WIN32API SendInput(UINT nInputs, LPINPUT pInputs, int chSize)
288{
289 dprintf(("not correctly implemented"));
290
291 // The simulated input is sent to the
292 // foreground thread's message queue.
293 // (WM_KEYUP, WM_KEYDOWN)
294 // After GetMessage or PeekMessage,
295 // TranslateMessage posts an appropriate
296 // WM_CHAR message.
297
298 HWND hwnd = GetForegroundWindow();
299
300 LPINPUT piBase = pInputs;
301 for (int i = 0;
302 i < nInputs;
303 i++,
304 piBase++)
305 {
306 switch(piBase->type)
307 {
308 case INPUT_MOUSE:
309 {
310 PMOUSEINPUT p = (PMOUSEINPUT)&piBase->mi;
311 MSG msg;
312 HWND hwndCapture;
313
314 hwndCapture = GetCapture();
315 if(hwndCapture) hwnd = hwndCapture;
316
317 if(p->dwFlags & MOUSEEVENTF_MOVE)
318 {
319 if(!(p->dwFlags & MOUSEEVENTF_ABSOLUTE)) {
320 POINT pt;
321
322 if(GetCursorPos(&pt) == TRUE) {
323 LONG relx = (LONG)p->dx;
324 LONG rely = (LONG)p->dy;
325
326 p->dx = pt.x + relx;
327 p->dy = pt.y + rely;
328 }
329 else {
330 DebugInt3();
331 return 0;
332 }
333 }
334 SetCursorPos(p->dx, p->dy);
335 OSLibSendWinMessage(hwnd, WM_MOUSEMOVE);
336 }
337
338 if(p->dwFlags & MOUSEEVENTF_LEFTDOWN)
339 {
340 KeySetOverlayKeyState(VK_LBUTTON, KEYOVERLAYSTATE_DOWN);
341 OSLibSendWinMessage(hwnd, WM_LBUTTONDOWN);
342 }
343 if(p->dwFlags & MOUSEEVENTF_LEFTUP)
344 {
345 KeySetOverlayKeyState(VK_LBUTTON, KEYOVERLAYSTATE_DONTCARE);
346 OSLibSendWinMessage(hwnd, WM_LBUTTONUP);
347 }
348 if(p->dwFlags & MOUSEEVENTF_RIGHTDOWN)
349 {
350 KeySetOverlayKeyState(VK_RBUTTON, KEYOVERLAYSTATE_DOWN);
351 OSLibSendWinMessage(hwnd, WM_RBUTTONDOWN);
352 }
353 if(p->dwFlags & MOUSEEVENTF_RIGHTUP)
354 {
355 KeySetOverlayKeyState(VK_RBUTTON, KEYOVERLAYSTATE_DONTCARE);
356 OSLibSendWinMessage(hwnd, WM_RBUTTONUP);
357 }
358 if(p->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
359 {
360 KeySetOverlayKeyState(VK_MBUTTON, KEYOVERLAYSTATE_DOWN);
361 OSLibSendWinMessage(hwnd, WM_MBUTTONDOWN);
362 }
363 if(p->dwFlags & MOUSEEVENTF_MIDDLEUP)
364 {
365 KeySetOverlayKeyState(VK_MBUTTON, KEYOVERLAYSTATE_DONTCARE);
366 OSLibSendWinMessage(hwnd, WM_MBUTTONUP);
367 }
368 }
369 break;
370
371 // compose a keyboard input message
372 case INPUT_KEYBOARD:
373 {
374 PKEYBDINPUT p = (PKEYBDINPUT)&piBase->ki;
375 MSG msg;
376 BOOL fUnicode = (p->dwFlags & KEYEVENTF_UNICODE) == KEYEVENTF_UNICODE;
377 DWORD extrainfo = GetMessageExtraInfo();
378
379 //TODO: We should really send an OS/2 WM_CHAR message here and let
380 // our existing code handle everything (WM_CHAR generation)
381 // This is a quick and dirty implementation. Not entirely correct.
382
383 // build keyboard message
384 msg.message = (p->dwFlags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
385
386 if (p->dwFlags & KEYEVENTF_SCANCODE)
387 {
388 // keystroke is identified by the scancode
389 if (fUnicode)
390 msg.wParam = MapVirtualKeyW(p->wScan, 1);
391 else
392 msg.wParam = MapVirtualKeyA(p->wScan, 1);
393 }
394 else
395 msg.wParam = p->wVk;
396
397 msg.lParam = 0x0000001 | // repeat count
398 ( (p->wScan & 0xff) << 16); // scan code
399
400 if (p->dwFlags & KEYEVENTF_EXTENDEDKEY)
401 msg.lParam |= (1 << 24);
402
403 // set additional message flags
404 if (msg.message == WM_KEYDOWN)
405 {
406 // @@@PH
407 // bit 30 - previous key state cannot be set, how to determine?
408 }
409 else
410 {
411 // WM_KEYUP -> previous key is always 1, transistion state
412 // always 1
413 msg.lParam |= (1 << 30);
414 msg.lParam |= (1 << 31);
415 }
416
417 msg.time = p->time;
418
419 // @@@PH
420 // unknown: do we have to post or to send the message?
421
422 SetMessageExtraInfo( (LPARAM)p->dwExtraInfo );
423
424 KeySetOverlayKeyState(msg.wParam, (msg.message == WM_KEYDOWN) ? KEYOVERLAYSTATE_DOWN : KEYOVERLAYSTATE_DONTCARE);
425
426 if (fUnicode)
427 SendMessageW(hwnd, msg.message, msg.wParam, msg.lParam);
428 else
429 SendMessageA(hwnd, msg.message, msg.wParam, msg.lParam);
430
431 if(msg.message == WM_KEYDOWN) {
432 char keybstate[256];
433 WORD key = 0;
434
435 GetKeyboardState((LPBYTE)&keybstate[0]);
436 if(ToAscii(p->wVk, p->wScan, (LPBYTE)&keybstate[0], &key, 0) != 0) {
437 SendMessageA(hwnd, WM_CHAR, key, msg.lParam);
438 }
439 }
440
441 //restore extra info
442 SetMessageExtraInfo(extrainfo);
443 break;
444 }
445
446 case INPUT_HARDWARE:
447 {
448 PHARDWAREINPUT p = (PHARDWAREINPUT)&piBase->hi;
449
450 // @@@PH
451 // not supported for the time being
452 }
453 break;
454
455 default:
456 dprintf(("unsupported input packet type %d",
457 piBase->type));
458 break;
459 }
460 }
461
462 return 0;
463}
464
465/*****************************************************************************
466 * Name : BOOL WIN32API DragDetect
467 * Purpose : The DragDetect function captures the mouse and tracks its movement
468 * Parameters: HWND hwnd
469 * POINT pt
470 * Variables :
471 * Result : If the user moved the mouse outside of the drag rectangle while
472 * holding the left button down, the return value is TRUE.
473 * If the user did not move the mouse outside of the drag rectangle
474 * while holding the left button down, the return value is FALSE.
475 * Remark :
476 * Status : UNTESTED STUB
477 *
478 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
479 *****************************************************************************/
480BOOL WIN32API DragDetect(HWND hwnd, POINT pt)
481{
482 dprintf(("not implemented"));
483
484 return (FALSE);
485}
486//******************************************************************************
487//******************************************************************************
488typedef struct __TRACKINGLIST {
489 TRACKMOUSEEVENT tme;
490 POINT pos; /* center of hover rectangle */
491 INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */
492} _TRACKINGLIST;
493
494#define UINT_PTR UINT
495static _TRACKINGLIST TrackingList[10];
496static int iTrackMax = 0;
497static UINT_PTR timer;
498static const INT iTimerInterval = 50; /* msec for timer interval */
499
500/* FIXME: need to implement WM_NCMOUSELEAVE and WM_NCMOUSEHOVER for */
501/* TrackMouseEventProc and _TrackMouseEvent */
502static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
503 DWORD dwTime)
504{
505 int i = 0;
506 POINT pos;
507 HWND hwnd;
508 INT hoverwidth = 0, hoverheight = 0;
509
510 GetCursorPos(&pos);
511 hwnd = WindowFromPoint(pos);
512
513 SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
514 SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
515
516 /* loop through tracking events we are processing */
517 while (i < iTrackMax) {
518 /* see if this tracking event is looking for TME_LEAVE and that the */
519 /* mouse has left the window */
520 if ((TrackingList[i].tme.dwFlags & TME_LEAVE) &&
521 (TrackingList[i].tme.hwndTrack != hwnd)) {
522 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
523
524 /* remove the TME_LEAVE flag */
525 TrackingList[i].tme.dwFlags ^= TME_LEAVE;
526 }
527
528 /* see if we are tracking hovering for this hwnd */
529 if(TrackingList[i].tme.dwFlags & TME_HOVER) {
530 /* add the timer interval to the hovering time */
531 TrackingList[i].iHoverTime+=iTimerInterval;
532
533 /* has the cursor moved outside the rectangle centered around pos? */
534 if((abs(pos.x - TrackingList[i].pos.x) > (hoverwidth / 2.0))
535 || (abs(pos.y - TrackingList[i].pos.y) > (hoverheight / 2.0)))
536 {
537 /* record this new position as the current position and reset */
538 /* the iHoverTime variable to 0 */
539 TrackingList[i].pos = pos;
540 TrackingList[i].iHoverTime = 0;
541 }
542
543 /* has the mouse hovered long enough? */
544 if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
545 {
546 PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER, 0, 0);
547
548 /* stop tracking mouse hover */
549 TrackingList[i].tme.dwFlags ^= TME_HOVER;
550 }
551 }
552
553 /* see if we are still tracking TME_HOVER or TME_LEAVE for this entry */
554 if((TrackingList[i].tme.dwFlags & TME_HOVER) ||
555 (TrackingList[i].tme.dwFlags & TME_LEAVE)) {
556 i++;
557 } else { /* remove this entry from the tracking list */
558 TrackingList[i] = TrackingList[--iTrackMax];
559 }
560 }
561
562 /* stop the timer if the tracking list is empty */
563 if(iTrackMax == 0) {
564 KillTimer(0, timer);
565 timer = 0;
566 }
567}
568
569
570/***********************************************************************
571 * TrackMouseEvent [USER32]
572 *
573 * Requests notification of mouse events
574 *
575 * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted
576 * to the hwnd specified in the ptme structure. After the event message
577 * is posted to the hwnd, the entry in the queue is removed.
578 *
579 * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely
580 * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted
581 * immediately and the TME_LEAVE flag being ignored.
582 *
583 * PARAMS
584 * ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
585 *
586 * RETURNS
587 * Success: non-zero
588 * Failure: zero
589 *
590 */
591
592BOOL WINAPI
593TrackMouseEvent (TRACKMOUSEEVENT *ptme)
594{
595 DWORD flags = 0;
596 int i = 0;
597 BOOL cancel = 0, hover = 0, leave = 0, query = 0;
598 HWND hwnd;
599 POINT pos;
600
601 pos.x = 0;
602 pos.y = 0;
603
604 dprintf(("TrackMouseEvent: %lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime));
605
606 if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
607 WARN("wrong TRACKMOUSEEVENT size from app\n");
608 SetLastError(ERROR_INVALID_PARAMETER); /* FIXME not sure if this is correct */
609 return FALSE;
610 }
611
612 flags = ptme->dwFlags;
613
614 /* if HOVER_DEFAULT was specified replace this with the systems current value */
615 if(ptme->dwHoverTime == HOVER_DEFAULT)
616 SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &(ptme->dwHoverTime), 0);
617
618 GetCursorPos(&pos);
619 hwnd = WindowFromPoint(pos);
620
621 if ( flags & TME_CANCEL ) {
622 flags &= ~ TME_CANCEL;
623 cancel = 1;
624 }
625
626 if ( flags & TME_HOVER ) {
627 flags &= ~ TME_HOVER;
628 hover = 1;
629 }
630
631 if ( flags & TME_LEAVE ) {
632 flags &= ~ TME_LEAVE;
633 leave = 1;
634 }
635
636 /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
637 if ( flags & TME_QUERY ) {
638 flags &= ~ TME_QUERY;
639 query = 1;
640 i = 0;
641
642 /* Find the tracking list entry with the matching hwnd */
643 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
644 i++;
645 }
646
647 /* hwnd found, fill in the ptme struct */
648 if(i < iTrackMax)
649 *ptme = TrackingList[i].tme;
650 else
651 ptme->dwFlags = 0;
652
653 return TRUE; /* return here, TME_QUERY is retrieving information */
654 }
655
656 if ( flags )
657 FIXME("Unknown flag(s) %08lx\n", flags );
658
659 if(cancel) {
660 /* find a matching hwnd if one exists */
661 i = 0;
662
663 while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
664 i++;
665 }
666
667 if(i < iTrackMax) {
668 TrackingList[i].tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
669
670 /* if we aren't tracking on hover or leave remove this entry */
671 if(!((TrackingList[i].tme.dwFlags & TME_HOVER) ||
672 (TrackingList[i].tme.dwFlags & TME_LEAVE)))
673 {
674 TrackingList[i] = TrackingList[--iTrackMax];
675
676 if(iTrackMax == 0) {
677 KillTimer(0, timer);
678 timer = 0;
679 }
680 }
681 }
682 } else {
683 /* see if hwndTrack isn't the current window */
684 if(ptme->hwndTrack != hwnd) {
685 if(leave) {
686 PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
687 }
688 } else {
689 /* See if this hwnd is already being tracked and update the tracking flags */
690 for(i = 0; i < iTrackMax; i++) {
691 if(TrackingList[i].tme.hwndTrack == ptme->hwndTrack) {
692 if(hover) {
693 TrackingList[i].tme.dwFlags |= TME_HOVER;
694 TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime;
695 }
696
697 if(leave)
698 TrackingList[i].tme.dwFlags |= TME_LEAVE;
699
700 /* reset iHoverTime as per winapi specs */
701 TrackingList[i].iHoverTime = 0;
702
703 return TRUE;
704 }
705 }
706
707 /* if the tracking list is full return FALSE */
708 if (iTrackMax == sizeof (TrackingList) / sizeof(*TrackingList)) {
709 return FALSE;
710 }
711
712 /* Adding new mouse event to the tracking list */
713 TrackingList[iTrackMax].tme = *ptme;
714
715 /* Initialize HoverInfo variables even if not hover tracking */
716 TrackingList[iTrackMax].iHoverTime = 0;
717 TrackingList[iTrackMax].pos = pos;
718
719 iTrackMax++;
720
721 if (!timer) {
722 timer = SetTimer(0, 0, iTimerInterval, (TIMERPROC)TrackMouseEventProc);
723 }
724 }
725 }
726
727 return TRUE;
728}
729//******************************************************************************
730//******************************************************************************
731ULONG GetMouseKeyState()
732{
733 ULONG keystate = 0;
734
735 if(GetKeyState(VK_LBUTTON) & 0x8000)
736 keystate |= MK_LBUTTON;
737 if(GetKeyState(VK_RBUTTON) & 0x8000)
738 keystate |= MK_RBUTTON;
739 if(GetKeyState(VK_MBUTTON) & 0x8000)
740 keystate |= MK_MBUTTON;
741 if(GetKeyState(VK_SHIFT) & 0x8000)
742 keystate |= MK_SHIFT;
743 if(GetKeyState(VK_CONTROL) & 0x8000)
744 keystate |= MK_CONTROL;
745
746 return keystate;
747}
748//******************************************************************************
749//******************************************************************************
Note: See TracBrowser for help on using the repository browser.