showGif()

Post AHK_H specific scripts & libraries and discuss the usage and development of HotKeyIt's fork/branch
arcticir
Posts: 694
Joined: 17 Nov 2013, 11:32

showGif()

06 Jul 2017, 01:02

Forum has two ways to load GIF, ActiveX takes up too much memory, AniGIF.dll performance is very slow, loading large files is a nightmare.

ShowGif() to solve the above two issues,
Its drawback is the use of "SetTimer_", we all know that it is not very accurate.


Code: Select all

VarSetCapacity(GdiplusStartupInput,3*A_PtrSize,0),NumPut(1,GdiplusStartupInput ,0,"UInt")
GdiplusStartup(getvar(token:=0), &GdiplusStartupInput, 0)

k:=GuiCreate()
f:=showGif(k.hwnd,"D:\float\Synch\Picture\92e8647agy1fcmebv0skdg20aw0cdx6q.gif")
k.show("w" f.width " h" f.height)
MsgBox "destroy gif"
f:=""
return


showGif(hwnd,img:="",w:="",h:="",x:=0,y:=0){
	if A_EventInfo
	{
		KillTimer(0,w)
		if isobject((this:=object(A_EventInfo))) and isobject(this.gui)
		{
			t:=ahktime(),GdipImageSelectActiveFrame(this.pBitmap,this.ad,id:=this.id++)
			,GdipDrawImageRectRectI(this.G,this.pBitmap,0,0,this.width,this.height,0,0,this.gifWidth,this.gifHeight,2)
			,UpdateLayeredWindow(this.hwnd,0,this.pt[],getvar(temp1:=this.width|this.height<<32),this.hdc, getvar(temp2:=0),0,getvar(temp3:=255<<16|1<<24),2)
			,this.st:=SetTimer_(0,0,Abs(this.delay[id]- (ahktime(t)*1000)),this.rc)
			if this.id=this.count
				this.id:=0

		}
	} else if isobject(hwnd)
	{
		f:=hwnd,KillTimer(0,f.st),(f.delete("gui").Destroy())
		GlobalFree(f.rc),SelectObject(f.hdc, f.obm)
		DeleteObject(f.hbm),DeleteDC(f.hdc),GdipDeleteGraphics(f.G),GdipDisposeImage(f.pBitmap)
	}
	else 
	{
		this:={gui:gui:=GuiCreate("+E0x80000 +Parent" hwnd),id:1,x:x,y:y,Base:{__Delete: Func("showGif")},pt:pt:=Struct("x,y"),hwnd:gui.hwnd},gui.show("x" x " y" y)	
		GdipCreateBitmapFromFile(&img,getvar(pBitmap:=0))
		GdipGetImageDimension(pBitmap,__w:=getvar(width:=0), __h:=getvar(height:=0))
		this.gifwidth:=width:=NumGet(__w,"Float"),this.gifheight:=height:=NumGet(__h,"Float")
		this.width:=w?w:width,this.height:=h?h:height,VarSetCapacity(bi, 40, 0)
		,NumPut(this.width,bi,4),NumPut(this.height,bi,8),NumPut(40, bi, 0),NumPut(1,bi,12,"ushort"),NumPut(0, bi, 16),NumPut(32, bi, 14, "ushort")
		this.hbm:=hbm := CreateDIBSection( hdc:=GetDC(), &bi),ReleaseDC(0,hdc)
		this.hdc:=hdc := CreateCompatibleDC(),this.obm :=obm := SelectObject(hdc, hbm)
		GdipCreateFromHDC(hdc,getvar(G:=0)),GdipSetInterpolationMode(this.G:=G, 7)
		GdipImageGetFrameDimensionsCount(pBitmap,getvar(frameDimensions:=0))
		this.SetCapacity("dimensionIDs", 32)
		GdipImageGetFrameDimensionsList(pBitmap,this.ad:=this.GetAddress("dimensionIDs"), frameDimensions)
		GdipImageGetFrameCount(pBitmap,this.ad,getvar(count:=0))
		this.pBitmap:=pBitmap,this.count:=count,this.hdc:=hdc
		GdipGetPropertyItemSize(pBitmap, 0x5100, getvar(ItemSize:=0))
		VarSetCapacity(Item, ItemSize,0)
		GdipGetPropertyItem(pBitmap,0x5100, ItemSize, &Item)
		PropLen := NumGet(Item, 4,"UInt"),PropVal := NumGet(Item, 8 + A_PtrSize, "UPtr")
		this.delay :=r := [],pt.x:=this.x,pt.y:=this.y
		Loop PropLen//4
			r[A_Index-1] := (n := NumGet(PropVal+0, (A_Index-1)*4, "UInt"))?n * 10:100
		GdipImageSelectActiveFrame(pBitmap,this.ad,0)
		GdipDrawImageRectRectI(G,pBitmap,0,0,this.width,this.height,0,0,width,height,2)
		UpdateLayeredWindow(this.hwnd,0,pt[],getvar(temp1:=this.width|this.height<<32),this.hdc, getvar(temp2:=0),0,getvar(temp3:=255<<16|1<<24),2)
		this.rc		:=	RegisterCallback("showGif","F",4,&this)
		this.st		:=	SetTimer_(0,0,Abs(this.delay[0]),this.rc)
		return this
	}
}


ahkTime(s:=0,i:=6){
	static r:=(DllCall("QueryPerformanceFrequency",Int64P,r),r)
	DllCall("QueryPerformanceCounter",Int64P,n)
	if !i
	{
		p:=s/1000*r,n2:=n,c:=A_IsCritical,Critical("on")
		if s>15
			sleep(((s-5)//15)*15)
		while ((n2-n)<p)
			DllCall("QueryPerformanceCounter", "Int64P", n2)
		Return (Critical("c"),Round((n2-n)/r, 6))
	}
	Return (s ? Round((n-s)/r, i) : n)
}
Last edited by arcticir on 06 Jul 2017, 02:05, edited 1 time in total.
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: showGif()

06 Jul 2017, 01:04

I'm not a _H guy, but what' wrong with Gui, Add, Picture?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
arcticir
Posts: 694
Joined: 17 Nov 2013, 11:32

Re: showGif()

06 Jul 2017, 01:16

Picture control does not play GIF
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: showGif()

06 Jul 2017, 01:39

Ahh ok.. never tried it before :D
Glad you found a better working solution =)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: showGif()

06 Jul 2017, 02:52

Hello arcticir.
Unfortunately, I get an error :cry:

Code: Select all

Error:  Could not create Gui.

	Line#
	030: {
	031: f:=hwnd,KillTimer(0,f.st),(f.delete("gui").Destroy())
	032: GlobalFree(f.rc),SelectObject(f.hdc, f.obm)
	033: DeleteObject(f.hbm),DeleteDC(f.hdc),GdipDeleteGraphics(f.G),GdipDisposeImage(f.pBitmap)
	034: }
	035: Else
	036: {
--->	037: this:={gui:gui:=GuiCreate("+E0x80000 +Parent" hwnd),id:1,x:x,y:y,Base:{__Delete: Func("showGif")},pt:pt:=Struct("x,y"),hwnd:gui.hwnd},gui.show("x" x " y" y)
	038: GdipCreateBitmapFromFile(&img,getvar(pBitmap:=0))
	039: GdipGetImageDimension(pBitmap,__w:=getvar(width:=0), __h:=getvar(height:=0))
	040: this.gifwidth:=width:=NumGet(__w,"Float"),this.gifheight:=height:=NumGet(__h,"Float")
	041: this.width:=w?w:width,this.height:=h?h:height,VarSetCapacity(bi, 40, 0),NumPut(this.width,bi,4),NumPut(this.height,bi,8),NumPut(40, bi, 0),NumPut(1,bi,12,"ushort"),NumPut(0, bi, 16),NumPut(32, bi, 14, "ushort")
	043: this.hbm:=hbm := CreateDIBSection( hdc:=GetDC(), &bi),ReleaseDC(0,hdc)
	044: this.hdc:=hdc := CreateCompatibleDC(),this.obm :=obm := SelectObject(hdc, hbm)
	045: GdipCreateFromHDC(hdc,getvar(G:=0)),GdipSetInterpolationMode(this.G:=G, 7)

The current thread will exit.
I changed the gif to an existing one. And just downloaded the latest ahk_h v2.
Also,
ahkTime() wrote:

Code: Select all

Critical("c")

Here is another creative gif script, for anyone interested, Laughing Man.
arcticir
Posts: 694
Joined: 17 Nov 2013, 11:32

Re: showGif()

07 Jul 2017, 10:28

Sorry, I can not reproduce this error.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: showGif()

07 Jul 2017, 11:31

I removed +parent" hwnd and did DllCall("SetParent", "Ptr", gui.hwnd, "Ptr", hwnd, "Ptr"), I get no error and the gui shows with correct dimensions but no image :think:
Spoiler
arcticir
Posts: 694
Joined: 17 Nov 2013, 11:32

Re: showGif()

08 Jul 2017, 04:15

SetParent will destroy child window properties.
titep
Posts: 31
Joined: 14 Nov 2015, 09:01

Re: showGif()

17 Jul 2018, 21:31

The example script return error , even added #Include Gdip.ahk

---------------------------
ShowGif.ahk
---------------------------
Error: Call to nonexistent function.

Specifically: GdiplusStartup(getvar(token:=0), &GdiplusStartupInput, 0)

Line#
003: VarSetCapacity(GdiplusStartupInput,3*A_PtrSize,0),NumPut(1,GdiplusStartupInput ,0,"UInt")
---> 004: GdiplusStartup(getvar(token:=0), &GdiplusStartupInput, 0)
006: k := GuiCreate()
007: f := showGif(k.hwnd, A_ScriptDir "\NhatMinh.gif")
008: k.show("w" f.width " h" f.height)
009: MsgBox,"destroy gif"
010: f := ""
011: Return
014: {

The program will exit.
---------------------------
OK
---------------------------

Return to “AutoHotkey_H”

Who is online

Users browsing this forum: No registered users and 16 guests