AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

ScreenMagnifier
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
holomind



Joined: 11 Mar 2006
Posts: 299
Location: Munich, Germany

PostPosted: Fri Aug 11, 2006 11:34 pm    Post subject: Reply with quote

my optimized version

* removed buffer
* move away when mouse is inside the Magnifier

Code:

#NoEnv
SetBatchLines -1

CoordMode Mouse, Screen
OnExit #x
zoom = 2                ; initial magnification, 1..32
R = 128                 ; half side of magnifier window
Rz := R/zoom
                        ; GUI 2 shows the magnified image
Gui 2:+AlwaysOnTop -Caption +Resize +ToolWindow +E0x20
Gui 2:Show, % "w" 2*R+3 " h" 2*R+3 " x0 y0", Magnifier
WinGet MagnifierID, id,  Magnifier
WinSet Transparent, 255, Magnifier ; makes the window invisible to magnification
WinGet PrintSourceID, ID
                        ; Frame around magnified area
Gui +AlwaysOnTop -Caption +ToolWindow +E0x20 +0x800000
Gui Color, C
MouseGetPos x, y
Gui Show, % "w" 2*Rz " h" 2*Rz " x" x-Rz " y" y-Rz, Frame
WinSet TransColor, C, Frame

hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
hdc_frame := DllCall("GetDC", UInt, MagnifierID)

SetTimer Repaint, 50   ; flow through

Repaint:
   MouseGetPos x, y
   xz := In(x-Rz-6,0,A_ScreenWidth-2*Rz) ; keep the frame on screen
   yz := In(y-Rz-6,0,A_ScreenHeight-2*Rz)
   WinMove Frame,,%xz%, %yz%, % 2*Rz, % 2*Rz
   DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,0, Int,2*R, Int,2*R
   , UInt,hdd_frame, UInt,xz, UInt,yz, Int,2*Rz, Int,2*Rz, UInt,0xCC0020) ; SRCCOPY
   
   inside_old := inside
   inside := (( x < R*2 ) and ( y < R*2 ) ) * R*2 
   if ( %inside_old% <> %inside% )
       WinMove Magnifier,, ,%inside%
   
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")
     zoom *= 1.189207115         ; sqrt(sqrt(2))
  If (zoom >  1 and A_ThisHotKey = "^+WheelDown")
     zoom /= 1.189207115
  Rz := R/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
}
Back to top
View user's profile Send private message Visit poster's website
d-man



Joined: 08 Jun 2006
Posts: 245

PostPosted: Sat Aug 12, 2006 12:31 am    Post subject: Reply with quote

could someone make one where the magnifier is on the bottom and takes the whole width of the screen. i would want to make the middle mouse button turn it on & off also
Back to top
View user's profile Send private message
holomind



Joined: 11 Mar 2006
Posts: 299
Location: Munich, Germany

PostPosted: Sat Aug 12, 2006 12:44 am    Post subject: Reply with quote

d-man wrote:
could someone make one where the magnifier is on the bottom and takes the whole width of the screen. i would want to make the middle mouse button turn it on & off also


Like This ? you only have to play around with the numbers for R and w/h/x/y ??

if you move to much right it blurs. as it is offscreen!

if you want that windows dont maximize over the magnifier you can in win2k and xp . drag and drop a folder to the side of the screen, which then will be "snapped" to the border. then resize it and rightclick and make it always on top like the taskbar. later you can hide and close this toolbar with a rightclick on your taskbar, and you will find your folder there which you can check/uncheck.

or you simply make your taskbar bigger temporaily and cannot use it while the magnifier is on. ?

Mouseclick is enabled, or usw win-p for "pause". (repaint is stopped )

the script keeps running until you press win-x "exit"

Code:
#NoEnv
SetBatchLines -1

CoordMode Mouse, Screen
OnExit #x
zoom = 2                ; initial magnification, 1..32
R = 128                 ; half side of magnifier window
Rz := R/zoom
                        ; GUI 2 shows the magnified image
Gui 2:+AlwaysOnTop -Caption +Resize +ToolWindow +E0x20
Gui 2:Show, % "w" A_ScreenWidth " h" 2*R+3 " x0 y" A_ScreenHeight -2*R , Magnifier
WinGet MagnifierID, id,  Magnifier
WinSet Transparent, 255, Magnifier ; makes the window invisible to magnification
WinGet PrintSourceID, ID
                        ; Frame around magnified area
Gui +AlwaysOnTop -Caption +ToolWindow +E0x20 +0x800000
Gui Color, C
MouseGetPos x, y
Gui Show, % "w" 2*Rz " h" 2*Rz " x" x-Rz " y" y-Rz, Frame
WinSet TransColor, C, Frame

hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
hdc_frame := DllCall("GetDC", UInt, MagnifierID)

SetTimer Repaint, 50   ; flow through

Repaint:
   MouseGetPos x, y
   xz := In(x-Rz-6,0,A_ScreenWidth-2*Rz) ; keep the frame on screen
   yz := In(y-Rz-6,0,A_ScreenHeight-2*Rz)
   WinMove Frame,,%xz%, %yz%, % 2*Rz, % 2*Rz
   DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,0, Int,A_ScreenWidth, Int,2*R
   , UInt,hdd_frame, UInt,xz, UInt,yz, Int,A_ScreenWidth / zoom, Int,2*Rz, UInt,0xCC0020) ; SRCCOPY
   
Return

#x::
   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

^+WheelUp::                      ; Ctrl+Shift+WheelUp to zoom in
^+WheelDown::                    ; Ctrl+Shift+WheelUp to zoom out
  If (zoom < 31 and A_ThisHotKey = "^+WheelUp")
     zoom *= 1.189207115         ; sqrt(sqrt(2))
  If (zoom >  1 and A_ThisHotKey = "^+WheelDown")
     zoom /= 1.189207115
  Rz := R/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
}
Back to top
View user's profile Send private message Visit poster's website
d-man



Joined: 08 Jun 2006
Posts: 245

PostPosted: Sat Aug 12, 2006 1:38 am    Post subject: Reply with quote

sweet thx a lot

Code:
Like This ? you only have to play around with the numbers for R and w/h/x/y ??


ah.. well.. yea... uh... the script looked so scary i was afraid to touch it Embarassed
Back to top
View user's profile Send private message
holomind



Joined: 11 Mar 2006
Posts: 299
Location: Munich, Germany

PostPosted: Sat Aug 12, 2006 1:42 am    Post subject: Reply with quote

d-man wrote:

ah.. well.. yea... uh... the script looked so scary i was afraid to touch it Embarassed


yeah, thats lazlo's *compact* style. no line too much. and mixed up by three authors Wink
Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 3942
Location: Pittsburgh

PostPosted: Sat Aug 12, 2006 3:21 am    Post subject: Reply with quote

holomind wrote:
to make it even shorter, i recognized the buffers are not used.
I removed the corresponding 4 lines in my script above.
holomind wrote:
due to +E0x20, the magnifier is stuck in the top-left corner.
You are right, there is no need for the style +E0x20. I deleted it, and now, like in your original script, the magnifier window is movable by dragging it with its title bar.

The window is also resizable. Under the GuiSize label we set the dimensions used in the script, so any size rectangular magnifier window is possible. The moving frame adjusts to this.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 3942
Location: Pittsburgh

PostPosted: Sat Aug 12, 2006 3:45 am    Post subject: Reply with quote

Holomind's jumping magnifier window idea is clever, but it is hard to implement with resizable windows. There might not be enough room inside the screen, and you probably want the window to jump when the frame overlaps it, not when the mouse pointer enters it. Also, if you happen to be interested in the transition area, the jumping window drives you crazy, therefore, you might need some hysteresis.

If someone (d-man) wants a huge magnifier window, he just has to move and resize it.
Back to top
View user's profile Send private message
holomind



Joined: 11 Mar 2006
Posts: 299
Location: Munich, Germany

PostPosted: Sat Aug 12, 2006 4:05 am    Post subject: Reply with quote

you could use "WinSet Region" and make the region of the Frame-Window visible. (Digg hole in the Magnifier-Window using 2 polygons ) but i dont know if this is usefull. if your magnifier is bigger then half of the screen it doesnt make much sense to move it out of the way, but with less then A_ScreenHeight or A_ScreenWidth it might make sense.
i also like the hidden feature to doubleclick the titlebar of Magnifier and have fullscreen magnifier and "simulate" a different screen resolution Wink ideal for zooming swf-videos. quicktime gets zoomed , but not avi. but thats not a problem as avi can be made fullscreen.

i also like the new #p (pause) button i made for d-man, so the script can run in background and wakes up when needed. (but perhaps it saves memory to close and restart the script from an outside ahk-script ?)

also you can use the antialize toggle, which IMO makes sense with odd zoomlevels (half pixels). the SetStrechBltMode only has to set once and not before every DC-Copy.

Code:

#a::
  antialize := 4 - antialize
  DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_frame, "int", antialize )  ; Antializing ?
Return
Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 3942
Location: Pittsburgh

PostPosted: Sat Aug 12, 2006 4:11 am    Post subject: Reply with quote

(Bist du verrückt? Es ist fünf Uhr Samstagmorgen!)
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 3942
Location: Pittsburgh

PostPosted: Sat Aug 12, 2006 4:32 am    Post subject: Reply with quote

I used the magnifier to get hints from existing icons, how to set the colors of pixels in my own icons. In that application antialiasing makes more harm than good. However, as you say, magnifying small web pictures, even videos is another good application, where antialiasing improves the image. In your code example you have to initialize the "antialize" variable, but with this variant you don't (and save a whole line of code).
Code:
#a::
  antialize := !antialize
  DllCall("gdi32.dll\SetStretchBltMode", UInt,hdc_frame, Int,4*antialize)
Return
Back to top
View user's profile Send private message
Trombonisto



Joined: 18 Aug 2006
Posts: 7
Location: Vogtland/ Germany

PostPosted: Fri Aug 18, 2006 1:49 am    Post subject: Reply with quote

Hello!

You did a really good job! Congratulation!

I modified the magnifier for my situation e.g. no mouse wheel, that was simple. But I'm not able to make a crosshair I need in the magnifier. Could you help me please?

The centre of the crosshair must be the mouse point. I saw a magnifier with a little square in the middle of the crosshair showing an one pixel hole for exactly finding the right position. And if the crosshair could invert its colour over black it would be perfect.

For explanation: I would use the magnifier in combination with an own small tool for measurement of graphs and drawings and insert the coordinates into a spreadsheet. BTW how can I hinder that with every transmission the spreadsheet window shortly pops up?

I would be very grateful if you could help me.

Best greetings
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 3942
Location: Pittsburgh

PostPosted: Fri Aug 18, 2006 2:52 am    Post subject: Reply with quote

You can find a few crosshair scripts here. If you make the splash images semi-transparent (WinSet Transparent, 255…), they won't show up in the magnified image (too thick), but with another crosshair in the middle of the magnifier window, you can mark its center.

I don't know any simple way to invert the crosshair color, dependent on the background. The easiest, but not very nice solution was to just periodically redraw the lines, once black, once white, creating a flashing effect.

If you want to send input to an inactive window, try ControlSend.
Back to top
View user's profile Send private message
holomind



Joined: 11 Mar 2006
Posts: 299
Location: Munich, Germany

PostPosted: Fri Aug 18, 2006 7:04 am    Post subject: Reply with quote

hi, which version of the magniferscript do you use ? we have about 4 variants in this thread Wink i quess the last one from lazlo?

one idea to draw the crosshair is to use some strechblt or bitblt to invert the crosshair over the magnified image.

the current copy-mode is "SRCCOPY" but there also is a mode which produces XOR i think. this would invert all pixels. then it would not be really black but invert, perhaps this is even better as you dont loose the colorinformation behind the crosshair (as its inverse and you can guess?)

or one uses DLLCall for drawing Lines with GDI, there are Commands for Draw Dot, Draw Circle?, Draw Line, FillRect.

one trick could also be to create a black buffer (DC) and then bitblt only the needed black line over to the magnifier window/gui/DC.

in the bitblt you define the source-coordinates and the destination-coordinates. so you would need 2 bitblts to create your crosshair by bitblt of something like. destx1=mag_size/2, desty1=0, destx2=mag_size/2 +1, desty2=magnifier_height...
you get the idea

you should also check lazlos link for crosshair scripts.

i guess using ddl-calls for gdi32.dll will be fastest performance!
the magnifier already makes heavy use of bitblt or strechblt so it would be natural to use it for the crosshair also.
(adding 2 stechblts with SCRINVERT for exampe, one for horizontal and one for vertical line)

eg. like here:
http://www.autohotkey.com/forum/viewtopic.php?t=5273
Code:

;#############   draw cross lines   ###########################################
DrawCross( p_x, p_y, p_w, p_h )
  {
    global   hdc_frame, h_pen
         
    ;margin to the inside of the region to start drawing the lines
    LineMargin = 10

    ;select the correct pen into DC
    DllCall( "gdi32.dll\SelectObject"
           , "uint", hdc_frame
           , "uint", h_pen )
               
    ;update the current position to specified point
    DllCall( "gdi32.dll\MoveToEx"
           , "uint", hdc_frame
           , "int", p_x+LineMargin
           , "int", p_y+LineMargin
           , "uint", 0)
   
    ;draw a line from the current position up to, but not including, the specified point.
    DllCall( "gdi32.dll\LineTo"
           , "uint", hdc_frame
           , "int", p_x+p_w-LineMargin
           , "int", p_y+p_h-LineMargin)
   
    DllCall( "gdi32.dll\MoveToEx"
           , "uint", hdc_frame
           , "int", p_x+p_w-LineMargin
           , "int", p_y+LineMargin
           , "uint", 0)

    DllCall( "gdi32.dll\LineTo"
           , "uint", hdc_frame
           , "int", p_x+LineMargin
           , "int", p_y+p_h-LineMargin)


for the xor idea see:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceui40/html/cerefbitblt.asp
Code:

SRCAND    Combines the colors of the source and destination rectangles by using the Boolean AND operator.
SRCCOPY    Copies the source rectangle directly to the destination rectangle.
SRCERASE    Combines the inverted colors of the destination rectangle with the colors of the source rectangle by using the Boolean AND operator.
SRCINVERT    Combines the colors of the source and destination rectangles by using the Boolean XOR operator.
SRCPAINT    Combines the colors of the source and destination rectangles by using the Boolean OR operator.


the integerss for the modes
Code:

public enum TernaryRasterOperations
{
SRCCOPY = 0x00CC0020, /* dest = source*/
SRCPAINT = 0x00EE0086, /* dest = source OR dest*/
SRCAND = 0x008800C6, /* dest = source AND dest*/
SRCINVERT = 0x00660046, /* dest = source XOR dest*/
SRCERASE = 0x00440328, /* dest = source AND (NOT dest )*/
NOTSRCCOPY = 0x00330008, /* dest = (NOT source)*/
NOTSRCERASE = 0x001100A6, /* dest = (NOT src) AND (NOT dest) */
MERGECOPY = 0x00C000CA, /* dest = (source AND pattern)*/
MERGEPAINT = 0x00BB0226, /* dest = (NOT source) OR dest*/
PATCOPY = 0x00F00021, /* dest = pattern*/
PATPAINT = 0x00FB0A09, /* dest = DPSnoo*/
PATINVERT = 0x005A0049, /* dest = pattern XOR dest*/
DSTINVERT = 0x00550009, /* dest = (NOT dest)*/
BLACKNESS = 0x00000042, /* dest = BLACK*/
WHITENESS = 0x00FF0062, /* dest = WHITE*/
};

i also like the idea with

Code:

Gui +E0x20

for making the window "clickthrough" and allowing normal usage of mouse and context-menu. but this would interfere with moving the magnifierwindow as already discussed.

perhaps you already use the version which acts as a lens following the mouse directly.


Last edited by holomind on Sat Aug 19, 2006 9:41 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
Trombonisto



Joined: 18 Aug 2006
Posts: 7
Location: Vogtland/ Germany

PostPosted: Fri Aug 18, 2006 5:21 pm    Post subject: Reply with quote

Hello Laszlo and holomind!

Many thanks for your very quick response!

I use the holomind version from August 11.

All your sugestions sound very good but I guess to implemet them in my script should be too hard for me as a poor AHK- beginner. But in the next few days I want to try it. Hope that I can't destroy someting in my system with such code?

I set the code from http://www.autohotkey.com/forum/viewtopic.php?t=5273 into the August 11 version after
WinGet PrintSourceID, ID
and tried to adapt:
Code:
;#############   draw cross lines   ###########################################
;specify the style, thickness and color of the cross lines
  h_pen := DllCall( "gdi32.dll\CreatePen"
                   , "int", 1
                   , "int", 1
                   , "uint", 0x00BBGGRR)

;retrieve the ID number
  WinGet, hw_frame, id

;Get handle to display device context (DC) for the client area of a specified window
  hdc_frame := DllCall( "GetDC"
                      , "uint", hw_frame )                   

DrawCross( x, y, w, h )
  {
    global   hdc_frame, h_pen
         
    ;margin to the inside of the region to start drawing the lines
    LineMargin = 10

    ;select the correct pen into DC
    DllCall( "gdi32.dll\SelectObject"
           , "uint", hdc_frame
           , "uint", h_pen )
               
    ;update the current position to specified point
    DllCall( "gdi32.dll\MoveToEx"
           , "uint", hdc_frame
           , "int", x+LineMargin
           , "int", y+LineMargin
           , "uint", 0)
   
    ;draw a line from the current position up to, but not including, the specified point.
    DllCall( "gdi32.dll\LineTo"
           , "uint", hdc_frame
           , "int", x+w-LineMargin
           , "int", y+h-LineMargin)
   
    DllCall( "gdi32.dll\MoveToEx"
           , "uint", hdc_frame
           , "int", x+w-LineMargin
           , "int", y+LineMargin
           , "uint", 0)

    DllCall( "gdi32.dll\LineTo"
           , "uint", hdc_frame
           , "int", x+LineMargin
           , "int", y+h-LineMargin)
  }

But nothing happens Crying or Very sad I repeat it seems to be too dfficult to me!

Maybe tomorrow I have a better day. Bye

Trombonisto
Back to top
View user's profile Send private message
holomind



Joined: 11 Mar 2006
Posts: 299
Location: Munich, Germany

PostPosted: Fri Aug 18, 2006 6:08 pm    Post subject: Reply with quote

oh, i thought my hints for using this functions would be enough for a startoff.
perhaps i find some time on weekend to try my version with srcinvert and bitblt. which should be realtively easy and fast.

you took the idea with moveTo and LineTo. so more like classical draw-a-line.

do you really need a black crosshair? as i gues using little xors with bitblt would be easier. like applying a mask/filter with a image-editor.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3, 4, 5, 6  Next
Page 2 of 6

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group