1 (изменено: serzh82saratov, 2017-12-28 23:25:42)

Тема: AHK: AnimateWindow и StretchBlt

Как в данном коде при применении AnimateWindow сделать, чтобы изображение не пропадало?

Gui, +hwndhGui -Caption -DPIScale +Border
Gui, Add, Text, hwndhDevCon w222 h222 Border
Gui, Show

hdcDest := DllCall("GetDC", Ptr, hDevCon, Ptr)
hdcSrc := DllCall("GetDC", Ptr, 0, Ptr)
StretchBlt(hdcDest, 0, 0, 222, 222, hdcSrc, 0, 0, 111, 111)

Sleep 666

Loop 2
	DllCall("AnimateWindow", "Ptr", hGui, "Int", 333, "UInt", 0x00010002)
	, DllCall("AnimateWindow", "Ptr", hGui, "Int", 333, "UInt", 0x0000002) 
ExitApp 

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

2 (изменено: serzh82saratov, 2017-12-28 23:25:52)

Re: AHK: AnimateWindow и StretchBlt

Вопрос "как" вроде снят, теперь вопрос насколько это правильно.


Gui, +hwndhGui -Caption -DPIScale +Border +Owner
Gui, Add, Text, hwndhDevCon w222 h222 Border +0xE  ;	SS_BITMAP := 0xE
Gui, Show

hdcDest := DllCall("GetDC", Ptr, hDevCon, Ptr)
hdcSrc := DllCall("GetDC", Ptr, 0, Ptr)

StretchBlt(hdcDest, 1, 1, 220, 220, hdcSrc, 0, 0, 111, 111)
hBM := DCToStatic(hdcDest, hDevCon, 0, 0, 220, 220)

Sleep 666
Loop 3
{
	DllCall("AnimateWindow", "Ptr", hGui, "Int", 333, "UInt", 0x00010002) 
	DllCall("AnimateWindow", "Ptr", hGui, "Int", 333, "UInt", 0x0000002)  
}
Sleep 666
DllCall("DeleteObject", Ptr, hBM)
StretchBlt(hdcDest, 0, 0, 220, 220, hdcSrc, 0, 0, 333, 333)
Return 

DCToStatic(hDC, hDevCon, X, Y, W, H) {
	tDC := DllCall("CreateCompatibleDC", UInt, 0) 
	hBM := DllCall("CopyImage", Ptr, DllCall("CreateBitmap", Int, W, Int, H, UInt, 1, UInt, 24
							, UInt, 0), UInt, 0, Int, 0, Int, 0, UInt, 0x2008, UInt) 
	oBM := DllCall("SelectObject", Ptr, tDC, Ptr, hBM) 
	DllCall("BitBlt", Ptr, tDC, UInt, 0, UInt, 0, Int, W, Int, H, Ptr, hDC, UInt, X, UInt, Y, UInt, 0xC000CA) 
	DllCall("SelectObject", Ptr, tDC, Ptr, oBM)
	DllCall("DeleteDC", Ptr, tDC)
	SendMessage, 0x172, 0, hBM,, ahk_id %hDevCon%  ;	STM_SETIMAGE, IMAGE_BITMAP
	Return hBM
}

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

3

Re: AHK: AnimateWindow и StretchBlt

А что значит

hdcSrc := DllCall("GetDC")

?

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

4

Re: AHK: AnimateWindow и StretchBlt

hWnd [in]
A handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire screen.

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

5

Re: AHK: AnimateWindow и StretchBlt

Имеешь ввиду так правильно:

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

6

Re: AHK: AnimateWindow и StretchBlt

А проверить? Где тут value which is null?

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

7

Re: AHK: AnimateWindow и StretchBlt

Под х32 так работает, под х64 забыл проверить, поправил.

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

8

Re: AHK: AnimateWindow и StretchBlt

serzh82saratov пишет:

Имеешь ввиду так правильно:

У меня предыдущий вариант возвращал 0.

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

9

Re: AHK: AnimateWindow и StretchBlt

Все DllCall, возвращающие хэндлы, должны бы заканчиваться на , Ptr).

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

10

Re: AHK: AnimateWindow и StretchBlt

Да, верно.
А по сабжу есть идеи? Во втором посте очень бывает что в начале применения AnimateWindow окно мелькает.

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

11

Re: AHK: AnimateWindow и StretchBlt

Кроме использования Layered Window и GDI+ никаких.

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

12

Re: AHK: AnimateWindow и StretchBlt

А Layered вроде не может быть дочерним?

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

13

Re: AHK: AnimateWindow и StretchBlt

Нет, но можно надёжно привязать к основному окну, отслеживая WM_MOVE.

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

14

Re: AHK: AnimateWindow и StretchBlt

А например при отмене минимизации окна с включенным аеро, как синхронизировать появление?

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

15

Re: AHK: AnimateWindow и StretchBlt

Ох, я о таких тонкостях не задумывался. Можно задержать появление "дочернего", а в основном окне просто прорисовать его содержание.

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

16 (изменено: serzh82saratov, 2017-12-29 03:39:09)

Re: AHK: AnimateWindow и StretchBlt

Оказалось что с +Border у окна к которому применяется AW_HIDE происходит мелькание.
Можно таким костылём обойти, сделать подкладку из окна без Border:


Gui, +AlwaysOnTop -DPIScale +hwndhGui1 -Caption  

Gui, 2: +AlwaysOnTop -DPIScale +hwndhGui2 -Caption +Parent%hGui1% +Border
Gui, 2: Add, Text, hwndhText x50 y50 w300 h300 Border 0xE  ; SS_BITMAP := 0xE
Gui, 2: Show, x0 y0 w400 h400

Gui, Show, w402 h402

Sleep 666 

hdcDest := DllCall("GetDC", Ptr, hText, Ptr)
hdcSrc := DllCall("GetDC", Ptr, 0, Ptr)

StretchBlt(hdcDest, 0, 0, 298, 298, hdcSrc, 222, 222, 111, 111)
Sleep 666
hBM := DCToStatic(hdcDest, hText, 0, 0, 298, 298) 

DllCall("AnimateWindow", "Ptr", hGui1, "Int", 1333, "UInt", 0x00010002) 
DllCall("AnimateWindow", "Ptr", hGui1, "Int", 1333, "UInt", 0x0000001)  

Sleep 666

DllCall("DeleteObject", Ptr, hBM)
StretchBlt(hdcDest, 0, 0, 298, 298, hdcSrc, 0, 0, 333, 333) 
Return

DCToStatic(hDC, hDevCon, X, Y, W, H) {
	tDC := DllCall("CreateCompatibleDC", UInt, 0) 
	hBM := DllCall("CopyImage", Ptr, DllCall("CreateBitmap", Int, W, Int, H, UInt, 1, UInt, 24
							, UInt, 0), UInt, 0, Int, 0, Int, 0, UInt, 0x2008, UInt) 
	oBM := DllCall("SelectObject", Ptr, tDC, Ptr, hBM) 
	DllCall("BitBlt", Ptr, tDC, UInt, 0, UInt, 0, Int, W, Int, H, Ptr, hDC, UInt, X, UInt, Y, UInt, 0xC000CA) 
	DllCall("SelectObject", Ptr, tDC, Ptr, oBM)
	DllCall("DeleteDC", Ptr, tDC)
	SendMessage, 0x172, 0, hBM,, ahk_id %hDevCon%  ;	STM_SETIMAGE, IMAGE_BITMAP
	Return hBM
}

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

17 (изменено: serzh82saratov, 2018-01-07 13:14:54)

Re: AHK: AnimateWindow и StretchBlt

teadrinker
C Layered конечно красиво, картинка полностью статична, но и кушает проца в 2 раза больше.
Можешь глянуть UpdateWindow, а то кажется как то громоздко, делал по этому примеру.
И UpdateLayeredWindow может обновлять окно в текущих координатах, чтобы не указывать экранные?


#SingleInstance Force
#NoEnv
#Persistent
SetBatchLines, -1
ListLines, Off
OnMessage(0x0020, "WM_SETCURSOR") 
OnMessage(0x201, "LBUTTONDOWN") ; WM_LBUTTONDOWN
OnMessage(0xA1, "LBUTTONDOWN") ; WM_NCLBUTTONDOWN
DetectHiddenWindows, On
CoordMode, Mouse, Screen 
OnExit, Exit

If !pToken := GdipStartup()
{
	MsgBox, 4112, Gdiplus Error, Gdiplus failed to start. Please ensure you have Gdiplus on your system.
	ExitApp
}
Global oZoom := {}  
ZoomCreate()
ZoomShow(1)
Magnify() 
oZoom.Start := 1
Return

1::  ;	переместить окно к мыши
	MouseGetPos, X, Y 
	hDWP := DllCall("BeginDeferWindowPos", "Int", 2)
	hDWP := DllCall("DeferWindowPos"
	, "Ptr", hDWP, "Ptr", oZoom.hLW, "UInt", 0
	, "Int", X + 1 + 12
	, "Int", Y + 46 + 12, "Int", 0, "Int", 0
	, "UInt", 0x0011)    ; 0x0010 := SWP_NOACTIVATE | 0x0001 := SWP_NOSIZE 
	hDWP := DllCall("DeferWindowPos"                        
	, "Ptr", hDWP, "Ptr", oZoom.hGui, "UInt", 0                  	
	, "Int", X + 12, "Int", Y + 12, "Int", 0, "Int", 0	
	, "UInt", 0x0011)    ; 0x0010 := SWP_NOACTIVATE | 0x0001 := SWP_NOSIZE 
	DllCall("EndDeferWindowPos", "Ptr", hDWP) 
	return

2:: oZoom.Pause := !oZoom.Pause 

3::  ;	показать скрыть окно
ZoomHide:
	ZoomShow(oZoom.Show := !oZoom.Show)
	return
	
Escape:: ExitApp 

ZoomCreate() {
	oZoom.Zoom := 8
	oZoom.Mark := "Cross"
	oZoom.MemoryZoomSize := 0
	oZoom.GuiMinW := 306
	oZoom.GuiMinH := 351
	FontSize := (A_ScreenDPI = 120 ? 10 : 12)
	
	GuiW := 306, GuiH := 351
	
	Gui, Zoom: -DPIScale +Border  +LabelZoomOn +HWNDhGui +AlwaysOnTop -Caption +E0x08000000  ;	
	Gui, Zoom: Color, F0F0F0
	Gui, Zoom: Add, Text, hwndhStatic +Border
	DllCall("SetClassLong", "Ptr", hGui, "int", -26
	, "int", DllCall("GetClassLong", "Ptr", hGui, "int", -26) | 0x20000)

	Gui, LW: -Caption +E0x80000 +AlwaysOnTop +ToolWindow +HWNDhLW +Owner%hGui% +E0x08000000   ;	+E0x08000000           E0x20
	Gui, LW: Show, NA w0 h0
	
	Gui, ZoomTB: +HWNDhTBGui -Caption -DPIScale +Parent%hGui% +E0x08000000 +0x40000000 -0x80000000
	Gui, ZoomTB: Color, F0F0F0
	Gui, ZoomTB: Font, s%FontSize%
	Gui, ZoomTB: Add, Slider, hwndhSliderZoom gSliderZoom x8 Range1-50 w152 Center AltSubmit NoTicks, % oZoom.Zoom
	Gui, ZoomTB: Add, Text, hwndhTextZoom Center x+10 yp+3 w36, % oZoom.Zoom
	Gui, ZoomTB: Font
	Gui, ZoomTB: Add, Button, hwndhChangeMark gChangeMark x+10 yp w52, % oZoom.Mark
	Gui, ZoomTB: Add, Button, hwndhZoomHideBut gZoomHide x+10 yp, X
	Gui, ZoomTB: Show, NA x0 y0
	
	Gui, Zoom: Show, % "NA Hide xCenter yCenter w" GuiW " h" GuiH, AhkSpyZoom
	Gui, Zoom: +MinSize
	
	oZoom.hdcSrc := DllCall("GetDC", "UPtr", 0, "UPtr")
	oZoom.hDCBuf := CreateCompatibleDC() 
	oZoom.hdcMemory := CreateCompatibleDC()
	
	oZoom.hGui := hGui
	oZoom.hStatic := hStatic 
	oZoom.hTBGui := hTBGui
	oZoom.hLW := hLW
	
	oZoom.vTextZoom := hTextZoom
	oZoom.vChangeMark := hChangeMark
	oZoom.vZoomHideBut := hZoomHideBut
	oZoom.vSliderZoom := hSliderZoom
	
	SetSize()  
}

ChangeMark()  {
	Static Mark := {"Cross":"Square","Square":"Grid","Grid":"None","None":"Cross","":"None"}
	oZoom.Mark := Mark[oZoom.Mark], ChangeMarker(), Redraw()
	GuiControl, ZoomTB:, % oZoom.vChangeMark, % oZoom.Mark
	GuiControl, ZoomTB:, -0x0001, % oZoom.vChangeMark
	GuiControl, ZoomTB:, Focus, % oZoom.vTextZoom 
}

SliderZoom() {
	SetTimer, ChangeZoom, -1
}

ChangeZoom(Val = "")  {
	If Val =
		GuiControlGet, Val, ZoomTB:, % oZoom.vSliderZoom
	If (Val < 1 || Val > 50)
		Return 
	GuiControl, ZoomTB:, % oZoom.vSliderZoom, % oZoom.Zoom := Val
	GuiControl, ZoomTB:, % oZoom.vTextZoom, % oZoom.Zoom
	SetSize()
	Redraw() 
}

SetSize() {
	Static Top := 45, Left := 0, Right := 6, Bottom := 6 
	Width := oZoom.LWWidth := oZoom.GuiWidth - Left - Right
	Height := oZoom.LWHeight := oZoom.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
	
	oZoom.conX := (((conW - Width) // 2)) * -1
	oZoom.conY :=  (((conH - Height) // 2)) * -1
	
	hDWP := DllCall("BeginDeferWindowPos", "Int", 2)
	hDWP := DllCall("DeferWindowPos"
	, "Ptr", hDWP, "Ptr", oZoom.hStatic, "UInt", 0
	, "Int", Left , "Int", Top, "Int", Width + 2, "Int", Height + 2
	, "UInt", 0x0010)    ; 0x0010 := SWP_NOACTIVATE
	hDWP := DllCall("DeferWindowPos"
	, "Ptr", hDWP, "Ptr", oZoom.hTBGui, "UInt", 0
	, "Int", (oZoom.GuiWidth - oZoom.GuiMinW) / 2
	, "Int", 0, "Int", 0, "Int", 0
	, "UInt", 0x0011)    ; 0x0010 := SWP_NOACTIVATE | 0x0001 := SWP_NOSIZE 
	DllCall("EndDeferWindowPos", "Ptr", hDWP)

	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 := Round(Width / 2 - Zoom / 2)
	oZoom.yCenter := Round(Height / 2 - Zoom / 2) 
	
	ChangeMarker()
}

ChangeMarker() {
	Try GoTo % "Marker" oZoom.Mark
	
	MarkerCross: 
		oZoom.oMarkers["Cross"] := [{x:0,y:oZoom.yCenter - 1,w:oZoom.nWidthDest,h:1}
		, {x:0,y:oZoom.yCenter + oZoom.Zoom,w:oZoom.nWidthDest,h:1}
		, {x:oZoom.xCenter - 1,y:0,w:1,h:oZoom.nHeightDest}
		, {x:oZoom.xCenter + oZoom.Zoom,y:0,w:1,h:oZoom.nHeightDest}]	
		Return

	MarkerSquare:
		oZoom.oMarkers["Square"] := [{x:oZoom.xCenter - 1,y:oZoom.yCenter,w:oZoom.Zoom + 2,h:1}
		, {x:oZoom.xCenter - 1,y:oZoom.yCenter + oZoom.Zoom + 1,w:oZoom.Zoom + 2,h:1}
		, {x:oZoom.xCenter - 1,y:oZoom.yCenter + 1,w:1,h:oZoom.Zoom}
		, {x:oZoom.xCenter + oZoom.Zoom,y:oZoom.yCenter + 1,w:1,h:oZoom.Zoom}]
		Return
		
	MarkerGrid:
		If (oZoom.Zoom = 1) {
			Gosub MarkerSquare
			Return oZoom.oMarkers["Grid"] := oZoom.oMarkers["Square"]
		}
		oZoom.oMarkers["Grid"] := [{x:oZoom.xCenter - oZoom.Zoom,y:oZoom.yCenter - oZoom.Zoom,w:oZoom.Zoom * 3,h:1}
		, {x:oZoom.xCenter - oZoom.Zoom,y:oZoom.yCenter,w:oZoom.Zoom * 3,h:1}
		, {x:oZoom.xCenter - oZoom.Zoom,y:oZoom.yCenter + oZoom.Zoom,w:oZoom.Zoom * 3,h:1}
		, {x:oZoom.xCenter - oZoom.Zoom,y:oZoom.yCenter + oZoom.Zoom * 2,w:oZoom.Zoom * 3,h:1}
		, {x:oZoom.xCenter - oZoom.Zoom,y:oZoom.yCenter - oZoom.Zoom,w:1,h:oZoom.Zoom * 3}
		, {x:oZoom.xCenter,y:oZoom.yCenter - oZoom.Zoom,w:1,h:oZoom.Zoom * 3}
		, {x:oZoom.xCenter + oZoom.Zoom,y:oZoom.yCenter - oZoom.Zoom,w:1,h:oZoom.Zoom * 3}
		, {x:oZoom.xCenter + oZoom.Zoom * 2,y:oZoom.yCenter - oZoom.Zoom,w:1,h:oZoom.Zoom * 3}]
		Return
}

Magnify(one = 0) {
	Static New
	If (oZoom.Show && oZoom.SIZING != 2 && !oZoom.Pause)
	{
		MouseGetPos, mX, mY, WinID
		If (WinID != oZoom.hLW && WinID != oZoom.hGui)
		{
			New := 1, oZoom.MouseX := mX, oZoom.MouseY := mY 
			UpdateWindow(oZoom.hdcSrc, mX - oZoom.nXOriginSrcOffset, mY - oZoom.nYOriginSrcOffset)
		}
	}
	Else If New
		Memory(), New := 0
	SetTimer, Magnify, -10
} 

Exit:
	ReleaseDC(oZoom.hdcSrc)
	DeleteDC(oZoom.hdcSrc) 
	DeleteDC(oZoom.hDCBuf) 
	DeleteDC(oZoom.hdcMemory) 
	GdipShutdown(pToken)
	ExitApp

ZoomShow(Show)  {
	oZoom.Show := Show
	If Show {  
		WinGetPos, WinX, WinY, WinW, , % "ahk_id" oZoom.hGui
		oZoom.LWX := WinX + 1, oZoom.LWY := WinY + 46
		Gui, Zoom: Show, % "NA Hide x" WinX " y" WinY
		Gui, LW: Show, % "NA x" oZoom.LWX " y" oZoom.LWY " w" 0 " h" 0 
		Gui, Zoom: Show, NA
		try Gui, LW: Show, % "NA x" oZoom.LWX " y" oZoom.LWY " w" oZoom.LWWidth " h" oZoom.LWHeight  
		Return
	}
	Gui,  LW: Show, % "NA w" 0 " h" 0  ;	нельзя применять Hide, иначе после появления и ресайза остаётся прозрачный след 
	; Gui,  LW: Show, NA Hide   
	Gui,  Zoom: Show, NA Hide   
}

ZoomOnSize() { 
	If A_EventInfo != 0
		Return 
	oZoom.GuiWidth := A_GuiWidth
	oZoom.GuiHeight := A_GuiHeight
	SetSize()
	Redraw()
}

	; _________________________________________________ Sizing _________________________________________________

WM_SETCURSOR(W, L, M, H) {
	Static SIZENWSE := DllCall("User32.dll\LoadCursor", "Ptr", NULL, "Int", 32642, "UPtr")
			, SIZENS := DllCall("User32.dll\LoadCursor", "Ptr", NULL, "Int", 32645, "UPtr")
			, SIZEWE := DllCall("User32.dll\LoadCursor", "Ptr", NULL, "Int", 32644, "UPtr")
	If (oZoom.SIZING = 2)
		Return
	If (W = oZoom.hGui)
	{
		MouseGetPos, mX, mY
		WinGetPos, WinX, WinY, WinW, WinH, % "ahk_id " oZoom.hLW
		If (mX > WinX && mY > WinY)
		{
			If (mX < WinX + WinW - 10)
				DllCall("User32.dll\SetCursor", "Ptr", SIZENS), oZoom.SIZINGType := "NS"
			Else If (mY < WinY + WinH - 10)
				DllCall("User32.dll\SetCursor", "Ptr", SIZEWE), oZoom.SIZINGType := "WE"
			Else
				DllCall("User32.dll\SetCursor", "Ptr", SIZENWSE), oZoom.SIZINGType := "NWSE"  
			Return oZoom.SIZING := 1
		}
	}
	Else
		oZoom.SIZING := 0, oZoom.SIZINGType := ""
}

LBUTTONDOWN(W, L, M, H) { 
	If oZoom.SIZING
	{ 
		oZoom.SIZING := 2
		SetSystemCursor("SIZE" oZoom.SIZINGType)
		SetTimer, Sizing, -1
		KeyWait LButton
		SetTimer, Sizing, Off
		RestoreCursors() 
		oZoom.SIZING := 0, oZoom.SIZINGType := ""
	}
}

Sizing() {
	MouseGetPos, mX, mY
	WinGetPos, WinX, WinY, , , % "ahk_id " oZoom.hGui
	If (oZoom.SIZINGType = "NWSE" || oZoom.SIZINGType = "WE")
		Width := " w" (mX - WinX < oZoom.GuiMinW ? oZoom.GuiMinW : mX - WinX)
	If (oZoom.SIZINGType = "NWSE" || oZoom.SIZINGType = "NS")
		Height := " h" (mY - WinY < oZoom.GuiMinH ? oZoom.GuiMinH : mY - WinY) 
	Gui, Zoom:Show, % "NA" Width . Height
	SetTimer, Sizing, -1
}

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() { 
	DllCall("SystemParametersInfo", UInt, 0x57, UInt, 0, UInt, 0, UInt, 0)  ;	SPI_SETCURSORS := 0x57
}

	; _________________________________________________ Gdip _________________________________________________

Memory() { 
	SysGet, VSX, 76
	SysGet, VSY, 77
	SysGet, VSWidth, 78
	SysGet, VSHeight, 79
	oZoom.nXOriginSrc := oZoom.MouseX - VSX, oZoom.nYOriginSrc := oZoom.MouseY - VSY
	hBM := DllCall("Gdi32.Dll\CreateCompatibleBitmap", "Ptr", oZoom.hdcSrc, "Int", VSWidth, "Int", VSHeight)
	DllCall("Gdi32.Dll\SelectObject", "Ptr", oZoom.hdcMemory, "Ptr", hBM), DllCall("DeleteObject", "Ptr", hBM)
	StretchBlt(oZoom.hdcMemory, 0, 0, VSWidth, VSHeight, oZoom.hdcSrc, VSX, VSY, VSWidth, VSHeight) 
} 

Redraw() { 
	If oZoom.Start
		UpdateWindow(oZoom.hdcMemory, oZoom.nXOriginSrc - oZoom.nXOriginSrcOffset, oZoom.nYOriginSrc - oZoom.nYOriginSrcOffset)
}

UpdateWindow(Src, X, Y) {
	WinGetPos, WinX, WinY, , , % "ahk_id" oZoom.hGui
	oZoom.LWX := WinX + 1, oZoom.LWY := WinY + 46
	hbm := CreateDIBSection(oZoom.nWidthDest, oZoom.nHeightDest, oZoom.hDCBuf)
	DllCall("SelectObject", "UPtr", oZoom.hDCBuf, "UPtr", hbm)
	StretchBlt(oZoom.hDCBuf, oZoom.conX, oZoom.conY, oZoom.nWidthDest, oZoom.nHeightDest
	, Src, X, Y, oZoom.nWidthSrc, oZoom.nHeightSrc)
	For k, v In oZoom.oMarkers[oZoom.Mark]
		StretchBlt(oZoom.hDCBuf, v.x, v.y, v.w, v.h, oZoom.hDCBuf, v.x, v.y, v.w, v.h, 0x5A0049)	; PATINVERT
	DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "UPtr", hbm, "UPtr", 0, "UPtr*", pBitmap) 
	DllCall("SelectObject", "UPtr", oZoom.hDCBuf, "UPtr", hbm)  
	DllCall("gdiplus\GdipCreateFromHDC", "UPtr", oZoom.hDCBuf, "UPtr*", G)  
	DrawImage(G, pBitmap, 0, 0, oZoom.LWWidth, oZoom.LWHeight)
	If oZoom.Show
		UpdateLayeredWindow(oZoom.hLW, oZoom.hDCBuf, oZoom.LWX, oZoom.LWY, oZoom.LWWidth, oZoom.LWHeight)
	DllCall("DeleteObject", "UPtr", hbm)
	DllCall("gdiplus\GdipDeleteGraphics", "UPtr", G)
	DllCall("gdiplus\GdipDisposeImage", "UPtr", pBitmap)
}

GdipStartup() {
	if !DllCall("GetModuleHandle", "str", "gdiplus", UPtr)
		DllCall("LoadLibrary", "str", "gdiplus")
	VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
	DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, UPtr, &si, UPtr, 0)
	Return pToken
}

GdipShutdown(pToken) {
	DllCall("gdiplus\GdiplusShutdown", UPtr, pToken)
	if hModule := DllCall("GetModuleHandle", "str", "gdiplus", UPtr)
		DllCall("FreeLibrary", UPtr, hModule)
	Return 0
}

UpdateLayeredWindow(hwnd, hdc, x, y, w, h) {
	Static pt, _ := VarSetCapacity(pt, 8)
	NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")
	Return DllCall("UpdateLayeredWindow"
					, UPtr, hwnd
					, UPtr, 0
					, UPtr, &pt
					, "int64*", w|h<<32
					, UPtr, hdc
					, "int64*", 0
					, "uint", 0
					, "UInt*", 33488896  ;	(Alpha := 255)<<16|1<<24
					, "uint", 2)
}

StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster=0x40CC0020) {  ;	0x00CC0020|0x40000000
	Return DllCall("gdi32\StretchBlt"
					, UPtr, ddc
					, "int", dx
					, "int", dy
					, "int", dw
					, "int", dh
					, UPtr, sdc
					, "int", sx
					, "int", sy
					, "int", sw
					, "int", sh
					, "uint", Raster)
}

CreateDIBSection(w, h, hdc) {
	Static bi, _ := VarSetCapacity(bi, 40, 0)
	NumPut(w, bi, 4, "uint")
	NumPut(h, bi, 8, "uint")
	NumPut(40, bi, 0, "uint")
	NumPut(1, bi, 12, "ushort")
	NumPut(0, bi, 16, "uInt")
	NumPut(32, bi, 14, "ushort")
	Return DllCall("CreateDIBSection"
					, "UPtr", hdc
					, "UPtr", &bi
					, "uint", 0
					, "UPtr*",
					, "UPtr", 0
					, "uint", 0, "UPtr")
}

DrawImage(pGraphics, pBitmap, dx, dy, dw, dh) {
	Return DllCall("gdiplus\GdipDrawImageRectRect"
				, "UPtr", pGraphics
				, "UPtr", pBitmap
				, "float", dx
				, "float", dy
				, "float", dw
				, "float", dh
				, "float", dx
				, "float", dy
				, "float", dw
				, "float", dh
				, "int", 2
				, "UPtr",
				, "UPtr", 0
				, "UPtr", 0)
}

ReleaseDC(hdc, hwnd=0) {
	Return DllCall("ReleaseDC", "UPtr", hwnd, "UPtr", hdc)
}

DeleteDC(hdc) {
	Return DllCall("DeleteDC", "UPtr", hdc)
}

CreateCompatibleDC(hdc=0) {
	Return DllCall("CreateCompatibleDC", "UPtr", hdc)
}

С AnimateWindow тоже нужен костыль в виде подмены картинкой, ведь теперь 2 окна. А вот для минимизации и восстановления оказывается достаточно +Owner, но только после восстановления, Layered начинает отбрасывать тень, так что тоже понадобится костыль. Для демо, можно у Gui Zoom убрать E0x08000000.

serzh82saratov пишет:

А Layered вроде не может быть дочерним?

Судя по справке, это не актуально начиная с 8.
https://msdn.microsoft.com/en-us/librar … s.85).aspx.

Windows 8:  The WS_EX_LAYERED style is supported for top-level windows and child windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.

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

18

Re: AHK: AnimateWindow и StretchBlt

serzh82saratov пишет:

И UpdateLayeredWindow может обновлять окно в текущих координатах, чтобы не указывать экранные?

Можно не указывать.

serzh82saratov пишет:

кажется как то громоздко

Поучилось убрать всё кроме CreateDIBSection, но работает так только с аеро.

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

19

Re: AHK: AnimateWindow и StretchBlt

serzh82saratov пишет:

кушает проца в 2 раза больше

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

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

20

Re: AHK: AnimateWindow и StretchBlt

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

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

21

Re: AHK: AnimateWindow и StretchBlt

А зачем тебе это Animate Window? Для рюшечек? Не проще в контексте контрола static рисовать?

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

22

Re: AHK: AnimateWindow и StretchBlt

Не понял, ты сейчас про какой мой пост?

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

23

Re: AHK: AnimateWindow и StretchBlt

Так чем Layered Window лучше, чем просто в static рисовать?

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

24

Re: AHK: AnimateWindow и StretchBlt

Картинка статичная, вообще не мелькает. И не надо отслеживать WM_Paint, а с ним мельканий никак не избежать.

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

25 (изменено: serzh82saratov, 2018-01-08 15:12:25)

Re: AHK: AnimateWindow и StretchBlt

WM_Paint - я про это.

Gui, +hwndhGui -Caption -DPIScale +Border
Gui, Add, Text, hwndhDevCon w222 h222 Border
Gui, Show

hdcDest := DllCall("GetDC", Ptr, hDevCon, Ptr)
hdcSrc := DllCall("GetDC", Ptr, 0, Ptr)
StretchBlt(hdcDest, 0, 0, 222, 222, hdcSrc, 0, 0, 111, 111)
Sleep 555
Gui, Show, % "x" A_ScreenWidth - 100
Sleep 555
Gui, Show, % "xCenter"
Return

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

26

Re: AHK: AnimateWindow и StretchBlt

Не совсем понял, откуда мелькания. Я вчера набросал вариант со static со StretchBlt, никаких мельканий не заметил. Правда, с aero на другую тему переключаться не пробовал.

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

27

Re: AHK: AnimateWindow и StretchBlt

Ну тогда приведи свой код.

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

28

Re: AHK: AnimateWindow и StretchBlt

Ок, вечером.

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

29

Re: AHK: AnimateWindow и StretchBlt

#NoEnv
SetBatchLines, -1

Gui, +hwndhGui +AlwaysOnTop -DPIScale
Gui, Margin, 20, 20
Gui, Add, Pic, w351 h351 hwndhPic border
Gui, Show,, Zoom: 5
oZoom := new Zoom(hPic)
Return

GuiClose:
   oZoom := ""
   ExitApp
   
#If WinActive("ahk_id" . hGui)
WheelUp:: 
WheelDown:: Gui, Show,, % "Zoom: " . oZoom.ChangeZoom(A_ThisHotkey = "WheelUp")
#If

class Zoom  {
   __New(hPic)  {
      CoordMode, Mouse
      this.hParent := DllCall("GetParent", Ptr, hPic)
      WinGetPos,,, W, H, ahk_id %hPic%
      this.PicWidth := W, this.PicHeight := H
      this.CurrentZoom := 5
      this.hDC := DllCall("GetDC", Ptr, hPic, Ptr)
      this.hSDC := DllCall("GetDC", Ptr, 0, Ptr)
      this.oMDC := new this.CompatibleDC(this.hDC, W, H)
      this.hMDC := this.oMDC.hCDC
      
      this.timer := timer := ObjBindMethod(this, "Draw")
      SetTimer, % timer, 10
      OnMessage( 0xF, ObjBindMethod(this, "WM_PAINT") )
   }
   
   __Delete()  {
      timer := this.timer
      SetTimer, % timer, Delete
      this.oMDC := ""
      DllCall("DeleteDC", Ptr, this.hDC)
      DllCall("DeleteDC", Ptr, this.hSDC)
   }
      
   Draw()  {
      MouseGetPos, mouse_x, mouse_y
      w := this.PicWidth/this.CurrentZoom
      h := this.PicHeight/this.CurrentZoom
      DllCall("StretchBlt", Ptr, this.hDC, Int, 0, Int, 0, Int, this.PicWidth - 2, int, this.PicHeight - 2
                          , Ptr, this.hSDC, Int, mouse_x - w/2, Int, mouse_y - h/2, Int, w, Int, h, UInt, SRCCOPY := 0xCC0020)
      this.BitBlt(this.hMDC, this.hDC)
   }
   
   BitBlt(ddc, sdc)  {
      DllCall("BitBlt", Ptr, ddc, Int, 0, Int, 0, Int, this.PicWidth, Int, this.PicHeight
                      , Ptr, sdc, Int, 0, Int, 0, UInt, SRCCOPY := 0xCC0020)
   }
   
   ChangeZoom(mode)  {
      this.CurrentZoom += (mode ? 1 : -1)
      (this.CurrentZoom < 1 && this.CurrentZoom := 1)
      Return this.CurrentZoom
   }
   
   WM_PAINT(wp, lp, msg, hwnd)  {
      if (this.hParent = hwnd)  {
         timer := ObjBindMethod(this, "BitBlt", this.hDC, this.hMDC)
         SetTimer, % timer, -10
      }
   }
   
   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

30 (изменено: serzh82saratov, 2018-01-08 17:09:15)

Re: AHK: AnimateWindow и StretchBlt

Всё равно немного заметен вертикальный рассинхрон и WM_PAINT в классической теме. И в моём случае this.hMDC это DC всего экрана, и WM_PAINT происходит медленне, плюс в цикле Draw уже неполучится каждый раз его сохранять.

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

31

Re: AHK: AnimateWindow и StretchBlt

Ещё не понятно, что у тебя показывается у краёв экрана.

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

32

Re: AHK: AnimateWindow и StretchBlt

serzh82saratov пишет:

Всё равно немного заметен вертикальный рассинхрон и WM_PAINT.

Это не понял.

serzh82saratov пишет:

И в моём случае this.hMDC это DC всего экрана

А зачем это? Для перерисовки картинки нужен только её контент.

serzh82saratov пишет:

Ещё не понятно, что у тебя показывается у краёв экрана.

Ну просто не учтена эта ситуация, думаю, вопрос на пару строк кода.

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

33

Re: AHK: AnimateWindow и StretchBlt

teadrinker пишет:

Это не понял.

Вертикальная синхронизация. Картинка разъежается по горизонтали, это в основном в классической теме, и не сильно заметно, но изредка режет глаз.

teadrinker пишет:

А зачем это? Для перерисовки картинки нужен только её контент.

Ну а если я захочу поставить на паузу, растянуть окно, и уменьшить зум, что я увижу?

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

34

Re: AHK: AnimateWindow и StretchBlt

teadrinker пишет:

Это не понял.

Про WM_PAINT я отвечал.

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

35

Re: AHK: AnimateWindow и StretchBlt

serzh82saratov пишет:

Ну а если я захочу поставить на паузу, растянуть окно, и уменьшить зум, что я увижу?

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

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

36

Re: AHK: AnimateWindow и StretchBlt

Так экран уже поменяется 100 раз.

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

37

Re: AHK: AnimateWindow и StretchBlt

В моём варианте, если ты заметил, данные берутся непосредственно с DC экрана.

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

38

Re: AHK: AnimateWindow и StretchBlt

Так всё же что это даёт?

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

39

Re: AHK: AnimateWindow и StretchBlt

Прежде всего скорость. И всё время свежие данные.

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

40

Re: AHK: AnimateWindow и StretchBlt

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

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

41

Re: AHK: AnimateWindow и StretchBlt

Так лучше иметь свежие, их всегда сохранить можно.

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