1 (изменено: serzh82saratov, 2016-04-27 02:38:48)

Тема: AHK: Экранная лупа

Перекопав примеры, так и не нашёл код с нормальным указателем пикселя (рамка пикселя который под курсором), поддержкой нескольких мониторов и толковым масштабированием при изменении размера окна лупы.
Наваял код, в нём остались проблемы:

  • [РЕШЕНО] При зуме равном 1, края экрана "зеркалируются". Возможно в параметре dwRop функции  StretchBlt надо скомбинировать флаги (я таковую комбинацию не нашёл), или вообще StretchBlt заменить на другой метод.

  • [РЕШЕНО] Если поставить на паузу (F12), то при сворачивании \ разворачивании прежняя картинка пропадает, также затирается та часть окна, которую при передвижении окна перенесли за край экрана.

  • Небольшие мелькания при изменении увеличения или растягивании окна (терпимо).

+ Старый код.

#NoEnv
#SingleInstance Force
#KeyHistory 0
ListLines Off
SetBatchLines,-1
OnExit, ZoomOnClose

Global oZoom := {}

oZoom.Zoom := 12
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%
Gui, Dev: Add, Text, hwndhDevCon
Gui, Dev: Show, NA
Gui, Dev: Color, ffffff

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

oZoom.hdcSrc := DllCall("GetDC", Ptr, "")
oZoom.hdcDest := DllCall("GetDC", Ptr, hDevCon, Ptr)
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)

F12::Pause
#If

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


SetSize() {
	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 := 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
	Magnify()
	GuiControl, Dev: +Redraw, % oZoom.hDevCon
}

StretchBlt(hdcDest, hdcSrc, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, dwRop = 0xC000CA) {	; MERGECOPY
	DllCall("gdi32.dll\StretchBlt", Ptr, hdcDest
								, Int, nXOriginDest
								, Int, nYOriginDest
								, Int, nWidthDest
								, Int, nHeightDest
								, Ptr, hdcSrc
								, Int, nXOriginSrc
								, Int, nYOriginSrc
								, Int, nWidthSrc
								, Int, nHeightSrc
								, UInt, dwRop)
}

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
}

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")
}

Текущая версия здесь.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

2

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

Первый вопрос решился с помощью SetStretchBltMode. Но есть такая фишка, что недействительная область экрана может быть не только чёрной, а белой например.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

3 (изменено: Alectric, 2016-03-28 17:48:22)

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

Может у окна "Redraw" отключать во время паузы?...

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

4

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

Не совсем понял, это как?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5

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

Не знаю, я просто предположил...

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

6

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

Вообщем по второму вопросу так и не нашёл решения, почему картинка "сделанная" с помощью StretchBlt как бы не "закрепляется", не понятно. Думаю требуются более глубокие познания gdi.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

7

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

Возможно стоит смотреть в сторону UpdateLayeredWindow, но сразу не понятно как сделать Layered Window дочерним, аналогично как в коде выше.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

8

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

Layered Windows дочерними не бывают. Я бы посмотрел, но пока некогда, завал по работе.

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

9

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

Спасибо. Пока смотрю в сторону отловить WM_PAINT, и нарисовать прежнюю картинку, но конечно интереснее знать как нарисовать стабильное изображение.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

10

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

serzh82saratov пишет:

Пока смотрю в сторону отловить WM_PAINT

А, я просто не совсем понял, вот пример, может, поможет. Вроде, если поставить на паузу, не затирается.

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

11

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

Что то получается, но как в моём случае сохранить саму картинку чтобы её указать в BitBlt как hdcSrc?



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

oZoom.Zoom := 2
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%
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: +MinSize

oZoom.hdcSrc := DllCall("GetDC", Ptr, "")
oZoom.hdcDest := DllCall("GetDC", Ptr, hDevCon, Ptr)
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, CtrlID, 2
	CoordMode, Mouse, %S_CoordModeMouse%
	If (!oZoom.Pause && oZoom.hDev != CtrlID && 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 
	}
	SetTimer, Magnify, -50
} 

SetSize() {
	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 := 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
	Magnify()
	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
}

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() { 
	ToolTip % BitBlt(oZoom.hdcDest, 0, 0, oZoom.nWidthDest, oZoom.nHeightDest, oZoom.hdcDest, 0, 0) 
}

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

StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster="") {
	Ptr := A_PtrSize ? "UPtr" : "UInt" 
	return DllCall("gdi32\StretchBlt"
					, Ptr, ddc
					, "int", dx
					, "int", dy
					, "int", dw
					, "int", dh
					, Ptr, sdc
					, "int", sx
					, "int", sy
					, "int", sw
					, "int", sh
					, "uint", Raster ? Raster : 0x00CC0020)
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

12

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

Особо не вдумывался, но наверное можно создать отдельный контекст (DC) для запоминания картинки.

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

13

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

Тоже сразу об этом подумал, но всё это похоже на костыли, наверное.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

14

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

OFF: AHK - это один большой костыль...

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

15

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

Alectric
Ну не знаю, думаю в данном случае просто недостаточно знаний в gdi.

teadrinker
А каковы вообще причины того что что картинка не закрепяется? Это и есть отличие от LayeredWindow?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

16

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

serzh82saratov пишет:

Тоже сразу об этом подумал, но всё это похоже на костыли

Нет, ничуть. Так всегда поступают при создании изменяющейся графики. Делают Memory Device Context специально для запоминания, и чтобы не нужно было всё время что-то стирать в видимом окне.

serzh82saratov пишет:

А каковы вообще причины того что что картинка не закрепяется? Это и есть отличие от LayeredWindow?

Она в обычном окне и не должна в таком случае. Да, LayeredWindow для этого удобнее, но там есть свои сложности.

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

17

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

teadrinker пишет:

Делают Memory Device Context

А как лучше его сделать? Скрытый контрол?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

18

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

Нет, просто контекст экрана.

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

19

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

Ещё один?

DllCall("GetDC", Ptr, "")
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

20

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

Ну да.

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

21

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

Так мы когда в него пишем, это же на экране отображается...

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

22

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

То есть пишем чтобы сохранить. Нужно получать картинку которая была перед паузой скрипта.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

23

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

Нужно от него ещё получить CompatibleDC. Сейчас не могу подробнее, не дома.

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

24

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

Алгоритм такой — то, что нужно показать в окне, посылаем и в наш дополнительный контекст. Когда отлавливается WM_PAINT — отправляем из контекста в окно.

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

25

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

Кажется разобрался

DllCall("CreateCompatibleDC", "Ptr", 0) 

ещё потребовались CreateCompatibleBitmap и SelectObject перед записью.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

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 Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

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 Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

30

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

serzh82saratov пишет:

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

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 Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

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 Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

34

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

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 Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

36

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

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

37

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

serzh82saratov пишет:

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

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 Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

39

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

Кстати это:

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

40

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

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

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

41

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

42

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

serzh82saratov пишет:

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

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

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

43

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

44

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

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

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

45

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

46

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

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

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

47

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

48

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

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

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

49

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

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

50

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

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

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

51 (изменено: teadrinker, 2018-01-09 19:05:33)

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

Оказалось, можно только прямоугольник закрашивать. В принципе, это практически то же самое, что установить фон, так как под CompatibleDC всё равно нужна CompatibleBitmap определённого размера.

Gui, -DPIScale
Gui, Color, White
Gui, Margin, 40, 20
Gui, Add, Pic, w40 h40 hwndhPic1
Gui, Add, Pic, x+7 yp wp hp hwndhPic2

options := { hStatic:     hPic1
           , cellsNumber: 8
           , rowsNumber:  8
           , darkColor:   0xFF0D00    ; будет фоном
           , lightColor:  0xC618 }
           
board1 := new ChessBoard(options)

options.hStatic := hPic2
options.darkColor := 0x028E9B
options.lightColor := 0xFF7800

board2 := new ChessBoard(options)

Gui, Show
Return

GuiClose:
   ExitApp

class ChessBoard
{
   __New(options)  {
      this.options := options
      hPic := options.hStatic
      this.hParent := DllCall("GetAncestor", Ptr, hPic, UInt, GA_ROOT := 2, Ptr)
      
      WinGetPos,,, W, H, ahk_id %hPic%
      this.BoardWidth := W, this.BoardHeight := H
      this.CellWidth := W/options.cellsNumber
      this.CellHeight := H/options.rowsNumber
      
      this.hDC := DllCall("GetDC", Ptr, hPic, Ptr)
      this.oMDC := new this.CompatibleDC(this.hDC, W, H)
      this.hMDC := this.oMDC.hCDC
      
      OnMessage( 0xF, this.redraw := ObjBindMethod(this, "WM_PAINT") )
      this.DrawBoard()
   }
   
   __Delete()  {
      this.oMDC := ""
      DllCall("DeleteDC", Ptr, this.hDC)
      OnMessage(0xF, this.redraw, 0)
   }
   
   DrawBoard()  {
      brush := new this.Brush(this.hMDC, this.options.darkColor)
      this.FillRect(this.hMDC, brush.hBrush, 0, 0, this.BoardWidth, this.BoardHeight)
      
      brush := new this.Brush(this.hMDC, this.options.lightColor)
      Loop % this.options.rowsNumber  {
         row := A_Index
         Loop % this.options.cellsNumber  {
            cell := A_Index
            if mod(row + cell, 2)
               continue
            X := this.CellWidth*(cell - 1)
            Y := this.CellHeight*(row - 1)
            this.FillRect(this.hMDC, brush.hBrush, X, Y, X + this.CellWidth, Y + this.CellHeight)
         }
      }
      this.BitBlt(this.hDC, this.hMDC)
   }
   
   FillRect(hDC, hBrush, left, top, right, bottom)  {
      VarSetCapacity(RECT, 16, 0)
      NumPut(left,   RECT, 0)
      NumPut(top,    RECT, 4)
      NumPut(right,  RECT, 8)
      NumPut(bottom, RECT, 12, "UInt")
      DllCall("FillRect", Ptr, hDC, Ptr, &RECT, Ptr, hBrush)
   }
   
   BitBlt(ddc, sdc)  {
      DllCall("BitBlt", Ptr, ddc, Int, 0, Int, 0, Int, this.BoardWidth, Int, this.BoardHeight
                      , Ptr, sdc, Int, 0, Int, 0, UInt, SRCCOPY := 0xCC0020)
   }
   
   WM_PAINT(wp, lp, msg, hwnd)  {
      if (this.hParent = hwnd)   {
         timer := ObjBindMethod(this, "BitBlt", this.hDC, this.hMDC)
         SetTimer, % timer, -10
      }
   }
   
   class Brush
   {
      __New(hDC, color)  {
         this.hBrush := DllCall("CreateSolidBrush", UInt, DllCall("Ws2_32\ntohl", UInt, color << 8, UInt), Ptr)
         this.oBR := DllCall("SelectObject", Ptr, hDC, Ptr, this.hBrush, Ptr)
      }
      
      __Delete()  {
         DllCall("SelectObject", Ptr, hDC, Ptr, this.oBR, Ptr)
         DllCall("DeleteObject", Ptr, this.hBrush)
      }
   }
   
   class CompatibleDC
   {
      __New(hDC, w, h)  {
         this.hCDC := DllCall("CreateCompatibleDC", Ptr, hDC, Ptr)
         this.hCBM := DllCall("CreateCompatibleBitmap", Ptr, hDC, Int, w, Int, h, Ptr)
         this.oBM := DllCall("SelectObject", Ptr, this.hCDC, Ptr, this.hCBM, Ptr)
      }
      
      __Delete()  {
         DllCall("SelectObject", Ptr, this.hCDC, Ptr, this.oBM, Ptr)
         DllCall("DeleteDC", Ptr, this.hCDC)
         DllCall("DeleteObject", Ptr, this.hCBM)
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

52

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

То есть получается просто рисование, заполнение SolidBrush всех указанных явно прямоугольников. Я так вроде делал, но на больших количествах прямоугольников начинает мелькать при движении окна. Например w1400 h400 80х80 уже мелькает с аеро, при перемещении даже окно тормозит, и кажется не так то быстро оно рисуется.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

53

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

80х80 — это что?

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

54

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

Вот так?

SetBatchLines, -1
Gui, -DPIScale
Gui, Color, White
Gui, Margin, 20, 20
Gui, Add, Pic, w640 h640 hwndhPic1
Gui, Add, Pic, x+7 yp wp hp hwndhPic2

options := { hStatic:     hPic1
           , cellsNumber: 8
           , rowsNumber:  8
           , darkColor:   0xFF0D00    ; будет фоном
           , lightColor:  0xC618 }
           
board1 := new ChessBoard(options)

options.hStatic := hPic2
options.darkColor := 0x028E9B
options.lightColor := 0xFF7800

board2 := new ChessBoard(options)

Gui, Show
Return

GuiClose:
   ExitApp

class ChessBoard
{
   __New(options)  {
      this.options := options
      hPic := options.hStatic
      this.hParent := DllCall("GetAncestor", Ptr, hPic, UInt, GA_ROOT := 2, Ptr)
      
      WinGetPos,,, W, H, ahk_id %hPic%
      this.BoardWidth := W, this.BoardHeight := H
      this.CellWidth := W/options.cellsNumber
      this.CellHeight := H/options.rowsNumber
      
      this.hDC := DllCall("GetDC", Ptr, hPic, Ptr)
      this.oMDC := new this.CompatibleDC(this.hDC, W, H)
      this.hMDC := this.oMDC.hCDC
      
      OnMessage( 0xF, this.redraw := ObjBindMethod(this, "WM_PAINT") )
      this.DrawBoard()
   }
   
   __Delete()  {
      this.oMDC := ""
      DllCall("DeleteDC", Ptr, this.hDC)
      OnMessage(0xF, this.redraw, 0)
   }
   
   DrawBoard()  {
      brush := new this.Brush(this.hMDC, this.options.darkColor)
      this.FillRect(this.hMDC, brush.hBrush, 0, 0, this.BoardWidth, this.BoardHeight)
      
      brush := new this.Brush(this.hMDC, this.options.lightColor)
      Loop % this.options.rowsNumber  {
         row := A_Index
         Loop % this.options.cellsNumber  {
            cell := A_Index
            if mod(row + cell, 2)
               continue
            X := this.CellWidth*(cell - 1)
            Y := this.CellHeight*(row - 1)
            this.FillRect(this.hMDC, brush.hBrush, X, Y, X + this.CellWidth, Y + this.CellHeight)
         }
      }
      this.BitBlt(this.hDC, this.hMDC)
   }
   
   FillRect(hDC, hBrush, left, top, right, bottom)  {
      VarSetCapacity(RECT, 16, 0)
      NumPut(left,   RECT, 0)
      NumPut(top,    RECT, 4)
      NumPut(right,  RECT, 8)
      NumPut(bottom, RECT, 12, "UInt")
      DllCall("FillRect", Ptr, hDC, Ptr, &RECT, Ptr, hBrush)
   }
   
   BitBlt(ddc, sdc)  {
      DllCall("BitBlt", Ptr, ddc, Int, 0, Int, 0, Int, this.BoardWidth, Int, this.BoardHeight
                      , Ptr, sdc, Int, 0, Int, 0, UInt, SRCCOPY := 0xCC0020)
   }
   
   WM_PAINT(wp, lp, msg, hwnd)  {
      if (this.hParent = hwnd)   {
         timer := ObjBindMethod(this, "BitBlt", this.hDC, this.hMDC)
         SetTimer, % timer, -10
      }
   }
   
   class Brush
   {
      __New(hDC, color)  {
         this.hBrush := DllCall("CreateSolidBrush", UInt, DllCall("Ws2_32\ntohl", UInt, color << 8, UInt), Ptr)
         this.oBR := DllCall("SelectObject", Ptr, hDC, Ptr, this.hBrush, Ptr)
      }
      
      __Delete()  {
         DllCall("SelectObject", Ptr, hDC, Ptr, this.oBR, Ptr)
         DllCall("DeleteObject", Ptr, this.hBrush)
      }
   }
   
   class CompatibleDC
   {
      __New(hDC, w, h)  {
         this.hCDC := DllCall("CreateCompatibleDC", Ptr, hDC, Ptr)
         this.hCBM := DllCall("CreateCompatibleBitmap", Ptr, hDC, Int, w, Int, h, Ptr)
         this.oBM := DllCall("SelectObject", Ptr, this.hCDC, Ptr, this.hCBM, Ptr)
      }
      
      __Delete()  {
         DllCall("SelectObject", Ptr, this.hCDC, Ptr, this.oBM, Ptr)
         DllCall("DeleteDC", Ptr, this.hCDC)
         DllCall("DeleteObject", Ptr, this.hCBM)
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

55

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

С SetBatchLines конечно по лучше, но например с cellsNumber: 320, rowsNumber:  320 уже заметна задержка при старте, и мелькает, слева больше.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

56

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

У меня задержка тоже есть, а мелькание слева — это отчасти зрительный эффект, по-моему. Задержек при перемещении окна у меня нет.

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

57

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

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

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

58

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

Да уж, цикл без FillRect тоже заметен по времени.
Кстати, class как метод class`а всегда можно было использовать?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

59

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

serzh82saratov пишет:

Да уж, цикл без FillRect тоже заметен по времени.

При желании его можно оптимизировать, сейчас он проскакивает вхолостую те поля, где фон уже нарисован.

serzh82saratov пишет:

Кстати, class как метод class`а всегда можно было использовать?

Это не метод класса, это вложенный класс (class NestedClass). Его можно и вовне вынести.

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

60

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

А что там значит extends BaseClassName?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

61

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

MsgBox, % MyClass.var

class MainClass  {
   static var := "test"
}

class MyClass extends MainClass  {
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

62

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

Копия получается... Что это даёт?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

63

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

Не копия, а наследование. Получается один общий класс, свойства и методы которого можно использовать в других классах.

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

64

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

То есть если имена методов или переменных будут совпадать, то они уникальны для каждого класса.


MainClass.Method1()
MyClass.Method1()

class MainClass  {
	Method1() {
		MsgBox % A_ThisFunc
	} 
}

class MyClass extends MainClass  {
	Method1() {
		MsgBox % A_ThisFunc
	} 
}

Если в MyClass убрать Method1, то он наследуется из MainClass.


MainClass.Method1()
MyClass.Method1()

class MainClass  {
	Method1() {
		MsgBox % A_ThisFunc
	} 
}

class MyClass extends MainClass  { 
}

Если в MainClass убрать Method1, то он наследуется из MyClass, но в MyClass пропадает.


MainClass.Method1()
MyClass.Method1()

class MainClass  { 
}

class MyClass extends MainClass  {
	Method1() {
		MsgBox % A_ThisFunc
	} 
}

Зачем это всё?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

65

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

serzh82saratov пишет:

Если в MainClass убрать Method1, то он наследуется из MyClass, но в MyClass пропадает.

Ты перепутал, ничего не пропадает.


MainClass.Method1()
;MyClass.Method1()

class MainClass  { 
}

class MyClass extends MainClass  {
   Method1() {
      MsgBox % A_ThisFunc
   } 
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

66 (изменено: serzh82saratov, 2018-01-10 04:20:11)

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

Так почему MyClass.Method1() не показывает? Он же есть в первом примере.
А во втором показывает MainClass.Method1().

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

67

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

Почему не показывает?

;MainClass.Method1()
MyClass.Method1()

class MainClass  { 
}

class MyClass extends MainClass  {
   Method1() {
      MsgBox % A_ThisFunc
   } 
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

68

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

А сразу обе строки почему не показывают?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

69

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


MainClass.Method1()
MyClass.Method1()

class MainClass  {
   Method1() {
      MsgBox % A_ThisFunc
   } 
}

class MyClass extends MainClass  { 
}

В этом примере class MyClass наследует методы MainClass, получается метод Method1 есть в обоих.

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

70

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

serzh82saratov пишет:

А сразу обе строки почему не показывают?

Не понял вопроса.

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

71

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

Не знаешь как не включать определённое окно (хотя бы своё) в снимок экрана? Встроенная лупа показывает экран, причём своё окно не включает в обзор.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

72

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

Думаю, никак. У встроенной в этом режиме просто прозрачно всё, кроме рамки.

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

73

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

Посмотри в режиме "закреплено" наведя на заголовок.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

74

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

teadrinker пишет:

Думаю, основная проблема в скорости выполнения AHK-скриптов

Наверняка какая то байда в GDI есть. Вот без цикла заполняет область, 800 2х цветных полос с градиентом, довольно быстро, может не только для полос, но и для квадратов есть, и без градиента.



#SingleInstance force
#NoEnv

Gui, Add, Pic, x+5 y5 w1600 h1000 hwndHPIC 0xE
Colorlist:=[0xff000000,0xffffffff]
Gui, Show 

t := 1111
Loop
{
	LinearGradient(HPIC, Colorlist, 0,2,0) 
	Sleep t
	LinearGradient(HPIC, Colorlist, 2,2,2) 
	Sleep t
	LinearGradient(HPIC, Colorlist, 1,2,2) 
	Sleep t
	LinearGradient(HPIC, Colorlist, 3,2,2) 
	Sleep t
}
return


LinearGradient(HWND, oColors, D = 0, BW = 0, BH = 0) {  
	IC := oColors.MaxIndex()
	
	oPositions := [0.0]
	P := 1.0 / (IC - 1)
	Loop, % (IC - 2)
		oPositions.Insert(P * A_Index)
	oPositions.Insert(1.0)
	
	If !DllCall("GetModuleHandle", "Str", "Gdiplus")
		hGDIP := DllCall("LoadLibrary", "Str", "Gdiplus")
	VarSetCapacity(SI, 16, 0)
	Numput(1, SI, "UInt")
	DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
	If (!pToken) {
		ErrorLevel := "GDIPlus could not be started!`nCheck the availability of GDIPlus on your system, please!"
		Return False
	}
	VarSetCapacity(RECT, 16, 0)
	DllCall("User32.dll\GetClientRect", "Ptr", HWND, "Ptr", &RECT)
	W := NumGet(RECT, 8, "Int")
	H := NumGet(RECT, 12, "Int")
	If D Not In 0,1,2,3
		D := 0
	If BW Not Between 1 And W
		BW := W 
	If BH Not Between 1 And H
		BH := H
	DllCall("Gdiplus.dll\GdipCreateBitmapFromScan0", "Int", W, "Int", H, "Int", 0
         , "Int", 0x26200A, "Ptr", 0, "PtrP", pBitmap)
	DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", pBitmap, "PtrP", pGraphics)
	VarSetCapacity(RECTF, 16, 0)
	NumPut(BW, RECTF,  8, "Float")
	NumPut(BH, RECTF, 12, "Float")
	DllCall("Gdiplus.dll\GdipCreateLineBrushFromRect", "Ptr", &RECTF
         , "Int", 0, "Int", 0, "Int", D, "Int", 0, "PtrP", pBrush)
	VarSetCapacity(COLORS, IC * 4, 0)
	O := -4
	For I, V In oColors 
		NumPut(V | 0x00000000, COLORS, O += 4, "UInt")
	VarSetCapacity(POSITIONS, IC * 4, 0)
	O := -4
	For I, V In oPositions
		NumPut(V, POSITIONS, O += 4, "Float")
	DllCall("Gdiplus.dll\GdipSetLinePresetBlend", "Ptr", pBrush, "Ptr", &COLORS, "Ptr", &POSITIONS, "Int", IC)
	
	DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrush
		, "Float", 0, "Float", 0, "Float", W, "Float", H)
		
	DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "Int", 0X00FFFFFF)
	
	DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pBitmap)
	DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", pBrush)
	DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", pGraphics)
	
	DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
	If (hGDIP)
		DllCall("FreeLibrary", "Ptr", hGDIP)
		
	SendMessage, STM_SETIMAGE := 0x172, IMAGE_BITMAP := 0x0, hBitmap, , ahk_id %HWND%
	
	DllCall("Gdi32.dll\DeleteObject", "Ptr", hBitmap)
	Return True
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

75 (изменено: serzh82saratov, 2018-01-10 09:43:58)

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

Думаю тут ответ.
Про текстурные кисти, оно как то тиражируется на всю область, в случае шахмат можно нарисовать в памяти 4 четыре квадрата и заполнить им как текстурой.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

76 (изменено: serzh82saratov, 2018-01-10 15:01:22)

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

Ну вот, а ты говоришь, одной строкой делается. Осталось только в Bitmapе нарисовать что надо.


sFile = D:\Images\10х10.bmp

#SingleInstance, Force
#NoEnv
SetBatchLines, -1
OnMessage(0x201, "WM_LBUTTONDOWN")

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

Width :=1400, Height := 1000

Gui, 1: -Caption +E0x80000 +hwndhwnd +AlwaysOnTop +ToolWindow +OwnDialogs  
Gui, 1: Show, NA

hbm := CreateDIBSection(Width, Height) 
hdc := CreateCompatibleDC() 
obm := SelectObject(hdc, hbm)

G := Gdip_GraphicsFromHDC(hdc) 
Gdip_SetSmoothingMode(G, 4) 

pBitmap := Gdip_CreateBitmapFromFile(sFile)
pBrush := Gdip_CreateTextureBrush(pBitmap, 0)

Gdip_FillRectangle(G, pBrush, 0, 0, Width, Height) 

Gdip_DeleteBrush(pBrush)

UpdateLayeredWindow(hwnd, hdc, 20, 20, Width, Height)

SelectObject(hdc, obm)

DeleteObject(hbm)

DeleteDC(hdc)

Gdip_DeleteGraphics(G)
Return 

Exit: 
	Gdip_Shutdown(pToken)
	ExitApp 
	
Escape:: ExitApp

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { 
		PostMessage, 0xA1, 2 
}

И при движении кажется только визуальный эффект остаётся.


Так текстом, только не пойму как задать свой фон.


#SingleInstance, Force
#NoEnv
SetBatchLines, -1
OnMessage(0x201, "WM_LBUTTONDOWN")

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

Width :=1400, Height := 1000

Gui, 1: -Caption +E0x80000 +hwndhwnd +AlwaysOnTop +ToolWindow +OwnDialogs  
Gui, 1: Show, NA

hbm := CreateDIBSection(Width, Height) 
hdc := CreateCompatibleDC() 
obm := SelectObject(hdc, hbm)

G := Gdip_GraphicsFromHDC(hdc) 
Gdip_SetSmoothingMode(G, 4) 

  ;	Пытаюсь сделать общий фон
  
pBrush2 := Gdip_BrushCreateSolid(0xaa004400)
Gdip_FillRoundedRectangle(G, pBrush2, 0, 0, Width, Height, 0)
Gdip_DeleteBrush(pBrush2)

Font = Arial

If !Gdip_FontFamilyCreate(Font)
{
   MsgBox, 48, Font error!, The font you have specified does not exist on the system
   ExitApp
}

WidthText :=100, HeightText := 22
Options = x0p y0p w%WidthText%p h%HeightText%p Centre cffffffff r4 s20 Italic 

hbm2 := CreateDIBSection(WidthText, HeightText) 
hdc2 := CreateCompatibleDC() 
obm2 := SelectObject(hdc2, hbm2) 
G2 := Gdip_GraphicsFromHDC(hdc2) 
Gdip_SetSmoothingMode(G2, 4) 

Gdip_TextToGraphics(G2, "Tutorial", Options, Font, WidthText, HeightText)
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "UPtr", hbm2, "UPtr", 0, "UPtr*", pBitmap)
SelectObject(hdc2, obm2)
DeleteObject(hbm2) 
DeleteDC(hdc2) 
Gdip_DeleteGraphics(G2)

pBrush := Gdip_CreateTextureBrush(pBitmap, 0)

Gdip_FillRectangle(G, pBrush, 0, 0, Width, Height) 

Gdip_DeleteBrush(pBrush)

UpdateLayeredWindow(hwnd, hdc, 20, 20, Width, Height)

SelectObject(hdc, obm)

DeleteObject(hbm)

DeleteDC(hdc)

Gdip_DeleteGraphics(G)
Return

Exit: 
	Gdip_Shutdown(pToken)
	ExitApp 
	
Escape:: ExitApp

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { 
		PostMessage, 0xA1, 2 
}
Post's attachments

10х10.bmp 374 b, 4 downloads since 2018-01-10 

You don't have the permssions to download the attachments of this post.
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

77

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

serzh82saratov пишет:
pBrush := Gdip_CreateTextureBrush(pBitmap, 0)

Да, верная идея. В GDI есть аналог — PatternBrush.

Gui, -DPIScale
Gui, Color, White
Gui, Margin, 20, 20
Gui, Add, Pic, w640 h640 hwndhPic1
Gui, Add, Pic, x+7 yp wp hp hwndhPic2

options := { hStatic:     hPic1
           , cellsNumber: 80
           , rowsNumber:  80
           , darkColor:   0xFF0D00    ; будет фоном
           , lightColor:  0xC618 }
           
board1 := new ChessBoard(options)

options := { hStatic:     hPic2
           , cellsNumber: 80
           , rowsNumber:  80
           , darkColor:   0x028E9B    ; будет фоном
           , lightColor:  0xFF7800 }

board2 := new ChessBoard(options)

Gui, Show
Return

GuiClose:
   ExitApp

class ChessBoard
{
   __New(options)  {
      this.options := options
      hPic := options.hStatic
      this.hParent := DllCall("GetAncestor", Ptr, hPic, UInt, GA_ROOT := 2, Ptr)
      
      WinGetPos,,, W, H, ahk_id %hPic%
      this.BoardWidth := W, this.BoardHeight := H
      this.CellWidth := W/options.cellsNumber
      this.CellHeight := H/options.rowsNumber
      
      this.hDC := DllCall("GetDC", Ptr, hPic, Ptr)
      this.oMDC := new this.CompatibleDC(this.hDC, W, H)
      this.hMDC := this.oMDC.hCDC
      
      OnMessage( 0xF, this.redraw := ObjBindMethod(this, "WM_PAINT") )
      this.DrawBoard()
   }
   
   __Delete()  {
      this.oMDC := ""
      DllCall("DeleteDC", Ptr, this.hDC)
      OnMessage(0xF, this.redraw, 0)
   }
   
   DrawBoard()  {
      oCDC := new this.CompatibleDC(this.hDC, this.CellWidth*2, this.CellHeight*2)
      hCDC := oCDC.hCDC
      Loop 2  {
         row := A_Index
         Loop 2  {
            cell := A_Index
            X := this.CellWidth*(cell - 1)
            Y := this.CellHeight*(row - 1)
            brush := new this.Brush(hCDC, this.options[ mod(row + cell, 2) ? "darkColor" : "lightColor" ])
            this.FillRect(hCDC, brush.hBrush, X, Y, X + this.CellWidth, Y + this.CellHeight)
         }
      }
      brush := new this.Brush(this.hMDC, oCDC.hCBM)
      this.FillRect(this.hMDC, brush.hBrush, 0, 0, this.BoardWidth, this.BoardHeight)
      this.BitBlt(this.hDC, this.hMDC)
   }
   
   FillRect(hDC, hBrush, left, top, right, bottom)  {
      VarSetCapacity(RECT, 16, 0)
      NumPut(left,   RECT, 0)
      NumPut(top,    RECT, 4)
      NumPut(right,  RECT, 8)
      NumPut(bottom, RECT, 12, "UInt")
      DllCall("FillRect", Ptr, hDC, Ptr, &RECT, Ptr, hBrush)
   }
   
   BitBlt(ddc, sdc)  {
      DllCall("BitBlt", Ptr, ddc, Int, 0, Int, 0, Int, this.BoardWidth, Int, this.BoardHeight
                      , Ptr, sdc, Int, 0, Int, 0, UInt, SRCCOPY := 0xCC0020)
   }
   
   WM_PAINT(wp, lp, msg, hwnd)  {
      if (this.hParent = hwnd)   {
         timer := ObjBindMethod(this, "BitBlt", this.hDC, this.hMDC)
         SetTimer, % timer, -10
      }
   }
   
   class Brush
   {
      __New(hDC, pattern)  {
         if DllCall("GetObject", Ptr, pattern, Int, 0, Ptr, 0)
            this.hBrush := DllCall("CreatePatternBrush", Ptr, pattern, Ptr)
         else
            this.hBrush := DllCall("CreateSolidBrush", UInt, DllCall("Ws2_32\ntohl", UInt, pattern << 8, UInt), Ptr)
         this.oBR := DllCall("SelectObject", Ptr, hDC, Ptr, this.hBrush, Ptr)
      }
      
      __Delete()  {
         DllCall("SelectObject", Ptr, hDC, Ptr, this.oBR, Ptr)
         DllCall("DeleteObject", Ptr, this.hBrush)
      }
   }
   
   class CompatibleDC
   {
      __New(hDC, w, h)  {
         this.hCDC := DllCall("CreateCompatibleDC", Ptr, hDC, Ptr)
         this.hCBM := DllCall("CreateCompatibleBitmap", Ptr, hDC, Int, w, Int, h, Ptr)
         this.oBM := DllCall("SelectObject", Ptr, this.hCDC, Ptr, this.hCBM, Ptr)
      }
      
      __Delete()  {
         DllCall("SelectObject", Ptr, this.hCDC, Ptr, this.oBM, Ptr)
         DllCall("DeleteDC", Ptr, this.hCDC)
         DllCall("DeleteObject", Ptr, this.hCBM)
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

78

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

Интересно как с текстом, хочется типа водяных знаков, наклонный полупрозрачный текст (желательно с тенью) на непрозрачном фоне.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

79

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

serzh82saratov пишет:

Так текстом, только не пойму как задать свой фон.

Для текста фон задаётся через SetBkColor.

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

80

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

Не получается.

Gdip_TextToGraphics(G2, "Tutorial", Options, Font, WidthText, HeightText)
DllCall("SetBkColor", Ptr, hdc2, UInt, 0xffffff)
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

81

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

В G2 просто залей фон прямоугольником перед добавлением текста.

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

82

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

Так? А черный фон как убрать, как сделать прозрачным на что текстура накладывается?


#SingleInstance, Force
#NoEnv
SetBatchLines, -1
OnMessage(0x201, "WM_LBUTTONDOWN")

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

Width := 1600, Height := 1000

Gui, 1: -Caption +E0x80000 +hwndhwnd +AlwaysOnTop +ToolWindow +OwnDialogs  
Gui, 1: Show, NA

hbm := CreateDIBSection(Width, Height) 
hdc := CreateCompatibleDC() 
obm := SelectObject(hdc, hbm)

G := Gdip_GraphicsFromHDC(hdc) 
Gdip_SetSmoothingMode(G, 4) 

  ;	Пытаюсь сделать общий фон
  
; pBrush2 := Gdip_BrushCreateSolid(0xaa004400)
; Gdip_FillRoundedRectangle(G, pBrush2, 0, 0, Width, Height, 0)
; Gdip_DeleteBrush(pBrush2)

Font = Arial

If !Gdip_FontFamilyCreate(Font)
{
   MsgBox, 48, Font error!, The font you have specified does not exist on the system
   ExitApp
}

WidthText := 100, HeightText := 25
Options = x0p y0p w%WidthText%p h%HeightText%p Centre cffffffff r4 s20 Italic 

hbm2 := CreateDIBSection(WidthText, HeightText) 
hdc2 := CreateCompatibleDC() 
obm2 := SelectObject(hdc2, hbm2) 
G2 := Gdip_GraphicsFromHDC(hdc2) 

pBrush := Gdip_BrushCreateSolid(0x55198F00)
Gdip_FillRectangle(G2, pBrush, 0, 0, WidthText, HeightText)
Gdip_DeleteBrush(pBrush)
Gdip_SetSmoothingMode(G2, 4) 

Gdip_TextToGraphics(G2, "Tutorial", Options, Font, WidthText, HeightText)
 
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "UPtr", hbm2, "UPtr", 0, "UPtr*", pBitmap)
SelectObject(hdc2, obm2)
DeleteObject(hbm2) 
DeleteDC(hdc2) 
Gdip_DeleteGraphics(G2)

pBrush := Gdip_CreateTextureBrush(pBitmap, 0)

Gdip_FillRectangle(G, pBrush, 0, 0, Width, Height)

Gdip_DeleteBrush(pBrush)

UpdateLayeredWindow(hwnd, hdc, 20, 20, Width, Height)

SelectObject(hdc, obm)

DeleteObject(hbm)

DeleteDC(hdc)

Gdip_DeleteGraphics(G)
Return

Exit: 
	Gdip_Shutdown(pToken)
	ExitApp 
	
Escape:: ExitApp

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { 
		PostMessage, 0xA1, 2 
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

83 (изменено: serzh82saratov, 2018-01-10 21:07:32)

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

Получается нужен не фон текста, то есть как раз текст без фона надо, а нужен фон окна прозрачный или полупрозрачный с заданным цветом. Сейчас он просто чёрный.
Также как если в 76 1 пример использовать иконку с прозрачностью.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

84

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

Похоже, эта кисть прозрачный фон не поддерживает.


#SingleInstance, Force
#NoEnv
SetBatchLines, -1
OnMessage(0x201, "WM_LBUTTONDOWN")

If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}
OnExit, Exit

Width := 1600, Height := 1000

Gui, 1: -Caption +E0x80000 +hwndhwnd +AlwaysOnTop +ToolWindow +OwnDialogs  
Gui, 1: Show, NA

hbm := CreateDIBSection(Width, Height) 
hdc := CreateCompatibleDC() 
obm := SelectObject(hdc, hbm)

G := Gdip_GraphicsFromHDC(hdc) 
Gdip_SetSmoothingMode(G, 4) 

  ;   Пытаюсь сделать общий фон
  
; pBrush2 := Gdip_BrushCreateSolid(0xaa004400)
; Gdip_FillRoundedRectangle(G, pBrush2, 0, 0, Width, Height, 0)
; Gdip_DeleteBrush(pBrush2)

Font = Arial

If !Gdip_FontFamilyCreate(Font)
{
   MsgBox, 48, Font error!, The font you have specified does not exist on the system
   ExitApp
}

WidthText := 100, HeightText := 25
Options = x0p y0p w%WidthText%p h%HeightText%p Centre cffffffff r4 s20 Italic 

hbm2 := CreateDIBSection(WidthText, HeightText) 
hdc2 := CreateCompatibleDC() 
obm2 := SelectObject(hdc2, hbm2) 
G2 := Gdip_GraphicsFromHDC(hdc2) 

pBrush := Gdip_BrushCreateSolid(0xFF198F00)
Gdip_FillRectangle(G2, pBrush, 0, 0, WidthText, HeightText)
Gdip_DeleteBrush(pBrush)
Gdip_SetSmoothingMode(G2, 4) 

Gdip_TextToGraphics(G2, "Tutorial", Options, Font, WidthText, HeightText)
 
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "UPtr", hbm2, "UPtr", 0, "UPtr*", pBitmap)
SelectObject(hdc2, obm2)
DeleteObject(hbm2) 
DeleteDC(hdc2) 
Gdip_DeleteGraphics(G2)

pBrush := Gdip_CreateTextureBrush(pBitmap, 0)

Gdip_FillRectangle(G, pBrush, 0, 0, Width, Height)

Gdip_DeleteBrush(pBrush)

UpdateLayeredWindow(hwnd, hdc, 20, 20, Width, Height)

SelectObject(hdc, obm)

DeleteObject(hbm)

DeleteDC(hdc)

Gdip_DeleteGraphics(G)
Return

Exit: 
   Gdip_Shutdown(pToken)
   ExitApp 
   
Escape:: ExitApp

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { 
      PostMessage, 0xA1, 2 
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

85

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

Так у иконок же прозрачность выодит.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

86

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

Да, точно. Наверно, нужны ещё какие-то пляски с бубном, чтобы получить bitmap из graphics с прозрачностью.

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

87

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

Пример из библиотеки не поможет? Текст непрозрачен.


; gdi+ ahk tutorial 8 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to write text onto a gui

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk

; Start gdi+
If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}
OnExit, Exit

; Set the width and height we want as our drawing area, to draw everything in. This will be the dimensions of our bitmap
Width := 300, Height := 200

; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs

; Show the window
Gui, 1: Show, NA

; Get a handle to this window we have created in order to update it later
hwnd1 := WinExist()

; Create a gdi bitmap with width and height of what we are going to draw into it. This is the entire drawing area for everything
hbm := CreateDIBSection(Width, Height)

; Get a device context compatible with the screen
hdc := CreateCompatibleDC()

; Select the bitmap into the device context
obm := SelectObject(hdc, hbm)

; Get a pointer to the graphics of the bitmap, for use with drawing functions
G := Gdip_GraphicsFromHDC(hdc)

; Set the smoothing mode to antialias = 4 to make shapes appear smother (only used for vector drawing and filling)
Gdip_SetSmoothingMode(G, 4)

; Create a partially transparent, black brush (ARGB = Transparency, red, green, blue) to draw a rounded rectangle with
pBrush := Gdip_BrushCreateSolid(0x11004400)

; Fill the graphics of the bitmap with a rounded rectangle using the brush created
; Filling the entire graphics - from coordinates (0, 0) the entire width and height
; The last parameter (20) is the radius of the circles used for the rounded corners
Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 20)

; Delete the brush as it is no longer needed and wastes memory
Gdip_DeleteBrush(pBrush)

; We can specify the font to use. Here we use Arial as most systems should have this installed
Font = Arial
; Next we can check that the user actually has the font that we wish them to use
; If they do not then we can do something about it. I choose to give a wraning and exit!
If !Gdip_FontFamilyCreate(Font)
{
   MsgBox, 48, Font error!, The font you have specified does not exist on the system
   ExitApp
}

; There are a lot of things to cover with the function Gdip_TextToGraphics

; The 1st parameter is the graphics we wish to use (our canvas)

; The 2nd parameter is the text we wish to write. It can include new lines `n

; The 3rd parameter, the options are where all the action takes place...
; You can write literal x and y coordinates such as x20 y50 which would place the text at that position in pixels
; or you can include the last 2 parameters (Width and Height of the Graphics we will use) and then you can use x10p
; which will place the text at 10% of the width and y30p which is 30% of the height
; The same percentage marker may be used for width and height also, so w80p makes the bounding box of the rectangle the text
; will be written to 80% of the width of the graphics. If either is missed (as I have missed height) then the height of the bounding
; box will be made to be the height of the graphics, so 100%

; Any of the following words may be used also: Regular,Bold,Italic,BoldItalic,Underline,Strikeout to perform their associated action

; To justify the text any of the following may be used: Near,Left,Centre,Center,Far,Right with different spelling of words for convenience

; The rendering hint (the quality of the antialiasing of the text) can be specified with r, whose values may be:
; SystemDefault = 0
; SingleBitPerPixelGridFit = 1
; SingleBitPerPixel = 2
; AntiAliasGridFit = 3
; AntiAlias = 4

; The size can simply be specified with s

; The colour and opacity can be specified for the text also by specifying the ARGB as demonstrated with other functions such as the brush
; So cffff0000 would make a fully opaque red brush, so it is: cARGB (the literal letter c, follwed by the ARGB)

; The 4th parameter is the name of the font you wish to use

; As mentioned previously, you don not need to specify the last 2 parameters, the width and height, unless
; you are planning on using the p option with the x,y,w,h to use the percentage
Options = x10p y30p w80p Centre cff000000 r4 s20 Underline Italic
Gdip_TextToGraphics(G, "Tutorial 8`n`nThank you for trying this example", Options, Font, Width, Height)


; Update the specified window we have created (hwnd1) with a handle to our bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
; With some simple maths we can place the gui in the centre of our primary monitor horizontally and vertically at the specified heigth and width
UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height)

; By placing this OnMessage here. The function WM_LBUTTONDOWN will be called every time the user left clicks on the gui
OnMessage(0x201, "WM_LBUTTONDOWN")


; Select the object back into the hdc
SelectObject(hdc, obm)

; Now the bitmap may be deleted
DeleteObject(hbm)

; Also the device context related to the bitmap may be deleted
DeleteDC(hdc)

; The graphics may now be deleted
Gdip_DeleteGraphics(G)
Return

;#######################################################################

; This function is called every time the user clicks on the gui
; The PostMessage will act on the last found window (this being the gui that launched the subroutine, hence the last parameter not being needed)
WM_LBUTTONDOWN()
{
   PostMessage, 0xA1, 2
}

;#######################################################################

Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp
Return
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

88

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


#SingleInstance, Force
#NoEnv
SetBatchLines, -1
OnMessage(0x201, "WM_LBUTTONDOWN")

If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}
OnExit, Exit

Width := 1600, Height := 1000

Gui, 1: -Caption +E0x80000 +hwndhwnd +AlwaysOnTop +ToolWindow +OwnDialogs  
Gui, 1: Show, NA

hbm := CreateDIBSection(Width, Height) 
hdc := CreateCompatibleDC() 
obm := SelectObject(hdc, hbm)

G := Gdip_GraphicsFromHDC(hdc) 
Gdip_SetSmoothingMode(G, 4) 

  ;   Пытаюсь сделать общий фон
  
pBrush2 := Gdip_BrushCreateSolid(0xaa004400)
Gdip_FillRoundedRectangle(G, pBrush2, 0, 0, Width, Height, 0)
Gdip_DeleteBrush(pBrush2)

Font = Arial

If !Gdip_FontFamilyCreate(Font)
{
   MsgBox, 48, Font error!, The font you have specified does not exist on the system
   ExitApp
}

WidthText := 100, HeightText := 25
Options = x0p y0p w%WidthText%p h%HeightText%p Centre cffffffff r4 s20 Italic 

pBitmap := Gdip_CreateBitmap(WidthText, HeightText) 
G2 := Gdip_GraphicsFromImage(pBitmap)
Gdip_SetSmoothingMode(G2, 4) 

Gdip_TextToGraphics(G2, "Tutorial", Options, Font, WidthText, HeightText)
 
Gdip_DeleteGraphics(G2)

pBrush := Gdip_CreateTextureBrush(pBitmap, 0)

Gdip_FillRectangle(G, pBrush, 0, 0, Width, Height)

Gdip_DeleteBrush(pBrush)

UpdateLayeredWindow(hwnd, hdc, 20, 20, Width, Height)

SelectObject(hdc, obm)

DeleteObject(hbm)

DeleteDC(hdc)

Gdip_DeleteGraphics(G)
Return

Exit: 
   Gdip_Shutdown(pToken)
   ExitApp 
   
Escape:: ExitApp

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { 
      PostMessage, 0xA1, 2 
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

89

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

Надо взять на заметку: Gdip_CreateBitmap() создаёт прозрачную bitmap.

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

90

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

О, супер. А как наклонить отдельно каждый текст градусов на 30, не пойму как этот метод вызвать. И про тень от текста не знаешь?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

91

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

Не-а, не интересовался пока.

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

92 (изменено: serzh82saratov, 2018-01-11 00:19:38)

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

Вариант наклона всей текстуры тоже интересен.
Вышла ерунда. Координаты в Gdip_TranslateWorldTransform и размеры в Gdip_FillRectangle, путём подбора.
И правильно ли у меня задана прозрачность фону, или можно проще?


#SingleInstance, Force
#NoEnv
SetBatchLines, -1
OnMessage(0x201, "WM_LBUTTONDOWN")

If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}
OnExit, Exit

Width := 1600, Height := 1000
transmain := 88
transtext := ff

Gui, 1: -Caption +E0x80000 +hwndhwnd +AlwaysOnTop +ToolWindow +OwnDialogs  
Gui, 1: Show, NA

hbm := CreateDIBSection(Width, Height) 
hdc := CreateCompatibleDC() 
obm := SelectObject(hdc, hbm)

G := Gdip_GraphicsFromHDC(hdc) 
Gdip_SetSmoothingMode(G, 4) 
Gdip_SetInterpolationMode(G, 7)

  ;   задаю прозрачность фону
  
pBrush := Gdip_BrushCreateSolid("0x" transmain "36D107")
Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 0)
Gdip_DeleteBrush(pBrush)

  ;   ^ прозрачность фону
  
Font = Arial

If !Gdip_FontFamilyCreate(Font)
{
   MsgBox, 48, Font error!, The font you have specified does not exist on the system
   ExitApp
}

WidthText := 100, HeightText := 25
Options = x0p y0p w%WidthText%p h%HeightText%p Centre c%transtext%000000 r4 s20 Italic 


Angle := -22
Gdip_RotateWorldTransform(G, Angle) 
Gdip_TranslateWorldTransform(G, -700, 0)
 

pBitmap := Gdip_CreateBitmap(WidthText, HeightText) 
G2 := Gdip_GraphicsFromImage(pBitmap)
Gdip_SetSmoothingMode(G2, 4) 

Gdip_TextToGraphics(G2, "Tutorial", Options, Font, WidthText, HeightText)
 
Gdip_DeleteGraphics(G2)

pBrush := Gdip_CreateTextureBrush(pBitmap, 0)

Gdip_FillRectangle(G, pBrush, 0, 0, Width*2, Height*2)

Gdip_DeleteBrush(pBrush)

UpdateLayeredWindow(hwnd, hdc, 20, 20, Width, Height)

SelectObject(hdc, obm)

DeleteObject(hbm)

DeleteDC(hdc)

Gdip_DeleteGraphics(G)
Return

Exit: 
   Gdip_Shutdown(pToken)
   ExitApp 
   
Escape:: ExitApp

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { 
      PostMessage, 0xA1, 2 
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

93

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

Вроде правильно.

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

94

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

Можешь объяснить как использовать пример, там жирным выделено.
Что за SystemBrushes?

// Draw the shadow text
   g->DrawString(textToDisplay,
                 font,
                 SystemBrushes::ControlLight,
                 x + 5, y + 5);

   // Draw the foreground text
   g->DrawString(textToDisplay, font, SystemBrushes::ControlText,
                 x, y);
}

На анк ничего не нашёл.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

95 (изменено: teadrinker, 2018-01-12 03:28:51)

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

SystemBrushes — это кисти с предустановленными цветами, которые используются системой по умолчанию для отрисовки определённых элементов интерфейса. Описание класса здесь, аналог в winapi GDI — GetSysColorBrush(), на GDI+ не нашёл.

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

96

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

А на GDI я так понял пример сложно будет сделать, так как надо писать аналог Gdip_TextToGraphics.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

97

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

Здесь у меня текст добавляется без использования GDI+.

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

98

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

На GDI+ вроде так можно:
http://microsoft.public.win32.programme … colorbrush

99

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

Только зачем? Цвет кисти можно взять любой.

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

100

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

Ты имеешь ввиду что в примере идёт простое наложение текстов, и с тенями (SHADOW) это никак не связано?


 
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
OnMessage(0x201, "WM_LBUTTONDOWN")

If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}
OnExit, Exit

Width := 1600, Height := 1000
transmain := ff
transtext := 22

Gui, 1: -Caption +E0x80000 +hwndhwnd +AlwaysOnTop +ToolWindow +OwnDialogs  
Gui, 1: Show, NA

hbm := CreateDIBSection(Width, Height) 
hdc := CreateCompatibleDC() 
obm := SelectObject(hdc, hbm)

G := Gdip_GraphicsFromHDC(hdc) 
Gdip_SetSmoothingMode(G, 4) 
Gdip_SetInterpolationMode(G, 7)

  ;   задаю прозрачность фону
  
pBrush := Gdip_BrushCreateSolid("0xffffffff")
Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 0)
Gdip_DeleteBrush(pBrush)

  ;   ^ прозрачность фону
  
Font = Arial

If !Gdip_FontFamilyCreate(Font)
{
   MsgBox, 48, Font error!, The font you have specified does not exist on the system
   ExitApp
}

WidthText := 250, HeightText := 85


Angle := -22
Gdip_RotateWorldTransform(G, Angle) 
Gdip_TranslateWorldTransform(G, -700, 0)
 

pBitmap := Gdip_CreateBitmap(WidthText, HeightText) 
G2 := Gdip_GraphicsFromImage(pBitmap)
Gdip_SetSmoothingMode(G2, 4)  


Text = Tutorial
Options = x2p y8p w%WidthText%p h%HeightText%p  c22888888 r4 s40 Italic 
Gdip_TextToGraphics(G2, Text, Options, Font, WidthText, HeightText)

Options = x0p y0p w%WidthText%p h%HeightText%p  c44000000 r4 s40 Italic 
Gdip_TextToGraphics(G2, Text, Options, Font, WidthText, HeightText)
 
Gdip_DeleteGraphics(G2)

pBrush := Gdip_CreateTextureBrush(pBitmap, 0)

Gdip_FillRectangle(G, pBrush, 0, 0, Width*2, Height*2)

Gdip_DeleteBrush(pBrush)

UpdateLayeredWindow(hwnd, hdc, 20, 20, Width, Height)

SelectObject(hdc, obm)

DeleteObject(hbm)

DeleteDC(hdc)

Gdip_DeleteGraphics(G)
Return

Exit: 
   Gdip_Shutdown(pToken)
   ExitApp 
   
Escape:: ExitApp

WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { 
      PostMessage, 0xA1, 2 
} 
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui