另一个例子:https://www.autohotkey.com/boards/viewtopic.php?p=453660#p453660

 

Gdip下拉列表示例 By Hellbent.ahk

;*****************************************************************************************************
;~ #Include <PopUpWindow_V2> ; At the bottom of the script【可不用】
;*****************************************************************************************************
#SingleInstance, Force
SetBatchlines, -1
;~ SetMouseDelay, 1
;~ CoordMode, Mouse, Screen
#NoEnv
GDIP_STARTUP()


FontList := []
testList := GetFontNames( 1 )
ddlList := ""
for k, v in testList	{
  if( inStr( k , "@" ) ){
    FontList.Push( SubStr( k , 2 ) )
    ddlList .= SubStr( k , 2 ) "|"
  }else{
    FontList.Push( k )
    ddlList .= k "|"
  }
}

fontsize := []
Loop, 30
  FontSize.Push( A_Index + 7 )

Width := 950
Height := 300
ScaleFactor := A_ScreenDPI / 96


Gui, 1:New, HwndGuiHwnd
Gui, 1:Color, 22262a
Gui, 1:Add, Edit, % "xm y" ( height - 120 ) * ScaleFactor " w" ( Width - 20 ) * ScaleFactor " h70 hwndEdit1Hwnd", Sample Text


Gui, 1:Font, s12
Gui, 1:Add, DDL, % "xm y+10 w"  Width - 20 " choose1 r10 " , % ddlList

Gui, 1:Show, % "w" Width * ScaleFactor " h" height * ScaleFactor


bob := New DropDownListv1( {  EditHwnd: Edit1Hwnd , Bind: "TestFunction" , ScaleFactor: ScaleFactor , W: 400 , FontSize: 12 , Font: "Comic Sans MS" , Parent: GuiHwnd , List: FontList } )
;~ bob := New DropDownListv1( {  EditHwnd: Edit1Hwnd , Bind: "TestFunction" , ScaleFactor: ScaleFactor , W: 400 , FontSize: 12 , Font: "Comic Sans MS" , Parent: GuiHwnd , List: [1,2,3,4] } )
FontSize := New DropDownListv1( { Y: 50 , EditHwnd: Edit1Hwnd , Bind: "ChangeFontSize" , ScaleFactor: ScaleFactor , W: 120 , FontSize: 24 , Font: "Comic Sans MS" , Parent: GuiHwnd , List: FontSize } )

return


GuiClose:
GuiContextMenu:
*ESC::ExitApp

RALT::PopUpWindow.Helper()


  
TestFunction( obj ){
  Gui, 1:Font, , % obj.List[ obj.Selected ]
  GuiControl, 1:Font, % obj.EditHwnd 
  ;~ Clipboard := obj.List[ obj.Selected ]
}

ChangeFontSize( obj ){
  Gui, 1:Font, % "s" obj.List[ obj.Selected ]
  GuiControl, 1:Font, % obj.EditHwnd 
}

;********************************************************
GetFontNames(charset){ ;https://www.autohotkey.com/boards/viewtopic.php?t=12416#p386353
   hDC := DllCall("GetDC", "UInt", 0, "Ptr")
   VarSetCapacity(LOGFONT, 92, 0)
   NumPut(charset, &LOGFONT + 23, "UChar")
   DllCall("EnumFontFamiliesEx", "Ptr", hDC, "Ptr", 0 , "Ptr", RegisterCallback("EnumFontFamExProc", "F", 4) , "Ptr", pFonts := Object(Fonts := {}), "UInt", 0)
   ObjRelease(pFonts), DllCall("ReleaseDC", "Ptr", 0, "Ptr", hDC)
   Return Fonts
}
EnumFontFamExProc(lpelfe, lpntme, FontType, lParam){
   font := StrGet(lpelfe + 28)
   Object(lParam)[font] := ""
   Return true
}

;**********************************************************************************************************************

class DropDownListv1	{
  __New( obj := "" ){
    This._SetDefaults()
    This._UpdateDefaults( obj )
    This._CreateWindows()
    This._CreateControls()
    This._DrawHeader()
    This._SetTimer( This.HoverTimer , 100 )
  }
  _SetDefaults(){
    This.Parent := ""
    This.ScaleFactor := 1
    This.X := 10
    This.Y := 10
    This.W := 300
    This.HeaderMargin := 5
    This.Font := "Arial"
    This.FontSize := 12
    This.FontColor := "0xFF000000"
    This.FontOptions := "Center vCenter NoWrap  "
    This.H := Floor( This._GetTextSize() + 2 * This.HeaderMargin )
    This.PanelStartingPositionY := 9
    This.Selected := 1
    This.StartingPosition := 1
    This.MainColor := "0xFFFFFFFF"
    This.ArrowColor := "0xFF000000"
    This.Rows := 10
    This.BodyMargin := 3
    This.PanelTextPading := 1
    This.PanelTextHeight := Floor( This._GetTextSize() )
    This.PanelHeight := This.PanelTextHeight + 2 * This.PanelTextPading
    This.BodyHeight := This.BodyMargin * 2 + ( This.PanelHeight * This.Rows ) + ( This.BodyMargin * ( This.Rows - 1 ) ) + This.PanelStartingPositionY
    This.ThumbMinY := This.PanelStartingPositionY + 2
    This.ThumbRange := This.BodyHeight - This.ThumbMinY - 6 
    This.ThumbY := This.ThumbMinY
    This.Interval := Floor( This.ThumbRange / This.List.Length() )
    This.PanelColor1 := "0xFFCFCFCF"
    This.PanelColor2 := "0xFFEFEFEF"
    This.HighLightPanelColor := "0x3300AAFF"
    This.SelectedPanelColor := "0x990099FF"
    This.SelectedFontColor := This.FontColor
    This.HighlightFontColor := This.FontColor
    This.HeaderFontColor := This.FontColor
    This.SliderTrackColor := "0xFFDCDCDC"
    This.SliderButtonColor := "0xFFFFFFFF"
    This.SliderRidgeColor := "0x33333333"
    This.BorderColor := "0X33000000"
    This.Hovered := ""
    This.PanelControls := []
    This.Active := 0
    This.CallBind := This._CallBind.Bind( This )
    This.HoverTimer := This._Hover.Bind( This )
    This.FocusColor := "0x990099FF"
    This.Focused := 0
  }
  _UpdateDefaults( obj := "" ){
    for k, v in obj
      This[ k ] := obj[ k ] 
    This.H := Floor( This._GetTextSize() + 2 * This.HeaderMargin )
    This.Roundness := This.H / 5
    if( obj.Bind )
      This.Bind := func( obj.Bind ).Bind( This )
    if( This.Rows < 8 )
      This.Rows := 8
    This.PanelTextHeight := Floor( This._GetTextSize() )
    This.PanelHeight := This.PanelTextHeight + 2 * This.PanelTextPading
    This.BodyHeight := This.BodyMargin * 2 + ( This.PanelHeight * This.Rows ) + ( This.BodyMargin * ( This.Rows - 1 ) ) + This.PanelStartingPositionY
    This.ThumbMinY := This.PanelStartingPositionY + 2
    This.ThumbRange := This.BodyHeight - This.ThumbMinY - 6 - 2
    This.Interval := Floor( ( This.ThumbRange * This.ScaleFactor) / This.List.Length() )
    This.TotalInterval := This.Interval * This.List.Length()
    This.ThumbHeight := This.ThumbRange - This.TotalInterval
    While( This.Interval > 1 ){
      This.Interval -= 1
      This.TotalInterval := This.Interval * This.List.Length()
      This.ThumbHeight := This.ThumbRange - This.TotalInterval
    }
    This.Thumb := { X: ( This.W - 32 ) , Y: This.ThumbMinY , W: 26 , H: This.ThumbHeight }
    This._MoveThumbControl()
    This.Panels := []
    This.PanelHandles := []
    temp := This.PanelStartingPositionY - 2
    Loop, % This.Rows	{
      This.Panels[ A_Index ] := { X: 4 , Y: temp , W: ( This.W - 34 - 6 ) , H: This.PanelHeight , Hwnd: "" }
      temp += This.PanelHeight + This.BodyMargin
    }
    This.ToggleButton := { X: 2 , Y: 2 , W: ( This.W - 4 ) , H: ( This.H - 4 ) , Hwnd: "" }
    This.WheelActive := 0
    This.FT := 0
    OnMessage( 0x020A , This._WheelChange.Bind( This ) )
    OnMessage( 0x201 , This._WatchFocus.Bind( This ) )
    OnMessage( 0x100 , This._WatchKeyPress.Bind( This ) )
    if( !obj.HasKey( "HeaderFontColor" ) )
      This.HeaderFontColor := This.FontColor
    if( !obj.HasKey( "HighlightFontColor" ) )
      This.HighlightFontColor := This.FontColor
  }
  _CreateWindows(){
    This.Gui1 :=  New PopUpWindow( { AutoShow: 1 , X: This.X * This.ScaleFactor , Y: This.Y * This.ScaleFactor , W: This.W * This.ScaleFactor , H: This.H * This.ScaleFactor , Options: " -DPIScale +AlwaysOnTop +Parent" This.Parent } )
    This.Gui2 :=  New PopUpWindow( { AutoShow: 1 , X: This.X * This.ScaleFactor , Y: This.Y * This.ScaleFactor , W: This.W * This.ScaleFactor , H: This.BodyHeight * This.ScaleFactor , Options: " -DPIScale +AlwaysOnTop +Owner" This.Gui1.Hwnd } )
  }
  _CreateControls(){
    Gui, % This.Gui2.Hwnd ":Add", Text, % "x" ( This.W - 34 ) * This.ScaleFactor " y" This.ThumbY * This.ScaleFactor " w" 30 * This.ScaleFactor " h" This.ThumbHeight * This.ScaleFactor " hwndhwnd" 
    This.ThumbHwnd := hwnd
    bd := This._AdjustSlider.Bind( This )
    GuiControl, % This.Gui2.Hwnd ":+G", % hwnd, % bd 
    Loop, % This.Rows	{
      Gui, % This.Gui2.Hwnd ":Add", Text, % "x" This.Panels[ A_Index ].X * This.ScaleFactor " y" This.Panels[ A_Index ].Y * This.ScaleFactor " w" This.Panels[ A_Index ].W * This.ScaleFactor " h" This.Panels[ A_Index ].H * This.ScaleFactor " hwndhwnd"
      This.Panels[ A_Index ].Hwnd := hwnd
      This.PanelHandles[ hwnd ] := A_Index
      bd := This._SelectPanel.Bind( This )
      GuiControl, % This.Gui2.Hwnd ":+G" , % hwnd , % bd
    }
    Gui, % This.Gui1.Hwnd ":Add", Text, % "x" This.ToggleButton.X * This.ScaleFactor " y" This.ToggleButton.Y * This.ScaleFactor " w" This.ToggleButton.W * This.ScaleFactor " h" This.ToggleButton.H * This.ScaleFactor " hwndhwnd"
    This.ToggleButton.Hwnd := hwnd
    This.HKBind := This._LButtonHK.Bind( This )
    bd := This._ToggleBody.Bind( This )
    GuiControl, % This.Gui1.Hwnd ":+G" , % hwnd , % bd
  }
  _MoveThumbControl(){
    GuiControl, % This.Gui2.Hwnd ":Move" , % This.ThumbHwnd , % "y" This.Thumb.Y * This.ScaleFactor " h" This.ThumbHeight * This.ScaleFactor
  }
  _Hover(){
    MouseGetPos,,, win , ctrl , 2 
    if( win = This.Gui2.Hwnd ){
      if( !This.Hovered && This.PanelHandles[ ctrl ] ){
        This.Hovered := ctrl
        This._DrawBody()
      }
    }
    if( This.Hovered && ctrl != This.Hovered ){
      This.Hovered := ""
      if( This.Active )
        This._DrawBody()
    }
  }
  _WheelChange( input ){
    local ctrl , Dir , win 
    if( This.WheelActive )
      return
    if( This.ft := !This.ft )
      return
    This.WheelActive := 1
    Dir := ( (input >> 16 ) > 0x7FFF ) || ( ( input < 0 ) ? ( 1 ) : ( 0 ) )
    MouseGetPos,,, win, ctrl, 2
    if( !Dir &&  ctrl = This.ToggleButton.Hwnd ){
      ( --This.Selected < 1 ) ? ( This.Selected := 1 )
      This.StartingPosition := This.Selected
    }else if( Dir &&  ctrl = This.ToggleButton.Hwnd ){
      ( ++This.Selected > This.List.Length() ) ? ( This.Selected := This.List.Length() )
      This.StartingPosition := This.Selected
    }else if( !Dir && win = This.Gui2.Hwnd ){
      ( --This.StartingPosition < 1 ) ? ( This.StartingPosition := 1 )
    }else if( Dir && win = This.Gui2.Hwnd ){
      ( ++This.StartingPosition > This.List.Length() ) ? ( This.StartingPosition := This.List.Length() )
    }
    This.Thumb.Y := This.ThumbMinY + This.StartingPosition
    This._MoveThumbControl()
    This._DrawHeader()
    if( This.Active )
      This._DrawBody()
    if( ctrl = This.ToggleButton.Hwnd )
      This._SetTimer( This.CallBind , -30 )
    This.WheelActive := 0
  }
  _WatchKeyPress( key ){
    if( key = 9 && This.Focused )
      This.SetFocus( 0 )
  }
  _WatchFocus(){
    MouseGetPos,,, win, ctrl, 2
    if( This.Focused && ctrl != This.ToggleButton.Hwnd && win != This.Gui2.Hwnd && ctrl )
      This.SetFocus( 0 )
    else if( !This.Focused && ( ctrl = This.ToggleButton.Hwnd || win = This.Gui2.Hwnd ) )
      This.SetFocus( 1 )
  }
  SetFocus( value , option := 1 ){
    if( This.Focused := value )
      GuiControl, % This.Gui1.Hwnd ":Focus" , % This.ToggleButton.Hwnd
    This._DrawHeader()
  }
  _SetTimer( Timer , Amount := 30 ){
    SetTimer, % Timer, % Amount
  }
  _CallBind(){
    Try
      This.Bind.Call()
  }
  _SelectPanel(){
    MouseGetPos,,,, ctrl, 2
    if( This.List[ This.PanelHandles[ ctrl ] + This.StartingPosition - 1 ] != "" ){
      This.Output := This.List[ This.PanelHandles[ ctrl ] + This.StartingPosition - 1 ]
      This.Selected := This.PanelHandles[ ctrl ] + This.StartingPosition - 1
      This._DrawBody()
      bd := This.HKBind 
      HotKey, ~LButton, % bd , Off
      This.Active := 0
      This.Gui2.ClearWindow( 1 )
      This._DrawHeader()
      This._SetTimer( This.CallBind , -30 )
    }
  }
  _ToggleBody(){
    if( This.Active := !This.Active ){
      WinGetPos, x, y,,, % "ahk_Id " This.Gui1.Hwnd
      This.Gui2.UpdateSettings( { X: x , Y: y + ( This.Gui1.H  ) } )
      This.StartingPosition := This.Selected 
      This.Focused := 1
      This._DrawBody()
      bd := This.HKBind
      Hotkey, ~LButton , % bd , On
    }else{
      This.Gui2.ClearWindow( 1 )
      bd := This.HKBind 
      HotKey, ~LButton, % bd , Off
    }
    This._DrawHeader()
  }
  _LButtonHK(){
    MouseGetPos,,, win, ctrl, 2
    if( win != This.Gui2.Hwnd && ctrl != This.ToggleButton.Hwnd ){
      bd := This.HKBind 
      HotKey, ~LButton, % bd , Off
      This.Active := 0
      This.Gui2.ClearWindow( 1 )
      This._DrawHeader()
    }
  }
  _AdjustSlider(){
    local ly
    CoordMode, Mouse, Client
    While( GetKeyState( "LButton" ) ){
      MouseGetPos,, y
      if( ly != y ){
        ly := y
        y /= This.ScaleFactor
        if( ( y - This.ThumbHeight / 2 ) <  This.ThumbMinY ){
          This.Thumb.Y := This.ThumbMinY 
          This.StartingPosition := 1
        }else if( ( y + This.ThumbHeight / 2 ) > ( This.ThumbMinY + This.ThumbRange ) ){
          This.Thumb.Y := This.ThumbMinY + This.ThumbRange - This.ThumbHeight
          This.StartingPosition := This.List.Length()
        }else{
          This.Thumb.Y := y - This.ThumbHeight / 2
          This.StartingPosition := floor( This.Thumb.Y - This.ThumbMinY )
        }
        This._MoveThumbControl()
        This._DrawBody()
      }
      sleep, 10
    }
  }
  _DrawHeader(){
    local brush , pen 
    This.Gui1.ClearWindow()
    Brush := Gdip_CreateLineBrushFromRect( 1 * This.ScaleFactor , 1 * This.ScaleFactor , ( This.W - 2 ) * This.ScaleFactor , ( This.H - 2 ) * This.ScaleFactor , This.MainColor , ( This.MainColor2 != "" ) ? ( This.MainColor2 ) : ( This.MainColor ) , 1 , 1 ) 
    , Gdip_FillRoundedRectangle( This.Gui1.G , Brush , 2 * This.ScaleFactor , 2 * This.ScaleFactor , ( This.W - 4 ) * This.ScaleFactor , ( This.H - 4 ) * This.ScaleFactor , This.Roundness * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    Brush := Gdip_CreateLineBrush( 1 * This.ScaleFactor , 1 * This.ScaleFactor , ( This.W / 2 ) * This.ScaleFactor , ( This.H - 2 ) * This.ScaleFactor , "0xaaaaaaaa" , "0xFF000000" , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.Gui1.G , Pen , 2 * This.ScaleFactor , 2 * This.ScaleFactor , ( This.W - 4 ) * This.ScaleFactor , ( This.H - 4 ) * This.ScaleFactor , This.Roundness * This.ScaleFactor ) , Gdip_DeletePen( Pen )
    if( This.Focused ){
      Brush := Gdip_BrushCreateSolid( This.FocusColor )
      , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) 
      , Gdip_DrawRoundedRectangle( This.Gui1.G , Pen , 4 * This.ScaleFactor , 4 * This.ScaleFactor , ( This.W - 8 ) * This.ScaleFactor , ( This.H - 8 ) * This.ScaleFactor , This.Roundness * This.ScaleFactor ) 
      , Gdip_DeletePen( Pen )
    }
    Brush := Gdip_BrushCreateSolid( This.HeaderFontColor ) , Gdip_TextToGraphics( This.Gui1.G , This.List[ This.Selected ] , "s" This.FontSize * This.ScaleFactor " " This.FontOptions " NoWrap c" Brush " x" 5 * This.ScaleFactor " y" 2 * This.ScaleFactor  , This.Font , ( This.W - ( This.W / 4 ) ) * This.ScaleFactor , This.H * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    Brush := Gdip_BrushCreateSolid( This.ArrowColor ) , Gdip_TextToGraphics( This.Gui1.G , ( !This.Active ) ? ( 6 ) : ( 5 ) , "s" ( s := 16 ) * This.ScaleFactor " " This.FontOptions " c" Brush " x" ( This.W - 30 ) * This.ScaleFactor " y" 1 * This.ScaleFactor  , "WebDings" , 30 * This.ScaleFactor , This.H * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    This.Gui1.UpdateWindow()
  }
  _DrawBody(){
    local temp , brush , pen , tog 
    This.Gui2.ClearWindow()
    Brush := Gdip_BrushCreateSolid( This.MainColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , 2 * This.ScaleFactor , 7 * This.ScaleFactor , ( This.W - 4 ) * This.ScaleFactor , ( This.BodyHeight - 4 - 7 ) * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    Brush := Gdip_BrushCreateSolid( This.BorderColor ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( This.Gui2.G , Pen , 2 * This.ScaleFactor , 7 * This.ScaleFactor , ( This.W - 4 ) * This.ScaleFactor , ( This.BodyHeight - 4 - 7 ) * This.ScaleFactor , This.Roundness * This.ScaleFactor ) , Gdip_DeletePen( Pen )
    Brush := Gdip_BrushCreateSolid( This.MainColor ) , Gdip_FillPolygon( This.Gui2.G, Brush , ( This.W / 2 ) * This.ScaleFactor "," 0 * This.ScaleFactor "|" ( This.W - ( This.W / 5 ) ) * This.ScaleFactor "," 100 * This.ScaleFactor "|" ( This.W / 5 ) * This.ScaleFactor "," 100 * This.ScaleFactor "|" ) , Gdip_DeleteBrush( Brush )
    temp := This.PanelStartingPositionY
    Loop, % This.Rows	{
      tog := !tog
      if( ( A_Index + This.StartingPosition - 1 ) = This.Selected ){
        Brush := Gdip_BrushCreateSolid( This.SelectedPanelColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , 4 * This.ScaleFactor , temp * This.ScaleFactor , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
        Brush := Gdip_BrushCreateSolid( This.SelectedFontColor ) , Gdip_TextToGraphics( This.Gui2.G, This.List[ A_Index + This.StartingPosition - 1 ] , "s" This.FontSize * This.ScaleFactor " NoWrap vCenter  c" Brush " x" 4 * This.ScaleFactor " y" ( temp + 1 ) * This.ScaleFactor  , "Segoe ui" , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
      }else if( A_Index = This.PanelHandles[ This.Hovered ] ){
        Brush := Gdip_BrushCreateSolid( This.HighLightPanelColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , 4 * This.ScaleFactor , temp * This.ScaleFactor , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
        Brush := Gdip_BrushCreateSolid( This.HighlightFontColor ) , Gdip_TextToGraphics( This.Gui2.G, This.List[ A_Index + This.StartingPosition - 1 ] , "s" This.FontSize * This.ScaleFactor " NoWrap vCenter  c" Brush " x" 4 * This.ScaleFactor " y" ( temp + 1 ) * This.ScaleFactor  , "Segoe ui" , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
      }else{
        Brush := Gdip_BrushCreateSolid( ( !tog ) ? ( This.PanelColor1 ) : ( This.PanelColor2 ) ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , 4 * This.ScaleFactor , temp * This.ScaleFactor , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
        Brush := Gdip_BrushCreateSolid( This.FontColor ) , Gdip_TextToGraphics( This.Gui2.G, This.List[ A_Index + This.StartingPosition - 1 ] , "s" This.FontSize * This.ScaleFactor " NoWrap vCenter  c" Brush " x" 4 * This.ScaleFactor " y" ( temp + 1 ) * This.ScaleFactor  , "Segoe ui" , ( This.W - 34 - 6 ) * This.ScaleFactor , This.PanelHeight * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
      }
      temp += This.PanelHeight + This.BodyMargin
    }
    Brush := Gdip_BrushCreateSolid( This.SliderTrackColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , ( This.W - 34 ) * This.ScaleFactor , 9 * This.ScaleFactor , 30 * This.ScaleFactor , ( This.BodyHeight - 15 ) * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    Brush := Gdip_BrushCreateSolid( This.SliderButtonColor ) , Gdip_FillRoundedRectangle( This.Gui2.G, Brush , ( This.W - 32 ) * This.ScaleFactor , This.Thumb.Y * This.ScaleFactor , 26 * This.ScaleFactor , This.ThumbHeight * This.ScaleFactor , 5 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    Brush := Gdip_BrushCreateSolid( This.SliderRidgeColor ) , Gdip_FillRectangle( This.Gui2.G , Brush , ( This.Thumb.X + 3 ) * This.ScaleFactor , ( This.Thumb.Y + ( This.ThumbHeight / 2 ) - 5 ) * This.ScaleFactor , ( This.Thumb.W - 6 ) * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    Brush := Gdip_BrushCreateSolid( This.SliderRidgeColor ) , Gdip_FillRectangle( This.Gui2.G , Brush , ( This.Thumb.X + 3 ) * This.ScaleFactor , ( This.Thumb.Y + ( This.ThumbHeight / 2 ) + 5 ) * This.ScaleFactor , ( This.Thumb.W - 6 ) * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    Brush := Gdip_BrushCreateSolid( This.SliderRidgeColor ) , Gdip_FillRectangle( This.Gui2.G , Brush , ( This.Thumb.X + 3 ) * This.ScaleFactor , ( This.Thumb.Y + ( This.ThumbHeight / 2 ) ) * This.ScaleFactor , ( This.Thumb.W - 6 ) * This.ScaleFactor , 3 * This.ScaleFactor ) , Gdip_DeleteBrush( Brush )
    This.Gui2.UpdateWindow()
  }
  _GetTextSize( index := 4 ){
    local pBitmap, G, Brush, temparr
    pBitmap := Gdip_CreateBitmap( 10 , 10 ) , G := Gdip_GraphicsFromImage( pBitmap ), Gdip_SetSmoothingMode( G , 2 )
    Brush := Gdip_BrushCreateSolid( "0xFF000000")
    temparr := StrSplit( Gdip_TextToGraphics( G , ( This.Text ) ? ( This.Text ) : ( "Test String" ), " s" This.Fontsize " c" Brush " " This.FontOptions " x" 0 " y" 0 , This.Font , 10000, 10000  ),"|","|"  ) , Gdip_DeleteBrush( Brush )
    Gdip_DeleteGraphics( G ) , Gdip_DisposeImage( pBitmap )
    return temparr[ index ]
  }
  Delete(){
    This.Gui2.DeleteWindow()
    This.Gui1.DeleteWindow()
  }
}

;#############################################################################

class PopUpWindow	{
;PopUpWindow v2.2
;Date Written: Oct 28th, 2021
;Last Edit: Feb 7th, 2022 :Changed the trigger method.
;Written By: Hellbent aka CivReborn
;SpcThanks: teadrinker , malcev 
  static Index := 0 , Windows := [] , Handles := [] , EditHwnd , HelperHwnd
  __New( obj := "" ){
    This._SetDefaults()
    This.UpdateSettings( obj )
    This._CreateWindow()
    This._CreateWindowGraphics()
    if( This.AutoShow )
      This.ShowWindow( This.Title )
  }
  _SetDefaults(){
    This.X := 10
    This.Y := 10
    This.W := 10
    This.H := 10
    This.Smoothing := 2
    This.Options := " -DPIScale +AlwaysOnTop "
    This.AutoShow := 0
    This.GdipStartUp := 0
    This.Title := ""
    
    This.Controls := []
    This.Handles := []
    This.Index := 0 
  }
  AddTrigger( obj ){
    local k , v , cc , bd
    
    This.Controls[ ++This.Index ] := { 	X:		10
                    ,	Y:		10
                    ,	W:		10
                    ,	H:		10	}
    for k, v in obj
      This.Controls[ This.Index ][ k ] := obj[ k ] 
    cc := This.Controls[ This.Index ]
    Gui, % This.Hwnd ":Add", Text, % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd"
    This.Handles[ hwnd ] := This.Index
    This.Controls[ This.Index ].Hwnd := hwnd
    
    if( IsObject( cc.Label ) ){
      bd := cc.Label
      GuiControl, % This.Hwnd ":+G" , % hwnd , % bd
    }else{
      bd := This._TriggerCall.Bind( This )
      GuiControl, % This.Hwnd ":+G" , % hwnd , % bd
    }
    return hwnd
    
  }
  _TriggerCall(){
    MouseGetPos,,,, ctrl, 2
    Try
      ;~ SetTimer, % This.Controls[ This.Handles[ ctrl ] ].Label, -0
      gosub, % This.Controls[ This.Handles[ ctrl ] ].Label
    
        
  }
  DrawTriggers( color := "0xFFFF0000" , AutoUpdate := 0 ){
    local brush , cc 
    Brush := Gdip_BrushCreateSolid( color ) 
    Gdip_SetSmoothingMode( This.G , 3 )
    loop, % This.Controls.Length()	{
      cc := This.Controls[ A_Index ]
      Gdip_FillRectangle( This.G , Brush , cc.x , cc.y , cc.w , cc.h )
    
    }
    Gdip_DeleteBrush( Brush )
    Gdip_SetSmoothingMode( This.G , This.Smoothing )
    if( AutoUpdate )
      This.UpdateWindow()
  }
  UpdateSettings( obj := "" , UpdateGraphics := 0 ){
    local k , v
    if( IsObject( obj ) )
      for k, v in obj
        This[ k ] := obj[ k ]
    ( This.X = "Center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 ) 	
    ( This.Y = "Center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 ) 	
    if( UpdateGraphics ){
      This._DestroyWindowsGraphics()
      This._CreateWindowGraphics()
    }
  }
  _CreateWindow(){
    local hwnd
    Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Options
    PopUpWindow.Index++
    This.Index := PopUpWindow.Index
    PopUpWindow.Windows[ PopUpWindow.Index ] := This
    This.Hwnd := hwnd
    PopUpWindow.Handles[ hwnd ] := PopUpWindow.Index
    if( This.GdipStartUp && !PopUpWindow.pToken )
      PopUpWindow.pToken := GDIP_STARTUP()
  }
  _DestroyWindowsGraphics(){
    Gdip_DeleteGraphics( This.G )
    SelectObject( This.hdc , This.obm )
    DeleteObject( This.hbm )
    DeleteDC( This.hdc )
  }
  _CreateWindowGraphics(){
    This.hbm := CreateDIBSection( This.W , This.H )
    This.hdc := CreateCompatibleDC()
    This.obm := SelectObject( This.hdc , This.hbm )
    This.G := Gdip_GraphicsFromHDC( This.hdc )
    Gdip_SetSmoothingMode( This.G , This.Smoothing )
  }
  ShowWindow( Title := "" ){
    Gui , % This.Hwnd ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
  }
  HideWindow(){
    Gui , % This.Hwnd ":Hide",
  }
  UpdateWindow(){
    UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H )
  }
  ClearWindow( AutoUpdate := 0 ){
    Gdip_GraphicsClear( This.G )
    if( Autoupdate )
      This.UpdateWindow()
  }
  DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
    Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
    if( dispose )
      Gdip_DisposeImage( pBitmap )
    if( Autoupdate )
      This.UpdateWindow()
  }
  PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ){
    if( isObject( color ) ){
      Brush := Gdip_BrushCreateSolid( ( color.HasKey( "Color" ) ) ? ( color.Color ) : ( "0xFF000000" ) ) 
      if( color.Haskey( "Round" ) )
        Gdip_FillRoundedRectangle( This.G , Brush , color.X , color.Y , color.W , color.H , color.Round )
      else
        Gdip_FillRectangle( This.G , Brush , color.X , color.Y , color.W , color.H ) 
    }else{
      Brush := Gdip_BrushCreateSolid( color ) 
      Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 ) 
    }
    Gdip_DeleteBrush( Brush )
    if( AutoUpdate )
      This.UpdateWindow()
  }
  DeleteWindow( GDIPShutdown := 0 ){
    Gui, % This.Hwnd ":Destroy"
    SelectObject( This.hdc , This.obm )
    DeleteObject( This.hbm )
    DeleteDC( This.hdc )
    Gdip_DeleteGraphics( This.G )
    hwnd := This.Hwnd
    for k, v in PopUpWindow.Windows[ Hwnd ]
      This[k] := ""
    PopUpWindow.Windows[ Hwnd ] := ""
    if( GDIPShutdown ){
      Gdip_Shutdown( PopUpWindow.pToken )
      PopUpWindow.pToken := ""
    }
  }
  _OnClose( wParam ){
    if( wParam = 0xF060 ){	;SC_CLOSE ;[ clicking on the gui close button ]
      Try{
        Gui, % PopUpWindow.HelperHwnd ":Destroy"
        SoundBeep, 555
      }
    }
  }
  CreateCachedBitmap( pBitmap , Dispose := 0 ){
    local pCachedBitmap
    if( This.CachedBitmap )
      This.DisposeCachedbitmap()
    DllCall( "gdiplus\GdipCreateCachedBitmap" , "Ptr" , pBitmap , "Ptr" , this.G , "PtrP" , pCachedBitmap )
    This.CachedBitmap := pCachedBitmap
    if( Dispose )
      Gdip_DisposeImage( pBitmap )
  }
  DrawCachedBitmap( AutoUpdate := 0 ){
    DllCall( "gdiplus\GdipDrawCachedBitmap" , "Ptr" , this.G , "Ptr" , This.CachedBitmap , "Int" , 0 , "Int" , 0 )
    if( AutoUpdate )
      This.UpdateWindow()
  }
  DisposeCachedbitmap(){
    DllCall( "gdiplus\GdipDeleteCachedBitmap" , "Ptr" , This.CachedBitmap )
  }
  Helper(){
    local hwnd , MethodList := ["__New","UpdateSettings","ShowWindow","HideWindow","UpdateWindow","ClearWindow","DrawBitmap","PaintBackground","DeleteWindow" , "AddTrigger" , "DrawTriggers", "CreateCachedBitmap" , "DrawCachedBitmap" , "DisposeCachedbitmap" ]
    Gui, New, +AlwaysOnTop +ToolWindow +HwndHwnd
    PopUpWindow.HelperHwnd := hwnd
    Gui, Add, Edit, xm ym w250 r1 Center hwndhwnd, Gui1
    PopUpWindow.EditHwnd := hwnd
    loop, % MethodList.Length()	
      Gui, Add, Button, xm y+1 w250 r1 gPopUpWindow._HelperClip, % MethodList[ A_Index ]
    Gui, Show,,
    OnMessage( 0x112 , This._OnClose.Bind( hwnd ) )
  }
  _HelperClip(){
    local ClipList 
    
    GuiControlGet, out, % PopUpWindow.HelperHwnd ":", % PopUpWindow.EditHwnd	
    
    ClipList := 		{ 	__New: 					" := New PopUpWindow( { AutoShow: 1 , X: 0 , Y: 0 , W: A_ScreenWidth , H: A_ScreenHeight , Options: "" -DPIScale +AlwaysOnTop "" } )"
              ,	UpdateSettings:			".UpdateSettings( { X: """" , Y: """" , W: """" , H: """" } , UpdateGraphics := 0 )"
              ,	ShowWindow:				".ShowWindow( Title := """" )"
              ,	HideWindow:				".HideWindow()"
              ,	UpdateWindow:			".UpdateWindow()"
              ,	ClearWindow:			".ClearWindow( AutoUpdate := 0 )"
              ,	DrawBitmap:				".DrawBitmap( pBitmap := """" , { X: 0 , Y: 0 , W: " Out ".W , H: " Out ".H } , dispose := 1 , AutoUpdate := 0 )"
              ,	PaintBackground:		".PaintBackground( color := ""0xFF000000"" , AutoUpdate := 0 )  "  ";{ Color: ""0xFF000000"" , X: 2 , Y: 2 , W: " Out ".W - 4 , H: " Out ".H - 4 , Round: 10 }"
              ,	DeleteWindow:			".DeleteWindow( GDIPShutdown := 0 )"
              ,	AddTrigger:				".AddTrigger( { X: """" , Y: """" , W: """" , H: """" , Value: """" , Label: """" } )"	
              ,	DrawTriggers:			".DrawTriggers( color := ""0xFFFF0000"" , AutoUpdate := 0 )"	
              ,	CreateCachedBitmap:		".CreateCachedBitmap( pBitmap , Dispose := 0 )"	
              ,	DrawCachedBitmap: 		".DrawCachedBitmap( AutoUpdate := 0 )"	
              ,	DisposeCachedbitmap:	".DisposeCachedbitmap()"	}
              
    clipboard := Out ClipList[ A_GuiControl ]
    
  }
}

; Gdip_By Hellbent.ahk
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Gdip standard library v1.45 by tic (Tariq Porter) 07/09/11
; Modifed by Rseding91 using fincs 64 bit compatible Gdip library 5/1/2013
; Supports: Basic, _L ANSi, _L Unicode x86 and _L Unicode x64
;
; Updated 2/20/2014 - fixed Gdip_CreateRegion() and Gdip_GetClipRegion() on AHK Unicode x86
; Updated 5/13/2013 - fixed Gdip_SetBitmapToClipboard() on AHK Unicode x64
; 此库不包含Base64相关的函数
;######################################################
UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  if ((x != "") && (y != ""))
    VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")
 
  if (w = "") ||(h = "")
    WinGetPos,,, w, h, ahk_id %hwnd%
   
  return DllCall("UpdateLayeredWindow"
          , Ptr, hwnd
          , Ptr, 0
          , Ptr, ((x = "") && (y = "")) ? 0 : &pt
          , "int64*", w|h<<32
          , Ptr, hdc
          , "int64*", 0
          , "uint", 0
          , "UInt*", Alpha<<16|1<<24
          , "uint", 2)
}
 
BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster=""){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdi32\BitBlt", Ptr, dDC, "int", dx, "int", dy, "int", dw, "int", dh, Ptr, sDC, "int", sx, "int", sy, "uint", Raster ? Raster : 0x00CC0020)
}
StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster=""){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  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)
}
SetStretchBltMode(hdc, iStretchMode=4){
  return DllCall("gdi32\SetStretchBltMode", A_PtrSize ? "UPtr" : "UInt", hdc, "int", iStretchMode)
}
SetImage(hwnd, hBitmap){
  SendMessage, 0x172, 0x0, hBitmap,, ahk_id %hwnd%
  E := ErrorLevel
  DeleteObject(E)
  return E
}
SetSysColorToControl(hwnd, SysColor=15){
   WinGetPos,,, w, h, ahk_id %hwnd%
   bc := DllCall("GetSysColor", "Int", SysColor, "UInt")
   pBrushClear := Gdip_BrushCreateSolid(0xff000000 | (bc >> 16 | bc & 0xff00 | (bc & 0xff) << 16))
   pBitmap := Gdip_CreateBitmap(w, h), G := Gdip_GraphicsFromImage(pBitmap)
   Gdip_FillRectangle(G, pBrushClear, 0, 0, w, h)
   hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
   SetImage(hwnd, hBitmap)
   Gdip_DeleteBrush(pBrushClear)
   Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap), DeleteObject(hBitmap)
   return 0
}
Gdip_BitmapFromScreen(Screen=0, Raster=""){
  if (Screen = 0)
  {
    Sysget, x, 76
    Sysget, y, 77   
    Sysget, w, 78
    Sysget, h, 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 != "")
  {
    Sysget, M, Monitor, %Screen%
    x := MLeft, y := MTop, w := MRight-MLeft, h := MBottom-MTop
  }
  else
  {
    StringSplit, S, Screen, |
    x := S1, y := S2, w := S3, h := S4
  }
 
  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)
  
  pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
  SelectObject(chdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
  return pBitmap
}
Gdip_BitmapFromHWND(hwnd){
  WinGetPos,,, Width, Height, ahk_id %hwnd%
  hbm := CreateDIBSection(Width, Height), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
  PrintWindow(hwnd, hdc)
  pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
  SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
  return pBitmap
}
CreateRectF(ByRef RectF, x, y, w, h){
   VarSetCapacity(RectF, 16)
   NumPut(x, RectF, 0, "float"), NumPut(y, RectF, 4, "float"), NumPut(w, RectF, 8, "float"), NumPut(h, RectF, 12, "float")
}
CreateRect(ByRef Rect, x, y, w, h){
  VarSetCapacity(Rect, 16)
  NumPut(x, Rect, 0, "uint"), NumPut(y, Rect, 4, "uint"), NumPut(w, Rect, 8, "uint"), NumPut(h, Rect, 12, "uint")
}
CreateSizeF(ByRef SizeF, w, h){
   VarSetCapacity(SizeF, 8)
   NumPut(w, SizeF, 0, "float"), NumPut(h, SizeF, 4, "float")   
}
CreatePointF(ByRef PointF, x, y){
   VarSetCapacity(PointF, 8)
   NumPut(x, PointF, 0, "float"), NumPut(y, PointF, 4, "float")   
}
CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  hdc2 := hdc ? hdc : GetDC()
  VarSetCapacity(bi, 40, 0)
  NumPut(w, bi, 4, "uint"), NumPut(h, bi, 8, "uint"), NumPut(40, bi, 0, "uint"), NumPut(1, bi, 12, "ushort"), NumPut(0, bi, 16, "uInt"), NumPut(bpp, bi, 14, "ushort")
  hbm := DllCall("CreateDIBSection", Ptr, hdc2, Ptr, &bi, "uint", 0, A_PtrSize ? "UPtr*" : "uint*", ppvBits, Ptr, 0, "uint", 0, Ptr)
  if !hdc
    ReleaseDC(hdc2)
  return hbm
}
PrintWindow(hwnd, hdc, Flags=0){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("PrintWindow", Ptr, hwnd, Ptr, hdc, "uint", Flags)
}
DestroyIcon(hIcon){
  return DllCall("DestroyIcon", A_PtrSize ? "UPtr" : "UInt", hIcon)
}
PaintDesktop(hdc){
  return DllCall("PaintDesktop", A_PtrSize ? "UPtr" : "UInt", hdc)
}
CreateCompatibleBitmap(hdc, w, h){
  return DllCall("gdi32\CreateCompatibleBitmap", A_PtrSize ? "UPtr" : "UInt", hdc, "int", w, "int", h)
}
CreateCompatibleDC(hdc=0){
   return DllCall("CreateCompatibleDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}
SelectObject(hdc, hgdiobj){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("SelectObject", Ptr, hdc, Ptr, hgdiobj)
}
DeleteObject(hObject){
   return DllCall("DeleteObject", A_PtrSize ? "UPtr" : "UInt", hObject)
}
GetDC(hwnd=0){
  return DllCall("GetDC", A_PtrSize ? "UPtr" : "UInt", hwnd)
}
GetDCEx(hwnd, flags=0, hrgnClip=0){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("GetDCEx", Ptr, hwnd, Ptr, hrgnClip, "int", flags)
}
ReleaseDC(hdc, hwnd=0){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
}
DeleteDC(hdc){
   return DllCall("DeleteDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}
Gdip_LibraryVersion(){
  return 1.45
}
Gdip_LibrarySubVersion(){
  return 1.47
}
Gdip_BitmapFromBRA(ByRef BRAFromMemIn, File, Alternate=0){
  Static FName = "ObjRelease"
  if !BRAFromMemIn
    return -1
  Loop, Parse, BRAFromMemIn, `n
  {
    if (A_Index = 1)
    {
      StringSplit, Header, A_LoopField, |
      if (Header0 != 4 || Header2 != "BRA!")
        return -2
    }
    else if (A_Index = 2)
    {
      StringSplit, Info, A_LoopField, |
      if (Info0 != 3)
        return -3
    }
    else
      break
  }
  if !Alternate
    StringReplace, File, File, \, \\, All
  RegExMatch(BRAFromMemIn, "mi`n)^" (Alternate ? File "\|.+?\|(\d+)\|(\d+)" : "\d+\|" File "\|(\d+)\|(\d+)") "$", FileInfo)
  if !FileInfo
    return -4
  hData := DllCall("GlobalAlloc", "uint", 2, Ptr, FileInfo2, Ptr)
  pData := DllCall("GlobalLock", Ptr, hData, Ptr)
  DllCall("RtlMoveMemory", Ptr, pData, Ptr, &BRAFromMemIn+Info2+FileInfo1, Ptr, FileInfo2)
  DllCall("GlobalUnlock", Ptr, hData)
  DllCall("ole32\CreateStreamOnHGlobal", Ptr, hData, "int", 1, A_PtrSize ? "UPtr*" : "UInt*", pStream)
  DllCall("gdiplus\GdipCreateBitmapFromStream", Ptr, pStream, A_PtrSize ? "UPtr*" : "UInt*", pBitmap)
  If (A_PtrSize)
    %FName%(pStream)
  Else
    DllCall(NumGet(NumGet(1*pStream)+8), "uint", pStream)
  return pBitmap
}
Gdip_DrawRectangle(pGraphics, pPen, x, y, w, h){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipDrawRectangle", Ptr, pGraphics, Ptr, pPen, "float", x, "float", y, "float", w, "float", h)
}
Gdip_DrawRoundedRectangle(pGraphics, pPen, x, y, w, h, r){
  Gdip_SetClipRect(pGraphics, x-r, y-r, 2*r, 2*r, 4)
  Gdip_SetClipRect(pGraphics, x+w-r, y-r, 2*r, 2*r, 4)
  Gdip_SetClipRect(pGraphics, x-r, y+h-r, 2*r, 2*r, 4)
  Gdip_SetClipRect(pGraphics, x+w-r, y+h-r, 2*r, 2*r, 4)
  E := Gdip_DrawRectangle(pGraphics, pPen, x, y, w, h)
  Gdip_ResetClip(pGraphics)
  Gdip_SetClipRect(pGraphics, x-(2*r), y+r, w+(4*r), h-(2*r), 4)
  Gdip_SetClipRect(pGraphics, x+r, y-(2*r), w-(2*r), h+(4*r), 4)
  Gdip_DrawEllipse(pGraphics, pPen, x, y, 2*r, 2*r)
  Gdip_DrawEllipse(pGraphics, pPen, x+w-(2*r), y, 2*r, 2*r)
  Gdip_DrawEllipse(pGraphics, pPen, x, y+h-(2*r), 2*r, 2*r)
  Gdip_DrawEllipse(pGraphics, pPen, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
  Gdip_ResetClip(pGraphics)
  return E
}
Gdip_DrawEllipse(pGraphics, pPen, x, y, w, h){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipDrawEllipse", Ptr, pGraphics, Ptr, pPen, "float", x, "float", y, "float", w, "float", h)
}
Gdip_DrawBezier(pGraphics, pPen, x1, y1, x2, y2, x3, y3, x4, y4){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipDrawBezier", Ptr, pgraphics, Ptr, pPen, "float", x1, "float", y1, "float", x2, "float", y2, "float", x3, "float", y3, "float", x4, "float", y4)
}
Gdip_DrawArc(pGraphics, pPen, x, y, w, h, StartAngle, SweepAngle){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipDrawArc", Ptr, pGraphics, Ptr, pPen, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}
Gdip_DrawPie(pGraphics, pPen, x, y, w, h, StartAngle, SweepAngle){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipDrawPie", Ptr, pGraphics, Ptr, pPen, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}
Gdip_DrawLine(pGraphics, pPen, x1, y1, x2, y2){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipDrawLine", Ptr, pGraphics, Ptr, pPen, "float", x1, "float", y1, "float", x2, "float", y2)
}
Gdip_DrawLines(pGraphics, pPen, Points){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  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\GdipDrawLines", Ptr, pGraphics, Ptr, pPen, Ptr, &PointF, "int", Points0)
}
Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipFillRectangle", Ptr, pGraphics, Ptr, pBrush, "float", x, "float", y, "float", w, "float", h)
}
Gdip_FillRoundedRectangle(pGraphics, pBrush, x, y, w, h, r){
  Region := Gdip_GetClipRegion(pGraphics)
  Gdip_SetClipRect(pGraphics, x-r, y-r, 2*r, 2*r, 4)
  Gdip_SetClipRect(pGraphics, x+w-r, y-r, 2*r, 2*r, 4)
  Gdip_SetClipRect(pGraphics, x-r, y+h-r, 2*r, 2*r, 4)
  Gdip_SetClipRect(pGraphics, x+w-r, y+h-r, 2*r, 2*r, 4)
  E := Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h)
  Gdip_SetClipRegion(pGraphics, Region, 0)
  Gdip_SetClipRect(pGraphics, x-(2*r), y+r, w+(4*r), h-(2*r), 4)
  Gdip_SetClipRect(pGraphics, x+r, y-(2*r), w-(2*r), h+(4*r), 4)
  Gdip_FillEllipse(pGraphics, pBrush, x, y, 2*r, 2*r)
  Gdip_FillEllipse(pGraphics, pBrush, x+w-(2*r), y, 2*r, 2*r)
  Gdip_FillEllipse(pGraphics, pBrush, x, y+h-(2*r), 2*r, 2*r)
  Gdip_FillEllipse(pGraphics, pBrush, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
  Gdip_SetClipRegion(pGraphics, Region, 0)
  Gdip_DeleteRegion(Region)
  return E
}
Gdip_FillPolygon(pGraphics, pBrush, Points, FillMode=0){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  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\GdipFillPolygon", Ptr, pGraphics, Ptr, pBrush, Ptr, &PointF, "int", Points0, "int", FillMode)
}
Gdip_FillPie(pGraphics, pBrush, x, y, w, h, StartAngle, SweepAngle){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipFillPie", Ptr, pGraphics, Ptr, pBrush, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}
Gdip_FillEllipse(pGraphics, pBrush, x, y, w, h){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipFillEllipse", Ptr, pGraphics, Ptr, pBrush, "float", x, "float", y, "float", w, "float", h)
}
Gdip_FillRegion(pGraphics, pBrush, Region){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipFillRegion", Ptr, pGraphics, Ptr, pBrush, Ptr, Region)
}
Gdip_FillPath(pGraphics, pBrush, Path)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  return DllCall("gdiplus\GdipFillPath", Ptr, pGraphics, Ptr, pBrush, Ptr, Path)
}
Gdip_DrawImagePointsRect(pGraphics, pBitmap, Points, sx="", sy="", sw="", sh="", Matrix=1)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  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")
  }
 
  if (Matrix&1 = "")
    ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
  else if (Matrix != 1)
    ImageAttr := Gdip_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 = "")
  {
    sx := 0, sy := 0
    sw := Gdip_GetImageWidth(pBitmap)
    sh := Gdip_GetImageHeight(pBitmap)
  }
 
  E := DllCall("gdiplus\GdipDrawImagePointsRect"
        , Ptr, pGraphics
        , Ptr, pBitmap
        , Ptr, &PointF
        , "int", Points0
        , "float", sx
        , "float", sy
        , "float", sw
        , "float", sh
        , "int", 2
        , Ptr, ImageAttr
        , Ptr, 0
        , Ptr, 0)
  if ImageAttr
    Gdip_DisposeImageAttributes(ImageAttr)
  return E
}
Gdip_DrawImage(pGraphics, pBitmap, dx="", dy="", dw="", dh="", sx="", sy="", sw="", sh="", Matrix=1)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  if (Matrix&1 = "")
    ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
  else if (Matrix != 1)
    ImageAttr := Gdip_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 := Gdip_GetImageWidth(pBitmap)
      sh := dh := Gdip_GetImageHeight(pBitmap)
    }
    else
    {
      sx := sy := 0
      sw := Gdip_GetImageWidth(pBitmap)
      sh := Gdip_GetImageHeight(pBitmap)
    }
  }
 
  E := DllCall("gdiplus\GdipDrawImageRectRect"
        , Ptr, pGraphics
        , 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
    Gdip_DisposeImageAttributes(ImageAttr)
  return E
}
Gdip_SetImageAttributesColorMatrix(Matrix)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  VarSetCapacity(ColourMatrix, 100, 0)
  Matrix := RegExReplace(RegExReplace(Matrix, "^[^\d-\.]+([\d\.])", "$1", "", 1), "[^\d-\.]+", "|")
  StringSplit, Matrix, Matrix, |
  Loop, 25
  {
    Matrix := (Matrix%A_Index% != "") ? Matrix%A_Index% : Mod(A_Index-1, 6) ? 0 : 1
    NumPut(Matrix, ColourMatrix, (A_Index-1)*4, "float")
  }
  DllCall("gdiplus\GdipCreateImageAttributes", A_PtrSize ? "UPtr*" : "uint*", ImageAttr)
  DllCall("gdiplus\GdipSetImageAttributesColorMatrix", Ptr, ImageAttr, "int", 1, "int", 1, Ptr, &ColourMatrix, Ptr, 0, "int", 0)
  return ImageAttr
}
 
Gdip_GraphicsFromImage(pBitmap)
{
  DllCall("gdiplus\GdipGetImageGraphicsContext", A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
  return pGraphics
}
Gdip_GraphicsFromHDC(hdc)
{
  DllCall("gdiplus\GdipCreateFromHDC", A_PtrSize ? "UPtr" : "UInt", hdc, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
  return pGraphics
}
Gdip_GetDC(pGraphics)
{
  DllCall("gdiplus\GdipGetDC", A_PtrSize ? "UPtr" : "UInt", pGraphics, A_PtrSize ? "UPtr*" : "UInt*", hdc)
  return hdc
}
Gdip_ReleaseDC(pGraphics, hdc)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  return DllCall("gdiplus\GdipReleaseDC", Ptr, pGraphics, Ptr, hdc)
}
Gdip_GraphicsClear(pGraphics, ARGB=0x00ffffff)
{
  return DllCall("gdiplus\GdipGraphicsClear", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", ARGB)
}
Gdip_BlurBitmap(pBitmap, Blur)
{
  if (Blur > 100) || (Blur < 1)
    return -1   
  sWidth := Gdip_GetImageWidth(pBitmap), sHeight := Gdip_GetImageHeight(pBitmap)
  dWidth := sWidth//Blur, dHeight := sHeight//Blur
  pBitmap1 := Gdip_CreateBitmap(dWidth, dHeight)
  G1 := Gdip_GraphicsFromImage(pBitmap1)
  Gdip_SetInterpolationMode(G1, 7)
  Gdip_DrawImage(G1, pBitmap, 0, 0, dWidth, dHeight, 0, 0, sWidth, sHeight)
  Gdip_DeleteGraphics(G1)
  pBitmap2 := Gdip_CreateBitmap(sWidth, sHeight)
  G2 := Gdip_GraphicsFromImage(pBitmap2)
  Gdip_SetInterpolationMode(G2, 7)
  Gdip_DrawImage(G2, pBitmap1, 0, 0, sWidth, sHeight, 0, 0, dWidth, dHeight)
  Gdip_DeleteGraphics(G2)
  Gdip_DisposeImage(pBitmap1)
  return pBitmap2
}
Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=75)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  SplitPath, sOutput,,, Extension
  if Extension not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
    return -1
  Extension := "." Extension
  DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
  VarSetCapacity(ci, nSize)
  DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
  if !(nCount && nSize)
    return -2
  If (A_IsUnicode){
    StrGet_Name := "StrGet"
    Loop, %nCount%
    {
      sString := %StrGet_Name%(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
      if !InStr(sString, "*" Extension)
        continue
      
      pCodec := &ci+idx
      break
    }
  } else {
    Loop, %nCount%
    {
      Location := NumGet(ci, 76*(A_Index-1)+44)
      nSize := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "uint", 0, "int",  0, "uint", 0, "uint", 0)
      VarSetCapacity(sString, nSize)
      DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "str", sString, "int", nSize, "uint", 0, "uint", 0)
      if !InStr(sString, "*" Extension)
        continue
      pCodec := &ci+76*(A_Index-1)
      break
    }
  }
  
  if !pCodec
    return -3
  if (Quality != 75)
  {
    Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
    if Extension in .JPG,.JPEG,.JPE,.JFIF
    {
      DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
      VarSetCapacity(EncoderParameters, nSize, 0)
      DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, 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-pad-4
          NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
          break
        }
      }    
    }
  }
  if (!A_IsUnicode)
  {
    nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, 0, "int", 0)
    VarSetCapacity(wOutput, nSize*2)
    DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, &wOutput, "int", nSize)
    VarSetCapacity(wOutput, -1)
    if !VarSetCapacity(wOutput)
      return -4
    E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &wOutput, Ptr, pCodec, "uint", p ? p : 0)
  }
  else
    E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &sOutput, Ptr, pCodec, "uint", p ? p : 0)
  return E ? -5 : 0
}
Gdip_GetPixel(pBitmap, x, y)
{
  DllCall("gdiplus\GdipBitmapGetPixel", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "uint*", ARGB)
  return ARGB
}
Gdip_SetPixel(pBitmap, x, y, ARGB)
{
   return DllCall("gdiplus\GdipBitmapSetPixel", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "int", ARGB)
}
Gdip_GetImageWidth(pBitmap){
   DllCall("gdiplus\GdipGetImageWidth", A_PtrSize ? "UPtr" : "UInt", pBitmap, "uint*", Width)
   return Width
}
Gdip_GetImageHeight(pBitmap){
   DllCall("gdiplus\GdipGetImageHeight", A_PtrSize ? "UPtr" : "UInt", pBitmap, "uint*", Height)
   return Height
}
Gdip_GetImageDimensions(pBitmap, ByRef Width, ByRef Height){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  DllCall("gdiplus\GdipGetImageWidth", Ptr, pBitmap, "uint*", Width)
  DllCall("gdiplus\GdipGetImageHeight", Ptr, pBitmap, "uint*", Height)
}
Gdip_GetDimensions(pBitmap, ByRef Width, ByRef Height){
  Gdip_GetImageDimensions(pBitmap, Width, Height)
}
Gdip_GetImagePixelFormat(pBitmap){
  DllCall("gdiplus\GdipGetImagePixelFormat", A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "UInt*", Format)
  return Format
}
Gdip_GetDpiX(pGraphics){
  DllCall("gdiplus\GdipGetDpiX", A_PtrSize ? "UPtr" : "uint", pGraphics, "float*", dpix)
  return Round(dpix)
}
Gdip_GetDpiY(pGraphics){
  DllCall("gdiplus\GdipGetDpiY", A_PtrSize ? "UPtr" : "uint", pGraphics, "float*", dpiy)
  return Round(dpiy)
}
Gdip_GetImageHorizontalResolution(pBitmap){
  DllCall("gdiplus\GdipGetImageHorizontalResolution", A_PtrSize ? "UPtr" : "uint", pBitmap, "float*", dpix)
  return Round(dpix)
}
Gdip_GetImageVerticalResolution(pBitmap){
  DllCall("gdiplus\GdipGetImageVerticalResolution", A_PtrSize ? "UPtr" : "uint", pBitmap, "float*", dpiy)
  return Round(dpiy)
}
Gdip_BitmapSetResolution(pBitmap, dpix, dpiy){
  return DllCall("gdiplus\GdipBitmapSetResolution", A_PtrSize ? "UPtr" : "uint", pBitmap, "float", dpix, "float", dpiy)
}
Gdip_CreateBitmapFromFile(sFile, IconNumber=1, IconSize=""){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  , PtrA := A_PtrSize ? "UPtr*" : "UInt*"
  SplitPath, sFile,,, ext
  if ext in exe,dll
  {
    Sizes := IconSize ? IconSize : 256 "|" 128 "|" 64 "|" 48 "|" 32 "|" 16
    BufSize := 16 + (2*(A_PtrSize ? A_PtrSize : 4))
    
    VarSetCapacity(buf, BufSize, 0)
    Loop, Parse, Sizes, |
    {
      DllCall("PrivateExtractIcons", "str", sFile, "int", IconNumber-1, "int", A_LoopField, "int", A_LoopField, PtrA, hIcon, PtrA, 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
    }
    VarSetCapacity(dib, 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, PtrA, pBitmapOld)
    pBitmap := Gdip_CreateBitmap(Width, Height)
    G := Gdip_GraphicsFromImage(pBitmap)
    , Gdip_DrawImage(G, pBitmapOld, 0, 0, Width, Height, 0, 0, Width, Height)
    SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
    Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmapOld)
    DestroyIcon(hIcon)
  }
  else
  {
    if (!A_IsUnicode)
    {
      VarSetCapacity(wFile, 1024)
      DllCall("kernel32\MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sFile, "int", -1, Ptr, &wFile, "int", 512)
      DllCall("gdiplus\GdipCreateBitmapFromFile", Ptr, &wFile, PtrA, pBitmap)
    }
    else
      DllCall("gdiplus\GdipCreateBitmapFromFile", Ptr, &sFile, PtrA, pBitmap)
  }
  
  return pBitmap
}
Gdip_CreateBitmapFromHBITMAP(hBitmap, Palette=0){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr, hBitmap, Ptr, Palette, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
  return pBitmap
}
Gdip_CreateHBITMAPFromBitmap(pBitmap, Background=0xffffffff){
  DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "uint*", hbm, "int", Background)
  return hbm
}
Gdip_CreateBitmapFromHICON(hIcon){
  DllCall("gdiplus\GdipCreateBitmapFromHICON", A_PtrSize ? "UPtr" : "UInt", hIcon, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
  return pBitmap
}
Gdip_CreateHICONFromBitmap(pBitmap){
  DllCall("gdiplus\GdipCreateHICONFromBitmap", A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "uint*", hIcon)
  return hIcon
}
Gdip_CreateBitmap(Width, Height, Format=0x26200A){
  DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Width, "int", Height, "int", 0, "int", Format, A_PtrSize ? "UPtr" : "UInt", 0, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
  Return pBitmap
}
Gdip_CreateBitmapFromClipboard(){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  if !DllCall("OpenClipboard", Ptr, 0)
    return -1
  if !DllCall("IsClipboardFormatAvailable", "uint", 8)
    return -2
  if !hBitmap := DllCall("GetClipboardData", "uint", 2, Ptr)
    return -3
  if !pBitmap := Gdip_CreateBitmapFromHBITMAP(hBitmap)
    return -4
  if !DllCall("CloseClipboard")
    return -5
  DeleteObject(hBitmap)
  return pBitmap
}
Gdip_SetBitmapToClipboard(pBitmap){
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  off1 := A_PtrSize = 8 ? 52 : 44, off2 := A_PtrSize = 8 ? 32 : 24
  hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
  DllCall("GetObject", Ptr, hBitmap, "int", VarSetCapacity(oi, 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+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")
}
Gdip_CloneBitmapArea(pBitmap, x, y, w, h, Format=0x26200A){
  DllCall("gdiplus\GdipCloneBitmapArea", "float", x, "float", y, "float", w, "float", h, "int", Format, A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "UInt*", pBitmapDest)
  return pBitmapDest
}
Gdip_CreatePen(ARGB, w){
   DllCall("gdiplus\GdipCreatePen1", "UInt", ARGB, "float", w, "int", 2, A_PtrSize ? "UPtr*" : "UInt*", pPen)
   return pPen
}
Gdip_CreatePenFromBrush(pBrush, w){
  DllCall("gdiplus\GdipCreatePen2", A_PtrSize ? "UPtr" : "UInt", pBrush, "float", w, "int", 2, A_PtrSize ? "UPtr*" : "UInt*", pPen)
  return pPen
}
Gdip_BrushCreateSolid(ARGB=0xff000000){
  DllCall("gdiplus\GdipCreateSolidFill", "UInt", ARGB, A_PtrSize ? "UPtr*" : "UInt*", pBrush)
  return pBrush
}
Gdip_BrushCreateHatch(ARGBfront, ARGBback, HatchStyle=0){
  DllCall("gdiplus\GdipCreateHatchBrush", "int", HatchStyle, "UInt", ARGBfront, "UInt", ARGBback, A_PtrSize ? "UPtr*" : "UInt*", pBrush)
  return pBrush
}
 
;#####################################################################################
 
Gdip_CreateTextureBrush(pBitmap, WrapMode=1, x=0, y=0, w="", h="")
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  , PtrA := A_PtrSize ? "UPtr*" : "UInt*"
  
  if !(w && h)
    DllCall("gdiplus\GdipCreateTexture", Ptr, pBitmap, "int", WrapMode, PtrA, pBrush)
  else
    DllCall("gdiplus\GdipCreateTexture2", Ptr, pBitmap, "int", WrapMode, "float", x, "float", y, "float", w, "float", h, PtrA, pBrush)
  return pBrush
}
 
Gdip_CreateLineBrush(x1, y1, x2, y2, ARGB1, ARGB2, WrapMode=1)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  CreatePointF(PointF1, x1, y1), CreatePointF(PointF2, x2, y2)
  DllCall("gdiplus\GdipCreateLineBrush", Ptr, &PointF1, Ptr, &PointF2, "Uint", ARGB1, "Uint", ARGB2, "int", WrapMode, A_PtrSize ? "UPtr*" : "UInt*", LGpBrush)
  return LGpBrush
}
 
Gdip_CreateLineBrushFromRect(x, y, w, h, ARGB1, ARGB2, LinearGradientMode=1, WrapMode=1)
{
  CreateRectF(RectF, x, y, w, h)
  DllCall("gdiplus\GdipCreateLineBrushFromRect", A_PtrSize ? "UPtr" : "UInt", &RectF, "int", ARGB1, "int", ARGB2, "int", LinearGradientMode, "int", WrapMode, A_PtrSize ? "UPtr*" : "UInt*", LGpBrush)
  return LGpBrush
}
 
Gdip_CloneBrush(pBrush)
{
  DllCall("gdiplus\GdipCloneBrush", A_PtrSize ? "UPtr" : "UInt", pBrush, A_PtrSize ? "UPtr*" : "UInt*", pBrushClone)
  return pBrushClone
}
 
Gdip_DeletePen(pPen)
{
   return DllCall("gdiplus\GdipDeletePen", A_PtrSize ? "UPtr" : "UInt", pPen)
}
 
Gdip_DeleteBrush(pBrush)
{
   return DllCall("gdiplus\GdipDeleteBrush", A_PtrSize ? "UPtr" : "UInt", pBrush)
}
 
Gdip_DisposeImage(pBitmap)
{
   return DllCall("gdiplus\GdipDisposeImage", A_PtrSize ? "UPtr" : "UInt", pBitmap)
}
 
Gdip_DeleteGraphics(pGraphics)
{
   return DllCall("gdiplus\GdipDeleteGraphics", A_PtrSize ? "UPtr" : "UInt", pGraphics)
}
 
Gdip_DisposeImageAttributes(ImageAttr)
{
  return DllCall("gdiplus\GdipDisposeImageAttributes", A_PtrSize ? "UPtr" : "UInt", ImageAttr)
}
 
Gdip_DeleteFont(hFont)
{
   return DllCall("gdiplus\GdipDeleteFont", A_PtrSize ? "UPtr" : "UInt", hFont)
}
 
Gdip_DeleteStringFormat(hFormat)
{
   return DllCall("gdiplus\GdipDeleteStringFormat", A_PtrSize ? "UPtr" : "UInt", hFormat)
}
 
Gdip_DeleteFontFamily(hFamily)
{
   return DllCall("gdiplus\GdipDeleteFontFamily", A_PtrSize ? "UPtr" : "UInt", hFamily)
}
 
Gdip_DeleteMatrix(Matrix)
{
   return DllCall("gdiplus\GdipDeleteMatrix", A_PtrSize ? "UPtr" : "UInt", Matrix)
}
 
Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="", 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
}
 
Gdip_DrawString(pGraphics, sString, hFont, hFormat, pBrush, ByRef RectF)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  if (!A_IsUnicode)
  {
    nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, 0, "int", 0)
    VarSetCapacity(wString, nSize*2)
    DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, &wString, "int", nSize)
  }
  
  return DllCall("gdiplus\GdipDrawString"
          , Ptr, pGraphics
          , Ptr, A_IsUnicode ? &sString : &wString
          , "int", -1
          , Ptr, hFont
          , Ptr, &RectF
          , Ptr, hFormat
          , Ptr, pBrush)
}
 
Gdip_MeasureString(pGraphics, sString, hFont, hFormat, ByRef RectF)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  VarSetCapacity(RC, 16)
  if !A_IsUnicode
  {
    nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, "uint", 0, "int", 0)
    VarSetCapacity(wString, nSize*2)   
    DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, &wString, "int", nSize)
  }
  
  DllCall("gdiplus\GdipMeasureString"
          , Ptr, pGraphics
          , Ptr, A_IsUnicode ? &sString : &wString
          , "int", -1
          , Ptr, hFont
          , Ptr, &RectF
          , Ptr, hFormat
          , Ptr, &RC
          , "uint*", Chars
          , "uint*", Lines)
  
  return &RC ? NumGet(RC, 0, "float") "|" NumGet(RC, 4, "float") "|" NumGet(RC, 8, "float") "|" NumGet(RC, 12, "float") "|" Chars "|" Lines : 0
}
 
; Near = 0
; Center = 1
; Far = 2
Gdip_SetStringFormatAlign(hFormat, Align)
{
   return DllCall("gdiplus\GdipSetStringFormatAlign", A_PtrSize ? "UPtr" : "UInt", hFormat, "int", Align)
}
 
 
Gdip_StringFormatCreate(Format=0, Lang=0)
{
   DllCall("gdiplus\GdipCreateStringFormat", "int", Format, "int", Lang, A_PtrSize ? "UPtr*" : "UInt*", hFormat)
   return hFormat
}
 
Gdip_FontCreate(hFamily, Size, Style=0)
{
   DllCall("gdiplus\GdipCreateFont", A_PtrSize ? "UPtr" : "UInt", hFamily, "float", Size, "int", Style, "int", 0, A_PtrSize ? "UPtr*" : "UInt*", hFont)
   return hFont
}
 
Gdip_FontFamilyCreate(Font)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  if (!A_IsUnicode)
  {
    nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &Font, "int", -1, "uint", 0, "int", 0)
    VarSetCapacity(wFont, nSize*2)
    DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &Font, "int", -1, Ptr, &wFont, "int", nSize)
  }
  
  DllCall("gdiplus\GdipCreateFontFamilyFromName"
          , Ptr, A_IsUnicode ? &Font : &wFont
          , "uint", 0
          , A_PtrSize ? "UPtr*" : "UInt*", hFamily)
  
  return hFamily
}
 
Gdip_CreateAffineMatrix(m11, m12, m21, m22, x, y)
{
   DllCall("gdiplus\GdipCreateMatrix2", "float", m11, "float", m12, "float", m21, "float", m22, "float", x, "float", y, A_PtrSize ? "UPtr*" : "UInt*", Matrix)
   return Matrix
}
 
Gdip_CreateMatrix()
{
   DllCall("gdiplus\GdipCreateMatrix", A_PtrSize ? "UPtr*" : "UInt*", Matrix)
   return Matrix
}
Gdip_CreatePath(BrushMode=0)
{
  DllCall("gdiplus\GdipCreatePath", "int", BrushMode, A_PtrSize ? "UPtr*" : "UInt*", Path)
  return Path
}
 
Gdip_AddPathEllipse(Path, x, y, w, h)
{
  return DllCall("gdiplus\GdipAddPathEllipse", A_PtrSize ? "UPtr" : "UInt", Path, "float", x, "float", y, "float", w, "float", h)
}
 
Gdip_AddPathPolygon(Path, Points)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  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\GdipAddPathPolygon", Ptr, Path, Ptr, &PointF, "int", Points0)
}
 
Gdip_DeletePath(Path)
{
  return DllCall("gdiplus\GdipDeletePath", A_PtrSize ? "UPtr" : "UInt", Path)
}
 
Gdip_SetTextRenderingHint(pGraphics, RenderingHint)
{
  return DllCall("gdiplus\GdipSetTextRenderingHint", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", RenderingHint)
}
 
Gdip_SetInterpolationMode(pGraphics, InterpolationMode)
{
   return DllCall("gdiplus\GdipSetInterpolationMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", InterpolationMode)
}
Gdip_SetSmoothingMode(pGraphics, SmoothingMode)
{
   return DllCall("gdiplus\GdipSetSmoothingMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", SmoothingMode)
}
Gdip_SetCompositingMode(pGraphics, CompositingMode=0)
{
   return DllCall("gdiplus\GdipSetCompositingMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", CompositingMode)
}
 
Gdip_Startup()
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
    DllCall("LoadLibrary", "str", "gdiplus")
  VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
  DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, Ptr, &si, Ptr, 0)
  return pToken
}
 
Gdip_Shutdown(pToken)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
  if hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
    DllCall("FreeLibrary", Ptr, hModule)
  return 0
}
 
Gdip_RotateWorldTransform(pGraphics, Angle, MatrixOrder=0)
{
  return DllCall("gdiplus\GdipRotateWorldTransform", A_PtrSize ? "UPtr" : "UInt", pGraphics, "float", Angle, "int", MatrixOrder)
}
 
Gdip_ScaleWorldTransform(pGraphics, x, y, MatrixOrder=0)
{
  return DllCall("gdiplus\GdipScaleWorldTransform", A_PtrSize ? "UPtr" : "UInt", pGraphics, "float", x, "float", y, "int", MatrixOrder)
}
 
Gdip_TranslateWorldTransform(pGraphics, x, y, MatrixOrder=0)
{
  return DllCall("gdiplus\GdipTranslateWorldTransform", A_PtrSize ? "UPtr" : "UInt", pGraphics, "float", x, "float", y, "int", MatrixOrder)
}
 
Gdip_ResetWorldTransform(pGraphics)
{
  return DllCall("gdiplus\GdipResetWorldTransform", A_PtrSize ? "UPtr" : "UInt", pGraphics)
}
 
Gdip_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)
}
 
Gdip_GetRotatedDimensions(Width, Height, Angle, ByRef RWidth, ByRef RHeight)
{
  pi := 3.14159, 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)))
}
 
 
Gdip_ImageRotateFlip(pBitmap, RotateFlipType=1)
{
  return DllCall("gdiplus\GdipImageRotateFlip", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", RotateFlipType)
}
 
Gdip_SetClipRect(pGraphics, x, y, w, h, CombineMode=0)
{
   return DllCall("gdiplus\GdipSetClipRect",  A_PtrSize ? "UPtr" : "UInt", pGraphics, "float", x, "float", y, "float", w, "float", h, "int", CombineMode)
}
 
Gdip_SetClipPath(pGraphics, Path, CombineMode=0)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  return DllCall("gdiplus\GdipSetClipPath", Ptr, pGraphics, Ptr, Path, "int", CombineMode)
}
 
Gdip_ResetClip(pGraphics)
{
   return DllCall("gdiplus\GdipResetClip", A_PtrSize ? "UPtr" : "UInt", pGraphics)
}
 
Gdip_GetClipRegion(pGraphics)
{
  Region := Gdip_CreateRegion()
  DllCall("gdiplus\GdipGetClip", A_PtrSize ? "UPtr" : "UInt", pGraphics, "UInt*", Region)
  return Region
}
 
Gdip_SetClipRegion(pGraphics, Region, CombineMode=0)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  return DllCall("gdiplus\GdipSetClipRegion", Ptr, pGraphics, Ptr, Region, "int", CombineMode)
}
 
Gdip_CreateRegion()
{
  DllCall("gdiplus\GdipCreateRegion", "UInt*", Region)
  return Region
}
 
Gdip_DeleteRegion(Region)
{
  return DllCall("gdiplus\GdipDeleteRegion", A_PtrSize ? "UPtr" : "UInt", Region)
}
 
 
Gdip_LockBits(pBitmap, x, y, w, h, ByRef Stride, ByRef Scan0, ByRef BitmapData, LockMode = 3, PixelFormat = 0x26200a)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  CreateRect(Rect, x, y, w, h)
  VarSetCapacity(BitmapData, 16+2*(A_PtrSize ? A_PtrSize : 4), 0)
  E := DllCall("Gdiplus\GdipBitmapLockBits", Ptr, pBitmap, Ptr, &Rect, "uint", LockMode, "int", PixelFormat, Ptr, &BitmapData)
  Stride := NumGet(BitmapData, 8, "Int")
  Scan0 := NumGet(BitmapData, 16, Ptr)
  return E
}
 
Gdip_UnlockBits(pBitmap, ByRef BitmapData)
{
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  return DllCall("Gdiplus\GdipBitmapUnlockBits", Ptr, pBitmap, Ptr, &BitmapData)
}
 
Gdip_SetLockBitPixel(ARGB, Scan0, x, y, Stride)
{
  Numput(ARGB, Scan0+0, (x*4)+(y*Stride), "UInt")
}
 
;#####################################################################################
 
Gdip_GetLockBitPixel(Scan0, x, y, Stride)
{
  return NumGet(Scan0+0, (x*4)+(y*Stride), "UInt")
}
 
;#####################################################################################
 
Gdip_PixelateBitmap(pBitmap, ByRef pBitmapOut, BlockSize)
{
  static PixelateBitmap
  
  Ptr := A_PtrSize ? "UPtr" : "UInt"
  
  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
    )
    
    VarSetCapacity(PixelateBitmap, StrLen(MCode_PixelateBitmap)//2)
    Loop % StrLen(MCode_PixelateBitmap)//2    ;%
      NumPut("0x" SubStr(MCode_PixelateBitmap, (2*A_Index)-1, 2), PixelateBitmap, A_Index-1, "UChar")
    DllCall("VirtualProtect", Ptr, &PixelateBitmap, Ptr, VarSetCapacity(PixelateBitmap), "uint", 0x40, A_PtrSize ? "UPtr*" : "UInt*", 0)
  }
 
  Gdip_GetImageDimensions(pBitmap, Width, Height)
  
  if (Width != Gdip_GetImageWidth(pBitmapOut) || Height != Gdip_GetImageHeight(pBitmapOut))
    return -1
  if (BlockSize > Width || BlockSize > Height)
    return -2
 
  E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1)
  E2 := Gdip_LockBits(pBitmapOut, 0, 0, Width, Height, Stride2, Scan02, BitmapData2)
  if (E1 || E2)
    return -3
 
  E := DllCall(&PixelateBitmap, Ptr, Scan01, Ptr, Scan02, "int", Width, "int", Height, "int", Stride1, "int", BlockSize)
  
  Gdip_UnlockBits(pBitmap, BitmapData1), Gdip_UnlockBits(pBitmapOut, BitmapData2)
  return 0
}
 
;#####################################################################################
 
Gdip_ToARGB(A, R, G, B)
{
  return (A << 24) | (R << 16) | (G << 8) | B
}
 
;#####################################################################################
 
Gdip_FromARGB(ARGB, ByRef A, ByRef R, ByRef G, ByRef B)
{
  A := (0xff000000 & ARGB) >> 24
  R := (0x00ff0000 & ARGB) >> 16
  G := (0x0000ff00 & ARGB) >> 8
  B := 0x000000ff & ARGB
}
 
;#####################################################################################
 
Gdip_AFromARGB(ARGB)
{
  return (0xff000000 & ARGB) >> 24
}
 
;#####################################################################################
 
Gdip_RFromARGB(ARGB)
{
  return (0x00ff0000 & ARGB) >> 16
}
 
;#####################################################################################
 
Gdip_GFromARGB(ARGB)
{
  return (0x0000ff00 & ARGB) >> 8
}
 
;#####################################################################################
 
Gdip_BFromARGB(ARGB)
{
  return 0x000000ff & ARGB
}
 
;#####################################################################################
 
StrGetB(Address, Length=-1, Encoding=0)
{
  ; Flexible parameter handling:
  if Length is not integer
  Encoding := Length,  Length := -1
 
  ; Check for obvious errors.
  if (Address+0 < 1024)
    return
 
  ; Ensure 'Encoding' contains a numeric identifier.
  if Encoding = UTF-16
    Encoding = 1200
  else if Encoding = UTF-8
    Encoding = 65001
  else if SubStr(Encoding,1,2)="CP"
    Encoding := SubStr(Encoding,3)
 
  if !Encoding ; "" or 0
  {
    ; No conversion necessary, but we might not want the whole string.
    if (Length == -1)
      Length := DllCall("lstrlen", "uint", Address)
    VarSetCapacity(String, Length)
    DllCall("lstrcpyn", "str", String, "uint", Address, "int", Length + 1)
  }
  else if Encoding = 1200 ; UTF-16
  {
    char_count := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0x400, "uint", Address, "int", Length, "uint", 0, "uint", 0, "uint", 0, "uint", 0)
    VarSetCapacity(String, char_count)
    DllCall("WideCharToMultiByte", "uint", 0, "uint", 0x400, "uint", Address, "int", Length, "str", String, "int", char_count, "uint", 0, "uint", 0)
  }
  else if Encoding is integer
  {
    ; Convert from target encoding to UTF-16 then to the active code page.
    char_count := DllCall("MultiByteToWideChar", "uint", Encoding, "uint", 0, "uint", Address, "int", Length, "uint", 0, "int", 0)
    VarSetCapacity(String, char_count * 2)
    char_count := DllCall("MultiByteToWideChar", "uint", Encoding, "uint", 0, "uint", Address, "int", Length, "uint", &String, "int", char_count * 2)
    String := StrGetB(&String, char_count, 1200)
  }
  
  return String
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。