GDI+ standard library 1.45 by tic

Post your working scripts, libraries and tools
_Ne0n
Posts: 7
Joined: 31 Aug 2018, 08:20

Re: GDI+ standard library 1.45 by tic

18 Dec 2018, 09:05

nnnik, thank u for hint. I saw on this function, but not used it cos it draw's bitmap into pGraphics. (I needed DC>DC) I will try do something with it.
_Ne0n
Posts: 7
Joined: 31 Aug 2018, 08:20

Re: GDI+ standard library 1.45 by tic

27 Dec 2018, 18:51

How it looks? :0
Just AHK and GDI+.
User avatar
nnnik
Posts: 4276
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: GDI+ standard library 1.45 by tic

27 Dec 2018, 20:44

Nice gj
Recommends AHK Studio
_Ne0n
Posts: 7
Joined: 31 Aug 2018, 08:20

Re: GDI+ standard library 1.45 by tic

08 Jan 2019, 12:45

Hello :)
I have next function:
Spoiler
If in addition to the file directory, put a the height and width, then function reduce/enlarge the image, while maintaining the proportions.
MsgBox at the same time displays about 265ms, which is not good.
Someone faced with this?
I convert image 4160x2340 to 72x72.
User avatar
jeeswg
Posts: 6832
Joined: 19 Dec 2016, 01:58
Location: UK

Re: GDI+ standard library 1.45 by tic

12 Mar 2019, 02:31

- Hello, to support #Warn, changes like this need to be done for IntP/UIntP/PtrP etc in DllCall. I.e. you assign a value in advance.

Code: Select all

	;Warning:  This variable has not been assigned a value.
	;before:
	DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", 1, "PtrP", pStream)

	;after:
	pStream := 0
	DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", 1, "PtrP", pStream)

	;after (alternative):
	DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", 1, "PtrP", pStream:=0)
- Also, to support #Warm, 'local' by itself should be added to every function.
- Although, this would mean that you'd need AHK v1.1.27+ to use the library.
- That said, the users could remove 'local', to make it work on older versions. Thanks.
Last edited by jeeswg on 26 Mar 2019, 15:04, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
iseahound
Posts: 466
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: GDI+ standard library 1.45 by tic

21 Mar 2019, 21:41

What is the purpose of lines such as

Code: Select all

	pBitmap := ""

inside

Code: Select all

Gdip_CreateBitmapFromHICON(hIcon)
{
	pBitmap := ""

	DllCall("gdiplus\GdipCreateBitmapFromHICON", A_PtrSize ? "UPtr" : "UInt", hIcon, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
	return pBitmap
}
They actually don't do anything.
swagfag
Posts: 3001
Joined: 11 Jan 2017, 17:59

Re: GDI+ standard library 1.45 by tic

22 Mar 2019, 01:44

so it doesn't upset #warn methinks
guest3456
Posts: 2677
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

22 Mar 2019, 08:51

yes if you guys are talking about the v1/v2 version of the lib

one guy already added support for #WarnAll

example commit
https://github.com/mmikeww/AHKv2-Gdip/commit/8f7a787c94f3339ecc27c20a2e71c77426210be4

iseahound
Posts: 466
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: GDI+ standard library 1.45 by tic

22 Mar 2019, 10:55

For the DllCall standardization, are we doing lowercase or uppercase letters?

Code: Select all

DllCall( "SendMessage", Ptr, hwnd, "UInt", 0x172, "UInt", 0x0, Ptr, hBitmap )
to

Code: Select all

DllCall( "SendMessage", "Ptr", hwnd, "UInt", 0x172, "UInt", 0x0, "Ptr", hBitmap )
or

Code: Select all

DllCall( "SendMessage", "ptr", hwnd, "uint", 0x172, "uint", 0x0, "ptr", hBitmap )
I feel like it shouldn't really matter, other than size arguments are encased in quotes for maximum compatibility, speed, and reliability.
iseahound
Posts: 466
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: GDI+ standard library 1.45 by tic

22 Mar 2019, 11:54

I realized why the #Warn changes bothered me. If the variable is initalized, then the address should be passed.

Code: Select all

Gdip_CreateBitmapFromHICON(hIcon)
{
	pBitmap := ""

	DllCall("gdiplus\GdipCreateBitmapFromHICON", A_PtrSize ? "UPtr" : "UInt", hIcon, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
	return pBitmap
}
becomes

Code: Select all

Gdip_CreateBitmapFromHICON(hIcon)
{
	pBitmap := ""

	DllCall("gdiplus\GdipCreateBitmapFromHICON", A_PtrSize ? "UPtr" : "UInt", hIcon, A_PtrSize ? "UPtr" : "uint", &pBitmap)
	return pBitmap
}
I changed uint* to plain old uint since we already have the address via &pBitmap.
swagfag
Posts: 3001
Joined: 11 Jan 2017, 17:59

Re: GDI+ standard library 1.45 by tic

22 Mar 2019, 17:02

iseahound wrote:
22 Mar 2019, 11:54
If the variable is initalized, then the address should be passed.
why? it works either way. yes u can use "Ptr" and &, but what practical difference does it make
Helgef
Posts: 4004
Joined: 17 Jul 2016, 01:02
Contact:

Re: GDI+ standard library 1.45 by tic

23 Mar 2019, 00:50

Don't do that iseahound, that is undefined behaviour. You need to use varsetcapacity and numget if you use ptr vs ptr*.

Edit, in v2 you can do "ptr", &var := 0.
iseahound
Posts: 466
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: GDI+ standard library 1.45 by tic

24 Mar 2019, 10:35

Helgef wrote:
23 Mar 2019, 00:50
Edit, in v2 you can do "ptr", &var := 0.
Not that I would, but do I interpret that as "ptr", &(var := 0)?
Helgef
Posts: 4004
Joined: 17 Jul 2016, 01:02
Contact:

Re: GDI+ standard library 1.45 by tic

24 Mar 2019, 14:13

yes.
Operators in Expressions wrote:The precedence of the assignment operators is automatically raised when it would avoid a syntax error or provide more intuitive behavior.
User avatar
jeeswg
Posts: 6832
Joined: 19 Dec 2016, 01:58
Location: UK

Re: GDI+ standard library 1.45 by tic

26 Mar 2019, 15:12

- @iseahound: The reason is to avoid #Warn errors, e.g. 'Warning: This variable has not been assigned a value.'
- There is an advantage also that such code is easier to translate to other languages.
- I've updated my example earlier on this page, to demonstrate that you can do var:=0 within the DllCall function call, a 3-character fix to avoid the warning: :=0.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
RazorHalo
Posts: 28
Joined: 21 Dec 2015, 21:23

Re: GDI+ standard library 1.45 by tic

12 Apr 2019, 01:20

Hi All,

I was wondering if using DllCall can we only access the Functions of GDI+ or is there also a way to use it's methods.
I want to rotate a graphicspath on the center of its bounding rectangle and it would be a lot easier if I could use the RotateAt method.

It looks to me like I can only access the functions in the dll, any attempt to use the RotateAt method yields no returned status code at all.

Function:
https://docs.microsoft.com/en-us/windows/desktop/gdiplus/-gdiplus-matrix-flat

Method:
https://docs.microsoft.com/en-us/windows/desktop/api/gdiplusmatrix/nf-gdiplusmatrix-matrix-rotateat

Maybe there is a way to access it that I'm not aware of? I can't seem to find any reference to this from searching.

RH
swagfag
Posts: 3001
Joined: 11 Jan 2017, 17:59

Re: GDI+ standard library 1.45 by tic

12 Apr 2019, 02:21

no there isn't. only functions
User avatar
nnnik
Posts: 4276
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: GDI+ standard library 1.45 by tic

12 Apr 2019, 07:50

The RotateAt method is a C++ library wrapper around the DllCalls.
This specific method probably just performs multiple of the basic operations:
  • Move the point that you want to rotate around to the center using GdipTranslateMatrix
  • Rotate using GdipRotateMatrix
  • Move the point back to where it was before
In AHK we can't access the C++ wrapper library but need to write our own.
Recommends AHK Studio
guest3456
Posts: 2677
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

12 Apr 2019, 23:51

the Matrix::RotateAt link mentions "gdiplusmatrix.h" as a requirement. googling the source for that file i found a few diff options, this one looked closest to what you'd need to do:

https://pdfium.googlesource.com/pdfium/+/5110c4743751145c4ae1934cd1d83bc6c55bb43f/core/src/fxge/Microsoft%20SDK/include/GdiPlusMatrix.h

Code: Select all

    Status RotateAt(IN REAL angle, 
                    IN const PointF& center, 
                    IN MatrixOrder order = MatrixOrderPrepend)
    {
        if(order == MatrixOrderPrepend)
        {
            SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order));
            SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
            return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order));
        }
        else
        {
            SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order));
            SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
            return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order));
        }
    }

User avatar
RazorHalo
Posts: 28
Joined: 21 Dec 2015, 21:23

Re: GDI+ standard library 1.45 by tic

13 Apr 2019, 00:15

Thanks guys, after playing around for a few hours I was able to get it working. Here are the GDip Matrix functions I wrapped for the rotations and a sample script to see it implemented.

The thing that got me stuck the most was not realizing the order the transformations were applied with the MatrixOrder variable. It needs to be Append for this so that it will always put the transformation you want to do AFTER the one you just did. I'm sure there is a reason that it is defaulted to Prepend, but it doesn't make sense to me to do it in that order.

Matrix Functions for Gdip
Just add them to your GDip_All.ahk for future use:

Code: Select all

;#####################################################################################
; Matrix functions added by RazorHalo
;#####################################################################################

; NOTE: Be aware of the order that transoformations are applied.  You may need to pass MatrixOrder as 1 for "Append"
; the (default is 0 for "Prepend") to get the correct results.

Gdip_ResetMatrix(pMatrix)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

   return DllCall("gdiplus\GdipResetMatrix", Ptr, pMatrix)
}

Gdip_RotateMatrix(pMatrix, Angle, MatrixOrder=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

   return DllCall("gdiplus\GdipRotateMatrix", Ptr, pMatrix, "float", Angle, "Int", MatrixOrder)
}

Gdip_GetPathWorldBounds(pPath)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	rData := {}

	VarSetCapacity(RectF, 16)
	NumPut(0, RectF, 0, "float"), NumPut(0, RectF, 4, "float"), NumPut(0, RectF, 8, "float"), NumPut(0, RectF, 12, "float")

	status := DllCall("gdiplus\GdipGetPathWorldBounds", Ptr, pPath, Ptr, &RectF)

	If (!status) {
			  rData.x := NumGet(RectF, 0, "float")
			, rData.y := NumGet(RectF, 4, "float")
			, rData.w := NumGet(RectF, 8, "float")
			, rData.h := NumGet(RectF, 12, "float")
	} Else {
		Return status
	}
	
   return rData
}

Gdip_ScaleMatrix(pMatrix, scaleX, scaleY, MatrixOrder=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

   return DllCall("gdiplus\GdipScaleMatrix", Ptr, pMatrix, "float", scaleX, "float", scaleY, "Int", MatrixOrder)
}

Gdip_TranslateMatrix(pMatrix, offsetX, offsetY, MatrixOrder=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

   return DllCall("gdiplus\GdipTranslateMatrix", Ptr, pMatrix, "float", offsetX, "float", offsetY, "Int", MatrixOrder)
}

Gdip_TransformPath(pPath, pMatrix)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	return DllCall("gdiplus\GdipTransformPath", Ptr, pPath, Ptr, pMatrix)
}

Gdip_SetMatrixElements(pMatrix, m11, m12, m21, m22, x, y)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	return DllCall("gdiplus\GdipSetMatrixElements", Ptr, pMatrix, "float", m11, "float", m12, "float", m21, "float", m22, "float", x, "float", y)
   
}
Gdip_GetLastStatus(pMatrix)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	return DllCall("gdiplus\GdipGetLastStatus", Ptr, pMatrix)
}

Sample Script that will rotate a square around
Note - it uses the matrix functions I wrapped and needs some of the GraphicsPath Functions by Learning One

Code: Select all

#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
SetBatchLines -1

;Need to include your path to Gdip or have in the same directory as script
#Include Gdip_all.ahk

Gui Mapper: New, hWndhMap -DPIScale +OwnDialogs
Gui Show, NA w600 h600, Mapper

Gui 1: +E0x80000 +LastFound -Caption -DPIScale +ParentMapper
hGui := WinExist()
Gui 1: Show, NA
w:= A_ScreenWidth, h:= A_ScreenHeight

pToken := Gdip_Startup()
hbm := CreateDIBSection(w, h), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4)

;Create a GraphicsPath
pPath := Gdip_CreatePath() ; creates a Path (GraphicsPath object)

;Add figure to path
Gdip_StartPathFigure(pPath) ; starts a new figure in this Path
Gdip_AddPathLine(pPath, 200, 200, 400, 200)
Gdip_AddPathLine(pPath, 400, 200, 400, 400)
Gdip_AddPathLine(pPath, 400, 400, 200, 400)
Gdip_AddPathLine(pPath, 200, 400, 200, 200)
Gdip_ClosePathFigure(pPath) ; closes the current figure of this path

;Create a Pen to draw with
pPen := Gdip_CreatePen(0xff000000, 3)

;Rotate the graphic until exit
Loop {
	Gdip_GraphicsClear(G)						; Clear the graphics
	RotateAtCenter(pPath, 5)					; Rotate the path by 5deg on its center
	Gdip_DrawPath(G, pPen, pPath)				; draw rectangle
	UpdateLayeredWindow(hGui, hdc, 0, 0, w, h)	; Update the layred window
	Sleep 100
}

Esc::
;Cleanup and Exit
Gdip_DeletePen(pPen)
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Gdip_Shutdown(pToken)
return
ExitApp

;#####################################################################################
; RotateAtCenter Function by RazorHalo
;#####################################################################################
;The Matrix order has to be "Append" for the transformations to be applied in the correct order - instead of the default "Prepend"

RotateAtCenter(pPath, Angle, MatrixOrder=1) {

	;Get bouinding rectangle of the graphics path
	;returns array x,y,w,h
	Rect := Gdip_GetPathWorldBounds(pPath)
	
	;Calcualte center of bounding rectangle which will be the center of the graphics path
	cX := Rect.x + (Rect.w / 2)
	cY := Rect.y + (Rect.h / 2)
	
	;Create a Matrix for the transformations
	pMatrix := Gdip_CreateMatrix()
	
	;Move the GraphicsPath center to the origin (0, 0) of the graphics object
	Gdip_TranslateMatrix(pMatrix, -cX , -cY)

	;Rotate matrix on graphics object origin
	Gdip_RotateMatrix(pMatrix, Angle, MatrixOrder)
	
	;Move the GraphicsPath origin point back to its original position
	Gdip_TranslateMatrix(pMatrix, cX, cY, MatrixOrder)

	;Apply the transformations
	Gdip_TransformPath(pPath, pMatrix)
	
	;Reset Matrix?  Delete Matrix?  Do I still need it for future rotations?
	GDip_DeleteMatrix(pMatrix)

}


;#####################################################################################
; GraphicsPath functions added by RazorHalo
;#####################################################################################

; NOTE: Be aware of the order that transoformations are applied.  You may need to pass MatrixOrder as 1 for "Append"
; the (default is 0 for "Prepend") to get the correct results.

Gdip_ResetMatrix(pMatrix)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

   return DllCall("gdiplus\GdipResetMatrix", Ptr, pMatrix)
}

Gdip_RotateMatrix(pMatrix, Angle, MatrixOrder=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

   return DllCall("gdiplus\GdipRotateMatrix", Ptr, pMatrix, "float", Angle, "Int", MatrixOrder)
}

Gdip_GetPathWorldBounds(pPath)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	rData := {}

	VarSetCapacity(RectF, 16)
	NumPut(0, RectF, 0, "float"), NumPut(0, RectF, 4, "float"), NumPut(0, RectF, 8, "float"), NumPut(0, RectF, 12, "float")

	status := DllCall("gdiplus\GdipGetPathWorldBounds", Ptr, pPath, Ptr, &RectF)

	If (!status) {
			  rData.x := NumGet(RectF, 0, "float")
			, rData.y := NumGet(RectF, 4, "float")
			, rData.w := NumGet(RectF, 8, "float")
			, rData.h := NumGet(RectF, 12, "float")
	} Else {
		Return status
	}
	
   return rData
}

Gdip_ScaleMatrix(pMatrix, scaleX, scaleY, MatrixOrder=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

   return DllCall("gdiplus\GdipScaleMatrix", Ptr, pMatrix, "float", scaleX, "float", scaleY, "Int", MatrixOrder)
}

Gdip_TranslateMatrix(pMatrix, offsetX, offsetY, MatrixOrder=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

   return DllCall("gdiplus\GdipTranslateMatrix", Ptr, pMatrix, "float", offsetX, "float", offsetY, "Int", MatrixOrder)
}

Gdip_TransformPath(pPath, pMatrix)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	return DllCall("gdiplus\GdipTransformPath", Ptr, pPath, Ptr, pMatrix)
}

Gdip_SetMatrixElements(pMatrix, m11, m12, m21, m22, x, y)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	return DllCall("gdiplus\GdipSetMatrixElements", Ptr, pMatrix, "float", m11, "float", m12, "float", m21, "float", m22, "float", x, "float", y)
   
}
Gdip_GetLastStatus(pMatrix)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"

	return DllCall("gdiplus\GdipGetLastStatus", Ptr, pMatrix)
}


;#####################################################################################
; GraphicsPath functions added by Learning one
;#####################################################################################

; Function Gdip_AddPathBeziers
; Description Adds a sequence of connected Bézier splines to the current figure of this path.
;
; pPath Pointer to the GraphicsPath
; Points the coordinates of all the points passed as x1,y1|x2,y2|x3,y3.....
;
; return status enumeration. 0 = success

; Notes The first spline is constructed from the first point through the fourth point in the array and uses the second and third points as control points. Each subsequent spline in the sequence needs exactly three more points: the ending point of the previous spline is used as the starting point, the next two points in the sequence are control points, and the third point is the ending point.

Gdip_AddPathBeziers(pPath, Points) {
StringSplit, Points, Points, |
VarSetCapacity(PointF, 8*Points0)
Loop, %Points0%
{
StringSplit, Coord, Points%A_Index%, `,
NumPut(Coord1, PointF, 8*(A_Index-1), "float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "float")
}
return DllCall("gdiplus\GdipAddPathBeziers", "uint", pPath, "uint", &PointF, "int", Points0)
}

Gdip_AddPathBezier(pPath, x1, y1, x2, y2, x3, y3, x4, y4) { ; Adds a Bézier spline to the current figure of this path
return DllCall("gdiplus\GdipAddPathBezier", "uint", pPath
, "float", x1, "float", y1, "float", x2, "float", y2
, "float", x3, "float", y3, "float", x4, "float", y4)
}

; Function Gdip_AddPathLines
; Description Adds a sequence of connected lines to the current figure of this path.
;
; pPath Pointer to the GraphicsPath
; Points the coordinates of all the points passed as x1,y1|x2,y2|x3,y3.....
;
; return status enumeration. 0 = success

Gdip_AddPathLines(pPath, Points) {
StringSplit, Points, Points, |
VarSetCapacity(PointF, 8*Points0)
Loop, %Points0%
{
StringSplit, Coord, Points%A_Index%, `,
NumPut(Coord1, PointF, 8*(A_Index-1), "float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "float")
}
return DllCall("gdiplus\GdipAddPathLine2", "uint", pPath, "uint", &PointF, "int", Points0)
}

Gdip_AddPathLine(pPath, x1, y1, x2, y2) {
return DllCall("gdiplus\GdipAddPathLine", "uint", pPath
, "float", x1, "float", y1, "float", x2, "float", y2)
}

Gdip_AddPathArc(pPath, x, y, w, h, StartAngle, SweepAngle) {
return DllCall("gdiplus\GdipAddPathArc", "uint", pPath, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}

Gdip_AddPathPie(pPath, x, y, w, h, StartAngle, SweepAngle) {
return DllCall("gdiplus\GdipAddPathPie", "uint", pPath, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}

Gdip_StartPathFigure(pPath) { ; Starts a new figure without closing the current figure. Subsequent points added to this path are added to the new figure.
return DllCall("gdiplus\GdipStartPathFigure", "uint", pPath)
}

Gdip_ClosePathFigure(pPath) { ; Closes the current figure of this path.
return DllCall("gdiplus\GdipClosePathFigure", "uint", pPath)
}

; Function Gdip_DrawPath
; Description draws a sequence of lines and curves defined by a GraphicsPath object
;
; pGraphics Pointer to the Graphics of a bitmap
; pPen Pointer to a pen
; pPath Pointer to a Path
;
; return status enumeration. 0 = success

Gdip_DrawPath(pGraphics, pPen, pPath) {
return DllCall("gdiplus\GdipDrawPath", "uint", pGraphics, "uint", pPen, "uint", pPath)
}

Gdip_WidenPath(pPath, pPen, Matrix=0, Flatness=1) { ; Replaces this path with curves that enclose the area that is filled when this path is drawn by a specified pen. This method also flattens the path.
return DllCall("gdiplus\GdipWidenPath", "uint", pPath, "uint", pPen, "uint", Matrix, "float", Flatness)
}

Gdip_ClonePath(pPath) {
DllCall("gdiplus\GdipClonePath", "uint", pPath, "uint*", pPathClone)
return pPathClone
}

Return to “Scripts and Functions”

Who is online

Users browsing this forum: gwarble, malcev and 13 guests