now the idea of using bitblt to draw black lines applied.
(the lines go offset if you change zoom, i didnt understand the usage of M_C and R_C and zoom_c. so it does not adopt. i only want to show, how to use bitblt to draw lines (by copying black pixels from the DC to itself)
or in other words. fill a rectangle which is only one pixel high or wide.
perhaps this is faster as the drawline algorythm, as there is no need to detect the steps and angles. but lines are drawn by hardware-accelleration so one should not see a difference. also if the programmers implementing the line algo were smart they use bitblt for horizontal and vertical lines anyways.
one difference is that you can draw a line with one dll-call with drawline you have 2 dllcalls, one for move (define start) and draw (to define end).
you could make the cross even with less dllcalls (4) if you first draw the black cross (1hor 1 ver) and then repaint the inside of the cross not with copy-style solid but copy-style src-copy (frame2magnifiert) which needs more calulation for the right coordinates (you need strechblt and cant do it with bitblt)
bitblt: copy without zoom from src to dest. so you only define the start of src. (src-witdh/heihght are same with dest.w/h !)
strechblt: copy with zoom, so you define both rectangles src + dest for the drawing engine to know what to do.
after applying this change , the reactiontime was still slow, so maybe the drawline dllcalls arent so bad.
the problem was with your "optimization" of the move-magnifier.
in honor of lazlo i used supercompressed codestyle to move the window only when it changed. you removed this from your script and winmove (which is painfully slow) was called every repaint (and not only when it changes).
AHK is not smart enough to detect that the new position is the same and nothing is needed to be done. but on some posts in this forum this "bug" is used to force a repaint of the window calling winmove with old or no position.
so here my modified script:
* changed drawlines to bitblit draw horizontal vertial (note that this will never work with diagonal lines!)
* bugfixed the move-away function to make the script react much faster.
you can simply exchange the DrawCross function with the old one if you want your red lines back (which probably are not as slow as i suggested)
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
; Frame around magnified area
Gui +AlwaysOnTop -Caption +ToolWindow +E0x20 +0x800000
Gui Color, 0x00CCCCCC
MouseGetPos x, y
Gui Show, % "w" 2*Rz " h" 2*Rz " x" x-Rz " y" y-Rz, Frame
WinSet TransColor, 0x00CCCCCC, Frame
WinGet FrameID, id , Frame
hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
hdc_frame := DllCall("GetDC", UInt, MagnifierID)
;############# draw cross lines ###########################################
DrawCross( M_C , R_C, zoom_c, dc )
{
;vertical
DllCall("gdi32.dll\BitBlt", UInt,dc, Int,R_C, Int,0, Int,1, Int,R_C
, UInt,dc, UInt,0, UInt,0, UInt,0x00000042) ; SOLID_BLACK (42)
DllCall("gdi32.dll\BitBlt", UInt,dc, Int,R_C+M_C-2, Int,0, Int,1, Int,R_C
, UInt,dc, UInt,0, UInt,0, UInt,0x00000042) ; SOLID_BLACK (42)
DllCall("gdi32.dll\BitBlt", UInt,dc, Int,R_C, Int,R_C+M_C, Int,1, Int,R_C
, UInt,dc, UInt,0, UInt,0, UInt,0x00000042) ; SOLID_BLACK (42)
DllCall("gdi32.dll\BitBlt", UInt,dc, Int,R_C+M_C-2, Int,R_C+M_C, Int,1, Int,R_C
, UInt,dc, UInt,0, UInt,0, UInt,0x00000042) ; SOLID_BLACK (42)
;horizontal
DllCall("gdi32.dll\BitBlt", UInt,dc, Int,1, Int,R_C, Int,R_C, Int,1
, UInt,dc, UInt,0, UInt,0, UInt,0x00000042) ; SOLID_BLACK (42)
DllCall("gdi32.dll\BitBlt", UInt,dc, Int,1, Int,R_C+M_C, Int,R_C, Int,1
, UInt,dc, UInt,0, UInt,0, UInt,0x00000042) ; SOLID_BLACK (42)
DllCall("gdi32.dll\BitBlt", UInt,dc, Int,R_C+M_C-1, Int,R_C, Int,R_C, Int,1
, UInt,dc, UInt,0, UInt,0, UInt,0x00000042) ; SOLID_BLACK (42)
DllCall("gdi32.dll\BitBlt", UInt,dc, Int,R_C+M_C-1, Int,R_C+M_C, Int,R_C, Int,1
, UInt,dc, UInt,0, UInt,0, UInt,0x00000042) ; SOLID_BLACK (42)
}
SetTimer Repaint, 50 ; flow through
Repaint:
MouseGetPos x, y
xz := x-Rz
yz := y-Rz
WinMove Frame,,%xz%, %yz%, % 2*Rz, % 2*Rz
WinGetPos, mx, my, mw,mh, Magnifier
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
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 )
WinMove Magnifier,, ,pos_new
pos_old := pos_new
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
; you could even read the current mousespeed for later use ?
; maybe not every body uses speed=10 ?
; my guess is that SysParaInfo will return the current speed
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 to %mouse_speed_old%
mouse_slow =
return
;Mouse move one step with arrow keys
#Up::
MouseMove, 0, -1, 0, R
Return
#Down::
MouseMove, 0, 1, 0, R
Return
#Left::
MouseMove, -1, 0, 0, R
Return
#Right::
MouseMove, 1, 0, 0, R
Return