GDI+ MeasureString function not working in v2-alpha

Get help for the alpha version of AutoHotkey v2 here. Please state the v2 version you are working with in the title when making a new topic.
bmcclure
Posts: 11
Joined: 29 May 2018, 22:11
Google: ben.mcclure
GitHub: bmcclure

GDI+ MeasureString function not working in v2-alpha

Post by bmcclure » 05 Dec 2020, 19:02

I have been modifying a version of the Gdip_All.ahk library that worked with v2 earlier this year so that it works in the latest version, and most functionality is working well but I am having an issue with the MeasureString function.

This is my code:

Code: Select all

Gdip_MeasureString(pGraphics, sString, hFont, hFormat, ByRef RectF)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	RC := BufferAlloc(16)

	Chars := 0
	Lines := 0
	DllCall("gdiplus\GdipMeasureString"
					, Ptr, pGraphics
					, Ptr, StrPtr(sString)
					, "Int", -1
					, Ptr, hFont
					, Ptr, ObjPtr(RectF)
					, Ptr, hFormat
					, Ptr, ObjPtr(RC)
					, "UInt*", Chars
					, "UInt*", Lines)
    
	return ObjPtr(RC) ? NumGet(RC, 0, "Float") "|" NumGet(RC, 4, "Float") "|" NumGet(RC, 8, "Float") "|" NumGet(RC, 12, "Float") "|" Chars "|" Lines : 0
}
The problem is that all of the NumGet calls after the DllCall indicate "Invalid memory read/write." I tried changing the type for the RC parameter to

Code: Select all

Ptr . "*"
and I thought that was working, but then the RC value is never actually modified, all 4 values stay at 0.

I know that pGraphics is valid as it is used to draw other shapes onto. sString is a valid string. hFont is a valid font object. RectF is a bounding box that is at 0, 0 and is 200x80. hFormat is constructed via bitwise operations as 1|1 because I specified both vertical and horizontal centering.

the Gdip_DrawString function takes all of the same parameters and it actually works, so I'm having trouble figuring out what I'm doing wrong that's preventing me from getting an updated RC structure from the DllCall.

Could anyone provide any tips on this? Thanks!

swagfag
Posts: 4126
Joined: 11 Jan 2017, 17:59

Re: GDI+ MeasureString function not working in v2-alpha

Post by swagfag » 06 Dec 2020, 03:25

  • Ptr := A_PtrSize ? "UPtr" : "UInt" not needed, replace all ptr types with 'Ptr'
  • declare library functions force-local or declare their variables local
  • , Ptr, StrPtr(sString)this could probably just be 'Str', sString, but i cant check for sure
  • ObjPtr(RC) returns the address of where the AHK object RC is in the script process's memory, which is not the same address as the one which the buffer uses to store its data in(accessible via the buffer's .Ptr property ). when passing buffers to Ptr typed DllCall arguments, u can just pass the buffer as is, ie 'Ptr', RC,
  • , Ptr, ObjPtr(RectF) same thing here. if RectF is a previously allocated ahk buffer, pass it as is. also ByRef is not needed in this case
  • return ObjPtr(RC) ?this check doesnt make much sense. check the DllCall's return value instead or A_LastError if relevant

bmcclure
Posts: 11
Joined: 29 May 2018, 22:11
Google: ben.mcclure
GitHub: bmcclure

Re: GDI+ MeasureString function not working in v2-alpha

Post by bmcclure » 07 Dec 2020, 23:05

Thanks for the tips!

I think passing the buffer's ".Ptr" property might fix it, I'll give that a try. Using the "Ptr" and passing RC directly does not work, however, as it complains that it expected an integer and received a Buffer object.

bmcclure
Posts: 11
Joined: 29 May 2018, 22:11
Google: ben.mcclure
GitHub: bmcclure

Re: GDI+ MeasureString function not working in v2-alpha

Post by bmcclure » 08 Dec 2020, 01:18

That did fix it! I cleaned up a ton of the other code based on your tips as well, and everything is working for me so far. I appreciate it!

Post Reply

Return to “AutoHotkey v2 Help”