GDI+ standard library 1.45 by tic

Post your working scripts, libraries and tools for AHK v1.1 and older
jonathan scott james
Posts: 42
Joined: 05 Apr 2016, 01:56

Re: GDI+ standard library 1.45 by tic

19 Apr 2018, 07:24

this actually works .. i discovered you can only name your gui 1: or just leave it blank, or you cant exit app without back clicking the t ray and selecting exit,,, also, you have to rel;eace pen or whoa,, it writes all over the titlebars and makes artifacts all over every window in the desktop and all over the screen.
but this works perfectly!!!

Code: Select all

;copyright jonathanscottjamesthegreat
x:=1,y:=1
Gui,1: +LastFound +AlwaysOnTop 
GuiHwnd := WinExist()
Gui,1: Show , H300 W1020
Gui,1: +Resize
         hDC := DllCall("GetDC", UInt, GuiHwnd)
   hCurrPen1 := DllCall("CreatePen", UInt, 0, UInt, 1, UInt, 0xd8e9EC)
   hCurrPen2 := DllCall("CreatePen", UInt, 0, UInt, 1, UInt, 0x008800)

DrawLine:
x:=x+1-1008*(x>1009)
y:=y+1-257*(y>259)

   DllCall("SelectObject", UInt,hdc, UInt,hCurrPen1)
   DllCall("gdi32.dll\MoveToEx", UInt, hdc, Uint,x, Uint, 1,   Uint, 0 )
   DllCall("gdi32.dll\LineTo",    UInt,hdc, Uint,x, Uint, 261, Uint, 0 )
   DllCall("gdi32.dll\MoveToEx", UInt, hdc, Uint,Old_x, Uint, Old_y, Uint, 0 )

   DllCall("SelectObject", UInt,hdc, UInt,hCurrPen2)
   DllCall("gdi32.dll\LineTo", UInt,hdc,Uint,x,Uint,y)

Old_x:=x,Old_y:=y
goto DrawLine

esc::
GuiClose:
DllCall("DeleteObject", UInt,hCurrPen1)
DllCall("DeleteObject", UInt,hCurrPen2)
DllCall("ReleaseDC", UInt, 0, UInt, hDC)
exitapp
jonathan scott james
Posts: 42
Joined: 05 Apr 2016, 01:56

Re: GDI+ standard library 1.45 by tic

19 Apr 2018, 10:43

interesdting how you can assign the pen outside of the loop , but you stil need to DllCall("SelectObject", UInt,hdc, UInt,hCurrPen2) and releace. is there a way to alocate more stack? void or something?

i can't find the x on my posts .. to delete them... should i just edit them and delete the contents to void them?.
that last version of my script actually works ok. but i still want to try your include "gdi.ahk "
(xp sp3 with manually upgraded "msse.msi" so it's still active....)
(i never realized you can't make a gui anything but 1 or leave it blank...)
gregster
Posts: 8886
Joined: 30 Sep 2013, 06:48

Re: GDI+ standard library 1.45 by tic

19 Apr 2018, 11:31

No, please don't empty your posts - that is not the idea of a forum. Just leave them be - please keep the integrity of the forum intact. If you want to add something, just edit them and add a commentary (ideally, start the line with the word Edit:)
smarq8
Posts: 69
Joined: 16 Jan 2016, 00:33

Re: GDI+ standard library 1.45 by tic

22 May 2018, 09:06

i found problem with Gdip_TextToGraphics() and not working vertical alignment (vCentre|vCenter|Top|Up|Bottom|Down)
Here is my solution:

Code: Select all

replace this:
Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="", Measure=0)
whit this:
Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width=0, Height=0, Measure=0)
otherwise Width and Height variable that are needed for some equations/function pass null string instead of value so they will not working

Code: Select all

		 /*
		if (vPos = "vCentre") || (vPos = "vCenter")
			ypos += (Height-ReturnRC4)//2     // Height store nothing so equation will fail
		else if (vPos = "Top") || (vPos = "Up")
			ypos := 0                        // probably even not required because it's default setting. In this case it move string to the top of bitmap so it make no sense for me
		else if (vPos = "Bottom") || (vPos = "Down")
			ypos := Height-ReturnRC4         // it probably should increment ypos instead of store new value and also if Height is emty string then it will fail
		 */
		if (vPos = "vCentre") || (vPos = "vCenter")
			ypos += (Height-ReturnRC4)//2
		;else if (vPos = "Top") || (vPos = "Up")
		;	ypos += 0
		else if (vPos = "Bottom") || (vPos = "Down")
			ypos += Height-ReturnRC4
			

Code: Select all

Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width=0, Height=0, Measure=0)
{
	IWidth := Width, IHeight:= Height
	
	RegExMatch(Options, "i)X([\-\d\.]+)(p*)", xpos)
	RegExMatch(Options, "i)Y([\-\d\.]+)(p*)", ypos)
	RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width)
	RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height)
	RegExMatch(Options, "i)C(?!(entre|enter))([a-f\d]+)", Colour)
	RegExMatch(Options, "i)Top|Up|Bottom|Down|vCentre|vCenter", vPos)
	RegExMatch(Options, "i)NoWrap", NoWrap)
	RegExMatch(Options, "i)R(\d)", Rendering)
	RegExMatch(Options, "i)S(\d+)(p*)", Size)

	if !Gdip_DeleteBrush(Gdip_CloneBrush(Colour2))
		PassBrush := 1, pBrush := Colour2
	
	if !(IWidth && IHeight) && (xpos2 || ypos2 || Width2 || Height2 || Size2)
		return -1

	Style := 0, Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
	Loop, Parse, Styles, |
	{
		if RegExMatch(Options, "\b" A_loopField)
		Style |= (A_LoopField != "StrikeOut") ? (A_Index-1) : 8
	}
  
	Align := 0, Alignments := "Near|Left|Centre|Center|Far|Right"
	Loop, Parse, Alignments, |
	{
		if RegExMatch(Options, "\b" A_loopField)
			Align |= A_Index//2.1      ; 0|0|1|1|2|2
	}

	xpos := (xpos1 != "") ? xpos2 ? IWidth*(xpos1/100) : xpos1 : 0
	ypos := (ypos1 != "") ? ypos2 ? IHeight*(ypos1/100) : ypos1 : 0
	Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
	Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
	if !PassBrush
		Colour := "0x" (Colour2 ? Colour2 : "ff000000")
	Rendering := ((Rendering1 >= 0) && (Rendering1 <= 5)) ? Rendering1 : 4
	Size := (Size1 > 0) ? Size2 ? IHeight*(Size1/100) : Size1 : 12

	hFamily := Gdip_FontFamilyCreate(Font)
	hFont := Gdip_FontCreate(hFamily, Size, Style)
	FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
	hFormat := Gdip_StringFormatCreate(FormatStyle)
	pBrush := PassBrush ? pBrush : Gdip_BrushCreateSolid(Colour)
	if !(hFamily && hFont && hFormat && pBrush && pGraphics)
		return !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
   
	CreateRectF(RC, xpos, ypos, Width, Height)
	Gdip_SetStringFormatAlign(hFormat, Align)
	Gdip_SetTextRenderingHint(pGraphics, Rendering)
	ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)

	if vPos
	{
		StringSplit, ReturnRC, ReturnRC, |
		 
		if (vPos = "vCentre") || (vPos = "vCenter")
			ypos += (Height-ReturnRC4)//2
		;else if (vPos = "Top") || (vPos = "Up")
		;	ypos += 0
		else if (vPos = "Bottom") || (vPos = "Down")
			ypos += Height-ReturnRC4
		
		CreateRectF(RC, xpos, ypos, Width, ReturnRC4)
		ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
	}

	if !Measure
		E := Gdip_DrawString(pGraphics, Text, hFont, hFormat, pBrush, RC)

	if !PassBrush
		Gdip_DeleteBrush(pBrush)
	Gdip_DeleteStringFormat(hFormat)   
	Gdip_DeleteFont(hFont)
	Gdip_DeleteFontFamily(hFamily)
	return E ? E : ReturnRC
}
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

22 May 2018, 18:19

smarq8 wrote:i found problem with Gdip_TextToGraphics() and not working vertical alignment (vCentre|vCenter|Top|Up|Bottom|Down)
Here is my solution:

Code: Select all

replace this:
Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="", Measure=0)
whit this:
Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width=0, Height=0, Measure=0)
otherwise Width and Height variable that are needed for some equations/function pass null string instead of value so they will not working

Code: Select all

		 /*
		if (vPos = "vCentre") || (vPos = "vCenter")
			ypos += (Height-ReturnRC4)//2     // Height store nothing so equation will fail
		else if (vPos = "Top") || (vPos = "Up")
			ypos := 0                        // probably even not required because it's default setting. In this case it move string to the top of bitmap so it make no sense for me
		else if (vPos = "Bottom") || (vPos = "Down")
			ypos := Height-ReturnRC4         // it probably should increment ypos instead of store new value and also if Height is emty string then it will fail
		 */
		if (vPos = "vCentre") || (vPos = "vCenter")
			ypos += (Height-ReturnRC4)//2
		;else if (vPos = "Top") || (vPos = "Up")
		;	ypos += 0
		else if (vPos = "Bottom") || (vPos = "Down")
			ypos += Height-ReturnRC4
			
Thank you sir. I wonder if the vPos vertical alignment was added later, because there is no mention of it in Example 8 where tic describes all of the parameters for that function. In that Example 8, he does mention that the only time you'd need to pass the Width/Height params is if you want to use the percentage features of x/y/w/h.

However, how could you expect to calculate the Center or Bottom without knowing the height? if Height=0, when what is the "center"?

Can you post some examples of why you think the ypos value should be incremented? I think if someone specifies Top/Bottom then those should be absolute and override any x/y values

just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GDI+ standard library 1.45 by tic

23 May 2018, 03:51

guest3456 wrote:In that Example 8, he does mention that the only time you'd need to pass the Width/Height params is if you want to use the percentage features of x/y/w/h.
I think that's only half the truth, because they are used if w or h are not found in Options:

Code: Select all

...
	Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
	Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
...
I suggest to add error checks, for example

Code: Select all

...
	if !RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width) && (IWidth = "")
		return -1
	if !RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height) && (IHeight = "")
		return -1
...
smarq8
Posts: 69
Joined: 16 Jan 2016, 00:33

Re: GDI+ standard library 1.45 by tic

23 May 2018, 08:13

However, how could you expect to calculate the Center or Bottom without knowing the height? if Height=0, when what is the "center"?
because this function first measure boundary dimmension and them move in once of the expected side by the half of it independent of font size etc

here is resoult after modyfication

Code: Select all

o := "x" _x " y" RECT.y2 "  cffFFE900 r4  Center Top"
Gdip_TextToGraphics2(pGraphics, round(stx,dx), o) ; bottom numbers
(...)
o := "x" RECT.x1 " y" _y "  cffFFE900 r4 Right vCenter"
Gdip_TextToGraphics2(pGraphics, round(sty,dy), o) ; left numbers
screenshot.1527079696.png
screenshot.1527079696.png (7.16 KiB) Viewed 6920 times
and here is resoult for oryginal function: as you can see "Top" move text to top of my bitmap instat align coord with top of string boudaries and "vCeter" has no effect
screenshot.1527079864.png
screenshot.1527079864.png (7.2 KiB) Viewed 6920 times
@just me
I think that's only half the truth, because they are used if w or h are not found in Options:
but is still do not assign valid number in Width and Height in some cases (they are still empty in some cases). As I posted my exmaple code above then they are empty even after this code - default param is NULL and regex do not found anything and "IWidth := Width, IHeight:= Height" is at the top of the function so where from it assign any numerical value?

I alsy tried your suggestion and after that text is not even printed
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

23 May 2018, 08:54

just me wrote:
guest3456 wrote:In that Example 8, he does mention that the only time you'd need to pass the Width/Height params is if you want to use the percentage features of x/y/w/h.
I think that's only half the truth, because they are used if w or h are not found in Options:

Code: Select all

...
	Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
	Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
...
I suggest to add error checks, for example

Code: Select all

...
	if !RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width) && (IWidth = "")
		return -1
	if !RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height) && (IHeight = "")
		return -1
...
Well even if w/h aren't found in Options, everything still works fine even with the default IWidth/H values. Try changing Example 8 to this:

Code: Select all

Options := "x40 cbbffffff r4 s20 Underline Italic"                        ; no w/h in options
Gdip_TextToGraphics(G, "Tutorial 8`n`nThank you for trying this example", Options, Font)   ; no w/h passed
This works normally, but it fails with your error throw.. So i'd rather not change tic's original API


smarq8 wrote: and here is resoult for oryginal function: as you can see "Top" move text to top of my bitmap instat align coord with top of string boudaries and "vCeter" has no effect
I don't fully understand what you're saying but I think you should just calculate your coordinates differently instead of changing the TextToGraphics function. Why would you use "Top" when you want the text displayed on the bottom? All of these vertical positions Top|Bottom|vCenter should OVERRIDE any y option, in my opinion.



Here are my thoughts:
https://github.com/mmikeww/AHKv2-Gdip/issues/17
And related changes that I think:
https://github.com/mmikeww/AHKv2-Gdip/c ... 514942eee6

what do you guys think

smarq8
Posts: 69
Joined: 16 Jan 2016, 00:33

Re: GDI+ standard library 1.45 by tic

23 May 2018, 09:19

Top option does mean if you use x50 y100 then your string should by aligned by the top of its boundary so your string should be below y100, is you use Bottom option then text should be above y100 because bottom of the text is aligned to coordinates, if you use Right then it should ba on the left side of coords and so on. ofc I can calculate coordinate manually but it will be probably almost same method as in this function - measure string boundary by the Gdip_MeasureString() and then shift coordinates, but wait then what for is Bottom|Top|... options if I can't use them for better synatx ;)?
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

23 May 2018, 09:42

smarq8 wrote:Top option does mean if you use x50 y100 then your string should by aligned by the top of its boundary so your string should be below y100, is you use Bottom option then text should be above y100 because bottom of the text is aligned to coordinates, if you use Right then it should ba on the left side of coords and so on. ofc I can calculate coordinate manually but it will be probably almost same method as in this function - measure string boundary by the Gdip_MeasureString() and then shift coordinates, but wait then what for is Bottom|Top|... options if I can't use them for better synatx ;)?
Ahhhh ok I think I understand what you are saying now. However, the original function for Top used ypos=0, so I think the original intent was clear and not to do it your way. Also in the original function, Bottom changed the ypos using assignment := not increment += so I think its pretty clear that tic wanted it to be absolute. But yes the vCenter originally used increment so there is some confusion... I'm not sure what's best

Also as I mentioned in the github issue with my thought #2, you still have a problem when you specify h option:

Code: Select all

Options := "Bottom h50 cbbffffff"
Gdip_TextToGraphics(G, "Tutorial 8`n`nThank you for trying this example", Options, Font, Width, Height)

smarq8
Posts: 69
Joined: 16 Jan 2016, 00:33

Re: GDI+ standard library 1.45 by tic

23 May 2018, 10:12

untill i use it for only quick boundary align then it look ok, that why i create Gdip_TextToGraphics2() instead of overwite oryginal function and lost time in the future because no backward compatibility scripts
just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GDI+ standard library 1.45 by tic

23 May 2018, 10:37

After some re-thinking I believe that changing the default values of Width and Height to 0 might be the only option. It would make more clear what actually happens within the function. The call of CreateRectF() converts empty parameters to 0. If you change the vPos related part, existing scripts might get 'wrong' results after updating to the new version.

Edit: After some more re-thinking I believe that the function shouldn't be changed. Existing scripts might get 'wrong' results after updating to the new version.

The calculation of vcenter reminds me on GDI text functions. GDI doesn't provide an option to center multi-line text vertically. GDIP has the GdipSetStringFormatLineAlign() function which might do the job. If it is working as required, I would add a new function (e.g. Gdip_TextToGraphics2() implementing all changes (like already suggested by smarq8).
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

23 May 2018, 12:42

just me wrote: Edit: After some more re-thinking I believe that the function shouldn't be changed. Existing scripts might get 'wrong' results after updating to the new version.
This is my conclusion as well. I've summed it up with screenshots here:
https://github.com/mmikeww/AHKv2-Gdip/i ... -391436275

But I'm glad we've documented it both on the forum here and on github so other users can find this

Thank you to smarq8

User avatar
Onimuru
Posts: 107
Joined: 08 Sep 2018, 18:35
Contact:

Re: GDI+ standard library 1.45 by tic

10 Sep 2018, 11:19

Hi guys!

What is the correct method for changing the color of a GDIp layered window? I don't understand the difference between hdc and G. I'm not sure which one I'm actually drawing on. Do I need to destroy the window and recreate it with a different brush to effect a color change every time or is there an easier way?
HelderThury

Re: GDI+ standard library 1.45 by tic

09 Oct 2018, 04:58

Hello!

When I compile a ImageSearch function, from compiled returns erro 0 (not found) and a scripted returns 1.

What is wrong? Is the GDIP problem?
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

09 Oct 2018, 09:31

HelderThury wrote:Hello!

When I compile a ImageSearch function, from compiled returns erro 0 (not found) and a scripted returns 1.

What is wrong? Is the GDIP problem?
Can you paste your full script?

_Ne0n
Posts: 7
Joined: 31 Aug 2018, 08:20

Re: GDI+ standard library 1.45 by tic

17 Dec 2018, 08:47

The following code fills the window with gray and draws two rectangles.
How to draw the second rectangle transparent relative to the first rectangle?
It should be like this.
Image
Spoiler
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: GDI+ standard library 1.45 by tic

17 Dec 2018, 11:34

i dont think blitting supports this kind of layered transparency. u can pass ur graphics object around and draw to it, then render it at the end instead:

Code: Select all

#Include Gdip_All.ahk

if(!Gdip_Startup())
	msgbox % "Can't start GDI+"

Gui, -Caption +hwndhwnd +E0x80000 +AlwaysOnTop ; WS_EX_LAYERED
Gui, Show, W1 H1 Hide


w:=100,h:=100
x:=(A_ScreenWidth-w)//2
y:=(A_ScreenHeight-h)//2

hdc:=CreateCompatibleDC()
hbm:=CreateDIBSection(w, h)
obm:=SelectObject(hdc, hbm)

pGraphics := Gdip_GraphicsFromHDC(hdc)

DrawPoly(pGraphics, 0, 0, w, h, 0xFFeeeeee)
DrawPoly(pGraphics, 0, 0, w, 30, 0xFFbbeeaa)
DrawPoly(pGraphics, 40, 0, 50, 30, 0x20000000)

UpdateLayeredWindow(hwnd, hdc, x, y, w, h)
Gui, Show
return

DrawPoly(pGraphics, x, y, w, h, ARGB) {
	pBrush := Gdip_BrushCreateSolid(ARGB)
	Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h)
	Gdip_DeleteBrush(pBrush)
}
_Ne0n
Posts: 7
Joined: 31 Aug 2018, 08:20

Re: GDI+ standard library 1.45 by tic

17 Dec 2018, 15:06

swagfag, thank you for reply. I write script using OOP. This script have next structure:
class GUI
  • class Button
  • class Edit
  • class DDL
  • e.t.c
Like a standard AHK gui. What u think about it? Gui engine from scratch, is it good idea?

Each class have its own bitmap(CreateDIBSection), DC(CreateCompatibleDC) and graphics(GraphicsFromHDC).
And I asked myself the following question:
how do I draw the contents of one class into another?

Now im using BitBlt(), but this not support alpha. (support,but not so as i want. Bitblt only copy content.)
Can i copy content of Button into GUI? (using, for example, graphics)

P.S. if u something not understood, let me know.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: GDI+ standard library 1.45 by tic

17 Dec 2018, 17:13

I would not reccomend going with the structure you suggested but rather provide each class a pGraphics that is correctly transformed when this element has to redraw itself.
Drawing bitmaps onto each other is an expensive operation - you do not gain any performance by buffering each class.

The function you are looking for would be called Gdip_DrawImage.
Recommends AHK Studio

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: kashmirLZ and 69 guests