Magnification API

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Magnification API

14 May 2017, 10:34

I made a modification of an old 'Magnification API' script:

Magnification API and AutoHotkey - Ask for Help - AutoHotkey Community
http://www.autohotkey.com/board/topic/64060-magnification-api-and-autohotkey/

I have the following issues:
- is it possible to save the current image as a file? [my main concern, I would like to be able to navigate back to an old image if a GUI item disappears]
- does it work on Windows 8, Windows 10?
- why doesn't 100% zoom look exactly the same as the screen
- to make it work in 64-bit (I tried to do this, not sure what the problem is, it shows (0,0) instead of the correct coordinate)
- are there better alternatives, is using Gdip.ahk to printscreen and enlarge and a Static control with an image the best way, or some other way?
- is it possible to acquire the height of a tool window title bar, it doesn't appear to be available via SysGet

Thanks.

Code: Select all

;Magnification API and AutoHotkey - Ask for Help - AutoHotkey Community
;http://www.autohotkey.com/board/topic/64060-magnification-api-and-autohotkey/

OnExit, Uninitialize

vCtlW := 320, vCtlH := 240
vMagFactor := 2
vDoWinWithinScreen := 1
vOffset := 0 ;window within screen offset
;vOffset := 50

Gui, +E0x80000 +AlwaysOnTop +ToolWindow hWndhGui
Gui, Show, % "w" vCtlW " h" vCtlH " x450 y200", MagnifierWindowAHK
WinSet, Transparent, 255, % "ahk_id " hGui
vSfx := (A_PtrSize=8) ? "Ptr" : ""
hInstance := DllCall("GetWindowLong" vSfx, "Ptr",hGui, "Int",-6, "Ptr") ;GWL_HINSTANCE := -6
DllCall("kernel32\LoadLibrary", "Str","magnification.dll", "Ptr")
DllCall("magnification\MagInitialize")
GroupAdd, WinGroupMag, % "ahk_id " hGui

WS_CHILD := 0x40000000
WS_VISIBLE := 0x10000000
MS_SHOWMAGNIFIEDCURSOR := 0x1
vWinStyle := WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE
hCtl := DllCall("user32\CreateWindowEx", "UInt",0, "Str","Magnifier", "Str","MagnifierWindow", "UInt",vWinStyle, "Int",0, "Int",0, "Int",vCtlW, "Int",vCtlH, "Ptr",hGui, "Ptr",0, "Ptr",hInstance, "Ptr",0, "Ptr")

;The transformation matrix is
; (n, 0.0, 0.0)
; (0.0, n, 0.0)
; (0.0, 0.0, 1.0)
;where n is the magnification factor.

VarSetCapacity(MAGTRANSFORM, 36, 0)
NumPut(vMagFactor, MAGTRANSFORM, (1-1)*4, "Float")
NumPut(vMagFactor, MAGTRANSFORM, (5-1)*4, "Float")
NumPut(1, MAGTRANSFORM, (9-1)*4, "Float")

CoordMode, Mouse, Screen
Loop
{
	if !WinActive("ahk_id " hGui)
	{
		Gosub Uninitialize
		return
	}

	MouseGetPos, vMouseX, vMouseY
	if !vGuiW
		WinGetPos,,, vGuiW, vGuiH, % "ahk_id " hGui
	vRectX := vMouseX-(vGuiW/(2*vMagFactor)), vRectY := vMouseY-(vGuiH/(2*vMagFactor))
	vGuiX := vMouseX-(vGuiW/2), vGuiY := vMouseY-(vGuiH/2)
	;account for window title bar
	vRectY += 10/vMagFactor

	DllCall("magnification\MagSetWindowTransform", "Ptr",hCtl, "Ptr",&MAGTRANSFORM)
	;VarSetCapacity(RECT, 16, 0)
	;NumPut(vRectX, RECT, 0, "Int") ;left
	;NumPut(vRectY, RECT, 4, "Int") ;top
	;NumPut(vCtlW, RECT, 8, "Int") ;right ;in this case the width is wanted
	;NumPut(vCtlH, RECT, 12, "Int") ;bottom ;in this case the height is wanted
	DllCall("magnification\MagSetWindowSource", "Ptr",hCtl, "Int",vRectX, "Int",vRectY, "Int",vCtlW, "Int",vCtlH)

	;keep window within screen / certain coordinates
	if vDoWinWithinScreen
	{
		if (vGuiX < vOffset)
			vGuiX := vOffset
		if (vGuiX+vGuiW > A_ScreenWidth-vOffset)
			vGuiX := A_ScreenWidth-vOffset-vGuiW
		if (vGuiY < vOffset)
			vGuiY := vOffset
		if (vGuiY+vGuiH > A_ScreenHeight-vOffset)
			vGuiY := A_ScreenHeight-vOffset-vGuiH
	}

	if (vGuiX2 = vGuiX) && (vGuiY2 = vGuiY)
		Sleep, 700
	else
		WinMove, % "ahk_id " hGui,, % vGuiX, % vGuiY
	Sleep, 300

	vGuiX2 := vGuiX
	vGuiY2 := vGuiY
}
return

#IfWinActive MagnifierWindowAHK ahk_class AutoHotkeyGUI
Esc::
Uninitialize:
Gui, Destroy
DllCall("magnification\MagUninitialize")
ExitApp
#IfWinActive
[900th post, number 9, number 9, number 9 ...]
Last edited by jeeswg on 18 Mar 2019, 21:58, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Magnification API

14 May 2017, 11:58

Regarding alternatives, you can use dwm (search msdn). Con: per window, pro: very easy, low CPU, 100 % looks like 100 % :wave:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Magnification API

18 Mar 2019, 22:01

The problem, when trying to run this script with AHK 64-bit, is this line:
DllCall("magnification\MagSetWindowSource", "Ptr",hCtl, "Int",vRectX, "Int",vRectY, "Int",vCtlW, "Int",vCtlH)
Can it be modified to run in 64-bit?

The dll function's definition is this:
MagSetWindowSource function | Microsoft Docs
https://docs.microsoft.com/en-us/windows/desktop/api/magnification/nf-magnification-magsetwindowsource

Code: Select all

BOOL MagSetWindowSource(
  HWND hwnd,
  RECT rect
);
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Magnification API

19 Mar 2019, 01:10

We discussed this here. You can use :arrow: dllcall_stuct.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Magnification API

19 Mar 2019, 08:18

Thanks Helgef. I have what appears to be a working script (AHK 64-bit and 32-bit) based on the rules for 64-bit mentioned there.

Code: Select all

;Magnification API and AutoHotkey - Ask for Help - AutoHotkey Community
;http://www.autohotkey.com/board/topic/64060-magnification-api-and-autohotkey/

OnExit, Uninitialize

vCtlW := 320, vCtlH := 240
vMagFactor := 2
vDoWinWithinScreen := 1
vOffset := 0 ;window within screen offset
;vOffset := 50

Gui, +E0x80000 +AlwaysOnTop +ToolWindow hWndhGui
Gui, Show, % "w" vCtlW " h" vCtlH " x450 y200", MagnifierWindowAHK
WinSet, Transparent, 255, % "ahk_id " hGui
vSfx := (A_PtrSize=8) ? "Ptr" : ""
hInstance := DllCall("GetWindowLong" vSfx, "Ptr",hGui, "Int",-6, "Ptr") ;GWL_HINSTANCE := -6
DllCall("kernel32\LoadLibrary", "Str","magnification.dll", "Ptr")
DllCall("magnification\MagInitialize")
GroupAdd, WinGroupMag, % "ahk_id " hGui

WS_CHILD := 0x40000000
WS_VISIBLE := 0x10000000
MS_SHOWMAGNIFIEDCURSOR := 0x1
vWinStyle := WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE
hCtl := DllCall("user32\CreateWindowEx", "UInt",0, "Str","Magnifier", "Str","MagnifierWindow", "UInt",vWinStyle, "Int",0, "Int",0, "Int",vCtlW, "Int",vCtlH, "Ptr",hGui, "Ptr",0, "Ptr",hInstance, "Ptr",0, "Ptr")

;The transformation matrix is
; (n, 0.0, 0.0)
; (0.0, n, 0.0)
; (0.0, 0.0, 1.0)
;where n is the magnification factor.

VarSetCapacity(MAGTRANSFORM, 36, 0)
NumPut(vMagFactor, MAGTRANSFORM, (1-1)*4, "Float")
NumPut(vMagFactor, MAGTRANSFORM, (5-1)*4, "Float")
NumPut(1, MAGTRANSFORM, (9-1)*4, "Float")

CoordMode, Mouse, Screen
Loop
{
	if !WinActive("ahk_id " hGui)
	{
		Gosub Uninitialize
		return
	}

	MouseGetPos, vMouseX, vMouseY
	if !vGuiW
		WinGetPos,,, vGuiW, vGuiH, % "ahk_id " hGui
	vRectX := vMouseX-(vGuiW/(2*vMagFactor)), vRectY := vMouseY-(vGuiH/(2*vMagFactor))
	vGuiX := vMouseX-(vGuiW/2), vGuiY := vMouseY-(vGuiH/2)
	;account for window title bar
	vRectY += 10/vMagFactor

	DllCall("magnification\MagSetWindowTransform", "Ptr",hCtl, "Ptr",&MAGTRANSFORM)

	if (A_PtrSize = 8)
	{
		VarSetCapacity(RECT, 16, 0)
		NumPut(vRectX, RECT, 0, "Int") ;left
		NumPut(vRectY, RECT, 4, "Int") ;top
		NumPut(vCtlW, RECT, 8, "Int") ;right ;in this case the width is wanted
		NumPut(vCtlH, RECT, 12, "Int") ;bottom ;in this case the height is wanted
		DllCall("magnification\MagSetWindowSource", "Ptr",hCtl, "Ptr",&RECT)
	}
	else
		DllCall("magnification\MagSetWindowSource", "Ptr",hCtl, "Int",vRectX, "Int",vRectY, "Int",vCtlW, "Int",vCtlH)

	;keep window within screen / certain coordinates
	if vDoWinWithinScreen
	{
		if (vGuiX < vOffset)
			vGuiX := vOffset
		if (vGuiX+vGuiW > A_ScreenWidth-vOffset)
			vGuiX := A_ScreenWidth-vOffset-vGuiW
		if (vGuiY < vOffset)
			vGuiY := vOffset
		if (vGuiY+vGuiH > A_ScreenHeight-vOffset)
			vGuiY := A_ScreenHeight-vOffset-vGuiH
	}

	if (vGuiX2 = vGuiX) && (vGuiY2 = vGuiY)
		Sleep, 700
	else
		WinMove, % "ahk_id " hGui,, % vGuiX, % vGuiY
	Sleep, 300

	vGuiX2 := vGuiX
	vGuiY2 := vGuiY
}
return

#IfWinActive MagnifierWindowAHK ahk_class AutoHotkeyGUI
Esc::
Uninitialize:
Gui, Destroy
DllCall("magnification\MagUninitialize")
ExitApp
#IfWinActive
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
rommmcek
Posts: 1474
Joined: 15 Aug 2014, 15:18

Re: Magnification API

20 Mar 2019, 01:48

This is great!

The first Ahk magnifier I know, wich works on modern Windows correctly!
Adding -Caption, -DpiScreen, NA and WS_EX_CLICKTHROUGH becomes really useful!

P.s.: Shouldn't be this: vRectX := vMouseX-Floor(vGuiW/(2*vMagFactor)), vRectY := vMouseY-Floor(vGuiH/(2*vMagFactor)) making vRectY += 10/vMagFactor redundant.
Edit: Correct observation, but wrong conclusion (didn't see comment):
comment by jeeswg wrote: ;account for window title bar
Last edited by rommmcek on 28 Mar 2019, 10:10, edited 1 time in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Magnification API

20 Mar 2019, 03:02

It looks right jeeswg.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: AHK_user, Descolada, sharonhuston and 225 guests