GDI+ standard library 1.45 by tic

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: GDI+ standard library 1.45 by tic

25 Jun 2015, 14:36

Libs sind schön aber ich muss sagen dass die sind manchmal auch zu groß... :/ :)

@tic can't wait for the class based lib to be complete :D nice work
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: GDI+ standard library 1.45 by tic

03 Jul 2015, 14:00

@tic Did you ever get a satisfactory solution for throwing errors when you try to call a non-existent method on a class?
User avatar
dd900
Posts: 121
Joined: 27 Oct 2013, 16:03

Re: GDI+ standard library 1.45 by tic

04 Jul 2015, 08:00

Im having trouble getting the BRA example to work.
Gdip wrote:File loading error!, Could not load the image specified
Using latest AHK_L/H
I've tried both Gdip.ahk and Gdip_all.ahk
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: GDI+ standard library 1.45 by tic

05 Jul 2015, 01:46

GeekDude

I would just implement something similar to Coco suggested:

Code: Select all

mc := new MyClass()
mc.MyMethod
mc.MyMethod1()

class ErrorClass
{
	__Call(method)
	{
		throw Exception("Non-existent method", -1, method)
	}
}

class MyClass extends ErrorClass
{
	MyMethod()
	{
		MsgBox, MyMethod
	}
}
and remove it for production.

dd900

Yes, there have been several changes to ahk that break this part. I have working fragments, but didn't rewrite it all. I am still undecided on whether to use bra or zip (insert some joke) for Gdip2 (But only if there is enough interest in that library being completed). It currently uses a messy zip implementation.
If you want to use it and want a specific function to work, I'm sure I've already fixed it for personal use as it is fast for reading multiple images.
User avatar
dd900
Posts: 121
Joined: 27 Oct 2013, 16:03

Re: GDI+ standard library 1.45 by tic

05 Jul 2015, 13:08

I would have immediate use for your functions. I have 4 sets of 6 images that I am using for animations. So rather than distributing a ton of img resources with my script I was trying to use your example to store the images in one file. I would very much appreciate if you would be willing to share a working example of how to create and use a :lol: BRA/ZIP :lol: file for animation purposes. Thank you.
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: GDI+ standard library 1.45 by tic

05 Jul 2015, 13:32

tic

I'm not joedf, but thanks for the info anyways :P
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: GDI+ standard library 1.45 by tic

05 Jul 2015, 16:01

GeekDude wrote:tic

I'm not joedf, but thanks for the info anyways :P
Heh sorry...I did know that, but it was 2 am. My mind must be going :)
samardac
Posts: 212
Joined: 30 Nov 2014, 13:36

Re: GDI+ standard library 1.45 by tic

09 Jul 2015, 11:27

How to add control to layered GUI?
I want to make gui using GDI+ Librery and then add Pictures(Gui Pictures for buttons).
This is code, another words how to add controls like Pictures to it:

Code: Select all

; gdi+ ahk tutorial 3 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to take make a gui from an existing image on disk
; For the example we will use png as it can handle transparencies. The image will also be halved in size

#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

; 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()

; If the image we want to work with does not exist on disk, then download it...
If !FileExist("background.png")
UrlDownloadToFile, http://www.autohotkey.net/~tic/background.png, background.png

; Get a bitmap from the image
pBitmap := Gdip_CreateBitmapFromFile("background.png")

; Check to ensure we actually got a bitmap from the file, in case the file was corrupt or some other error occured
If !pBitmap
{
	MsgBox, 48, File loading error!, Could not load the image specified
	ExitApp
}

; Get the width and height of the bitmap we have just created from the file
; This will be the dimensions that the file is
Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap)

; 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
; We are creating this "canvas" at half the size of the actual image
; We are halving it because we want the image to show in a gui on the screen at half its dimensions
hbm := CreateDIBSection(Width//2, Height//2)

; 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)

; We do not need SmoothingMode as we did in previous examples for drawing an image
; Instead we must set InterpolationMode. This specifies how a file will be resized (the quality of the resize)
; Interpolation mode has been set to HighQualityBicubic = 7
Gdip_SetInterpolationMode(G, 7)

; DrawImage will draw the bitmap we took from the file into the graphics of the bitmap we created
; We are wanting to draw the entire image, but at half its size
; Coordinates are therefore taken from (0,0) of the source bitmap and also into the destination bitmap
; The source height and width are specified, and also the destination width and height (half the original)
; Gdip_DrawImage(pGraphics, pBitmap, dx, dy, dw, dh, sx, sy, sw, sh, Matrix)
; d is for destination and s is for source. We will not talk about the matrix yet (this is for changing colours when drawing)
Gdip_DrawImage(G, pBitmap, 0, 0, Width//2, Height//2, 0, 0, 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
; So this will position our gui at (0,0) with the Width and Height specified earlier (half of the original image)
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width//2, Height//2)


; 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)

; The bitmap we made from the image may be deleted
Gdip_DisposeImage(pBitmap)
Return

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

Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp
Return
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: GDI+ standard library 1.45 by tic

20 Jul 2015, 11:46

Hi samardac

You will need to draw the controls yourself and handle user interaction. I have posted examples around that demonstrate this.
A simple way to handle an image that has a click handler is to create an object with the image, and its coordinates, then poll the mouses position and lbutton state, and perform actions based upon the result.

I have integrated this by default into Gdip2 so that custom controls can be added and handled easily, but I am unsure of the level of interest in this project.
User avatar
dd900
Posts: 121
Joined: 27 Oct 2013, 16:03

Re: GDI+ standard library 1.45 by tic

20 Jul 2015, 16:58

tic wrote:I have integrated this by default into Gdip2 so that custom controls can be added and handled easily, but I am unsure of the level of interest in this project.
Interest level = :dance: :superhappy:
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: GDI+ standard library 1.45 by tic

20 Jul 2015, 17:07

tic wrote:Hi samardac

You will need to draw the controls yourself and handle user interaction. I have posted examples around that demonstrate this.
A simple way to handle an image that has a click handler is to create an object with the image, and its coordinates, then poll the mouses position and lbutton state, and perform actions based upon the result.

I have integrated this by default into Gdip2 so that custom controls can be added and handled easily, but I am unsure of the level of interest in this project.
OnMessage for WM_LBUTTONDOWN and WM_MOUSEMOVE are a lot more graceful than polling
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: GDI+ standard library 1.45 by tic

20 Jul 2015, 17:20

GeekDude wrote:OnMessage for WM_LBUTTONDOWN and WM_MOUSEMOVE are a lot more graceful than polling
I recommend to not use this for gdi+ layered window manipulation unless the user is requiring very simple triggers. Neither of those messages will play nicely with other actions as they are not intended to interact with a custom window that does not implement standard controls, and also you will have to muddy your scope by implementing global variables.

Edit:
Gdip2 implements a draw routine that will be called upon a state machine to redraw all of your "objects" every poll, based upon triggers and external states, similar to OpenGl, Directx etc.
It calls SetTimer on a function instance:
[v1.1.20+]: If not a valid label name, this parameter can be the name of a function, or a single variable reference containing a function object. For example, SetTimer %funcobj%, 1000 or SetTimer % funcobj, 1000. Other expressions which return objects are currently unsupported.
samardac
Posts: 212
Joined: 30 Nov 2014, 13:36

Re: GDI+ standard library 1.45 by tic

21 Jul 2015, 00:58

tic,
Thank you very much, I just working on one project where I need GDI gui with buttons, but now have to pause it a bit, so when I''ll back to it I'll ask you some questions.
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: GDI+ standard library 1.45 by tic

21 Jul 2015, 10:41

Could you explain the scope issues a bit more in depth? I'm not sure what you mean by that.
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: GDI+ standard library 1.45 by tic

21 Jul 2015, 11:23

GeekDude wrote:Could you explain the scope issues a bit more in depth? I'm not sure what you mean by that.

Hi, apologies, you are correct, the scope can be maintained.
I had not realised that OnMessage had also been changed in v1.1.20 as well as SetTimer.
Thanks for pointing this out to me. Here is a non-gdi+ example:

Code: Select all

#SingleInstance Force

myc := new MyClass()
return

class MyClass
{
	LButtonDown := false
	LastMousePos := { X: -1, Y: -1 }
	LastClickPos := { X: -1, Y: -1 }
	
	__New()
	{
		Gui, 1: Show, w400 h400	; Not like this. Would actually create a window contained in this class. Just for testing
		fn := this.MsgHandler.Bind(this, {})
		OnMessage(0x200, fn)	;WM_MOUSEMOVE
		OnMessage(0x201, fn)	;WM_LBUTTONDOWN
		OnMessage(0x202, fn)	;WM_LBUTTONUP
	}
	
	MsgHandler(t, wParam, lParam, msg, hwnd)
	{
		if (msg = 0x200)
		{
			this.LastMousePos := { X: lParam & 0xFFFF, Y: lParam >> 16 }
		}
		else if (msg = 0x201)
		{
			this.LButtonDown := true
			this.LastClickPos := this.LastMousePos
		}
		else if (msg = 0x202)
		{
			this.LButtonDown := false
		}
		
		if (this.LastClickPos.X != -1)
			Tooltip, % "Last clicked position: (" this.LastClickPos.X ", " this.LastClickPos.Y ")"
	}
}
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: GDI+ standard library 1.45 by tic

03 Aug 2015, 00:53

Hey tic,

I found your old function Write 2 digit numbers to the system tray icon.

I test the script on the botton of the page and it only writes the numbers, without a visible Icon.

Is it possible to write numbers over an Icon like this?
Image

(ps download link is broken ahk.net)

Edit: Working on it atm...
(Source: tba)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
tic
Posts: 92
Joined: 03 Nov 2014, 03:10

Re: GDI+ standard library 1.45 by tic

11 Aug 2015, 14:48

jNizM: We can do this by using Gdip_TextToGraphics, and then using Shell_NotifyIcon. Someone will need to work out the new structure size of NOTIFYICONDATA to get it to work in AHK_L

https://msdn.microsoft.com/en-us/librar ... s.85).aspx
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
kon
Posts: 1756
Joined: 29 Sep 2013, 17:11

Re: GDI+ standard library 1.45 by tic

11 Aug 2015, 15:04

tic wrote:Someone will need to work out the new structure size of NOTIFYICONDATA to get it to work in AHK_L
Quite a while ago I asked for help doing just this. just me calculated the new structure, see here. Note that in his next post he made a small correction: offIcon := offFlags + 4 + A_PtrSize.
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: GDI+ standard library 1.45 by tic

12 Aug 2015, 11:55

jNizM had presented me with some pretty functional code in the IRC. It used raw dllcalls instead of tic's wrapper. I changed it to using the wrapper, and it seems to be working pretty well on both 32 and 64 bit. What do you think of the code? I get the feeling that I did something wrong, especially since I couldn't get Gdip_CreateBitmapFromFile to work how I wanted.

Code: Select all

#NoEnv

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

NotifyIcon := new Notify()
Sleep, 1000

loop, 10
{
	NotifyIcon.SetText(A_Index-1)
	Sleep, 500
}
return

Exit:
Gdip_Shutdown(pToken)
ExitApp
return


Class Notify
{
	__New(IconFont="Verdana", IconSize=16)
	{
		this.IconFont := IconFont, this.IconSize := IconSize
		
		;this.pBitmapIcon := Gdip_CreateBitmapFromFile(A_AhkPath)
		DllCall("shell32.dll\SHExtractIconsW", "Str", A_AhkPath
		, "Int", 0, "Int", IconSize, "Int", IconSize
		, "Ptr*", hIcon, "UInt*", 0, "UInt", 1, "UInt", 0)
		this.pBitmapIcon := Gdip_CreateBitmapFromHICON(hIcon)
		DestroyIcon(hIcon)
		
		this.pBitmap := Gdip_CreateBitmap(IconSize, IconSize)
		this.G := Gdip_GraphicsFromImage(this.pBitmap)
		this.pBrush := Gdip_BrushCreateSolid(0xFF5555FF)
	}
	
	SetText(String)
	{
		Gdip_GraphicsClear(this.G, 0x00000000)
		Gdip_DrawImage(this.G, this.pBitmapIcon)
		
		; Draw the "bubble"
		Gdip_FillRectangle(this.G, this.pBrush, 5, 6, 11, 9)
		Gdip_FillRectangle(this.G, this.pBrush, 6, 5, 9, 11)
		
		Gdip_TextToGraphics(this.G, String, "x7 y5 s8 cFFFFFFFF", this.IconFont)
		
		hIcon := Gdip_CreateHICONFromBitmap(this.pBitmap)
		this.SetIcon(hIcon)
		DestroyIcon(hIcon)
	}
	
	SetIcon(hIcon)
	{
		static NIM_MODIFY := 1, NIF_ICON := 2, NOTIFYICONDATA
		, Size := VarSetCapacity(NOTIFYICONDATA, (A_PtrSize == 8) ? 976 : 956, 0)
		Addr := NumPut(Size, NOTIFYICONDATA, 0,           "UInt") ; UINT cbSize
		Addr := NumPut(A_ScriptHwnd, Addr+0, A_PtrSize-4, "UPtr") ; HWND  hWnd
		Addr := NumPut(1028,         Addr+0, 0,           "UInt") ; UINT  uID
		Addr := NumPut(NIF_ICON,     Addr+0, 0,           "UInt") ; UINT  uFlags
		Addr := NumPut(hIcon,        Addr+0, A_PtrSize,   "UPtr") ; HICON hIcon
		DllCall("shell32.dll\Shell_NotifyIcon", "UInt", NIM_MODIFY, "UPtr", &NOTIFYICONDATA)
	}
	
	__Delete()
	{
		Gdip_DeleteBrush(this.pBrush)
		Gdip_DeleteGraphics(this.G)
		Gdip_DisposeImage(this.pBitmap)
		Gdip_DisposeImage(this.pBitmapIcon)
	}
}
mikemonk
Posts: 3
Joined: 29 Aug 2015, 16:14

Re: GDI+ standard library 1.45 by tic

29 Aug 2015, 16:36

I am not able to get his to run. I am on v 1.1.22.04 on a Windows 8 machine.

I've tried gdip, gdip_all, running as administrators, and then compiling it and running.

No matter what I've tried, nothing shows in the tray, and I get an error when attempting to run this: http://www.autohotkey.com/board/topic/4 ... -07122014/

Any help would be greatly appreciated.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 64 guests