26

Re: AHK: Экранная лупа

Примерно так. Пока непонятно предназначение CreateCompatibleBitmap и SelectObject.


#NoEnv
#SingleInstance Force
#KeyHistory 0
ListLines Off
SetBatchLines,-1
OnExit, ZoomOnClose
OnMessage(0xF, "WM_Paint")
Global oZoom := {} 

oZoom.Zoom := 4
oZoom.Mark := "Cross"		; Cross, Square, Grid

; WinX := 1559
; WinY := 594
WinW := 300
WinH := 360

Gui, Zoom: +AlwaysOnTop +Resize -DPIScale +hwndhGui +LabelZoomOn
Gui, Zoom: Font, s12
Gui, Zoom: Color, ffffff
Gui, Zoom: Add, Slider, vSliderZoom gSliderZoom x8 Range1-50 w176 Center AltSubmit NoTicks, % oZoom.Zoom
Gui, Zoom: Add, Text, vTextZoom Center x+10 yp+3 w36, % oZoom.Zoom
Gui, Zoom: Font
Gui, Zoom: Add, Button, gChangeMark vChangeMark x+10 yp w52, % oZoom.Mark
Gui, Dev: +HWNDhDev -Caption -DPIScale +Parent%hGui% +Border
Gui, Dev: Add, Pic, hwndhDevCon 
Gui, Dev: Show, NA
Gui, Dev: Color, ffffff

; Gui, Zoom: Show, x%WinX% y%WinY% w%WinW% h%WinH%, Magnify
Gui, Zoom: Show, w%WinW% h%WinH%, Magnify
Gui, Zoom: +MinSize

oZoom.hdcSrc := DllCall("GetDC", Ptr, 0)
oZoom.hdcDest := DllCall("GetDC", Ptr, hDevCon, Ptr)
oZoom.hdcDummyDest := DllCall("CreateCompatibleDC", "Ptr", 0)  
DllCall("Gdi32.Dll\SetStretchBltMode", "Ptr", oZoom.hdcDest, "Int", 4)
oZoom.hGui := hGui
oZoom.hDev := hDev
oZoom.hDevCon := hDevCon
Magnify() 
Return

#If !oZoom.Minimize
+Up::MouseMove, 0, -1, 0, R
+Down::MouseMove, 0, 1, 0, R
+Left::MouseMove, -1, 0, 0, R
+Right::MouseMove, 1, 0, 0, R

^Up::
^DoWn::
^WheelUp::
^WheelDown::ChangeZoom(InStr(A_ThisHotKey, "DoWn") ? oZoom.Zoom + 1 : oZoom.Zoom - 1)

1:: oZoom.Pause := !oZoom.Pause
#If

Magnify() {
	S_CoordModeMouse := A_CoordModeMouse
	CoordMode, Mouse, Screen
	MouseGetPos, mX, mY, WinID
	CoordMode, Mouse, %S_CoordModeMouse% 
	If (!oZoom.Pause && WinID != oZoom.hGui)
	{   
		StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
			, oZoom.hdcSrc, mX - oZoom.nXOriginSrcOffset, mY - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
		For k, v In oZoom.oMarkers[oZoom.Mark]
			StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT 

		hBM := DllCall("Gdi32.Dll\CreateCompatibleBitmap", "Ptr", oZoom.hdcSrc, "Int", oZoom.nWidthSrc, "Int", oZoom.nHeightSrc)
		DllCall("Gdi32.Dll\SelectObject", "Ptr", oZoom.hdcDummyDest, "Ptr", hBM), DllCall("DeleteObject", "Ptr", hBM)
		BitBlt(oZoom.hdcDummyDest, 0, 0, oZoom.nWidthSrc, oZoom.nHeightSrc, oZoom.hdcSrc, mX - oZoom.nXOriginSrcOffset, mY - oZoom.nYOriginSrcOffset)
	}
	SetTimer, Magnify, -10
}

SetSize() {
	Static Top := 64, Left := 4, Right := 4, Bottom := 4
 
	GetClientPos(oZoom.hGui, GuiWidth, GuiHeight)
	Width := GuiWidth - Left - Right
	Height := GuiHeight - Top - Bottom
	Zoom := oZoom.Zoom
	conW := Mod(Width, Zoom) ? Width - Mod(Width, Zoom) + Zoom : Width
	conW := Mod(conW // Zoom, 2) ? conW : conW + Zoom
	conH := Mod(Height, Zoom) ? Height - Mod(Height, Zoom) + Zoom : Height
	conH := Mod(conH // Zoom, 2) ? conH : conH + Zoom
	conX := ((conW - Width) // 2) * -1
	conY := ((conH - Height) // 2) * -1

	oZoom.nWidthSrc := conW // Zoom
	oZoom.nHeightSrc := conH // Zoom
	oZoom.nXOriginSrcOffset := oZoom.nWidthSrc // 2
	oZoom.nYOriginSrcOffset := oZoom.nHeightSrc // 2
	oZoom.nWidthDest := conW
	oZoom.nHeightDest := conH
	oZoom.xCenter := conW / 2 - Zoom / 2
	oZoom.yCenter := conH / 2 - Zoom / 2

	Zoom := oZoom.Zoom
	nWidthDest := oZoom.nWidthDest
	nHeightDest := oZoom.nHeightDest
	xCenter := oZoom.xCenter, yCenter := oZoom.yCenter

	oZoom.oMarkers["Cross"] := [{x:0,y:yCenter - 1,w:nWidthDest,h:1}
		, {x:0,y:yCenter + Zoom,w:nWidthDest,h:1}
		, {x:xCenter - 1,y:0,w:1,h:nHeightDest}
		, {x:xCenter + Zoom,y:0,w:1,h:nHeightDest}]

	oZoom.oMarkers["Square"] := [{x:xCenter - 1,y:yCenter,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + Zoom + 1,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + 1,w:1,h:Zoom}
		, {x:xCenter + Zoom,y:yCenter + 1,w:1,h:Zoom}]

	oZoom.oMarkers["Grid"] := Zoom = 1 ? oZoom.oMarkers["Square"]
		: [{x:xCenter - Zoom,y:yCenter - Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom * 2,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom * 2,y:yCenter - Zoom,w:1,h:Zoom * 3}]

	WinMove, % "ahk_id" oZoom.hDev, , Left, Top, Width, Height
	GuiControl, Dev: -Redraw, % oZoom.hDevCon
	WinMove, % "ahk_id" oZoom.hDevCon, , conX, conY, conW, conH
	Redraw()
	GuiControl, Dev: +Redraw, % oZoom.hDevCon 
} 

ZoomOnSize() {
	If A_EventInfo != 1
	{
		SetTimer, SetSize, -100
		oZoom.Minimize := 0
	}
	Else
		oZoom.Minimize := 1
}

SliderZoom() {
	GuiControlGet, SliderZoom, Zoom:
	ChangeZoom(SliderZoom)
}

ChangeZoom(Val) {
	If (Val < 1 || Val > 50)
		Return
	GuiControl, Zoom: , TextZoom, % oZoom.Zoom := Val
	GuiControl, Zoom: , SliderZoom, % oZoom.Zoom
	SetTimer, SetSize, -150
}

ChangeMark() {
	oZoom.Mark := ["Cross","Square","Grid","None"][{"Cross":2,"Square":3,"Grid":4,"None":1}[oZoom.Mark]]
	GuiControl, Zoom: , ChangeMark, % oZoom.Mark
	Redraw()
}

ZoomOnClose:
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcDest)
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcSrc)
	ExitApp

GetClientPos(hwnd, ByRef W, ByRef H)  {
	VarSetCapacity(pwi, 60, 0), NumPut(60, pwi, 0, "UInt")
	DllCall("GetWindowInfo", "Ptr", hwnd, "UInt", &pwi)
	W := NumGet(pwi, 28, "int") - NumGet(pwi, 20, "int")
	H := NumGet(pwi, 32, "int") - NumGet(pwi, 24, "int")
}

WM_Paint() {
	SetTimer, Redraw, -10
}

Redraw() { 
	StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
		, oZoom.hdcDummyDest, 0, 0, oZoom.nWidthSrc, oZoom.nHeightSrc)
	For k, v In oZoom.oMarkers[oZoom.Mark]
		StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT
}

BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster="") {
	Ptr := A_PtrSize ? "UPtr" : "UInt" 
	return DllCall("Gdi32.Dll\BitBlt"
					, Ptr, dDC
					, "int", dx
					, "int", dy
					, "int", dw
					, "int", dh
					, Ptr, sDC
					, "int", sx
					, "int", sy
					, "uint", Raster ? Raster : 0xC000CA)
}

StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster="") {
	Ptr := A_PtrSize ? "UPtr" : "UInt" 
	return DllCall("Gdi32.Dll\StretchBlt"
					, Ptr, ddc
					, "int", dx
					, "int", dy
					, "int", dw
					, "int", dh
					, Ptr, sdc
					, "int", sx
					, "int", sy
					, "int", sw
					, "int", sh
					, "uint", Raster ? Raster : 0xC000CA)
}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

27

Re: AHK: Экранная лупа

DC содержит набор графических объектов, в том числе битмап. Compatible DC при создании имеет чёрно-белый битмап размером 1 пиксель. Поэтому нужно для него создать нужный битмап и выбрать его, чтобы заместить дефолтный.

28

Re: AHK: Экранная лупа

Думаю, хорошо было бы в режиме паузы добавить возможность не только увеличивать изображение, но еще и двигать - аналог руки в фотошопе.

29

Re: AHK: Экранная лупа

YMP
Спасибо за пояснения.
Malcev
Для этого надо будет каждый раз сохранять в Memory Device Context весь экран, возможно это будет существенно замедлять работу, особенно на 2 мониторах с 4к, попробую на досуге.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

30

Re: AHK: Экранная лупа

serzh82saratov пишет:

Для этого надо будет каждый раз сохранять в Memory Device Context весь экран, возможно это будет существенно замедлять работу

Уже на экране 4480х1600 грузит проц на 10%. Как вариант сохранять в момент наступления паузы, но только иногда можно не попасть в "кон".

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

31 (изменено: serzh82saratov, 2016-04-14 04:05:35)

Re: AHK: Экранная лупа

Вообщем такая пока штука:


#NoEnv
#SingleInstance Force
#KeyHistory 0
ListLines Off
SetBatchLines,-1
OnExit, ZoomOnClose
Try Menu, Tray, Icon, Shell32, 23
OnMessage(0xF, "WM_Paint")
Global oZoom := {}

oZoom.Zoom := 1
oZoom.Mark := "Cross"		; Cross, Square, Grid, None

; WinX := 1559
; WinY := 594
WinW := 300
WinH := 360

Gui, Zoom: +AlwaysOnTop +Resize -DPIScale +hwndhGui +LabelZoomOn
Gui, Zoom: Font, s12
Gui, Zoom: Color, ffffff
Gui, Zoom: Add, Slider, vSliderZoom gSliderZoom x8 Range1-50 w176 Center AltSubmit NoTicks, % oZoom.Zoom
Gui, Zoom: Add, Text, vTextZoom Center x+10 yp+3 w36, % oZoom.Zoom
Gui, Zoom: Font
Gui, Zoom: Add, Button, gChangeMark vChangeMark x+10 yp w52, % oZoom.Mark
Gui, Dev: +HWNDhDev -Caption -DPIScale +Parent%hGui% +Border
Gui, Dev: Add, Pic, hwndhDevCon 
Gui, Dev: Show, NA
Gui, Dev: Color, ffffff

; Gui, Zoom: Show, x%WinX% y%WinY% w%WinW% h%WinH%, Magnify
Gui, Zoom: Show, w%WinW% h%WinH%, Magnify
Gui, Zoom: +MinSize

oZoom.hdcSrc := DllCall("GetDC", "Ptr", 0)
oZoom.hdcDest := DllCall("GetDC", "Ptr", hDevCon, "Ptr")
oZoom.hdcMemory := DllCall("CreateCompatibleDC", "Ptr", 0)  
DllCall("Gdi32.Dll\SetStretchBltMode", "Ptr", oZoom.hdcDest, "Int", 4)
oZoom.hGui := hGui
oZoom.hDev := hDev
oZoom.hDevCon := hDevCon
Magnify()  
Return

#If !oZoom.Minimize
+Up::MouseMove, 0, -1, 0, R
+Down::MouseMove, 0, 1, 0, R
+Left::MouseMove, -1, 0, 0, R
+Right::MouseMove, 1, 0, 0, R

^Up::
^DoWn::
^WheelUp::
^WheelDown::ChangeZoom(InStr(A_ThisHotKey, "DoWn") ? oZoom.Zoom + 1 : oZoom.Zoom - 1)

1:: oZoom.Pause := !oZoom.Pause
#If

Magnify() {
	If !oZoom.Pause
	{
		MouseGetPos, , , WinID
		If (WinID != oZoom.hGui)
		{
			SetTimer, Memory, Off
			DllCall("GetCursorPos", "int64P", pt)
			oZoom.MouseX := pt << 32 >> 32, oZoom.MouseY := pt >> 32
			StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
				, oZoom.hdcSrc, oZoom.MouseX - oZoom.nXOriginSrcOffset, oZoom.MouseY - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
			For k, v In oZoom.oMarkers[oZoom.Mark]
				StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT 
			SetTimer, Memory, -30
		}
	}
	SetTimer, Magnify, -10
}

Memory() {
	SysGet, VirtualScreenX, 76
	SysGet, VirtualScreenY, 77
	SysGet, VirtualScreenWidth, 78
	SysGet, VirtualScreenHeight, 79 
	oZoom.nXOriginSrc := oZoom.MouseX - VirtualScreenX, oZoom.nYOriginSrc := oZoom.MouseY - VirtualScreenY
	hBM := DllCall("Gdi32.Dll\CreateCompatibleBitmap", "Ptr", oZoom.hdcSrc, "Int", VirtualScreenWidth, "Int", VirtualScreenHeight)
	DllCall("Gdi32.Dll\SelectObject", "Ptr", oZoom.hdcMemory, "Ptr", hBM), DllCall("DeleteObject", "Ptr", hBM)
	BitBlt(oZoom.hdcMemory, 0, 0, VirtualScreenWidth, VirtualScreenHeight, oZoom.hdcSrc, VirtualScreenX, VirtualScreenY)
}

Redraw() {
	StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
		, oZoom.hdcMemory, oZoom.nXOriginSrc - oZoom.nXOriginSrcOffset, oZoom.nYOriginSrc - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
	For k, v In oZoom.oMarkers[oZoom.Mark]
		StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT
}

SetSize() {
	Static Top := 64, Left := 4, Right := 4, Bottom := 4
 
	GetClientPos(oZoom.hGui, GuiWidth, GuiHeight)
	Width := GuiWidth - Left - Right
	Height := GuiHeight - Top - Bottom
	Zoom := oZoom.Zoom
	conW := Mod(Width, Zoom) ? Width - Mod(Width, Zoom) + Zoom : Width
	conW := Mod(conW // Zoom, 2) ? conW : conW + Zoom
	conH := Mod(Height, Zoom) ? Height - Mod(Height, Zoom) + Zoom : Height
	conH := Mod(conH // Zoom, 2) ? conH : conH + Zoom
	conX := ((conW - Width) // 2) * -1
	conY := ((conH - Height) // 2) * -1

	oZoom.nWidthSrc := conW // Zoom
	oZoom.nHeightSrc := conH // Zoom
	oZoom.nXOriginSrcOffset := oZoom.nWidthSrc // 2
	oZoom.nYOriginSrcOffset := oZoom.nHeightSrc // 2
	oZoom.nWidthDest := nWidthDest := conW
	oZoom.nHeightDest := nHeightDest := conH
	oZoom.xCenter := xCenter := conW / 2 - Zoom / 2
	oZoom.yCenter := yCenter := conH / 2 - Zoom / 2

	oZoom.oMarkers["Cross"] := [{x:0,y:yCenter - 1,w:nWidthDest,h:1}
		, {x:0,y:yCenter + Zoom,w:nWidthDest,h:1}
		, {x:xCenter - 1,y:0,w:1,h:nHeightDest}
		, {x:xCenter + Zoom,y:0,w:1,h:nHeightDest}]

	oZoom.oMarkers["Square"] := [{x:xCenter - 1,y:yCenter,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + Zoom + 1,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + 1,w:1,h:Zoom}
		, {x:xCenter + Zoom,y:yCenter + 1,w:1,h:Zoom}]

	oZoom.oMarkers["Grid"] := Zoom = 1 ? oZoom.oMarkers["Square"]
		: [{x:xCenter - Zoom,y:yCenter - Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom * 2,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom * 2,y:yCenter - Zoom,w:1,h:Zoom * 3}]

	WinMove, % "ahk_id" oZoom.hDev, , Left, Top, Width, Height
	GuiControl, Dev: -Redraw, % oZoom.hDevCon
	WinMove, % "ahk_id" oZoom.hDevCon, , conX, conY, conW, conH
	Redraw()
	GuiControl, Dev: +Redraw, % oZoom.hDevCon 
} 

ZoomOnSize() {
	If A_EventInfo != 1
	{
		SetTimer, SetSize, -100
		oZoom.Minimize := 0
	}
	Else
		oZoom.Minimize := 1
}

SliderZoom() {
	GuiControlGet, SliderZoom, Zoom:
	ChangeZoom(SliderZoom)
}

ChangeZoom(Val) {
	If (Val < 1 || Val > 50)
		Return
	GuiControl, Zoom: , TextZoom, % oZoom.Zoom := Val
	GuiControl, Zoom: , SliderZoom, % oZoom.Zoom
	SetTimer, SetSize, -150
}

ChangeMark() {
	oZoom.Mark := ["Cross","Square","Grid","None"][{"Cross":2,"Square":3,"Grid":4,"None":1}[oZoom.Mark]]
	GuiControl, Zoom: , ChangeMark, % oZoom.Mark
	Redraw()
}

ZoomOnClose:
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcDest)
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcSrc)
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcMemory)
	ExitApp

GetClientPos(hwnd, ByRef W, ByRef H)  {
	VarSetCapacity(pwi, 60, 0), NumPut(60, pwi, 0, "UInt")
	DllCall("GetWindowInfo", "Ptr", hwnd, "UInt", &pwi)
	W := NumGet(pwi, 28, "Int") - NumGet(pwi, 20, "Int")
	H := NumGet(pwi, 32, "Int") - NumGet(pwi, 24, "Int")
}

WM_Paint() {
	SetTimer, Redraw, -10
}

BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster = 0x00CC0020) {
	Return DllCall("Gdi32.Dll\BitBlt"
					, "Ptr", dDC
					, "Int", dx
					, "Int", dy
					, "Int", dw
					, "Int", dh
					, "Ptr", sDC
					, "Int", sx
					, "Int", sy
					, "Uint", Raster)
}

StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster = 0x00CC0020) {
	Return DllCall("Gdi32.Dll\StretchBlt"
					, "Ptr", dDC
					, "Int", dx
					, "Int", dy
					, "Int", dw
					, "Int", dh
					, "Ptr", sDC
					, "Int", sx
					, "Int", sy
					, "Int", sw
					, "Int", sh
					, "Uint", Raster)
}

Потестируйте, у кого как, после надо будет прикрутить руку, индикаторы какие нибудь, и настройки.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

32

Re: AHK: Экранная лупа

Как-то она сильно дергается при увеличении-уменьшении по сравнению с этим вариантом:
https://autohotkey.com/board/topic/1066 … magnifier/

33

Re: AHK: Экранная лупа

Это третий вопрос темы.
Может я сильно перемудрил в функции SetSize, просто для меня принципиально что определяемый пиксель должен находится точно в центре лупы, а также полоски подсвечивающие пиксель.
Посмотри, так получше стало?


#NoEnv
#SingleInstance Force
#KeyHistory 0
ListLines Off
SetBatchLines,-1
OnExit("ZoomOnClose")
Try Menu, Tray, Icon, Shell32, 23
OnMessage(0xF, "WM_Paint")
Global oZoom := {}

oZoom.Zoom := 1
oZoom.Mark := "Cross"		; Cross, Square, Grid, None

; WinX := 1559
; WinY := 594
WinW := 300
WinH := 360

Gui, Zoom: +AlwaysOnTop +Resize -DPIScale +hwndhGui +LabelZoomOn
Gui, Zoom: Font, s12
Gui, Zoom: Color, ffffff
Gui, Zoom: Add, Slider, vSliderZoom gSliderZoom x8 Range1-50 w176 Center AltSubmit NoTicks, % oZoom.Zoom
Gui, Zoom: Add, Text, vTextZoom Center x+10 yp+3 w36, % oZoom.Zoom
Gui, Zoom: Font
Gui, Zoom: Add, Button, gChangeMark vChangeMark x+10 yp w52, % oZoom.Mark
Gui, Dev: +HWNDhDev -Caption -DPIScale +Parent%hGui% +Border
Gui, Dev: Add, Pic, hwndhDevCon 
Gui, Dev: Show, NA
Gui, Dev: Color, ffffff

; Gui, Zoom: Show, x%WinX% y%WinY% w%WinW% h%WinH%, Magnify
Gui, Zoom: Show, w%WinW% h%WinH%, Magnify
Gui, Zoom: +MinSize

oZoom.hdcSrc := DllCall("GetDC", "Ptr", 0)
oZoom.hdcDest := DllCall("GetDC", "Ptr", hDevCon, "Ptr")
oZoom.hdcMemory := DllCall("CreateCompatibleDC", "Ptr", 0)  
DllCall("Gdi32.Dll\SetStretchBltMode", "Ptr", oZoom.hdcDest, "Int", 4)
oZoom.hGui := hGui
oZoom.hDev := hDev
oZoom.hDevCon := hDevCon
Magnify()  
Return

#If !oZoom.Minimize
+Up::MouseMove, 0, -1, 0, R
+Down::MouseMove, 0, 1, 0, R
+Left::MouseMove, -1, 0, 0, R
+Right::MouseMove, 1, 0, 0, R

^Up::
^DoWn::
^WheelUp::
^WheelDown::ChangeZoom(InStr(A_ThisHotKey, "DoWn") ? oZoom.Zoom + 1 : oZoom.Zoom - 1)

1:: oZoom.Pause := !oZoom.Pause
#If

Magnify() {
	If !oZoom.Pause
	{
		MouseGetPos, , , WinID
		If (WinID != oZoom.hGui)
		{
			SetTimer, Memory, Off
			DllCall("GetCursorPos", "int64P", pt)
			oZoom.MouseX := pt << 32 >> 32, oZoom.MouseY := pt >> 32
			StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
				, oZoom.hdcSrc, oZoom.MouseX - oZoom.nXOriginSrcOffset, oZoom.MouseY - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
			For k, v In oZoom.oMarkers[oZoom.Mark]
				StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT 
			SetTimer, Memory, -30
		}
	}
	SetTimer, Magnify, -10
}

Memory() {
	SysGet, VirtualScreenX, 76
	SysGet, VirtualScreenY, 77
	SysGet, VirtualScreenWidth, 78
	SysGet, VirtualScreenHeight, 79 
	oZoom.nXOriginSrc := oZoom.MouseX - VirtualScreenX, oZoom.nYOriginSrc := oZoom.MouseY - VirtualScreenY
	hBM := DllCall("Gdi32.Dll\CreateCompatibleBitmap", "Ptr", oZoom.hdcSrc, "Int", VirtualScreenWidth, "Int", VirtualScreenHeight)
	DllCall("Gdi32.Dll\SelectObject", "Ptr", oZoom.hdcMemory, "Ptr", hBM), DllCall("DeleteObject", "Ptr", hBM)
	BitBlt(oZoom.hdcMemory, 0, 0, VirtualScreenWidth, VirtualScreenHeight, oZoom.hdcSrc, VirtualScreenX, VirtualScreenY)
}

Redraw() {
	StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
		, oZoom.hdcMemory, oZoom.nXOriginSrc - oZoom.nXOriginSrcOffset, oZoom.nYOriginSrc - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
	For k, v In oZoom.oMarkers[oZoom.Mark]
		StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT
}

SetSize() {
	Static Top := 64, Left := 4, Right := 4, Bottom := 4
 
	GetClientPos(oZoom.hGui, GuiWidth, GuiHeight)
	Width := GuiWidth - Left - Right
	Height := GuiHeight - Top - Bottom
	Zoom := oZoom.Zoom
	conW := Mod(Width, Zoom) ? Width - Mod(Width, Zoom) + Zoom : Width
	conW := Mod(conW // Zoom, 2) ? conW : conW + Zoom
	conH := Mod(Height, Zoom) ? Height - Mod(Height, Zoom) + Zoom : Height
	conH := Mod(conH // Zoom, 2) ? conH : conH + Zoom
	conX := ((conW - Width) // 2) * -1
	conY := ((conH - Height) // 2) * -1

	oZoom.nWidthSrc := conW // Zoom
	oZoom.nHeightSrc := conH // Zoom
	oZoom.nXOriginSrcOffset := oZoom.nWidthSrc // 2
	oZoom.nYOriginSrcOffset := oZoom.nHeightSrc // 2
	oZoom.nWidthDest := nWidthDest := conW
	oZoom.nHeightDest := nHeightDest := conH
	xCenter := conW / 2 - Zoom / 2
	yCenter := conH / 2 - Zoom / 2

	oZoom.oMarkers["Cross"] := [{x:0,y:yCenter - 1,w:nWidthDest,h:1}
		, {x:0,y:yCenter + Zoom,w:nWidthDest,h:1}
		, {x:xCenter - 1,y:0,w:1,h:nHeightDest}
		, {x:xCenter + Zoom,y:0,w:1,h:nHeightDest}]

	oZoom.oMarkers["Square"] := [{x:xCenter - 1,y:yCenter,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + Zoom + 1,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + 1,w:1,h:Zoom}
		, {x:xCenter + Zoom,y:yCenter + 1,w:1,h:Zoom}]

	oZoom.oMarkers["Grid"] := Zoom = 1 ? oZoom.oMarkers["Square"]
		: [{x:xCenter - Zoom,y:yCenter - Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom * 2,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom * 2,y:yCenter - Zoom,w:1,h:Zoom * 3}]
	
	SetWindowPos(oZoom.hDev, Left, Top, Width, Height)
	SetWindowPos(oZoom.hDevCon, conX, conY, conW, conH)
	Redraw()
}

SetWindowPos(hWnd, x, y, w, h) {
	Static SWP_ASYNCWINDOWPOS := 0x4000, SWP_DEFERERASE := 0x2000, SWP_NOACTIVATE := 0x0010, SWP_NOCOPYBITS := 0x0100
		, SWP_NOOWNERZORDER := 0x0200, SWP_NOREDRAW := 0x0008, SWP_NOSENDCHANGING := 0x0400
	DllCall("SetWindowPos"
		, "Ptr", hWnd
		, "Ptr", 0
		, "Int", x
		, "Int", y
		, "Int", w
		, "Int", h
		, "UInt", SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW|SWP_NOSENDCHANGING)
}

ZoomOnSize() {
	If A_EventInfo != 1
	{
		SetTimer, SetSize, -10
		oZoom.Minimize := 0
	}
	Else
		oZoom.Minimize := 1
}

SliderZoom() {
	GuiControlGet, SliderZoom, Zoom:
	ChangeZoom(SliderZoom)
}

ChangeZoom(Val) {
	If (Val < 1 || Val > 50)
		Return
	GuiControl, Zoom:, TextZoom, % oZoom.Zoom := Val
	If A_GuiControl =
		GuiControl, Zoom:, SliderZoom, % oZoom.Zoom
	SetSize()
}

ChangeMark() {
	oZoom.Mark := ["Cross","Square","Grid","None"][{"Cross":2,"Square":3,"Grid":4,"None":1}[oZoom.Mark]]
	GuiControl, Zoom:, ChangeMark, % oZoom.Mark
	Redraw()
}

ZoomOnClose() {
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcDest)
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcSrc)
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcMemory)
	ExitApp
}

GetClientPos(hwnd, ByRef W, ByRef H)  {
	VarSetCapacity(pwi, 60, 0), NumPut(60, pwi, 0, "UInt")
	DllCall("GetWindowInfo", "Ptr", hwnd, "UInt", &pwi)
	W := NumGet(pwi, 28, "Int") - NumGet(pwi, 20, "Int")
	H := NumGet(pwi, 32, "Int") - NumGet(pwi, 24, "Int")
}

WM_Paint() {
	SetTimer, Redraw, -10
}

BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster = 0x00CC0020) {
	Return DllCall("Gdi32.Dll\BitBlt"
		, "Ptr", dDC
		, "Int", dx
		, "Int", dy
		, "Int", dw
		, "Int", dh
		, "Ptr", sDC
		, "Int", sx
		, "Int", sy
		, "Uint", Raster)
}

StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster = 0x00CC0020) {
	Return DllCall("Gdi32.Dll\StretchBlt"
		, "Ptr", dDC
		, "Int", dx
		, "Int", dy
		, "Int", dw
		, "Int", dh
		, "Ptr", sDC
		, "Int", sx
		, "Int", sy
		, "Int", sw
		, "Int", sh
		, "Uint", Raster)
} 
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

34

Re: AHK: Экранная лупа

Ещё заметил такое дело, что пиксели иногда "замыливаются". Помогает именение размера окна до определённых значений.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

35 (изменено: serzh82saratov, 2016-04-14 17:32:06)

Re: AHK: Экранная лупа

Внёс ещё изменения.
Предыдущий баг с замыливанием появился из за растра взятого из Gdip standard library, вернул MERGECOPY.


#NoEnv
#SingleInstance Force
#KeyHistory 0
ListLines Off
SetBatchLines,-1
OnExit("ZoomOnClose")
Try Menu, Tray, Icon, Shell32, 23
OnMessage(0xF, "WM_Paint")
OnMessage(0x214, "WM_SIZING")
Global oZoom := {}

oZoom.Zoom := 1
oZoom.Mark := "Cross"		; Cross, Square, Grid, None

; WinX := 1559
; WinY := 594
WinW := 300
WinH := 360

Gui, Zoom: +AlwaysOnTop +Resize -DPIScale +hwndhGui +LabelZoomOn
Gui, Zoom: Font, s12
Gui, Zoom: Color, ffffff
Gui, Zoom: Add, Slider, vSliderZoom gSliderZoom x8 Range1-50 w176 Center AltSubmit NoTicks, % oZoom.Zoom
Gui, Zoom: Add, Text, vTextZoom Center x+10 yp+3 w36, % oZoom.Zoom
Gui, Zoom: Font
Gui, Zoom: Add, Button, gChangeMark vChangeMark x+10 yp w52, % oZoom.Mark
Gui, Dev: +HWNDhDev -Caption -DPIScale +Parent%hGui% +Border
Gui, Dev: Add, Pic, hwndhDevCon 
Gui, Dev: Show, NA
Gui, Dev: Color, ffffff

; Gui, Zoom: Show, x%WinX% y%WinY% w%WinW% h%WinH%, Magnify
Gui, Zoom: Show, w%WinW% h%WinH%, Magnify
Gui, Zoom: +MinSize

oZoom.hdcSrc := DllCall("GetDC", "Ptr", 0)
oZoom.hdcDest := DllCall("GetDC", "Ptr", hDevCon, "Ptr")
oZoom.hdcMemory := DllCall("CreateCompatibleDC", "Ptr", 0)  
DllCall("Gdi32.Dll\SetStretchBltMode", "Ptr", oZoom.hdcDest, "Int", 4)
oZoom.hGui := hGui
oZoom.hDev := hDev
oZoom.hDevCon := hDevCon
Magnify()  
Return

#If !oZoom.Minimize
+Up::MouseMove, 0, -1, 0, R
+Down::MouseMove, 0, 1, 0, R
+Left::MouseMove, -1, 0, 0, R
+Right::MouseMove, 1, 0, 0, R

^Up::
^DoWn::
^WheelUp::
^WheelDown::ChangeZoom(InStr(A_ThisHotKey, "DoWn") ? oZoom.Zoom + 1 : oZoom.Zoom - 1)

1:: oZoom.Pause := !oZoom.Pause
#If

Magnify() {
	If (!oZoom.Pause && !oZoom.Minimize && !oZoom.Sizing)
	{
		MouseGetPos, , , WinID
		If (WinID != oZoom.hGui)
		{
			SetTimer, Memory, Off
			DllCall("GetCursorPos", "int64P", pt)
			oZoom.MouseX := pt << 32 >> 32, oZoom.MouseY := pt >> 32
			StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
				, oZoom.hdcSrc, oZoom.MouseX - oZoom.nXOriginSrcOffset, oZoom.MouseY - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
			For k, v In oZoom.oMarkers[oZoom.Mark]
				StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT 
			SetTimer, Memory, -30
		}
	}
	SetTimer, Magnify, -10
}

Memory() {
	SysGet, VirtualScreenX, 76
	SysGet, VirtualScreenY, 77
	SysGet, VirtualScreenWidth, 78
	SysGet, VirtualScreenHeight, 79 
	oZoom.nXOriginSrc := oZoom.MouseX - VirtualScreenX, oZoom.nYOriginSrc := oZoom.MouseY - VirtualScreenY
	hBM := DllCall("Gdi32.Dll\CreateCompatibleBitmap", "Ptr", oZoom.hdcSrc, "Int", VirtualScreenWidth, "Int", VirtualScreenHeight)
	DllCall("Gdi32.Dll\SelectObject", "Ptr", oZoom.hdcMemory, "Ptr", hBM), DllCall("DeleteObject", "Ptr", hBM)
	BitBlt(oZoom.hdcMemory, 0, 0, VirtualScreenWidth, VirtualScreenHeight, oZoom.hdcSrc, VirtualScreenX, VirtualScreenY)
}

Redraw() {
	StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
		, oZoom.hdcMemory, oZoom.nXOriginSrc - oZoom.nXOriginSrcOffset, oZoom.nYOriginSrc - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
	For k, v In oZoom.oMarkers[oZoom.Mark]
		StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT
}

SetSize() {
	Critical
	Static Top := 64, Left := 4, Right := 4, Bottom := 4
	SetTimer, Magnify, Off
	GetClientPos(oZoom.hGui, GuiWidth, GuiHeight)
	Width := GuiWidth - Left - Right
	Height := GuiHeight - Top - Bottom
	Zoom := oZoom.Zoom
	conW := Mod(Width, Zoom) ? Width - Mod(Width, Zoom) + Zoom : Width
	conW := Mod(conW // Zoom, 2) ? conW : conW + Zoom
	conH := Mod(Height, Zoom) ? Height - Mod(Height, Zoom) + Zoom : Height
	conH := Mod(conH // Zoom, 2) ? conH : conH + Zoom
	conX := ((conW - Width) // 2) * -1
	conY := ((conH - Height) // 2) * -1

	oZoom.nWidthSrc := conW // Zoom
	oZoom.nHeightSrc := conH // Zoom
	oZoom.nXOriginSrcOffset := oZoom.nWidthSrc // 2
	oZoom.nYOriginSrcOffset := oZoom.nHeightSrc // 2
	oZoom.nWidthDest := nWidthDest := conW
	oZoom.nHeightDest := nHeightDest := conH
	xCenter := conW / 2 - Zoom / 2
	yCenter := conH / 2 - Zoom / 2
	
	oZoom.oMarkers["Cross"] := [{x:0,y:yCenter - 1,w:nWidthDest,h:1}
		, {x:0,y:yCenter + Zoom,w:nWidthDest,h:1}
		, {x:xCenter - 1,y:0,w:1,h:nHeightDest}
		, {x:xCenter + Zoom,y:0,w:1,h:nHeightDest}]

	oZoom.oMarkers["Square"] := [{x:xCenter - 1,y:yCenter,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + Zoom + 1,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + 1,w:1,h:Zoom}
		, {x:xCenter + Zoom,y:yCenter + 1,w:1,h:Zoom}]

	oZoom.oMarkers["Grid"] := Zoom = 1 ? oZoom.oMarkers["Square"]
		: [{x:xCenter - Zoom,y:yCenter - Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom * 2,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom * 2,y:yCenter - Zoom,w:1,h:Zoom * 3}]
	
	SetWindowPos(oZoom.hDevCon, conX, conY, conW, conH)
	SetWindowPos(oZoom.hDev, Left, Top, Width, Height)
	Redraw()
	SetTimer, Magnify, -10
}

SetWindowPos(hWnd, x, y, w, h) {
	Static SWP_ASYNCWINDOWPOS := 0x4000, SWP_DEFERERASE := 0x2000, SWP_NOACTIVATE := 0x0010, SWP_NOCOPYBITS := 0x0100
		, SWP_NOOWNERZORDER := 0x0200, SWP_NOREDRAW := 0x0008, SWP_NOSENDCHANGING := 0x0400
	DllCall("SetWindowPos"
		, "Ptr", hWnd
		, "Ptr", 0
		, "Int", x
		, "Int", y
		, "Int", w
		, "Int", h
		, "UInt", SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW|SWP_NOSENDCHANGING)
	SetTimer, RedrawWindow, -100
}

RedrawWindow() {
	DllCall("RedrawWindow", "Ptr", oZoom.hGui, "Uint", 0, "Uint", 0, "Uint", 0x1|0x4) 
}
	
ZoomOnSize() {
	If A_EventInfo != 1
	{
		oZoom.Minimize := 0
		SetTimer, SetSize, -10
	}
	Else
		oZoom.Minimize := 1
}

SliderZoom() {
	GuiControlGet, SliderZoom, Zoom:
	ChangeZoom(SliderZoom)
}

ChangeZoom(Val) {
	If (Val < 1 || Val > 50)
		Return
	SetTimer, Magnify, Off
	GuiControl, Zoom:, TextZoom, % oZoom.Zoom := Val
	If A_GuiControl =
		GuiControl, Zoom:, SliderZoom, % oZoom.Zoom
	SetTimer, SetSize, -10
}

ChangeMark() {
	oZoom.Mark := ["Cross","Square","Grid","None"][{"Cross":2,"Square":3,"Grid":4,"None":1}[oZoom.Mark]]
	GuiControl, Zoom:, ChangeMark, % oZoom.Mark
	Redraw()
}

ZoomOnClose() {
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcDest)
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcSrc)
	DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcMemory)
	ExitApp
}

GetClientPos(hwnd, ByRef W, ByRef H)  {
	VarSetCapacity(pwi, 60, 0), NumPut(60, pwi, 0, "UInt")
	DllCall("GetWindowInfo", "Ptr", hwnd, "UInt", &pwi)
	W := NumGet(pwi, 28, "Int") - NumGet(pwi, 20, "Int")
	H := NumGet(pwi, 32, "Int") - NumGet(pwi, 24, "Int")
}

WM_Paint() {
	SetTimer, Redraw, -10
}

WM_SIZING(wp) { 
	oZoom.Sizing := 1
	SetTimer, NoSizing, -100
}

NoSizing() { 
	oZoom.Sizing := 0
}

BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster = 0xC000CA) {
	Return DllCall("Gdi32.Dll\BitBlt"
		, "Ptr", dDC
		, "Int", dx
		, "Int", dy
		, "Int", dw
		, "Int", dh
		, "Ptr", sDC
		, "Int", sx
		, "Int", sy
		, "Uint", Raster)
}

StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster = 0xC000CA) {
	Return DllCall("Gdi32.Dll\StretchBlt"
		, "Ptr", dDC
		, "Int", dx
		, "Int", dy
		, "Int", dw
		, "Int", dh
		, "Ptr", sDC
		, "Int", sx
		, "Int", sy
		, "Int", sw
		, "Int", sh
		, "Uint", Raster)
}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

36

Re: AHK: Экранная лупа

Так не дергается.
А двигать изображение в режиме паузы можно будет?

37

Re: AHK: Экранная лупа

serzh82saratov пишет:

Потестируйте, у кого как, после надо будет прикрутить руку, индикаторы какие нибудь, и настройки.

Рука - это про двигать.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

38 (изменено: serzh82saratov, 2016-04-16 01:49:44)

Re: AHK: Экранная лупа

С рукой.


#NoEnv
#SingleInstance Force
#KeyHistory 0
ListLines Off
SetBatchLines,-1
OnExit("ZoomOnClose")
Try Menu, Tray, Icon, Shell32, 23
OnMessage(0xF, "WM_Paint")
OnMessage(0x214, "WM_SIZING")
OnMessage(0x0020, "WM_SETCURSOR")
Global oZoom := {}

oZoom.Zoom := 2
oZoom.Mark := "Cross"		; Cross, Square, Grid, None

; WinX := 1559
; WinY := 594
WinW := 300
WinH := 360

Gui, Zoom: +AlwaysOnTop +Resize -DPIScale +hwndhGui +LabelZoomOn +E0x20
Gui, Zoom: Font, s12
Gui, Zoom: Color, ffffff
Gui, Zoom: Add, Slider, vSliderZoom gSliderZoom x8 Range1-50 w176 Center AltSubmit NoTicks, % oZoom.Zoom
Gui, Zoom: Add, Text, vTextZoom Center x+10 yp+3 w36, % oZoom.Zoom
Gui, Zoom: Font
Gui, Zoom: Add, Button, gChangeMark vChangeMark x+10 yp w52, % oZoom.Mark
Gui, Dev: +HWNDhDev -Caption -DPIScale +Parent%hGui% +Border
Gui, Dev: Add, Pic, hwndhDevCon
Gui, Dev: Show, NA
Gui, Dev: Color, ffffff

; Gui, Zoom: Show, x%WinX% y%WinY% w%WinW% h%WinH%, Magnify
Gui, Zoom: Show, w%WinW% h%WinH%, Magnify
Gui, Zoom: +MinSize

oZoom.hdcSrc := DllCall("GetDC", "Ptr", 0)
oZoom.hdcDest := DllCall("GetDC", "Ptr", hDevCon, "Ptr")
oZoom.hdcMemory := DllCall("CreateCompatibleDC", "Ptr", 0)
DllCall("Gdi32.Dll\SetStretchBltMode", "Ptr", oZoom.hdcDest, "Int", 4)
oZoom.hGui := hGui
oZoom.hDev := hDev
oZoom.hDevCon := hDevCon
Magnify()
Return

#If !oZoom.Minimize

+Up::MouseStep(0, -1)
+Down::MouseStep(0, 1)
+Left::MouseStep(-1, 0)
+Right::MouseStep(1, 0)

^Up::
^DoWn::
^WheelUp::
^WheelDown::ChangeZoom(InStr(A_ThisHotKey, "DoWn") ? oZoom.Zoom + 1 : oZoom.Zoom - 1)

1:: oZoom.Pause := !oZoom.Pause

#If

Magnify() {
	If (!oZoom.Pause && !oZoom.Minimize && !oZoom.Sizing)
	{
		MouseGetPos, , , WinID
		If (WinID != oZoom.hGui)
		{
			SetTimer, Memory, Off
			DllCall("GetCursorPos", "int64P", pt)
			oZoom.MouseX := pt << 32 >> 32, oZoom.MouseY := pt >> 32
			StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
				, oZoom.hdcSrc, oZoom.MouseX - oZoom.nXOriginSrcOffset, oZoom.MouseY - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
			For k, v In oZoom.oMarkers[oZoom.Mark]
				StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT
			SetTimer, Memory, -30
		}
	}
	SetTimer, Magnify, -10
}

Memory() {
	SysGet, VirtualScreenX, 76
	SysGet, VirtualScreenY, 77
	SysGet, VirtualScreenWidth, 78
	SysGet, VirtualScreenHeight, 79
	oZoom.nXOriginSrc := oZoom.MouseX - VirtualScreenX, oZoom.nYOriginSrc := oZoom.MouseY - VirtualScreenY
	hBM := DllCall("Gdi32.Dll\CreateCompatibleBitmap", "Ptr", oZoom.hdcSrc, "Int", VirtualScreenWidth, "Int", VirtualScreenHeight)
	DllCall("Gdi32.Dll\SelectObject", "Ptr", oZoom.hdcMemory, "Ptr", hBM), DllCall("DeleteObject", "Ptr", hBM)
	BitBlt(oZoom.hdcMemory, 0, 0, VirtualScreenWidth, VirtualScreenHeight, oZoom.hdcSrc, VirtualScreenX, VirtualScreenY)
	oZoom.VirtualScreenWidth := VirtualScreenWidth, oZoom.VirtualScreenHeight := VirtualScreenHeight
}

Redraw() {
	StretchBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest
		, oZoom.hdcMemory, oZoom.nXOriginSrc - oZoom.nXOriginSrcOffset, oZoom.nYOriginSrc - oZoom.nYOriginSrcOffset, oZoom.nWidthSrc, oZoom.nHeightSrc)
	For k, v In oZoom.oMarkers[oZoom.Mark]
		StretchBlt(oZoom.hdcDest, v.x, v.y, v.w, v.h, oZoom.hdcDest, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT
}

SetSize() {
	Critical
	Static Top := 64, Left := 4, Right := 4, Bottom := 4
	SetTimer, Magnify, Off
	GetClientPos(oZoom.hGui, GuiWidth, GuiHeight)
	Width := GuiWidth - Left - Right
	Height := GuiHeight - Top - Bottom
	Zoom := oZoom.Zoom
	conW := Mod(Width, Zoom) ? Width - Mod(Width, Zoom) + Zoom : Width
	conW := Mod(conW // Zoom, 2) ? conW : conW + Zoom
	conH := Mod(Height, Zoom) ? Height - Mod(Height, Zoom) + Zoom : Height
	conH := Mod(conH // Zoom, 2) ? conH : conH + Zoom
	conX := ((conW - Width) // 2) * -1
	conY := ((conH - Height) // 2) * -1

	oZoom.nWidthSrc := conW // Zoom
	oZoom.nHeightSrc := conH // Zoom
	oZoom.nXOriginSrcOffset := oZoom.nWidthSrc // 2
	oZoom.nYOriginSrcOffset := oZoom.nHeightSrc // 2
	oZoom.nWidthDest := nWidthDest := conW
	oZoom.nHeightDest := nHeightDest := conH
	xCenter := conW / 2 - Zoom / 2
	yCenter := conH / 2 - Zoom / 2

	oZoom.oMarkers["Cross"] := [{x:0,y:yCenter - 1,w:nWidthDest,h:1}
		, {x:0,y:yCenter + Zoom,w:nWidthDest,h:1}
		, {x:xCenter - 1,y:0,w:1,h:nHeightDest}
		, {x:xCenter + Zoom,y:0,w:1,h:nHeightDest}]

	oZoom.oMarkers["Square"] := [{x:xCenter - 1,y:yCenter,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + Zoom + 1,w:Zoom + 2,h:1}
		, {x:xCenter - 1,y:yCenter + 1,w:1,h:Zoom}
		, {x:xCenter + Zoom,y:yCenter + 1,w:1,h:Zoom}]

	oZoom.oMarkers["Grid"] := Zoom = 1 ? oZoom.oMarkers["Square"]
		: [{x:xCenter - Zoom,y:yCenter - Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter + Zoom * 2,w:Zoom * 3,h:1}
		, {x:xCenter - Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom,y:yCenter - Zoom,w:1,h:Zoom * 3}
		, {x:xCenter + Zoom * 2,y:yCenter - Zoom,w:1,h:Zoom * 3}]

	SetWindowPos(oZoom.hDevCon, conX, conY, conW, conH)
	SetWindowPos(oZoom.hDev, Left, Top, Width, Height)
	Redraw()
	SetTimer, Magnify, -10
}

SetWindowPos(hWnd, x, y, w, h) {
	Static SWP_ASYNCWINDOWPOS := 0x4000, SWP_DEFERERASE := 0x2000, SWP_NOACTIVATE := 0x0010, SWP_NOCOPYBITS := 0x0100
		, SWP_NOOWNERZORDER := 0x0200, SWP_NOREDRAW := 0x0008, SWP_NOSENDCHANGING := 0x0400
		, uFlags := SWP_ASYNCWINDOWPOS|SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW|SWP_NOSENDCHANGING
	DllCall("SetWindowPos"
		, "Ptr", hWnd
		, "Ptr", 0
		, "Int", x
		, "Int", y
		, "Int", w
		, "Int", h
		, "UInt", uFlags)
	SetTimer, RedrawWindow, -100
}

RedrawWindow() {
	DllCall("RedrawWindow", "Ptr", oZoom.hGui, "Uint", 0, "Uint", 0, "Uint", 0x1|0x4)
}

ZoomOnSize() {
	If A_EventInfo != 1
	{
		oZoom.Minimize := 0
		SetTimer, SetSize, -10
	}
	Else
		oZoom.Minimize := 1
}

SliderZoom() {
	GuiControlGet, SliderZoom, Zoom:
	ChangeZoom(SliderZoom)
}

ChangeZoom(Val) {
	If (Val < 1 || Val > 50)
		Return
	SetTimer, Magnify, Off
	GuiControl, Zoom:, TextZoom, % oZoom.Zoom := Val
	If A_GuiControl =
		GuiControl, Zoom:, SliderZoom, % oZoom.Zoom
	SetTimer, SetSize, -10
}

ChangeMark() {
	oZoom.Mark := ["Cross","Square","Grid","None"][{"Cross":2,"Square":3,"Grid":4,"None":1}[oZoom.Mark]]
	GuiControl, Zoom:, ChangeMark, % oZoom.Mark
	Redraw()
}

ZoomOnClose() {
	ZoomOnEscape:
		DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcDest)
		DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcSrc)
		DllCall("Gdi32.Dll\DeleteDC", "Ptr", oZoom.hdcMemory)
		ExitApp
}

GetClientPos(hwnd, ByRef W, ByRef H)  {
	VarSetCapacity(pwi, 60, 0), NumPut(60, pwi, 0, "UInt")
	DllCall("GetWindowInfo", "Ptr", hwnd, "UInt", &pwi)
	W := NumGet(pwi, 28, "Int") - NumGet(pwi, 20, "Int")
	H := NumGet(pwi, 32, "Int") - NumGet(pwi, 24, "Int")
}

WM_Paint() {
	SetTimer, Redraw, -10
}

WM_SIZING() {
	SetTimer, Magnify, Off
	oZoom.Sizing := 1
	SetTimer, NoSizing, 10
}

NoSizing() {
	If GetKeyState("LButton", "P")
		Return
	oZoom.Sizing := 0
	SetTimer, NoSizing, Off
	SetTimer, Magnify, -10
}

BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster = 0xC000CA) {
	Return DllCall("Gdi32.Dll\BitBlt"
		, "Ptr", dDC
		, "Int", dx
		, "Int", dy
		, "Int", dw
		, "Int", dh
		, "Ptr", sDC
		, "Int", sx
		, "Int", sy
		, "Uint", Raster)
}

StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster = 0xC000CA) {
	Return DllCall("Gdi32.Dll\StretchBlt"
		, "Ptr", dDC
		, "Int", dx
		, "Int", dy
		, "Int", dw
		, "Int", dh
		, "Ptr", sDC
		, "Int", sx
		, "Int", sy
		, "Int", sw
		, "Int", sh
		, "Uint", Raster)
}

	; _________________________________________________ MoveHand _________________________________________________

WM_SETCURSOR(W, L, M, H) {
	If (oZoom.SIZING)
		Return
	If (oZoom.Pause && W = oZoom.hDev && GetKeyState("LButton", "P"))
	{
		SetTimer, Hand, -1
		Return oZoom.SIZING := 1
	}
}

Hand() {
	SetTimer, Magnify, Off
	DllCall("GetCursorPos", "int64P", pt)
	oZoom.MoveHandX := pt << 32 >> 32, oZoom.MoveHandY := pt >> 32
	oZoom.MoveXSrc := oZoom.nXOriginSrc, oZoom.MoveYSrc := oZoom.nYOriginSrc
	SetSystemCursor("HAND")
	SetTimer, MoveHand, 10
	KeyWait, LButton
	SetTimer, MoveHand, Off
	RestoreCursors()
	oZoom.SIZING := 0
	SetTimer, Magnify, -10
}

MoveHand() {
	Static PrnXOriginSrc, PrnYOriginSrc
	PrnXOriginSrc := oZoom.nXOriginSrc
	PrnYOriginSrc := oZoom.nYOriginSrc
	DllCall("GetCursorPos", "int64P", pt)
	MouseX := pt << 32 >> 32, MouseY := pt >> 32
	XOdds := oZoom.MoveHandX - MouseX
	XOff := XOdds > 0 ? Floor(XOdds / oZoom.Zoom) : Ceil(XOdds / oZoom.Zoom)
	oZoom.nXOriginSrc := oZoom.MoveXSrc + XOff
	YOdds := oZoom.MoveHandY - MouseY
	YOff := YOdds > 0 ? Floor(YOdds / oZoom.Zoom) : Ceil(YOdds / oZoom.Zoom)
	oZoom.nYOriginSrc := oZoom.MoveYSrc + YOff
	If (PrnXOriginSrc <> oZoom.nXOriginSrc || PrnYOriginSrc <> oZoom.nYOriginSrc)
		LimitsOriginSrc(), Redraw()
}

MoveStep(StepX, StepY) {
	oZoom.nXOriginSrc += StepX
	oZoom.nYOriginSrc += StepY
	LimitsOriginSrc(), Redraw()
}

LimitsOriginSrc() {
	X := oZoom.nXOriginSrc
	oZoom.nXOriginSrc := X < 0 ? 0 : X > oZoom.VirtualScreenWidth - 1 ? oZoom.VirtualScreenWidth - 1 : X
	Y := oZoom.nYOriginSrc
	oZoom.nYOriginSrc := Y < 0 ? 0 : Y > oZoom.VirtualScreenHeight - 1 ? oZoom.VirtualScreenHeight - 1 : Y
}

MouseStep(x, y) {
	If !oZoom.Pause
		MouseMove, x, y, 0, R
	Else
		MoveStep(x, y)
}

SetSystemCursor(CursorName, cx = 0, cy = 0) {
	Static SystemCursors := {ARROW:32512, IBEAM:32513, WAIT:32514, CROSS:32515, UPARROW:32516, SIZE:32640, ICON:32641, SIZENWSE:32642
					, SIZENESW:32643, SIZEWE:32644 ,SIZENS:32645, SIZEALL:32646, NO:32648, HAND:32649, APPSTARTING:32650, HELP:32651}
    Local CursorHandle, hImage, Name, ID
	If (CursorHandle := DllCall("LoadCursor", Uint, 0, Int, SystemCursors[CursorName]))
		For Name, ID in SystemCursors
			hImage := DllCall("CopyImage", Ptr, CursorHandle, Uint, 0x2, Int, cx, Int, cy, Uint, 0)
			, DllCall("SetSystemCursor", Ptr, hImage, Int, ID)
}

RestoreCursors() {
	Static SPI_SETCURSORS := 0x57
	DllCall("SystemParametersInfo", UInt, SPI_SETCURSORS, UInt, 0, UInt, 0, UInt, 0)
}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

39

Re: AHK: Экранная лупа

Кстати это:

В качестве дополнения добавлена экранная лупа. Смотрите в описании.

кто нибудь запускал?

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

40

Re: AHK: Экранная лупа

Запустил, вроде работает. Лучше было бы, чтоб дополнения можно было скачать из интерфейса программы, я не нашёл, как.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

41

Re: AHK: Экранная лупа

В Help - About есть ссылка на описание, в шапке написано про дополнение, ниже в спойлере ссылки для скачивания. Ну а если описание не читать, то можно и не узнать, что есть например меню.
В интерфейс даже не знаю куда это определить...

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

42

Re: AHK: Экранная лупа

serzh82saratov пишет:

Ну а если описание не читать, то можно и не узнать, что есть например меню.

Да, это точно, я его долго искал. Можно обычное оконное меню сделать, и там где-нибудь пункт «загрузить дополнения».

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

43

Re: AHK: Экранная лупа

Есть такое понятие как фон контекста (dc background)? То есть фон всегда чёрный, хочется установить другой цвет, например контекст размером 100х100, рисуем в нём StretchBlt в  0, 0, 100, 50 и нижняя половина остаётся заданного цвета.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

44

Re: AHK: Экранная лупа

Я уже не помню, гуглить надо.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

45

Re: AHK: Экранная лупа

Я тоже не нашёл.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

46

Re: AHK: Экранная лупа

Теперь-то я уже нашёл, если нужно могу написать пример. Что рисовать-то?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

47

Re: AHK: Экранная лупа

Зелёно-красную шахматную доску (5рх квадрат) можешь?

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

48

Re: AHK: Экранная лупа

А фон где должен быть? Вокруг неё? Или фон это один из цветов?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

49

Re: AHK: Экранная лупа

Фон это один из цветов.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

50

Re: AHK: Экранная лупа

Попробую, но не уверен, что сегодня успею.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg