2015-12-17 8 views
1

В настоящее время я определяю, на каком экране находится окно, проверяя, на каком экране это очень левое верхнее положение. Теперь я хотел бы изменить это, чтобы я смог узнать, на какой scren будет найдена наибольшая площадь поверхности окна.
Любые идеи, как это можно сделать?Определение того, на каком экране находится окно (путем проверки того, где находится наибольшая площадь поверхности)

Вот мой старый код: (она просто перемещает активное окно между всеми доступными экранами при нажатии F1)

F1:: 
    WinGetPos, X, Y,,, A 
    window := {x:X,y:Y} 
    monitors := GetMonitors() 
    Loop % monitors.MaxIndex() { 
     curMonitor := monitors[A_Index] 
     If IsPointInRectange(window,curMonitor) { 
      nextMonitorIndex := (A_Index = monitors.MaxIndex() ? 1 : A_Index+1) 
      nextMonitor := monitors[nextMonitorIndex] 
      percPos := {} 
      percPos.x := (window.x-curMonitor.x1)/(curMonitor.x2-curMonitor.x1) 
      percPos.y := (window.y-curMonitor.y1)/(curMonitor.y2-curMonitor.y1) 
      windowNew := {} 
      windowNew.x := nextMonitor.x1+(nextMonitor.x2-nextMonitor.x1)*percPos.x 
      windowNew.y := nextMonitor.y1+(nextMonitor.y2-nextMonitor.y1)*percPos.y 
      WinMove, A,, windowNew.x, windowNew.y 

     } 
    } 
Return 

IsPointInRectange(point,rect) { 
    If point.x >= rect.x1 && point.x < rect.x2 
    && point.y >= rect.y1 && point.y < rect.y2 
     Return True 
} 

GetMonitors() { 
    monitors := [] 
    SysGet, monCount, 80 ;SM_CMONITORS 
    Loop % monCount { 
     SysGet, mon, Monitor, %A_Index% 
     monitors[A_Index] := {x1: monLeft, x2: monRight, y1: monTop, y2: monBottom} 
    } 
    Return monitors 
} 
+0

, если вы знаете, положение, ширину и высоту окна и ширины и высоты ваших мониторов, вы можете также вычислить прямоугольные поверхности в каждой из них – Blauhirn

+0

Просто вычислить центр вашего окна (влево + вправо)/2 Центральная точка определяет экран с самой большой недвижимостью. –

+0

@RobertIlbrink Нет, это не потому, что центр не обязательно находится на любом экране ... – Forivin

ответ

1

MonitorFromWindow() Было решение. :) Вот новый код: (?)

;Win+Enter to move the active window to the next screen 
#Enter:: 
    WinGet, activeWindowHwnd, ID, A 
    activeMonitorHwnd := MDMF_FromHWND(activeWindowHwnd) 
    monitors := MDMF_Enum() 

    monitorHwndList := [] 
    For currentMonitorHwnd, info In monitors 
     monitorHwndList[A_Index] := currentMonitorHwnd 

    nextMonitorHwnd := "" 
    For currentMonitorHwnd, info In monitors 
     If (currentMonitorHwnd = activeMonitorHwnd) 
      nextMonitorHwnd := (A_Index=monitorHwndList.MaxIndex() ? monitorHwndList[1] : monitorHwndList[A_Index+1]) 

    activeMonitor := MDMF_GetInfo(activeMonitorHwnd) 
    nextMonitor := MDMF_GetInfo(nextMonitorHwnd) 

    WinGetPos, x, y, w, h, ahk_id %activeWindowHwnd% 
    activeWindow := {Left:x, Top:y, Right:x+w, Bottom:y+h} 

    relativePercPos := {} 
    relativePercPos.Left := (activeWindow.Left-activeMonitor.Left)/(activeMonitor.Right-activeMonitor.Left) 
    relativePercPos.Top := (activeWindow.Top-activeMonitor.Top)/(activeMonitor.Bottom-activeMonitor.Top) 
    relativePercPos.Right := (activeWindow.Right-activeMonitor.Left)/(activeMonitor.Right-activeMonitor.Left) 
    relativePercPos.Bottom := (activeWindow.Bottom-activeMonitor.Top)/(activeMonitor.Bottom-activeMonitor.Top) 

    ;MsgBox % activeWindow.Top "`n" activeWindow.Left " - " activeWindow.Right "`n" activeWindow.Bottom 
    ;MsgBox % relativePercPos.Top*100 "`n" relativePercPos.Left*100 " - " relativePercPos.Right*100 "`n" relativePercPos.Bottom*100 

    activeWindowNewPos := {} 
    activeWindowNewPos.Left := nextMonitor.Left+(nextMonitor.Right-nextMonitor.Left)*relativePercPos.Left 
    activeWindowNewPos.Top := nextMonitor.Top+(nextMonitor.Bottom-nextMonitor.Top)*relativePercPos.Top 

    WinMove, A,, activeWindowNewPos.Left, activeWindowNewPos.Top 
Return 

;Credits to "just me" for the following code: 

; ====================================================================================================================== 
; Multiple Display Monitors Functions -> msdn.microsoft.com/en-us/library/dd145072(v=vs.85).aspx ======================= 
; ====================================================================================================================== 
; Enumerates display monitors and returns an object containing the properties of all monitors or the specified monitor. 
; ====================================================================================================================== 
MDMF_Enum(HMON := "") { 
    Static EnumProc := RegisterCallback("MDMF_EnumProc") 
    Static Monitors := {} 
    If (HMON = "") ; new enumeration 
     Monitors := {} 
    If (Monitors.MaxIndex() = "") ; enumerate 
     If !DllCall("User32.dll\EnumDisplayMonitors", "Ptr", 0, "Ptr", 0, "Ptr", EnumProc, "Ptr", &Monitors, "UInt") 
     Return False 
    Return (HMON = "") ? Monitors : Monitors.HasKey(HMON) ? Monitors[HMON] : False 
} 
; ====================================================================================================================== 
; Callback function that is called by the MDMF_Enum function. 
; ====================================================================================================================== 
MDMF_EnumProc(HMON, HDC, PRECT, ObjectAddr) { 
    Monitors := Object(ObjectAddr) 
    Monitors[HMON] := MDMF_GetInfo(HMON) 
    Return True 
} 
; ====================================================================================================================== 
; Retrieves the display monitor that has the largest area of intersection with a specified window. 
; ====================================================================================================================== 
MDMF_FromHWND(HWND) { 
    Return DllCall("User32.dll\MonitorFromWindow", "Ptr", HWND, "UInt", 0, "UPtr") 
} 
; ====================================================================================================================== 
; Retrieves the display monitor that contains a specified point. 
; If either X or Y is empty, the function will use the current cursor position for this value. 
; ====================================================================================================================== 
MDMF_FromPoint(X := "", Y := "") { 
    VarSetCapacity(PT, 8, 0) 
    If (X = "") || (Y = "") { 
     DllCall("User32.dll\GetCursorPos", "Ptr", &PT) 
     If (X = "") 
     X := NumGet(PT, 0, "Int") 
     If (Y = "") 
     Y := NumGet(PT, 4, "Int") 
    } 
    Return DllCall("User32.dll\MonitorFromPoint", "Int64", (X & 0xFFFFFFFF) | (Y << 32), "UInt", 0, "UPtr") 
} 
; ====================================================================================================================== 
; Retrieves the display monitor that has the largest area of intersection with a specified rectangle. 
; Parameters are consistent with the common AHK definition of a rectangle, which is X, Y, W, H instead of 
; Left, Top, Right, Bottom. 
; ====================================================================================================================== 
MDMF_FromRect(X, Y, W, H) { 
    VarSetCapacity(RC, 16, 0) 
    NumPut(X, RC, 0, "Int"), NumPut(Y, RC, 4, Int), NumPut(X + W, RC, 8, "Int"), NumPut(Y + H, RC, 12, "Int") 
    Return DllCall("User32.dll\MonitorFromRect", "Ptr", &RC, "UInt", 0, "UPtr") 
} 
; ====================================================================================================================== 
; Retrieves information about a display monitor. 
; ====================================================================================================================== 
MDMF_GetInfo(HMON) { 
    NumPut(VarSetCapacity(MIEX, 40 + (32 << !!A_IsUnicode)), MIEX, 0, "UInt") 
    If DllCall("User32.dll\GetMonitorInfo", "Ptr", HMON, "Ptr", &MIEX) { 
     MonName := StrGet(&MIEX + 40, 32) ; CCHDEVICENAME = 32 
     MonNum := RegExReplace(MonName, ".*(\d+)$", "$1") 
     Return {Name:  (Name := StrGet(&MIEX + 40, 32)) 
      , Num:  RegExReplace(Name, ".*(\d+)$", "$1") 
      , Left:  NumGet(MIEX, 4, "Int") ; display rectangle 
      , Top:  NumGet(MIEX, 8, "Int") ; " 
      , Right:  NumGet(MIEX, 12, "Int") ; " 
      , Bottom: NumGet(MIEX, 16, "Int") ; " 
      , WALeft: NumGet(MIEX, 20, "Int") ; work area 
      , WATop:  NumGet(MIEX, 24, "Int") ; " 
      , WARight: NumGet(MIEX, 28, "Int") ; " 
      , WABottom: NumGet(MIEX, 32, "Int") ; " 
      , Primary: NumGet(MIEX, 36, "UInt")} ; contains a non-zero value for the primary monitor. 
    } 
    Return False 
}