Champak Posted August 8, 2023 Share Posted August 8, 2023 I'm trying to move the mouse between three monitors (shaped like an L if that matters). But it's not working because the primary monitor (laptop) has 150% scale. I've seen a couple older posts that try to tackle the issue of mousemove and scaling, but the solutions don't quite tackle the basic compensation issue of a simple mouse move...more like tracking, and I can't really decode what they put together. Has anyone come up with a simple compensation for mousemove with a scaled primary screen? Link to comment Share on other sites More sharing options...
ioa747 Posted August 8, 2023 Share Posted August 8, 2023 I know that I know nothing Link to comment Share on other sites More sharing options...
Champak Posted August 8, 2023 Author Share Posted August 8, 2023 I guess I'm missing something and don't see how to implement this. I see how this can help with resolution and monitor count, which I don't have an issue with, but I don't see how this can help with window scaling and mousemove coordinates taking it into consideration. Link to comment Share on other sites More sharing options...
ioa747 Posted August 8, 2023 Share Posted August 8, 2023 I assumed that knowing the resolution of each monitor and its position within the monitors grid would help move the mouse between them I know that I know nothing Link to comment Share on other sites More sharing options...
Champak Posted August 8, 2023 Author Share Posted August 8, 2023 No, everything is just off when a monitor has the scale changed. Look at the image. All monitors are 1920 with monitor 1 having a scale of 150%. If I set MouseMove(2000, 500) the mouse should end up around the green line on monitor 2, but it instead ends up around the blue line. When the scale is at 100% the mouse moves where I expect it to. Some mousemove coordinates wont even move to screen 2 all together even if the coordinates dictate it should be on screen 2. Link to comment Share on other sites More sharing options...
argumentum Posted August 8, 2023 Share Posted August 8, 2023 if CV ( control viewer mod ) works then maybe you can use part of the UDF I'm putting together. Champak and ioa747 2 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Solution ioa747 Posted August 8, 2023 Solution Share Posted August 8, 2023 (edited) can you show the console output from the script i suggested? indeed, the mouse lives in its world (with a zoom factor of 200% it makes half the journey), while the ToolTip goes normally to its position however the problem seems to be fixed by using DPIAwareness.au3 which I found after digging in CV as suggested by @argumentum DPIAwareness.au3 Spoiler expandcollapse popup#include-once ; #include "DPIAwareness.au3" #include <Array.au3> #include <GUIConstantsEx.au3> ;;; https://www.autoitscript.com/forum/topic/199786-making-your-compiled-application-dpi-aware/?do=findComment&comment=1433365 #include <GDIPlus.au3> #include <WinAPIGdiDC.au3> #include <WinAPISysWin.au3> ;~ _GDIPlus_Startup() ; Done in "CV.au3" ; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware ; enum _MONITOR_DPI_TYPE Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI Global Const $WM_DPICHANGED = 0x02E0 Func _WinAPI_SetDPIAwareness($hGUI = 0) Switch @OSBuild Case 6000 To 9199 If Not DllCall("user32.dll", "bool", "SetProcessDPIAware") Then Return SetError(1, 0, 0) Return 1 Case 9200 To 13999 _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE) If @error Then Return SetError(2, 0, 0) Return 1 Case @OSBuild > 13999 #cs Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)), Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)), Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)), Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)), Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5)) #ce _WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI) If @error Then Return SetError(3, @error, 0) Return 1 EndSwitch Return -1 EndFunc ;==>_WinAPI_SetDPIAwareness Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness Local $aResult = DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware) If @error Then Return SetError(1, 0, 0) #forceref $aResult Return 1 EndFunc ;==>_WinAPI_SetProcessDpiAwareness Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 3) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext $DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext $iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode Local $aResult, $aResult1, $aResult2, $aResult31, $aResult32 Switch $iMode Case 1 Local $hDC = _WinAPI_GetDC($hGUI) $aResult1 = DllCall("user32.dll", "int", "GetDpiFromDpiAwarenessContext", "ptr", $hDC) If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0) _WinAPI_ReleaseDC(0, $hDC) $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0) Case 2 ;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle()) $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI) If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0) $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0) Case 3 $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext") If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0) $aResult32 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0]) If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0) $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0) EndSwitch Return 1 EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext Example expandcollapse popup; https://www.autoitscript.com/forum/topic/210653-mousemove-and-scaling-issue/#comment-1522551 #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <WindowsConstants.au3> #include <WinAPIGdi.au3> #include "DPIAwareness.au3" _WinAPI_SetDPIAwareness() Global $hGui = GUICreate('Au3Gui', 500, 500, -1, -1, $WS_OVERLAPPEDWINDOW) WinSetTrans($hGui, '', 100) Global $Label1 = GUICtrlCreateLabel("", 200, 200, 300, 300) GUICtrlSetFont(-1, 200, 900, 0, "MS Sans Serif") GUISetState(@SW_SHOW, $hGui) Global $aMon = _GetMonitorsArray() If IsArray($aMon) Then #Region ===( test1 )=== For $i = 1 To $aMon[0][0] WinMove($hGui, "", $aMon[$i][1], $aMon[$i][2], $aMon[$i][3], $aMon[$i][4]) GUISetState(@SW_MAXIMIZE, $hGui) GUICtrlSetData($Label1, $i) ConsoleWrite(" index: " & $i & @CRLF) ConsoleWrite("- [0]=handle=" & $aMon[$i][0] & @CRLF) ConsoleWrite("- [1]=left=" & $aMon[$i][1] & @CRLF) ConsoleWrite("- [2]=top=" & $aMon[$i][2] & @CRLF) ConsoleWrite("- [3]=width=" & $aMon[$i][3] & @CRLF) ConsoleWrite("- [4]=height=" & $aMon[$i][4] & @CRLF) ConsoleWrite("" & @CRLF) _GetMonitorInfo($hGui) Sleep(2000) Next GUIDelete($hGui) #EndRegion ===( test1 )=== #Region ===( test2 )=== Global $iX, $iY For $i = 1 To $aMon[0][0] ;the start point $iX = $aMon[$i][1] $iY = $aMon[$i][2] ;plus the midle point $iX += $aMon[$i][3] / 2 $iY += $aMon[$i][4] / 2 ConsoleWrite($iX & ", " & $iY & @CRLF) ToolTip("Mouse x, y:" & @CRLF & $iX & ", " & $iY, $iX, $iY, "midle point:", 1, 3) MouseMove($iX, $iY, 70) Global $aPos = MouseGetPos() ConsoleWrite("MouseGetPos x, y:" & $aPos[0] & ", " & $aPos[1] & @CRLF) Sleep(3000) ToolTip("") Next #EndRegion ===( test2 )=== EndIf ;---------------------------------------------------------------------------------------- Func _GetMonitorInfo($hWindow) Local $hMonitor = _WinAPI_MonitorFromWindow($hWindow, $MONITOR_DEFAULTTONULL) Local $aData = _WinAPI_GetMonitorInfo($hMonitor) ConsoleWrite('MonitorInfo **********************' & @CRLF) If Not @error Then ConsoleWrite('Handle: ' & $hMonitor & @CRLF) ConsoleWrite('Rectangle: ' & DllStructGetData($aData[0], 1) & ', ' & DllStructGetData($aData[0], 2) & ', ' & DllStructGetData($aData[0], 3) & ', ' & DllStructGetData($aData[0], 4) & @CRLF) ConsoleWrite('Work area: ' & DllStructGetData($aData[1], 1) & ', ' & DllStructGetData($aData[1], 2) & ', ' & DllStructGetData($aData[1], 3) & ', ' & DllStructGetData($aData[1], 4) & @CRLF) ConsoleWrite('Primary: ' & $aData[2] & @CRLF) ConsoleWrite('Device name: ' & $aData[3] & @CRLF) ConsoleWrite("**********************************" & @CRLF & @CRLF) EndIf EndFunc ;==>_GetMonitorInfo ;---------------------------------------------------------------------------------------- Func _GetMonitorsArray() Local $aPos, $aData = _WinAPI_EnumDisplayMonitors() If IsArray($aData) Then ReDim $aData[$aData[0][0] + 1][5] For $i = 1 To $aData[0][0] $aPos = _WinAPI_GetPosFromRect($aData[$i][1]) For $j = 0 To 3 $aData[$i][$j + 1] = $aPos[$j] Next Next EndIf Return $aData EndFunc ;==>_GetMonitorsArray ;---------------------------------------------------------------------------------------- ;comment / uncomment the _WinAPI_SetDPIAwareness() func to see the different Edited August 9, 2023 by ioa747 Correction argumentum and Champak 1 1 I know that I know nothing Link to comment Share on other sites More sharing options...
Champak Posted August 9, 2023 Author Share Posted August 9, 2023 Thank both of you...the best part about your example @ioa747 is you saved me time because that is exactly the function I was going to do in having the mouse center on the screen. Link to comment Share on other sites More sharing options...
ioa747 Posted September 20, 2023 Share Posted September 20, 2023 Since this is where the idea was born, to update the thread, the continuation MultiMonitors.au3 I know that I know nothing Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now