Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

ScreenMagnifier


  • Please log in to reply
104 replies to this topic
jonjan
  • Members
  • 34 posts
  • Last active: Feb 25 2013 01:21 PM
  • Joined: 21 Mar 2006

I figured out how to do it. Thank you for everyone's time. I do have some other questions, but don't pertain to the magnifier script so I will post in other areas of the forum.


I sure wish you would have shared what you found! lol This is exactly half of what I am looking for :lol:

yes4me
  • Members
  • 25 posts
  • Last active: Apr 08 2012 08:22 AM
  • Joined: 28 Nov 2008
Is there a way to display the crosslines without having to redraw everything every 15 ms or whatever you use in settimer?
I am thinking of layers, like one layer get updated for the zoom and get updated every 15ms, and one layer does not get updated in order to reduce CPU usage.

  • Guests
  • Last active:
  • Joined: --

okay, so I've worked out how to get more than one instance running (just ran two ahk's with different filenames lol) and I've managed to get the windows to stay put and clone a specific area. The last thing I want to work out is how to get the GUI / GDI commands to distort when I change the window size... any ideas?

edit: it appears I need to change this line:

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

but it's well beyond my understanding... here's some documentation on the stretchblt function:

http://msdn.microsoft.com/en-us/library/dd145120(VS.85).aspx


any ideas?

MiL0
  • Members
  • 27 posts
  • Last active: Jul 10 2011 11:01 PM
  • Joined: 06 Sep 2010
also looking for a method to rotate the cloned windows by 90/180 degress... feasible?

bmoore45
  • Members
  • 273 posts
  • Last active: Mar 14 2012 01:00 PM
  • Joined: 10 Jul 2011
Is there a way to modify this so that the mouse cursor isn't hidden in the magnifier window??
I noticed a couple people have asked but couldn't find a response.

thanks, great script!!

Ben

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006

Is there a way to display the crosslines without having to redraw everything every 15 ms or whatever you use in settimer?
I am thinking of layers, like one layer get updated for the zoom and get updated every 15ms, and one layer does not get updated in order to reduce CPU usage.


you can just leave the area of the crosslines while copying with bitblt. so this way you would make 4 bitblts, which would be in sum nearly same time of processing cpu, and just "don't" copy the crosslines, and only update them when needed. as this is writiting to the hdc directly maybe you need to redraw the whole thing including the crosslines if you move the magnifier window itself.
you would copy like
1) left-up corner to -1,-1,
2) right-up corner to -1,1
3) right-down corner to 1,1
4) left-down corner to 1,-1
and basically leave the lines (-witdh,0) to (witdh,0) and (0,-height) to (0,height) effectively without repaint thus keeping the crosshair.

but the effect will be minimal as, painting the crosshair is very little cpu, even compared to a full repaint with bitblt, which also is very fast. (as 2d gipd operations are hardware accellerated). you can try to optimize, but my rough guess is, the overall performance benefit will be 1%, which means not noticable.

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006

also looking for a method to rotate the cloned windows by 90/180 degress... feasible?


it's possible with the image-transform functions. but it will be more complicated than just doing a bitblt. also it will involve the use of gdip_start etc. which is described in the gdip.ahk library.

<!-- m -->http://msdn.microsof...ry ... 85).aspx<!-- m -->

if you want to flip the whole screen/desktop by 90 or 180 degrees its better to do this in your display settings of the operating system as normally the graphics card support this natively.

holomind
  • Members
  • 341 posts
  • Last active: Aug 23 2015 03:27 PM
  • Joined: 11 Mar 2006

Is there a way to modify this so that the mouse cursor isn't hidden in the magnifier window??
I noticed a couple people have asked but couldn't find a response.

thanks, great script!!

Ben


this will not be possible i guess, but you can clone the mouse, even magnified version of it. by drawing a "new" mouse on the corresponding position in the magnified window. one reason it is not shown in the magnified area is, that the mouse (and the cursor) are hardware accelleated and are drawn "on top" of the screen independent of other graphics, so the bitblt cannot "see" it and thus dont copy it. but actually some screenshot tools manage to copy the mouse, but maybe they even reinsert the mouse on top.
in windows you can even set a different mouse cursor, so for this purpose you could change it to crosshair which might be better for zoom operations . for example your mouse changes into a cursor if you type inside a text-field. (similar effect). i think there are some wmessage calls to change the cursor.

<!-- m -->http://www.autohotke...topic62373.html<!-- m -->
<!-- m -->http://www.autohotke... ... sc&start=0<!-- m -->

here is some ahk script to modify your mousepointer:
<!-- m -->http://www.autohotke.../topic2197.html<!-- m -->

greetings....

Selt
  • Guests
  • Last active:
  • Joined: --
Can someone make some relatively simple (but not for me) adjustments to this nice Magnifier script (made by ivanw), so that once the magnifier sticks to a position on the screen (it happens when the spacebar is pressed):

its window becomes inactive (that is, not affected by either spacebar or escape, or any other keys) and becomes active again only when clicked on by the mouse and

loses its connection with the mouse pointer, thus magnifying only the area over which its window is positioned.

Selt
  • Guests
  • Last active:
  • Joined: --
This script
; 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     := 
  wh        := 10
  whMin     := 10

  wwMax     := 
  ww        := 100
  wwMin     := 20


  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

;=================================================================================


timtranslates
  • Members
  • 35 posts
  • Last active: Aug 20 2015 10:37 AM
  • Joined: 23 Apr 2007
Could someone confirm whether the version posted in the initial message is the latest version? If not, could I have a link to the latest version. Sometimes video is not smooth (every few seconds there's a very short pause before it jumps and catches up). Though maybe that's just a problem with my computer. Also, is there a way of hiding the mouse pointer?
http://www.timtranslates.com
For professional translations.

rhr
  • Members
  • 217 posts
  • Last active: Feb 13 2015 02:41 AM
  • Joined: 28 Jun 2012
Cool! Would I like add invert color?

ЯHR

 

 

 

 

 


Marshall666
  • Members
  • 45 posts
  • Last active: May 16 2013 04:03 PM
  • Joined: 09 Mar 2013

i remembered that the little frame also uses a lot of winmoves, which i learned is slow.

actually you dont need the frame (as you have your mouse there and the real value is small when you only want to find the right pixel.

so this version without any winmoves is really smooth, updating your zoomed area without noticable delay.

* this version is with red lines again,
* the #up etc. is compressed to oneliners
* little bit more comments inside code
 

#NoEnv
SetBatchLines -1

CoordMode Mouse, Screen
OnExit #x
  zoom = 8                ; initial magnification, 1..32
  halfside = 128          ; circa halfside of the magnifier
  part := halfside/zoom
  Rz := Round(part)
  R := Rz*zoom
  LineMargin := 10
                        ; GUI 2 shows the magnified image
Gui 2:+AlwaysOnTop -Caption +Resize +ToolWindow +E0x20
Gui 2:Show, % "w" 2*R+zoom+3 " h" 2*R+zoom+3 " 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)

;#############   draw cross lines   ###########################################
DrawCross( M_C , R_C, zoom_c, 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 )         
        ;update the current position to specified point - 1st horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", M_C, "int", R_C, "uint", 0)
        ;draw a line from the current position up to, but not including, the specified point.
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C)
        ; 2nd horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", M_C, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C+zoom_c)
        ; 3rd horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", 2*R_C+zoom_c-M_C, "int", R_C)
        ; 4th horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", 2*R_C+zoom_c-M_C, "int", R_C+zoom_c)       
        ; 1st vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C, "int", M_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C)
        ; 2nd vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", M_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C+zoom_c, "int", R_C)
        ; 3rd vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", 2*R_C+zoom_c-M_C)
        ; 4th vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C+zoom_c, "int", 2*R_C+zoom_c-M_C)
} 
SetTimer Repaint, 50   ; flow through

Repaint:
     MouseGetPos x, y
     xz := x-Rz
     yz := y-Rz

     DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,0, Int,2*R+zoom, Int,2*R+zoom
     , UInt,hdd_frame, UInt,xz, UInt,yz, Int,2*Rz+1, Int,2*Rz+1, UInt,0xCC0020) ; SRCCOPY
     
     DrawCross( LineMargin, R, zoom, hdc_frame )
     
     ; keep the frame outside the magnifier and precalculate wanted position
     If (x < (2*R+zoom+8) and y < (2*R+zoom+8))
           pos_new := (2*R+zoom+8)
     Else
           pos_new := 0

     if ( pos_old <> pos_new )          ; only move if the real position of window needs to change
        WinMove Magnifier,, ,pos_new
    
     pos_old := pos_new     ; store value for next loop
    
Return

#x::
     DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
     DllCall("gdi32.dll\DeleteDC", UInt,hdd_frame )
   
ExitApp

#+::
^+WheelUp::                      ; Ctrl+Shift+WheelUp to zoom in
#-::
^+WheelDown::                    ; Ctrl+Shift+WheelUp to zoom out
    If (zoom < 31 and ( A_ThisHotKey = "^+WheelUp" or A_ThisHotKey ="#+") )
       zoom *= 1.189207115         ; sqrt(sqrt(2))
    If (zoom >  1 and ( A_ThisHotKey = "^+WheelDown" or A_ThisHotKey = "#-"))
       zoom /= 1.189207115
   
    part := halfside/zoom           ;new calculation of the magnified image
    Rz := Round(part)
    R := Rz*zoom
    Gui 2:Show, % "w" 2*R+zoom+3 " h" 2*R+zoom+3 " x0 y0", Magnifier
    TrayTip,,% "Zoom = " Round(100*zoom) "%"
   
Return

      ; Mouse slow down:
      ; The first parameter is always 0x71 (SPI_SETMOUSESPEED).
      ; The third parameter is the speed (range is 1-20, 10 is default).
F9::
   if  mouse_slow = 
   {
      ; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getting_hardware_information.asp
      ; http://www.autohotkey.com/forum/topic5264.html

    DllCall("SystemParametersInfo", UInt, 0x70, UInt, 0, UIntP, mouse_speed_old, UInt, 0) ; important UintP (eg. return P(ointer) ?) 
    TrayTip,, your old mousespeed was %mouse_speed_old% , setting to 3
    DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, 3, UInt, 0)
    mouse_slow = 1
   }
return

F9 up::
    DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, 10, UInt, 0)
    TrayTip,, restoring your mousespeed 
    mouse_slow = 
return

;Mouse move one step with arrow keys
#Up::MouseMove, 0, -1, 0, R

#Down::MouseMove, 0, 1, 0, R

#Left::MouseMove, -1, 0, 0, R

#Right::MouseMove, 1, 0, 0, R
Woow, REALY great Work! wink.png
But how can i make the MouseCursor Visible?
iDont like the Crosshair Style..
 
I hope someone can help..

 



avpvid
  • Members
  • 5 posts
  • Last active: Jun 09 2014 12:49 PM
  • Joined: 08 Aug 2013

Using these functions, what would be the method of simply grabbing the whole display and doing a vertical flip on it (not rotation, but so the image is a mirrored effect)? Would like to use this to flip a powerpoint in real-time for a teleprompter screen.



philu
  • Members
  • 15 posts
  • Last active: Jan 21 2016 06:34 PM
  • Joined: 28 Aug 2012

****ing awesome!