﻿id	summary	reporter	owner	description	type	status	milestone	component	version	severity	resolution	keywords	cc
3942	@EVT_POS, @EVT_TIME, @EVT_INFO event macros	AutoXenon	Jon	"

References:

{{{
learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessagepos
learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessagetime
learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessageextrainfo
devblogs.microsoft.com/oldnewthing/20121101-00/?p=6193
}}}


Motivation:

Manually calling MouseGetPos() when an OnEvent function is triggered may result in an incorrect position as there might be new mouse movements from the time the message is posted. The correct way to retrieve the associated cursor position or message timestamp is to make a DllCall to GetMessagePos/GetMessageTime within the OnEvent function. This results in frequently re-used boilerplate code in every GUISetOnEvent and GUIRegisterMsg callbacks. It also has a bit of overhead for frequently received messages, having to call it from within AutoIt's interpreter

Since these data are always associated with every Windows Message, it makes sense to just make it a built-in macro that is called from the C++ core for all Windows Messages. The syscall is pretty fast so I don't think it would be necessary to make it optionally activated, but if it turns out that it needs it after all then we could always just have it hidden behind an Opt('EventExtraInfo',1) flag or something like that.

Note that the raw @EVT_POS returned from the WinAPI call is a 32-bit dword where x and y are signed 16-bits. In my boilerplates I use DllStructCreate with pointers to recast them into two signed shorts like so:


{{{#!autoit
Func GetMessagePos($dll='user32.dll')
     Local $pos = DllCall($dll,'dword','GetMessagePos')[0]
     Local $_ = DllStructCreate('dword;')
     DllStructSetData($_,1,$pos)
     Local $val = DllStructCreate('short x;short y',DllStructGetPtr($_))
     Local $pos = [$val.x,$val.y]
     Return $pos
EndFunc
}}}

And the boilerplates for GetMessageTime and GetMessageExtraInfo is as follows


{{{#!autoit
Func GetMessageTime($dll='user32.dll')
     Return DllCall($dll,'long','GetMessageTime')[0]
EndFunc

Func GetMessageExtraInfo($dll='user32.dll')
     Return DllCall($dll,'lparam','GetMessageExtraInfo')[0]
EndFunc
}}}

A sample application using the above boilerplates:


{{{#!autoit
#OnAutoItStartRegister SetProcessDPIAware

Opt(""GUIOnEventMode"",1)
Global Const $user32 = DllOpen('user32.dll')

GUICreate('',@DesktopWidth,@DesktopHeight,0,0,0x80000000,8)
GUISetOnEvent(-3,Quit)
GUISetOnEvent(-7,OnPrimaryDown)
GUISetOnEvent(-8,OnPrimaryUp)
GUISetOnEvent(-9,OnSecondaryDown)
GUISetOnEvent(-10,OnSecondaryUp)
GUISetState()
HotKeySet('{space}',OnSpace)
While Sleep(1000)
WEnd

Func Quit()
     Exit
EndFunc

Func OnPrimaryDown()
     Local $pos = GetMessagePos($user32), $time = GetMessageTime($user32), $info = GetMessageExtraInfo($user32)
     ToolTip('pos: '&$pos[0]&','&$pos[1]&@CRLF&'time: '&$time&@CRLF&'info: '&Hex($info),$pos[0],$pos[1],'PrimaryDown')
EndFunc

Func OnSecondaryDown()
     Local $pos = GetMessagePos($user32), $time = GetMessageTime($user32), $info = GetMessageExtraInfo($user32)
     ToolTip('pos: '&$pos[0]&','&$pos[1]&@CRLF&'time: '&$time&@CRLF&'info: '&Hex($info),$pos[0],$pos[1],'SecondaryDown')
EndFunc

Func OnPrimaryUp()
     ToolTip('')
EndFunc

Func OnSecondaryUp()
     ToolTip('')
EndFunc

Func OnSpace()
     Local Static $on = False
     $on = not $on
     Local $_ = DllStructCreate('dword;struct;long;long;dword;dword;dword;ulong_ptr;endstruct;')
     DllStructSetData($_,1,0)
     DllStructSetData($_,5,$on ? 2 : 4)
     DllStructSetData($_,6,420)
     DllStructSetData($_,7,0xdeadbeef)
     Return DllCall( $user32, 'uint', 'SendInput', 'uint', 1, 'struct*', $_, 'int', DllStructGetSize($_) )[0]
EndFunc

Func GetMessagePos($dll='user32.dll')
     Local $pos = DllCall($dll,'dword','GetMessagePos')[0]
     Local $_ = DllStructCreate('dword;')
     DllStructSetData($_,1,$pos)
     Local $val = DllStructCreate('short;short',DllStructGetPtr($_))
     Local $pos = [DllStructGetData($val,1),DllStructGetData($val,2)]
     Return $pos
EndFunc

Func GetMessageTime($dll='user32.dll')
     Return DllCall($dll,'long','GetMessageTime')[0]
EndFunc

Func GetMessageExtraInfo($dll='user32.dll')
     Return DllCall($dll,'lparam','GetMessageExtraInfo')[0]
EndFunc

Func SetProcessDPIAware()
     GUICreate('')
     DllCall('user32.dll', 'bool', 'SetProcessDPIAware')
     GUIDelete()
EndFunc
}}}
"	Feature Request	assigned		AutoIt		None			
