 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Thu Sep 28, 2006 12:57 pm Post subject: |
|
|
It's time this great topic got a bump. Furthermore, I've added a link to it from the script showcase. Holomind, if you'd like to edit the wording below, feel free to send me a revised version: | Quote: | | Screen Magnifier -- by Holomind: This screen magnifier has the several advantages over the one included with the operating system, including: Customizable refresh interval and zoom level (including shrink/de-magnify); antialiasing to provide nicer output; and it is open-source (as a result, there are several variations to choose from, or you can tweak the script yourself). |
|
|
| Back to top |
|
 |
Timothy Guest
|
Posted: Sun Nov 12, 2006 9:16 pm Post subject: |
|
|
| What's the code for copying transparent windows and tooltips? |
|
| Back to top |
|
 |
holomind
Joined: 11 Mar 2006 Posts: 299 Location: Munich, Germany
|
Posted: Mon Nov 13, 2006 12:35 pm Post subject: |
|
|
i guess its not easy to copy transparent windows with bitblt.
i think transparent windows are rendered by hardware and are a kind of overlay like accellerated video. it would be possible to capture this windows with directx or opengl which can access the "pixels" in the overlay. |
|
| Back to top |
|
 |
ivanw
Joined: 26 Dec 2006 Posts: 12 Location: Paris, France
|
Posted: Tue Dec 26, 2006 8:29 pm Post subject: |
|
|
As I am rather satisfied with what I could do based on information from this thread, I thought it would be fair to share a somewhat newer version.
I have a Microsoft Mouse which activates the intelliPoint magnifier. This one is really nice as it is part of the MS driver. I recently acquired the MX "best mouse ever" from Logitech and I miss this tool I’ve come to depend on.
In an attempt to make something as close as possible, I could find the best part of what I needed to know about AutoHotkey to do something I am rather happy with... Here it is:
Features:
Has no frame, just a thin border
Follows mouse - unless you hit the spacebar to stick it in place
Scalable - scrollwheel
Resizable - shift scrollwheel
| Code: |
; Autohotkey script "Screen Magnifier"
;=================================================================================
#SingleInstance ignore
Process, Priority, , High
OnExit handle_exit
hotkey, Space, toggle_follow
hotkey, Escape, GuiClose
hotkey, F18, GuiClose
; Init variables
follow := 1
ZOOMFX := 1.189207115
zoom := 2
antialias := 1
delay := 10
whMax := 400
wh := 200
whMin := 100
wwMax := 800
ww := 480
wwMin := 200
mx := 0
my := 0
mxp := mx
myp := my
wwD := 0
whD := 0
; Init zoom window
MouseGetPos, mx, my
Gui, +AlwaysOnTop +Owner -Resize -ToolWindow +E0x00000020
Gui, Show, NoActivate W%ww% H%wh% X-1000 Y-1000, MagWindow ; start offscreen
WinSet, Transparent , 254, MagWindow
Gui, -Caption
Gui, +Border
WinGet, PrintSourceID, id
hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
WinGet, PrintScreenID, id, MagWindow
hdc_frame := DllCall("GetDC", UInt, PrintScreenID)
if(antialias != 0)
DllCall("gdi32.dll\SetStretchBltMode", "uint", hdc_frame, "int", 4*antialias)
Gosub, Repaint
return
;=================================================================================
; Input events
WheelUp:: ; zoom in
if zoom < 4
zoom *= %ZOOMFX%
return
WheelDown:: ; zoom out
if zoom > %ZOOMFX%
zoom /= %ZOOMFX%
return
+WheelDown:: ; larger
wwD = 32
whD = 32
Gosub, Repaint
return
+WheelUp:: ; smaller
wwD = -32
whD = -32
Gosub, Repaint
return
;=================================================================================
; toggle_follow
toggle_follow:
follow := 1 - follow
return
; Repaint
Repaint:
CoordMode, Mouse, Screen
MouseGetPos, mx, my
WinGetPos, wx, wy, ww, wh, MagWindow
if(wwD != 0)
{
ww += wwD
wh += whD
wwD = 0
whD = 0
}
if(mx != mxp) OR (my !- myp)
{
DllCall( "gdi32.dll\StretchBlt"
, UInt, hdc_frame
, Int , 2 ; nXOriginDest
, Int , 2 ; nYOriginDest
, Int , ww-6 ; nWidthDest
, Int , wh-6 ; nHeightDest
, UInt, hdd_frame ; hdcSrc
, Int , mx - (ww / 2 / zoom) ; nXOriginSrc
, Int , my - (wh / 2 / zoom) ; nYOriginSrc
, Int , ww / zoom ; nWidthSrc
, Int , wh / zoom ; nHeightSrc
, UInt, 0xCC0020) ; dwRop (raster operation)
if(follow == 1)
WinMove, MagWindow, ,mx-ww/2, my-wh/2, %ww%, %wh%
mxp = mx
myp = my
}
SetTimer, Repaint , %delay%
return
; GuiClose handle_exit
GuiClose:
handle_exit:
DllCall("gdi32.dll\DeleteDC" , UInt,hdc_frame )
DllCall("gdi32.dll\DeleteDC" , UInt,hdd_frame )
Process, Priority, , Normal
ExitApp
;=================================================================================
|
I must add that something is missing here: This script must be started from outside as it only has a an exit point (Escape or F18). |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 3943 Location: Pittsburgh
|
Posted: Tue Dec 26, 2006 9:48 pm Post subject: |
|
|
Very nice! Works perfectly.
If you want to add features:
- I'd like to change the vertical and horizontal size of the magnifier window, independently.
- I'd like to be able to anchor the magnified area, too, such that it does not follow the mouse. (If I play Internet Chess, the time display is too small. It would be nice to be able to show it 4 times magnified in the top center part of the screen, updated real time.) |
|
| Back to top |
|
 |
ivanw
Joined: 26 Dec 2006 Posts: 12 Location: Paris, France
|
Posted: Tue Dec 26, 2006 11:05 pm Post subject: |
|
|
1. Resizing is a nice feature of the MS IntelliPoint version and it should be possible to make it work in this one with AutoHkey.
The expansion is based on dragging the mouse pointer away from the center of the magnification rectangle to expand in both width and/or height.
2. About being able to fix the center of the magnification area, you only have to allow disarming the mx, my sensing in the RePaint function after selection.
May be I'll make those improvements but, as of right now, I miss a good motivation to do so... tomorrow maybe  |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3600 Location: Belgrade
|
Posted: Wed Dec 27, 2006 9:14 am Post subject: |
|
|
I get empty box!
But I see the goal, and I always wanted that ms mouse just cuz of that....
You should create separate topic for this. _________________
 |
|
| Back to top |
|
 |
ivanw
Joined: 26 Dec 2006 Posts: 12 Location: Paris, France
|
Posted: Wed Dec 27, 2006 2:09 pm Post subject: |
|
|
majkinetor, I wanted to give credits to people who gave some of their time and effort in this topic.
I've opened a follow up from here with some back-links: ScreenMagnifier - IntelliPoint clone?
Now I don't now what can give you an empty box... As I am an emigrant from the Unix community, my contribution relies 100% on AutoHotkeys as Windows low level calls are concerned... Hopefully, someone will help in the new dedicated thread...
-ivan |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3600 Location: Belgrade
|
Posted: Wed Dec 27, 2006 2:11 pm Post subject: |
|
|
well, it is probably some trivial thing...
If I find time I will look into it.
Thx for concern. _________________
 |
|
| Back to top |
|
 |
testzugang
Joined: 07 Jun 2007 Posts: 2
|
Posted: Fri Jun 08, 2007 12:05 am Post subject: |
|
|
Hi,
really great stuff here
I tried to change the source to have three small magnifiers (which magnify the pixel under itself) at the same time. But it doesn't work properly... Maybe there are syntax errors (I'm quite new to ahk...) but I think it's another problem.
I hope somebody can give me a hint...
| Code: | Process, Priority, , High
OnExit handle_exit
hotkey, Escape, GuiClose
nrW = 3 ;number of windows
ZOOMFX := 1.189207115
zoom := 2
delay := 100
mx := 0
my := 0
Loop %nrW%
{
;MsgBox This window will be displayed three times.
;fenster%a_index% = %a_index%
;MsgBox fenster%a_index%
labelW = f%a_index%
ind = %a_index%
wx := ind
wx *= 100
ww := 100
gui %a_index%: +Label%labelW% +AlwaysOnTop -Resize -ToolWindow +E0x00000020
lw = gui %a_index% ;current gui
gui %a_index%: +LastFound
WinSet, Transparent , 254
gui %a_index%: -Caption +Border
gui %a_index%:show, h30 w%ww% x%wx% y%wx%
Test(lw)
}
return
Test(f)
{
WinGetPos, wx, wy, ww, wh, f
MsgBox %wx% %wy% %ww% %wh% %f%
WinGet, PrintSourceID, id
hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
WinGet, PrintScreenID, id, %f%
hdc_frame := DllCall("GetDC", UInt, PrintScreenID)
MsgBox %hdd_frame% %hdc_frame%
DllCall( "gdi32.dll\StretchBlt"
, UInt, hdc_frame
, Int , 2 ; nXOriginDest
, Int , 2 ; nYOriginDest
, Int , ww-6 ; nWidthDest
, Int , wh-6 ; nHeightDest
, UInt, hdd_frame ; hdcSrc
, Int , wx - (ww / 2 / zoom) ; nXOriginSrc
, Int , wy - (wh / 2 / zoom) ; nYOriginSrc
, Int , ww / zoom ; nWidthSrc
, Int , wh / zoom ; nHeightSrc
, UInt, 0xCC0020) ; dwRop (raster operation)
}
GuiClose:
handle_exit:
DllCall("gdi32.dll\DeleteDC" , UInt,hdc_frame )
DllCall("gdi32.dll\DeleteDC" , UInt,hdd_frame )
Process, Priority, , Normal
ExitApp
|
I changed the Repaint label to a function, I think dynamically generated gui only work this way, don't they? |
|
| Back to top |
|
 |
testzugang
Joined: 07 Jun 2007 Posts: 2
|
Posted: Mon Jun 11, 2007 10:23 am Post subject: |
|
|
I have changed some things but it still doesn't work...
Doesn't anybody know what's missing?
| Code: | Process, Priority, , High
OnExit handle_exit
hotkey, Escape, GuiClose
nrW = 3 ;number of windows
zoom := 2
delay := 100
WinGet, PrintSourceID, id
hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
MsgBox Main %hdd_frame%
Loop %nrW%
{
;MsgBox This window will be displayed three times.
;fenster%a_index% = %a_index%
;MsgBox fenster%a_index%
labelW = f%a_index%
ind = %a_index%
wx := ind
wx *= 100
ww := 100
gui %a_index%: +Label%labelW% +AlwaysOnTop -Resize -ToolWindow +E0x00000020
lw = gui %a_index% ;current gui
gui %a_index%: +LastFound
WinSet, Transparent , 254
gui %a_index%: -Caption +Border
gui %a_index%:show, h30 w%ww% x%wx% y%wx%
WinGet, PrintScreenID, id, %a_index%
hdc_frame%a_index% := DllCall("GetDC", UInt, PrintScreenID)
MsgBox % Looping hdc_frame%a_index%
Test(lw, a_index, hdd_frame, zoom)
}
return
Test(f, c, hdd, z)
{
WinGetPos, wx, wy, ww, wh, f
;MsgBox %wx% %wy% %ww% %wh% %f% %c% %z%
;WinGet, PrintSourceID, id
;hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
;WinGet, PrintScreenID, id, %f%
;hdc_frame := DllCall("GetDC", UInt, PrintScreenID)
hdc := % hdc_frame%c%
MsgBox Test %hdd% - %hdc%
DllCall( "gdi32.dll\StretchBlt"
, UInt, hdc
, Int , 2 ; nXOriginDest
, Int , 2 ; nYOriginDest
, Int , ww-6 ; nWidthDest
, Int , wh-6 ; nHeightDest
, UInt, hdd ; hdcSrc
, Int , wx - (ww / 2 / z) ; nXOriginSrc
, Int , wy - (wh / 2 / z) ; nYOriginSrc
, Int , ww / zoom ; nWidthSrc
, Int , wh / zoom ; nHeightSrc
, UInt, 0xCC0020) ; dwRop (raster operation)
}
GuiClose:
handle_exit:
DllCall("gdi32.dll\DeleteDC" , UInt,hdc_frame )
DllCall("gdi32.dll\DeleteDC" , UInt,hdd_frame )
Process, Priority, , Normal
ExitApp |
|
|
| Back to top |
|
 |
ricke
Joined: 14 Sep 2006 Posts: 31
|
Posted: Thu Jun 14, 2007 8:44 pm Post subject: |
|
|
So I decided to make my own version of this one.
Amazing work Holomind !!
Cred to all that made it possible..... I have just stolen code from all over the place and put the pieces together.
Dont forget that u need:
(see http://www.autohotkey.com/forum/viewtopic.php?t=11860 for links)
GDIplusWrapper.ahk
DllCallStruct.ahk
BinaryEncodingDecoding.ahk
I made a magnifier version mostly to be able to make very accurate screencaptures...
And I added the colorpicker so I can check and see that the cap is exactly as the original (the bmp quality setting confuses me.... use noParams now seem to work.
pics taken with this tool should be easy to relocate with imagesearch....
So features:
-Screen Capture part of screen (win+P is the hotkey)
-Magnifier of Selected area (any height and width)
(change big window fast with mouse.... use keyboard for pixelperfection)
-Dual hair cross (somewhat modified)
-colorpicker (TrayTooltip with color info about the pixel in the haircross)
Only spent a day on this one so it may contain some bugs....
known bug: added keywait on almost every "step-key" because if i let it run at full speed.... (the key repeat rate) it seem to be too fast and it hang and flickers...
it's possible to replace keywait with sleep,70 or something
So here is the code
| Code: |
#NoEnv
#Include GDIPlusWrapper.ahk
SetBatchLines -1
CoordMode Mouse, Screen
CoordMode Pixel, Screen
OnExit GuiClose
zoom = 9 ; initial magnification
aimH = 20 ; Height of aim window
aimW = 33 ; Width of aim window
;;;;;;;;;; GUI big ;;;;;;;;;;
Gui +AlwaysOnTop +Caption +Resize +ToolWindow
Gui Show, % "w" aimW*zoom " h" aimH*zoom " x0 y0", Magnifier
WinGet MagnifierID, id, Magnifier
WinSet Transparent, 255, Magnifier ; makes the window invisible to magnification
WinGet PrintSourceID, ID
;;;;;;;;;; GUI aim ;;;;;;;;;;
Gui 2:+AlwaysOnTop -Caption +ToolWindow +0x800000
Gui 2:Color, C
MouseGetPos mouseX, mouseY
Gui 2:Show, % "w" aimW " h" aimH " x" mouseX-aimW " y" mouseY-aimH, AimFrame
WinSet TransColor, C, AimFrame
hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
hdc_frame := DllCall("GetDC", UInt, MagnifierID)
SetTimer Repaint, 50 ; flow through
;########## PROCEDURES ##########
;;;;;;;;;; Repaint - Updates the big window and displays the pixelcolor with TrayTip.
Repaint:
MouseGetPos mouseX, mouseY
PGC_Y:=mouseY-1
PGC_X:=mouseX-1
PixelGetColor, PGC, %PGC_X%, %PGC_Y%,RGB
TrayTip,, RGB PixelColor:`n%PGC%, 1,
xz := In(mouseX-aimW/2,-1,A_ScreenWidth-aimW+1) ; keep the frame on screen
yz := In(mouseY-aimH/2,-1,A_ScreenHeight-aimH+1) ;In(x,a,b) closest number to x in [a,b]
WinMove AimFrame,,%xz%, %yz%, % aimW, % aimH
DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,0, Int,aimW*zoom, Int,aimH*zoom
, UInt,hdd_frame, UInt,xz, UInt,yz, Int,aimW, Int,aimH, UInt,0xCC0020) ; SRCCOPY
DrawCross(aimW, aimH, zoom, hdc_frame)
Return
;;;;;;;;;; GuiSize - Scales the aim window if big is resized (and update caption on big window)
GuiSize:
aimW := A_GuiWidth/zoom
aimH := A_GuiHeight/zoom
aimW := round(aimW)
aimh := round(aimH)
Gui Show, % "w" aimW*zoom " h" aimH*zoom ,(%aimW%x%aimH%) %zoom%x Zoom
Return
;;;;;;;;;; Cleaning up ;;;;;;;;;;
GuiClose:
DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
DllCall("gdi32.dll\DeleteDC", UInt,hdd_frame )
ExitApp
;########## HOTKEYS ##########
;;;;;;;;;; Win+R - Reloads app ;;;;;;;;;;
#r::
keywait, Lwin
reload
return
;;;;;;;;;; Win+Up - Zooms In ;;;;;;;;;;
#Up::
if (((zoom+1)*aimW < A_ScreenWidth ) AND ((zoom+1)*aimH < (A_ScreenHeight-22) )) ;stops before window get bigger than screen
zoom+=1
Gui Show, % "w" aimW*zoom " h" aimH*zoom ,(%aimW%x%aimH%) %zoom%x Zoom ;update capion and size
keywait, up ;Added because I got some glitches when at full "key repeat"-rate
return
;;;;;;;;;; Win+Down - Zooms Out ;;;;;;;;;;
#Down::
if (zoom > 1) ;stop so it does go negative
zoom-=1
Gui Show, % "w" aimW*zoom " h" aimH*zoom ,(%aimW%x%aimH%) %zoom%x Zoom ;update capion and size
keywait, down ;Added because I got some glitches when at full "key repeat"-rate
return
;;;;;;;;;; Win+P - Takes a screenshot of whats inside the aim window
#P::
filename=%A_Now%.bmp ;just a unique filename
noParams = NONE
GDIplus_Start()
WinGetPos , X_cap, Y_cap, W_cap, H_cap, AimFrame
GDIplus_CaptureScreenRectangle(bitmap, X_cap, Y_cap, W_cap, H_cap)
GDIplus_GetEncoderCLSID(bmpEncoder, #GDIplus_mimeType_BMP)
GDIplus_SaveImage(bitmap, filename, bmpEncoder, noParams)
GDIplus_DisposeImage(bitmap)
GDIplus_Stop()
return
;;;;;;;;;; Ctrl+Arrows - Moves the aim window 1 pixel at the time ;;;;;;;;;;
^Up::MouseMove, 0, -1, 0, R
^Down::MouseMove, 0, 1, 0, R
^Left::MouseMove, -1, 0, 0, R
^Right::MouseMove, 1, 0, 0, R
;;;;;;;;;; Shift+Arrows Change Size of aim window ;;;;;;;;;;
+Right::
if (zoom*(aimW+1) < A_ScreenWidth)
aimW+=1
Gui Show, % "w" aimW*zoom " h" aimH*zoom ,(%aimW%x%aimH%) %zoom%x Zoom
keywait, right
return
+Left::
if (aimW > 4)
aimW-=1
Gui Show, % "w" aimW*zoom " h" aimH*zoom ,(%aimW%x%aimH%) %zoom%x Zoom
keywait, left
return
+Down::
if (zoom*(aimH+1) < (A_ScreenHeight-22))
aimH+=1
Gui Show, % "w" aimW*zoom " h" aimH*zoom ,(%aimW%x%aimH%) %zoom%x Zoom
keywait, Down
return
+Up::
if (aimH > 4)
aimH-=1
Gui Show, % "w" aimW*zoom " h" aimH*zoom ,(%aimW%x%aimH%) %zoom%x Zoom
keywait, Up
return
;########## Functions ##########
;;;;;;;;;; Draws the Crosshairs ;;;;;;;;;;
DrawCross( X_CL , Y_CL, Z_CL, dc )
{
;specify the style, thickness and color of the cross lines
h_pen := DllCall( "gdi32.dll\CreatePen", "int", 0, "int", 1, "uint", 0x0000FF)
;select the correct pen into DC
DllCall( "gdi32.dll\SelectObject", "uint", dc, "uint", h_pen )
;draw horizontal lines
DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", 0, "int",floor((Y_CL-1)/2)*Z_CL , "uint", 0)
DllCall( "gdi32.dll\LineTo", "uint", dc, "int", X_CL*Z_CL, "int", floor((Y_CL-1)/2)*Z_CL)
DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", 0, "int",floor((Y_CL-1)/2)*Z_CL+Z_CL , "uint", 0)
DllCall( "gdi32.dll\LineTo", "uint", dc, "int", X_CL*Z_CL, "int", floor((Y_CL-1)/2)*Z_CL+Z_CL)
;draw vertical lines
DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int",floor((X_CL-1)/2)*Z_CL, "int", 0, "uint", 0)
DllCall( "gdi32.dll\LineTo", "uint", dc, "int", floor((X_CL-1)/2)*Z_CL, "int", Y_CL*Z_CL)
DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int",floor((X_CL-1)/2)*Z_CL+Z_CL, "int", 0, "uint", 0)
DllCall( "gdi32.dll\LineTo", "uint", dc, "int", floor((X_CL-1)/2)*Z_CL+Z_CL, "int", Y_CL*Z_CL)
}
;;;;;;;;;; Select Compare ;;;;;;;;;;
In(x,a,b) { ; closest number to x in [a,b]
IfLess x,%a%, Return a
IfLess b,%x%, Return b
Return x
}
|
Look inside the code to find all the hotkeys......
Open for suggestions for better solutions....
really want some input on how to optimize the code....
And again credit to all those that wrote the code in the first place.... this is just another version of their work.
Please report bugs (and solution if u found one)
///Ricke |
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Thu Jul 12, 2007 1:15 am Post subject: |
|
|
Does anyone have an idea why the magnifier is just white when using Aero in Vista? Ok, I think it's because Aero uses DirectX, but could the Magnifier be improved to support that? The system's own magnifier works also with Aero. _________________ Tekl |
|
| Back to top |
|
 |
joebob Guest
|
Posted: Thu Sep 13, 2007 7:16 pm Post subject: Toggle the screen magnifier on and off? |
|
|
| How do I set up the Caps lock key to toggle the screen magnifier on and off? |
|
| Back to top |
|
 |
Icarus
Joined: 24 Nov 2005 Posts: 420
|
Posted: Mon Sep 17, 2007 8:43 pm Post subject: |
|
|
Well,
I must admit I did not read through this entire thread, but I did test some of the variants of this nice script.
No offense, but with all the beauty of a 50-line magnifier code, there seem to be a basic problem with taking this to the next level.
In all the versions I tested, the smoothness of movement (both of the window, and of its content) are nothing close to the Windows magnifier. My eyes got tired after a couple of minutes with this magnifier.
Personally, I like using a magnifier, and I was looking to develop one my own - using AHK of course - so naturally, I started to look at this thread.
Couple questions, if anyone cares to share:
1. Did anyone manage to create a version that has smooth motion in both aspects (content, and window-following-mouse)
2. Did anyone manage to do a version that supports inverse colors?
3. Did anyone manage (or have an idea about how to do it) to show the mouse cursor itself in the window (and not some crosshair)
4. (yeah, more than a couple, sorry) An extremely important feature in a magnifier (to my taste) is the ability to follow keyboard caret and focus - anyone attempted that? |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|