; Gdip standard library v1.00 by thqby 07/24/2020
; Supports: _L 2.0 a117
#Requires AutoHotkey v2.0-a
class CGdip
{
static pToken:=0, hModule:=0, RefCount:=0
static Startup(){
CGdip.RefCount+=1
if CGdip.RefCount>1
return CGdip.pToken
if (!CGdip.hModule&&!DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr"))
CGdip.hModule:=DllCall("LoadLibrary", "Str", "gdiplus")
si:=BufferAlloc(A_PtrSize = 8 ? 24 : 16, 0), NumPut("UInt", 1, si, 0)
DllCall("gdiplus\GdiplusStartup", "Ptr*", pToken:=0, "Ptr", si, "Ptr", 0), CGdip.pToken:=pToken
return pToken
}
static Shutdown(){
CGdip.RefCount-=1
if CGdip.RefCount>0
return 0
if CGdip.pToken
DllCall("gdiplus\GdiplusShutdown", "Ptr", CGdip.pToken), CGdip.pToken:=0
if CGdip.hModule
DllCall("FreeLibrary", "Ptr", CGdip.hModule), CGdip.hModule:=0
return 0
}
static SetImageAttributesColorMatrix(Matrix){
ColourMatrix:=BufferAlloc(100, 0)
Matrix:=RegExReplace(RegExReplace(Matrix, "^[^\d-\.]+([\d\.])", "$1", , 1), "[^\d-\.]+", "|")
Matrix:=StrSplit(Matrix, "|")
Loop 25
{
Matrix_:=(Matrix[A_Index] != "") ? Matrix[A_Index] : Mod(A_Index-1, 6) ? 0 : 1
NumPut("float", Matrix_, ColourMatrix, (A_Index-1)*4)
}
DllCall("gdiplus\GdipCreateImageAttributes", "Ptr*", ImageAttr:=0)
DllCall("gdiplus\GdipSetImageAttributesColorMatrix", "Ptr", ImageAttr, "int", 1, "int", 1, "Ptr", ColourMatrix, "Ptr", 0, "int", 0)
return ImageAttr
}
static DisposeImageAttributes(ImageAttr){
return DllCall("gdiplus\GdipDisposeImageAttributes", "Ptr", ImageAttr)
}
static CreateRegion(){
DllCall("gdiplus\GdipCreateRegion", "UInt*", Region:=0)
return Region
}
static DeleteRegion(Region){
return DllCall("gdiplus\GdipDeleteRegion", "Ptr", Region)
}
static GetImageDimensions(pBitmap, ByRef Width, ByRef Height){
Width:=0, Height:=0
DllCall("gdiplus\GdipGetImageWidth", "Ptr", pBitmap, "Uint*", Width)
DllCall("gdiplus\GdipGetImageHeight", "Ptr", pBitmap, "Uint*", Height)
}
static GetImageWidth(pBitmap){
DllCall("gdiplus\GdipGetImageWidth", "Ptr", pBitmap, "Uint*", Width:=0)
return Width
}
static GetImageHeight(pBitmap){
DllCall("gdiplus\GdipGetImageHeight", "Ptr", pBitmap, "Uint*", Height:=0)
return Height
}
class Graphics
{
Ptr:=0, hdc:=0
__New(pGraphics){
if (!pGraphics)
throw "invalid pGraphics"
else
this.Ptr:=pGraphics
}
__Delete(){
if (!CGdip.pToken)
return
if this.hdc
this.ReleaseDC()
if (this.Ptr)
DllCall("gdiplus\GdipDeleteGraphics", "Ptr", this)
}
static FromHDC(hdc){
DllCall("gdiplus\GdipCreateFromHDC", "Ptr", hdc, "Ptr*", pGraphics:=0)
return CGdip.Graphics.New(pGraphics)
}
static FromBitmap(pBitmap){
DllCall("gdiplus\GdipGetImageGraphicsContext", "Ptr", pBitmap, "Ptr*", pGraphics:=0)
return CGdip.Graphics.New(pGraphics)
}
DrawRectangle(pPen, x, y, w, h){
return DllCall("gdiplus\GdipDrawRectangle", "Ptr", this, "Ptr", pPen, "float", x, "float", y, "float", w, "float", h)
}
DrawRoundedRectangle(pPen, x, y, w, h, r){
this.SetClipRect(x-r, y-r, 2*r, 2*r, 4)
this.SetClipRect(x+w-r, y-r, 2*r, 2*r, 4)
this.SetClipRect(x-r, y+h-r, 2*r, 2*r, 4)
this.SetClipRect(x+w-r, y+h-r, 2*r, 2*r, 4)
E:=this.DrawRectangle(pPen, x, y, w, h)
this.ResetClip()
this.SetClipRect(x-(2*r), y+r, w+(4*r), h-(2*r), 4)
this.SetClipRect(x+r, y-(2*r), w-(2*r), h+(4*r), 4)
this.DrawEllipse(pPen, x, y, 2*r, 2*r)
this.DrawEllipse(pPen, x+w-(2*r), y, 2*r, 2*r)
this.DrawEllipse(pPen, x, y+h-(2*r), 2*r, 2*r)
this.DrawEllipse(pPen, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
this.ResetClip()
return E
}
DrawEllipse(pPen, x, y, w, h){
return DllCall("gdiplus\GdipDrawEllipse", "Ptr", this, "Ptr", pPen, "float", x, "float", y, "float", w, "float", h)
}
DrawBezier(pPen, x1, y1, x2, y2, x3, y3, x4, y4){
return DllCall("gdiplus\GdipDrawBezier", "Ptr", this, "Ptr", pPen
, "float", x1, "float", y1, "float", x2, "float", y2
, "float", x3, "float", y3, "float", x4, "float", y4)
}
DrawArc(pPen, x, y, w, h, StartAngle, SweepAngle){
return DllCall("gdiplus\GdipDrawArc", "Ptr", this, "Ptr", pPen
, "float", x, "float", y, "float", w, "float", h
, "float", StartAngle, "float", SweepAngle)
}
DrawPie(pPen, x, y, w, h, StartAngle, SweepAngle){
return DllCall("gdiplus\GdipDrawPie", "Ptr", this, "Ptr", pPen, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}
DrawLine(pPen, x1, y1, x2, y2){
return DllCall("gdiplus\GdipDrawLine"
, "Ptr", this, "Ptr", pPen
, "float", x1, "float", y1, "float", x2, "float", y2)
}
DrawLines(pPen, Points){
Points:=StrSplit(Points, "|")
PointF:=BufferAlloc(8*Points.Length)
Loop Points.Length
Coord:=StrSplit(Points[A_Index], ","), NumPut("float", Coord[1], "float", Coord[2], PointF, 8*(A_Index-1))
return DllCall("gdiplus\GdipDrawLines", "Ptr", this, "Ptr", pPen, "Ptr", PointF, "int", Points.Length)
}
DrawImage(pBitmap, dx:="", dy:="", dw:="", dh:="", sx:="", sy:="", sw:="", sh:="", Matrix:=1){
ImageAttr:=0
if !IsNumber(Matrix)
ImageAttr:=CGdip.SetImageAttributesColorMatrix(Matrix)
else if (Matrix != 1)
ImageAttr:=CGdip.SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" Matrix "|0|0|0|0|0|1")
if (sx = "" && sy = "" && sw = "" && sh = "")
{
if (dx = "" && dy = "" && dw = "" && dh = "")
{
sx:=dx:=0, sy:=dy:=0
sw:=dw:=CGdip.GetImageWidth(pBitmap)
sh:=dh:=CGdip.GetImageHeight(pBitmap)
}
else
{
sx:=sy:=0
sw:=CGdip.GetImageWidth(pBitmap)
sh:=CGdip.GetImageHeight(pBitmap)
}
}
E:=DllCall("gdiplus\GdipDrawImageRectRect", "Ptr", this, "Ptr", pBitmap
, "float", dx, "float", dy, "float", dw, "float", dh
, "float", sx, "float", sy, "float", sw, "float", sh
, "int", 2, "Ptr", ImageAttr, "Ptr", 0, "Ptr", 0)
if ImageAttr
CGdip.DisposeImageAttributes(ImageAttr)
return E
}
DrawString(ByRef sString, hFont, hFormat, pBrush, RectF){
return DllCall("gdiplus\GdipDrawString", "Ptr", this, "Str", sString, "int", -1
, "Ptr", hFont, "Ptr", RectF, "Ptr", hFormat, "Ptr", pBrush)
}
MeasureString(ByRef sString, hFont, hFormat, RectF){
RC:=BufferAlloc(16, 0)
DllCall("gdiplus\GdipMeasureString", "Ptr", this, "Ptr", StrPtr(sString), "int", -1
, "Ptr", hFont, "Ptr", RectF, "Ptr", hFormat
, "Ptr", RC, "Uint*", Chars:=0, "Uint*", Lines:=0)
return RC.Ptr ? {x:NumGet(RC, 0, "float"), y:NumGet(RC, 4, "float"), w:NumGet(RC, 8, "float"), h:NumGet(RC, 12, "float"), chars:Chars, lines:Lines} : 0
}
FillRectangle(pBrush, x, y, w, h){
return DllCall("gdiplus\GdipFillRectangle"
, "Ptr", this, "Ptr", pBrush
, "float", x, "float", y, "float", w, "float", h)
}
FillRoundedRectangle(pBrush, x, y, w, h, r){
Region:=this.GetClipRegion()
this.SetClipRect(x-r, y-r, 2*r, 2*r, 4)
this.SetClipRect(x+w-r, y-r, 2*r, 2*r, 4)
this.SetClipRect(x-r, y+h-r, 2*r, 2*r, 4)
this.SetClipRect(x+w-r, y+h-r, 2*r, 2*r, 4)
E:=this.FillRectangle(pBrush, x, y, w, h)
this.SetClipRegion(Region, 0)
this.SetClipRect(x-(2*r), y+r, w+(4*r), h-(2*r), 4)
this.SetClipRect(x+r, y-(2*r), w-(2*r), h+(4*r), 4)
this.FillEllipse(pBrush, x, y, 2*r, 2*r)
this.FillEllipse(pBrush, x+w-(2*r), y, 2*r, 2*r)
this.FillEllipse(pBrush, x, y+h-(2*r), 2*r, 2*r)
this.FillEllipse(pBrush, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
this.SetClipRegion(Region, 0)
CGdip.DeleteRegion(Region)
return E
}
FillPolygon(pBrush, Points, FillMode:=0){
Points:=StrSplit(Points, "|")
PointF:=BufferAlloc(8*Points.Length)
Loop Points.Length
Coord:=StrSplit(Points[A_Index], ","), NumPut("float", Coord[1], "float", Coord[2], PointF, 8*(A_Index-1))
return DllCall("gdiplus\GdipFillPolygon", "Ptr", this, "Ptr", pBrush, "Ptr", PointF, "int", Points.Length, "int", FillMode)
}
FillPie(pBrush, x, y, w, h, StartAngle, SweepAngle){
return DllCall("gdiplus\GdipFillPie", "Ptr", this, "Ptr", pBrush
, "float", x, "float", y, "float", w, "float", h
, "float", StartAngle, "float", SweepAngle)
}
FillEllipse(pBrush, x, y, w, h){
return DllCall("gdiplus\GdipFillEllipse", "Ptr", this, "Ptr", pBrush, "float", x, "float", y, "float", w, "float", h)
}
FillRegion(pBrush, Region){
return DllCall("gdiplus\GdipFillRegion", "Ptr", this, "Ptr", pBrush, "Ptr", Region)
}
SetClipRect(x, y, w, h, CombineMode:=0){
return DllCall("gdiplus\GdipSetClipRect", "Ptr", this, "float", x, "float", y, "float", w, "float", h, "int", CombineMode)
}
SetClipPath(pPath, CombineMode:=0){
return DllCall("gdiplus\GdipSetClipPath", "Ptr", this, "Ptr", pPath, "int", CombineMode)
}
ResetClip(){
return DllCall("gdiplus\GdipResetClip", "Ptr", this)
}
GetClipRegion(){
Region:=CGdip.CreateRegion()
DllCall("gdiplus\GdipGetClip", "Ptr", this, "UInt", Region)
return Region
}
SetClipRegion(Region, CombineMode:=0){
return DllCall("gdiplus\GdipSetClipRegion", "Ptr", this, "Ptr", Region, "int", CombineMode)
}
; SystemDefault = 0
; SingleBitPerPixelGridFit = 1
; SingleBitPerPixel = 2
; AntiAliasGridFit = 3
; AntiAlias = 4
SetTextRenderingHint(RenderingHint:=0){
return DllCall("gdiplus\GdipSetTextRenderingHint", "Ptr", this, "int", RenderingHint)
}
SetInterpolationMode(InterpolationMode:=0){
; Default = 0
; LowQuality = 1
; HighQuality = 2
; Bilinear = 3
; Bicubic = 4
; NearestNeighbor = 5
; HighQualityBilinear = 6
; HighQualityBicubic = 7
return DllCall("gdiplus\GdipSetInterpolationMode", "Ptr", this, "int", InterpolationMode)
}
SetSmoothingMode(SmoothingMode:=0){
; Default = 0
; HighSpeed = 1
; HighQuality = 2
; None = 3
; AntiAlias = 4
return DllCall("gdiplus\GdipSetSmoothingMode", "Ptr", this, "int", SmoothingMode)
}
SetCompositingMode(CompositingMode:=0){
; CompositingModeSourceOver = 0 (blended)
; CompositingModeSourceCopy = 1 (overwrite)
return DllCall("gdiplus\GdipSetCompositingMode", "Ptr", this, "int", CompositingMode)
}
GetDC(){
if this.hdc
return this.hdc
DllCall("gdiplus\GdipGetDC", "Ptr", this, "Ptr*", hdc:=0), this.hdc:=hdc
return hdc
}
ReleaseDC(){
DllCall("gdiplus\GdipReleaseDC", "Ptr", this, "Ptr", this.hdc), this.hdc:=0
}
RotateWorldTransform(Angle, MatrixOrder:=0){
return DllCall("gdiplus\GdipRotateWorldTransform", "Ptr", this, "float", Angle, "int", MatrixOrder)
}
ScaleWorldTransform(x, y, MatrixOrder:=0){
return DllCall("gdiplus\GdipScaleWorldTransform", "Ptr", this, "float", x, "float", y, "int", MatrixOrder)
}
TranslateWorldTransform(x, y, MatrixOrder:=0){
return DllCall("gdiplus\GdipTranslateWorldTransform", "Ptr", this, "float", x, "float", y, "int", MatrixOrder)
}
ResetWorldTransform(){
return DllCall("gdiplus\GdipResetWorldTransform", "Ptr", this)
}
}
class Bitmap
{
Ptr:=0, Dispose:=0
__New(pBitmap, Dispose:=1){
if (!pBitmap)
throw "invalid pBitmap"
else
this.Ptr:=pBitmap, this.Dispose:=Dispose
}
__Delete(){
if (this.Ptr && this.Dispose && CGdip.pToken)
DllCall("gdiplus\GdipDisposeImage", "Ptr", this)
}
static FromHWND(hwnd){
WinGetPos(,, Width, Height, hwnd)
hbm:=CreateDIBSection(Width, Height), hdc:=CreateCompatibleDC(), obm:=SelectObject(hdc, hbm)
PrintWindow(hwnd, hdc)
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr", hbm, "Ptr", 0, "Ptr*", pBitmap:=0)
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
return CGdip.Bitmap.New(pBitmap)
}
static FromBase64(ByRef Base64){
If !(DllCall("crypt32\CryptStringToBinary", "Str", Base64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UInt*", DecLen:=0, "Ptr", 0, "Ptr", 0))
return -1
Dec:=BufferAlloc(DecLen)
If !(DllCall("crypt32\CryptStringToBinary", "Str", Base64, "UInt", 0, "UInt", 0x01, "Ptr", Dec, "UInt*", DecLen, "Ptr", 0, "Ptr", 0))
return -2
If !(pStream:=DllCall("shlwapi\SHCreateMemStream", "Ptr", Dec, "UInt", DecLen, "UPtr"))
return -3
DllCall("gdiplus\GdipCreateBitmapFromStreamICM", "Ptr", pStream, "Ptr*", pBitmap:=0)
DllCall("DeleteObject", "Ptr", pStream)
return CGdip.Bitmap.New(pBitmap)
}
static FromFile(sFile, IconNumber:=1, IconSize:=""){
SplitPath(sFile, , , ext)
if (ext~="i)^(exe|dll|icl)$")
{
Sizes:=IconSize ? IconSize : 256 "|" 128 "|" 64 "|" 48 "|" 32 "|" 16
BufSize:=16 + (2*(A_PtrSize ? A_PtrSize : 4))
buf:=BufferAlloc(BufSize, 0)
Loop Parse Sizes, "|"
{
DllCall("PrivateExtractIcons", "Str", sFile, "int", IconNumber-1, "int", A_LoopField, "int", A_LoopField, "Ptr*", hIcon:=0, "Ptr*", 0, "Uint", 1, "Uint", 0)
if !hIcon
continue
if !DllCall("GetIconInfo", "Ptr", hIcon, "Ptr", buf)
{
DestroyIcon(hIcon)
continue
}
hbmMask :=NumGet(buf, 12 + ((A_PtrSize ? A_PtrSize : 4) - 4))
hbmColor:=NumGet(buf, 12 + ((A_PtrSize ? A_PtrSize : 4) - 4) + (A_PtrSize ? A_PtrSize : 4))
if !(hbmColor && DllCall("GetObject", "Ptr", hbmColor, "int", BufSize, "Ptr", buf))
{
DestroyIcon(hIcon)
continue
}
break
}
if !hIcon
return -1
Width:=NumGet(buf, 4, "int"), Height:=NumGet(buf, 8, "int")
hbm:=CreateDIBSection(Width, -Height), hdc:=CreateCompatibleDC(), obm:=SelectObject(hdc, hbm)
if !DllCall("DrawIconEx", "Ptr", hdc, "int", 0, "int", 0, "Ptr", hIcon, "Uint", Width, "Uint", Height, "Uint", 0, "Ptr", 0, "Uint", 3)
{
DestroyIcon(hIcon)
return -2
}
dib:=BufferAlloc(104)
DllCall("GetObject", "Ptr", hbm, "int", A_PtrSize = 8 ? 104 : 84, "Ptr", dib) ; sizeof(DIBSECTION) = 76+2*(A_PtrSize=8?4:0)+2*A_PtrSize
Stride:=NumGet(dib, 12, "Int"), Bits:=NumGet(dib, 20 + (A_PtrSize = 8 ? 4 : 0)) ; padding
DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Width, "int", Height, "int", Stride, "int", 0x26200A, "Ptr", Bits, "Ptr*", pBitmapOld:=0)
DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Width, "int", Height, "int", 0, "int", 0x26200A, "Ptr", 0, "Ptr*", pBitmap:=0)
DllCall("gdiplus\GdipGetImageGraphicsContext", "Ptr", pBitmap, "Ptr*", G:=0)
G:=CGdip.Graphics.FromBitmap(pBitmap), G.DrawImage(pBitmapOld, 0, 0, Width, Height, 0, 0, Width, Height)
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmapOld)
DestroyIcon(hIcon)
}
else
DllCall("gdiplus\GdipCreateBitmapFromFile", "Ptr", StrPtr(sFile), "Ptr*", pBitmap:=0)
return CGdip.Bitmap.New(pBitmap)
}
static FromScreen(Screen:=0, Raster:=""){
if (Screen = 0){
x:=SySGet(76)
y:=SySGet(77)
w:=SySGet(78)
h:=SySGet(79)
}
else if (SubStr(Screen, 1, 5) = "hwnd:"){
Screen:=SubStr(Screen, 6)
if !WinExist( "ahk_id " Screen)
return -2
WinGetPos(, , w, h, "ahk_id" Screen)
x:=y:=0
hhdc:=GetDCEx(Screen, 3)
}
else if (Screen&1 != ""){
MonitorGet(Screen, x, y, w, h)
w-=x, h-=y
}
else {
S:=StrSplit(Screen, "|")
x:=S[1], y:=S[2], w:=S[3], h:=S[4]
}
if (x = "") || (y = "") || (w = "") || (h = "")
return -1
chdc:=CreateCompatibleDC(), hbm:=CreateDIBSection(w, h, chdc), obm:=SelectObject(chdc, hbm), hhdc:=hhdc ? hhdc : GetDC()
BitBlt(chdc, 0, 0, w, h, hhdc, x, y, Raster)
ReleaseDC(hhdc)
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr", hbm, "Ptr", 0, "Ptr*", pBitmap:=0)
SelectObject(chdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
return CGdip.Bitmap.New(pBitmap)
}
static FromHBITMAP(hBitmap, Palette:=0){
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr", hBitmap, "Ptr", Palette, "Ptr*", pBitmap:=0)
return CGdip.Bitmap.New(pBitmap)
}
static FromHICON(hIcon){
DllCall("gdiplus\GdipCreateBitmapFromHICON", "Ptr", hIcon, "Ptr*", pBitmap:=0)
return CGdip.Bitmap.New(pBitmap)
}
static Create(Width, Height, Format:=0x26200A){
DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Width, "int", Height, "int", 0, "int", Format, "Ptr", 0, "Ptr*", pBitmap:=0)
return CGdip.Bitmap.New(pBitmap)
}
static FromBRA(BRAFromMemIn, File, Alternate:=0){
pBitmap:=0, pStream:=0
If !(BRAFromMemIn)
Return -1
Headers:=StrSplit(StrGet(BRAFromMemIn, 256, "CP0"), "`n")
Header:=StrSplit(Headers[1], "|")
HeaderLength:=Header.Length
If (HeaderLength != 4) || (Header[2] != "BRA!")
Return -2
_Info:=StrSplit(Headers[2], "|")
_InfoLength:=_Info.Length
If (_InfoLength != 3)
Return -3
OffsetTOC:=StrPut(Headers[1], "CP0") + StrPut(Headers[2], "CP0") ; + 2
OffsetData:=_Info[2]
SearchIndex:=Alternate ? 1 : 2
TOC:=StrGet(BRAFromMemIn + OffsetTOC, OffsetData - OffsetTOC - 1, "CP0")
RX1:="mi`n)^"
Offset:=Size:=0
If RegExMatch(TOC, RX1 . (Alternate ? File "\|.+?" : "\d+\|" . File) . "\|(\d+)\|(\d+)$", FileInfo) {
Offset:=OffsetData + FileInfo[1]
Size:=FileInfo[2]
}
If (Size = 0)
Return -4
hData:=DllCall("GlobalAlloc", "UInt", 2, "UInt", Size, "UPtr")
pData:=DllCall("GlobalLock", "Ptr", hData, "UPtr")
DllCall("RtlMoveMemory", "Ptr", pData, "Ptr", BRAFromMemIn + Offset, "Ptr", Size)
DllCall("GlobalUnlock", "Ptr", hData)
DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", 1, "Ptr*", pStream)
DllCall("Gdiplus.dll\GdipCreateBitmapFromStream", "Ptr", pStream, "Ptr*", pBitmap)
ObjRelease(pStream)
Return CGdip.Bitmap.New(pBitmap)
}
static FromClipboard(){
if !DllCall("OpenClipboard", "Ptr", 0)
return -1
if !DllCall("IsClipboardFormatAvailable", "Uint", 8){
DllCall("CloseClipboard")
return -2
}
pBitmap:=0
if (hBitmap:=DllCall("GetClipboardData", "Uint", 2, "Ptr"))
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr", hBitmap, "Ptr", 0, "Ptr*", pBitmap)
, DeleteObject(hBitmap)
DllCall("CloseClipboard")
return CGdip.Bitmap.New(pBitmap)
}
SetClipboard(){
off1:=A_PtrSize = 8 ? 52 : 44, off2:=A_PtrSize = 8 ? 32 : 24
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", this, "Ptr*", hBitmap:=0, "int", 0xffffffff)
DllCall("GetObject", "Ptr", hBitmap, "int", oi:=BufferAlloc(A_PtrSize = 8 ? 104 : 84, 0), "Ptr", oi)
hdib:=DllCall("GlobalAlloc", "Uint", 2, "Ptr", 40+NumGet(oi, off1, "UInt"), "Ptr")
pdib:=DllCall("GlobalLock", "Ptr", hdib, "Ptr")
DllCall("RtlMoveMemory", "Ptr", pdib, "Ptr", oi.Ptr+off2, "Ptr", 40)
DllCall("RtlMoveMemory", "Ptr", pdib+40, "Ptr", NumGet(oi, off2 - (A_PtrSize ? A_PtrSize : 4), "Ptr"), "Ptr", NumGet(oi, off1, "UInt"))
DllCall("GlobalUnlock", "Ptr", hdib)
DllCall("DeleteObject", "Ptr", hBitmap)
DllCall("OpenClipboard", "Ptr", 0)
DllCall("EmptyClipboard")
DllCall("SetClipboardData", "Uint", 8, "Ptr", hdib)
DllCall("CloseClipboard")
}
CreateHBITMAP(Background:=0xffffffff){
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", this, "Ptr*", hbm:=0, "int", Background)
return hbm
}
CreateHICON(){
DllCall("gdiplus\GdipCreateHICONFromBitmap", "Ptr", this, "Ptr*", hIcon:=0)
return hIcon
}
CloneArea(x, y, w, h, Format:=0x26200A){
DllCall("gdiplus\GdipCloneBitmapArea"
, "float", x, "float", y, "float", w, "float", h
, "int", Format, "Ptr", this, "Ptr*", pBitmapDest:=0)
return pBitmapDest
}
RotateFlip(RotateFlipType:=1){
return DllCall("gdiplus\GdipImageRotateFlip", "Ptr", this, "int", RotateFlipType)
}
Save(sOutput, Quality:=75){
SplitPath(sOutput,,, Extension, Name)
if !(Extension~="i)^(BMP|DIB|RLE|JPG|JPEG|JPE|JFIF|GIF|TIF|TIFF|PNG)$")
return -1
Extension:="." Extension
DllCall("gdiplus\GdipGetImageEncodersSize", "Uint*", nCount:=0, "Uint*", nSize:=0)
ci:=BufferAlloc(nSize)
DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "Ptr", ci)
if !(nCount && nSize)
return -2
Loop nCount
{
sString:=StrGet(NumGet(ci, (idx:=(48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize, "Ptr"), "UTF-16")
if !InStr(sString, "*" Extension)
continue
pCodec:=ci.Ptr+idx
break
}
if !pCodec
return -3
p:=0
if (Quality != 75)
{
Quality:=(Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
if (Extension~="i)^(\.JPG|\.JPEG|\.JPE|\.JFIF)$")
{
DllCall("gdiplus\GdipGetEncoderParameterListSize", "Ptr", this, "Ptr", pCodec, "Uint*", nSize:=0)
EncoderParameters:=BufferAlloc(nSize, 0)
DllCall("gdiplus\GdipGetEncoderParameterList", "Ptr", this, "Ptr", pCodec, "Uint", nSize, "Ptr", EncoderParameters)
Loop NumGet(EncoderParameters, "UInt") ;%
{
elem:=(24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad:=A_PtrSize = 8 ? 4 : 0)
if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
{
p:=elem+EncoderParameters.Ptr-pad-4
NumPut("UInt", Quality, NumGet(NumPut("UInt", 4, NumPut("UInt", 1, p+0)+20), "Ptr"))
break
}
}
}
}
if Name
E:=DllCall("gdiplus\GdipSaveImageToFile", "Ptr", this, "Ptr", StrPtr(sOutput), "Ptr", pCodec, "Uint", p)
else {
DllCall("ole32\CreateStreamOnHGlobal", "Ptr", 0, "Int", 1, "Ptr*", pStream:=0)
DllCall("gdiplus\GdipSaveImageToStream", "Ptr", this, "Ptr", pStream, "Ptr", pCodec, "UInt", p)
return pStream
}
return E ? -5 : 0
}
GetPixel(x, y){
DllCall("gdiplus\GdipBitmapGetPixel", "Ptr", this, "int", x, "int", y, "Uint*", ARGB:=0)
return ARGB
}
SetPixel(x, y, ARGB){
return DllCall("gdiplus\GdipBitmapSetPixel", "Ptr", this, "int", x, "int", y, "int", ARGB)
}
GetWidth(){
return CGdip.GetImageWidth(this)
}
GetHeight(){
return CGdip.GetImageHeight(this)
}
GetDimensions(ByRef Width, ByRef Height){
CGdip.GetImageDimensions(this, Width, Height)
}
GetPixelFormat(){
DllCall("gdiplus\GdipGetImagePixelFormat", "Ptr", this, "UInt*", Format:=0)
return Format
}
LockBits(x, y, w, h, ByRef Stride, ByRef Scan0, ByRef BitmapData, LockMode:=3, PixelFormat:=0x26200a){
CreateRect(_Rect, x, y, w, h), BitmapData:=BufferAlloc(16+2*A_PtrSize, 0)
_E:=DllCall("Gdiplus\GdipBitmapLockBits", "Ptr", this, "Ptr", _Rect, "Uint", LockMode, "int", PixelFormat, "Ptr", BitmapData)
Stride:=NumGet(BitmapData, 8, "Int")
Scan0:=NumGet(BitmapData, 16, "Ptr")
return _E
}
UnlockBits(BitmapData){
return DllCall("Gdiplus\GdipBitmapUnlockBits", "Ptr", this, "Ptr", BitmapData)
}
SetLockBitPixel(ARGB, Scan0, x, y, Stride){
NumPut("UInt", ARGB, Scan0+0, (x*4)+(y*Stride))
}
GetLockBitPixel(Scan0, x, y, Stride){
return NumGet(Scan0+0, (x*4)+(y*Stride), "UInt")
}
Pixelate(ByRef pBitmapOut, BlockSize){
static PixelateBitmap:=""
if (PixelateBitmap = "") {
if A_PtrSize != 8 ; x86 machine code
MCode_PixelateBitmap:="
(LTrim Join
558BEC83EC3C8B4514538B5D1C99F7FB56578BC88955EC894DD885C90F8E830200008B451099F7FB8365DC008365E000894DC88955F08945E833FF897DD4
397DE80F8E160100008BCB0FAFCB894DCC33C08945F88945FC89451C8945143BD87E608B45088D50028BC82BCA8BF02BF2418945F48B45E02955F4894DC4
8D0CB80FAFCB03CA895DD08BD1895DE40FB64416030145140FB60201451C8B45C40FB604100145FC8B45F40FB604020145F883C204FF4DE475D6034D18FF
4DD075C98B4DCC8B451499F7F98945148B451C99F7F989451C8B45FC99F7F98945FC8B45F899F7F98945F885DB7E648B450C8D50028BC82BCA83C103894D
C48BC82BCA41894DF48B4DD48945E48B45E02955E48D0C880FAFCB03CA895DD08BD18BF38A45148B7DC48804178A451C8B7DF488028A45FC8804178A45F8
8B7DE488043A83C2044E75DA034D18FF4DD075CE8B4DCC8B7DD447897DD43B7DE80F8CF2FEFFFF837DF0000F842C01000033C08945F88945FC89451C8945
148945E43BD87E65837DF0007E578B4DDC034DE48B75E80FAF4D180FAFF38B45088D500203CA8D0CB18BF08BF88945F48B45F02BF22BFA2955F48945CC0F
B6440E030145140FB60101451C0FB6440F010145FC8B45F40FB604010145F883C104FF4DCC75D8FF45E4395DE47C9B8B4DF00FAFCB85C9740B8B451499F7
F9894514EB048365140033F63BCE740B8B451C99F7F989451CEB0389751C3BCE740B8B45FC99F7F98945FCEB038975FC3BCE740B8B45F899F7F98945F8EB
038975F88975E43BDE7E5A837DF0007E4C8B4DDC034DE48B75E80FAF4D180FAFF38B450C8D500203CA8D0CB18BF08BF82BF22BFA2BC28B55F08955CC8A55
1488540E038A551C88118A55FC88540F018A55F888140183C104FF4DCC75DFFF45E4395DE47CA68B45180145E0015DDCFF4DC80F8594FDFFFF8B451099F7
FB8955F08945E885C00F8E450100008B45EC0FAFC38365DC008945D48B45E88945CC33C08945F88945FC89451C8945148945103945EC7E6085DB7E518B4D
D88B45080FAFCB034D108D50020FAF4D18034DDC8BF08BF88945F403CA2BF22BFA2955F4895DC80FB6440E030145140FB60101451C0FB6440F010145FC8B
45F40FB604080145F883C104FF4DC875D8FF45108B45103B45EC7CA08B4DD485C9740B8B451499F7F9894514EB048365140033F63BCE740B8B451C99F7F9
89451CEB0389751C3BCE740B8B45FC99F7F98945FCEB038975FC3BCE740B8B45F899F7F98945F8EB038975F88975103975EC7E5585DB7E468B4DD88B450C
0FAFCB034D108D50020FAF4D18034DDC8BF08BF803CA2BF22BFA2BC2895DC88A551488540E038A551C88118A55FC88540F018A55F888140183C104FF4DC8
75DFFF45108B45103B45EC7CAB8BC3C1E0020145DCFF4DCC0F85CEFEFFFF8B4DEC33C08945F88945FC89451C8945148945103BC87E6C3945F07E5C8B4DD8
8B75E80FAFCB034D100FAFF30FAF4D188B45088D500203CA8D0CB18BF08BF88945F48B45F02BF22BFA2955F48945C80FB6440E030145140FB60101451C0F
B6440F010145FC8B45F40FB604010145F883C104FF4DC875D833C0FF45108B4DEC394D107C940FAF4DF03BC874068B451499F7F933F68945143BCE740B8B
451C99F7F989451CEB0389751C3BCE740B8B45FC99F7F98945FCEB038975FC3BCE740B8B45F899F7F98945F8EB038975F88975083975EC7E63EB0233F639
75F07E4F8B4DD88B75E80FAFCB034D080FAFF30FAF4D188B450C8D500203CA8D0CB18BF08BF82BF22BFA2BC28B55F08955108A551488540E038A551C8811
8A55FC88540F018A55F888140883C104FF4D1075DFFF45088B45083B45EC7C9F5F5E33C05BC9C21800
)"
else ; x64 machine code
MCode_PixelateBitmap:="
(LTrim Join
4489442418488954241048894C24085355565741544155415641574883EC28418BC1448B8C24980000004C8BDA99488BD941F7F9448BD0448BFA8954240C
448994248800000085C00F8E9D020000418BC04533E4458BF299448924244C8954241041F7F933C9898C24980000008BEA89542404448BE889442408EB05
4C8B5C24784585ED0F8E1A010000458BF1418BFD48897C2418450FAFF14533D233F633ED4533E44533ED4585C97E5B4C63BC2490000000418D040A410FAF
C148984C8D441802498BD9498BD04D8BD90FB642010FB64AFF4403E80FB60203E90FB64AFE4883C2044403E003F149FFCB75DE4D03C748FFCB75D0488B7C
24188B8C24980000004C8B5C2478418BC59941F7FE448BE8418BC49941F7FE448BE08BC59941F7FE8BE88BC69941F7FE8BF04585C97E4048639C24900000
004103CA4D8BC1410FAFC94863C94A8D541902488BCA498BC144886901448821408869FF408871FE4883C10448FFC875E84803D349FFC875DA8B8C249800
0000488B5C24704C8B5C24784183C20448FFCF48897C24180F850AFFFFFF8B6C2404448B2424448B6C24084C8B74241085ED0F840A01000033FF33DB4533
DB4533D24533C04585C97E53488B74247085ED7E42438D0C04418BC50FAF8C2490000000410FAFC18D04814863C8488D5431028BCD0FB642014403D00FB6
024883C2044403D80FB642FB03D80FB642FA03F848FFC975DE41FFC0453BC17CB28BCD410FAFC985C9740A418BC299F7F98BF0EB0233F685C9740B418BC3
99F7F9448BD8EB034533DB85C9740A8BC399F7F9448BD0EB034533D285C9740A8BC799F7F9448BC0EB034533C033D24585C97E4D4C8B74247885ED7E3841
8D0C14418BC50FAF8C2490000000410FAFC18D04814863C84A8D4431028BCD40887001448818448850FF448840FE4883C00448FFC975E8FFC2413BD17CBD
4C8B7424108B8C2498000000038C2490000000488B5C24704503E149FFCE44892424898C24980000004C897424100F859EFDFFFF448B7C240C448B842480
000000418BC09941F7F98BE8448BEA89942498000000896C240C85C00F8E3B010000448BAC2488000000418BCF448BF5410FAFC9898C248000000033FF33
ED33F64533DB4533D24533C04585FF7E524585C97E40418BC5410FAFC14103C00FAF84249000000003C74898488D541802498BD90FB642014403D00FB602
4883C2044403D80FB642FB03F00FB642FA03E848FFCB75DE488B5C247041FFC0453BC77CAE85C9740B418BC299F7F9448BE0EB034533E485C9740A418BC3
99F7F98BD8EB0233DB85C9740A8BC699F7F9448BD8EB034533DB85C9740A8BC599F7F9448BD0EB034533D24533C04585FF7E4E488B4C24784585C97E3541
8BC5410FAFC14103C00FAF84249000000003C74898488D540802498BC144886201881A44885AFF448852FE4883C20448FFC875E941FFC0453BC77CBE8B8C
2480000000488B5C2470418BC1C1E00203F849FFCE0F85ECFEFFFF448BAC24980000008B6C240C448BA4248800000033FF33DB4533DB4533D24533C04585
FF7E5A488B7424704585ED7E48418BCC8BC5410FAFC94103C80FAF8C2490000000410FAFC18D04814863C8488D543102418BCD0FB642014403D00FB60248
83C2044403D80FB642FB03D80FB642FA03F848FFC975DE41FFC0453BC77CAB418BCF410FAFCD85C9740A418BC299F7F98BF0EB0233F685C9740B418BC399
F7F9448BD8EB034533DB85C9740A8BC399F7F9448BD0EB034533D285C9740A8BC799F7F9448BC0EB034533C033D24585FF7E4E4585ED7E42418BCC8BC541
0FAFC903CA0FAF8C2490000000410FAFC18D04814863C8488B442478488D440102418BCD40887001448818448850FF448840FE4883C00448FFC975E8FFC2
413BD77CB233C04883C428415F415E415D415C5F5E5D5BC3
)"
PixelateBitmap:=BufferAlloc(nCount:=StrLen(MCode_PixelateBitmap)//2)
if (!DllCall("crypt32\CryptStringToBinary", "Str", MCode_PixelateBitmap, "Uint", 0, "Uint", 4, "Ptr", PixelateBitmap, "Uint*", nCount, "Ptr", 0, "Ptr", 0)){
Loop nCount
NumPut("UChar", ("0x" SubStr(MCode_PixelateBitmap, (2*A_Index)-1, 2)) + 0, PixelateBitmap, A_Index-1)
}
DllCall("VirtualProtect", "Ptr", PixelateBitmap, "UInt", nCount, "Uint", 0x40, "Uint*", 0)
}
this.GetDimensions(Width:=0, Height:=0), cBO:=CGdip.Bitmap.New(pBitmapOut, 0)
if (Width != cBO.GetWidth() || Height != cBO.GetHeight())
return -1
if (BlockSize > Width || BlockSize > Height)
return -2
E1:=this.LockBits(0, 0, Width, Height, Stride1:=0, Scan01:=0, BitmapData1:="")
E2:=cBO.LockBits(0, 0, Width, Height, Stride2:=0, Scan02:=0, BitmapData2:="")
if (E1 || E2)
return -3
; E:=- unused exit code
DllCall(PixelateBitmap, "Ptr", Scan01, "Ptr", Scan02, "int", Width, "int", Height, "int", Stride1, "int", BlockSize)
this.UnlockBits(BitmapData1), cBO.UnlockBits(BitmapData2)
return 0
}
}
class StringFormat
{
Ptr:=0
__New(Format:="", LineAlign:=0, Align:=0){
; StringFormatFlagsDirectionRightToLeft = 0x00000001
; StringFormatFlagsDirectionVertical = 0x00000002
; StringFormatFlagsNoFitBlackBox = 0x00000004
; StringFormatFlagsDisplayFormatControl = 0x00000020
; StringFormatFlagsNoFontFallback = 0x00000400
; StringFormatFlagsMeasureTrailingSpaces = 0x00000800
; StringFormatFlagsNoWrap = 0x00001000
; StringFormatFlagsLineLimit = 0x00002000
; StringFormatFlagsNoClip = 0x00004000
if (Format="")
DllCall("gdiplus\GdipStringFormatGetGenericDefault", "Ptr*", hFormat:=0)
else DllCall("gdiplus\GdipCreateStringFormat", "int", Format, "int", 0, "Ptr*", hFormat:=0)
if (Align){
; Near = 0 Center = 1 Far = 2
DllCall("gdiplus\GdipSetStringFormatAlign", "Ptr", hFormat, "int", Align)
}
if (LineAlign){
; Near = 0 Center = 1 Far = 2
DllCall("gdiplus\GdipSetStringFormatLineAlign", "Ptr", hFormat, "int", LineAlign)
}
this.Ptr:=hFormat
if !hFormat
throw "Create StringFormat Failed"
}
__Delete(){
if (this.Ptr && CGdip.pToken)
DllCall("gdiplus\GdipDeleteStringFormat", "Ptr", this)
}
}
class Font
{
static FontFamilys:=Map(), FontFamilys.CaseSense:="Off"
Ptr:=0, prop:="", font:=""
__New(font, size, style:=0){
; Regular = 0
; Bold = 1
; Italic = 2
; BoldItalic = 3
; Underline = 4
; Strikeout = 8
FontFamilys:=CGdip.Font.FontFamilys
if !FontFamilys.Has(font){
DllCall("gdiplus\GdipCreateFontFamilyFromName", "Ptr", StrPtr(Font), "Uint", 0, "Ptr*", hFamily:=0)
if (!hFamily)
throw "Create Font Family Failed"
FontFamilys[font]:={Ptr:hFamily, Fonts:Map()}
} else hFamily:=FontFamilys[font].Ptr
prop:=size " " style
if FontFamilys[font].Fonts.Has(prop)
this.Ptr:=FontFamilys[font].Fonts[prop].Ptr, FontFamilys[font].Fonts[prop].RefCount++
else {
DllCall("gdiplus\GdipCreateFont", "Ptr", hFamily, "float", Size, "int", Style, "int", 0, "Ptr*", hFont:=0)
if (!hFont){
if (!FontFamilys[font].Fonts.Count)
DllCall("gdiplus\GdipDeleteFontFamily", "Ptr", hFamily), FontFamilys.Delete(font)
throw "Create Font Failed"
}
FontFamilys[font].Fonts[prop]:={Ptr:(this.Ptr:=hFont), RefCount:1}
}
this.prop:=prop, this.font:=font
}
__Delete(){
FontFamilys:=CGdip.Font.FontFamilys
if (!CGdip.pToken)
return FontFamilys.Clear()
if (!this.Ptr||(--FontFamilys[this.font].Fonts[this.prop].RefCount))
return
FontFamilys[this.font].Fonts.Delete(this.prop)
DllCall("gdiplus\GdipDeleteFont", "Ptr", this)
if (!FontFamilys[this.font].Fonts.Count)
DllCall("gdiplus\GdipDeleteFontFamily", "Ptr", FontFamilys[this.font])
, FontFamilys.Delete(this.font)
}
}
class Pen
{
static Pens:=Map(), Pens.CaseSense:="Off"
Ptr:=0, prop:=""
__New(pPen, prop:=""){
if (!pPen)
throw "invalid pPen"
this.Ptr:=pPen
if (this.prop:=prop){
Pens:=CGdip.Pen.Pens
if (!Pens.Has(prop))
Pens[prop]:={Ptr:pPen, RefCount:1}
else Pens[prop].RefCount++
}
}
__Delete(){
Pens:=CGdip.Pen.Pens
if (!CGdip.pToken)
return Pens.Clear()
if (!this.Ptr)
return
if (this.prop&&Pens.Has(this.prop)){
if (--Pens[this.prop].RefCount)
return
Pens.Delete(this.prop)
}
DllCall("gdiplus\GdipDeletePen", "Ptr", this)
}
static Create(ARGB, w){
prop:=Format("{:x}|{:.1f}", ARGB, w), Pens:=CGdip.Pen.Pens
if Pens.Has(prop)
return CGdip.Pen.New(Pens[prop].Ptr, prop)
DllCall("gdiplus\GdipCreatePen1", "UInt", ARGB, "float", w, "int", 2, "Ptr*", pPen:=0)
return CGdip.Pen.New(pPen, prop)
}
static FromBrush(pBrush, w){
DllCall("gdiplus\GdipCreatePen2", "Ptr", pBrush, "float", w, "int", 2, "Ptr*", pPen:=0)
return CGdip.Pen.New(pPen)
}
}
class Brush
{
static SolidBrushs:=Map(), SolidBrushs.CaseSense:="Off"
Ptr:=0, prop:=""
__New(pBrush, prop:=""){
if (!pBrush)
throw "invalid pBrush"
this.Ptr:=pBrush
if (this.prop:=prop){
SolidBrushs:=CGdip.Brush.SolidBrushs
if (!SolidBrushs.Has(prop))
SolidBrushs[prop]:={Ptr:pBrush, RefCount:1}
else SolidBrushs[prop].RefCount++
}
}
__Delete(){
SolidBrushs:=CGdip.Brush.SolidBrushs
if (!CGdip.pToken)
return SolidBrushs.Clear()
if (!this.Ptr)
return
if (this.prop&&SolidBrushs.Has(this.prop)){
if (--SolidBrushs[this.prop].RefCount)
return
SolidBrushs.Delete(this.prop)
}
DllCall("gdiplus\GdipDeleteBrush", "Ptr", this)
}
static SolidFill(ARGB:=0xff000000){
if (Type(ARGB) = "String" && ARGB~="i)^[a-f\d]+$")
ARGB:=Integer("0x" ARGB)
prop:=Format("{:x}", ARGB), SolidBrushs:=CGdip.Brush.SolidBrushs
if SolidBrushs.Has(prop)
return CGdip.Brush.New(SolidBrushs[prop].Ptr, prop)
DllCall("gdiplus\GdipCreateSolidFill", "UInt", ARGB, "Ptr*", pBrush:=0)
return CGdip.Brush.New(pBrush, prop)
}
static HatchBrush(ARGBfront, ARGBback, HatchStyle:=0){
DllCall("gdiplus\GdipCreateHatchBrush", "int", HatchStyle, "UInt", ARGBfront, "UInt", ARGBback, "Ptr*", pBrush:=0)
return CGdip.Brush.New(pBrush)
}
static TextureBrush(pBitmap, WrapMode:=1, x:=0, y:=0, w:="", h:=""){
pBrush:=0
if !(w && h)
DllCall("gdiplus\GdipCreateTexture", "Ptr", pBitmap, "int", WrapMode, "Ptr*", pBrush)
else
DllCall("gdiplus\GdipCreateTexture2", "Ptr", pBitmap, "int", WrapMode, "float", x, "float", y, "float", w, "float", h, "Ptr*", pBrush)
return CGdip.Brush.New(pBrush)
}
static LineBrush(x1, y1, x2, y2, ARGB1, ARGB2, WrapMode:=1){
; WrapModeTile = 0
; WrapModeTileFlipX = 1
; WrapModeTileFlipY = 2
; WrapModeTileFlipXY = 3
; WrapModeClamp = 4
CreatePointF(PointF1, x1, y1), CreatePointF(PointF2, x2, y2)
DllCall("gdiplus\GdipCreateLineBrush", "Ptr", PointF1, "Ptr", PointF2, "Uint", ARGB1, "Uint", ARGB2, "int", WrapMode, "Ptr*", LGpBrush:=0)
return CGdip.Brush.New(LGpBrush)
}
static LineBrushFromRect(x, y, w, h, ARGB1, ARGB2, LinearGradientMode:=1, WrapMode:=1){
; LinearGradientModeHorizontal = 0
; LinearGradientModeVertical = 1
; LinearGradientModeForwardDiagonal = 2
; LinearGradientModeBackwardDiagonal = 3
CreateRectF(RectF, x, y, w, h)
DllCall("gdiplus\GdipCreateLineBrushFromRect", "Ptr", RectF, "int", ARGB1, "int", ARGB2, "int", LinearGradientMode, "int", WrapMode, "Ptr*", LGpBrush:=0)
return CGdip.Brush.New(LGpBrush)
}
Clone(){
DllCall("gdiplus\GdipCloneBrush", "Ptr", this, "Ptr*", pBrushClone:=0)
return CGdip.Brush.New(pBrushClone)
}
}
class Matrix
{
Ptr:=0
__New(params*){
if (params.Length=6)
DllCall("gdiplus\GdipCreateMatrix2", "float", params[1], "float", params[2], "float", params[3]
, "float", params[4], "float", params[5], "float", params[6], "Ptr*", Matrix:=0)
else
DllCall("gdiplus\GdipCreateMatrix", "Ptr*", Matrix:=0)
if Matrix
this.Ptr:=Matrix
else
throw "Create Matrix Failed"
}
__Delete(){
if (this.Ptr&&CGdip.pToken)
DllCall("gdiplus\GdipDeleteMatrix", "Ptr", this)
}
}
}
CreateCompatibleBitmap(hdc, w, h){
return DllCall("gdi32\CreateCompatibleBitmap", "Ptr", hdc, "int", w, "int", h)
}
CreateDIBSection(w, h, hdc:="", bpp:=32, ByRef ppvBits:=0){
hdc2:=hdc ? hdc : GetDC()
bi:=BufferAlloc(40, 0)
NumPut("Uint", 40, "Uint", Integer(w), "Uint", Integer(h), "ushort", 1, "ushort", bpp, "uInt", 0, bi, 0)
hbm:=DllCall("CreateDIBSection", "Ptr", hdc2, "Ptr", bi, "Uint", 0, "Ptr*", ppvBits, "Ptr", 0, "Uint", 0, "Ptr")
if !hdc
ReleaseDC(hdc2)
return hbm
}
PrintWindow(hwnd, hdc, Flags:=0){
return DllCall("PrintWindow", "Ptr", hwnd, "Ptr", hdc, "Uint", Flags)
}
PaintDesktop(hdc){
return DllCall("PaintDesktop", "Ptr", hdc)
}
DestroyIcon(hIcon){
return DllCall("DestroyIcon", "Ptr", hIcon)
}
CreateCompatibleDC(hdc:=0){
return DllCall("CreateCompatibleDC", "Ptr", hdc)
}
SelectObject(hdc, hgdiobj){
return DllCall("SelectObject", "Ptr", hdc, "Ptr", hgdiobj)
}
DeleteObject(hObject){
return DllCall("DeleteObject", "Ptr", hObject)
}
GetDC(hwnd:=0){
return DllCall("GetDC", "Ptr", hwnd)
}
GetDCEx(hwnd, flags:=0, hrgnClip:=0){
return DllCall("GetDCEx", "Ptr", hwnd, "Ptr", hrgnClip, "int", flags)
}
ReleaseDC(hdc, hwnd:=0){
return DllCall("ReleaseDC", "Ptr", hwnd, "Ptr", hdc)
}
DeleteDC(hdc){
return DllCall("DeleteDC", "Ptr", hdc)
}
CreateRectF(ByRef RectF, x, y, w, h){
RectF:=BufferAlloc(16)
NumPut("float", x, "float", y, "float", w, "float", h, RectF, 0)
}
CreateRect(ByRef Rect, x, y, w, h){
Rect:=BufferAlloc(16)
NumPut("Uint", x, "Uint", y, "Uint", w, "Uint", h, Rect, 0)
}
CreateSizeF(ByRef SizeF, w, h){
SizeF:=BufferAlloc(8)
NumPut("float", w, "float", h, SizeF, 0)
}
CreatePointF(ByRef PointF, x, y){
PointF:=BufferAlloc(8)
NumPut("float", x, "float", y, PointF, 0)
}
SetSysColorToControl(hwnd, SysColor:=15){
WinGetPos(, , w, h, Integer(hwnd))
bc:=DllCall("GetSysColor", "Int", SysColor, "UInt")
BrushClear:=CGdip.Brush.SolidFill(0xff000000 | (bc >> 16 | bc & 0xff00 | (bc & 0xff) << 16))
Bitmap:=CGdip.Bitmap.Create(w, h), G:=CGdip.Graphics.FromBitmap(Bitmap)
G.FillRectangle(BrushClear, 0, 0, w, h)
hBitmap:=Bitmap.CreateHBITMAP()
SetImage(hwnd, hBitmap)
DeleteObject(hBitmap)
return 0
}
SetImage(hwnd, hBitmap){
E:=SendMessage(0x172, 0x0, hBitmap,, Integer(hwnd))
DeleteObject(E)
return E
}
SetStretchBltMode(hdc, iStretchMode:=4){
; STRETCH_ANDSCANS = 0x01
; STRETCH_ORSCANS = 0x02
; STRETCH_DELETESCANS = 0x03
; STRETCH_HALFTONE = 0x04
return DllCall("gdi32\SetStretchBltMode", "Ptr", hdc, "int", iStretchMode)
}
StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster:=""){
return DllCall("gdi32\StretchBlt", "Ptr", ddc, "int", dx, "int", dy, "int", dw, "int", dh
, "Ptr", sdc, "int", sx, "int", sy, "int", sw, "int", sh, "Uint", Raster ? Raster : 0x00CC0020)
}
BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster:=""){
; BLACKNESS = 0x00000042
; NOTSRCERASE = 0x001100A6
; NOTSRCCOPY = 0x00330008
; SRCERASE = 0x00440328
; DSTINVERT = 0x00550009
; PATINVERT = 0x005A0049
; SRCINVERT = 0x00660046
; SRCAND = 0x008800C6
; MERGEPAINT = 0x00BB0226
; MERGECOPY = 0x00C000CA
; SRCCOPY = 0x00CC0020
; SRCPAINT = 0x00EE0086
; PATCOPY = 0x00F00021
; PATPAINT = 0x00FB0A09
; WHITENESS = 0x00FF0062
; CAPTUREBLT = 0x40000000
; NOMIRRORBITMAP = 0x80000000
return DllCall("gdi32\BitBlt", "Ptr", dDC, "int", dx, "int", dy, "int", dw, "int", dh
, "Ptr", sDC, "int", sx, "int", sy, "Uint", Raster ? Raster : 0x00CC0020)
}
UpdateLayeredWindow(hwnd, hdc, x:="", y:="", w:="", h:="", Alpha:=255){
if (x != "" && y != "")
pt:=BufferAlloc(8), NumPut("UInt", Integer(x), "UInt", Integer(y), pt, 0)
if (w = "" || h = "")
WinGetPos(, , w, h, Integer(hwnd))
return DllCall("UpdateLayeredWindow", "Ptr", hwnd, "Ptr", 0, "Ptr", ((x = "") && (y = "")) ? 0 : pt
, "int64*", Integer(w)|Integer(h)<<32, "Ptr", hdc, "int64*", 0, "Uint", 0, "UInt*", Alpha<<16|1<<24, "Uint", 2)
}
MDMF_FromPoint(X :="", Y:="") {
If (X = "" || Y = "") {
PT:=BufferAlloc(8, 0)
DllCall("User32.dll\GetCursorPos", "Ptr", PT)
X:=X = "" ? NumGet(PT, 0, "Int") : X
Y:=Y = "" ? NumGet(PT, 4, "Int") : Y
}
Return DllCall("User32.dll\MonitorFromPoint", "Int64", (X & 0xFFFFFFFF) | (Y << 32), "UInt", 0, "Ptr")
}
MDMF_GetInfo(HMON) {
MIEX:=BufferAlloc(40 + 64)
NumPut("UInt", MIEX.Size, MIEX, 0)
If DllCall("User32.dll\GetMonitorInfo", "Ptr", HMON, "Ptr", MIEX) {
MonName:=StrGet(MIEX.Ptr + 40, 32) ; CCHDEVICENAME = 32
MonNum:=RegExReplace(MonName, ".*(\d+)$", "$1")
Return { Name: (Name:=StrGet(MIEX.Ptr + 40, 32))
, Num: RegExReplace(Name, ".*(\d+)$", "$1")
, Left: NumGet(MIEX, 4, "Int") ; display rectangle
, Top: NumGet(MIEX, 8, "Int") ; "
, Right: NumGet(MIEX, 12, "Int") ; "
, Bottom: NumGet(MIEX, 16, "Int") ; "
, WALeft: NumGet(MIEX, 20, "Int") ; work area
, WATop: NumGet(MIEX, 24, "Int") ; "
, WARight: NumGet(MIEX, 28, "Int") ; "
, WABottom: NumGet(MIEX, 32, "Int") ; "
, Primary: NumGet(MIEX, 36, "UInt")} ; contains a non-zero value for the primary monitor.
}
Return False
}
GetRotatedTranslation(Width, Height, Angle, ByRef xTranslation, ByRef yTranslation){
pi:=3.14159, TAngle:=Angle*(pi/180)
Bound:=(Angle >= 0) ? Mod(Angle, 360) : 360-Mod(-Angle, -360)
if ((Bound >= 0) && (Bound <= 90))
xTranslation:=Height*Sin(TAngle), yTranslation:=0
else if ((Bound > 90) && (Bound <= 180))
xTranslation:=(Height*Sin(TAngle))-(Width*Cos(TAngle)), yTranslation:=-Height*Cos(TAngle)
else if ((Bound > 180) && (Bound <= 270))
xTranslation:=-(Width*Cos(TAngle)), yTranslation:=-(Height*Cos(TAngle))-(Width*Sin(TAngle))
else if ((Bound > 270) && (Bound <= 360))
xTranslation:=0, yTranslation:=-Width*Sin(TAngle)
}
GetRotatedDimensions(Width, Height, Angle, ByRef RWidth, ByRef RHeight){
pi:=3.1415926, TAngle:=Angle*(pi/180)
if !(Width && Height)
return -1
RWidth:=Ceil(Abs(Width*Cos(TAngle))+Abs(Height*Sin(TAngle)))
RHeight:=Ceil(Abs(Width*Sin(TAngle))+Abs(Height*Cos(Tangle)))
}
示例,画一幅图并保存为png格式
#DllLoad GdiPlus.dll
#Include CGdip.ahk
; Start gdi+
CGdip.Startup()
; Create a 400x400 pixel gdi+ bitmap
pBitmap := CGdip.Bitmap.Create(400, 400)
; Get a pointer to the graphics of the bitmap, for use with drawing functions
G := CGdip.Graphics.FromBitmap(pBitmap)
; Set the smoothing mode to antialias = 4 to make shapes appear smoother (only used for vector drawing and filling)
G.SetSmoothingMode(4)
; Create a hatched brush with background and foreground colours specified (HatchStyleBackwardDiagonal = 3)
pBrush := CGdip.Brush.HatchBrush(0xff553323, 0xffc09e8e, 31)
; Draw into the graphics of the bitmap from coordinates (100,80) a filled rectangle with 200 width and 250 height using the brush created
G.FillRectangle(pBrush, (400-200)//2, (400-250)//2, 200, 250)
; Create a hatched brush with background and foreground colours specified (HatchStyleBackwardDiagonal = 3)
pBrush := CGdip.Brush.HatchBrush(0xff000000, 0xff4d3538, 31)
; Draw an ellipse into the graphics with the brush we just created. 40 degree sweep angle starting at 250 degrees (0 degrees from right horizontal)
G.FillPie(pBrush, (400-80)//2, (400-80)//2, 80, 80, 250, 40)
; Delete the brush created to save memory as we don't need the same brush anymore
pBrush:=""
; Create a white brush
pBrushWhite := CGdip.Brush.SolidFill(0xffffffff)
; Create a black brush
pBrushBlack := CGdip.Brush.SolidFill(0xff000000)
; Loop to draw 2 ellipses filling them with white then black in the centre of each
Loop 2
{
x := (A_Index = 1) ? 120 : 220, y := 100
G.FillEllipse(pBrushWhite, x, y, 60, 60)
x += 15, y+=15
G.FillEllipse(pBrushBlack, x, y, 30, 30)
}
; Delete both brushes
pBrushWhite:=pBrushBlack:=""
; Create a hatched brush with background and foreground colours specified (HatchStyle30Percent = 10)
pBrush := CGdip.Brush.HatchBrush(0xfff22231, 0xffa10f19, 10)
; Again draw another ellipse into the graphics with the specified brush
G.FillPie(pBrush, 150, 200, 100, 80, 0, 180)
; Delete the brush
pBrush:=""
; Create a 3 pixel wide slightly transparent black pen
pPen := CGdip.Pen.Create(0xbb000000, 3)
; Create some coordinates for the lines in format x1,y1,x2,y2 then loop and draw all the lines
Lines := "180,200,130,220|180,190,130,195|220,200,270,220|220,190,270,195"
for k,v in StrSplit(Lines, "|")
{
Pos := StrSplit(v, ",")
G.DrawLine(pPen, Pos[1], Pos[2], Pos[3], Pos[4])
}
; Delete the pen
pPen:=""
; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui1:=Gui.New("-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs")
Gui1.Show("NA")
; Get the width and height of the bitmap
Width := pBitmap.GetWidth(), Height := pBitmap.GetHeight()
hbm := pBitmap.CreateHBITMAP()
; Get a device context compatible with the screen
hdc := CreateCompatibleDC()
; Select the bitmap into the device context
obm := SelectObject(hdc, hbm)
; 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
UpdateLayeredWindow(Gui1.Hwnd, hdc, (A_ScreenWidth-Width)//2, 0, Width, Height)
; 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)
; Save the bitmap to file "File.png" (extension can be .png,.bmp,.jpg,.tiff,.gif)
; Bear in mind transparencies may be lost with some image formats and will appear black
if MsgBox("Bitmap saved as 'File.png' ", , 4)="Yes"
pBitmap.Save("File.png")
; The bitmap can be deleted
pBitmap:=""
; The graphics may now be deleted
G:=""
; ...and gdi+ may now be shutdown
CGdip.Shutdown()
ExitApp
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
搞个v2的btt就屌了