Autohotkey Fullscreening With Cmd.exe - cmd

Using ahk, what script can I use to fullscreen cmd on windows 7?
I have already managed to fullscreen with windows 10, but on windows 7 it looks like this.
However you can see the on the top and left side there are borders, I am using the following script.
WinGetTitle, currentWindow, A
IfWinExist %currentWindow%
{
WinSet, Style, ^0xC00000 ; toggle title bar
}
return
What can I do to make it work?

Perhaps you need to remove the border?
Try this:
/* YABT+ - Yet Another Borderless-Window Toggle
* by Barrow (March 30, 2012)
* rewritten by kon (May 16, 2014)
* http://www.autohotkey.com/board/topic/78903-yabt-yet-another-borderless-window-toggle/page-2#entry650488
* updated by Hastarin (Dec 5, 2014)
* updated by WAZAAAAA (Sep 27, 2016)
* tested with AutoHotkey v1.1.24.01
*/
WinGetTitle, currentWindow, A
IfWinExist %currentWindow%
{
Toggle_Window(WinExist(currentWindow))
}
Toggle_Window(Window:="") {
static A := Init()
if (!Window)
MouseGetPos,,, Window
WinGet, S, Style, % (i := "_" Window) ? "ahk_id " Window : ; Get window style
if (S & +0xC00000) { ; If not borderless
WinGet, IsMaxed, MinMax, % "ahk_id " Window
if (A[i, "Maxed"] := IsMaxed = 1 ? true : false)
WinRestore, % "ahk_id " Window
WinGetPos, X, Y, W, H, % "ahk_id " Window ; Store window size/location
for k, v in ["X", "Y", "W", "H"]
A[i, v] := %v%
Loop, % A.MCount { ; Determine which monitor to use
if (X >= A.Monitor[A_Index].Left
&& X < A.Monitor[A_Index].Right
&& Y >= A.Monitor[A_Index].Top
&& Y < A.Monitor[A_Index].Bottom) {
WinSet, Style, -0xC00000, % "ahk_id " Window ; Remove borders
WinSet, Style, -0x40000, % "ahk_id " Window ; Including the resize border
WinSet, ExStyle, -0x00000200, % "ahk_id " Window ;Also WS_EX_CLIENTEDGE
; The following lines are the x,y,w,h of the maximized window
; ie. to offset the window 10 pixels up: A.Monitor[A_Index].Top - 10
WinMove, % "ahk_id " Window,
, A.Monitor[A_Index].Left ; X position
, A.Monitor[A_Index].Top ; Y position
, A.Monitor[A_Index].Right - A.Monitor[A_Index].Left ; Width
, A.Monitor[A_Index].Bottom - A.Monitor[A_Index].Top ; Height
break
}
}
}
else if (S & -0xC00000) { ; If borderless
WinSet, Style, +0x40000, % "ahk_id " Window ; Reapply borders
WinSet, Style, +0xC00000, % "ahk_id " Window
WinSet, ExStyle, +0x00000200, % "ahk_id " Window ;Also WS_EX_CLIENTEDGE
WinMove, % "ahk_id " Window,, A[i].X, A[i].Y, A[i].W, A[i].H ; Return to original position
if (A[i].Maxed)
WinMaximize, % "ahk_id " Window
A.Remove(i)
}
}
Init() {
A := {}
SysGet, n, MonitorCount
Loop, % A.MCount := n {
SysGet, Mon, Monitor, % i := A_Index
for k, v in ["Left", "Right", "Top", "Bottom"]
A["Monitor", i, v] := Mon%v%
}
return A
}

Related

Select whole words when mouse hovers over- Autohotkey

If the cursor is of the IBeam type and the F20 key is pressed and dragged, the text is selected with the shortcut Ctrl + Shift + right (or in the direction to which it is moved) .
Is there any way of doing this? https://imgur.com/a/Rqrfwjk
I have this code but it is based on the number of pixels moved and not on whether the cursor is over a word
#If WinActive("ahk_exe chrome.exe") && A_Cursor = "IBeam"
~LButton::
Click
MouseGetPos, x1
SetTimer, Check, 100
SoundBeep, 1500
KeyWait, LButton
SetTimer, Check, Off
SoundBeep, 1000
Return
#If
Check:
MouseGetPos, x2
f := Floor(Abs((x2 - x1) / 110))
Switch
{
Case x2 > x1: Send ^+{Right %f%}
Case x2 < x1: Send % "{Right}^+{Left " f + 1 "}"
}
Return

Quick selection script issue

I have this autohotkey script that points to the entire word by pointing to the first word and if the cursor scrolls 110px in one direction. The code uses Ctrl + Shift + {Right} to select the next words, but for the previous words you can't use Ctrl + Shift + {Left} because the current word is deselected.
How could I solve this problem so that it selects well in this direction?
#If WinActive("ahk_exe chrome.exe") && A_Cursor = "IBeam" ; Is in Chrome and cursor is on text field
~LButton::
Click
MouseGetPos, x1
SetTimer, Check, 100
SoundBeep, 1500
KeyWait, LButton
SetTimer, Check, Off
SoundBeep, 1000
Return
#If
Check:
MouseGetPos, x2
f := Floor(Abs((x2 - x1) / 110)) ; calculate if the pointer have travel 110px
Switch
{
Case x2 > x1: Send ^+{Right %f%}
Case x2 < x1: Send % "{Right}^+{Left " f + 1 "}" ;Does not allow selecting the previous word while keeping the current word selected
}
Return

Is there some way to set a window's focus without changing its relative zorder?

There is a bug in an application (IntelliJ IDEA) where it fails to honour focus follows mouse (X-mouse). When I move the mouse on top of IntelliJ, it flashes the window. I figure I could capture the flashing and just force it to have focus. Tried this using AHK. It almost worked (got the RegisterShellHookWindow to work and it would run the call back message), but I couldn't give the window focus using SetFocus, presumably because I was in a different process space? I've tried some other ways to give the window focus, but all seem to raise the window, which isn't acceptable.
Is there some manner which I could force a window to capture focus in a different process space or is this not possible due to some security restrictions?
Here is the AHK code (with debugging statements) if anyone is interested (though it doesn't have to be written in AHK):
; Register shell hook to detect flashing windows.
DllCall("RegisterShellHookWindow", "Ptr", A_ScriptHwnd)
OnMessage(DllCall("RegisterWindowMessage", "Str", "SHELLHOOK"), "ShellEvent")
FHex( int, pad=0 ) { ; Function by [VxE]. Formats an integer (decimals are truncated) as hex.
; "Pad" may be the minimum number of digits that should appear on the right of the "0x".
Static hx := "0123456789ABCDEF"
If !( 0 < int |= 0 )
Return !int ? "0x0" : "-" FHex( -int, pad )
s := 1 + Floor( Ln( int ) / Ln( 16 ) )
h := SubStr( "0x0000000000000000", 1, pad := pad < s ? s + 2 : pad < 16 ? pad + 2 : 18 )
u := A_IsUnicode = 1
Loop % s
NumPut( *( &hx + ( ( int & 15 ) << u ) ), h, pad - A_Index << u, "UChar" ), int >>= 4
Return h
}
FlashWindowEx(hWnd := 0, dwFlags := 0, uCount := 0, dwTimeout := 0) {
Static A64 := (A_PtrSize = 8 ? 4 : 0) ; alignment for pointers in 64-bit environment
Static cbSize := 4 + A64 + A_PtrSize + 4 + 4 + 4 + A64
VarSetCapacity(FLASHWINFO, cbSize, 0) ; FLASHWINFO structure
Addr := &FLASHWINFO
Addr := NumPut(cbSize, Addr + 0, 0, "UInt")
Addr := NumPut(hWnd, Addr + 0, A64, "Ptr")
Addr := NumPut(dwFlags, Addr + 0, 0, "UInt")
Addr := NumPut(uCount, Addr + 0, 0, "UInt")
Addr := NumPut(dwTimeout, Addr + 0, 0, "Uint")
Return DllCall("User32.dll\FlashWindowEx", "Ptr", &FLASHWINFO, "UInt")
}
SetFocus(HWND) {
HPREV := HWND
While (HPREV := DllCall("User32.dll\GetWindow", "Ptr", HPREV, "UInt", 3, "UPtr")) ; GW_HWNDPREV = 3
If DllCall("User32.dll\IsWindowVisible", "Ptr", HPREV, "UInt")
Break
WinActivate, ahk_id %HWND%
If (HPREV)
DllCall("User32.dll\SetWindowPos", "Ptr", HWND, "Ptr", HPREV, "Int", 0, "Int", 0, "Int", 0, "Int", 0, "UInt", 0x0B)
}
ShellEvent(wParam, lParam) {
_wParam := FHex(wParam)
_lParam := FHex(lParam)
X := 0
Y := 0
MouseGetPos, X, Y
ToolTip % "1: (" . X . ", " . Y . ") Trying to activate " . _wParam . ", " . _lParam . ".", (X+1), (Y+1),1
if (wParam = 0x8006) ; HSHELL_FLASH
{ ; lParam contains the ID of the window which flashed:
FlashWindowEx(lParam)
;WinActivate, ahk_id %lParam%
;SetFocus(lParam)
DLLCall("User32.dll\SetFocus", "Ptr", lParam, "Ptr")
ToolTip % "2: (" . X . ", " . Y . ") Trying to activate " _wParam . ", " . _lParam . ".", (X+1), (Y+21),2
}
}

Use windows key as part of keyboard shortcut in Visual Studio 2017

I have a global hotkey (in AutoHotkey) that uses ctrl+alt+win+1, but Visual Studio 2017 registers this as ctrl+alt+1, causing a conflict between these two programs.
According to a previous question it is impossible to use # (windows) key as part of Visual Studio keyboard shortcut, but is there a way to have it not respond to commands that do use it?
It is difficult to say how to solved this, i can not see in your question what Ahk Script it is, but you can try, this on your Windows System:
1 - You can run a external Ahk Script (in the Background) [KeypressToReg.ahk] this Script can Scan All you Keyboard Movements and then put it into Only One [Windows Registry Key]
This is only a Simulation to Show you, that it Will Write the Keypress Value to a Single Register key.
2 - Then You can run Visual Studio 2017 and Look [What Value it is] if you press the key [Ctrl+Alt+Win+1]
(You can use this Ahk Script [ShowKeypressValue.ahk]) (Note - this script is only to let you see what Value it is.)
3 - Now you can Simple use that String Value "Ctrl + Alt + LWin + 1" without to must have using this ^!{LWin}1::, to execute any kind of Ahk Codes. (you can even Make a Short Script From Other Languages Like Visual Studio 2017, you only need to acces that registry key.)
loop
{
RegRead, KeypressValue, HKEY_CURRENT_USER,software\GetKeypressValue,KeypressValue ; read KeypressValue
if (KeypressValue="Ctrl + Alt + LWin + 1")
{
; Here you can put the code.
;WriteReg_KeypressValue("He it Works")
}
}
ShowKeypressValue.ahk
#SingleInstance force
Gui, +AlwaysOnTop -MaximizeBox
Gui, Add, Text, center y10 h50 w300 vVar, %KeypressValue%
Gui, Color, White
Gui, show
size=18
Gui, Font, s%size%
GuiControl, Font, var
loop
{
RegRead, KeypressValue, HKEY_CURRENT_USER,software\GetKeypressValue,KeypressValue ; read KeypressValue
if (KeypressValue="Ctrl + Alt + LWin + 1")
{
; Here you can put the code.
;WriteReg_KeypressValue("He it Works")
}
sleep 50
GuiControl,, var, %KeypressValue%
}
~esc::exitapp
WriteReg_KeypressValue(a)
{
RegWrite, REG_SZ, HKEY_CURRENT_USER,software\GetKeypressValue,KeypressValue,%a% ;Write the KeypressValue
}
[KeypressToReg.ahk]
; KeypressToReg.ahk comes from KeypressOSD.ahk By RaptorX
; The Changelog you will find it on the Bottom of the script.
;This code works with a getkeyname from a Dllcall (See Bottom Script- by Lexikos)
;you can press the esc key to exit.
#SingleInstance force
#NoEnv
SetBatchLines, -1
ListLines, Off
; Settings
global TransN := 200 ; 0~255
global ShowSingleKey := True
global ShowMouseButton := True
global ShowSingleModifierKey := True
global ShowModifierKeyCount := true
global ShowStickyModKeyCount := false
global DisplayTime := 2000 ; In milliseconds
global GuiPosition := "Bottom" ; Top or Bottom
global FontSize := 50
global GuiHeight := 115
CreateGUI()
CreateHotkey()
return
OnKeyPressed:
try {
key := GetKeyStr()
ShowHotkey(key)
SetTimer, HideGUI, % -1 * DisplayTime
}
return
OnKeyUp:
return
_OnKeyUp:
tickcount_start := A_TickCount
return
CreateGUI() {
global
Gui, +AlwaysOnTop -Caption +Owner +LastFound +E0x20
Gui, Margin, 0, 0
Gui, Color, Black
Gui, Font, cWhite s%FontSize% bold, Arial
Gui, Add, Text, vHotkeyText Center y20
WinSet, Transparent, %TransN%
}
CreateHotkey() {
Loop, 95
{
k := Chr(A_Index + 31)
k := (k = " ") ? "Space" : k
Hotkey, % "~*" k, OnKeyPressed
Hotkey, % "~*" k " Up", _OnKeyUp
}
Loop, 24 ; F1-F24
{
Hotkey, % "~*F" A_Index, OnKeyPressed
Hotkey, % "~*F" A_Index " Up", _OnKeyUp
}
Loop, 10 ; Numpad0 - Numpad9
{
Hotkey, % "~*Numpad" A_Index - 1, OnKeyPressed
Hotkey, % "~*Numpad" A_Index - 1 " Up", _OnKeyUp
}
Otherkeys := "WheelDown|WheelUp|WheelLeft|WheelRight|XButton1|XButton2|Browser_Forward|Browser_Back|Browser_Refresh|Browser_Stop|Browser_Search|Browser_Favorites|Browser_Home|Volume_Mute|Volume_Down|Volume_Up|Media_Next|Media_Prev|Media_Stop|Media_Play_Pause|Launch_Mail|Launch_Media|Launch_App1|Launch_App2|Help|Sleep|PrintScreen|CtrlBreak|Break|AppsKey|NumpadDot|NumpadDiv|NumpadMult|NumpadAdd|NumpadSub|NumpadEnter|Tab|Enter|Esc|BackSpace"
. "|Del|Insert|Home|End|PgUp|PgDn|Up|Down|Left|Right|ScrollLock|CapsLock|NumLock|Pause|sc145|sc146|sc046|sc123"
Loop, parse, Otherkeys, |
{
Hotkey, % "~*" A_LoopField, OnKeyPressed
Hotkey, % "~*" A_LoopField " Up", _OnKeyUp
}
If ShowMouseButton {
Loop, Parse, % "LButton|MButton|RButton", |
Hotkey, % "~*" A_LoopField, OnKeyPressed
}
for i, mod in ["Ctrl", "Shift", "Alt"] {
Hotkey, % "~*" mod, OnKeyPressed
Hotkey, % "~*" mod " Up", OnKeyUp
}
for i, mod in ["LWin", "RWin"]
Hotkey, % "~*" mod, OnKeyPressed
}
ShowHotkey(HotkeyStr) {
WinGetPos, ActWin_X, ActWin_Y, ActWin_W, ActWin_H, A
if !ActWin_W
throw
text_w := (ActWin_W > A_ScreenWidth) ? A_ScreenWidth : ActWin_W
;GuiControl, , HotkeyText, %HotkeyStr%
;GuiControl, Move, HotkeyText, w%text_w% Center
RegWrite, REG_SZ, HKEY_CURRENT_USER,software\GetKeypressValue,KeypressValue,%HotkeyStr%
if (GuiPosition = "Top")
gui_y := ActWin_Y
else
gui_y := (ActWin_Y+ActWin_H) - 115 - 50
;Gui, Show, NoActivate x%ActWin_X% y%gui_y% h%GuiHeight% w%text_w%
}
GetKeyStr() {
static modifiers := ["Ctrl", "Shift", "Alt", "LWin", "RWin"]
static repeatCount := 1
for i, mod in modifiers {
if GetKeyState(mod)
prefix .= mod " + "
}
if (!prefix && !ShowSingleKey)
throw
key := SubStr(A_ThisHotkey, 3)
if (key ~= "i)^(Ctrl|Shift|Alt|LWin|RWin)$") {
if !ShowSingleModifierKey {
throw
}
key := ""
prefix := RTrim(prefix, "+ ")
if ShowModifierKeyCount {
if !InStr(prefix, "+") && IsDoubleClickEx() {
if (A_ThisHotKey != A_PriorHotKey) || ShowStickyModKeyCount {
if (++repeatCount > 1) {
prefix .= " ( * " repeatCount " )"
}
} else {
repeatCount := 0
}
} else {
repeatCount := 1
}
}
} else {
if ( StrLen(key) = 1 ) {
key := GetKeyChar(key, "A")
} else if ( SubStr(key, 1, 2) = "sc" ) {
key := SpecialSC(key)
} else if (key = "LButton") && IsDoubleClick() {
key := "Double-Click"
}
_key := (key = "Double-Click") ? "LButton" : key
static pre_prefix, pre_key, keyCount := 1
global tickcount_start
if (prefix && pre_prefix) && (A_TickCount-tickcount_start < 300) {
if (prefix != pre_prefix) {
result := pre_prefix pre_key ", " prefix key
} else {
keyCount := (key=pre_key) ? (keyCount+1) : 1
key := (keyCount>2) ? (key " (" keyCount ")") : (pre_key ", " key)
}
} else {
keyCount := 1
}
pre_prefix := prefix
pre_key := _key
repeatCount := 1
}
return result ? result : prefix . key
}
SpecialSC(sc) {
static k := {sc046: "ScrollLock", sc145: "NumLock", sc146: "Pause", sc123: "Genius LuxeMate Scroll"}
return k[sc]
}
; by Lexikos - https://autohotkey.com/board/topic/110808-getkeyname-for-other-languages/#entry682236
GetKeyChar(Key, WinTitle:=0) {
thread := WinTitle=0 ? 0
: DllCall("GetWindowThreadProcessId", "ptr", WinExist(WinTitle), "ptr", 0)
hkl := DllCall("GetKeyboardLayout", "uint", thread, "ptr")
vk := GetKeyVK(Key), sc := GetKeySC(Key)
VarSetCapacity(state, 256, 0)
VarSetCapacity(char, 4, 0)
n := DllCall("ToUnicodeEx", "uint", vk, "uint", sc
, "ptr", &state, "ptr", &char, "int", 2, "uint", 0, "ptr", hkl)
return StrGet(&char, n, "utf-16")
}
IsDoubleClick(MSec = 300) {
Return (A_ThisHotKey = A_PriorHotKey) && (A_TimeSincePriorHotkey < MSec)
}
IsDoubleClickEx(MSec = 300) {
preHotkey := RegExReplace(A_PriorHotkey, "i) Up$")
Return (A_ThisHotKey = preHotkey) && (A_TimeSincePriorHotkey < MSec)
}
HideGUI() {
Gui, Hide
}
esc::exitapp
;---------------------------------------------
; ChangeLog : v2.22 (2017-02-25) - Now pressing the same combination keys continuously more than 2 times,
; for example press Ctrl+V 3 times, will displayed as "Ctrl + v (3)"
; v2.21 (2017-02-24) - Fixed LWin/RWin not poping up start menu
; v2.20 (2017-02-24) - Added displaying continuous-pressed combination keys.
; e.g.: With CTRL key held down, pressing K and U continuously will shown as "Ctrl + k, u"
; v2.10 (2017-01-22) - Added ShowStickyModKeyCount option
; v2.09 (2017-01-22) - Added ShowModifierKeyCount option
; v2.08 (2017-01-19) - Fixed a bug
; v2.07 (2017-01-19) - Added ShowSingleModifierKey option (default is True)
; v2.06 (2016-11-23) - Added more keys. Thanks to SashaChernykh.
; v2.05 (2016-10-01) - Fixed not detecting "Ctrl + ScrollLock/NumLock/Pause". Thanks to lexikos.
; v2.04 (2016-10-01) - Added NumpadDot and AppsKey
; v2.03 (2016-09-17) - Added displaying "Double-Click" of the left mouse button.
; v2.02 (2016-09-16) - Added displaying mouse button, and 3 settings (ShowMouseButton, FontSize, GuiHeight)
; v2.01 (2016-09-11) - Display non english keyboard layout characters when combine with modifer keys.
; v2.00 (2016-09-01) - Removed the "Fade out" effect because of its buggy.
; - Added support for non english keyboard layout.
; - Added GuiPosition setting.
; v1.00 (2013-10-11) - First release.
;--------------------------------------------

Determining which screen a window is on (by checking where the most surfacearea is located)

I'm currently determining which screen a window is on, by checking on which screen it's very left-top position is. Now I'd like to change that so that I can find out on which scren the most surface area of the window is to be found.
Any ideas how that can be accomplished?
Here is my old code:
(it simply moves the active window between all available screens when pressing 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
}
MonitorFromWindow() Was the solution. :)
Here is new the code:
;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
}

Resources