GDI+ standard library 1.45 by tic
Re: GDI+ standard library 1.45 by tic
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.
Re: GDI+ standard library 1.45 by tic
How it looks? :0
Just AHK and GDI+.
Just AHK and GDI+.
Re: GDI+ standard library 1.45 by tic
Hello
I have next function:
MsgBox at the same time displays about 265ms, which is not good.
Someone faced with this?
I convert image 4160x2340 to 72x72.
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.
Re: GDI+ standard library 1.45 by tic
- 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.
- 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.
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)
- 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
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: GDI+ standard library 1.45 by tic
What is the purpose of lines such as
inside
They actually don't do anything.
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
}
Re: GDI+ standard library 1.45 by tic
so it doesn't upset #warn methinks
Re: GDI+ standard library 1.45 by tic
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
one guy already added support for #WarnAll
example commit
https://github.com/mmikeww/AHKv2-Gdip/commit/8f7a787c94f3339ecc27c20a2e71c77426210be4
Re: GDI+ standard library 1.45 by tic
For the DllCall standardization, are we doing lowercase or uppercase letters?
to
or
I feel like it shouldn't really matter, other than size arguments are encased in quotes for maximum compatibility, speed, and reliability.
Code: Select all
DllCall( "SendMessage", Ptr, hwnd, "UInt", 0x172, "UInt", 0x0, Ptr, hBitmap )
Code: Select all
DllCall( "SendMessage", "Ptr", hwnd, "UInt", 0x172, "UInt", 0x0, "Ptr", hBitmap )
Code: Select all
DllCall( "SendMessage", "ptr", hwnd, "uint", 0x172, "uint", 0x0, "ptr", hBitmap )
Re: GDI+ standard library 1.45 by tic
I realized why the #Warn changes bothered me. If the variable is initalized, then the address should be passed.
becomes
I changed uint* to plain old uint since we already have the address via &pBitmap.
Code: Select all
Gdip_CreateBitmapFromHICON(hIcon)
{
pBitmap := ""
DllCall("gdiplus\GdipCreateBitmapFromHICON", A_PtrSize ? "UPtr" : "UInt", hIcon, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
return pBitmap
}
Code: Select all
Gdip_CreateBitmapFromHICON(hIcon)
{
pBitmap := ""
DllCall("gdiplus\GdipCreateBitmapFromHICON", A_PtrSize ? "UPtr" : "UInt", hIcon, A_PtrSize ? "UPtr" : "uint", &pBitmap)
return pBitmap
}
Re: GDI+ standard library 1.45 by tic
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.
Edit, in v2 you can do "ptr", &var := 0.
Re: GDI+ standard library 1.45 by tic
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.
Re: GDI+ standard library 1.45 by tic
- @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.
- 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
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: GDI+ standard library 1.45 by tic
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
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
Re: GDI+ standard library 1.45 by tic
no there isn't. only functions
Re: GDI+ standard library 1.45 by tic
The RotateAt method is a C++ library wrapper around the DllCalls.
This specific method probably just performs multiple of the basic operations:
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
Recommends AHK Studio
Re: GDI+ standard library 1.45 by tic
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
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));
}
}
Re: GDI+ standard library 1.45 by tic
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:
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
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 (v1)”
Who is online
Users browsing this forum: Bing [Bot] and 69 guests