I played around with DC and DllCalls a little bit and built it into a Screen Magnifier similar to the one built in at Windows/Accessories.
The advantage of this vs. the builtin.
* you have the sourcecode and can customize it
* you can enable antializing (the built in has none!)
* you can set the speed of repaint (delay in ms with the slider, windows default is about 1000ms)
* you can define different zoomlevels, even unmagnify (shrink)
Due to a trick and using transparent 254 the window appears solid, but is invisible for BitBlt (DC_Copy), so the window does not copy itself and you even can magnify regions behind the loupe- window!
Like in the Builtin Magnifier, the mouseposition is watched and used for the selected region.
you also can resize the zoom window and the content is adopted automatically. (no distort, but large area)
I can even manage to zoom video (with 1-10ms delay) and watch it.
sometimes id like to zoom little flash-videos on websites without having to change my screen-resolution.
so now if somebody could find out how to save the contents of the DC to a file (BMP or other, DIB? Binarysave..) one could make nice tools with it.
=> solved see save screenshot with dgiplus only
there are many "mutations/variations" of this script, so choose the one you like. perhaps if find time to make a little "gallery" of the different versions and their differences. (there is no one size fits all, and the nice thing of having the sourcecode anybody can improve it)
this is the second code-section.
http://www.holomind.de/ahk/magnifier/magnifier_smooth.exe
Code:
OnExit handle_exit
Gui, +AlwaysOnTop +Owner +Resize +ToolWindow ; window for the dock
Gui, Show, NoActivate w400 h400 x300 y50 , PrintScreen
Gui, Add, DDL, vzoom , 0.5|1|2||4|8|16
Gui, Add, Checkbox, y12 x150 vantialize, Antialize ?
Gui, Add, Slider, vdelay x220 y0 Range15-200
Gui, Add, Text, x340 y12 w80 vdelay2
WinGet PrintScreenID, id ,PrintScreen ;
WinSet, Transparent , 254, PrintScreen
;retrieve the unique ID number (HWND/handle) of that window
WinGet, PrintSourceID, id
hotkey , #x , toggle_follow
hotkey , +$LButton , click_through
toolbar_def:=35
toolbar := toolbar_def
follow :=0
hdd_frame := DllCall( "GetDC", UInt, PrintSourceID )
hdc_frame := DllCall( "GetDC", UInt, PrintScreenID )
hdc_buffer := DllCall("gdi32.dll\CreateCompatibleDC", UInt, hdc_frame) ; buffer
hbm_buffer := DllCall("gdi32.dll\CreateCompatibleBitmap", UInt,hdc_frame, Int,A_ScreenWidth, Int,A_ScreenHeight)
Gosub, Repaint
return
toggle_follow:
follow := 1 - follow
if follow = 1
{
WinSet Region, 0-0 W%ww% H%wh% E , PrintScreen
toolbar := -32 ; height of window title
GuiControl, Hide, zoom
}
else
{
WinSet Region,, PrintScreen
toolbar :=toolbar_def
GuiControl, Show, zoom
}
Return
click_through:
if follow = 1
{
Gui, Hide
Send, {Click}
SetTimer, Repaint , Off
Sleep, 100
Gui, Show
SetTimer, Repaint, %delay%
}
Return
Repaint:
CoordMode, Mouse, Screen
MouseGetPos, start_x, start_y ; position of mouse
Gui, Submit, NoHide ; needed to read the dropdown and slidervalue
GuiControl,, delay2 , delay %delay% ms
WinGetPos, wx, wy, ww, wh , PrintScreen
wh2 := wh - toolbar
DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_frame, "int", 4 * antialize ) ; Halftone better quality with stretch
DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,toolbar, Int,ww, Int,wh - toolbar
, UInt,hdd_frame, Int
, start_x-(ww / 2 / zoom)
, Int,start_y -( wh2 / 2/zoom), Int,ww / zoom, Int,wh2 / zoom ,UInt,0xCC0020) ; SRCCOPY
if follow = 1
WinMove, PrintScreen, ,start_x -ww/2 , start_y-wh/2
SetTimer, Repaint , %delay%
Return
GuiClose:
handle_exit:
DllCall("gdi32.dll\DeleteObject", UInt,hbm_buffer)
DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
DllCall("gdi32.dll\DeleteDC", UInt,hdd_frame )
DllCall("gdi32.dll\DeleteDC", UInt,hdc_buffer)
ExitApp
or with less gui, my current favorite (less frames is smoother)
Code:
#NoEnv
SetBatchLines -1
CoordMode Mouse, Screen
OnExit GuiClose
zoom = 2 ; initial magnification, 1..32
antialize = 0
Rx = 128 ; half vertical/horizontal side of magnifier window
Ry = 128
Zx := Rx/zoom ; frame x/y size
Zy := Ry/zoom
; GUI to show the magnified image
Gui +AlwaysOnTop +Resize +ToolWindow
Gui Show, % "w" 2*Rx " h" 2*Ry " x0 y0", Magnifier
WinGet MagnifierID, id, Magnifier
WinSet Transparent, 255, Magnifier ; makes the window invisible to magnification
WinGet PrintSourceID, ID
hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
hdc_frame := DllCall("GetDC", UInt, MagnifierID)
SetTimer Repaint, 50 ; flow through
Repaint:
MouseGetPos x, y
xz := In(x-Zx-6,0,A_ScreenWidth-2*Zx) ; keep the frame on screen
yz := In(y-Zy-6,0,A_ScreenHeight-2*Zy)
; WinMove Frame,,%xz%, %yz%, % 2*Zx, % 2*Zy
DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,0, Int,2*Rx, Int,2*Ry
, UInt,hdd_frame, UInt,xz, UInt,yz, Int,2*Zx, Int,2*Zy, UInt,0xCC0020) ; SRCCOPY
Return
GuiSize:
Rx := A_GuiWidth/2
Ry := A_GuiHeight/2
Zx := Rx/zoom
Zy := Ry/zoom
TrayTip,,% "Frame = " Round(2*Zx) " × " Round(2*Zy) "`nMagnified to = " A_GuiWidth "×" A_GuiHeight
Return
#a::
antialize := !antialize
DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_frame, "int", 4*antialize ) ; Antializing ?
Return
#x::
GuiClose:
DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
DllCall("gdi32.dll\DeleteDC", UInt,hdd_frame )
ExitApp
#p::
MButton::
if paused =
{
Gui, 2:Hide
Gui, Hide
SetTimer, Repaint, Off
paused = 1
}
else
{
Gui, 2:Show
Gui, Show
SetTimer, Repaint, 50
paused =
}
Return
^+Up::
^+Down::
^+WheelUp:: ; Ctrl+Shift+WheelUp to zoom in
^+WheelDown:: ; Ctrl+Shift+WheelUp to zoom out
If (zoom < 31 and ( A_ThisHotKey = "^+WheelUp" or A_ThisHotKey = "^+Up" ))
zoom *= 1.189207115 ; sqrt(sqrt(2))
If (zoom > 1 and ( A_ThisHotKey = "^+WheelDown" or A_ThisHotKey = "^+Down" ))
zoom /= 1.189207115
Zx := Rx/zoom
Zy := Ry/zoom
TrayTip,,% "Zoom = " Round(100*zoom) "%"
Return
In(x,a,b) { ; closest number to x in [a,b]
IfLess x,%a%, Return a
IfLess b,%x%, Return b
Return x
}