Jump to content
tcurran

Which Monitor is a Window On?

Recommended Posts

tcurran

Given a specific XY coordinate, this snippet returns the handle to the monitor the coordinate appears on... or 0 if it is off all screens. Particularly useful in multiple monitor setups where monitors have different resolutions or are offset vertically or horizontally (in which case, there are areas of the virtual desktop that are off all screens).

You could also use it to return the handle of the monitor where a window is placed, or where the mouse was clicked, or other similar applications.

#include <WinAPIGdi.au3> ;for _WinOnMonitor()

Func _WinOnMonitor($iXPos, $iYPos)
    Local $aMonitors = _WinAPI_EnumDisplayMonitors()
    If IsArray($aMonitors) Then
        ReDim $aMonitors[$aMonitors[0][0] + 1][5]
        For $ix = 1 To $aMonitors[0][0]
            $aPos = _WinAPI_GetPosFromRect($aMonitors[$ix][1])
            For $j = 0 To 3
                $aMonitors[$ix][$j + 1] = $aPos[$j]
            Next
        Next
    EndIf
    For $ixMonitor = 1 to $aMonitors[0][0] ; Step through array of monitors
        If $iXPos > $aMonitors[$ixMonitor][1] And $iXPos <  $aMonitors[$ixMonitor][1] + $aMonitors[$ixMonitor][3] Then
            If $iYPos > $aMonitors[$ixMonitor][2] And $iYPos < $aMonitors[$ixMonitor][2] + $aMonitors[$ixMonitor][4] Then
                Return $aMonitors[$ixMonitor][0] ; return handle to monitor coordinate is on
            EndIf
        EndIf
    Next
    Return 0 ;Return 0 if coordinate is on none of the monitors
EndFunc ;==>  _WinOnMonitor

 

Edited by tcurran
  • Like 1

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • jaberwacky
      By jaberwacky
      I'm working on a script for one or more monitors that will wrap the mouse around the monitors and yet still allow you to drag windows to the edge of the monitor for the Windows 7 Snap feature. 
      So, this is a basic script that does what I set out to do.  I think it will even work on multiple monitors.
      If you have more than two monitors and want to test then I will love you forever.
      [update -- 05/19/2013] This update has a major difference.  When the user drags the mouse to the edge of a monitor there is a 300 millisecond delay before the mouse will wrap.  This will give the user some time to change their mind.  When the user drags a window or selection rectangle to the edge of a monitor the user will have 700 milliseconds to take advantage of the Windows 7 Snap feature.  If the user has not moved the mouse from the edge within that time then the window will move to the opposite edge.  There are several speed optimizations without getting too silly and wishy washy.
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_testing=y #AutoIt3Wrapper_Run_AU3Check=n #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_AU3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -w 7 -d #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; ============================================================================ ; = MosueWrap:                                                              = ; =     I intend to allow for mouse wrap action but still be able to utilize = ; =     the Windows 7 Snap feature.                                          = ; =     Should work on any number of monitors.                               = ; =                                                                         = ; = Credits:                                                                = ; =   Guinness, etc.                                                        = ; ============================================================================ #include <Misc.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> _Singleton(@ScriptName) Global Const $mouse_proc_callback = DllCallbackRegister("mouse_proc", "long", "int;wparam;lparam") Global Const $hook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($mouse_proc_callback), _WinAPI_GetModuleHandle(0)) Global Const $user32 = DllOpen("User32.Dll") OnAutoItExitRegister("cleanup") Global $mouse_hover_time = 300 Global $vertical = True Global $horizontal = True Global $paused = True Do   Switch Not $paused     Case True       mouse_wrap()       $paused = True   EndSwitch   Sleep(25) Until False Func mouse_proc($code, $w_param, $l_param)   Switch $code >= 0     Case True       Switch $w_param         Case $WM_LBUTTONDOWN, $WM_RBUTTONDOWN           $mouse_hover_time = 700         Case $WM_LBUTTONUP, $WM_RBUTTONUP           $mouse_hover_time = 300         Case $WM_MOUSEMOVE           $paused = False         EndSwitch   EndSwitch   Return _WinAPI_CallNextHookEx($hook, $code, $w_param, $l_param) EndFunc Func mouse_wrap()   Static Local $virtual_desktop_width = _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN) - 1   Static Local $last_x = -1   Static Local $last_y = -1   Local Const $x = MouseGetPos(0)   Local Const $y = MouseGetPos(1)   Switch ($last_x <> $x) Or ($last_y <> $y)     Case True       $last_x = $x       $last_y = $y       Switch $horizontal         Case True           Select             Case $x = 0               Switch hovertime_left_right(0)                 Case True                   MouseMove($virtual_desktop_width, $y, 0)                   Return True               EndSwitch             Case $x = $virtual_desktop_width               Switch hovertime_left_right($virtual_desktop_width)                 Case True                   MouseMove(1, $y, 0)                   Return True               EndSwitch           EndSelect       EndSwitch       Switch $vertical         Case True           Local Const $monitor_height = get_monitor_height($x, $y) - 1           Select             Case $y = 0               Switch hovertime_top_bottom(0)                 Case True                   MouseMove($x, $monitor_height, 0)               EndSwitch             Case $y = $monitor_height               Switch hovertime_top_bottom($monitor_height)                 Case True                   MouseMove($x, 1, 0)               EndSwitch           EndSelect       EndSwitch   EndSwitch   Return True EndFunc Func hovertime_top_bottom(Const ByRef $edge)   Local Const $hover_time = TimerInit()   Do     Switch MouseGetPos(1) <> $edge       Case True         Return False     EndSwitch   Until Round(TimerDiff($hover_time)) = $mouse_hover_time   Return True EndFunc Func hovertime_left_right(Const ByRef $edge)   Local Const $hover_time = TimerInit()   Do     Switch MouseGetPos(0) <> $edge       Case True         Return False     EndSwitch   Until Round(TimerDiff($hover_time)) = $mouse_hover_time   Return True EndFunc Func get_monitor_height(Const ByRef $x, Const ByRef $y)   Static Local $point = DllStructCreate($tagPOINT)   DllStructSetData($point, 'x', $x)   DllStructSetData($point, 'y', $y)   Local Const $monitor_handle = _WinAPI_MonitorFromPoint($point)   Local Const $monitor_info = _WinAPI_GetMonitorInfo($monitor_handle)   Return DllStructGetData($monitor_info[1], 4) EndFunc #region ; WinAPIEx ; #FUNCTION# ==================================================================================================================== ; Name...........: _WinAPI_GetMonitorInfo ; Description....: Retrieves information about a display monitor. ; Syntax.........: _WinAPI_GetMonitorInfo ( $hMonitor ) ; Parameters.....: $hMonitor - A handle to the display monitor of interest. ; Return values..: Success   - The array containing the following information: ; ;                              [0] - $tagRECT structure that specifies the display monitor rectangle, in virtual-screen coordinates. ;                              [1] - $tagRECT structure that specifies the work area rectangle of the display monitor that can be used by applications, in virtual-screen coordinates. ;                              [2] - 1 (True) for the primary display monitor, or 0 (False) otherwise. ;                              [3] - The device name of the monitor being used, e.g. "\\.\DISPLAY1". ;                  Failure - 0 and sets the @error flag to non-zero. ; Author.........: Yashied ; Modified.......: ; Remarks........: None ; Related........: ; Link...........: @@MsdnLink@@ GetMonitorInfo ; Example........: Yes ; =============================================================================================================================== Func _WinAPI_GetMonitorInfo(Const ByRef $hMonitor)   ; I set these to static because I didn't want them to execute everytime the function entered.   Static Local $tMIEX = DllStructCreate("dword;long[4];long[4];dword;wchar[32]")   Static Local $size = DllStructGetSize($tMIEX)   Static Local $miex_size = DllStructSetData($tMIEX, 1, $size)   Local Const $Ret = DllCall($user32, "int", "GetMonitorInfoW", "ptr", $hMonitor, "ptr", DllStructGetPtr($tMIEX))   If (@error) Or (Not $Ret[0]) Then Return SetError(1, 0, False)   Static Local $ptr[2] = [DllStructGetPtr($tMIEX, 1), DllStructGetPtr($tMIEX, 2)]   Local $Result[4]   For $i = 0 To 1     $Result[$i] = DllStructCreate($tagRECT)     If Not _WinAPI_MoveMemory(DllStructGetPtr($Result[$i]), $ptr[$i], 16) Then       Return SetError(2, 0, False)     EndIf   Next   Switch DllStructGetData($tMIEX, 4)     Case 1 ; MONITORINFOF_PRIMARY       $Result[2] = 1     Case Else       $Result[2] = 0   EndSwitch   $Result[3] = DllStructGetData($tMIEX, 5)   Return $Result EndFunc ; #FUNCTION# ==================================================================================================================== ; Name...........: _WinAPI_MonitorFromPoint ; Description....: Retrieves a handle to the display monitor that contains a specified point. ; Syntax.........: _WinAPI_MonitorFromPoint ( $tPOINT [, $iFlag] ) ; Parameters.....: $tPOINT - $tagPOINT structure that specifies the point of interest in virtual-screen coordinates. ;                  $iFlag  - The flag that specifies the function's return value if the point is not contained within any display ;                            monitor. This parameter can be one of the following values. ;                            $MONITOR_DEFAULTTONEAREST ;                            $MONITOR_DEFAULTTONULL ;                            $MONITOR_DEFAULTTOPRIMARY ; Return values..: Success - A handle to the display monitor that contains a specified point, or the value depends on the ;                            $MONITOR_* constant. ;                  Failure - 0 and sets the @error flag to non-zero. ; Author.........: Yashied ; Modified.......: ; Remarks........: None ; Related........: ; Link...........: @@MsdnLink@@ MonitorFromPoint ; Example........: Yes ; =============================================================================================================================== Func _WinAPI_MonitorFromPoint(Const ByRef $tPOINT, Const $iFlag = 1)   Static Local $tpoint_ptr = DllStructGetPtr($tPOINT)   Static Local $tPT = DllStructCreate("long[2]", $tpoint_ptr)   Local Const $Ret = DllCall($user32, "ptr", "MonitorFromPoint", "long", DllStructGetData($tPT, 1, 1), "long", DllStructGetData($tPT, 1, 2), "dword", $iFlag)   If (@error) Then Return SetError(1, 0, False)   Return $Ret[0] EndFunc ; #FUNCTION# ==================================================================================================================== ; Name...........: _WinAPI_MoveMemory ; Description....: Moves a block of memory from one location to another. ; Syntax.........: _WinAPI_MoveMemory ( $pDestination, $pSource, $iLength ) ; Parameters.....: $pDestination - A pointer to the starting address of the move destination. ;                  $pSource      - A pointer to the starting address of the block of memory to be moved. ;                  $iLength      - The size of the block of memory to move, in bytes. ; Return values..: Success       - 1. ;                  Failure       - 0 and sets the @error flag to non-zero. ; Author.........: Yashied ; Modified.......: ; Remarks........: The source and destination blocks may overlap. ; Related........: ; Link...........: @@MsdnLink@@ RtlMoveMemory ; Example........: Yes ; =============================================================================================================================== Func _WinAPI_MoveMemory(Const ByRef $pDestination, Const ByRef $pSource, Const ByRef $iLength)   Static Local $ntdll = DllOpen("ntdll.dll")   DllCall($ntdll, "none", "RtlMoveMemory", "ptr", $pDestination, "ptr", $pSource, "ulong_ptr", $iLength)   If (@error) Then Return SetError(1, 0, False)   Return True EndFunc #endregion ; WinAPIEx Func cleanup()   _WinAPI_UnhookWindowsHookEx($hook)   DllCallbackFree($mouse_proc_callback)   DllClose($user32) EndFunc
×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.