According to the documentation, pvParam is the parameter that receives the current mouse speed, not the return value. The return value represents whether it is successful or not. It will return 0(failed) here, and then the 2nd call always sets the mouse speed to 1.
SPI_GETMOUSESPEED: pvParam is a point to an integer.
SPI_SETMOUSESPEED: It is an integer.
The equivalent C code is:
UINT pvParam = 0;
BOOL ret = 0;
ret = SystemParametersInfo(SPI_GETMOUSESPEED, 0, &pvParam, 0);
pvParam++;
ret = SystemParametersInfo(SPI_SETMOUSESPEED, 0, (LPVOID)pvParam, 0);
So you could declare its type as IntPtr:
$f=@'
[DllImport("user32.dll")]public static extern int SystemParametersInfo(
int uAction,
int uParam,
IntPtr lpvParam,
int fuWinIni
);
'@
And then create a IntPtr instance to receive the Integer, and read the Integer from the instance. Finally, conver the new value to a new IntPtr and call set method:
[IntPtr]$srcSpeedPtr = [system.runtime.interopservices.marshal]::AllocHGlobal(4)
$mSpeed::SystemParametersInfo($get, 0, $srcSpeedPtr, 0)
$srcSpeed = [system.runtime.interopservices.marshal]::ReadInt32($srcSpeedPtr, 0)
echo $srcSpeed
[IntPtr]$newSpeed = [IntPtr]::new($srcSpeed + 1)
$mSpeed::SystemParametersInfo($set, 0, $newSpeed, 0)
[system.runtime.interopservices.marshal]::FreeHGlobal($srcSpeedPtr)