FastPrints - Fast and organized screen capture and save tool with features

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
RAFACN
Posts: 12
Joined: 20 May 2016, 10:06
Location: BRAZIL

FastPrints - Fast and organized screen capture and save tool with features

20 May 2016, 11:03

Hey Guys! :)
This is my tool called FastPrints. I hope you guys like it!

Preview GIF:
https://imgur.com/CHZI6rR

*The updated version is in Portuguese but if you dont understand portuguese there is no problem cause the usage description is written in english right here. Also i will update the english version soon.

Usage Tutorial (in Portuguese):
[youtube]www.youtube.com/watch?v=9L7RwOr2EJU[/youtube]

FastPrints - Fast and organized screen capture and save tool
Basic Commands:
Control + F2 -> Menu
Control + F1 -> Shot and Save (NOTATION: Title_Sequencial)
RControl (Hold) -> Bound Area
RControl (Click) -> Unbound Area
Appskey (Hold) -> Draw Arrow
Appskey (Click) -> Remove Last Drawn Arrow

Advanced Commands:
Control + F3 -> Shot and Save (NOTATION: Title_Sequencial-SubSequencial)
Control + F5 -> Bound and Save (NOTATION: Title_Sequencial)
Control + F12 -> Undo Capture

System Commands:
Control + Insert -> Restart tool
Control + Escape -> Close tool



I use a high number of GLOBAL variables (most for debuggin purposes), this really needs to be "cleaned up". But the code works fine as i see.

I used some functions i found some months ago from different guys in this forum. Sorry if i dont remember the full list of names, ok?!

Please, put the Tic's "Gdip.ahk" at the script's folder.


PORTUGUESE VERSION

Code: Select all

;~ BY: RAFAEL CARNEIRO NASCIMENTO (RAFACN)


#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

#SingleInstance force
SetBatchLines, -1
#InstallMouseHook ; necessário, mas deixa os outros scripts lentos pois implica: Persistent

#Include Gdip.ahk

CoordMode, Mouse, Screen

TRAY_SETUP()

;~ Inicializa variáveis
GLOBAL Texto := "MinhaImagem"
GLOBAL Sequencial := "00001"
GLOBAL Last_Sequencial := Sequencial
GLOBAL Sub_Sequencial := "001"
GLOBAL LastSavedImagePath := ""
GLOBAL LastSave
GLOBAL USING_TOOLTIP_DEBUG := False
GLOBAL chkSHOWING_WARNINGS := True
GLOBAL chkKEEPING_FRAME := True
GLOBAL optSETAS_VERMELHAS := False
GLOBAL optSETAS_VERDES := False
GLOBAL optSETAS_AZUIS := False
GLOBAL optSETAS_ROXAS := False
GLOBAL optSETAS_ROSA := False
GLOBAL optSETAS_CINZA := False
GLOBAL optSETAS_BEGE := False
GLOBAL optSETAS_COLORIDAS := True
GLOBAL sldArrow_Size := 1
GLOBAL chkBold_Arrow := 1
GLOBAL USING_PROTECTION := False
GLOBAL USING_INSTRUCTIONS_ON_STARTUP := True
GLOBAL FASTER_SHOT_WAS_CALLED := False
GLOBAL SQUARE_IS_BEING_DRAWN := False
GLOBAL SQUARE_IS_DRAWN := False
GLOBAL AREA_IS_BOUNDED := False
GLOBAL arrowGui_IS_DESTROYED := True
GLOBAL x_ScreenSelected, y_ScreenSelected, w_ScreenSelected, h_ScreenSelected
GLOBAL pBitmap_0
GLOBAL pPen_0, G_0, hdc_0, obm_0, hbm_0, pToken_0, hwnd_0 ; <<< 1.4
GLOBAL pPen_1, G_1, hdc_1, obm_1, hbm_1, pToken_1, hwnd_1 ; <<< 1.4
GLOBAL IGUAL_pPen, IGUAL_G, IGUAL_hdc, IGUAL_obm, IGUAL_hbm, IGUAL_pToken, IGUAL_hwnd ; <<< 1.4
GLOBAL LAST_MX = 0
GLOBAL LAST_MY = 0
GLOBAL LAST_COLOR := 0xFF000000
Width := A_ScreenWidth, Height := A_ScreenHeight
Window_D := Distance(0, 0, Width, Height)

GLOBAL USING_debugGlobalVariables := False
GLOBAL USING_GdipTooltipHelp := False
GLOBAL USING_showMemoryUsage := False

GLOBAL List_Buffer

if(USING_GdipTooltipHelp)
{
	GLOBAL	GraphicsClear_G_0 := False
		,DeletePen_pPen_0 := False
		,DeleteGraphics_G_0 := False
		,SelectObject_obm_0 := False
		,DeleteObject_hbm_0 := False
		,DeleteDC_hdc_0 := False
		,DisposeImage_pBitmap_0 := False
		,Shutdown_pToken_0 := False
		,Gui_dragOverlay_Destroy_0 := False
		,Startup_pToken_0 := False
		,BitmapFromScreen_pBitmap_0 := False
		,SaveBitmapToFile_pBitmap_0 := False
		,CloneBitmapArea_pBitmap_0 := False
		,CreateDIBSection_hbm_0 := False
		,CreateCompatibleDC_hdc_0 := False
		,SelectObject_hbm_0 := False
		,GraphicsFromHDC_G_0_hdc_0 := False
		,TextToGraphics_G_0 := False
		,UpdateLayeredWindow_hwnd_0_hdc_0 := False
		,CreatePen_pPen_0 := False
		,Gui_dragOverlay_Show_0 := False
		,Gui_arrowGui_Show_1 := False
		,Startup_pToken_1 := False
		,CreateDIBSection_hbm_1 := False
		,CreateCompatibleDC_hdc_1 := False
		,SelectObject_hbm_1 := False
		,GraphicsFromHDC_G_1_hdc_1 := False
		,GraphicsClear_G_1 := False
		,UpdateLayeredWindow_hwnd_1_hdc_1 := False
		,CreatePen_pPen_1 := False
		,DeletePen_pPen_1 := False
		,DrawLines_G_1_pPen_1 := False
		,Gui_arrowGui_Destroy_1 := False
		,Refresh_Count := 0
		,Count_GraphicsClear_G_0 := 0
		,Count_DeletePen_pPen_0 := 0
		,Count_DeleteGraphics_G_0 := 0
		,Count_SelectObject_obm_0 := 0
		,Count_DeleteObject_hbm_0 := 0
		,Count_DeleteDC_hdc_0 := 0
		,Count_DisposeImage_pBitmap_0 := 0
		,Count_Shutdown_pToken_0 := 0
		,Count_Gui_dragOverlay_Destroy_0 := 0
		,Count_Startup_pToken_0 := 0
		,Count_BitmapFromScreen_pBitmap_0 := 0
		,Count_SaveBitmapToFile_pBitmap_0 := 0
		,Count_CloneBitmapArea_pBitmap_0 := 0
		,Count_CreateDIBSection_hbm_0 := 0
		,Count_CreateCompatibleDC_hdc_0 := 0
		,Count_SelectObject_hbm_0 := 0
		,Count_GraphicsFromHDC_G_0_hdc_0 := 0
		,Count_TextToGraphics_G_0 := 0
		,Count_UpdateLayeredWindow_hwnd_0_hdc_0 := 0
		,Count_CreatePen_pPen_0 := 0
		,Count_Gui_dragOverlay_Show_0 := 0
		,Count_Gui_arrowGui_Show_1 := 0
		,Count_Startup_pToken_1 := 0
		,Count_CreateDIBSection_hbm_1 := 0
		,Count_CreateCompatibleDC_hdc_1 := 0
		,Count_SelectObject_hbm_1 := 0
		,Count_GraphicsFromHDC_G_1_hdc_1 := 0
		,Count_GraphicsClear_G_1 := 0
		,Count_UpdateLayeredWindow_hwnd_1_hdc_1 := 0
		,Count_CreatePen_pPen_1 := 0
		,Count_DeletePen_pPen_1 := 0
		,Count_DrawLines_G_1_pPen_1 := 0
		,Count_Gui_arrowGui_Destroy_1 := 0
}

GLOBAL TRIAL_DATE := 20210101 ; "01/01/2021"
GLOBAL Trial_DaysLeft, CurrentDate
FormatTime, CurrentDate,, yyyyMMdd

Trial_DaysLeft := TRIAL_DATE ; := 20160701
Trial_DaysLeft -= CurrentDate, days

If(Trial_DaysLeft<0)
	Trial_DaysLeft := 0

; PROTEÇÃO
; My serial number for Disc C:
if(USING_PROTECTION)
{
	;~ My_HD_SERIAL_NUMBER := "236110783"
	;~ DriveGet, hSerial, Serial, C:
	;~ MsgBox, %hSerial%
	if(CurrentDate > TRIAL_DATE)
	{
		Goto, Exit
	}
	;~ if(hSerial <> My_HD_SERIAL_NUMBER)
		;~ exitapp
}

;~ Exibe instruções iniciais via GUI
if(USING_INSTRUCTIONS_ON_STARTUP)
{
	INSTRUCTIONS()
}

If(!USING_debugGlobalVariables && !USING_showMemoryUsage)
{
	Goto JUMP_PersistentTimers
}

 ;~ ################################################################################# >>
;~ #Persistent
;~ If(USING_debugGlobalVariables)
	;~ SetTimer, debugGlobalVariables, 400
;~ If(USING_showMemoryUsage)
	;~ SetTimer, showMemoryUsage, 400
;~ If(USING_GdipTooltipHelp)
	;~ SetTimer, GdipTooltipHelp, 1000
;~ return
 ;~ ################################################################################# >>
debugGlobalVariables:
	if(USING_debugGlobalVariables)
	{
		IGUAL_pPen := (pPen_0 == pPen_1) && (pPen_0!="")
		IGUAL_G := (G_0 == G_1) && (G_0!="")
		IGUAL_hdc := (hdc_0 == hdc_1) && (hdc_0!="")
		IGUAL_obm := (obm_0 == obm_1) && (obm_0!="")
		IGUAL_hbm := (hbm_0 == hbm_1) && (hbm_0!="")
		IGUAL_pToken := (pToken_0 == pToken_1) && (pToken_0!="")
		IGUAL_hwnd := (hwnd_0 == hwnd_1) && (hwnd_0!="")
		tooltip,. pBitmap_0: %pBitmap_0%`n`n
				. pPen_0: %pPen_0%`t`t|pPen_1: %pPen_1%`t`t| %IGUAL_pPen%`n
				. G_0: %G_0%`t`t`t|G_1: %G_1%`t`t| %IGUAL_G%`n
				. hdc_0: %hdc_0%`t`t`t|hdc_1: %hdc_1%`t`t| %IGUAL_hdc%`n
				. obm_0: %obm_0%`t`t|obm_1: %obm_1%`t`t| %IGUAL_obm%`n
				. hbm_0: %hbm_0%`t`t|hbm_1: %hbm_1%`t`t| %IGUAL_hbm%`n
				. pToken_0: %pToken_0%`t`t|pToken_1: %pToken_1%`t| %IGUAL_pToken%`n
				. hwnd_0: %hwnd_0%`t`t|hwnd_1: %hwnd_1%`t| %IGUAL_hwnd%`n`n
				. |List_Buffer: `n%List_Buffer%
				. `n,1,30,8
	}
return
 ;~ ################################################################################# >>
GdipTooltipHelp:
	if(USING_GdipTooltipHelp)
	{
		Refresh_Count += 1
		if(Refresh_Count >= 8)
			TooltipHelp_ResetFlags()
		tooltip,. Startup_pToken_0: `t`t`t%Startup_pToken_0%|%Count_Startup_pToken_0%`n
				. CreateDIBSection_hbm_0: `t`t%CreateDIBSection_hbm_0%|%Count_CreateDIBSection_hbm_0%`n
				. CreateCompatibleDC_hdc_0: `t`t%CreateCompatibleDC_hdc_0%|%Count_CreateCompatibleDC_hdc_0%`n
				. SelectObject_hbm_0: `t`t`t%SelectObject_hbm_0%|%Count_SelectObject_hbm_0%`n
				. GraphicsFromHDC_G_0_hdc_0: `t`t%GraphicsFromHDC_G_0_hdc_0%|%Count_GraphicsFromHDC_G_0_hdc_0%`n
				. TextToGraphics_G_0: `t`t`t%TextToGraphics_G_0%|%Count_TextToGraphics_G_0%`n
				. UpdateLayeredWindow_hwnd_0_hdc_0: `t%UpdateLayeredWindow_hwnd_0_hdc_0%|%Count_UpdateLayeredWindow_hwnd_0_hdc_0%`n
				. CreatePen_pPen_0: `t`t`t%CreatePen_pPen_0%|%Count_CreatePen_pPen_0%`n
				. Gui_dragOverlay_Show_0: `t`t%Gui_dragOverlay_Show_0%|%Count_Gui_dragOverlay_Show_0%`n
				. `n
				. GraphicsClear_G_0: `t`t`t%GraphicsClear_G_0%|%Count_GraphicsClear_G_0%`n
				. DeletePen_pPen_0: `t`t`t%DeletePen_pPen_0%|%Count_DeletePen_pPen_0%`n
				. DeleteGraphics_G_0: `t`t`t%DeleteGraphics_G_0%|%Count_DeleteGraphics_G_0%`n
				. SelectObject_obm_0: `t`t`t%SelectObject_obm_0%|%Count_SelectObject_obm_0%`n
				. DeleteObject_hbm_0: `t`t`t%DeleteObject_hbm_0%|%Count_DeleteObject_hbm_0%`n
				. DeleteDC_hdc_0: `t`t`t%DeleteDC_hdc_0%|%Count_DeleteDC_hdc_0%`n
				. DisposeImage_pBitmap_0: `t`t%DisposeImage_pBitmap_0%|%Count_DisposeImage_pBitmap_0%`n
				. Shutdown_pToken_0: `t`t`t%Shutdown_pToken_0%|%Count_Shutdown_pToken_0%`n
				. Gui_dragOverlay_Destroy_0: `t`t%Gui_dragOverlay_Destroy_0%|%Count_Gui_dragOverlay_Destroy_0%`n
				. `n
				. BitmapFromScreen_pBitmap_0: `t`t%BitmapFromScreen_pBitmap_0%|%Count_BitmapFromScreen_pBitmap_0%`n
				. SaveBitmapToFile_pBitmap_0: `t`t%SaveBitmapToFile_pBitmap_0%|%Count_SaveBitmapToFile_pBitmap_0%`n
				. CloneBitmapArea_pBitmap_0: `t`t%CloneBitmapArea_pBitmap_0%|%Count_CloneBitmapArea_pBitmap_0%`n
				. `n
				. Startup_pToken_1: `t`t`t%Startup_pToken_1%|%Count_Startup_pToken_1%`n
				. CreateDIBSection_hbm_1: `t`t%CreateDIBSection_hbm_1%|%Count_CreateDIBSection_hbm_1%`n
				. CreateCompatibleDC_hdc_1: `t`t%CreateCompatibleDC_hdc_1%|%Count_CreateCompatibleDC_hdc_1%`n
				. SelectObject_hbm_1: `t`t`t%SelectObject_hbm_1%|%Count_SelectObject_hbm_1%`n
				. GraphicsFromHDC_G_1_hdc_1: `t`t%GraphicsFromHDC_G_1_hdc_1%|%Count_GraphicsFromHDC_G_1_hdc_1%`n
				. UpdateLayeredWindow_hwnd_1_hdc_1: `t%UpdateLayeredWindow_hwnd_1_hdc_1%|%Count_UpdateLayeredWindow_hwnd_1_hdc_1%`n
				. CreatePen_pPen_1: `t`t`t%CreatePen_pPen_1%|%Count_CreatePen_pPen_1%`n
				. DrawLines_G_1_pPen_1: `t`t`t%DrawLines_G_1_pPen_1%|%Count_DrawLines_G_1_pPen_1%`n
				. Gui_arrowGui_Show_1: `t`t`t%Gui_arrowGui_Show_1%|%Count_Gui_arrowGui_Show_1%`n
				. `n
				. GraphicsClear_G_1: `t`t`t%GraphicsClear_G_1%|%Count_GraphicsClear_G_1%`n
				. DeletePen_pPen_1: `t`t`t%DeletePen_pPen_1%|%Count_DeletePen_pPen_1%`n
				. Gui_arrowGui_Destroy_1: `t`t`t%Gui_arrowGui_Destroy_1%|%Count_Gui_arrowGui_Destroy_1%`n
				. `n
				. Refresh_Count: %Refresh_Count%`n,1,350,9
	}
return
 ;~ ################################################################################# >>
showMemoryUsage:
if(USING_showMemoryUsage)
{
  mem := GetProcessMemoryInfo("AutoHotkey.exe")
  ;~ tooltip, %mem% KB,1,1,MemoryUsage
  tooltip, Uso de Memória: %mem% KB,1,1,7
}
return
 ;~ ################################################################################# >>
JUMP_PersistentTimers:




;~ Desliga Timer utilizado para exibir algumas tooltips por tempo determinado.
RemoveToolTip:
	SetTimer, RemoveToolTip, Off
	ToolTip,,,,4 
	ToolTip
return

RemoveToolTip_DEBUG:
	SetTimer, RemoveToolTip_DEBUG, Off
	ToolTip,,,,2
	ToolTip,,,,3
	ToolTip,,,,4
	ToolTip,,,,5
	ToolTip,,,,6
	ToolTip,,,,7
	ToolTip,,,,8
	ToolTip,,,,9
	ToolTip,,,,10
return

;~ RemoveToolTip_MemoryUsage:
	;~ SetTimer, RemoveToolTip_MemoryUsage, Off
	;~ ToolTip,,,,MemoryUsage_Tooltip
;~ return
;~ ################################################################################# >>
;~ DEFINE ÁREA AO SEGURAR E ARRASTAR RCONTROL
;~ REMOVE AREA DEFINIDA AO CLICAR APENAS UMA VEZ RAPIDO
RControl:: ;~ LControl&RAlt::  ; AltGr
{
	if(SQUARE_IS_DRAWN)
	{
		Loop, 4
		{
			Sleep, 50
			If !( GetKeyState(A_ThisHotkey, "P") )
			{
					;~ REMOVE_DEFINED_AREA()  
					REMOVE_DEFINED_AREA_2() 
					tooltip, ÁREA DELIMITADA!
					SetTimer, RemoveToolTip, 2000
				return
			}
		}
	}
	else
	{
		DEFINE_AREA_TO_SAVE_2()
		if(!SQUARE_IS_DRAWN) 
		{
			tooltip, CANCELADO!
			SetTimer, RemoveToolTip, 2000
			return
		}
	}
}
return
;~ ################################################################################# >>
;~ CAPTURA E SALVA TELA - MODO 1 (TEXTO_SEQ)
^F1:: 
if(SQUARE_IS_BEING_DRAWN)
{
	;~ tooltip, MODO DE DESENHO ATIVADO`, PARA HABILITAR PRINTS APERTE SHIFT OU SEGURE E SELECIONE UMA ÁREA.
	tooltip, SEGURE SHIFT E ARRASTE O CURSOR PARA SELECIONAR A ÁREA OU CLIQUE NO SHIFT PARA CANCELAR.
	SetTimer, RemoveToolTip, 10000
	return
}
if(chkSHOWING_WARNINGS)
{
	IfExist, %A_WorkingDir%/CAPTURES/%Texto%_%Sequencial%.png
	{
		msgbox, 4, Alerta, Já existe um arquivo com o nome: %Texto%_%Sequencial%.png.`nContinuar?
		IfMsgBox, No
		{
			return
		}
		else
		{
			sleep 300 ; wait msgbox to close
		}
	}
}
	NAME_MODE := "TITLE_SEQ"
	FASTER_SHOT_WAS_CALLED := False
	Sub_Sequencial := "001"
	Sub_Sequencial := SubStr("000" . Sub_Sequencial,-2)
	GOTO JUMPKEY_1
;~ ################################################################################# >>
;~ CAPTURA E SALVA TELA - MODO 2 (TEXTO_SEQ-SUBSEQ)
^F3::
if(SQUARE_IS_BEING_DRAWN)
{
	;~ tooltip, MODO DE DESENHO ATIVADO`, PARA HABILITAR PRINTS APERTE SHIFT OU SEGURE E SELECIONE UMA ÁREA.
	tooltip, SEGURE SHIFT E ARRASTE O CURSOR PARA SELECIONAR A ÁREA OU CLIQUE NO SHIFT PARA CANCELAR.
	SetTimer, RemoveToolTip, 10000
	return
} 
if(chkSHOWING_WARNINGS)
{
	IfExist, %A_WorkingDir%/CAPTURES/%Texto%_%Sequencial%-%Sub_Sequencial%.png
	{
		msgbox, 4, Alerta, Já existe um arquivo com o nome: %Texto%_%Sequencial%-%Sub_Sequencial%.png.`nContinuar?
		IfMsgBox, No
		{
			return
		}
		else
		{
			sleep 300 ; wait msgbox to close
		}
	}
}
	NAME_MODE := "TITLE_SEQ-SUBSEQ"
	FASTER_SHOT_WAS_CALLED := False
	Sub_Sequencial := SubStr("000" . Sub_Sequencial,-2)
	GOTO JUMPKEY_1
;~ ################################################################################# >>
;~ CAPTURA E SALVA TELA - MODO 3 (TEXTO_SEQ) FAST MODE
^F5:: 
if(SQUARE_IS_BEING_DRAWN)
{
	;~ tooltip, MODO DE DESENHO ATIVADO`, PARA HABILITAR PRINTS APERTE SHIFT OU SEGURE E SELECIONE UMA ÁREA.
	tooltip, SEGURE SHIFT E ARRASTE O CURSOR PARA SELECIONAR A ÁREA OU CLIQUE NO SHIFT PARA CANCELAR.
	SetTimer, RemoveToolTip, 10000
	return
}
if(chkSHOWING_WARNINGS)
{
	IfExist, %A_WorkingDir%/CAPTURES/%Texto%_%Sequencial%.png
	{
		msgbox, 4, Alerta, Já existe um arquivo com o nome: %Texto%_%Sequencial%.png.`nContinuar?
		IfMsgBox, No
		{
			return
		}
		else
		{
			sleep 300 ; wait msgbox to close
		}
	}
}
	NAME_MODE := "TITLE_SEQ"
	FASTER_SHOT_WAS_CALLED := True
	Sub_Sequencial := "001"
	Sub_Sequencial := SubStr("000" . Sub_Sequencial,-2)
JUMPKEY_1:
{
	if(NAME_MODE == "TITLE_SEQ-SUBSEQ")
		Sequencial := Last_Sequencial ; mantém o sequencial
	
	Last_Sequencial := Sequencial
	
	if (!MAINPATH_IS_ACESSIBLE())
	{
		msgbox, Erro ao criar o diretório: %A_WorkingDir%\CAPTURES
		return
	}
	Gui,MenuFastPrints: Destroy
		
	;~ PROCEDIMENTO DE CAPTURA/SALVAMENTO DE TELA
	tooltip, 
	if(SQUARE_IS_DRAWN == False && FASTER_SHOT_WAS_CALLED == False)
	{
TOOLTIP_DEBUG(2, "SQUARE_IS_DRAWN == False`n > Gdip_Startup() `n > Gdip_BitmapFromScreen() `n > Gdip_SaveBitmapToFile() `n > Gdip_DisposeImage() `n > TESTE: Gdip_Shutdown()", 1, 50)
		if(arrowGui_IS_DESTROYED) 
		{
			pToken_0 := Gdip_Startup()
			TooltipHelp("pToken_0 := Gdip_Startup()")
		}
		pBitmap_0 := Gdip_BitmapFromScreen()
		TooltipHelp("pBitmap_0 := Gdip_BitmapFromScreen()")
		if(NAME_MODE == "TITLE_SEQ")
		{
			Gdip_SaveBitmapToFile(pBitmap_0, "CAPTURES\" Texto "_" Sequencial ".png")
			LastSavedImagePath := "CAPTURES\" Texto "_" Sequencial ".png"
			TooltipHelp("Gdip_SaveBitmapToFile(pBitmap_0)")
		}
		else if(NAME_MODE == "TITLE_SEQ-SUBSEQ")
		{
			Gdip_SaveBitmapToFile(pBitmap_0, "CAPTURES\" Texto "_" Sequencial "-" Sub_Sequencial ".png")
			LastSavedImagePath :=  "CAPTURES\" Texto "_" Sequencial "-" Sub_Sequencial ".png"
			TooltipHelp("Gdip_SaveBitmapToFile(pBitmap_0)")
		}
		Gdip_DisposeImage(pBitmap_0) ; Releases resources used by the Image object.
		TooltipHelp("Gdip_DisposeImage(pBitmap_0)")
		if(arrowGui_IS_DESTROYED) 
		{
			Gdip_Shutdown(pToken_0) 
			TooltipHelp("Gdip_Shutdown(pToken_0)")
		}
	}
	else
	{
		if(FASTER_SHOT_WAS_CALLED)
		{
			if(SQUARE_IS_DRAWN)
			{
				REMOVE_DEFINED_AREA_2() ; necessario caso já tivesse um quadrado desenhado antes desse modo ser chamado.
			}
			DEFINE_AREA_TO_SAVE()
			if(!SQUARE_IS_DRAWN) ; AREA_IS_BAUNDED == "NOT CATCHED") ; pBitmap_0 == "NOT CATCHED"
			{
				tooltip, CANCELADO!
				SetTimer, RemoveToolTip, 2000
				return
			}
		}
		
TOOLTIP_DEBUG(2, "SQUARE_IS_DRAWN == True `n > Gdip_CloneBitmapArea() `n > Gdip_SaveBitmapToFile()", 1, 50)	

		if(arrowGui_IS_DESTROYED) 
		{
			pToken_0 := Gdip_Startup() 
			TooltipHelp("pToken_0 := Gdip_Startup()")
		}
		
		pBitmap_0 := Gdip_CloneBitmapArea(Gdip_BitmapFromScreen(), x_ScreenSelected, y_ScreenSelected, w_ScreenSelected, h_ScreenSelected)
		TooltipHelp("pBitmap_0 := Gdip_BitmapFromScreen()")
		TooltipHelp("Gdip_CloneBitmapArea(pBitmap_0)")
		if(NAME_MODE == "TITLE_SEQ")
		{
			Gdip_SaveBitmapToFile(pBitmap_0, "CAPTURES\" Texto "_" Sequencial ".png")
			LastSavedImagePath :=  "CAPTURES\" Texto "_" Sequencial ".png"
			TooltipHelp("Gdip_SaveBitmapToFile(pBitmap_0)")
		}
		else if(NAME_MODE == "TITLE_SEQ-SUBSEQ")
		{
			Gdip_SaveBitmapToFile(pBitmap_0, "CAPTURES\" Texto "_" Sequencial "-" Sub_Sequencial ".png")
			LastSavedImagePath :=  "CAPTURES\" Texto "_" Sequencial "-" Sub_Sequencial ".png"
			TooltipHelp("Gdip_SaveBitmapToFile(pBitmap_0)")
		}
		;~ Gdip_DisposeImage(pBitmap) ; Releases resources used by the Image object. TESTE <<< 1.4
		Gdip_DisposeImage(pBitmap_0) ; Releases resources used by the Image object. TESTE <<< 1.4 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
		TooltipHelp("Gdip_DisposeImage(pBitmap_0)")
		
		if(arrowGui_IS_DESTROYED) 
		{
			Gdip_Shutdown(pToken_0) 
			TooltipHelp("Gdip_Shutdown(pToken_0)")
		}
	}
	
	if(NAME_MODE == "TITLE_SEQ")
	{
		tooltip, IMAGEM SALVA: %Texto%_%Sequencial%, 1, 1
	}
	else if(NAME_MODE == "TITLE_SEQ-SUBSEQ")
	{
		tooltip, IMAGEM SALVA: %Texto%_%Sequencial%-%Sub_Sequencial%, 1, 1
	}
	
	SetTimer, RemoveToolTip, 2000
	
	Sequencial++
	Sequencial := SubStr("00000" . Sequencial,-4)
		
	if(NAME_MODE == "TITLE_SEQ-SUBSEQ")
	{
		Sub_Sequencial++
		Sub_Sequencial := SubStr("000" . Sub_Sequencial,-2)
	}
	
	if(FASTER_SHOT_WAS_CALLED) 
	{
		REMOVE_DEFINED_AREA_2()
	}
return

;~ ################################################################################# >>
;~ ALTERA TÍTULO E SEQUENCIAL DO PRÓXIMO ARQUIVO A SER SALVO
^F2::
	if (!MAINPATH_IS_ACESSIBLE())
	{
		msgbox, Erro ao criar o diretório: %A_WorkingDir%\CAPTURES
		return
	}
	if(SQUARE_IS_BEING_DRAWN)
	{
		;~ tooltip, PARA DESBLOQUEAR O MENU`, APERTE SHIFT OU SEGURE E SELECIONE UMA ÁREA.
		tooltip, SEGURE SHIFT E ARRASTE O CURSOR PARA SELECIONAR A ÁREA OU CLIQUE NO SHIFT PARA CANCELAR.
		SetTimer, RemoveToolTip, 10000
		return
	}
;~ CRIA E EXIBE GUI
	Gui,MenuFastPrints:Destroy
	GUI_INICIO:
		
		Gui,MenuFastPrints:Add, GroupBox, x2 y10 w380 h60 , Título da imagem
		Gui,MenuFastPrints:Add, Edit, x12 y40 w190 h20 limit50 vTexto1, %Texto%
		Gui,MenuFastPrints:Add, Edit, x202 y40 w90 h20 limit5 vTexto2, %Sequencial%
		Gui,MenuFastPrints:Add, Edit, x292 y40 w40 h20 limit5 vTexto3, %Sub_Sequencial%
		Gui,MenuFastPrints:Add, Button, Default x332 y40 w40 h20 vbtnOK_RENAME gbtn_OK_RENAME, OK ; <<<<<<<<<< 1.4
		Gui,MenuFastPrints:Add, GroupBox, x2 y80 w380 h195, DELIMITAR ÁREA DE CAPTURA
		Gui,MenuFastPrints:Add, Button, x12 y110 w175 h70 vbtnAREA_TO_SAVE gbtn_AREA_TO_SAVE, PARA SALVAR A IMAGEM
		Gui,MenuFastPrints:Add, Button, x197 y110 w175 h70 vbtnAREA_TO_COPY gbtn_AREA_TO_COPY, PARA COPIAR A IMAGEM
		Gui,MenuFastPrints:Add, Button, x12 y190 w360 h70 vbtnREMOVE_AREA gbtn_REMOVE_AREA, REMOVER ÁREA
		Gui,MenuFastPrints:Add, Button, x12 y290 w360 h35 vbtnSHOW_GALLERY gbtn_SHOW_GALLERY, GALERIA
		Gui,MenuFastPrints:Add, Checkbox, x12 y335 vchkSHOWING_WARNINGS, Mostrar Alertas
		Gui,MenuFastPrints:Add, Checkbox, x117 y335 vchkKEEPING_FRAME, Manter Moldura
		Gui,MenuFastPrints:Add, GroupBox, x2 y375 w380 h160, CONFIGURAR SETAS
		Gui,MenuFastPrints:Add, Text, x12 y405, Cor:
		Gui,MenuFastPrints:Add, Radio, x12 y425 voptSETAS_COLORIDAS, Aleatória
		Gui,MenuFastPrints:Add, Radio, x102 y425 voptSETAS_VERMELHAS, Vermelha
		Gui,MenuFastPrints:Add, Radio, x214 y425 voptSETAS_VERDES, Verde
		Gui,MenuFastPrints:Add, Radio, x319 y425 voptSETAS_AZUIS , Azul
		Gui,MenuFastPrints:Add, Radio, x12 y445 voptSETAS_ROXAS, Roxa
		Gui,MenuFastPrints:Add, Radio, x102 y445 voptSETAS_ROSA, Rosa
		Gui,MenuFastPrints:Add, Radio, x214 y445 voptSETAS_CINZA, Cinza
		Gui,MenuFastPrints:Add, Radio, x319 y445 voptSETAS_BEGE, Bege
		Gui,MenuFastPrints:Add, Text, x12 y480, Tamanho:
		Gui,MenuFastPrints:Add, Slider, x7 y495 vsldArrow_Size TickInterval7 Range1-7, 1
		Gui,MenuFastPrints:Add, Checkbox, x122 y498 vchkBold_Arrow, Mais Largura

		
		if(chkSHOWING_WARNINGS)
			Guicontrol,MenuFastPrints:,chkSHOWING_WARNINGS,1
		
		if(chkKEEPING_FRAME)
			Guicontrol,MenuFastPrints:,chkKEEPING_FRAME,1
		
		Guicontrol,MenuFastPrints:,optSETAS_COLORIDAS,%optSETAS_COLORIDAS%
		Guicontrol,MenuFastPrints:,optSETAS_VERMELHAS,%optSETAS_VERMELHAS%
		Guicontrol,MenuFastPrints:,optSETAS_VERDES,%optSETAS_VERDES%
		Guicontrol,MenuFastPrints:,optSETAS_AZUIS,%optSETAS_AZUIS%
		Guicontrol,MenuFastPrints:,optSETAS_ROXAS,%optSETAS_ROXAS%
		Guicontrol,MenuFastPrints:,optSETAS_ROSA,%optSETAS_ROSA%
		Guicontrol,MenuFastPrints:,optSETAS_CINZA,%optSETAS_CINZA%
		Guicontrol,MenuFastPrints:,optSETAS_BEGE,%optSETAS_BEGE%
		Guicontrol,MenuFastPrints:,optSETAS_ROXAS,%optSETAS_ROXAS%
		Guicontrol,MenuFastPrints:,sldArrow_Size,%sldArrow_Size%
		Guicontrol,MenuFastPrints:,chkBold_Arrow,%chkBold_Arrow%
		
		
		if(SQUARE_IS_DRAWN)
		{
			GuiControl,MenuFastPrints:disable, btnAREA_TO_SAVE
			GuiControl,MenuFastPrints:disable, btnAREA_TO_COPY
			GuiControl,MenuFastPrints:enable, btnREMOVE_AREA
			GuiControl,MenuFastPrints:disable, chkKEEPING_FRAME			
		}
		else
		{
			GuiControl,MenuFastPrints:enable, btnAREA_TO_SAVE
			GuiControl,MenuFastPrints:enable, btnAREA_TO_COPY
			GuiControl,MenuFastPrints:disable, btnREMOVE_AREA
			GuiControl,MenuFastPrints:enable, chkKEEPING_FRAME	
		}
		
		Gui,MenuFastPrints:Show, w386 h537, Menu - FastPrints
	return

	;~ ButtonOK:
	btn_OK_RENAME:
		
		GuiControlGet,Texto1,MenuFastPrints:
		GuiControlGet,Texto2,MenuFastPrints:
		GuiControlGet,Texto3,MenuFastPrints:
		GuiControlGet,chkSHOWING_WARNINGS,MenuFastPrints:
		GuiControlGet,chkKEEPING_FRAME,MenuFastPrints:
		
		GuiControlGet, optSETAS_COLORIDAS
		GuiControlGet, optSETAS_VERMELHAS
		GuiControlGet, optSETAS_VERDES
		GuiControlGet, optSETAS_AZUIS
		GuiControlGet, optSETAS_ROXAS ; 4283768268
		GuiControlGet, optSETAS_ROSA ; 4291298969
		GuiControlGet, optSETAS_CINZA ; 4289386162
		GuiControlGet, optSETAS_BEGE ; 4287264805
		GuiControlGet, sldArrow_Size ; 4287264805
		GuiControlGet, chkBold_Arrow
		
		;~ if Texto1 is Alpha
		if(isValidFileName(Texto1))
		{
			if Texto2 is digit 
			{
				if Texto3 is digit 
				{
					Texto2 := SubStr("00000" . Texto2,-4)
					if(chkSHOWING_WARNINGS)
					{
						IfNotExist, %A_WorkingDir%/CAPTURES/%Texto1%_%Texto2%.png
						{
							Texto := Texto1
							Sequencial := Texto2
							Sequencial := SubStr("00000" . Sequencial,-4)
							Sub_Sequencial := Texto3 ; "001"
							Sub_Sequencial := SubStr("000" . Sub_Sequencial,-2)
							Last_Sequencial := Sequencial
							Gui, MenuFastPrints: Destroy
						}
						else
						{
							msgbox, 4, Alerta, Já existe um arquivo com o nome: %Texto1%_%Texto2%.png.`nContinuar?
							IfMsgBox, Yes
							{
								Texto := Texto1
								Sequencial := Texto2
								Sequencial := SubStr("00000" . Sequencial,-4)
								Sub_Sequencial := Texto3 ; "001"
								Sub_Sequencial := SubStr("000" . Sub_Sequencial,-2)
								Last_Sequencial := Sequencial
								Gui, MenuFastPrints: Destroy
							}
						}
					}
					else
					{
						Texto := Texto1
						Sequencial := Texto2
						Sequencial := SubStr("00000" . Sequencial,-4)
						Sub_Sequencial := Texto3 ; "001"
						Sub_Sequencial := SubStr("000" . Sub_Sequencial,-2)
						Last_Sequencial := Sequencial
						Gui, MenuFastPrints: Destroy

					}
				}
				else
					msgbox, Erro: Apenas números são permitidos no terceiro campo!
			}
			else
				msgbox, Erro: Apenas números são permitidos no segundo campo!
		}
		else
		{
			msgbox, Erro: Apenas números são permitidos no primeiro campo!
		}
	return
	
	;~ ButtonAREA_TO_SAVE:
	btn_AREA_TO_SAVE:
		;~ gui, destroy
		Gui, MenuFastPrints: Destroy
		DEFINE_AREA_TO_SAVE()
	return
	
	;~ ButtonAREA_TO_COPY:
	btn_AREA_TO_COPY:
		Gui, MenuFastPrints: Destroy
		DEFINE_AREA_TO_COPY()
	return
	
	;~ ButtonREMOVE_AREA:
	btn_REMOVE_AREA:	
		Gui, MenuFastPrints: Destroy
		REMOVE_DEFINED_AREA_2()
	return
	
	;~ ButtonGALLERY:
	btn_SHOW_GALLERY:
		Gui,MenuFastPrints:Destroy
		run, %A_WorkingDir%/CAPTURES
	return
	
	GuiClose:
	GuiEscape:
	MenuFastPrintsGuiClose:
	MenuFastPrintsGuiEscape:
		Gui,MenuFastPrints:Destroy
	return
}
return
;~ ################################################################################# >>
;~ CAPTURA E SALVA TELA PARCIAL (SELECIONADA COM MOUSE) -> necessario #InstallMouseHook
;~ F11::
DEFINE_AREA_TO_SAVE()
{
	tooltip, 
	CATCH_SCREEN_SELECTED_FIELD("TO_PNG_FILE") ; SELECTION_MODE = "TO_PNG_FILE" / "TO_CLIPBOARD" ; retorno => pBitmap_0 / "NOT CATCHED" <<<<<<<<<<<<<<<<< teste
}
return

;~ ################################################################################# >>
DEFINE_AREA_TO_SAVE_2()
{
	tooltip, 
	CATCH_SCREEN_SELECTED_FIELD_2()
}
return

;~ ################################################################################# >>
;~ CAPTURA PARA O CLIPBOARD TELA PARCIAL (SELECIONADA COM MOUSE) -> necessario #InstallMouseHook
;~ F12::
DEFINE_AREA_TO_COPY()
{
	tooltip, 
	CATCH_SCREEN_SELECTED_FIELD("TO_CLIPBOARD") 
}
return

;~ ################################################################################# >>
REMOVE_DEFINED_AREA()
{
TOOLTIP_DEBUG(3, "SQUARE_IS_DRAWN == True `n > Gdip_DeletePen() `n > Gdip_DeleteGraphics() `n > SelectObject() `n > DeleteObject() `n > DeleteDC() `n > Gdip_Shutdown()", 150, 50)	
	Gui, dragOverlay: Destroy
	TooltipHelp("Gui, dragOverlay: Destroy")
	Gdip_GraphicsClear(G_0) 
	TooltipHelp("Gdip_GraphicsClear(G_0)")
	UpdateLayeredWindow(hwnd_0, hdc_0)
	TooltipHelp("UpdateLayeredWindow(hwnd_0, hdc_0)")
	Gdip_DeletePen(pPen_0)
	TooltipHelp("Gdip_DeletePen(pPen_0)")
	Gdip_DeleteGraphics(G_0)
	TooltipHelp("Gdip_DeleteGraphics(G_0)")
	hbm_0 := SelectObject(hdc_0, obm_0)
	TooltipHelp("hbm_0 := SelectObject(hdc_0, obm_0)")
	DeleteObject(hbm_0)  
	TooltipHelp("DeleteObject(hbm_0)")
	DeleteDC(hdc_0) 
	TooltipHelp("DeleteDC(hdc_0)")
	Gdip_DisposeImage(pBitmap_0)
	TooltipHelp("Gdip_DisposeImage(pBitmap_0)")
	if(arrowGui_IS_DESTROYED)
	{
		Gdip_Shutdown(pToken_0)	
		TooltipHelp("Gdip_Shutdown(pToken_0)")
	}
	SQUARE_IS_DRAWN := False
	SQUARE_IS_BEING_DRAWN := False
}
return

;~ ################################################################################# >>
REMOVE_DEFINED_AREA_2()
{
	
	Gui, dragOverlay: Destroy 
	TooltipHelp("Gui, dragOverlay: Destroy")
	
	SQUARE_IS_DRAWN := False
	SQUARE_IS_BEING_DRAWN := False
}
return


;~ ################################################################################# >>
;~ CAPTURA PORÇÃO DA TELA SELECIONADA COM MOUSE (PEQUENO PRINTSCREEN) -> necessario #InstallMouseHook
;~ com apenas um clique, sem arrastar, a ação é cancelada e o clipboard continua intacto. 
CATCH_SCREEN_SELECTED_FIELD(SELECTION_MODE)
{
	if(SQUARE_IS_BEING_DRAWN) ; bloqueia multiplas chamadas por NumpadAdd ou NumpadSub
	{		
		return "NOT CATCHED"
	}
	
	SQUARE_IS_BEING_DRAWN := True ; Flag para informar que foi feita uma chamada por NumpadAdd ou NumpadSub, bloqueando novas chamadas
	
TOOLTIP_DEBUG(4, "SQUARE_IS_BEING_DRAWN == True `n > Gdip_Startup() `n > CreateDIBSection() `n > CreateCompatibleDC() `n > SelectObject() `n > Gdip_GraphicsFromHDC() `n > Gdip_TextToGraphics() `n > UpdateLayeredWindow", 300, 50)	
	if(arrowGui_IS_DESTROYED) ; rammstein2
	{
		pToken_0 := Gdip_Startup()
		TooltipHelp("pToken_0 := Gdip_Startup()")
	}
	Gui, dragOverlay: -Caption Hwndhwnd_0 +E0x20 +E0x80000 +LastFound  +ToolWindow +AlwaysOnTop +OwnDialogs +Owner ;  +OwnDialogs +Owner
	Gui, dragOverlay: Show, NA X0 Y0 W%A_ScreenWidth% H%A_ScreenHeight%, dragOverlay
	TooltipHelp("Gui, dragOverlay: Show")
	
	hbm_0 := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)
	TooltipHelp("hbm_0 := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)")
	hdc_0 := CreateCompatibleDC()
	TooltipHelp("hdc_0 := CreateCompatibleDC()")
	obm_0 := SelectObject(hdc_0, hbm_0)
	TooltipHelp("obm_0 := SelectObject(hdc_0, hbm_0)")
	G_0 := Gdip_GraphicsFromHDC(hdc_0)
	TooltipHelp("G_0 := Gdip_GraphicsFromHDC(hdc_0)")
	
	
	if(SELECTION_MODE == "TO_PNG_FILE")
	{
		Gdip_TextToGraphics(G_0, "SEGURE SHIFT, ARRASTE O CURSOR E DELIMITE SUA ÁREA DE CAPTURA!", "x0, y0 0xcFFFF0000 s25 Bold")
		TooltipHelp("Gdip_TextToGraphics(G_0)")
	}
	else
	{
		Gdip_TextToGraphics(G_0, "SEGURE SHIFT, ARRASTE O CURSOR E DELIMITE SUA ÁREA DE CAPTURA PARA O CLIPBOARD!", "x0, y0 0xcFFFF0000 s25 Bold")
		TooltipHelp("Gdip_TextToGraphics(G_0)")
	}
	UpdateLayeredWindow(hwnd_0, hdc_0)
	TooltipHelp("UpdateLayeredWindow(hwnd_0, hdc_0)")
	CoordMode, Mouse, Screen
	keywait, LShift, D 
	send {LShift up}
	MouseGetPos, sX, sY
	
TOOLTIP_DEBUG(5, "SQUARE_IS_BEING_DRAWN == True `n > Gdip_CreatePen() `n > Gdip_DrawRectangle() `n > UpdateLayeredWindow() `n > DLL: GdipGraphicsClear `n > Gdip_CloneBitmapArea(Gdip_BitmapFromScreen()) `n > Gdip_TextToGraphics() `n > UpdateLayeredWindow", 450, 50)
	pPen_0 := Gdip_CreatePen(0xcFFFF0000, 1)
	TooltipHelp("pPen_0 := Gdip_CreatePen()")
	while GetKeyState("LShift", "P") 
	{
		MouseGetPos, X, Y
		w := abs(X - sX)
		h := abs(y - sY)
		if (x > sX)
			x := sX
		if (y > sY)
			y := sy
		Gdip_DrawRectangle(G_0, pPen_0, x, y, w, h)
		UpdateLayeredWindow(hwnd_0, hdc_0)
		TooltipHelp("UpdateLayeredWindow(hwnd_0, hdc_0)")
		Gdip_GraphicsClear(G_0)
		TooltipHelp("Gdip_GraphicsClear(G_0)")
		sleep 50
	}
	
	If(chkKEEPING_FRAME)
	{
		x_ScreenSelected := x ;1.4.2
		y_ScreenSelected := y ;1.4.2
		w_ScreenSelected := w+1 ;1.4.2
		h_ScreenSelected := h+1 ;1.4.2
	}
	else
	{
		x_ScreenSelected := x+1 ;1.4.2
		y_ScreenSelected := y+1 ;1.4.2
		w_ScreenSelected := w-1 ;1.4.2
		h_ScreenSelected := h-1 ;1.4.2
	}
	
	pBitmap_0 := Gdip_CloneBitmapArea(Gdip_BitmapFromScreen(), x_ScreenSelected, y_ScreenSelected, w_ScreenSelected, h_ScreenSelected) 
	
	if(SELECTION_MODE == "TO_CLIPBOARD")
	{
		if(w != 0 && h != 0)
		{
			Gdip_SetBitmapToClipboard(pBitmap_0)
			;~ SQUARE_IS_DRAWN := True
			tooltip, IMAGEM COPIADA! Use Ctrl+V para colá-la onde desejar.
			SetTimer, RemoveToolTip, 2000
		}
		else
		{
			tooltip, CANCELADO!
			SetTimer, RemoveToolTip, 2000
		}
		
		; destroi o quadrado e o objeto criado, liberando memória
		Gui, dragOverlay: Destroy
		TooltipHelp("Gui, dragOverlay: Destroy")
		Gdip_DeletePen(pPen_0)
		TooltipHelp("Gdip_DeletePen(pPen_0)")
		Gdip_DeleteGraphics(G_0)	
		TooltipHelp("Gdip_DeleteGraphics(G_0)")
		hbm_0 := SelectObject(hdc_0, obm_0) ; <<< 1.4
		TooltipHelp("hbm_0 := SelectObject(hdc_0, obm_0)")
		DeleteObject(hbm_0)  
		TooltipHelp("DeleteObject(hbm_0)")
		DeleteDC(hdc_0) 
		TooltipHelp("DeleteDC(hdc_0)")
		Gdip_DisposeImage(pBitmap_0) ; <<< 1.4
		TooltipHelp("Gdip_DisposeImage(pBitmap_0)")
		if(arrowGui_IS_DESTROYED) ; rammstein2
		{
			Gdip_Shutdown(pToken_0)
			TooltipHelp("Gdip_Shutdown(pToken_0)")
		}
		SQUARE_IS_DRAWN := False
	}
	else if(SELECTION_MODE == "TO_PNG_FILE")
	{
		if(w != 0 && h != 0)
		{
			SQUARE_IS_DRAWN := True
			SQUARE_IS_BEING_DRAWN := False 
				tooltip, ÁREA DELIMITADA!
				SetTimer, RemoveToolTip, 2000
				
			Gdip_DeletePen(pPen_0)
			TooltipHelp("Gdip_DeletePen(pPen_0)")
			Gdip_DeleteGraphics(G_0)	
			TooltipHelp("Gdip_DeleteGraphics(G_0)")
			hbm_0 := SelectObject(hdc_0, obm_0)
			TooltipHelp("hbm_0 := SelectObject(hdc_0, obm_0)")
			DeleteObject(hbm_0)  
			TooltipHelp("DeleteObject(hbm_0)")
			DeleteDC(hdc_0) 
			TooltipHelp("DeleteDC(hdc_0)")
			Gdip_DisposeImage(pBitmap_0) ; <<< 1.4
			TooltipHelp("Gdip_DisposeImage(pBitmap_0)")
			if(arrowGui_IS_DESTROYED) 
			{
				Gdip_Shutdown(pToken_0)
				TooltipHelp("Gdip_Shutdown(pToken_0)")
			}
			
			return "CATCHED" ; pBitmap_0 ; "CATCHED" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
		}
		else
		{
TOOLTIP_DEBUG(6, "SQUARE_IS_BEING_DRAWN == True `n > Gdip_DeletePen() `n > Gdip_DeleteGraphics() `n > SelectObject() `n > DeleteObject() `n > DeleteDC() `n > Gdip_Shutdown()", 600, 50)
			Gdip_DeletePen(pPen_0)
			TooltipHelp("Gdip_DeletePen(pPen_0)")
			Gdip_DeleteGraphics(G_0)	
			TooltipHelp("Gdip_DeleteGraphics(G_0)")
			hbm_0 := SelectObject(hdc_0, obm_0)
			TooltipHelp("hbm_0 := SelectObject(hdc_0, obm_0)")
			DeleteObject(hbm_0)  
			TooltipHelp("DeleteObject(hbm_0)")
			DeleteDC(hdc_0) 
			TooltipHelp("DeleteDC(hdc_0)")
			Gdip_DisposeImage(pBitmap_0) ; <<< 1.4
			TooltipHelp("Gdip_DisposeImage(pBitmap_0)")
			if(arrowGui_IS_DESTROYED)
			{
				Gdip_Shutdown(pToken_0)
				TooltipHelp("Gdip_Shutdown(pToken_0)")
			}
			SQUARE_IS_DRAWN := False
				tooltip, CANCELADO!
				SetTimer, RemoveToolTip, 2000
		}
	}
	SQUARE_IS_BEING_DRAWN := False 
	return "NOT CATCHED"
}






CATCH_SCREEN_SELECTED_FIELD_2() ; RControl
{
	if(SQUARE_IS_BEING_DRAWN) ; bloqueia multiplas chamadas por NumpadAdd ou NumpadSub
	{		
		return "NOT CATCHED"
	}
	
	SQUARE_IS_BEING_DRAWN := True ; Flag para informar que foi feita uma chamada por NumpadAdd ou NumpadSub, bloqueando novas chamadas
	
TOOLTIP_DEBUG(4, "SQUARE_IS_BEING_DRAWN == True `n > Gdip_Startup() `n > CreateDIBSection() `n > CreateCompatibleDC() `n > SelectObject() `n > Gdip_GraphicsFromHDC() `n > Gdip_TextToGraphics() `n > UpdateLayeredWindow", 300, 50)	
	
	if(arrowGui_IS_DESTROYED) 
	{
		pToken_0 := Gdip_Startup()
		TooltipHelp("pToken_0 := Gdip_Startup()")
	}
	Gui, dragOverlay: -Caption Hwndhwnd_0 +E0x20 +E0x80000 +LastFound  +ToolWindow +AlwaysOnTop +OwnDialogs +Owner ;  +OwnDialogs +Owner
	Gui, dragOverlay: Show, NA X0 Y0 W%A_ScreenWidth% H%A_ScreenHeight%, dragOverlay
	TooltipHelp("Gui, dragOverlay: Show")
	
	hbm_0 := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)
	TooltipHelp("hbm_0 := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)")
	hdc_0 := CreateCompatibleDC()
	TooltipHelp("hdc_0 := CreateCompatibleDC()")
	obm_0 := SelectObject(hdc_0, hbm_0)
	TooltipHelp("obm_0 := SelectObject(hdc_0, hbm_0)")
	G_0 := Gdip_GraphicsFromHDC(hdc_0)
	TooltipHelp("G_0 := Gdip_GraphicsFromHDC(hdc_0)")
	
	
	CoordMode, Mouse, Screen
	send {RControl up}
	MouseGetPos, sX, sY
	
TOOLTIP_DEBUG(5, "SQUARE_IS_BEING_DRAWN == True `n > Gdip_CreatePen() `n > Gdip_DrawRectangle() `n > UpdateLayeredWindow() `n > DLL: GdipGraphicsClear `n > Gdip_CloneBitmapArea(Gdip_BitmapFromScreen()) `n > Gdip_TextToGraphics() `n > UpdateLayeredWindow", 450, 50)
	pPen_0 := Gdip_CreatePen(0xcFFFF0000, 1)
	TooltipHelp("pPen_0 := Gdip_CreatePen()")
	while GetKeyState("RControl", "P") 
	{
		MouseGetPos, X, Y
		w := abs(X - sX)
		h := abs(y - sY)
		if (x > sX)
			x := sX
		if (y > sY)
			y := sy
		
		Gdip_DrawRectangle(G_0, pPen_0, x, y, w, h)
		UpdateLayeredWindow(hwnd_0, hdc_0)
		TooltipHelp("UpdateLayeredWindow(hwnd_0, hdc_0)")
		
		Gdip_GraphicsClear(G_0)
		TooltipHelp("Gdip_GraphicsClear(G_0)")
		sleep 50
	}
	
	If(chkKEEPING_FRAME)
	{
		x_ScreenSelected := x ;1.4.2
		y_ScreenSelected := y ;1.4.2
		w_ScreenSelected := w+1 ;1.4.2
		h_ScreenSelected := h+1 ;1.4.2
	}
	else
	{
		x_ScreenSelected := x+1 ;1.4.2
		y_ScreenSelected := y+1 ;1.4.2
		w_ScreenSelected := w-1 ;1.4.2
		h_ScreenSelected := h-1 ;1.4.2
	}
	
	if(w != 0 && h != 0)
	{
		SQUARE_IS_DRAWN := True
		SQUARE_IS_BEING_DRAWN := False ; libera nova chamada por NumpadAdd ou NumpadSub
			tooltip, ÁREA DELIMITADA!
			SetTimer, RemoveToolTip, 2000
			
		Gdip_DeletePen(pPen_0)
		TooltipHelp("Gdip_DeletePen(pPen_0)")
		Gdip_DeleteGraphics(G_0)	
		TooltipHelp("Gdip_DeleteGraphics(G_0)")
		hbm_0 := SelectObject(hdc_0, obm_0)
		TooltipHelp("hbm_0 := SelectObject(hdc_0, obm_0)")
		DeleteObject(hbm_0)  
		TooltipHelp("DeleteObject(hbm_0)")
		DeleteDC(hdc_0) 
		TooltipHelp("DeleteDC(hdc_0)")
		Gdip_DisposeImage(pBitmap_0) ; <<< 1.4
		TooltipHelp("Gdip_DisposeImage(pBitmap_0)")
		if(arrowGui_IS_DESTROYED) ; rammstein2
		{
			Gdip_Shutdown(pToken_0)
			TooltipHelp("Gdip_Shutdown(pToken_0)")
		}
		
		
		return "CATCHED"
	}
	else
	{
TOOLTIP_DEBUG(6, "SQUARE_IS_BEING_DRAWN == True `n > Gdip_DeletePen() `n > Gdip_DeleteGraphics() `n > SelectObject() `n > DeleteObject() `n > DeleteDC() `n > Gdip_Shutdown()", 600, 50)
		; destroi o quadrado e o objeto criado, liberando memória
		Gui, dragOverlay: Destroy
		TooltipHelp("Gui, dragOverlay: Destroy")
		Gdip_DeletePen(pPen_0)
		TooltipHelp("Gdip_DeletePen(pPen_0)")
		Gdip_DeleteGraphics(G_0)	
		TooltipHelp("Gdip_DeleteGraphics(G_0)")
		hbm_0 := SelectObject(hdc_0, obm_0)
		TooltipHelp("hbm_0 := SelectObject(hdc_0, obm_0)")
		DeleteObject(hbm_0)  
		TooltipHelp("DeleteObject(hbm_0)")
		DeleteDC(hdc_0) 
		TooltipHelp("DeleteDC(hdc_0)")
		
		if(arrowGui_IS_DESTROYED) ; rammstein2
		{
			Gdip_Shutdown(pToken_0)
			TooltipHelp("Gdip_Shutdown(pToken_0)")
		}
		SQUARE_IS_DRAWN := False
			tooltip, CANCELADO!
			SetTimer, RemoveToolTip, 2000
	}
	SQUARE_IS_BEING_DRAWN := False ; libera nova chamada por NumpadAdd ou NumpadSub
	return "NOT CATCHED"
}

;~ ################################################################################# >>
MAINPATH_IS_ACESSIBLE()
{
	IfNotExist, %A_WorkingDir%\CAPTURES
	{
		filecreatedir, %A_WorkingDir%\CAPTURES
	}
	IfNotExist, %A_WorkingDir%\CAPTURES
	{
		;~ Erro ao criar a pasta: %A_WorkingDir%\CAPTURES
		return False
	}
	return True
}
 ;~ ################################################################################# >>
TRAY_SETUP()
{
	;~ if A_IsCompiled
	{
		applicationname=FastPrints 1.7

		Gosub,TRAY_MENU
		Return

		TRAY_MENU:
		Menu,Tray,NoStandard
		Menu,Tray,DeleteAll
		Menu,Tray,Add,%applicationname%,TRAY_COPYRIGHT

		Menu,Tray,Add
		Menu,Tray,Add,&About,TRAY_ABOUT
		Menu,Tray,Add,E&xit,TRAY_EXIT
		Menu,Tray,Default,%applicationname%
		Menu,Tray,Tip,%applicationname%
		Return

		TRAY_COPYRIGHT:	
		gui,copyright:Add, Text,, Copyright: Rafael Carneiro Nascimento | RAFACN
		gui,copyright:show
		return

		TRAY_ABOUT:
		Gui,about:Destroy
		Gui,about:Margin,20,20
		If(USING_PROTECTION)
			Gui,about:Add,Text,x+10 yp+10,FastPrints (TRIAL: %Trial_DaysLeft% DIAS)
		else
			Gui,about:Add,Text,x+10 yp+10,FastPrints (FULL LICENSE)
		Gui,about:Add,Text,xp+10 yp+30,Ferramenta de rápida e organizada captura de tela.
		Gui,about:Add,Text,xp yp+40,`n`nComandos Básicos: `n`n`tControl + F2`t`t`t -> `tAbrir Menu`n`n`tControl + F1`t`t`t -> `tPrintar e Salvar`n`n`tRControl (Segurar e Arrastar)`t -> `tDelimitar Área`n`n`tRControl (Clicar)`t`t`t -> `tRemover Delimitação de Área`n`n`tAppskey (Segurar e Arrastar)`t -> `tDesenhar Seta`n`n`tAppskey (Clicar)`t`t`t -> `tRemover Seta`n`n`nComandos Avançados: `n`n`tControl + F3`t`t -> `tPrintar e Salvar - SEQUENCIAMENTO ALTERNATIVO`n`n`tControl + F5`t`t -> `tDelimitar Área e Salvar`n`n`tControl + F12`t`t -> `tDesfazer Última Captura`n`n`nComandos do Sistema: `n`n`tControl + Insert`t`t -> `tReiniciar Ferramenta`n`n`tControl + Escape`t -> `tFechar Ferramenta
		Gui,about:Add,Text,xp yp+410,`n`nVersão: 1.7`nCopyright: Rafael Carneiro Nascimento

		Gui,about:Show,,About
		Return
		
		TRAY_EXIT:
		gosub, TRAY_COPYRIGHT
		ExitApp
	}
}
return
 ;~ ################################################################################# >>
INSTRUCTIONS()
{	
	Gui,about:Destroy
	Gui,about:Margin,20,20
	If(USING_PROTECTION)
		Gui,about:Add,Text,x+10 yp+10,FastPrints (TRIAL: %Trial_DaysLeft% DIAS)
	else
		Gui,about:Add,Text,x+10 yp+10,FastPrints (FULL LICENSE)
	Gui,about:Add,Text,xp+10 yp+30,Ferramenta de rápida e organizada captura de tela.
	Gui,about:Add,Text,xp yp+40,`n`nComandos Básicos: `n`n`tControl + F2`t`t`t -> `tAbrir Menu`n`n`tControl + F1`t`t`t -> `tPrintar e Salvar`n`n`tRControl (Segurar e Arrastar)`t -> `tDelimitar Área`n`n`tRControl (Clicar)`t`t`t -> `tRemover Delimitação de Área`n`n`tAppskey (Segurar e Arrastar)`t -> `tDesenhar Seta`n`n`tAppskey (Clicar)`t`t`t -> `tRemover Seta`n`n`nComandos Avançados: `n`n`tControl + F3`t`t -> `tPrintar e Salvar - SEQUENCIAMENTO ALTERNATIVO`n`n`tControl + F5`t`t -> `tDelimitar Área e Salvar`n`n`tControl + F12`t`t -> `tDesfazer Última Captura`n`n`nComandos do Sistema: `n`n`tControl + Insert`t`t -> `tReiniciar Ferramenta`n`n`tControl + Escape`t -> `tFechar Ferramenta
	Gui,about:Add,Text,xp yp+410,`n`nVersão: 1.7`nCopyright: Rafael Carneiro Nascimento

	Gui,about:Show,,About
}
return
 ;~ ################################################################################# >>
 TOOLTIP_DEBUG(Tooltip_ID, Tooltip_Text, Tooltip_Position_X, Tooltip_Position_Y)
 {
	if(USING_TOOLTIP_DEBUG)
		tooltip, %Tooltip_Text%, %Tooltip_Position_X%, %Tooltip_Position_Y%, %Tooltip_ID%
}
return
 ;~ ################################################################################# >>
 isValidFileName(_fileName, _isLong=true)
{
    static shortForbiddenChars := ";,=,+,<,>,|,"",[,],\,/,'"
    static longForbiddenChars := "<,>,|,"",\,/,:,*,?"
    
    forbiddenChars := _isLong ? longForbiddenChars : shortForbiddenChars
    Loop, Parse, forbiddenChars, `,
    {
        pos := InStr(_fileName, A_LoopField, true)
        if (pos > 0)
        {
            break
        }
    }
    ErrorLevel := pos
    
    return (pos ? false : true)
}



CREATE_arrowGui()
{
	Gui, arrowGui: -Caption Hwndhwnd_1 +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop 
	Gui, arrowGui: Show, NA
	TooltipHelp("Gui, arrowGui: Show")
	If !pToken_1 := Gdip_Startup()
	{
		MsgBox, 48, Erro com o gdiplus!, Gdiplus Falhou em iniciar. Assegure-se que seu sistema possui o gdiplus.
		ExitApp
	}
	TooltipHelp("pToken_1 := Gdip_Startup()")
	hbm_1 := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)
	TooltipHelp("hbm_1 := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)")
	hdc_1 := CreateCompatibleDC()
	TooltipHelp("hdc_1 := CreateCompatibleDC()")
	obm_1 := SelectObject(hdc_1, hbm_1)
	TooltipHelp("obm_1 := SelectObject(hdc_1, hbm_1)")
	G_1 := Gdip_GraphicsFromHDC(hdc_1)
	TooltipHelp("G_1 := Gdip_GraphicsFromHDC(hdc_1)")
	Gdip_SetSmoothingMode(G_1, 4) 
	arrowGui_IS_DESTROYED := False
}
return

;~ ################################################################################# >>
; UTILIZADA PARA NA HOTKEY APPSKEY!!!!
REMOVE_arrowGui()
{
	
	Gdip_DeleteGraphics(G_1)	
	TooltipHelp("Gdip_DeleteGraphics(G_1)")
	hbm_1 := SelectObject(hdc_1, obm_1)
	TooltipHelp("hbm_1 := SelectObject(hdc_1, obm_1)")
	DeleteObject(hbm_1)
	TooltipHelp("DeleteObject(hbm_1)")	
	DeleteDC(hdc_1) 
	TooltipHelp("DeleteDC(hdc_1)")
	
	Gdip_Shutdown(pToken_1)
	TooltipHelp("Gdip_Shutdown(pToken_1)")
	arrowGui_IS_DESTROYED := True
}
return

CLEAN_arrowGui() ; rammstein3
{
	Gui, arrowGui: destroy	
	TooltipHelp("Gui, arrowGui: Destroy")
}
return

 ;~ ################################################################################# >>
;~ LControl & RAlt:: ; AltGr
AppsKey::
Gui,MenuFastPrints: Destroy
Pressed_Time := A_TickCount
if(arrowGui_IS_DESTROYED)
{
	CREATE_arrowGui()
}
Loop, 4
{
	Sleep, 50
	if !(GetKeyState("AppsKey", "P"))
	{
		Gdip_GraphicsClear(G_1)
		TooltipHelp("Gdip_GraphicsClear(G_1)")
		Delete_One(List)
		Draw_Arrows(List)
		List_Buffer := List
		UpdateLayeredWindow(hwnd_1, hdc_1, 0, 0, Width, Height)
		TooltipHelp("UpdateLayeredWindow(hwnd_1, hdc_1, 0, 0, Width, Height)")
		if(!List_Count) ; << 1.03
		{
			REMOVE_arrowGui()  
			CLEAN_arrowGui() ; rammstein3 ; just destroy the Gui, because the graphics are already destroyed
			tooltip, Todas as setas foram devidamente removidas!, 1,1
			SetTimer, RemoveToolTip, 2000
		}
		return
	}
}

Add_One(List, 0,0,0,0) ;Dummy item to be deleted
MouseGetPos, StartX, StartY
While (GetKeyState("AppsKey", "P"))
{
	MouseGetPos, MX, MY
	Gdip_GraphicsClear(G_1)
	TooltipHelp("Gdip_GraphicsClear(G_1)")
	Delete_One(List)
	Add_One(List, StartX, StartY, MX, MY)
	Draw_Arrows(List)
	List_Buffer := List
	UpdateLayeredWindow(hwnd_1, hdc_1, 0, 0, Width, Height)
	TooltipHelp("UpdateLayeredWindow(hwnd_1, hdc_1, 0, 0, Width, Height)")
}
REMOVE_arrowGui() ; do not destroy the Gui
return

 ;~ ################################################################################# >>
Delete_One(ByRef List)
{
	global List_Count
	If !List
		return
	Loop, Parse, List, `n
		If (A_Index < List_Count)
			New_List .= A_LoopField . "`n"
	List := New_List
	List_Count -= 1
	return
}

 ;~ ################################################################################# >>
Add_One(ByRef List, x1, y1, x2, y2)
{
	global List_Count
	if(LAST_MX != x2 || LAST_MY != y2)
	{
		Color := Get_Color()
		LAST_COLOR := Color
		LAST_MX := x2
		LAST_MY := y2
	}
	else
	{
		Color := LAST_COLOR
	}
	New = %x1%|%y1%|%x2%|%y2%|%Color%`n
	List .= New
	List_Count += 1
	return
}

 ;~ ################################################################################# >>
Draw_Arrows(List) 
{ 
   global G_1, Window_D 
   
	tip_length := 10*sldArrow_Size
	chkBold_Arrow ? Arrow_Width_Increment := 1 : Arrow_Width_Increment := 0

   ; define an arrow tip pointing right, front at 0/0 in polar 
   tip1_length := tip_length
   tip1_angle := 150 ; degrees 
   tip2_length := tip_length
   tip2_angle := 210 ; degrees 
   tip1_angle *= 0.01745329252 
   tip2_angle *= 0.01745329252 
   Loop, Parse, List, `n 
   { 
      StringSplit, Coord, A_Loopfield, | 
      pPen_1 := Gdip_CreatePen(Coord5, sldArrow_Size + Arrow_Width_Increment) 
	  TooltipHelp("pPen_1 := Gdip_CreatePen()")
      ; move line to the base of the coord-system to ... 
      P2_X := Coord3 - Coord1 
      P2_Y := Coord4 - Coord2 
      ; get "direction the line is pointing to" 
      P2_r := Kart2Polar_r( P2_X, P2_Y) 
      P2_Phi := Kart2Polar_Phi( P2_X, P2_Y, P2_r) 
      ; rotate the arrow to the lines direction 
      curr_tip1_angle := tip1_angle + P2_Phi 
      curr_tip2_angle := tip2_angle + P2_Phi 
      ; transform arrow coord to cartesian    
      X1 := Round(Polar2Kart_X(tip1_length, curr_tip1_angle)) 
      X2 := Round(Polar2Kart_X(tip2_length, curr_tip2_angle)) 
      Y1 := Round(Polar2Kart_Y(tip1_length, curr_tip1_angle)) 
      Y2 := Round(Polar2Kart_Y(tip2_length, curr_tip2_angle)) 
      ; move arrow to the end of the line 
      X1 += Coord3 
      X2 += Coord3 
      Y1 += Coord4 
      Y2 += Coord4 
	  
      Points = %Coord1%,%Coord2%|%Coord3%,%Coord4% 
      PointArrow1 = %Coord3%,%Coord4%|%X1%,%Y1% 
      PointArrow2 = %Coord3%,%Coord4%|%X2%,%Y2% 
      ;~ TrayTip, Points, %PointArrow1%`n%PointArrow2% 
      Gdip_DrawLines(G_1, pPen_1, Points) 
      Gdip_DrawLines(G_1, pPen_1, PointArrow1) 
      Gdip_DrawLines(G_1, pPen_1, PointArrow2) 
	  TooltipHelp("Gdip_DrawLines(G_1, pPen_1)")
      Gdip_DeletePen(pPen_1) 
	  TooltipHelp("Gdip_DeletePen(pPen_1)")
   } 
   return 
}

 ;~ ################################################################################# >>
Get_Color()
{
	
	if (optSETAS_COLORIDAS)
	{
		Random, Red, 0, 225
		Random, Green, 0, 225
		Random, Blue, 0, 225
	}
	else
	{
		Red := 255*optSETAS_VERMELHAS
		Green := 255*optSETAS_VERDES
		Blue := 255*optSETAS_AZUIS
	}
	Color := 0xFF000000
	Color += (Red << 16)
	Color += (Green << 8)
	Color += (Blue << 0)
	
	Color += optSETAS_ROXAS*4283768268
	Color += optSETAS_ROSA*4291298969
	Color += optSETAS_CINZA*4289386162
	Color += optSETAS_BEGE*4287264805
	
	return (Color)
}

 ;~ ################################################################################# >>
;Thanks to Zed Gecko for these four funtions
Polar2Kart_X(r, Phi)
{
   x := r * Cos(Phi)
   return x
}

 ;~ ################################################################################# >>
Polar2Kart_Y(r, Phi)
{
   y := r * Sin(Phi)
   return y
}

 ;~ ################################################################################# >>
Kart2Polar_r( x, y)
{
   r := Sqrt( (x*x) + (y*y) )
   return r
}

 ;~ ################################################################################# >>
Kart2Polar_Phi(x, y, r)
{
   if (y < 0)
      Phi := -1 * ACos(x/r)
   else
      Phi := ACos(x/r)
   return Phi
}

 ;~ ################################################################################# >>
;Currently this is not used
Distance(x1, y1, x2, y2)
{
	N := (x2-x1)**2 + (y2-y1)**2
	return ( sqrt(N) )
}




 ;~ ################################################################################# >>
; http://www.autohotkey.com/forum/viewtopic.php?p=223061#223061
GetProcessMemoryInfo( pname )
{
  Process, Exist, %pname%
  pid := Errorlevel

  ; get process handle
  hProcess := DllCall( "OpenProcess", UInt, 0x10|0x400, Int, false, UInt, pid )

  ; get memory info
  VarSetCapacity( memCounters, 40, 0 )
  DllCall( "psapi.dll\GetProcessMemoryInfo", UInt, hProcess, UInt, &memCounters, UInt, 40 )
  DllCall( "CloseHandle", UInt, hProcess )

  list_x = cb,PageFaultCount,PeakWorkingSetSize,WorkingSetSize,QuotaPeakPagedPoolUsage 
  ,QuotaPagedPoolUsage,QuotaPeakNonPagedPoolUsage,QuotaNonPagedPoolUsage 
  ,PagefileUsage,PeakPagefileUsage

  n=0 
  Loop, Parse, list_x, `,
  {
    n+=4
    SetFormat, Float, 0.0 ; round up K
    this := A_Loopfield
    this := NumGet( memCounters, (A_Index = 1 ? 0 : n-4), "UInt") / 1024

    ; omit cb
    If A_Index != 1
      info .= A_Loopfield . ": " . this . " K" . ( A_Loopfield != "" ? "`n" : "" )
  }

  Return PagefileUsage := NumGet( memCounters, 32, "UInt" ) / 1024 ; what Task Manager shows
}



TooltipHelp(TheCall)
{
	if (TheCall == "Gdip_GraphicsClear(G_0)") 
	{
		GraphicsClear_G_0 := True
		Count_GraphicsClear_G_0++
	}
	else if (TheCall == "Gdip_DeletePen(pPen_0)")
	{
		DeletePen_pPen_0 := True
		Count_DeletePen_pPen_0++
	}
	else if (TheCall == "Gdip_DeleteGraphics(G_0)")
	{
		DeleteGraphics_G_0 := True
		Count_DeleteGraphics_G_0++
	}
	else if (TheCall == "hbm_0 := SelectObject(hdc_0, obm_0)")
	{
		SelectObject_obm_0 := True
		Count_SelectObject_obm_0++
	}
	else if (TheCall == "DeleteObject(hbm_0)")
	{
		DeleteObject_hbm_0 := True
		Count_DeleteObject_hbm_0++
	}
	else if (TheCall == "DeleteDC(hdc_0)")
	{
		DeleteDC_hdc_0 := True
		Count_DeleteDC_hdc_0++
	}
	else if (TheCall == "Gdip_DisposeImage(pBitmap_0)")
	{
		DisposeImage_pBitmap_0 := True
		Count_DisposeImage_pBitmap_0++
	}
	else if (TheCall == "Gdip_Shutdown(pToken_0)")
	{
		Shutdown_pToken_0 := True
		Count_Shutdown_pToken_0++
	}
	else if (TheCall == "Gui, dragOverlay: Destroy")
	{
		Gui_dragOverlay_Destroy_0 := True
		Count_Gui_dragOverlay_Destroy_0++
	}
	else if (TheCall == "pToken_0 := Gdip_Startup()")
	{
		Startup_pToken_0 := True
		Count_Startup_pToken_0++
	}
	else if (TheCall == "pBitmap_0 := Gdip_BitmapFromScreen()")
	{
		BitmapFromScreen_pBitmap_0 := True
		Count_BitmapFromScreen_pBitmap_0++
	}
	else if (TheCall == "Gdip_SaveBitmapToFile(pBitmap_0)")
	{
		SaveBitmapToFile_pBitmap_0 := True
		Count_SaveBitmapToFile_pBitmap_0++
	}
	else if (TheCall == "Gdip_CloneBitmapArea(pBitmap_0)")
	{
		CloneBitmapArea_pBitmap_0 := True
		Count_CloneBitmapArea_pBitmap_0++
	}
	else if (TheCall == "hbm_0 := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)")
	{
		CreateDIBSection_hbm_0 := True
		Count_CreateDIBSection_hbm_0++
	}
	else if (TheCall == "hdc_0 := CreateCompatibleDC()")
	{
		CreateCompatibleDC_hdc_0 := True
		Count_CreateCompatibleDC_hdc_0++
	}
	else if (TheCall == "obm_0 := SelectObject(hdc_0, hbm_0)")
	{
		SelectObject_hbm_0 := True
		Count_SelectObject_hbm_0++
	}
	else if (TheCall == "G_0 := Gdip_GraphicsFromHDC(hdc_0)")
	{
		GraphicsFromHDC_G_0_hdc_0 := True
		Count_GraphicsFromHDC_G_0_hdc_0++
	}
	else if (TheCall == "Gdip_TextToGraphics(G_0)")
	{
		TextToGraphics_G_0 := True
		Count_TextToGraphics_G_0++
	}
	else if (TheCall == "UpdateLayeredWindow(hwnd_0, hdc_0)")
	{
		UpdateLayeredWindow_hwnd_0_hdc_0 := True
		Count_UpdateLayeredWindow_hwnd_0_hdc_0++
	}
	else if (TheCall == "pPen_0 := Gdip_CreatePen()")
	{
		CreatePen_pPen_0 := True
		Count_CreatePen_pPen_0++
	}
	else if (TheCall == "Gui, dragOverlay: Show")
	{
		Gui_dragOverlay_Show_0 := True
		Count_Gui_dragOverlay_Show_0++
	}
	else if (TheCall == "Gui, arrowGui: Show")
	{
		Gui_arrowGui_Show_1 := True
		Count_Gui_arrowGui_Show_1++
	}
	else if (TheCall == "pToken_1 := Gdip_Startup()")
	{
		Startup_pToken_1 := True
		Count_Startup_pToken_1++
	}
	else if (TheCall == "hbm_1 := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)")
	{
		CreateDIBSection_hbm_1 := True
		Count_CreateDIBSection_hbm_1++
	}
	else if (TheCall == "hdc_1 := CreateCompatibleDC()")
	{
		CreateCompatibleDC_hdc_1 := True
		Count_CreateCompatibleDC_hdc_1++
	}
	else if (TheCall == "obm_1 := SelectObject(hdc_1, hbm_1)")
	{
		SelectObject_hbm_1 := True
		Count_SelectObject_hbm_1++
	}
	else if (TheCall == "G_1 := Gdip_GraphicsFromHDC(hdc_1)")
	{
		GraphicsFromHDC_G_1_hdc_1 := True
		Count_GraphicsFromHDC_G_1_hdc_1++
	}
	else if (TheCall == "Gdip_GraphicsClear(G_1)")
	{
		GraphicsClear_G_1 := True
		Count_GraphicsClear_G_1++
	}
	else if (TheCall == "UpdateLayeredWindow(hwnd_1, hdc_1, 0, 0, Width, Height)")
	{
		UpdateLayeredWindow_hwnd_1_hdc_1 := True
		Count_UpdateLayeredWindow_hwnd_1_hdc_1++
	}
	else if (TheCall == "pPen_1 := Gdip_CreatePen()")
	{
		CreatePen_pPen_1 := True
		Count_CreatePen_pPen_1++
	}
	else if (TheCall == "Gdip_DeletePen(pPen_1)")
	{
		DeletePen_pPen_1 := true
		Count_DeletePen_pPen_1++
	}
	else if (TheCall == "Gdip_DrawLines(G_1, pPen_1)")
	{
		DrawLines_G_1_pPen_1 := true
		Count_DrawLines_G_1_pPen_1++
	}
	else if (TheCall == "Gui, arrowGui: Destroy")
	{
		Gui_arrowGui_Destroy_1 := True
		Count_Gui_arrowGui_Destroy_1++
	}
}
return


TooltipHelp_ResetFlags()
{
	GraphicsClear_G_0 := False
	DeletePen_pPen_0 := False
	DeleteGraphics_G_0 := False
	SelectObject_obm_0 := False
	DeleteObject_hbm_0 := False
	DeleteDC_hdc_0 := False
	DisposeImage_pBitmap_0 := False
	Shutdown_pToken_0 := False
	Gui_dragOverlay_Destroy_0 := False
	Startup_pToken_0 := False
	BitmapFromScreen_pBitmap_0 := False
	SaveBitmapToFile_pBitmap_0 := False
	CloneBitmapArea_pBitmap_0 := False
	CreateDIBSection_hbm_0 := False
	CreateCompatibleDC_hdc_0 := False
	SelectObject_hbm_0 := False
	GraphicsFromHDC_G_0_hdc_0 := False
	TextToGraphics_G_0 := False
	UpdateLayeredWindow_hwnd_0_hdc_0 := False
	CreatePen_pPen_0 := False
	Gui_dragOverlay_Show_0 := False
	Gui_arrowGui_Show_1 := False
	Startup_pToken_1 := False
	CreateDIBSection_hbm_1 := False
	CreateCompatibleDC_hdc_1 := False
	SelectObject_hbm_1 := False
	GraphicsFromHDC_G_1_hdc_1 := False
	GraphicsClear_G_1 := False
	UpdateLayeredWindow_hwnd_1_hdc_1 := False
	CreatePen_pPen_1 := False
	DeletePen_pPen_1 := False
	DrawLines_G_1_pPen_1 := False
	Gui_arrowGui_Destroy_1 := False
	Refresh_Count := 0
}
return



 ;~ ################################################################################# >>
^F12::
{
	if(LastSavedImagePath != "")
	{
		IfExist, %LastSavedImagePath%
		{
			FileDelete, %LastSavedImagePath%
		}
		if(NAME_MODE == "TITLE_SEQ")
		{
			Sequencial := Last_Sequencial
			tooltip, IMAGEM DELETADA: %Texto%_%Sequencial%, 1, 1
		}
		else if(NAME_MODE := "TITLE_SEQ-SUBSEQ")
		{
			tooltip, IMAGEM DELETADA: %Texto%_%Sequencial%-%Sub_Sequencial%, 1, 1
			tooltip, IMAGEM DELETADA: %LastSavedImagePath%,1,1
			Sub_Sequencial := Sub_Sequencial - 1
			Sub_Sequencial := SubStr("000" . Sub_Sequencial,-2)
		}		
		SetTimer, RemoveToolTip, 2000
		LastSavedImagePath := ""
	}
	else
	{
		tooltip, NÃO HÁ IMAGEM NA MEMÓRIA PARA SER DELETADA!,1,1
		SetTimer, RemoveToolTip, 2000
	}
}
return
 ;~ ################################################################################# >>
^ins::
{
	Reload
}
return
 ;~ ################################################################################# >>
^Esc::
{
	ExitApp
}
return


Exit:
{
	msgbox, Ops! A data de expiração do sistema já foi atingida.`n`nRafael Carneiro Nascimento.
}
exitapp

Include File:

Gdip.ahk By Tic

Code: Select all

###################################################
; STATUS ENUMERATION
; Return values for functions specified to have status enumerated return type
;#####################################################################################
;
; Ok =						= 0
; GenericError				= 1
; InvalidParameter			= 2
; OutOfMemory				= 3
; ObjectBusy				= 4
; InsufficientBuffer		= 5
; NotImplemented			= 6
; Win32Error				= 7
; WrongState				= 8
; Aborted					= 9
; FileNotFound				= 10
; ValueOverflow				= 11
; AccessDenied				= 12
; UnknownImageFormat		= 13
; FontFamilyNotFound		= 14
; FontStyleNotFound			= 15
; NotTrueTypeFont			= 16
; UnsupportedGdiplusVersion	= 17
; GdiplusNotInitialized		= 18
; PropertyNotFound			= 19
; PropertyNotSupported		= 20
; ProfileNotFound			= 21
;
;#####################################################################################
;#####################################################################################
; FUNCTIONS
;#####################################################################################
;
; UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)
; BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster="")
; StretchBlt(dDC, dx, dy, dw, dh, sDC, sx, sy, sw, sh, Raster="")
; SetImage(hwnd, hBitmap)
; Gdip_BitmapFromScreen(Screen=0, Raster="")
; CreateRectF(ByRef RectF, x, y, w, h)
; CreateSizeF(ByRef SizeF, w, h)
; CreateDIBSection
;
;#####################################################################################

; Function:     			UpdateLayeredWindow
; Description:  			Updates a layered window with the handle to the DC of a gdi bitmap
; 
; hwnd        				Handle of the layered window to update
; hdc           			Handle to the DC of the GDI bitmap to update the window with
; Layeredx      			x position to place the window
; Layeredy      			y position to place the window
; Layeredw      			Width of the window
; Layeredh      			Height of the window
; Alpha         			Default = 255 : The transparency (0-255) to set the window transparency
;
; return      				If the function succeeds, the return value is nonzero
;
; notes						If x or y omitted, then layered window will use its current coordinates
;							If w or h omitted then current width and height will be used

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)
}

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

; Function				BitBlt
; Description			The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle 
;						of pixels from the specified source device context into a destination device context.
;
; dDC					handle to destination DC
; dx					x-coord of destination upper-left corner
; dy					y-coord of destination upper-left corner
; dw					width of the area to copy
; dh					height of the area to copy
; sDC					handle to source DC
; sx					x-coordinate of source upper-left corner
; sy					y-coordinate of source upper-left corner
; Raster				raster operation code
;
; return				If the function succeeds, the return value is nonzero
;
; notes					If no raster operation is specified, then SRCCOPY is used, which copies the source directly to the destination rectangle
;
; 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

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)
}

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

; Function				StretchBlt
; Description			The StretchBlt function copies a bitmap from a source rectangle into a destination rectangle, 
;						stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary.
;						The system stretches or compresses the bitmap according to the stretching mode currently set in the destination device context.
;
; ddc					handle to destination DC
; dx					x-coord of destination upper-left corner
; dy					y-coord of destination upper-left corner
; dw					width of destination rectangle
; dh					height of destination rectangle
; sdc					handle to source DC
; sx					x-coordinate of source upper-left corner
; sy					y-coordinate of source upper-left corner
; sw					width of source rectangle
; sh					height of source rectangle
; Raster				raster operation code
;
; return				If the function succeeds, the return value is nonzero
;
; notes					If no raster operation is specified, then SRCCOPY is used. It uses the same raster operations as BitBlt		

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)
}

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

; Function				SetStretchBltMode
; Description			The SetStretchBltMode function sets the bitmap stretching mode in the specified device context
;
; hdc					handle to the DC
; iStretchMode			The stretching mode, describing how the target will be stretched
;
; return				If the function succeeds, the return value is the previous stretching mode. If it fails it will return 0
;
; STRETCH_ANDSCANS 		= 0x01
; STRETCH_ORSCANS 		= 0x02
; STRETCH_DELETESCANS 	= 0x03
; STRETCH_HALFTONE 		= 0x04

SetStretchBltMode(hdc, iStretchMode=4)
{
	return DllCall("gdi32\SetStretchBltMode"
					, A_PtrSize ? "UPtr" : "UInt", hdc
					, "int", iStretchMode)
}

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

; Function				SetImage
; Description			Associates a new image with a static control
;
; hwnd					handle of the control to update
; hBitmap				a gdi bitmap to associate the static control with
;
; return				If the function succeeds, the return value is nonzero

SetImage(hwnd, hBitmap)
{
	SendMessage, 0x172, 0x0, hBitmap,, ahk_id %hwnd%
	E := ErrorLevel
	DeleteObject(E)
	return E
}

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

; Function				SetSysColorToControl
; Description			Sets a solid colour to a control
;
; hwnd					handle of the control to update
; SysColor				A system colour to set to the control
;
; return				If the function succeeds, the return value is zero
;
; notes					A control must have the 0xE style set to it so it is recognised as a bitmap
;						By default SysColor=15 is used which is COLOR_3DFACE. This is the standard background for a control
;
; COLOR_3DDKSHADOW				= 21
; COLOR_3DFACE					= 15
; COLOR_3DHIGHLIGHT				= 20
; COLOR_3DHILIGHT				= 20
; COLOR_3DLIGHT					= 22
; COLOR_3DSHADOW				= 16
; COLOR_ACTIVEBORDER			= 10
; COLOR_ACTIVECAPTION			= 2
; COLOR_APPWORKSPACE			= 12
; COLOR_BACKGROUND				= 1
; COLOR_BTNFACE					= 15
; COLOR_BTNHIGHLIGHT			= 20
; COLOR_BTNHILIGHT				= 20
; COLOR_BTNSHADOW				= 16
; COLOR_BTNTEXT					= 18
; COLOR_CAPTIONTEXT				= 9
; COLOR_DESKTOP					= 1
; COLOR_GRADIENTACTIVECAPTION	= 27
; COLOR_GRADIENTINACTIVECAPTION	= 28
; COLOR_GRAYTEXT				= 17
; COLOR_HIGHLIGHT				= 13
; COLOR_HIGHLIGHTTEXT			= 14
; COLOR_HOTLIGHT				= 26
; COLOR_INACTIVEBORDER			= 11
; COLOR_INACTIVECAPTION			= 3
; COLOR_INACTIVECAPTIONTEXT		= 19
; COLOR_INFOBK					= 24
; COLOR_INFOTEXT				= 23
; COLOR_MENU					= 4
; COLOR_MENUHILIGHT				= 29
; COLOR_MENUBAR					= 30
; COLOR_MENUTEXT				= 7
; COLOR_SCROLLBAR				= 0
; COLOR_WINDOW					= 5
; COLOR_WINDOWFRAME				= 6
; COLOR_WINDOWTEXT				= 8

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
}

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

; Function				Gdip_BitmapFromScreen
; Description			Gets a gdi+ bitmap from the screen
;
; Screen				0 = All screens
;						Any numerical value = Just that screen
;						x|y|w|h = Take specific coordinates with a width and height
; Raster				raster operation code
;
; return      			If the function succeeds, the return value is a pointer to a gdi+ bitmap
;						-1:		one or more of x,y,w,h not passed properly
;
; notes					If no raster operation is specified, then SRCCOPY is used to the returned bitmap

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
}

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

; Function				Gdip_BitmapFromHWND
; Description			Uses PrintWindow to get a handle to the specified window and return a bitmap from it
;
; hwnd					handle to the window to get a bitmap from
;
; return				If the function succeeds, the return value is a pointer to a gdi+ bitmap
;
; notes					Window must not be not minimised in order to get a handle to it's client area

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
}

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

; Function    			CreateRectF
; Description			Creates a RectF object, containing a the coordinates and dimensions of a rectangle
;
; RectF       			Name to call the RectF object
; x            			x-coordinate of the upper left corner of the rectangle
; y            			y-coordinate of the upper left corner of the rectangle
; w            			Width of the rectangle
; h            			Height of the rectangle
;
; return      			No return value

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")
}

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

; Function    			CreateRect
; Description			Creates a Rect object, containing a the coordinates and dimensions of a rectangle
;
; RectF       			Name to call the RectF object
; x            			x-coordinate of the upper left corner of the rectangle
; y            			y-coordinate of the upper left corner of the rectangle
; w            			Width of the rectangle
; h            			Height of the rectangle
;
; return      			No return value

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")
}
;#####################################################################################

; Function		    	CreateSizeF
; Description			Creates a SizeF object, containing an 2 values
;
; SizeF         		Name to call the SizeF object
; w            			w-value for the SizeF object
; h            			h-value for the SizeF object
;
; return      			No Return value

CreateSizeF(ByRef SizeF, w, h)
{
   VarSetCapacity(SizeF, 8)
   NumPut(w, SizeF, 0, "float"), NumPut(h, SizeF, 4, "float")     
}
;#####################################################################################

; Function		    	CreatePointF
; Description			Creates a SizeF object, containing an 2 values
;
; SizeF         		Name to call the SizeF object
; w            			w-value for the SizeF object
; h            			h-value for the SizeF object
;
; return      			No Return value

CreatePointF(ByRef PointF, x, y)
{
   VarSetCapacity(PointF, 8)
   NumPut(x, PointF, 0, "float"), NumPut(y, PointF, 4, "float")     
}
;#####################################################################################

; Function				CreateDIBSection
; Description			The CreateDIBSection function creates a DIB (Device Independent Bitmap) that applications can write to directly
;
; w						width of the bitmap to create
; h						height of the bitmap to create
; hdc					a handle to the device context to use the palette from
; bpp					bits per pixel (32 = ARGB)
; ppvBits				A pointer to a variable that receives a pointer to the location of the DIB bit values
;
; return				returns a DIB. A gdi bitmap
;
; notes					ppvBits will receive the location of the pixels in the DIB

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
}

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

; Function				PrintWindow
; Description			The PrintWindow function copies a visual window into the specified device context (DC), typically a printer DC
;
; hwnd					A handle to the window that will be copied
; hdc					A handle to the device context
; Flags					Drawing options
;
; return				If the function succeeds, it returns a nonzero value
;
; PW_CLIENTONLY			= 1

PrintWindow(hwnd, hdc, Flags=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	
	return DllCall("PrintWindow", Ptr, hwnd, Ptr, hdc, "uint", Flags)
}

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

; Function				DestroyIcon
; Description			Destroys an icon and frees any memory the icon occupied
;
; hIcon					Handle to the icon to be destroyed. The icon must not be in use
;
; return				If the function succeeds, the return value is nonzero

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)
}

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

; Function				CreateCompatibleDC
; Description			This function creates a memory device context (DC) compatible with the specified device
;
; hdc					Handle to an existing device context					
;
; return				returns the handle to a device context or 0 on failure
;
; notes					If this handle is 0 (by default), the function creates a memory device context compatible with the application's current screen

CreateCompatibleDC(hdc=0)
{
   return DllCall("CreateCompatibleDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}

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

; Function				SelectObject
; Description			The SelectObject function selects an object into the specified device context (DC). The new object replaces the previous object of the same type
;
; hdc					Handle to a DC
; hgdiobj				A handle to the object to be selected into the DC
;
; return				If the selected object is not a region and the function succeeds, the return value is a handle to the object being replaced
;
; notes					The specified object must have been created by using one of the following functions
;						Bitmap - CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, CreateDIBitmap, CreateDIBSection (A single bitmap cannot be selected into more than one DC at the same time)
;						Brush - CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt, CreateHatchBrush, CreatePatternBrush, CreateSolidBrush
;						Font - CreateFont, CreateFontIndirect
;						Pen - CreatePen, CreatePenIndirect
;						Region - CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreateRectRgn, CreateRectRgnIndirect
;
; notes					If the selected object is a region and the function succeeds, the return value is one of the following value
;
; SIMPLEREGION			= 2 Region consists of a single rectangle
; COMPLEXREGION			= 3 Region consists of more than one rectangle
; NULLREGION			= 1 Region is empty

SelectObject(hdc, hgdiobj)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	
	return DllCall("SelectObject", Ptr, hdc, Ptr, hgdiobj)
}

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

; Function				DeleteObject
; Description			This function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object
;						After the object is deleted, the specified handle is no longer valid
;
; hObject				Handle to a logical pen, brush, font, bitmap, region, or palette to delete
;
; return				Nonzero indicates success. Zero indicates that the specified handle is not valid or that the handle is currently selected into a device context

DeleteObject(hObject)
{
   return DllCall("DeleteObject", A_PtrSize ? "UPtr" : "UInt", hObject)
}

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

; Function				GetDC
; Description			This function retrieves a handle to a display device context (DC) for the client area of the specified window.
;						The display device context can be used in subsequent graphics display interface (GDI) functions to draw in the client area of the window. 
;
; hwnd					Handle to the window whose device context is to be retrieved. If this value is NULL, GetDC retrieves the device context for the entire screen					
;
; return				The handle the device context for the specified window's client area indicates success. NULL indicates failure

GetDC(hwnd=0)
{
	return DllCall("GetDC", A_PtrSize ? "UPtr" : "UInt", hwnd)
}

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

; DCX_CACHE = 0x2
; DCX_CLIPCHILDREN = 0x8
; DCX_CLIPSIBLINGS = 0x10
; DCX_EXCLUDERGN = 0x40
; DCX_EXCLUDEUPDATE = 0x100
; DCX_INTERSECTRGN = 0x80
; DCX_INTERSECTUPDATE = 0x200
; DCX_LOCKWINDOWUPDATE = 0x400
; DCX_NORECOMPUTE = 0x100000
; DCX_NORESETATTRS = 0x4
; DCX_PARENTCLIP = 0x20
; DCX_VALIDATE = 0x200000
; DCX_WINDOW = 0x1

GetDCEx(hwnd, flags=0, hrgnClip=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	
    return DllCall("GetDCEx", Ptr, hwnd, Ptr, hrgnClip, "int", flags)
}

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

; Function				ReleaseDC
; Description			This function releases a device context (DC), freeing it for use by other applications. The effect of ReleaseDC depends on the type of device context
;
; hdc					Handle to the device context to be released
; hwnd					Handle to the window whose device context is to be released
;
; return				1 = released
;						0 = not released
;
; notes					The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common device context
;						An application cannot use the ReleaseDC function to release a device context that was created by calling the CreateDC function; instead, it must use the DeleteDC function. 

ReleaseDC(hdc, hwnd=0)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	
	return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
}

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

; Function				DeleteDC
; Description			The DeleteDC function deletes the specified device context (DC)
;
; hdc					A handle to the device context
;
; return				If the function succeeds, the return value is nonzero
;
; notes					An application must not delete a DC whose handle was obtained by calling the GetDC function. Instead, it must call the ReleaseDC function to free the DC

DeleteDC(hdc)
{
   return DllCall("DeleteDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}
;#####################################################################################

; Function				Gdip_LibraryVersion
; Description			Get the current library version
;
; return				the library version
;
; notes					This is useful for non compiled programs to ensure that a person doesn't run an old version when testing your scripts

Gdip_LibraryVersion()
{
	return 1.45
}

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

; Function				Gdip_LibrarySubVersion
; Description			Get the current library sub version
;
; return				the library sub version
;
; notes					This is the sub-version currently maintained by Rseding91
Gdip_LibrarySubVersion()
{
	return 1.47
}

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

; Function:    			Gdip_BitmapFromBRA
; Description: 			Gets a pointer to a gdi+ bitmap from a BRA file
;
; BRAFromMemIn			The variable for a BRA file read to memory
; File					The name of the file, or its number that you would like (This depends on alternate parameter)
; Alternate				Changes whether the File parameter is the file name or its number
;
; return      			If the function succeeds, the return value is a pointer to a gdi+ bitmap
;						-1 = The BRA variable is empty
;						-2 = The BRA has an incorrect header
;						-3 = The BRA has information missing
;						-4 = Could not find file inside the BRA

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
}

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

; Function				Gdip_DrawRectangle
; Description			This function uses a pen to draw the outline of a rectangle into the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pPen					Pointer to a pen
; x						x-coordinate of the top left of the rectangle
; y						y-coordinate of the top left of the rectangle
; w						width of the rectanlge
; h						height of the rectangle
;
; return				status enumeration. 0 = success
;
; notes					as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

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)
}

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

; Function				Gdip_DrawRoundedRectangle
; Description			This function uses a pen to draw the outline of a rounded rectangle into the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pPen					Pointer to a pen
; x						x-coordinate of the top left of the rounded rectangle
; y						y-coordinate of the top left of the rounded rectangle
; w						width of the rectanlge
; h						height of the rectangle
; r						radius of the rounded corners
;
; return				status enumeration. 0 = success
;
; notes					as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

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
}

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

; Function				Gdip_DrawEllipse
; Description			This function uses a pen to draw the outline of an ellipse into the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pPen					Pointer to a pen
; x						x-coordinate of the top left of the rectangle the ellipse will be drawn into
; y						y-coordinate of the top left of the rectangle the ellipse will be drawn into
; w						width of the ellipse
; h						height of the ellipse
;
; return				status enumeration. 0 = success
;
; notes					as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

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)
}

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

; Function				Gdip_DrawBezier
; Description			This function uses a pen to draw the outline of a bezier (a weighted curve) into the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pPen					Pointer to a pen
; x1					x-coordinate of the start of the bezier
; y1					y-coordinate of the start of the bezier
; x2					x-coordinate of the first arc of the bezier
; y2					y-coordinate of the first arc of the bezier
; x3					x-coordinate of the second arc of the bezier
; y3					y-coordinate of the second arc of the bezier
; x4					x-coordinate of the end of the bezier
; y4					y-coordinate of the end of the bezier
;
; return				status enumeration. 0 = success
;
; notes					as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

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)
}

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

; Function				Gdip_DrawArc
; Description			This function uses a pen to draw the outline of an arc into the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pPen					Pointer to a pen
; x						x-coordinate of the start of the arc
; y						y-coordinate of the start of the arc
; w						width of the arc
; h						height of the arc
; StartAngle			specifies the angle between the x-axis and the starting point of the arc
; SweepAngle			specifies the angle between the starting and ending points of the arc
;
; return				status enumeration. 0 = success
;
; notes					as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

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)
}

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

; Function				Gdip_DrawPie
; Description			This function uses a pen to draw the outline of a pie into the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pPen					Pointer to a pen
; x						x-coordinate of the start of the pie
; y						y-coordinate of the start of the pie
; w						width of the pie
; h						height of the pie
; StartAngle			specifies the angle between the x-axis and the starting point of the pie
; SweepAngle			specifies the angle between the starting and ending points of the pie
;
; return				status enumeration. 0 = success
;
; notes					as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

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)
}

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

; Function				Gdip_DrawLine
; Description			This function uses a pen to draw a line into the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pPen					Pointer to a pen
; x1					x-coordinate of the start of the line
; y1					y-coordinate of the start of the line
; x2					x-coordinate of the end of the line
; y2					y-coordinate of the end of the line
;
; return				status enumeration. 0 = success		

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)
}

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

; Function				Gdip_DrawLines
; Description			This function uses a pen to draw a series of joined lines into the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pPen					Pointer to a pen
; Points				the coordinates of all the points passed as x1,y1|x2,y2|x3,y3.....
;
; return				status enumeration. 0 = success				

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)
}

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

; Function				Gdip_FillRectangle
; Description			This function uses a brush to fill a rectangle in the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBrush				Pointer to a brush
; x						x-coordinate of the top left of the rectangle
; y						y-coordinate of the top left of the rectangle
; w						width of the rectanlge
; h						height of the rectangle
;
; return				status enumeration. 0 = success

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)
}

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

; Function				Gdip_FillRoundedRectangle
; Description			This function uses a brush to fill a rounded rectangle in the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBrush				Pointer to a brush
; x						x-coordinate of the top left of the rounded rectangle
; y						y-coordinate of the top left of the rounded rectangle
; w						width of the rectanlge
; h						height of the rectangle
; r						radius of the rounded corners
;
; return				status enumeration. 0 = success

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
}

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

; Function				Gdip_FillPolygon
; Description			This function uses a brush to fill a polygon in the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBrush				Pointer to a brush
; Points				the coordinates of all the points passed as x1,y1|x2,y2|x3,y3.....
;
; return				status enumeration. 0 = success
;
; notes					Alternate will fill the polygon as a whole, wheras winding will fill each new "segment"
; Alternate 			= 0
; Winding 				= 1

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)
}

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

; Function				Gdip_FillPie
; Description			This function uses a brush to fill a pie in the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBrush				Pointer to a brush
; x						x-coordinate of the top left of the pie
; y						y-coordinate of the top left of the pie
; w						width of the pie
; h						height of the pie
; StartAngle			specifies the angle between the x-axis and the starting point of the pie
; SweepAngle			specifies the angle between the starting and ending points of the pie
;
; return				status enumeration. 0 = success

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)
}

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

; Function				Gdip_FillEllipse
; Description			This function uses a brush to fill an ellipse in the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBrush				Pointer to a brush
; x						x-coordinate of the top left of the ellipse
; y						y-coordinate of the top left of the ellipse
; w						width of the ellipse
; h						height of the ellipse
;
; return				status enumeration. 0 = success

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)
}

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

; Function				Gdip_FillRegion
; Description			This function uses a brush to fill a region in the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBrush				Pointer to a brush
; Region				Pointer to a Region
;
; return				status enumeration. 0 = success
;
; notes					You can create a region Gdip_CreateRegion() and then add to this

Gdip_FillRegion(pGraphics, pBrush, Region)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	
	return DllCall("gdiplus\GdipFillRegion", Ptr, pGraphics, Ptr, pBrush, Ptr, Region)
}

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

; Function				Gdip_FillPath
; Description			This function uses a brush to fill a path in the Graphics of a bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBrush				Pointer to a brush
; Region				Pointer to a Path
;
; return				status enumeration. 0 = success

Gdip_FillPath(pGraphics, pBrush, Path)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	
	return DllCall("gdiplus\GdipFillPath", Ptr, pGraphics, Ptr, pBrush, Ptr, Path)
}

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

; Function				Gdip_DrawImagePointsRect
; Description			This function draws a bitmap into the Graphics of another bitmap and skews it
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBitmap				Pointer to a bitmap to be drawn
; Points				Points passed as x1,y1|x2,y2|x3,y3 (3 points: top left, top right, bottom left) describing the drawing of the bitmap
; sx					x-coordinate of source upper-left corner
; sy					y-coordinate of source upper-left corner
; sw					width of source rectangle
; sh					height of source rectangle
; Matrix				a matrix used to alter image attributes when drawing
;
; return				status enumeration. 0 = success
;
; notes					if sx,sy,sw,sh are missed then the entire source bitmap will be used
;						Matrix can be omitted to just draw with no alteration to ARGB
;						Matrix may be passed as a digit from 0 - 1 to change just transparency
;						Matrix can be passed as a matrix with any delimiter

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
}

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

; Function				Gdip_DrawImage
; Description			This function draws a bitmap into the Graphics of another bitmap
;
; pGraphics				Pointer to the Graphics of a bitmap
; pBitmap				Pointer to a bitmap to be drawn
; dx					x-coord of destination upper-left corner
; dy					y-coord of destination upper-left corner
; dw					width of destination image
; dh					height of destination image
; sx					x-coordinate of source upper-left corner
; sy					y-coordinate of source upper-left corner
; sw					width of source image
; sh					height of source image
; Matrix				a matrix used to alter image attributes when drawing
;
; return				status enumeration. 0 = success
;
; notes					if sx,sy,sw,sh are missed then the entire source bitmap will be used
;						Gdip_DrawImage performs faster
;						Matrix can be omitted to just draw with no alteration to ARGB
;						Matrix may be passed as a digit from 0 - 1 to change just transparency
;						Matrix can be passed as a matrix with any delimiter. For example:
;						MatrixBright=
;						(
;						1.5		|0		|0		|0		|0
;						0		|1.5	|0		|0		|0
;						0		|0		|1.5	|0		|0
;						0		|0		|0		|1		|0
;						0.05	|0.05	|0.05	|0		|1
;						)
;
; notes					MatrixBright = 1.5|0|0|0|0|0|1.5|0|0|0|0|0|1.5|0|0|0|0|0|1|0|0.05|0.05|0.05|0|1
;						MatrixGreyScale = 0.299|0.299|0.299|0|0|0.587|0.587|0.587|0|0|0.114|0.114|0.114|0|0|0|0|0|1|0|0|0|0|0|1
;						MatrixNegative = -1|0|0|0|0|0|-1|0|0|0|0|0|-1|0|0|0|0|0|1|0|0|0|0|0|1

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
}

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

; Function				Gdip_SetImageAttributesColorMatrix
; Description			This function creates an image matrix ready for drawing
;
; Matrix				a matrix used to alter image attributes when drawing
;						passed with any delimeter
;
; return				returns an image matrix on sucess or 0 if it fails
;
; notes					MatrixBright = 1.5|0|0|0|0|0|1.5|0|0|0|0|0|1.5|0|0|0|0|0|1|0|0.05|0.05|0.05|0|1
;						MatrixGreyScale = 0.299|0.299|0.299|0|0|0.587|0.587|0.587|0|0|0.114|0.114|0.114|0|0|0|0|0|1|0|0|0|0|0|1
;						MatrixNegative = -1|0|0|0|0|0|-1|0|0|0|0|0|-1|0|0|0|0|0|1|0|0|0|0|0|1

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
}

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

; Function				Gdip_GraphicsFromImage
; Description			This function gets the graphics for a bitmap used for drawing functions
;
; pBitmap				Pointer to a bitmap to get the pointer to its graphics
;
; return				returns a pointer to the graphics of a bitmap
;
; notes					a bitmap can be drawn into the graphics of another bitmap

Gdip_GraphicsFromImage(pBitmap)
{
	DllCall("gdiplus\GdipGetImageGraphicsContext", A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
	return pGraphics
}

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

; Function				Gdip_GraphicsFromHDC
; Description			This function gets the graphics from the handle to a device context
;
; hdc					This is the handle to the device context
;
; return				returns a pointer to the graphics of a bitmap
;
; notes					You can draw a bitmap into the graphics of another bitmap

Gdip_GraphicsFromHDC(hdc)
{
    DllCall("gdiplus\GdipCreateFromHDC", A_PtrSize ? "UPtr" : "UInt", hdc, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
    return pGraphics
}

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

; Function				Gdip_GetDC
; Description			This function gets the device context of the passed Graphics
;
; hdc					This is the handle to the device context
;
; return				returns the device context for the graphics of a bitmap

Gdip_GetDC(pGraphics)
{
	DllCall("gdiplus\GdipGetDC", A_PtrSize ? "UPtr" : "UInt", pGraphics, A_PtrSize ? "UPtr*" : "UInt*", hdc)
	return hdc
}

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

; Function				Gdip_ReleaseDC
; Description			This function releases a device context from use for further use
;
; pGraphics				Pointer to the graphics of a bitmap
; hdc					This is the handle to the device context
;
; return				status enumeration. 0 = success

Gdip_ReleaseDC(pGraphics, hdc)
{
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	
	return DllCall("gdiplus\GdipReleaseDC", Ptr, pGraphics, Ptr, hdc)
}

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

; Function				Gdip_GraphicsClear
; Description			Clears the graphics of a bitmap ready for further drawing
;
; pGraphics				Pointer to the graphics of a bitmap
; ARGB					The colour to clear the graphics to
;
; return				status enumeration. 0 = success
;
; notes					By default this will make the background invisible
;						Using clipping regions you can clear a particular area on the graphics rather than clearing the entire graphics

Gdip_GraphicsClear(pGraphics, ARGB=0x00ffffff)
{
    return DllCall("gdiplus\GdipGraphicsClear", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", ARGB)
}

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

; Function				Gdip_BlurBitmap
; Description			Gives a pointer to a blurred bitmap from a pointer to a bitmap
;
; pBitmap				Pointer to a bitmap to be blurred
; Blur					The Amount to blur a bitmap by from 1 (least blur) to 100 (most blur)
;
; return				If the function succeeds, the return value is a pointer to the new blurred bitmap
;						-1 = The blur parameter is outside the range 1-100
;
; notes					This function will not dispose of the original bitmap

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
}

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

; Function:     		Gdip_SaveBitmapToFile
; Description:  		Saves a bitmap to a file in any supported format onto disk
;   
; pBitmap				Pointer to a bitmap
; sOutput      			The name of the file that the bitmap will be saved to. Supported extensions are: .BMP,.DIB,.RLE,.JPG,.JPEG,.JPE,.JFIF,.GIF,.TIF,.TIFF,.PNG
; Quality      			If saving as jpg (.JPG,.JPEG,.JPE,.JFIF) then quality can be 1-100 with default at maximum quality
;
; return      			If the function succeeds, the return value is zero, otherwise:
;						-1 = Extension supplied is not a supported file format
;						-2 = Could not get a list of encoders on system
;						-3 = Could not find matching encoder for specified file format
;						-4 = Could not get WideChar name of output file
;						-5 = Could not save file to disk
;
; notes					This function will use the extension supplied from the sOutput parameter to determine the output format

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
}

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

; Function				Gdip_GetPixel
; Description			Gets the ARGB of a pixel in a bitmap
;
; pBitmap				Pointer to a bitmap
; x						x-coordinate of the pixel
; y						y-coordinate of the pixel
;
; return				Returns the ARGB value of the pixel

Gdip_GetPixel(pBitmap, x, y)
{
	DllCall("gdiplus\GdipBitmapGetPixel", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "uint*", ARGB)
	return ARGB
}

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

; Function				Gdip_SetPixel
; Description			Sets the ARGB of a pixel in a bitmap
;
; pBitmap				Pointer to a bitmap
; x						x-coordinate of the pixel
; y						y-coordinate of the pixel
;
; return				status enumeration. 0 = success

Gdip_SetPixel(pBitmap, x, y, ARGB)
{
   return DllCall("gdiplus\GdipBitmapSetPixel", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "int", ARGB)
}

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

; Function				Gdip_GetImageWidth
; Description			Gives the width of a bitmap
;
; pBitmap				Pointer to a bitmap
;
; return				Returns the width in pixels of the supplied bitmap

Gdip_GetImageWidth(pBitmap)
{
   DllCall("gdiplus\GdipGetImageWidth", A_PtrSize ? "UPtr" : "UInt", pBitmap, "uint*", Width)
   return Width
}

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

; Function				Gdip_GetImageHeight
; Description			Gives the height of a bitmap
;
; pBitmap				Pointer to a bitmap
;
; return				Returns the height in pixels of the supplied bitmap

Gdip_GetImageHeight(pBitmap)
{
   DllCall("gdiplus\GdipGetImageHeight", A_PtrSize ? "UPtr" : "UInt", pBitmap, "uint*", Height)
   return Height
}

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

; Function				Gdip_GetDimensions
; Description			Gives the width and height of a bitmap
;
; pBitmap				Pointer to a bitmap
; Width					ByRef variable. This variable will be set to the width of the bitmap
; Height				ByRef variable. This variable will be set to the height of the bitmap
;
; return				No return value
;						Gdip_GetDimensions(pBitmap, ThisWidth, ThisHeight) will set ThisWidth to the width and ThisHeight to the 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
}

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

; Function				Gdip_GetDpiX
; Description			Gives the horizontal dots per inch of the graphics of a bitmap
;
; pBitmap				Pointer to a bitmap
; Width					ByRef variable. This variable will be set to the width of the bitmap
; Height				ByRef variable. This variable will be set to the height of the bitmap
;
; return				No return value
;						Gdip_GetDimensions(pBitmap, ThisWidth, ThisHeight) will set ThisWidth to the width and ThisHeight to the height

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
}

;#####################################################################################
; Create resources
;#####################################################################################

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
}

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

; HatchStyleHorizontal = 0
; HatchStyleVertical = 1
; HatchStyleForwardDiagonal = 2
; HatchStyleBackwardDiagonal = 3
; HatchStyleCross = 4
; HatchStyleDiagonalCross = 5
; HatchStyle05Percent = 6
; HatchStyle10Percent = 7
; HatchStyle20Percent = 8
; HatchStyle25Percent = 9
; HatchStyle30Percent = 10
; HatchStyle40Percent = 11
; HatchStyle50Percent = 12
; HatchStyle60Percent = 13
; HatchStyle70Percent = 14
; HatchStyle75Percent = 15
; HatchStyle80Percent = 16
; HatchStyle90Percent = 17
; HatchStyleLightDownwardDiagonal = 18
; HatchStyleLightUpwardDiagonal = 19
; HatchStyleDarkDownwardDiagonal = 20
; HatchStyleDarkUpwardDiagonal = 21
; HatchStyleWideDownwardDiagonal = 22
; HatchStyleWideUpwardDiagonal = 23
; HatchStyleLightVertical = 24
; HatchStyleLightHorizontal = 25
; HatchStyleNarrowVertical = 26
; HatchStyleNarrowHorizontal = 27
; HatchStyleDarkVertical = 28
; HatchStyleDarkHorizontal = 29
; HatchStyleDashedDownwardDiagonal = 30
; HatchStyleDashedUpwardDiagonal = 31
; HatchStyleDashedHorizontal = 32
; HatchStyleDashedVertical = 33
; HatchStyleSmallConfetti = 34
; HatchStyleLargeConfetti = 35
; HatchStyleZigZag = 36
; HatchStyleWave = 37
; HatchStyleDiagonalBrick = 38
; HatchStyleHorizontalBrick = 39
; HatchStyleWeave = 40
; HatchStylePlaid = 41
; HatchStyleDivot = 42
; HatchStyleDottedGrid = 43
; HatchStyleDottedDiamond = 44
; HatchStyleShingle = 45
; HatchStyleTrellis = 46
; HatchStyleSphere = 47
; HatchStyleSmallGrid = 48
; HatchStyleSmallCheckerBoard = 49
; HatchStyleLargeCheckerBoard = 50
; HatchStyleOutlinedDiamond = 51
; HatchStyleSolidDiamond = 52
; HatchStyleTotal = 53
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
}

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

; WrapModeTile = 0
; WrapModeTileFlipX = 1
; WrapModeTileFlipY = 2
; WrapModeTileFlipXY = 3
; WrapModeClamp = 4
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
}

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

; LinearGradientModeHorizontal = 0
; LinearGradientModeVertical = 1
; LinearGradientModeForwardDiagonal = 2
; LinearGradientModeBackwardDiagonal = 3
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
}

;#####################################################################################
; Delete resources
;#####################################################################################

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)
}

;#####################################################################################
; Text functions
;#####################################################################################

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)
}

; StringFormatFlagsDirectionRightToLeft    = 0x00000001
; StringFormatFlagsDirectionVertical       = 0x00000002
; StringFormatFlagsNoFitBlackBox           = 0x00000004
; StringFormatFlagsDisplayFormatControl    = 0x00000020
; StringFormatFlagsNoFontFallback          = 0x00000400
; StringFormatFlagsMeasureTrailingSpaces   = 0x00000800
; StringFormatFlagsNoWrap                  = 0x00001000
; StringFormatFlagsLineLimit               = 0x00002000
; StringFormatFlagsNoClip                  = 0x00004000 
Gdip_StringFormatCreate(Format=0, Lang=0)
{
   DllCall("gdiplus\GdipCreateStringFormat", "int", Format, "int", Lang, A_PtrSize ? "UPtr*" : "UInt*", hFormat)
   return hFormat
}

; Regular = 0
; Bold = 1
; Italic = 2
; BoldItalic = 3
; Underline = 4
; Strikeout = 8
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
}

;#####################################################################################
; Matrix functions
;#####################################################################################

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
}

;#####################################################################################
; GraphicsPath functions
;#####################################################################################

; Alternate = 0
; Winding = 1
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)
}

;#####################################################################################
; Quality functions
;#####################################################################################

; SystemDefault = 0
; SingleBitPerPixelGridFit = 1
; SingleBitPerPixel = 2
; AntiAliasGridFit = 3
; AntiAlias = 4
Gdip_SetTextRenderingHint(pGraphics, RenderingHint)
{
	return DllCall("gdiplus\GdipSetTextRenderingHint", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", RenderingHint)
}

; Default = 0
; LowQuality = 1
; HighQuality = 2
; Bilinear = 3
; Bicubic = 4
; NearestNeighbor = 5
; HighQualityBilinear = 6
; HighQualityBicubic = 7
Gdip_SetInterpolationMode(pGraphics, InterpolationMode)
{
   return DllCall("gdiplus\GdipSetInterpolationMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", InterpolationMode)
}

; Default = 0
; HighSpeed = 1
; HighQuality = 2
; None = 3
; AntiAlias = 4
Gdip_SetSmoothingMode(pGraphics, SmoothingMode)
{
   return DllCall("gdiplus\GdipSetSmoothingMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", SmoothingMode)
}

; CompositingModeSourceOver = 0 (blended)
; CompositingModeSourceCopy = 1 (overwrite)
Gdip_SetCompositingMode(pGraphics, CompositingMode=0)
{
   return DllCall("gdiplus\GdipSetCompositingMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", CompositingMode)
}

;#####################################################################################
; Extra functions
;#####################################################################################

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
}

; Prepend = 0; The new operation is applied before the old operation.
; Append = 1; The new operation is applied after the old operation.
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)))
}

; RotateNoneFlipNone   = 0
; Rotate90FlipNone     = 1
; Rotate180FlipNone    = 2
; Rotate270FlipNone    = 3
; RotateNoneFlipX      = 4
; Rotate90FlipX        = 5
; Rotate180FlipX       = 6
; Rotate270FlipX       = 7
; RotateNoneFlipY      = Rotate180FlipX
; Rotate90FlipY        = Rotate270FlipX
; Rotate180FlipY       = RotateNoneFlipX
; Rotate270FlipY       = Rotate90FlipX
; RotateNoneFlipXY     = Rotate180FlipNone
; Rotate90FlipXY       = Rotate270FlipNone
; Rotate180FlipXY      = RotateNoneFlipNone
; Rotate270FlipXY      = Rotate90FlipNone 

Gdip_ImageRotateFlip(pBitmap, RotateFlipType=1)
{
	return DllCall("gdiplus\GdipImageRotateFlip", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", RotateFlipType)
}

; Replace = 0
; Intersect = 1
; Union = 2
; Xor = 3
; Exclude = 4
; Complement = 5
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)
}

;#####################################################################################
; BitmapLockBits
;#####################################################################################

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
}
Last edited by RAFACN on 30 May 2020, 21:44, edited 9 times in total.
User avatar
RAFACN
Posts: 12
Joined: 20 May 2016, 10:06
Location: BRAZIL

Re: FastPrints - Fast and organized screen capture and save tool with features

01 Jun 2016, 17:20

Why is this topic Blue and most of the others are Orange? (sorry for this stupid question.. but i noticed that orange ones are always on top.)
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: FastPrints - Fast and organized screen capture and save tool with features

01 Jun 2016, 18:09

RAFACN wrote:Why is this topic Blue and most of the others are Orange? (sorry for this stupid question.. but i noticed that orange ones are always on top.)
Topics are Blue if you have read them. Orange topics are ones that are still unread by you.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
RAFACN
Posts: 12
Joined: 20 May 2016, 10:06
Location: BRAZIL

Re: FastPrints - Fast and organized screen capture and save tool with features

02 Jun 2016, 10:29

Thank you, FanaticGuru!
User avatar
RAFACN
Posts: 12
Joined: 20 May 2016, 10:06
Location: BRAZIL

Re: FastPrints - Fast and organized screen capture and save tool with features

30 May 2020, 00:11

Updated on 30/05/2020

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 242 guests