; This is an AutoHotKey script. ; If you want to run this, you need to install AutoHotKey first. ; ; The script presents a simple GUI, allowing you to watch WM_ messages ; generated by the mouse. You need to click the GUI window ; to capture some mouse-related messages, or maybe more specifically, ; the large "text edit" widget. ; ; This tool is far from perfect, but will show you the broken behavior ; of the mouse output of a Windows 7 "touch panel device" ; as produced by the Microsoft Touch Input Service. ; ; Author: Frank Rysanek of FCC prumyslove systemy s.r.o. Gui,Add,Button,x3 y3 w44 h17 gMyClearButton, Clear Gui,Add,CheckBox,x52 y5 vMyTrackMouseMove,Track WM_MOUSEMOVE Gui,Add,CheckBox,x210 y5 vLbut, Gui,Add,CheckBox,x240 y5 vMbut, Gui,Add,CheckBox,x270 y5 vRbut, Gui,Add,Edit,x3 y23 w280 h600 vMyMsgLog ReadOnly, ;Gui,Show,w206 h626,WM mouse tracer Gui,Show,w350,WM mouse tracer ;ControlFocus,Edit1,WM mouse tracer global sLogBuf := global sAppend := ; WM_MOUSELEAVE and WM_MOUSEHOVER need a special setup, ; which however doesn't seem to work for me as per examples ;hWnd := WinExist() ;MouseLeaveAlreadySetUp := setMouseLeaveTracking(hWnd) OnMessage(282, "MouseEvent") OnMessage(512, "MouseEvent") ; do not trace WM_MOUSEMOVE OnMessage(513, "MouseEvent") OnMessage(514, "MouseEvent") OnMessage(515, "MouseEvent") OnMessage(516, "MouseEvent") OnMessage(517, "MouseEvent") OnMessage(518, "MouseEvent") OnMessage(519, "MouseEvent") OnMessage(520, "MouseEvent") OnMessage(521, "MouseEvent") OnMessage(522, "MouseEvent") OnMessage(523, "MouseEvent") OnMessage(524, "MouseEvent") OnMessage(525, "MouseEvent") OnMessage(0x2A1, "MouseEvent") OnMessage(0x2A3, "MouseEvent") OnMessage(576, "MouseEvent") OnMessage(577, "MouseEvent") OnMessage(578, "MouseEvent") ; doesn't seem to work :-/ I don't ever get this message: OnMessage(716, "UpYours") ; WM_TABLET_QUERYSYSTEMGESTURESTATUS return GuiEscape: GuiClose: ExitApp MyClearButton: sLogBuf := GuiControl,,MyMsgLog, %sLogBuf% Return MouseEvent(wParam, lParam, wMsg, hWnd) { if ( wMsg = 282 ) ; received by the main window sAppend = WM_GESTURENOTIFY else if ( wMsg = 512 ) ; received by the main window sAppend = WM_MOUSEMOVE else if ( wMsg = 513 ) { sAppend = WM_LBUTTONDOWN GuiControl,,LBut,1 } else if ( wMsg = 514 ) { sAppend = WM_LBUTTONUP GuiControl,,LBut,0 } else if ( wMsg = 515 ) { sAppend = WM_LBUTTONDBLCLK GuiControl,,LBut,1 } else if ( wMsg = 516 ) { sAppend = WM_RBUTTONDOWN GuiControl,,RBut,1 } else if ( wMsg = 517 ) { sAppend = WM_RBUTTONUP GuiControl,,RBut,0 } else if ( wMsg = 518 ) { sAppend = WM_RBUTTONDBLCLK GuiControl,,RBut,1 } else if ( wMsg = 519 ) { sAppend = WM_MBUTTONDOWN GuiControl,,MBut,1 } else if ( wMsg = 520 ) { sAppend = WM_MBUTTONUP GuiControl,,MBut,0 } else if ( wMsg = 521 ) { sAppend = WM_MBUTTONDBLCLK GuiControl,,MBut,1 } else if ( wMsg = 522 ) sAppend = WM_MOUSEWHEEL else if ( wMsg = 523 ) sAppend = WM_XBUTTONDOWN else if ( wMsg = 524 ) sAppend = WM_XBUTTONUP else if ( wMsg = 525 ) sAppend = WM_XBUTTONDBLCLK else if ( wMsg =0x2A1) sAppend = WM_MOUSEHOVER else if ( wMsg =0x2A3) ; received by whatever child widget... no use sAppend = WM_MOUSELEAVE else if ( wMsg = 576 ) sAppend = WM_TOUCHMOVE else if ( wMsg = 577 ) sAppend = WM_TOUCHDOWN else if ( wMsg = 578 ) sAppend = WM_TOUCHUP else sAppend = WM_WTF? %wMsg% Xdim := GET_X_LPARAM(lParam) Ydim := GET_Y_LPARAM(lParam) wParamHex := FHex(wParam, 4) sAppend = %sAppend% (X:%Xdim% Y:%Ydim% w:%wParamHex%) GuiControlGet,CheckBoxState,,MyTrackMouseMove ;if (wMsg != 512) ; WM_MOUSEMOVE just clogs the view if ((wMsg != 512) || (CheckBoxState = 1)) AppendToLog() ;SoundBeep, 500, 200 ; the right mouse button brings up a context menu... avoid it if ((wMsg = 516) || (wMsg = 517) || (wMsg = 518)) return 0 else return } AppendToLog() { sLogBuf = %sLogBuf%%sAppend%`r`n GuiControl,,MyMsgLog, %sLogBuf% ;scroll to bottom ;SendMessage, 0x0115, 7, 0,, ahk_id %hMyMsgLog% ;WM_VSCROLL ;SendMessage, 0x0115, 1, 0,, ahk_id %hMyMsgLog% ;WM_VSCROLL ControlSend,Edit1,^{End},WM mouse tracer } UpYours(wParam, lParam, wMsg, hWnd) { SoundBeep, 500, 200 return 1 ;TABLET_DISABLE_PRESSANDHOLD } ; lParam manipulation GET_X_LPARAM(lp) { return, UIntToShort(LoWord(lp)) } GET_Y_LPARAM(lp) { return, UIntToShort(HiWord(lp)) } LoWord(byref dword) { return, dword & 0xFFFF } HiWord(ByRef dword) { return, dword >> 16 } UIntToShort(ByRef num) { numPut(num,num,"UInt") return numGet(num, "Short") } FHex( int, pad=0 ) ; Function by [VxE]. Formats an integer (decimals are truncated) as hex. { ; "Pad" may be the minimum number of digits that should appear on the right of the "0x". Static hx := "0123456789ABCDEF" If !( 0 < int |= 0 ) Return !int ? "0x0" : "-" FHex( -int, pad ) s := 1 + Floor( Ln( int ) / Ln( 16 ) ) h := SubStr( "0x0000000000000000", 1, pad := pad < s ? s + 2 : pad < 16 ? pad + 2 : 18 ) u := A_IsUnicode = 1 Loop % s NumPut( *( &hx + ( ( int & 15 ) << u ) ), h, pad - A_Index << u, "UChar" ), int >>= 4 Return h } ; If this should work at all, it must be done after every WM_MOUSELEAVE setMouseLeaveTracking(hwnd) { SoundBeep, 500, 200 static v if !v { VarSetCapacity(v, size := A_Ptrsize = 8 ? 24 : 16, 0) NumPut(size, v, 0, "UInt") ; cbSize NumPut(0x00000003, v, 4, "UInt") ; dwFlags (TME_LEAVE | TME_HOVER) NumPut(hwnd, v, 8, "Ptr") ; HWND NumPut(1000, v, A_Ptrsize = 8 ? 16 : 12, "UInt") ; dwHoverTime 1000 ms } return DllCall("TrackMouseEvent", "Ptr", &v) ; Non-zero on success } ;AppendText(hEdit, ptrText) { ; SendMessage, 0x000E, 0, 0,, ahk_id %hEdit% ;WM_GETTEXTLENGTH ; SendMessage, 0x00B1, ErrorLevel, ErrorLevel,, ahk_id %hEdit% ;EM_SETSEL ; SendMessage, 0x00C2, False, ptrText,, ahk_id %hEdit% ;EM_REPLACESEL ;}